{"owner":"microsoft","repo":"fast","hasSkills":true,"totalSkillsCount":41,"totalTokensCount":90539,"categories":["copilot-instructions","anthropic-skill","plugin-manifest","cursor-rule"],"hasMcp":false,"mcpConfig":null,"found":[".github/copilot-instructions.md",".github/skills/documentation/SKILL.md",".github/skills/fast-bug-report/SKILL.md",".github/skills/fast-feature-request/SKILL.md",".github/skills/fast-pull-request/SKILL.md",".github/skills/rust/SKILL.md",".github/skills/shipping/SKILL.md",".github/skills/testing/SKILL.md",".github/skills/typescript/SKILL.md","packages/README.md","packages/fast-build/README.md","packages/fast-build/docs/migration/plugin-integrations.md","packages/fast-element/README.md","packages/fast-element/docs/ACKNOWLEDGEMENTS.md","packages/fast-element/docs/api-report.api.md","packages/fast-element/docs/architecture/fastelement.md","packages/fast-element/docs/architecture/html-tagged-template-literal.md","packages/fast-element/docs/architecture/intro.md","packages/fast-element/docs/architecture/overview.md","packages/fast-element/docs/architecture/updates.md","packages/fast-element/docs/arrays/api-report.api.md","packages/fast-element/docs/context/api-report.api.md","packages/fast-element/docs/declarative/api-report.api.md","packages/fast-element/docs/declarative/design.md","packages/fast-element/docs/declarative/lifecycle.md","packages/fast-element/docs/declarative/rendering.md","packages/fast-element/docs/declarative/schema-observer-map.md","packages/fast-element/docs/declarative/syntax.md","packages/fast-element/docs/di/api-report.api.md","packages/fast-element/docs/migration/fast-element-2.md","packages/fast-element/docs/migration/fast-element-3.md","packages/fast-element/docs/migration/fast-html.md","packages/fast-element/docs/styles/api-report.api.md","packages/fast-element/docs/template-bindings.md","packages/fast-router/README.md","packages/fast-router/docs/api-report.api.md","packages/fast-test-harness/README.md","sites/website/src/docs/1.x/tools/component-explorer.md","sites/website/src/docs/1.x/tools/hot-module-reload.md","sites/website/src/docs/1.x/tools/vscode.md",".cursorrules (fastapi-production-architecture-cursorrules-prompt-file.mdc)"],"skills":{".github/copilot-instructions.md":"---\nname: FAST Instructions\ndescription: This file describes the general instructions for working with the FAST monorepo, including repository structure, code style, tooling, and contribution guidelines.\napplyTo: '**/*'\n---\n\n# Instructions for FAST\n\n## General\n\n- **Explicit instruction only**: Do not take any action unless explicitly instructed. Wait for clear direction before making changes, running commands, or modifying files.\n\n## Repository Overview\n\nFAST (`@microsoft/fast`) is a Microsoft open-source monorepo for building W3C-standards-compliant Web Components. The core package is `@microsoft/fast-element` — a lightweight, performant Web Component authoring library with a declarative HTML entrypoint. Additional packages provide routing plus declarative build and test tooling.\n\n## Packages\n\nEach package includes a DESIGN.md file, read that to gain a general understanding of the code for that package.\n\n| Package | Status | Purpose |\n|---|---|---|\n| `@microsoft/fast-element` | Stable (v2) | Core Web Component library, including declarative HTML via `@microsoft/fast-element/declarative.js` |\n| `@microsoft/fast-router` | Alpha | Web Component router |\n| `@microsoft/fast-build` | Prerelease | Declarative HTML server side renderer |\n| `@microsoft/fast-test-harness` | Prerelease | Testing utilities for FASTElement components |\n\n### Sites\n\n| Package | Status | Purpose |\n|---|---|---|\n| `sites/website` | Private (not published as a package) | Documentation website source |\n| `sites/benchmarks` | Private (not published as a package) | Benchmarking site |\n\n### Example projects\n\n- `examples/design-system/` — Shared semantic design tokens (`@microsoft/fast-examples-design-system`) consumed by all example apps.\n- `examples/csr/todo-app/` — A simple To-Do app demonstrating FAST usage patterns and using the shared `@microsoft/fast-examples-design-system` tokens.\n- `examples/csr/todo-mobx-app/` — A To-Do app demonstrating how to integrate MobX state with `@microsoft/fast-element` using a single `autorun` per component (no custom bridge code).\n- `examples/ssr/chat-app/` — A declarative FAST chat demo that pre-renders with `@microsoft/fast-build` and streams canned assistant replies into the transcript. Dark theme.\n- `examples/ssr/webui-todo-app/` — A To-Do app demonstrating FAST declarative HTML with `@microsoft/webui` prerendering and `@microsoft/fast-element/declarative.js` hydration. Light theme.\n\n## Skills\n\nThese contain domain-specific guidance. Read when performing related tasks:\n\n- [TypeScript](./skills/typescript/SKILL.md) — compiler constraints, import/export conventions, decorator usage, testing patterns.\n- [Rust](./skills/rust/SKILL.md) — general guidance on performing updates between the crate and package.\n- [Shipping](./skills/shipping/SKILL.md) — pull request format, change file generation, documentation updates.\n- [Pull Request](./skills/fast-pull-request/SKILL.md) — generate a pull request description from the branch diff.\n- [Bug Report](./skills/fast-bug-report/SKILL.md) — generate a bug report issue from conversation context.\n- [Feature Request](./skills/fast-feature-request/SKILL.md) — generate a feature request issue from conversation context.\n- [Testing](./skills/testing/SKILL.md) — running tests locally and in CI, writing Playwright fixture tests.\n- [Documentation](./skills/documentation/SKILL.md) — adding documentation in code, markdown files in each package/crate, and the website.\n\n## Commands\n\nRun all commands from the monorepo root. Use workspace flags to target a single package.\n\n| Task | Command |\n|---|---|\n| Install | `npm ci` |\n| Build all | `npm run build` |\n| Build one package | `npm run build -w @microsoft/fast-element` |\n| Test all | `npm run test` |\n| Test one package | `npm run test -w @microsoft/fast-element` |\n| Test Chromium only | `npm run test:chromium` |\n| Build/test changed only | `lage build --since origin/main` |\n| Test changed only | `lage test:node test:chromium --since origin/main` |\n| Lint | `npm run lint` |\n| Lint fix | `npm run lint:fix` |\n| Format check | `npm run format:check` |\n| Format fix | `npm run format` |\n| Check (lint + format + imports) | `npm run biome:check` |\n| Check fix | `npm run biome:fix` |\n| CI check (read-only) | `npm run biome:ci` |\n| Generate change file | `npm run change` |\n| Check change files | `npm run checkchange` |\n| API docs | `npm run doc -w @microsoft/fast-element` |\n\nBuild and test commands use [Lage](https://microsoft.github.io/lage/) for dependency-aware task execution. Lage respects the package dependency graph and can run incrementally with `--since <ref>` to only build/test changed packages and their dependents. The CI pipelines use `--since` for pull requests to skip unchanged packages.\n\nAll `lint`, `biome:check`, `biome:fix`, and `biome:ci` commands use `biome-changed`, which runs biome only on files with uncommitted git changes. The `format:check` and `format` commands use biome's own `--changed` flag to compare against the default branch.\n\n## Project Structure\n\n```\npackages/<package>/\n  src/                    # Source code\n    index.ts              # Main barrel (re-exports)\n    <feature>/            # Feature directories\n      <feature>.ts        # Implementation\n      <feature>.pw.spec.ts # Co-located Playwright test\n  test/                   # Test harness (Vite dev server, fixtures)\n  dist/                   # Build output (ESM + declarations)\n  docs/                   # API reports (api-extractor)\n  DESIGN.md               # Code documentation for the package or crate\n  README.md               # README for published package use\n```\n\n- Source files use **kebab-case**: `element-controller.ts`, `update-queue.ts`.\n- Playwright test files use `*.pw.spec.ts` suffix, co-located next to the source they test.\n- Node test files use `*.spec.ts` suffix.\n\n## Code Style\n\n### Formatting & Linting (Biome)\n\n- 90-character print width, 4-space indent, double quotes, trailing commas.\n- Single-arg arrow functions omit parens: `x => x + 1`.\n- Import ordering enforced via `organizeImports`.\n- No `I` prefix on interfaces.\n- `any` is permitted (`noExplicitAny: off`).\n- Config: [`biome.jsonc`](../biome.jsonc).\n\n### Naming Conventions\n\n| Element | Convention | Examples |\n|---|---|---|\n| Classes | PascalCase | `ElementController`, `FASTElementDefinition` |\n| Interfaces/Types | PascalCase, no `I` prefix | `Accessor`, `Disposable`, `Expression` |\n| Methods/functions | camelCase | `getValue()`, `handleChange()` |\n| Constants | PascalCase frozen objects or camelCase | `SourceLifetime`, `emptyArray` |\n| Private fields | `_` prefix | `_template`, `_shadowRootOptions` |\n| Files | kebab-case | `element-controller.ts`, `observer-map.ts` |\n| Change callbacks | `${prop}Changed` | `childChanged()`, `templateChanged()` |\n\n### TypeScript\n\nKey constraints (details in [TypeScript skill](./skills/typescript/SKILL.md)):\n\n- ESM only (`\"type\": \"module\"`) — imports use `.js` extensions.\n- `import type { ... }` required for type-only imports (`verbatimModuleSyntax`).\n- Named exports only — no default exports.\n- Legacy decorators enabled (`experimentalDecorators: true`).\n- `strictNullChecks` and `noImplicitAny` enabled.\n\n## Tooling\n\n| Tool | Purpose |\n|---|---|\n| npm workspaces | Package management |\n| Lage | Task runner — dependency-aware builds and incremental testing |\n| TypeScript | Compilation |\n| Rollup | Bundling (`fast-element` only) |\n| Playwright | Testing |\n| Vite | Test dev server |\n| api-extractor | API documentation + `.d.ts` rollup |\n| beachball | Change files, versioning, publishing |\n| Biome | Formatting + Linting |\n| lefthook | Pre-commit hooks (runs `biome:check` and `checkchange` on staged files) |\n| Rust | Rendering Declarative templates (`fast-build` package and `microsoft-fast-build` crate only) |\n\n## Acceptance Checklist\n\nBefore finishing any change, run these commands from the monorepo root and confirm they pass:\n\n- [ ] `npm run build` — all packages build successfully\n- [ ] `npm run test` — all tests pass\n- [ ] `npm run biome:check` — Biome linting and formatting pass\n- [ ] `npm run checkchange` — beachball change files exist for any `packages/*` changes\n\nRead the [shipping skill](./skills/shipping/SKILL.md) and ensure you have updated everything outlined in that file.\n",".github/skills/documentation/SKILL.md":"---\nname: documentation\ndescription: Add documentation for contributors and developers.\n---\n\nDocumentation exists in 3 forms, code comments, design/architectural documentation that is made up of markdown files describing code flow and core concepts (such as DESIGN.md), and the documentation website.\n\nDesign/architectural documentation such as DESIGN.md should always be kept up-to-date.\n\nThe website captures the documentation primarily for the `@microsoft/fast-element` package. Other packages are treated as tangential, so testing packages or other utilities should have their own sections.\n\nThe website has been written in 11ty and primarily consists of markdown files. When making changes, ensure that the website has been scanned on whichever latest major version is available. These are organized by folder, so if 1.x/2.x/3.x folders are available, you will update the documentation in the 3.x folder.\n\nIf you are making a breaking change, ensure the migration document has been updated.\n\nAll markdown documentation aside from the package/crate level DESIGN.md files are in that package/crates docs folder.\n\nAny documentation created for the website should be written with the developer implementing the package in mind, it is not intended for other audiences.\n",".github/skills/fast-bug-report/SKILL.md":"---\nname: fast-bug-report\ndescription: Generate a bug report issue for the FAST repository using the provided template.\n---\nThis prompt only applies to generating Bug Report issues for the FAST repository.\n\nDo not create or modify any existing Github issues. This skill is only for\ngenerating the markdown content for a new issue based on the provided template.\n\nBased on the conversation context, generate a bug report as a markdown code\nblock using the template located at\n[../../ISSUE_TEMPLATE/bug-report.md](../../ISSUE_TEMPLATE/bug-report.md).\n\nThe summary should clearly state what the bug is and which part of the system\nis affected.\n\nRepro or Code Sample should provide clear, minimal steps to reproduce the issue.\nInclude a code snippet, repository link, or gist if possible.\n\nExpected Behavior should describe what the correct behavior should be.\n\nCurrent Behavior should explain what actually happens instead. Include the full\nerror message and stack trace if applicable. Mention screenshots if they would\nhelp illustrate the problem.\n\nPossible Solution is optional. Include it only if there is a concrete idea about\nthe cause or fix. Mention if the reporter is willing to contribute a fix.\n\nContext should explain how the bug affects the user and what they are trying to\naccomplish. This helps prioritize and design the right solution.\n\nYour Environment should capture relevant details: OS, device, browser, and\npackage version.\n\nSearch for existing open or closed issues that overlap with this bug report.\nIf duplicates or related issues exist, mention them in the Context section.\n\nSuggest a concise issue title in the format `fix: [what is the issue?] in [where is the issue?]`.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nAny comments in the template can be removed since they're only meant to provide\nguidance on how to fill out the template, and are not intended to be part of the\nfinal issue body.\n",".github/skills/fast-feature-request/SKILL.md":"---\nname: fast-feature-request\ndescription: Generate a feature request issue for the FAST repository using the provided template.\n---\nThis prompt only applies to generating Feature Request issues for the FAST repository.\n\nDo not create or modify any existing Github issues. This skill is only for\ngenerating the markdown content for a new issue based on the provided template.\n\nBased on the conversation context, generate a feature request as a markdown code\nblock using the template located at\n[../../ISSUE_TEMPLATE/feature-request.md](../../ISSUE_TEMPLATE/feature-request.md).\n\nThe summary should clearly state what the feature is and why it matters, focusing\non user value rather than implementation details.\n\nExpected Behavior should describe how the feature would work from an end-user or\ndeveloper perspective. Be specific about the desired outcome.\n\nCurrent Behavior should explain the gap — what exists today and how the absence of\nthis feature affects users. If there is a workaround, mention it briefly.\n\nPossible Solution is optional. Include it only if there is a concrete implementation\nidea worth capturing. Prefer high-level direction over prescriptive code.\n\nContext should explain the motivation — what the user is trying to accomplish\nand why this feature would help. Mention alternatives that were considered, if any.\n\nExamples is optional. Include it when code snippets, screenshots, or usage\nscenarios would clarify the request.\n\nSearch for existing open or closed issues that overlap with this feature request.\nIf duplicates or related issues exist, mention them in the Context section.\n\nSuggest a concise issue title in the format `feat: add [what] to/in [where]`.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nAny comments in the template can be removed since they're only meant to provide\nguidance on how to fill out the template, and are not intended to be part of the\nfinal issue body.\n",".github/skills/fast-pull-request/SKILL.md":"---\nname: fast-pull-request\ndescription: Generate a pull request description for the FAST repository using the provided template.\n---\nThis skill only applies to generating Pull Request descriptions for the FAST repository.\n\nDo not create or modify any existing Github pull requests. This skill is only for\ngenerating the markdown content for a pull request description based on the provided template.\n\nBased on the conversation context, generate a pull request description as a markdown code\nblock using the template located at\n[../../pull_request_template.md](../../pull_request_template.md).\n\nUse the Pull Request Template to generate a markdown code block for the most\nrelevant work on this git branch, compared to `main`.\n\nThe Description should be either a summary description of the content of the branch,\nor a list of the most relevant changes made in the branch. The goal is to address\nthe purpose of the pull request in a concise manner, rather than detailing every change. \"Why\"\nand \"what\" over \"how\".\n\nDetermine if any current github issues are being addressed by this work, and\nlist them in the Issues section with links. If none are found, remove the Issues section.\n\nThe reviewer notes section is optional. Include it only if there are specific\nareas where you would like feedback or attention from the reviewer.\n\nThe Test Plan section should outline any issues that need to be verified before merging,\nor steps to reproduce the behavior locally. Even a brief note is helpful, such as \"All existing tests pass\".\n\nThe checklist section should be completed to indicate the status of various\naspects of the pull request.\n\nIf there are change files that have been added to the PR, check the box labeled \"I have included a change request file using `$ npm run change`\".\n\nIf any new tests have been added, check the box labeled \"I have added tests for my changes.\"\n\nCheck the terminal output for evidence of passing tests, and check the box labeled \"I have tested my changes.\" if tests have been run and are passing. If not, leave the box unchecked.\n\nIf any doc blocks have been added or modified, or if any documentation files have been added or modified, check the box labeled \"I have updated the project documentation to reflect my changes.\" This also applies to any changes made to api-report files.\n\nThe final checkbox must be checked by the pull request author. It should never be checked when generating this PR description.\n\nThe Next Steps section is optional. Include it only if there are specific follow-up tasks\nor work items that should be addressed after merging this PR, such as updating documentation, adding new tests, or performing code cleanup. If any existing issues are being addressed by the next steps, reference them here.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nAny comments in the template can be removed since they're only meant to provide\nguidance on how to fill out the template, and are not intended to be part of the\nfinal PR description.\n",".github/skills/rust/SKILL.md":"---\ndescription: Use this guide when working on Rust changes in the FAST monorepo.\nname: rust\n---\n\n# Working with the Rust crate and the Rust NodeJS CLI\n\nThe primary location for the Rust logic should exist within a crate. If the logic is made accessible in the NodeJS environment via wrapping the crate and using a wasm bindgen, as much as possible any logic that exists in Rust should not be duplicated in JavaScript/TypeScript.\n\n## Breaking changes\n\nUnderstand [semver](https://semver.org/) and check the crate and package version. If the version is currently in a prerelease state, update the APIs with breaking changes as necessary and ensure that any generated pull request descriptions capture this.\n",".github/skills/shipping/SKILL.md":"---\ndescription: Use this skill when contributing changes to the FAST monorepo — creating pull requests, generating change files, writing PR descriptions, and keeping documentation up to date.\nname: shipping\n---\n\n# Shipping Patterns for FAST\n\nUse this guide when shipping changes in the FAST monorepo — writing PR descriptions, generating change files, and keeping documentation up to date.\n\n# Guardrails\n\nDo NOT perform any of the following actions autonomously. These require explicit human action:\n\n- **Do not merge or close pull requests** — no `gh pr merge`, `gh pr close`, or equivalent.\n- **Do not publish packages** — no `npm publish`, `beachball publish`, or release operations.\n- **Do not modify branch protection or repository settings**.\n\n## Key references\n\nRead these documents for additional context when needed:\n\n- [`.github/pull_request_template.md`](../../pull_request_template.md) — PR description template (source of truth for PR structure).\n- [`CONTRIBUTING.md`](../../../CONTRIBUTING.md) — Full contributor guide (machine setup, branching, governance).\n- [`BRANCH_GUIDE.md`](../../../BRANCH_GUIDE.md) — Branch management conventions.\n- [`beachball.config.js`](../../../beachball.config.js) — Beachball configuration (ignored patterns, publish settings).\n- [`CODE_OF_CONDUCT.md`](../../../CODE_OF_CONDUCT.md) — Community standards.\n\n### Package/Crate references\n\nRead these documents, they are located at the root of the specific package or crate, e.g. `packages/<package>/<file>.md` and relate to the package/crates they are located in. When making changes in the package/crate afterwards update these files if necessary.\n\n- `DESIGN.md` - Explains the code patterns.\n- `README.md` - Explains how a developer/agent would use this package/crate.\n\n# Commit and PR title conventions\n\nUse [conventional commit](https://www.conventionalcommits.org/) format for PR titles and merge commit messages:\n\n```\n<type>: <short summary>\n```\n\nCommon types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`.\n\nExamples:\n- `feat: add shadow DOM support to declarative templates`\n- `fix: resolve memory leak in template binding`\n- `chore: update dev dependencies`\n\n# Pull requests\n\nUse the repository's PR template at [`.github/pull_request_template.md`](../../pull_request_template.md) as the basis for all pull request descriptions.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nThe comments in the template can be removed since they're only meant to provide guidance on how to fill out the template, and are not intended to be part of the final PR description.\n\nFill out each section as detailed below.\n\n## Description\n\nThe Description should be either a summary description of the content of the branch,\nor a list of the most relevant changes made in the branch. The goal is to address\nthe purpose of the pull request in a concise manner, rather than detailing every change. \"Why\"\nand \"what\" over \"how\".\n\n## Issues\n\nDetermine if any current github issues are being addressed by this work, and\nlist them in the Issues section with links. If none are found, remove the Issues section.\n\n## Reviewer Notes\n\nThe reviewer notes section is optional. Include it only if there are specific\nareas where you would like feedback or attention from the reviewer.\n\n## Test Plan\n\nThe Test Plan section should outline any issues that need to be verified before merging,\nor steps to reproduce the behavior locally. Even a brief note is helpful, such as \"All existing tests pass\".\n\n## Checklist\n\nThe checklist section should be completed to indicate the status of various\naspects of the pull request.\n\nIf there are change files that have been added to the PR, check the box labeled \"I have included a change request file using `$ npm run change`\".\n\nIf any new tests have been added, check the box labeled \"I have added tests for my changes.\"\n\nCheck the terminal output for evidence of passing tests, and check the box labeled \"I have tested my changes.\" if tests have been run and are passing. If not, leave the box unchecked.\n\nIf any doc blocks have been added or modified, or if any documentation files have been added or modified, check the box labeled \"I have updated the project documentation to reflect my changes.\" This also applies to any changes made to api-report files.\n\nThe final checkbox must be checked by the pull request author. It should never be checked when generating this PR description.\n\n## Next Steps\n\nThe Next Steps section is optional. Include it only if there are specific follow-up tasks\nor work items that should be addressed after merging this PR, such as updating documentation, adding new tests, or performing code cleanup. If any existing issues are being addressed by the next steps, reference them here.\n\n# Acceptance checklist\n\nBefore making a change, if the change is addressing a bug make sure you write a test first and ensure that it is failing:\n\n```bash\nnpm run build            # all packages build successfully\nnpm run test             # test fails\n```\n\nBefore finishing any change, run these commands from the monorepo root and confirm they pass:\n\n```bash\nnpm run build            # all packages build successfully\nnpm run test             # all tests pass\nnpm run format:check     # Prettier formatting is correct\nnpm run checkchange      # Beachball change files exist for packages/* changes\n```\n\n# Change files\n\nAfter completing a change to any package under `packages/`, generate a Beachball change file:\n\n```bash\n# This should be run from the monorepo root\nnpm run change\n```\n\nThis walks through the steps to create a change description file that is required for versioning and publishing. The CI gate `npm run checkchange` will fail if a change file is missing for a modified package.\n\n## Change comments\n\nWrite the `comment` field as release-note text, not as a commit message. Use a\nconcise sentence that starts with a capital letter and ends with a period. Do not\nprefix comments with conventional commit types such as `fix:`, `feat:`, or\n`chore:`.\n\nBeachball uses change-file comments to generate package changelogs and release\nnotes. Sentence-style comments read cleanly in those user-facing outputs, while\ncommit-style prefixes duplicate the separate change type metadata and add noise.\n\n## Change types\n\nWhen prompted, select the appropriate change type:\n\n| Type | When to use |\n|---|---|\n| `major` | Breaking changes to public API |\n| `minor` | New features, non-breaking additions |\n| `patch` | Bug fixes, minor corrections |\n| `none` | Changes that don't affect the published package (tests, docs, tooling) |\n\n## When change files are NOT required\n\nThe Beachball config ([`beachball.config.js`](../../../beachball.config.js)) ignores these paths — changes limited to them do not need change files:\n\n- `.github/` — CI configs, templates, skills\n- Test files (`src/e2e/`, `src/tests/`, `src/fixtures/`)\n- `package-lock.json`\n- `.vscode/`, `.prettierrc`\n\nAdditionally, [`build/scripts/checkchange.mjs`](../../../build/scripts/checkchange.mjs) (which wraps `beachball check` for the `checkchange` npm script) skips the check entirely on **manual version bump** branches authored by a repo admin. Specifically, both of the following must be true for the current run:\n\n1. Branch name matches `^publish_\\d+$` (beachball's documented publish-branch convention).\n2. The actor (`$GITHUB_ACTOR` in CI; locally, the user from `gh api user`) has the `admin` role on `microsoft/fast`, verified via the GitHub REST API.\n\nIf either condition fails, the change-file requirement applies as before. See [`CONTRIBUTING.md` > Manual version bumps](../../../CONTRIBUTING.md#manual-version-bumps) for the full rationale and reviewer expectations.\n\n## Cross-branch targeting\n\nWhen working across feature branches, target the branch explicitly:\n\n```bash\nnpm run change -- --branch origin/{branch-name}\n```\n\n## Multiple unrelated changes\n\nIf addressing multiple unrelated issues, prefer separate pull requests.\n\n# Breaking changes\n\nWhen introducing breaking changes:\n\n1. Select `major` as the change type when running `npm run change`.\n2. Document the migration strategy in `packages/<package>/docs/migration/<migration-name>.md`.\n\nFormat for a migration document:\n\n```md\n# Migrating from previous versions\n\n## v1 to v2\n\n- Export `Foo` has been renamed to `Bar`.\n- `Bat` has been updated to use the new API [`BatConfig`](link/to/api).\n```\n\nIf the breaking change is significant or requires multiple PRs, open a [discussion](https://github.com/microsoft/fast/discussions) first.\n\n# Documentation\n\nAfter any changes ensure that the documentation is up to date, this includes the files DESIGN.md and README.md files for any packages/crates that have been modified. If your changes update or add to the public API, update the sites/website/src/docs/ files. Only update the latest version, these are denoted by major versions in their folder names inside the docs folder, 1.x, 2.x, etc., find the latest version of the docs and modify them if necessary.\n\nWhen adding or modifying exported APIs, run the website prebuild script to regenerate API documentation from the api-extractor output:\n\n```bash\nnpm run prebuild -w sites/website\n```\n\nThis runs [`sites/website/scripts/generate-docs.cjs`](../../../sites/website/scripts/generate-docs.cjs), which copies API documentation from each package's extracted API reports into the website source. Run this after building packages to ensure generated documentation stays in sync with the codebase.\n",".github/skills/testing/SKILL.md":"---\nname: testing\ndescription: Use this skill when running or writing tests in the FAST monorepo — local test execution, CI workflows, Playwright fixtures, and WebUI integration testing.\n---\n\n# Testing Patterns for FAST\n\nUse this guide when running or writing tests in the FAST monorepo. FAST uses [Playwright](https://playwright.dev/) for integration testing with a [Vite](https://vitejs.dev/) dev server.\n\n## Running tests\n\n### Locally\n\n#### First-time setup\n\nAfter cloning and installing dependencies (`npm ci`), install Playwright browsers:\n\n```bash\nnpx playwright install --with-deps\n```\n\n#### Commands\n\nAll commands are run from the **monorepo root**. Use `-w` to target a specific package.\n\n| Task | Command |\n|---|---|\n| Run all tests (all browsers) | `npm run test` |\n| Run all tests (Chromium only) | `npm run test:chromium` |\n| Test a single package (all browsers) | `npm run test -w @microsoft/fast-element` |\n| Test a single package (Chromium only) | `npm run test:chromium -w @microsoft/fast-element` |\n| Test changed packages only | `npx lage test:node test:chromium --since origin/main` |\n\n#### Interactive / debug workflows\n\nFor FAST declarative tests in `@microsoft/fast-element`, these additional scripts are available:\n\n| Task | Command |\n|---|---|\n| Playwright UI mode | `npm run test:ui:declarative -w @microsoft/fast-element` |\n| Start declarative source server | `npm run test-server:declarative -w @microsoft/fast-element` |\n| Rebuild fixtures | `npm run build:fixtures -w @microsoft/fast-element` |\n| Build fixtures with webui | `npm run build:fixtures:webui -w @microsoft/fast-element` |\n| Run webui integration tests | `npm run test:webui-integration -w @microsoft/fast-element` |\n\n**Playwright UI mode** (`test:ui`) starts a visual test runner where you can select and debug individual tests, view traces, and inspect DOM snapshots.\n\n**Declarative browser workflows** resolve `@microsoft/fast-element` package imports directly to `src` and let Vite transpile TypeScript on demand. Vite does not type-check these modules; the package build remains responsible for type checking, while `test:exports` imports every emitted package export.\n\n### Through GitHub Actions\n\nThe repository uses several CI workflows to validate changes.\n\n#### PR validation (ci-validate-pr.yml)\n\nRuns on every pull request targeting `main`, `releases/*`, or `features/*` branches. Tests run on **Ubuntu with Chromium only** for fast feedback.\n\nKey steps:\n- Checks for change files (`npm run checkchange`)\n- Biome lint/format check\n- Builds affected packages (incremental with `--since`)\n- Runs `test:node` and `test:chromium` for affected packages\n\n#### Cross-platform validation (ci-validate-platforms.yml)\n\nRuns on pushes to `main`, PRs targeting `main`, and on a weekly schedule. Tests run on **Ubuntu, Windows, and macOS** with **Chromium, Firefox, and Safari**.\n\nThis ensures cross-platform and cross-browser compatibility.\n\n#### WebUI integration testing (ci-webui-integration.yml)\n\nA dedicated workflow for validating FAST's integration with `@microsoft/webui`. This workflow runs on:\n\n- **Manual dispatch** (`workflow_dispatch`)\n- **Pushes to `webui/*` branches**\n\n> **Note:** This workflow does _not_ run on regular pull requests. It is scoped to `webui/*` branches to test integration changes in isolation before they land on `main`.\n\nThe workflow builds all packages, installs Playwright Chromium, and runs:\n\n```bash\nnpm run test:webui-integration -w @microsoft/fast-element\n```\n\nThis builds each fixture with `webui build --plugin=fast`, renders the protocol with the fixture's `state.json`, and runs the same Playwright specs against the webui-rendered output.\n\nTo trigger WebUI integration tests for your changes:\n\n1. Create a branch with the `webui/` prefix (e.g., `webui/my-integration-change`).\n2. Push the branch — the workflow runs automatically.\n3. Alternatively, trigger the workflow manually from the Actions tab using `workflow_dispatch`.\n\n#### Azure Pipelines (azure-pipelines-ci.yml)\n\nThe repository also has an Azure DevOps pipeline that runs on PRs to `main`. This pipeline runs in a 1ES-managed environment and includes SDL compliance checks in addition to building and testing.\n\n## Writing tests\n\nFAST tests are [Playwright](https://playwright.dev/) integration tests that run against fixture pages served by Vite.\n\n### Test file conventions\n\n- Test files use the `*.spec.ts` suffix (specifically `*.pw.spec.ts` for package `src/` tests).\n- Tests for developer-authored declarative markup and directives live in the matching\n  `test/declarative/fixtures/<category>/<feature>/<feature>.spec.ts` fixture.\n- Tests for implementation APIs and lifecycle behavior are co-located with their source as\n  `src/<feature>/<feature>.pw.spec.ts`.\n\n### Writing declarative fixture tests\n\nFixture tests in `@microsoft/fast-element/test/declarative/fixtures` are the primary way to verify declarative template features. Each fixture is a self-contained test case with its own HTML, state, templates, and component definitions.\n\nWhen changing declarative syntax, directive parsing, template generation, hydration behavior, or other user-authored template behavior, add or update a declarative fixture and exercise it in browser. Source-level parser tests may supplement narrow parsing edge cases, but they should not be the only coverage for syntax that users write in `entry.html` or `templates.html`. Use the local README files under `packages/fast-element/test/declarative/fixtures/` and each fixture category to choose the right fixture type and follow category-specific examples.\n\nFor a complete guide on creating fixtures — including how to write `entry.html`, `state.json`, `templates.html`, `main.ts`, and spec files — see:\n\n📄 **[Writing Fixtures](../../../packages/fast-element/test/declarative/fixtures/WRITING_FIXTURES.md)**\n\n### Quick example\n\n```typescript\nimport { expect, test } from \"@playwright/test\";\n\ntest.describe(\"my-feature\", async () => {\n    test(\"renders correctly\", async ({ page }) => {\n        await page.goto(\"/fixtures/bindings/my-feature/\");\n\n        const element = page.locator(\"my-element\");\n        await expect(element).toHaveText(\"Hello\");\n    });\n});\n```\n",".github/skills/typescript/SKILL.md":"---\ndescription: Use this guide when working on TypeScript changes in the FAST monorepo — authoring Web Components, writing templates and styles, working with the observable/reactive system, and testing.\nname: typescript\n---\n\n# TypeScript Patterns for FAST\n\n## Modules\n\n`fast-element` enables `verbatimModuleSyntax`, so type-only imports must use `import type`\nor the inline `type` qualifier:\n\n```ts\nimport type { Notifier, Subscriber } from \"./notifier.js\";\nimport { type Constructable, isFunction } from \"../interfaces.js\";\n```\n\nSub-entry-points expose focused APIs through the `exports` map:\n\n```ts\nimport { twoWay } from \"@microsoft/fast-element/two-way.js\";\nimport { reactive } from \"@microsoft/fast-element/state.js\";\n```\n\nThe barrel `index.ts` explicitly lists every re-export grouped by subsystem — no\n`export *` statements.\n\nAside from the `index.ts` or `index.*.ts` files there should be no barrel exports.\n\n## Side Effects\n\nDo not add side effectful code and do not add `sideEffects` to `package.json` files.\nAPIs added should import named exports.\n\n## Browser APIs\n\n### Do not use\n\nOur stance as a framework library is that certain browser APIs are best avoided by\nthe framework. We may facilitate the use of them through our provided APIs.\n\nList of APIs to avoid implementing in FAST packages:\n- `requestIdleCallback`\n- `setTimeout`\n- `setInterval`\n\n### Avoid\n\nSome browser APIs can be used but should be avoided as a developer may encounter\nedge cases with task queuing or other logic their app is executing.\n\nList of APIs to avoid in FAST packages:\n- `requestAnimationFrame`\n- `queueMicrotask`\n\n## Custom elements\n\nElements extend `FASTElement`. Do **not** use the `@customElement` decorator.\n\nUse `define()` for registration. `define()` returns a `Promise` that resolves\nimmediately when a template is provided:\n\nExample define.ts (side-effect import):\n```ts\nexport class MyElement extends FASTElement {\n    @observable items: string[] = [];\n}\n\nawait MyElement.define({\n    name: \"my-element\",\n    template,\n    styles,\n});\n```\n\n## Templates\n\nTemplates use the `html` tagged template literal typed to the element class:\n\n```ts\nimport { html } from \"@microsoft/fast-element/html.js\";\nimport { repeat } from \"@microsoft/fast-element/repeat.js\";\nimport { when } from \"@microsoft/fast-element/when.js\";\nimport type { MyElement } from \"./my-element.js\";\n\nexport const template = html<MyElement>`\n    <h1>${x => x.title}</h1>\n    ${when(x => x.showList, html<MyElement>`\n        <ul>\n            ${repeat(\n                x => x.items,\n                html<string>`<li>${x => x}</li>`\n            )}\n        </ul>\n    `)}\n`;\n```\n\n### Binding syntax\n\n| Prefix | Purpose | Example |\n|---|---|---|\n| `${x => ...}` | Content or attribute | `${x => x.name}` |\n| `@event` | Event listener | `@click=${x => x.handleClick()}` |\n| `@event` | Event with context | `@click=${(x, c) => c.parent.remove(x)}` |\n| `:prop` | DOM property | `:value=${twoWay(x => x.description)}` |\n| `?attr` | Boolean attribute | `?disabled=${x => !x.isValid}` |\n\nTwo-way bindings require a sub-entry-point import:\n\n```ts\nimport { twoWay } from \"@microsoft/fast-element/two-way.js\";\n```\n\n### Partial HTML\n\nUse `html.partial()` to inject pre-built HTML strings into a template without creating\na full `ViewTemplate`:\n\n```ts\nhtml<MyElement>`\n    <div>${html.partial(\"<span>static markup</span>\")}</div>\n`;\n```\n\n## Styles\n\nStyles use the `css` tagged template literal. They attach through the element definition's\n`styles` property:\n\n```ts\nimport { css } from \"@microsoft/fast-element/css.js\";\n\nexport const styles = css`\n    :host {\n        display: block;\n        padding: 16px;\n    }\n`;\n```\n\nFor declarative HTML definitions, styles live in a separate `.styles.css` file linked from\nboth the initial shadow root template and the `<f-template>`:\n\n```html\n<f-template name=\"my-element\">\n    <template>\n        <link rel=\"stylesheet\" href=\"./my-element.styles.css\">\n    </template>\n</f-template>\n```\n\n`css.partial()` works the same way as `html.partial()` — injecting raw CSS strings.\n\n## Reactivity\n\n`@attr` maps HTML attributes to properties. `@observable` creates reactive properties\ntracked by templates. `@volatile` marks getters whose dependencies change between calls:\n\n```ts\nimport { FASTElement } from \"@microsoft/fast-element/fast-element.js\";\nimport { attr, nullableNumberConverter } from \"@microsoft/fast-element/attr.js\";\nimport { Observable, observable } from \"@microsoft/fast-element/observable.js\";\nimport { volatile } from \"@microsoft/fast-element/volatile.js\";\n\nclass MyElement extends FASTElement {\n    @attr label?: string;\n    @attr({ mode: \"boolean\" }) active?: boolean;\n    @attr({ converter: nullableNumberConverter }) count?: number;\n\n    @observable private _items: string[] = [];\n\n    // Convention: ${propertyName}Changed\n    labelChanged(prev: string | undefined, next: string | undefined) {}\n\n    @volatile\n    get sortedItems(): readonly string[] {\n        return [...this._items].sort();\n    }\n}\n```\n\nNotify the system after in-place mutations that it cannot detect automatically:\n\n```ts\nthis._items.splice(index, 1);\nObservable.notify(this, \"_items\");\n```\n\nMake plain objects observable via the state sub-entry-point:\n\n```ts\nimport { reactive } from \"@microsoft/fast-element/state.js\";\nconst todo = reactive({ description: \"Buy milk\", done: false });\n```\n\n## Testing\n\nTests use Playwright Test (`*.pw.spec.ts`) and combine two patterns within the same file.\n\n### Direct-import tests\n\nFor logic that does not need browser APIs — the test callback takes no parameters:\n\n```ts\nimport { expect, test } from \"@playwright/test\";\nimport { Observable } from \"./observable.js\";\n\ntest.describe(\"Observable\", () => {\n    test(\"can get a notifier\", () => {\n        const notifier = Observable.getNotifier(new Model());\n        expect(notifier).toBeInstanceOf(PropertyChangeNotifier);\n    });\n});\n```\n\n### Browser-evaluated tests\n\nFor tests requiring DOM APIs, navigate to the Vite dev server and import via\n`\"/main.js\"`. The `@ts-expect-error` comment is required because TypeScript cannot\nresolve the URL-based import:\n\n```ts\ntest(\"renders element\", async ({ page }) => {\n    await page.goto(\"/\");\n\n    const result = await page.evaluate(async () => {\n        // @ts-expect-error: Client module.\n        const { FASTElement, html, uniqueElementName } = await import(\"/main.js\");\n        // ... test logic ...\n        return someSerializableValue;\n    });\n\n    expect(result).toBe(expected);\n});\n```\n\nOnly serializable values can cross the `page.evaluate` boundary — run `expect()`\nassertions outside it on the returned data.\n\nThe test harness at `packages/<package>/test/main.ts` re-exports source modules for\nbrowser tests. When adding new package exports, add them there too.\n\n## TypeScript idioms\n\n### Const-type merging for enumerations\n\nFrozen const objects paired with a type extracted from their values replace TypeScript\n`enum`:\n\n```ts\nexport const SourceLifetime = {\n    default: undefined,\n    couple: 1,\n} as const;\n\nexport type SourceLifetime =\n    (typeof SourceLifetime)[keyof typeof SourceLifetime];\n```\n\n### Interface-const merging\n\n`FASTElement` is both an interface (instance shape) and a const (constructor). Static\nmethods use `typeof` to carry overloaded signatures:\n\n```ts\nexport const FASTElement: {\n    new (): FASTElement;\n    define: typeof define;\n} = Object.assign(createFASTElement(HTMLElement), { define });\n```\n\n### Tagged template intersection types\n\n`html` and `css` are typed as intersections of a tagged template function and a\n`.partial()` method:\n\n```ts\ntype HTMLTemplateTag = (<TSource, TParent>(\n    strings: TemplateStringsArray,\n    ...values: TemplateValue<TSource, TParent>[]\n) => ViewTemplate<TSource, TParent>) & {\n    partial(html: string): InlineTemplateDirective;\n};\n```\n","packages/README.md":"# FAST Packages\n\nOur web component packages.\n\n## `@microsoft/fast-element`\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-element.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-element)\n\nThe `@microsoft/fast-element` library is a lightweight means to easily build performant, memory-efficient, standards-compliant Web Components. FAST Elements work in every major browser and can be used in combination with any front-end framework or even without a framework. To get up and running with `@microsoft/fast-element` see [the Getting Started guide](https://fast.design/docs/getting-started/quick-start).\n\n## `@microsoft/fast-router`\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-foundation.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-router)\n\nThe `@microsoft/fast-router` package contains a history-based navigation and routing solution designed around Web Components. By using `fast-router`, you can create multi-page and full application experiences. The router works with any Web Components, but has special support for Web Components built on FAST.","packages/fast-build/README.md":"# FAST Build\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-build.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-build)\n\nThe `fast-build` package renders the declarative HTML template syntax of [`@microsoft/fast-element`](https://www.npmjs.com/package/@microsoft/fast-element), primarily for use in testing environments. It is powered by a WebAssembly core with zero runtime npm dependencies.\n\n> **Note:** For production server-side rendering, we recommend using the [`@microsoft/webui`](https://github.com/microsoft/webui) project instead.\n\n## Installation\n\n### From NPM\n\nTo install the latest `@microsoft/fast-build` package using `npm`:\n\n```shell\nnpm install --save @microsoft/fast-build\n```\n\nWithin your JavaScript or TypeScript code, you can then import library APIs like this:\n\n```ts\nimport { render } from '@microsoft/fast-build';\n```\n\n## CLI usage\n\nOnce installed, the `fast` binary is available. Use the `build` subcommand to render an HTML template with an optional JSON state file, or `convert` to convert a FAST declarative HTML template to another supported syntax:\n\n```shell\nfast build [options]\nfast convert [options]\n```\n\n### Build options\n\n| Option | Default | Description |\n|---|---|---|\n| `--entry=\"<path>\"` | `index.html` | Entry HTML template to render |\n| `--state=\"<path>\"` | `{}` when omitted | JSON file containing the template state. If omitted, no state file is loaded and rendering uses an empty state object. If `--state` is provided, the file must exist. |\n| `--output=\"<path>\"` | `output.html` | Where to write the rendered HTML |\n| `--templates=\"<glob>\"` | _(none)_ | Glob pattern(s) for custom element template HTML files. Separate multiple patterns with commas. A warning is printed if not provided in non-streaming mode or if no files match a pattern. |\n| `--attribute-name-strategy=\"<strategy>\"` | `camelCase` | Strategy for mapping HTML attribute names to state property names on custom elements. `\"camelCase\"` converts dashes to camelCase (e.g. `foo-bar` → `fooBar`). `\"none\"` preserves dashes (e.g. `foo-bar` → `foo-bar`). See [Attribute name strategy](#attribute-name-strategy). |\n| `--markers_v2[=true/false]` | `false` | Emit FAST Element 2.x indexed hydration markers instead of the default FAST Element 3.x data-free markers. |\n| `--config=\"<path>\"` | `fast-build.config.json` | Path to a JSON configuration file. If omitted, `fast-build.config.json` in the current directory is used when present. CLI arguments take precedence over config values. See [Configuration file](#configuration-file). |\n| `--stream[=true/false]` | `false` | Write rendered HTML chunks directly to stdout instead of writing `--output`. Valueless `--stream` is treated as `true`. |\n\n### Example\n\nGiven an `index.html`:\n\n```html\n<html>\n  <body>\n    <h1>{{title}}</h1>\n    <p>{{description}}</p>\n  </body>\n</html>\n```\n\nAnd a `state.json`:\n\n```json\n{\n  \"title\": \"Hello FAST\",\n  \"description\": \"Server-side rendered with WebAssembly.\"\n}\n```\n\nRun:\n\n```shell\nfast build --entry=index.html --state=state.json --output=output.html\n```\n\nProduces `output.html`:\n\n```html\n<html>\n  <body>\n    <h1>Hello FAST</h1>\n    <p>Server-side rendered with WebAssembly.</p>\n  </body>\n</html>\n```\n\n### Streaming output\n\nPass `--stream`, `--stream=true`, or `--stream=false`, or set\n`\"stream\": true` in `fast-build.config.json`, to control stdout streaming. When\nstreaming is enabled, the CLI writes raw rendered HTML chunks to stdout, does\nnot write the `--output` file, and does not print the normal `Built: ...`\nmessage.\n\n```shell\nfast build --entry=index.html --state=state.json --stream\n```\n\nStreaming is simulated by the WebAssembly renderer: chunks are prepared in\nmemory, returned to JavaScript as a JSON array, parsed by the CLI, and then\nwritten to stdout. `--stream` uses the same entry renderer with its stream flag\nenabled and passes an empty templates map when no `--templates` glob is\nprovided. Chunk boundaries are safe for HTML parsing:\n\n- Attribute bindings stay within complete opening tag chunks.\n- Custom element opening chunks include the complete Declarative Shadow DOM\n  template.\n- Streamed output uses the same renderer preprocessing and custom-element host\n  attribute propagation as normal output.\n- Empty chunks are omitted.\n- Concatenating all chunks matches the normal non-streamed render.\n\n### Performance benchmarks for contributors\n\nThe renderer discovers tags and bindings in a forward scan, eliminating repeated\nremaining-suffix searches for adjacent custom elements and plain tags. Existing\nWASM exports, rendered bytes, default markers, and `markers_v2` remain compatible.\nRendering is still synchronous, and `--stream` still buffers all chunks in WASM.\n\nFrom a FAST repository checkout, not an installed npm package:\n\n```shell\nnpm run build -w @microsoft/fast-build\nnpm run bench:render -w @microsoft/fast-build -- --case=url_sink_siblings --output=/tmp/fast-render.json\nnpm run bench:render -w @microsoft/fast-build -- --case=url_sink_siblings --check-scaling\n```\n\nThe runner benchmarks the actual packaged WASM in fresh child processes in both\nmarker modes, recording timing, CPU, output hashes, throughput, and peak RSS.\nUse `--case`, `--counts`, `--samples`, or `--compare=<baseline.json>` to narrow\nor compare a run. Output files are never overwritten. Normal tests verify the\nsame fixtures against pre-optimization hashes without flaky timing thresholds.\nSee the [benchmark guide](../../crates/microsoft-fast-build/benchmark-baselines/README.md)\nfor native Criterion benchmarks, fixture sizes, methodology, and limitations.\n\nThe guide includes post-scanner repeat/state-heavy and many-definition profiles.\nStart expensive repeat cases with `--counts=250,1000 --warmup-count=250`;\nstate-overlay controls and separate native phases help identify the next\noptimization without running an unbounded matrix. Native CPU samples are not\nWASM allocation measurements, and no production rendering behavior is changed.\n\nThe guide also includes an opt-in native allocation baseline and a fresh-process\nmatrix command: `node crates/microsoft-fast-build/benches/profile-allocations.mjs\n--output=/tmp/fast-allocations.json` from the repository root. Its counters are\ndevelopment-only Rust tooling, not part of the npm CLI or WASM; native peak\nnewly-live heap is not process RSS.\n\n### Missing or omitted state\n\nState is optional. When `--state` is omitted and no `state` path is provided by config, `fast build` does not look for `state.json`; rendering uses an empty object (`{}`). An explicit `--state` path, or a `state` path from config, must exist or the command exits with an error.\n\n> **Breaking change:** Earlier versions implicitly loaded `state.json` from the current working directory when `--state` was omitted. To use a state file, pass `--state=state.json` or set `\"state\": \"state.json\"` in `fast-build.config.json`.\n\nWhen a binding value is not present in state:\n\n- Content bindings render nothing, including unresolved dot paths: `<p>{{foo.bar}}</p>` becomes `<p></p>`.\n- Attribute bindings omit the entire attribute, including unresolved dot paths: `<div class=\"{{foo.bar}}\"></div>` becomes `<div></div>`.\n- `<f-repeat>` treats a missing list binding, including unresolved dot paths, as an empty array and renders zero iterations. If the binding is present but is not an array, rendering still errors.\n\nExplicit `null` also omits an attribute, even in an interpolated attribute\nvalue. Empty strings remain present. Known HTML boolean attributes bound to\nJSON booleans use presence/absence; ordinary attributes (including ARIA)\nretain textual booleans. Use `?name` for browser-side truthy/falsy bindings.\nAuthor bindings resolving to absence still override template-host defaults.\nThese intentional output changes are described in the\n[plugin migration guide](./docs/migration/plugin-integrations.md).\n\n### APIs for build-time plugins\n\nImport the actual exported WASM subpath; do not slice rendered host HTML:\n\n```js\nimport {\n    parse_f_templates,\n    render_shadow_root,\n} from \"@microsoft/fast-build/wasm/microsoft_fast_build.js\";\n\nconst definitions = JSON.parse(parse_f_templates(templateHtml));\nconst templates = Object.fromEntries(\n    definitions.filter(definition => definition.name !== null)\n        .map(definition => [definition.name, definition]),\n);\nconst shadowRootHtml = render_shadow_root(\n    \"my-card\", JSON.stringify(templates), JSON.stringify(componentState),\n);\n```\n\nThe result is the complete DSD `<template>` fragment, with hydration markers\nand nested components, but no host, host defaults, or light DOM. Pass resolved\ncomponent state; the API does not derive it from caller-owned host attributes.\nIt accepts the existing attribute-name strategy and v2 marker options.\n\nParsed records add `formatVersion: 1` and `bindings` without changing the array\nshape. Binding records expose `name` (null for compound expressions),\n`expression`, syntax `kind`, lexical `paths`, and outer-to-inner repeat\n`scope` frames. `type` is null except for repeat collections (`\"array\"`);\n`optional` is null because required state declarations are not inferable.\n`$index` paths refer to the active repeat frame, not a root state key.\nClient expressions are described lexically, not fully JavaScript-type-checked.\nCode samples are excluded; metadata is not full syntax or state validation.\nGenerated WASM declarations expose these JSON interfaces.\n\n#### Authored binding source spans\n\nEach binding occurrence includes `span: { start, end }`. Both positions contain\n`offset`, `line`, and `column`, relative to the **complete HTML string passed to\n`parse_f_templates`**, not the extracted or trimmed template body. Duplicate\nexpressions have separate spans, including occurrences in host attributes,\ninterpolated attribute values, and nested directives.\n\n- `offset` is a zero-based UTF-16 code-unit offset, compatible with JavaScript\n  string slicing. It is not a UTF-8 byte offset.\n- `line` and `column` are one-based. Columns count UTF-16 code units, not visual\n  width or Unicode code points; a tab counts as one and a non-BMP character\n  counts as two.\n- Ranges are half-open: `start` is inclusive and `end` is exclusive. They cover\n  the trimmed expression, excluding braces and surrounding whitespace.\n- CRLF counts as one line break but two offset units. Lone CR and LF each count\n  as one line break. Input line endings are not normalized.\n- Repeat bindings locate the iterable expression, not the alias or `in` keyword,\n  matching their existing `expression` field. Nested `scope` frames are unchanged.\n\n```js\nconst [definition] = JSON.parse(parse_f_templates(templateHtml));\nfor (const binding of definition.bindings) {\n    const { start, end } = binding.span;\n    const authoredExpression = templateHtml.slice(start.offset, end.offset);\n    console.log(`${start.line}:${start.column}`, authoredExpression);\n}\n```\n\nPositions refer to the original, entity-encoded attribute text. No entity decoding\nis introduced. Code samples remain excluded without shifting subsequent spans.\nCallers associate the input with its file name and must regenerate metadata after\nediting that input. Bindings and directives inside HTML comments remain unsupported.\n\nRender exports reject unsupported/malformed explicit versions before rendering.\nLegacy unversioned maps and string definitions remain supported. The CLI keeps\nversion/binding fields when assembling a map; persisted metadata should do the\nsame instead of discarding them.\n\n#### Structured errors\n\nFailing render, conversion, composition, and metadata-validation APIs throw actual\nJavaScript `Error` objects, retaining the existing human-readable `message`.\nBoth WASM modules export this TypeScript interface (not a runtime constructor):\n\n```ts\ninterface FastBuildError extends Error {\n    code: string;\n    line?: number;\n    column?: number;\n    length?: number;\n    templateName?: string;\n}\n```\n\nUse `code`, such as `unclosed-binding`, `repeat-not-array`, or `missing-template`,\ninstead of parsing messages. The complete code lists are documented with the\n[renderer errors](../../crates/microsoft-fast-build/README.md#error-handling)\nand [converter errors](../../crates/microsoft-fast-convert/README.md#error-codes).\n\nLocations use one-based lines and UTF-16 columns, with a UTF-16 highlight `length`.\nTabs count as one unit, non-BMP characters as two; CRLF is one line break and lone\nCR/LF are also line breaks. A highlight covers the offending opening tag or\nbinding including its delimiters; an unclosed binding highlights its opening\ndelimiters. Unlike successful binding metadata, these are error-token ranges,\nnot trimmed expression ranges.\n\nEntry-render and conversion coordinates refer to the original HTML argument,\neven after code-sample escaping, inner-template extraction, or publisher-attribute\nrewriting. Light DOM remains in its caller's source. Errors in separately supplied\ncustom-element definitions include `templateName` and use coordinates within that\ndefinition's supplied `content`, not the entry HTML or the full file it was\nextracted from. Maintain a name-to-source mapping when presenting these locations.\nFor a missing inner template, the highlight identifies its containing\n`<f-template>`; duplicate-wrapper errors identify the second wrapper.\n\nCoordinates are absent when there is no meaningful HTML position: invalid state\nJSON, malformed metadata/options, missing template definitions or outer wrappers,\nfilesystem errors, and unsafe separately supplied CSS. A known `templateName`\ncan still be present without coordinates. `parse_f_templates` remains permissive:\nit does not gain strict syntax validation or new failures.\n\nFor a direct `render(html, stateJson)` call, an integration can report:\n\n```js\ntry {\n    render(html, stateJson);\n} catch (error) {\n    if (!(error instanceof Error)) throw error;\n    const location = error.line === undefined\n        ? inputPath\n        : `${inputPath}:${error.line}:${error.column}`;\n    console.error(`${location} [${error.code}]: ${error.message}`);\n}\n```\n\nSee the [migration guide](./docs/migration/plugin-integrations.md#structured-errors)\nwhen updating consumers that previously caught strings.\n\n### Custom element templates\n\nPass a glob pattern (or comma-separated list of patterns) to `--templates` to expand custom elements into [Declarative Shadow DOM](https://developer.chrome.com/docs/css-ui/declarative-shadow-dom):\n\n```shell\nfast build \\\n  --templates=\"./components/**/*.html\" \\\n  --entry=index.html \\\n  --state=state.json \\\n  --output=output.html\n```\n\nEach matched `.html` file is scanned for `<f-template>` elements. The `name` attribute of each `<f-template>` determines the custom element name. A single file may contain multiple templates.\n\nTemplate files must use the following format:\n\n```html\n<f-template name=\"my-button\">\n    <template>\n        <button>{{label}}</button>\n    </template>\n</f-template>\n```\n\nIf an `<f-template>` element has no `name` attribute, a warning is printed and it is ignored. Exact file paths (no wildcards) are also accepted as patterns, making it possible to register a single template file. The parser follows browser tag boundaries for the `<f-template>` and inner `<template>` wrappers, including ASCII whitespace before `>` in opening and closing tags.\n\nAny `shadowroot*` attributes on `<f-template>` are forwarded to the rendered Declarative Shadow DOM `<template>`. The CLI normalizes `shadowrootmode` and legacy `shadowroot` for compatibility: when neither has a non-empty value, it emits `shadowrootmode=\"open\" shadowroot=\"open\"`; when exactly one has a non-empty value, that value is mirrored to the other; when both have explicit non-empty values, both are preserved as authored, even if they conflict.\n\n### Attribute name strategy\n\nThe `--attribute-name-strategy` option controls how HTML attribute names on custom elements are mapped to state property names in their shadow templates.\n\n| Strategy | Behaviour | Template binding |\n|---|---|---|\n| `camelCase` (default) | Dashed attribute names converted to camelCase | `foo-bar` → `{{fooBar}}` |\n| `none` | Attribute names lowercased as-is, dashes preserved | `foo-bar` → `{{foo-bar}}` |\n\nThe `camelCase` strategy only affects \"plain\" custom element attributes. It does **not** change:\n- `data-*` attributes (always use `dataset.*` grouping)\n- `aria-*` attributes (always use ARIA reflection lookup)\n- HTML global attributes with known property names (e.g. `tabindex` → `tabIndex`)\n\n```shell\nfast build \\\n  --templates=\"./components/**/*.html\" \\\n  --attribute-name-strategy=camelCase \\\n  --entry=index.html \\\n  --state=state.json \\\n  --output=output.html\n```\n\n### Configuration file\n\nInstead of passing every option on the command line, you can place a `fast-build.config.json` file alongside your project files:\n\n```json\n{\n    \"entry\": \"index.html\",\n    \"state\": \"state.json\",\n    \"output\": \"output.html\",\n    \"templates\": \"./components/**/*.html\",\n    \"markers_v2\": true\n}\n```\n\nThe CLI automatically loads `fast-build.config.json` from the current directory when it exists. To use a different file, pass `--config`:\n\n```shell\nfast build --config=configs/my-build.json\n```\n\n**Precedence:** CLI arguments always override config file values. For example, `--output=other.html` will override the `output` value in the config file.\n\n**Path resolution:** File paths in the config file (`entry`, `state`, `output`, `templates`) are resolved relative to the config file's directory, not the current working directory. This ensures the config works correctly regardless of where the CLI is invoked.\n\nAll keys are optional. Only the following keys are allowed: `entry`, `state`, `output`, `templates`, `attribute-name-strategy`, `markers_v2`, and `stream`. Unknown keys produce an error. Values must be strings except `markers_v2` and `stream`, which must be JSON booleans (`true` or `false`). If `state` is omitted, rendering uses `{}`; if `state` is present, the referenced file must exist. CLI arguments always override config values, including `--stream=false` overriding `\"stream\": true`.\n\n## Convert\n\n`fast convert` converts FAST declarative template files using the converter WASM module in `wasm/convert/`. Supported syntax names, output extensions, and default output suffixes are read from the converter WASM metadata so the Rust converter remains the source of truth for syntax targets.\n\n```shell\nfast convert --syntax=webui-prerelease --templates=example.html\nfast convert --syntax=fast-v3-ts --templates=example.html --output=../*.template.ts\nfast convert --syntax=fast-v3-ts --templates=\"src/**/*.html\" --output=generated/*.template.ts\nfast convert --syntax=fast-v3-ts --templates=example.html \\\n    --type-source=MyElement --type-source-import=./my-element.js\n```\n\n### Convert options\n\n| Option | Default | Description |\n|---|---|---|\n| `--syntax=\"<syntax>\"` | _(required)_ | Target syntax: `webui-prerelease`, `webui-framework-prerelease`, or `fast-v3-ts` |\n| `--templates=\"<glob>\"` | _(required)_ | Comma-separated glob pattern(s) matching `.html` templates to convert. An exact single file path is also accepted. Loads the converter WASM module once for the whole batch. |\n| `--output=\"<path>\"` | Next to source | Output file path. `webui-prerelease` defaults to `*.webui.html`; `webui-framework-prerelease` defaults to `*.webui-framework.html`; `fast-v3-ts` defaults to `*.template.ts`. Any `*` in the output path is replaced with the input basename without extension. Every file matched by `--templates` is written under `--output`'s directory (or next to its source if `--output` is omitted). |\n| `--overwrite` | `false` | Allow replacing an existing output file. CLI presence always means `true`. |\n| `--typed[=true/false]` | `false` | Only for `fast-v3-ts`. Add an explicit `ElementViewTemplate<TSource>` export annotation and type-only import. Explicit false overrides configured true. |\n| `--type-source=\"<Name>\"` | _(none)_ | Only valid with `--syntax=fast-v3-ts`. Emits `export const template = html<Name>\\`…\\`;` instead of the untyped `html` call. Must be a dotted TypeScript identifier (e.g. `MyElement` or `Namespace.MyElement`). |\n| `--type-source-import=\"<module>\"` | _(none)_ | Requires `--type-source`. Also emits `import type { <Name> } from \"<module>\";` alongside the helper imports. |\n| `--config=\"<path>\"` | `fast-convert.config.json` | Path to a JSON configuration file. If omitted, `fast-convert.config.json` in the current directory is used when present. CLI arguments take precedence over config values. |\n\nOnly matched `.html` files are converted; non-`.html` files and directories are never matched. The output extension must match the selected syntax: `.html` for `webui-prerelease`/`webui-framework-prerelease` and `.ts` for `fast-v3-ts`. The output parent directory is created automatically if it doesn't exist (`mkdir -p` semantics), and an existing output file is rejected unless `--overwrite` or `\"overwrite\": true` is used. When a `--templates` pattern matches zero files, a warning is printed but the command does not fail unless every pattern matches zero files.\n\n`webui-framework-prerelease` converts FAST's declarative syntax into the Microsoft WebUI Framework's own declarative runtime syntax (`webui-prerelease` remains unchanged — it emits HTML for WebUI's separate FAST parser plugin instead). When `webui-framework-prerelease` strips an unsupported `f-slotted`/`f-children` directive, the CLI prints `Warning: <message>` to stderr for each stripped directive without failing the command.\n\n`--type-source` exists so templates that combine more than one differently-named\n`ref`/`children`/`slotted` directive (which otherwise fail to type-check once a\nreal `TSource` is supplied, because `html<TSource, TParent>` infers a single\n`TSource` for the whole tagged template) can be generated already type-checked\nagainst a concrete element type. See\n[`microsoft-fast-convert` DESIGN.md](../../crates/microsoft-fast-convert/DESIGN.md#explicit-tsource-generic).\n\n### Convert configuration file\n\n`fast-convert.config.json` follows the same precedence and path-resolution rules as `fast-build.config.json`: CLI arguments override config values, and `templates`/`output` paths from config are resolved relative to the config file directory.\n\n```json\n{\n    \"syntax\": \"fast-v3-ts\",\n    \"templates\": \"src/**/*.html\",\n    \"output\": \"generated/*.template.ts\",\n    \"overwrite\": false,\n    \"type-source\": \"MyElement\",\n    \"type-source-import\": \"./my-element.js\"\n}\n```\n\nOnly `syntax`, `templates`, `output`, `overwrite`, `type-source`,\n`type-source-import`, and `typed` are allowed. Values must be strings except\n`overwrite` and `typed`, which must be JSON booleans.\n\nFor declaration-emitting consumers, use `--typed --type-source=MyElement`.\nThe converter WASM's `convert_template_with_options` accepts an appended\noptional `typed` boolean. `convert_stylesheet(css, \"fast-v3-ts\", \"styles\",\ntrue)` emits an `ElementStyles` annotation. Existing calls remain untyped;\ntyped exports are tested with TypeScript `isolatedDeclarations`.\n\n### Running converter fixtures locally\n\nBuild the package WASM, then run the fixture validation:\n\n```shell\nnpm run build -w @microsoft/fast-build\nnpm run test:fixtures:convert -w @microsoft/fast-build\n```\n\nThe fixture tests run `fast convert` from fixture directories that contain\n`fast-convert.config.json`, so they verify the same default config discovery used\nby `fast build`. Generated fixture output is written under\n`packages/fast-build/test/.fixture-output/` and removed by the tests.\n`test/fixtures/convert/type-source.test.js` additionally type-checks\n`--type-source` output with the TypeScript compiler API against a companion\nelement type, using a separate `test/.fixture-output-type-source/` directory.\n\n## Template syntax\n\nBindings and FAST directive markup inside HTML comments are unsupported.\nCommenting out bound markup does not reliably disable its bindings and can cause\nrendering errors or client hydration mismatches. Remove unused bound markup\ninstead, and keep explanatory comments free of binding syntax and FAST directive\ntags.\n\nTemplate syntax follows the FAST declarative HTML format. See the\n[`@microsoft/fast-element` declarative documentation](../fast-element/docs/declarative/syntax.md)\nfor full documentation on bindings, conditionals, repeats, and directives.\n","packages/fast-build/docs/migration/plugin-integrations.md":"# Migrating plugin integration pipelines\n\n## Structured errors\n\nWASM failures now throw JavaScript `Error` objects rather than strings. Read\n`error.message` for the previous human-readable text; `String(error)` now has the\nstandard `Error: ` prefix. Replace message matching with stable `error.code`\nchecks. Both WASM declaration modules export a `FastBuildError` interface extending\n`Error`; it is a type only, not an exported constructor.\n\nOptional `line`/`column` are one-based UTF-16 coordinates, and `length` is a UTF-16\nerror-token highlight length. CRLF is one break; lone CR/LF also break lines.\nEntry and conversion coordinates refer to the complete supplied HTML. A named\ncustom-element render failure instead refers to its separately supplied `content`.\nUse `templateName` to select that source, rather than attaching its coordinates\nto the entry or to a full file from which `content` was extracted. Older metadata\ndoes not carry enough provenance to reconstruct those full-file positions.\nDo not fabricate HTML locations when these fields are absent (JSON/options,\nmissing sources, filesystem errors, or separate CSS).\n\nNative Rust `RenderError` and `ConvertError` expose `code()`, `location()` returning\nan optional `ErrorLocation`, `template_name()`, and `kind()`. Source-annotated\nvalidation errors may use the new `Located` variant; match `error.kind()` to\ninspect the underlying variant. Context fields now use boxed `ErrorContext`\ninstead of `String`; use `context.to_string()` to read the unchanged snippet and\n`String::into()` when constructing a context without source provenance.\nUpdate exhaustive enum matches for `Located`. These are intentional pre-1.0\nnative API changes. Successful rendering/conversion, warnings, missing-state\nbehavior, and permissive `parse_f_templates` parsing are unchanged.\n\n## Attribute output changes\n\nMissing and explicit `null` bindings now omit the entire attribute, including\nmixed literal/binding values. To intentionally keep `href=\"\"`, provide `\"\"`\ninstead of null. JSON booleans on known HTML boolean attributes use presence:\nfalse omits `disabled`, true emits it. ARIA/ordinary attribute booleans remain\ntextual. Use FAST's `?name` syntax for matching client-side truthy/falsy behavior.\nAuthor bindings resolving to absence suppress matching template-host defaults.\nRemove wrapper regular expressions that strip empty values: they would erase\nintentional empty strings. Hydration slot counts remain unchanged.\n\n## Typed converter output\n\nThe default output remains unchanged. Opt into `typed: true` (or `--typed`)\nfor explicit `ElementViewTemplate<TSource>` / `ElementStyles` annotations and\ntype-only imports, then remove wrapper string replacements. Supply\n`type_source`/`--type-source` when strict source-property checking is required.\nRust `ConvertOptions` struct literals must include the new `typed` field or\nuse `..ConvertOptions::default()`.\nThe pre-1.0 native error enums also gain integration-related variants; update\nexhaustive `RenderError` / `ConvertError` matches accordingly.\n\n## Caller-owned host markup\n\nReplace throwaway-host rendering and substring extraction with\n`render_shadow_root` (WASM) or `render_shadow_root_*_with_locator` (Rust).\nPass resolved component state and insert the returned complete DSD `<template>`\ninto the host you own. The fragment does not include host/default attributes\nor light-DOM children.\n\n## Persisted template metadata\n\n`parse_f_templates` keeps its JSON array shape and existing fields, adding\nper-record `formatVersion: 1` and `bindings`. Preserve these fields when\npersisting or constructing a keyed map. Unsupported/malformed explicit versions\nnow fail before rendering. Unversioned legacy maps remain supported, but cannot\nreceive stale-version protection. Regenerate metadata on format changes rather\nthan rewriting a version number onto incompatible data.\n\nBindings describe names, expression kinds, paths, and repeat scopes. Unknown\ntypes and state optionality are explicitly null, not inferred declarations.\nRepeat collections alone have a known array requirement. Complex/client\nreferences are lexical descriptions; metadata is not a full state schema or\nsyntax-validation certificate. Use application declarations for definitive\ntype/requiredness checks.\n\nEach newly parsed binding now includes an authored `span` with half-open `start`\nand `end` positions in the complete input string. Offsets are zero-based UTF-16;\nlines and UTF-16 columns are one-based. Use the original input, not the returned\ntrimmed `content`, when slicing or attaching diagnostics. The range covers the\ntrimmed expression without braces; repeat bindings locate only the iterable.\nCRLF counts as one line break and two offset units; lone CR and LF each count\nas a line break. Raw attribute entities are not decoded.\n\nFormat version 1 is unchanged, and renderers still accept older records without\nspans. Regenerate persisted metadata to obtain authored locations; preserve spans\nwhen mapping or serializing records. Native `BindingMetadata` struct literals\nmust now supply the public `span: SourceSpan` field; prefer `parse_f_templates`\nto constructing descriptive metadata manually. Generated WASM declarations expose\n`TemplateSourceSpan` and `TemplateSourcePosition`.\n","packages/fast-element/README.md":"# FAST Element\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-element.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-element)\n\nThe `fast-element` library is a lightweight means to easily build performant, memory-efficient, standards-compliant Web Components. FAST Elements work in every major browser and can be used in combination with any front-end framework or even without a framework.\n\n## Installation\n\n### From NPM\n\nTo install the latest `fast-element` library using `npm`:\n\n```shell\nnpm install --save @microsoft/fast-element\n```\n\nWithin your JavaScript or TypeScript code, you can then import library APIs like this:\n\n```ts\nimport { FASTElement } from '@microsoft/fast-element';\n```\n\n### From CDN\n\nA pre-bundled script that contains all APIs needed to build web components with FAST Element is available on CDN. You can use this script by adding [`type=\"module\"`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to the script element and then importing from the CDN.\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <script type=\"module\">\n          import { FASTElement } from \"https://cdn.jsdelivr.net/npm/@microsoft/fast-element/dist/fast-element.min.js\";\n\n          // your code here\n        </script>\n    </head>\n    <!-- ... -->\n</html>\n```\n\nThe markup above always references the latest release. When deploying to production, you will want to ship with a specific version. Here's an example of the markup for that:\n\n```html\n<script type=\"module\" src=\"https://cdn.jsdelivr.net/npm/@microsoft/fast-element@1.6.2/dist/fast-element.min.js\"></script>\n```\n\n:::note\nFor simplicity, examples throughout the documentation will assume the library has been installed from NPM, but you can always replace the import location with the CDN URL.\n:::\n\n:::tip\nLooking for a quick guide on building components?  Check out [our Cheat Sheet](../resources/cheat-sheet.md#building-components).\n:::\n\n## Browser Requirements\n\nFAST Element v3 assumes a client-side browser `Window` runtime with native\n`globalThis`, Custom Elements, DOM, Shadow DOM, and `requestAnimationFrame`.\nThe `FAST` object is now a module-scoped export (not on `globalThis`). If you\nneed to support an older browser without `globalThis`, load that polyfill before\nimporting `@microsoft/fast-element`.\n\nThe FAST Element client runtime is not intended to execute in workers,\nserver-side JavaScript runtimes, or other non-window hosts. Use server-side\nrendering tools to produce HTML for the browser, and run FAST Element in the\nclient window where custom elements connect, render, update, and hydrate.\n\n## Debug entrypoint\n\nThe declarative attribute fixture covers server-side omission of null/missing\nattributes and subsequent hydration updates. Explicit empty strings remain\npresent, and omitted attributes retain binding slots. See the\n[server-rendering guide](https://www.fast.design/docs/3.x/declarative-templates/server-rendering/)\nfor the rendering contract.\n\n`@microsoft/fast-element/debug.js` exports `enableDebug()` instead of configuring\nFAST at import time. The development root export and debug rollup bundle still\nenable debug behavior automatically.\n\n```ts\nimport { enableDebug } from \"@microsoft/fast-element/debug.js\";\n\nenableDebug();\n```\n\n## Server-rendered hydration\n\nCall `enableHydration()` from `@microsoft/fast-element/hydration.js` before\ncomponents connect to reuse their server-rendered DOM. Ordered sibling-bounded\nviews use pointer traversal and consume native markers without factory-index\narrays; unusual boundaries and potentially mutating cleanup retain the live\nRange fallback. Nested and adjacent repeats pair only their own server ranges,\npreserving SSR nodes while reconciling missing or excess items.\n\nCall `enableHydration()` before components are registered with the platform to\nalso enable pointer-only native marker cleanup for FAST components that do not\nobserve `data-fe`. Observation tracking is opt-in and excluded from client-only\n`FASTElement` bundles. Earlier registrations still hydrate correctly through\nthe conservative fallback, as do unknown registration, observed markers,\ncustomized built-ins, and overridden attribute methods. Cleanup remains\nsynchronous.\n\nExisting FAST 3 marker output and opt-in `markers_v2` remain supported without\napplication changes. See the [server-rendering guide](https://www.fast.design/docs/3.x/declarative-templates/server-rendering/)\nand [contributor performance workloads](./docs/template-bindings.md#hydration-cpu-regression-coverage).\nContributor-facing internals separate DOM traversal, binding target mapping,\nand repeat-range discovery; the opt-in benchmark spec is independent of the\ndeterministic correctness and allocation regression spec.\n\n## Export Sizes\n\nBundle sizes for each tree-shakeable export are tracked in [`SIZES.md`](./SIZES.md) and regenerated on every build. See the [Export Sizes](https://www.fast.design/docs/3.x/resources/export-sizes/) documentation page for the latest numbers.\n\n## Root Imports and Path Exports\n\nThe root `@microsoft/fast-element` entrypoint exports the FAST Element\nimplementation APIs, including the element base class, kernel, controller,\ndefinition APIs, template APIs, binding helpers, directives, styles, and schema\nhelpers. The FAST element registry is also available from\n`@microsoft/fast-element/registry.js` for focused definition lookups and\n`fastElementRegistry.whenRegistered(tagName)` registration promises.\nDeclarative, hydration, context, and dependency injection APIs are available\nfrom their focused path exports.\n\nFocused package path exports remain available for consumers that want to import\na narrower entrypoint directly. The website's\n[Path Exports](https://www.fast.design/docs/3.x/advanced/path-exports/) page is\ngenerated from `package.json` and lists each supported path.\n\n## Dynamic Style Application\n\nImport `css`, `CSSTemplateTag`, `CSSValue`, and style APIs such as\n`ElementStyles`, `CSSDirective`, `cssDirective`, `ComposableStyles`,\n`HostBehavior`, `HostController`, `StyleStrategy`, and `StyleTarget` from\n`@microsoft/fast-element`:\n\n```ts\nimport { ElementStyles, css } from \"@microsoft/fast-element\";\n```\n\nWhen runtime state or external signals need to add or remove styles, create the\n`ElementStyles` with `css` and toggle it through\n`this.$fastController.addStyles()` / `this.$fastController.removeStyles()` from\nthe element lifecycle or change handlers.\n\n`css` templates remain static style definitions. Runtime CSS bindings and\nbehavior-producing CSS directives are no longer supported; keep the condition on\nthe element and toggle a separate `ElementStyles` instance through the\ncontroller when styles need to change.\n\n## Declarative HTML\n\nBindings and FAST directive markup inside HTML comments are unsupported in\ndeclarative templates. Commenting out bound markup does not reliably disable its\nbindings; remove unused markup instead. See the\n[template syntax restrictions](./docs/declarative/syntax.md#html-comments).\n\nFAST Element publishes its declarative HTML runtime from\n`@microsoft/fast-element/declarative.js`. This entrypoint exports the\nfunctional APIs for declarative templates: `declarativeTemplate()`,\n`TemplateParser`, and related configuration types. `attributeMap()` and\n`observerMap()` are available from their own focused path exports. The\ndeclarative runtime is pure at import time; declarative APIs lazily install only\ndeclarative debug messages. Hydration is separate and remains opt-in through\n`enableHydration()` from `@microsoft/fast-element/hydration.js`.\n\n```ts\nimport { FASTElement } from \"@microsoft/fast-element\";\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n\nclass MyElement extends FASTElement {}\n\nMyElement.define({\n    name: \"my-element\",\n    template: declarativeTemplate(),\n});\n```\n\n`declarativeTemplate()` automatically defines FAST's internal native\n`<f-template>` publisher in the relevant registry, resolves the matching\n`<f-template name=\"my-element\">`, and keeps the definition template concrete\nbefore `define()` resolves. If multiple matching `<f-template>` elements are\nconnected, the first connected element supplies the template and later duplicates\ndo not reassign it. Consumers should not import or define the `<f-template>`\nimplementation directly.\n\nDeclarative schema behavior is enabled with define extensions:\n\n```ts\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [attributeMap(), observerMap()],\n);\n```\n\n`attributeMap()` creates `@attr`-style accessors for leaf bindings, and\n`observerMap()` creates deep observable accessors for discovered root\nproperties. Declarative templates assign `definition.schema` during template\nresolution so these extensions always have schema data when used with\n`declarativeTemplate()`. For non-declarative/manual schema use, import `Schema`\nfrom `@microsoft/fast-element` and pass it on the element definition;\n`observerMap()` can also receive\n`observerMap({ schema })` directly. When both extensions are present, attribute\nmapping runs before observer mapping.\n\nDeclarative utilities such as `deepMerge` are available from\n`@microsoft/fast-element/declarative-utilities.js`. See\n[`docs/declarative/syntax.md`](./docs/declarative/syntax.md) for declarative implementation\ndetails and the\n[Declarative HTML docs](https://fast.design/docs/3.x/declarative-templates/overview/)\nfor guides on writing f-templates, defining declarative elements, and\nserver-side rendering. Declarative event bindings use `$e` for the DOM event\nobject and `$c` for the execution context.\n\n## Prerendered Content Optimization\n\nHydration of prerendered content is **opt-in**. Call `enableHydration()` from `@microsoft/fast-element/hydration.js` before any FAST elements connect to activate the hydration path:\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nconst hydration = enableHydration();\n\nawait hydration.whenHydrated();\nconsole.log(\"hydration complete\");\n```\n\nBy default, hydration handles the initial prerendered batch and then no-ops\nafter the active hydration batch completes. If your app streams Declarative\nShadow DOM after the initial batch, keep the hydration hook active. In this\nmode, `enableHydration().whenHydrated()` intentionally remains pending because\nhydration never reaches a global completion point.\n\n```typescript\nimport { enableHydration, StopHydration } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({\n    stopHydration: StopHydration.never,\n});\n```\n\nFAST Element 3.x data-free hydration markers are the only format recognized\nby default. Server output that still emits the legacy FAST Element 2.x\nindexed markers will fail to hydrate unless you opt into that reader on its\ndedicated export path — an interoperability enhancement for backend systems\nthat have not yet adopted the data-free format:\n\n```typescript\nimport { enableHydration, markers_v2 } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ markers: markers_v2 });\n```\n\nBecause `markers_v2` is only referenced when explicitly imported, its legacy\nparsing logic is tree-shaken out of the bundle for consumers who don't use it.\n\nWhen using `@microsoft/fast-build`, set `\"markers_v2\": true` in\n`fast-build.config.json` so the renderer and client use the same format.\n\nWhen hydration is enabled and a FAST element connects with an existing shadow root (from server-side rendering or declarative shadow DOM), `ElementController` detects this and hydrates instead of re-rendering. Two properties on the controller let you inspect the result:\n\n- **`isPrerendered: Promise<boolean>`** — resolves `true` when the element had a declarative shadow root (DSD) at connect time, regardless of whether hydration ran.\n- **`isHydrated: Promise<boolean>`** — resolves `true` only when hydration actually ran successfully.\n\nThis enables several optimizations:\n\n- **Hydration instead of re-render**: The template uses `hydrate()` to map existing DOM nodes to binding targets rather than cloning new DOM.\n- **Declarative template resolution**: `declarativeTemplate()` waits for the\n  matching `<f-template>` before `define()` completes, so connected elements\n  hydrate with a concrete template.\n- **Attribute skip**: `onAttributeChangedCallback()` skips processing during initial upgrade when the element is prerendered, since server-rendered attribute values are already correct.\n- **Binding skip**: `HTMLBindingDirective.bind()` skips `updateTarget` for `attribute` and `booleanAttribute` aspect types when the view is prerendered.\n\n### Hydration Mismatch Diagnostics\n\nIf a prerendered DOM diverges from the client template in a way FAST cannot\nreconcile (the `render()` empty-boundary and `repeat()` count-mismatch cases\nrecover silently), `HydrationBindingError` or `HydrationTargetElementError` is\nthrown. By default the message is a single line pointing at the opt-in\n`hydrationDebugger()`. Install the debugger to get a rich\n\"Expected … / Received …\" report with the SSR HTML snippet and structured\n`expected` / `received` fields on the thrown error:\n\n```typescript\nimport { enableHydration, hydrationDebugger } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ debugger: hydrationDebugger() });\n```\n\nThe debugger module is tree-shaken out of production hydration bundles when\nnot imported, so the rich diagnostic helpers only land in builds that opt in.\n\nComponent authors can await both promises to distinguish prerendered content from successful hydration:\n\n```typescript\nconst controller = this.$fastController;\nconst prerendered = await controller.isPrerendered;\nconst hydrated = await controller.isHydrated;\n\nif (prerendered && !hydrated) {\n    // Had DSD but hydration wasn't enabled — client-side rendered\n}\n```\n\nCustom directives can also await `controller.isPrerendered` and `controller.isHydrated` (both `Promise<boolean>` on the `ViewController` interface) to determine how the view's content was rendered.\n\n## Define Extensions\n\nThe static `define()` method on a `FASTElement` subclass accepts an optional second argument — an array of extension callbacks that are invoked with the resolved element definition before the element is registered with the platform. This enables a plugin pattern where reusable behaviors can hook into element registration.\n\n```typescript\nimport { FASTElement, type FASTElementExtension } from \"@microsoft/fast-element\";\n\nfunction logger(): FASTElementExtension {\n    return definition => {\n        console.log(`Defining element: ${definition.name}`);\n    };\n}\n\nclass MyComponent extends FASTElement {\n    // component code\n}\n\nMyComponent.define({ name: \"my-component\", template, styles }, [logger()]);\n```\nEach extension receives the full `FASTElementDefinition`, which includes the resolved element name, type, template, styles, and attribute metadata. Extensions run before `customElements.define()`, so any setup they perform is available when existing DOM elements are upgraded.\n","packages/fast-element/docs/ACKNOWLEDGEMENTS.md":"# Acknowledgements\n\nThere are many great open source projects that have inspired us and enabled us to build FAST. Below are a few that stand out.\n\n* [.NET](https://dotnet.microsoft.com/) - Many thanks to the .NET team for sharing their policies and practices upon which our issue management and release planning docs and practices were based.\n* [asap](https://github.com/kriskowal/asap) - An awesome, time-tested async task queue implementation that heavily inspired our DOM update system.\n* [Aurelia 1 and Aurelia 2](https://aurelia.io/) - Various details of Aurelia 2's decorator and metadata model inspired us in the design of `fast-element`. Additionally, Aurelia 1's mechanisms for array observation, binding, and template compilation also guided us in our work.\n* [faastjs](https://github.com/faastjs) - A project with a similar name but a very different purpose. Their API documentation approach leveraging [api-extractor](https://api-extractor.com/) was a huge help to us.\n* [Knockout](https://knockoutjs.com/) - One of the first JavaScript libraries (if not the first) to implement an observer system. The original techniques for observables and computed observables have influenced many libraries over the years. Re-interpreting these ideas in terms of modern JavaScript and DOM has helped us to build a powerful and robust system.\n* [lit-html](https://lit-html.polymer-project.org/) - One of the first libraries to leverage standard JavaScript tagged template literals for HTML templates. We were inspired by this technique and wanted to explore whether it could be combined with our idea of arrow function binding expressions.\n* [Polymer](https://www.polymer-project.org/) - One of the first libraries (if not the first) to embrace Web Components.\n* [Vue](https://vuejs.org/) - We liked the terseness of the `:` and `@` syntax in templates, so we adapted it along with some modifications in our templates.\n","packages/fast-element/docs/api-report.api.md":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport interface AccessCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"access\";\n}\n\n// @public\nexport interface Accessor {\n    getValue(source: any): any;\n    name: string;\n    setValue(source: any, value: any): void;\n}\n\n// @public\nexport type AddViewBehaviorFactory = (factory: ViewBehaviorFactory) => string;\n\n// @public\nexport interface ArrayObserver extends SubscriberSet {\n    addSort(sort: Sort): void;\n    addSplice(splice: Splice): void;\n    flush(): void;\n    readonly lengthObserver: LengthObserver;\n    reset(oldCollection: any[] | undefined): void;\n    readonly sortObserver: SortObserver;\n    strategy: SpliceStrategy | null;\n}\n\n// @public\nexport const ArrayObserver: Readonly<{\n    readonly sorted: 0;\n    readonly enable: () => void;\n}>;\n\n// @public\nexport interface Aspected {\n    aspectType: DOMAspect;\n    dataBinding?: Binding;\n    sourceAspect: string;\n    targetAspect: string;\n}\n\n// @public\nexport function attr(config?: DecoratorAttributeConfiguration): (target: {}, property: string) => void;\n\n// @public\nexport function attr(target: {}, prop: string): void;\n\n// @public\nexport type AttributeConfiguration = {\n    property: string;\n    attribute?: string;\n    mode?: AttributeMode;\n    converter?: ValueConverter;\n};\n\n// @public\nexport const AttributeConfiguration: Readonly<{\n    locate: (target: {}) => AttributeConfiguration[];\n}>;\n\n// @public\nexport class AttributeDefinition implements Accessor {\n    constructor(Owner: Function, name: string, attribute?: string, mode?: AttributeMode, converter?: ValueConverter);\n    readonly attribute: string;\n    // @internal\n    static collect(Owner: Function, ...attributeLists: (ReadonlyArray<string | AttributeConfiguration> | undefined)[]): ReadonlyArray<AttributeDefinition>;\n    readonly converter?: ValueConverter;\n    getValue(source: HTMLElement): any;\n    readonly mode: AttributeMode;\n    readonly name: string;\n    // @internal (undocumented)\n    onAttributeChangedCallback(element: HTMLElement, value: any): void;\n    readonly Owner: Function;\n    setValue(source: HTMLElement, newValue: any): void;\n}\n\n// @public\nexport type AttributeMode = \"reflect\" | \"boolean\" | \"fromView\";\n\n// @public\nexport abstract class Binding<TSource = any, TReturn = any, TParent = any> {\n    constructor(evaluate: Expression<TSource, TReturn, TParent>, policy?: DOMPolicy, isVolatile?: boolean);\n    abstract createObserver(subscriber: Subscriber, directive: BindingDirective): ExpressionObserver<TSource, TReturn, TParent>;\n    evaluate: Expression<TSource, TReturn, TParent>;\n    isVolatile: boolean;\n    options?: any;\n    policy?: DOMPolicy;\n}\n\n// @public\nexport interface BindingDirective {\n    readonly aspectType?: DOMAspect;\n    readonly dataBinding: Binding;\n    readonly targetAspect?: string;\n}\n\n// @public\nexport const booleanConverter: ValueConverter;\n\n// @public\nexport type CachedPath = DefaultCachedPath | RepeatCachedPath | AccessCachedPath | EventCachedPath;\n\n// @public\nexport interface CachedPathCommon {\n    // (undocumented)\n    currentContext: string | null;\n    // (undocumented)\n    parentContext: string | null;\n    // (undocumented)\n    path: string;\n}\n\n// @public\nexport type CachedPathMap = Map<string, Map<string, JSONSchema>>;\n\n// @public\nexport type Callable = typeof Function.prototype.call | {\n    call(): void;\n};\n\n// @public\nexport interface CaptureType<TSource = any, TParent = any> {\n}\n\n// @public\nexport interface ChildListDirectiveOptions<T = any> extends NodeBehaviorOptions<T>, Omit<MutationObserverInit, \"subtree\" | \"childList\"> {\n}\n\n// @public\nexport function children<TSource = any, TParent = any>(propertyOrOptions: (keyof TSource & string) | ChildrenDirectiveOptions<keyof TSource & string>): CaptureType<TSource, TParent>;\n\n// @public\nexport class ChildrenDirective extends NodeObservationDirective<ChildrenDirectiveOptions> {\n    constructor(options: ChildrenDirectiveOptions);\n    disconnect(target: any): void;\n    getNodes(target: Element): Node[];\n    observe(target: any): void;\n}\n\n// @public\nexport type ChildrenDirectiveOptions<T = any> = ChildListDirectiveOptions<T> | SubtreeDirectiveOptions<T>;\n\n// @public\nexport interface ChildrenMap {\n    // (undocumented)\n    attributeName: string;\n    // (undocumented)\n    customElementName: string;\n}\n\n// @public\nexport type Class<T, C = {}> = C & Constructable<T> & {\n    readonly prototype: T;\n};\n\n// @public\nexport type CompilationStrategy = (\nhtml: string | HTMLTemplateElement,\nfactories: Record<string, ViewBehaviorFactory>,\npolicy: DOMPolicy) => HTMLTemplateCompilationResult;\n\n// @public\nexport type CompiledViewBehaviorFactory = Required<ViewBehaviorFactory>;\n\n// @public\nexport const Compiler: {\n    compile<TSource = any, TParent = any>(html: string | HTMLTemplateElement, factories: Record<string, ViewBehaviorFactory>, policy?: DOMPolicy): HTMLTemplateCompilationResult<TSource, TParent>;\n    setDefaultStrategy(strategy: CompilationStrategy): void;\n    aggregate(parts: (string | ViewBehaviorFactory)[], policy?: DOMPolicy): ViewBehaviorFactory;\n};\n\n// @public\nexport type ComposableStyles = string | ElementStyles | CSSStyleSheet;\n\n// @public\nexport function composedContains(reference: HTMLElement, test: HTMLElement): boolean;\n\n// @public\nexport function composedParent<T extends HTMLElement>(element: T): HTMLElement | null;\n\n// @beta\nexport type ComputedBuilder = {\n    on: {\n        setup(callback: ComputedSetupCallback): void;\n    };\n};\n\n// @beta\nexport type ComputedInitializer<T> = (builder: ComputedBuilder) => () => T;\n\n// @beta\nexport type ComputedSetupCallback = () => (() => void) | void;\n\n// @beta\nexport type ComputedState<T> = ReadonlyState<T> & Disposable & {\n    subscribe(subscriber: Subscriber): void;\n    unsubscribe(subscriber: Subscriber): void;\n};\n\n// @beta\nexport function computedState<T>(initialize: ComputedInitializer<T>, name?: string): ComputedState<T>;\n\n// @public\nexport type Constructable<T = {}> = {\n    new (...args: any[]): T;\n};\n\n// @public\nexport type ConstructibleStyleStrategy = {\n    new (styles: (string | CSSStyleSheet)[]): StyleStrategy;\n};\n\n// @public\nexport interface ContentTemplate {\n    create(): ContentView;\n}\n\n// @public\nexport interface ContentView {\n    bind(source: any, context?: ExecutionContext): void;\n    // (undocumented)\n    readonly context: ExecutionContext;\n    insertBefore(node: Node): void;\n    remove(): void;\n    unbind(): void;\n}\n\n// @public\nexport const css: CSSTemplateTag;\n\n// @public\nexport interface CSSDirective {\n    createCSS(): ComposableStyles;\n}\n\n// @public\nexport const CSSDirective: Readonly<{\n    getForInstance: (object: any) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    getByType: (key: Function) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    define<TType extends Constructable<CSSDirective>>(type: any): TType;\n}>;\n\n// @public\nexport function cssDirective(): (type: Constructable<CSSDirective>) => void;\n\n// @public\nexport interface CSSDirectiveDefinition<TType extends Constructable<CSSDirective> = Constructable<CSSDirective>> {\n    readonly type: TType;\n}\n\n// @public\nexport type CSSTemplateTag = ((strings: TemplateStringsArray, ...values: CSSValue[]) => ElementStyles) & {\n    partial(strings: TemplateStringsArray, ...values: CSSValue[]): CSSDirective;\n};\n\n// @public\nexport type CSSValue = ComposableStyles | CSSDirective;\n\n// @public\nexport function customElement(nameOrDef: string | PartialFASTElementDefinition): (type: Constructable<HTMLElement>) => void;\n\n// @public\nexport type DecoratorAttributeConfiguration = Omit<AttributeConfiguration, \"property\">;\n\n// @public\nexport interface DefaultCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"default\";\n}\n\n// @public\nexport class DefaultExecutionContext<TParent> implements ExecutionContext<TParent> {\n    get event(): Event;\n    eventDetail<TDetail>(): TDetail;\n    eventTarget<TTarget extends EventTarget>(): TTarget;\n    index: number;\n    get isEven(): boolean;\n    get isFirst(): boolean;\n    get isInMiddle(): boolean;\n    get isLast(): boolean;\n    get isOdd(): boolean;\n    length: number;\n    readonly parent: TParent;\n    readonly parentContext: ExecutionContext<TParent>;\n}\n\n// @public\nexport interface Disposable {\n    dispose(): void;\n}\n\n// @public\nexport const DOM: Readonly<{\n    readonly policy: DOMPolicy;\n    setPolicy(value: DOMPolicy): void;\n    setAttribute(element: HTMLElement, attributeName: string, value: any): void;\n    setBooleanAttribute(element: HTMLElement, attributeName: string, value: boolean): void;\n}>;\n\n// @public\nexport const DOMAspect: Readonly<{\n    readonly none: 0;\n    readonly attribute: 1;\n    readonly booleanAttribute: 2;\n    readonly property: 3;\n    readonly content: 4;\n    readonly tokenList: 5;\n    readonly event: 6;\n}>;\n\n// @public\nexport type DOMAspect = (typeof DOMAspect)[Exclude<keyof typeof DOMAspect, \"none\">];\n\n// @public\nexport type DOMAspectGuards = {\n    [DOMAspect.attribute]?: DOMSinkGuards;\n    [DOMAspect.booleanAttribute]?: DOMSinkGuards;\n    [DOMAspect.property]?: DOMSinkGuards;\n    [DOMAspect.content]?: DOMSinkGuards;\n    [DOMAspect.tokenList]?: DOMSinkGuards;\n    [DOMAspect.event]?: DOMSinkGuards;\n};\n\n// @public\nexport type DOMElementGuards = Record<string, DOMAspectGuards>;\n\n// @public\nexport type DOMGuards = {\n    elements: DOMElementGuards;\n    aspects: DOMAspectGuards;\n};\n\n// @public\nexport interface DOMPolicy {\n    createHTML(value: string): string;\n    protect(tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink): DOMSink;\n}\n\n// @public\nexport const DOMPolicy: Readonly<{\n    create(options?: DOMPolicyOptions): Readonly<DOMPolicy>;\n}>;\n\n// @public\nexport type DOMPolicyOptions = {\n    trustedType?: TrustedTypesPolicy;\n    guards?: Partial<DOMGuards>;\n};\n\n// @public\nexport type DOMSink = (target: Node, aspectName: string, value: any, ...args: any[]) => void;\n\n// @public\nexport type DOMSinkGuards = Record<string, (tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink) => DOMSink>;\n\n// @public\nexport class ElementController<TElement extends HTMLElement = HTMLElement> implements Notifier, HostController<TElement> {\n    // @internal\n    constructor(element: TElement, definition: FASTElementDefinition);\n    addBehavior(behavior: HostBehavior<TElement>): void;\n    addStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    protected behaviors: Map<HostBehavior<TElement>, number> | null;\n    protected bindObservables(): void;\n    protected captureBoundObservables(): void;\n    connect(): void;\n    protected connectBehaviors(): void;\n    get context(): ExecutionContext;\n    readonly definition: FASTElementDefinition;\n    disconnect(): void;\n    protected disconnectBehaviors(): void;\n    emit(type: string, detail?: any, options?: Omit<CustomEventInit, \"detail\">): void | boolean;\n    static forCustomElement(element: HTMLElement, override?: boolean): ElementController;\n    protected hasExistingShadowRoot: boolean;\n    // @internal\n    static installHydrationHook(hook: (controller: ElementController, template: ElementViewTemplate, element: HTMLElement, host: Node) => boolean): void;\n    get isBound(): boolean;\n    get isConnected(): boolean;\n    readonly isHydrated: Promise<boolean>;\n    readonly isPrerendered: Promise<boolean>;\n    get mainStyles(): ElementStyles | null;\n    set mainStyles(value: ElementStyles | null);\n    protected needsInitialization: boolean;\n    notify(args: any): void;\n    protected observeLateAttributes(): void;\n    onAttributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;\n    onUnbind(behavior: {\n        unbind(controller: ExpressionController<TElement>): any;\n    }): void;\n    removeBehavior(behavior: HostBehavior<TElement>, force?: boolean): void;\n    removeStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    protected renderTemplate(template: ElementViewTemplate | null | undefined): void;\n    static setStrategy(strategy: ElementControllerStrategy): void;\n    get shadowOptions(): ShadowRootOptions | undefined;\n    set shadowOptions(value: ShadowRootOptions | undefined);\n    readonly source: TElement;\n    get sourceLifetime(): SourceLifetime | undefined;\n    protected stage: Stages;\n    get subject(): TElement;\n    subscribe(subscriber: Subscriber, propertyToWatch?: any): void;\n    protected syncLateAttributes(): void;\n    get template(): ElementViewTemplate<TElement> | null;\n    set template(value: ElementViewTemplate<TElement> | null);\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: any): void;\n    readonly view: ElementView<TElement> | null;\n}\n\n// @public\nexport interface ElementControllerStrategy {\n    // (undocumented)\n    new (element: HTMLElement, definition: FASTElementDefinition): ElementController;\n}\n\n// @public\nexport const elements: (selector?: string) => ElementsFilter;\n\n// @public\nexport type ElementsFilter = (value: Node, index?: number, array?: Node[]) => boolean;\n\n// @public\nexport class ElementStyles {\n    constructor(styles: ReadonlyArray<ComposableStyles>);\n    // @internal (undocumented)\n    addStylesTo(target: StyleTarget): void;\n    // @internal (undocumented)\n    isAttachedTo(target: StyleTarget): boolean;\n    static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;\n    // @internal (undocumented)\n    removeStylesFrom(target: StyleTarget): void;\n    static setDefaultStrategy(Strategy: ConstructibleStyleStrategy): void;\n    get strategy(): StyleStrategy;\n    // (undocumented)\n    readonly styles: ReadonlyArray<ComposableStyles>;\n    static readonly supportsAdoptedStyleSheets: boolean;\n    withStrategy(Strategy: ConstructibleStyleStrategy): this;\n}\n\n// @public\nexport interface ElementView<TSource = any, TParent = any> extends View<TSource, TParent> {\n    appendTo(node: Node): void;\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): any;\n    }): void;\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface ElementViewTemplate<TSource = any, TParent = any> {\n    create(hostBindingTarget: Element): ElementView<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): ElementView<TSource, TParent>;\n}\n\n// @public\nexport const emptyArray: readonly never[];\n\n// @public\nexport function enableDebug(): void;\n\n// @public\nexport interface EventCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"event\";\n}\n\n// @public\nexport interface ExecutionContext<TParent = any> {\n    readonly event: Event;\n    eventDetail<TDetail>(): TDetail;\n    eventTarget<TTarget extends EventTarget>(): TTarget;\n    index: number;\n    readonly isEven: boolean;\n    readonly isFirst: boolean;\n    readonly isInMiddle: boolean;\n    readonly isLast: boolean;\n    readonly isOdd: boolean;\n    length: number;\n    parent: TParent;\n    parentContext: ExecutionContext<TParent>;\n}\n\n// @public\nexport const ExecutionContext: Readonly<{\n    default: ExecutionContext;\n    getEvent(): Event | null;\n    setEvent(event: Event | null): void;\n}>;\n\n// @public\nexport type Expression<TSource = any, TReturn = any, TParent = any> = (source: TSource, context: ExecutionContext<TParent>) => TReturn;\n\n// @public\nexport interface ExpressionController<TSource = any, TParent = any> {\n    readonly context: ExecutionContext<TParent>;\n    readonly isBound: boolean;\n    onUnbind(behavior: {\n        unbind(controller: ExpressionController<TSource, TParent>): any;\n    }): void;\n    readonly source: TSource;\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface ExpressionNotifier<TSource = any, TReturn = any, TParent = any> extends Notifier, ExpressionObserver<TSource, TReturn, TParent>, Disposable {\n    observe(source: TSource, context?: ExecutionContext): TReturn;\n    records(): IterableIterator<ObservationRecord>;\n    setMode(isAsync: boolean): void;\n}\n\n// @public\nexport interface ExpressionObserver<TSource = any, TReturn = any, TParent = any> {\n    bind(controller: ExpressionController<TSource, TParent>): TReturn;\n}\n\n// @public\nexport const FAST: {\n    warn(_code: number, _values?: Record<string, any>): void;\n    error(code: number, _values?: Record<string, any>): Error;\n    addMessages(messages: Record<number, string>): void;\n};\n\n// @public\nexport interface FASTElement extends HTMLElement {\n    $emit(type: string, detail?: any, options?: Omit<CustomEventInit, \"detail\">): boolean | void;\n    readonly $fastController: ElementController;\n    attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;\n    connectedCallback(): void;\n    disconnectedCallback(): void;\n}\n\n// @public\nexport const FASTElement: FASTElementConstructor;\n\n// @public\nexport interface FASTElementConstructor {\n    new (): FASTElement;\n    define<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(this: TType, nameOrDef: string | PartialFASTElementDefinition<TType>, extensions?: FASTElementExtension[]): Promise<TType>;\n    define<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition<TType>, extensions?: FASTElementExtension[]): Promise<TType>;\n    from<TBase extends typeof HTMLElement>(BaseType: TBase): {\n        new (): InstanceType<TBase> & FASTElement;\n    };\n}\n\n// @public\nexport class FASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributeLookup: Record<string, AttributeDefinition>;\n    readonly attributes: ReadonlyArray<AttributeDefinition>;\n    static compose<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition<TType>): Promise<FASTElementDefinition<TType>>;\n    define(registry?: CustomElementRegistry, extensions?: FASTElementExtension[]): this;\n    readonly elementOptions: ElementDefinitionOptions;\n    static readonly getByType: (key: Function) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    static readonly getForInstance: (object: any) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    get isDefined(): boolean;\n    readonly name: string;\n    readonly propertyLookup: Record<string, AttributeDefinition>;\n    // @internal\n    static registerBaseType(type: Function): void;\n    readonly registry: CustomElementRegistry;\n    schema?: Schema;\n    shadowOptions?: ShadowRootOptions;\n    readonly styles?: ElementStyles;\n    template?: ElementViewTemplate<InstanceType<TType>>;\n    readonly type: TType;\n}\n\n// @public\nexport type FASTElementExtension = (definition: FASTElementDefinition) => void;\n\n// @public\nexport interface FASTElementRegistry extends TypeRegistry<FASTElementDefinition> {\n    whenRegistered(name: string, registry?: CustomElementRegistry): Promise<FASTElementDefinition>;\n}\n\n// @public\nexport const fastElementRegistry: FASTElementRegistry;\n\n// @public\nexport type FASTElementTemplateResolver<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> = (definition: FASTElementDefinition<TType>) => ElementViewTemplate<InstanceType<TType>> | Promise<ElementViewTemplate<InstanceType<TType>>>;\n\n// @public\nexport interface HostBehavior<TSource = any> {\n    addedCallback?(controller: HostController<TSource>): void;\n    connectedCallback?(controller: HostController<TSource>): void;\n    disconnectedCallback?(controller: HostController<TSource>): void;\n    removedCallback?(controller: HostController<TSource>): void;\n}\n\n// @public\nexport interface HostController<TSource = any> extends ExpressionController<TSource> {\n    addBehavior(behavior: HostBehavior<TSource>): void;\n    addStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    readonly isConnected: boolean;\n    mainStyles: ElementStyles | null;\n    removeBehavior(behavior: HostBehavior<TSource>, force?: boolean): void;\n    removeStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n}\n\n// @public\nexport const html: HTMLTemplateTag;\n\n// @public\nexport class HTMLBindingDirective implements HTMLDirective, ViewBehaviorFactory, ViewBehavior, Aspected, BindingDirective {\n    constructor(dataBinding: Binding);\n    aspectType: DOMAspect;\n    // @internal\n    bind(controller: ViewController): void;\n    createBehavior(): ViewBehavior;\n    createHTML(add: AddViewBehaviorFactory): string;\n    dataBinding: Binding;\n    // @internal\n    handleChange(binding: Expression, observer: ExpressionObserver): void;\n    // @internal\n    handleEvent(event: Event): void;\n    id: string;\n    policy: DOMPolicy;\n    sourceAspect: string;\n    targetAspect: string;\n    targetNodeId: string;\n    targetTagName: string | null;\n    // @internal (undocumented)\n    unbind(controller: ViewController): void;\n}\n\n// @public\nexport interface HTMLDirective {\n    createHTML(add: AddViewBehaviorFactory): string;\n}\n\n// @public\nexport const HTMLDirective: Readonly<{\n    getForInstance: (object: any) => HTMLDirectiveDefinition<Constructable<HTMLDirective>> | undefined;\n    getByType: (key: Function) => HTMLDirectiveDefinition<Constructable<HTMLDirective>> | undefined;\n    define<TType extends Constructable<HTMLDirective>>(type: TType, options?: PartialHTMLDirectiveDefinition): TType;\n    assignAspect(directive: Aspected, value?: string): void;\n}>;\n\n// @public\nexport function htmlDirective(options?: PartialHTMLDirectiveDefinition): (type: Constructable<HTMLDirective>) => void;\n\n// @public\nexport interface HTMLDirectiveDefinition<TType extends Constructable<HTMLDirective> = Constructable<HTMLDirective>> extends Required<PartialHTMLDirectiveDefinition> {\n    readonly type: TType;\n}\n\n// @public\nexport interface HTMLTemplateCompilationResult<TSource = any, TParent = any> {\n    createView(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    // (undocumented)\n    readonly factories: CompiledViewBehaviorFactory[];\n}\n\n// @public\nexport type HTMLTemplateTag = (<TSource = any, TParent = any>(strings: TemplateStringsArray, ...values: TemplateValue<TSource, TParent>[]) => ViewTemplate<TSource, TParent>) & {\n    partial(html: string): InlineTemplateDirective;\n};\n\n// @public\nexport class HTMLView<TSource = any, TParent = any> extends DefaultExecutionContext<TParent> implements ElementView<TSource, TParent>, SyntheticView<TSource, TParent>, ExecutionContext<TParent> {\n    constructor(fragment: DocumentFragment, factories: ReadonlyArray<CompiledViewBehaviorFactory>, targets: ViewBehaviorTargets);\n    appendTo(node: Node): void;\n    bind(source: TSource, context?: ExecutionContext<TParent>): void;\n    context: ExecutionContext<TParent>;\n    dispose(): void;\n    static disposeContiguousBatch(views: SyntheticView[]): void;\n    firstChild: Node;\n    insertBefore(node: Node): void;\n    isBound: boolean;\n    isHydrated: Promise<boolean>;\n    isPrerendered: Promise<boolean>;\n    lastChild: Node;\n    // (undocumented)\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): void;\n    }): void;\n    remove(): void;\n    // @internal\n    _skipAttrUpdates: boolean;\n    source: TSource | null;\n    readonly sourceLifetime: SourceLifetime;\n    // (undocumented)\n    readonly targets: ViewBehaviorTargets;\n    unbind(): void;\n}\n\n// @public\nexport class InlineTemplateDirective implements HTMLDirective {\n    constructor(html: string, factories?: Record<string, ViewBehaviorFactory>);\n    createHTML(add: AddViewBehaviorFactory): string;\n    static readonly empty: InlineTemplateDirective;\n}\n\n// @public\nexport interface JSONSchema extends JSONSchemaCommon {\n    // (undocumented)\n    $defs?: Record<string, JSONSchemaDefinition>;\n    // (undocumented)\n    $id: string;\n    // (undocumented)\n    $schema: string;\n}\n\n// @public\nexport interface JSONSchemaCommon {\n    $observe?: boolean;\n    // (undocumented)\n    $ref?: string;\n    // (undocumented)\n    anyOf?: Array<any>;\n    // (undocumented)\n    items?: any;\n    // (undocumented)\n    properties?: any;\n    // (undocumented)\n    type?: string;\n}\n\n// @public\nexport interface JSONSchemaDefinition extends JSONSchemaCommon {\n    // (undocumented)\n    $fast_context: string;\n    // (undocumented)\n    $fast_parent_contexts: Array<string>;\n}\n\n// @public\nexport interface LengthObserver extends Subscriber {\n    length: number;\n}\n\n// @public\nexport function lengthOf<T>(array: readonly T[]): number;\n\n// @public\nexport function listener<T = any>(expression: Expression<T>, options?: AddEventListenerOptions): Binding<T>;\n\n// @public\nexport const Markup: Readonly<{\n    interpolation: (id: string) => string;\n    attribute: (id: string) => string;\n    comment: (id: string) => string;\n}>;\n\n// @public\nexport interface NodeBehaviorOptions<T = any> {\n    filter?: ElementsFilter;\n    property: T;\n}\n\n// @public\nexport abstract class NodeObservationDirective<T extends NodeBehaviorOptions> extends StatelessAttachedAttributeDirective<T> {\n    bind(controller: ViewController): void;\n    protected computeNodes(target: any): Node[];\n    protected abstract disconnect(target: any): void;\n    protected abstract getNodes(target: any): Node[];\n    protected getSource(target: Node): any;\n    get id(): string;\n    set id(value: string);\n    protected abstract observe(target: any): void;\n    targetNodeId: string;\n    unbind(controller: ViewController): void;\n    protected updateTarget(source: any, value: ReadonlyArray<any>): void;\n}\n\n// @public\nexport function normalizeBinding<TSource = any, TReturn = any, TParent = any>(value: Expression<TSource, TReturn, TParent> | Binding<TSource, TReturn, TParent> | {}): Binding<TSource, TReturn, TParent>;\n\n// @public\nexport interface Notifier {\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber, propertyToWatch?: any): void;\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: any): void;\n}\n\n// @public\nexport const nullableBooleanConverter: ValueConverter;\n\n// @public\nexport const nullableNumberConverter: ValueConverter;\n\n// @public\nexport const Observable: Readonly<{\n    setArrayObserverFactory(factory: (collection: any[]) => Notifier): void;\n    getNotifier: <T extends Notifier = Notifier>(source: any) => T;\n    track(source: unknown, propertyName: string): void;\n    trackVolatile(): void;\n    notify(source: unknown, args: any): void;\n    defineProperty(target: {}, nameOrAccessor: string | Accessor): void;\n    getAccessors: (target: {}) => Accessor[];\n    binding<TSource = any, TReturn = any>(expression: Expression<TSource, TReturn>, initialSubscriber?: Subscriber, isVolatileBinding?: boolean): ExpressionNotifier<TSource, TReturn>;\n    isVolatileBinding<TSource = any, TReturn = any>(expression: Expression<TSource, TReturn>): boolean;\n}>;\n\n// @public\nexport function observable(target: {}, nameOrAccessor: string | Accessor): void;\n\n// @public\nexport interface ObservationRecord {\n    propertyName: string;\n    propertySource: any;\n}\n\n// @public\nexport function oneTime<T = any>(expression: Expression<T>, policy?: DOMPolicy): Binding<T>;\n\n// @public\nexport function oneWay<T = any>(expression: Expression<T>, policy?: DOMPolicy, isVolatile?: boolean): Binding<T>;\n\n// @beta\nexport type OwnedState<T> = ReadonlyOwnedState<T> & {\n    set(owner: any, value: T): void;\n    asReadonly(): ReadonlyOwnedState<T>;\n};\n\n// @beta\nexport function ownedState<T>(value: T | (() => T), options?: string | StateOptions): OwnedState<T>;\n\n// @public\nexport const Parser: Readonly<{\n    parse(value: string, factories: Record<string, ViewBehaviorFactory>): (string | ViewBehaviorFactory)[] | null;\n}>;\n\n// @public\nexport interface PartialFASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributes?: (AttributeConfiguration | string)[];\n    readonly elementOptions?: ElementDefinitionOptions;\n    readonly name: string;\n    readonly registry?: CustomElementRegistry;\n    readonly schema?: Schema;\n    readonly shadowOptions?: Partial<ShadowRootOptions> | null;\n    readonly styles?: ComposableStyles | ComposableStyles[];\n    readonly template?: ElementViewTemplate<InstanceType<TType>> | FASTElementTemplateResolver<TType>;\n}\n\n// @public\nexport interface PartialHTMLDirectiveDefinition {\n    aspected?: boolean;\n}\n\n// @public\nexport class PropertyChangeNotifier implements Notifier {\n    constructor(subject: any);\n    notify(propertyName: string): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber, propertyToWatch?: string): void;\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: string): void;\n}\n\n// @beta\nexport function reactive<T>(object: T, deep?: boolean): T;\n\n// @beta\nexport type ReadonlyOwnedState<T> = {\n    (owner: any): T;\n};\n\n// @beta\nexport type ReadonlyState<T> = {\n    (): T;\n    readonly current: T;\n};\n\n// @public\nexport const ref: <TSource = any, TParent = any>(propertyName: keyof TSource & string) => CaptureType<TSource, TParent>;\n\n// @public\nexport class RefDirective extends StatelessAttachedAttributeDirective<string> {\n    bind(controller: ViewController): void;\n    targetNodeId: string;\n}\n\n// @public\nexport interface RegisterPathConfig {\n    // (undocumented)\n    childrenMap: ChildrenMap | null;\n    // (undocumented)\n    pathConfig: CachedPath;\n    // (undocumented)\n    rootPropertyName: string;\n}\n\n// @public\nexport function render<TSource = any, TItem = any, TParent = any>(value?: Expression<TSource, TItem> | Binding<TSource, TItem> | {}, template?: ContentTemplate | string | Expression<TSource, ContentTemplate | string | Node, TParent> | Binding<TSource, ContentTemplate | string | Node, TParent>): CaptureType<TSource, TParent>;\n\n// @public\nexport class RenderBehavior<TSource = any> implements ViewBehavior, Subscriber {\n    constructor(directive: RenderDirective);\n    bind(controller: ViewController): void;\n    // @internal\n    handleChange(source: any, observer: ExpressionObserver): void;\n    unbind(controller: ViewController): void;\n}\n\n// @public\nexport class RenderDirective<TSource = any> implements HTMLDirective, ViewBehaviorFactory, BindingDirective {\n    constructor(dataBinding: Binding<TSource>, templateBinding: Binding<TSource, ContentTemplate>, templateBindingDependsOnData: boolean);\n    createBehavior(): RenderBehavior<TSource>;\n    createHTML(add: AddViewBehaviorFactory): string;\n    // (undocumented)\n    readonly dataBinding: Binding<TSource>;\n    targetNodeId: string;\n    // (undocumented)\n    readonly templateBinding: Binding<TSource, ContentTemplate>;\n    // (undocumented)\n    readonly templateBindingDependsOnData: boolean;\n}\n\n// @public\nexport function repeat<TSource = any, TArray extends ReadonlyArray<any> = ReadonlyArray<any>, TParent = any>(items: Expression<TSource, TArray, TParent> | Binding<TSource, TArray, TParent> | ReadonlyArray<any>, template: Expression<TSource, ViewTemplate<any, TSource>> | Binding<TSource, ViewTemplate<any, TSource>> | ViewTemplate<any, TSource>, options?: RepeatOptions): CaptureType<TSource, TParent>;\n\n// @public\nexport class RepeatBehavior<TSource = any> implements ViewBehavior, Subscriber {\n    constructor(directive: RepeatDirective);\n    bind(controller: ViewController): void;\n    handleChange(source: any, args: Splice[] | Sort[] | ExpressionObserver): void;\n    unbind(): void;\n    // @internal (undocumented)\n    views: SyntheticView[];\n}\n\n// @public\nexport interface RepeatCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"repeat\";\n}\n\n// @public\nexport class RepeatDirective<TSource = any> implements HTMLDirective, ViewBehaviorFactory, BindingDirective {\n    constructor(dataBinding: Binding<TSource>, templateBinding: Binding<TSource, SyntheticViewTemplate>, options: RepeatOptions);\n    createBehavior(): RepeatBehavior<TSource>;\n    createHTML(add: AddViewBehaviorFactory): string;\n    // (undocumented)\n    readonly dataBinding: Binding<TSource>;\n    // (undocumented)\n    readonly options: RepeatOptions;\n    targetNodeId: string;\n    // (undocumented)\n    readonly templateBinding: Binding<TSource, SyntheticViewTemplate>;\n}\n\n// @public\nexport interface RepeatOptions {\n    positioning?: boolean;\n    recycle?: boolean;\n}\n\n// @public\nexport class Schema {\n    constructor(name: string);\n    addPath(config: RegisterPathConfig): void;\n    getRootProperties(): IterableIterator<string>;\n    getSchema(rootPropertyName: string): JSONSchema | null;\n}\n\n// @public\nexport const schemaRegistry: CachedPathMap;\n\n// @public\nexport interface ShadowRootOptions extends ShadowRootInit {\n    // @beta\n    registry?: CustomElementRegistry;\n}\n\n// @public\nexport const Signal: Readonly<{\n    subscribe(signal: string, subscriber: Subscriber): void;\n    unsubscribe(signal: string, subscriber: Subscriber): void;\n    send(signal: string): void;\n}>;\n\n// @public\nexport function signal<T = any>(expression: Expression<T>, options: string | Expression<T>, policy?: DOMPolicy): Binding<T>;\n\n// @public\nexport function slotted<TSource = any, TParent = any>(propertyOrOptions: (keyof TSource & string) | SlottedDirectiveOptions<keyof TSource & string>): CaptureType<TSource, TParent>;\n\n// @public\nexport class SlottedDirective extends NodeObservationDirective<SlottedDirectiveOptions> {\n    disconnect(target: EventSource): void;\n    getNodes(target: HTMLSlotElement): Node[];\n    // @internal (undocumented)\n    handleEvent(event: Event): void;\n    observe(target: EventSource): void;\n}\n\n// @public\nexport interface SlottedDirectiveOptions<T = any> extends NodeBehaviorOptions<T>, AssignedNodesOptions {\n}\n\n// @public\nexport class Sort {\n    constructor(sorted?: number[] | undefined);\n    // (undocumented)\n    sorted?: number[] | undefined;\n}\n\n// @public\nexport function sortedCount<T>(array: readonly T[]): number;\n\n// @public\nexport interface SortObserver extends Subscriber {\n    sorted: number;\n}\n\n// @public\nexport const SourceLifetime: Readonly<{\n    readonly unknown: undefined;\n    readonly coupled: 1;\n}>;\n\n// @public\nexport type SourceLifetime = (typeof SourceLifetime)[keyof typeof SourceLifetime];\n\n// @public\nexport class Splice {\n    constructor(index: number, removed: any[], addedCount: number);\n    // (undocumented)\n    addedCount: number;\n    adjustTo(array: any[]): this;\n    // (undocumented)\n    index: number;\n    // (undocumented)\n    removed: any[];\n    reset?: boolean;\n}\n\n// @public\nexport interface SpliceStrategy {\n    normalize(previous: unknown[] | undefined, current: unknown[], changes: Splice[] | undefined): readonly Splice[];\n    pop(array: any[], observer: ArrayObserver, pop: typeof Array.prototype.pop, args: any[]): any;\n    push(array: any[], observer: ArrayObserver, push: typeof Array.prototype.push, args: any[]): any;\n    reverse(array: any[], observer: ArrayObserver, reverse: typeof Array.prototype.reverse, args: any[]): any;\n    shift(array: any[], observer: ArrayObserver, shift: typeof Array.prototype.shift, args: any[]): any;\n    sort(array: any[], observer: ArrayObserver, sort: typeof Array.prototype.sort, args: any[]): any[];\n    splice(array: any[], observer: ArrayObserver, splice: typeof Array.prototype.splice, args: any[]): any;\n    readonly support: SpliceStrategySupport;\n    unshift(array: any[], observer: ArrayObserver, unshift: typeof Array.prototype.unshift, args: any[]): any[];\n}\n\n// @public\nexport const SpliceStrategy: Readonly<{\n    readonly reset: Splice[];\n    readonly setDefaultStrategy: (strategy: SpliceStrategy) => void;\n}>;\n\n// @public\nexport const SpliceStrategySupport: Readonly<{\n    readonly reset: 1;\n    readonly splice: 2;\n    readonly optimized: 3;\n}>;\n\n// @public\nexport type SpliceStrategySupport = (typeof SpliceStrategySupport)[keyof typeof SpliceStrategySupport];\n\n// @public\nexport const enum Stages {\n    connected = 1,\n    connecting = 0,\n    disconnected = 3,\n    disconnecting = 2\n}\n\n// @beta\nexport type State<T> = ReadonlyState<T> & {\n    current: T;\n    set(value: T): void;\n    asReadonly(): ReadonlyState<T>;\n};\n\n// @beta\nexport function state<T>(value: T, options?: string | StateOptions): State<T>;\n\n// @public\nexport abstract class StatelessAttachedAttributeDirective<TOptions> implements HTMLDirective, ViewBehaviorFactory, ViewBehavior {\n    constructor(options: TOptions);\n    abstract bind(controller: ViewController): void;\n    createBehavior(): ViewBehavior;\n    createHTML(add: AddViewBehaviorFactory): string;\n    // (undocumented)\n    protected options: TOptions;\n}\n\n// @beta\nexport type StateOptions = {\n    deep?: boolean;\n    name?: string;\n};\n\n// @public\nexport interface StyleStrategy {\n    addStylesTo(target: StyleTarget): void;\n    removeStylesFrom(target: StyleTarget): void;\n}\n\n// @public\nexport interface StyleTarget extends Pick<Node, \"getRootNode\"> {\n    adoptedStyleSheets?: CSSStyleSheet[];\n    append(styles: HTMLStyleElement): void;\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\n    removeChild(styles: HTMLStyleElement): void;\n}\n\n// @public\nexport interface Subscriber {\n    handleChange(subject: any, args: any): void;\n}\n\n// @public\nexport class SubscriberSet implements Notifier {\n    constructor(subject: any, initialSubscriber?: Subscriber);\n    has(subscriber: Subscriber): boolean;\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber): void;\n    unsubscribe(subscriber: Subscriber): void;\n}\n\n// @public\nexport interface SubtreeDirectiveOptions<T = any> extends NodeBehaviorOptions<T>, Omit<MutationObserverInit, \"subtree\" | \"childList\"> {\n    selector: string;\n    subtree: boolean;\n}\n\n// @public\nexport interface SyntheticView<TSource = any, TParent = any> extends View<TSource, TParent> {\n    readonly firstChild: Node;\n    insertBefore(node: Node): void;\n    readonly lastChild: Node;\n    remove(): void;\n}\n\n// @public\nexport interface SyntheticViewTemplate<TSource = any, TParent = any> {\n    create(): SyntheticView<TSource, TParent>;\n    inline(): CaptureType<TSource, TParent>;\n}\n\n// @public\nexport type TemplateValue<TSource, TParent = any> = Expression<TSource, any, TParent> | Binding<TSource, any, TParent> | HTMLDirective | CaptureType<TSource, TParent>;\n\n// @public\nexport type TrustedTypesPolicy = {\n    createHTML(html: string): string;\n};\n\n// @public\nexport function twoWay<T = any>(expression: Expression<T>, optionsOrChangeEvent?: TwoWayBindingOptions | string, policy?: DOMPolicy, isBindingVolatile?: boolean): Binding<T>;\n\n// @public\nexport type TwoWayBindingOptions = {\n    changeEvent?: string;\n    fromView?: (value: any) => any;\n};\n\n// @public\nexport interface TwoWaySettings {\n    determineChangeEvent(bindingSource: BindingDirective, target: HTMLElement): string;\n}\n\n// @public\nexport const TwoWaySettings: Readonly<{\n    configure(settings: TwoWaySettings): void;\n}>;\n\n// @public\nexport interface TypeDefinition {\n    type: Function;\n}\n\n// @public\nexport interface TypeRegistry<TDefinition extends TypeDefinition> {\n    getByType(key: Function): TDefinition | undefined;\n    getForInstance(object: any): TDefinition | undefined;\n    register(definition: TDefinition): boolean;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"UnobservableMutationObserver\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal\nexport class UnobservableMutationObserver extends MutationObserver {\n    constructor(callback: MutationCallback);\n    // (undocumented)\n    observe(target: Node, options?: MutationObserverInit | undefined): void;\n    // (undocumented)\n    unobserve(target: Node): void;\n}\n\n// @public\nexport interface UpdateQueue {\n    enqueue(callable: Callable): void;\n    next(): Promise<void>;\n    process(): void;\n    setMode(isAsync: boolean): void;\n}\n\n// @public\nexport const Updates: UpdateQueue;\n\n// @public\nexport interface ValueConverter {\n    fromView(value: any): any;\n    toView(value: any): any;\n}\n\n// @public\nexport interface View<TSource = any, TParent = any> extends Disposable {\n    bind(source: TSource, context?: ExecutionContext<TParent>): void;\n    readonly context: ExecutionContext<TParent>;\n    readonly isBound: boolean;\n    readonly source: TSource | null;\n    unbind(): void;\n}\n\n// @public\nexport interface ViewBehavior<TSource = any, TParent = any> {\n    bind(controller: ViewController<TSource, TParent>): void;\n}\n\n// @public\nexport interface ViewBehaviorFactory {\n    createBehavior(): ViewBehavior;\n    id?: string;\n    policy?: DOMPolicy;\n    targetNodeId?: string;\n    targetTagName?: string | null;\n}\n\n// @public\nexport interface ViewBehaviorOrchestrator<TSource = any, TParent = any> extends ViewController<TSource, TParent>, HostBehavior<TSource> {\n    addBehavior(behavior: ViewBehavior): void;\n    addBehaviorFactory(factory: ViewBehaviorFactory, target: Node): void;\n    // (undocumented)\n    addTarget(nodeId: string, target: Node): void;\n}\n\n// @public\nexport const ViewBehaviorOrchestrator: Readonly<{\n    create<TSource = any, TParent = any>(source: TSource): ViewBehaviorOrchestrator<TSource, TParent>;\n}>;\n\n// @public\nexport type ViewBehaviorTargets = {\n    [id: string]: Node;\n};\n\n// @public\nexport interface ViewController<TSource = any, TParent = any> extends ExpressionController<TSource, TParent> {\n    readonly isHydrated?: Promise<boolean>;\n    readonly isPrerendered?: Promise<boolean>;\n    // @internal\n    readonly _skipAttrUpdates?: boolean;\n    readonly targets: ViewBehaviorTargets;\n}\n\n// @public\nexport class ViewTemplate<TSource = any, TParent = any> implements ElementViewTemplate<TSource, TParent>, SyntheticViewTemplate<TSource, TParent> {\n    constructor(html: string | HTMLTemplateElement, factories?: Record<string, ViewBehaviorFactory>, policy?: DOMPolicy | undefined);\n    // @internal (undocumented)\n    compile(): HTMLTemplateCompilationResult<TSource, TParent>;\n    create(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    static create<TSource = any, TParent = any>(strings: string[], values: TemplateValue<TSource, TParent>[], policy?: DOMPolicy): ViewTemplate<TSource, TParent>;\n    readonly factories: Record<string, ViewBehaviorFactory>;\n    readonly html: string | HTMLTemplateElement;\n    inline(): CaptureType<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    withPolicy(policy: DOMPolicy): this;\n}\n\n// @public\nexport function volatile(target: {}, name: string | Accessor, descriptor: PropertyDescriptor): PropertyDescriptor;\n\n// @beta\nexport function watch(object: any, subscriber: Subscriber | ((subject: any, args: any) => void)): Disposable;\n\n// @public\nexport function when<TSource = any, TReturn = any, TParent = any>(condition: Expression<TSource, TReturn, TParent> | boolean, templateOrTemplateBinding: SyntheticViewTemplate<TSource, TParent> | Expression<TSource, SyntheticViewTemplate<TSource, TParent>, TParent>, elseTemplateOrTemplateBinding?: SyntheticViewTemplate<TSource, TParent> | Expression<TSource, SyntheticViewTemplate<TSource, TParent>, TParent>): CaptureType<TSource, TParent>;\n\n```\n","packages/fast-element/docs/architecture/fastelement.md":"# FASTElement\n\nThe `FASTElement` is our extension of the `HTMLElement`. As such it leverages the lifecycles but also requires additional setup before before the class `constructor` or the `connectedCallback` method is executed which are explained in the [overview](./overview.md). This document explains specifically what `FASTElement` leverages inside the `HTMLElement`s lifecycle hooks.\n\nFor an explanation into `HTMLElement` lifecycle hooks refer to the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks).\n\nBecause `FASTElement` extends `HTMLElement`, it is a browser `Window` runtime\nAPI. It is not intended to execute in workers, server-side JavaScript runtimes,\nor other non-window hosts where custom element lifecycle callbacks and animation\nframe scheduling are unavailable.\n\n## A Custom Element is Detected by the Browser\n\nBecause the `FASTElement` is an extension of the `HTMLElement`, it makes use of the same lifecycle hooks and extends them with `$fastController`. It also initializes using another class `ElementController`, the methods this are called during the custom elements native `constructor`, `connectedCallback`, `disconnectedCallback`, and `attributeChangedCallback` lifecycle hooks.\n\n### 🔄 **Lifecycle**: Initialization\n\n```mermaid\nflowchart TD\n    A[A <code>FASTElement</code> web component is added to the <code>DOM</code>] --> B\n    B[<code>FASTElement</code> initializes the <code>ElementController.forCustomElement</code> passing the Custom Element instance] --> C\n    B --> F[Observables applied to the <code>FASTElement</code> are updated on the FAST global without values]\n    C{Is an <code>ElementController</code> available?}\n    C --> |yes|E\n    C --> |no|D\n    D[Initialize a new <code>ElementController</code> referred to as setting an element controller strategy]\n    D --> F\n    E[<code>ElementController</code> captures the Custom Element instance and the definition and attaches them to the <code>$fastController</code> which is then attached to the instance]\n```\n\n### 🔄 **Lifecycle**: Component is connected\n\n```mermaid\nflowchart TD\n    A[browser <code>HTMLElement</code>'s <code>connectedCallback</code> is called] --> B\n    B[<code>this.$fastController.connect</code> in FASTElement is called] --> C\n    B --> D\n    B --> E\n    B --> F\n    C[bind observables by capturing public own Custom Element properties and setting those values through the matching accessors]\n    D[connect behaviors by call the <code>connectedCallback</code> on all behaviors]\n    E[render template, execute an <code>ElementViewTemplate</code>'s render method]\n    F[add styles either as an appended <code>StyleElement</code> node or an <code>adoptedStylesheet</code> which may include and attach behaviors]\n```\n\n#### Render Template\n\nThe rendering of the template on the `ElementController` is by the `renderTemplate` method which is called during the `ElementController.connect` method which is triggered by `HTMLElement`s `connectedCallback` lifecycle.\n\nThe `renderTemplate` identifies the Custom Element, and the shadow root associated with the Custom Element. This then places a rendering of the template (an `ElementView`) onto the internal `view` of the controller. When creating the `ElementView`/`HTMLView` using the `ViewTemplate.render`, the `Compiler.compile()` method identifies a `DocumentFragment` either by using an existing `<template>` tag, or creating one to wrap the contents of the shadow root. A new `CompilationContext` is created and the `compileAttributes` function is called, this results in the replacement of the placeholder attributes initally set-up during the pre-render step with their values if a value has been assigned. The factories with the associated nodes identified are then passed to the context. The view then binds all behaviors to the source element. The `CompilationContext.createView` is executed with the `DocumentFragment` as the root, and returns an `HTMLView`. This `HTMLView` includes an `appendTo` method to attach the fragment to the host element, which it then does. It should be noted that the compiled HTML is a `string`, which when set on the `DocumentFragment` as `innerHTML`, this allows the browser to dictate the creation of HTML nodes.\n\n### 🔄 **Lifecycle**: Component is disconnected\n\nWhen a component is disconnected, a cleanup step is created to remove associated behaviors.\n\n### 🔄 **Lifecycle**: Attribute has been changed\n\nAttributes have an `AttributeDefinition` which allows for converters, attachment of the `<attributName>Changed` aspect of the `@attr` decorator among other capabilities.\n\n```mermaid\nflowchart TD\n    A[The browser <code>HTMLElement</code>'s <code>attributeChangedCallback</code> is called] --> B\n    B[<code>this.$fastController.onAttributeChangedCallback</code> in <code>FASTElement</code> is called] --> C\n    C[calls the attribute definitions <code>onAttributeChangedCallback</code> method with the updated value] --> D\n    D[An <code>Updates.enqueue</code> is called which places the update in the task queue which is then executed, these are performed async unless otherwise specified]\n```\n\nThese changes are observed and similar to the way `Observables` work, they utilize an `Accessor` pattern which has a `getValue` and `setValue` in which DOM updates are applied.\n\nObservable backing slots such as `_foo` are FAST-owned internal state. The\ncontroller's connection-time observable binding only replays public own\nproperties that shadow prototype accessors; it does not normalize backing slots\ninto public property assignments. This keeps attribute converter output in its\nalready-converted model form while preserving pre-upgrade public property\nassignments and opt-in extension behavior.","packages/fast-element/docs/architecture/html-tagged-template-literal.md":"# `html` tagged template literal\n\nThe `html` export from `@microsoft/fast-element` is used to create the template logic for the custom element.\n\n## Pre-processing the `html` tagged template literal contents\n\nBefore the template can be used it goes through a step to convert it into a `ViewTemplate` which it does via the `ViewTemplate.create()` method. This is then used during the `compose` step, before `FASTElement` is instantiated.\n\nDuring the static `ViewTemplate.create()` method (called by the `html` tag), the following happens for each string:\n- Factories with unique IDs are created for each tag template literal argument (or `TemplateValue`) which matches with the corresponding string\n- A binding is created from the `TemplateValue`\n\nThe `Compiler.compile()` method is called lazily the first time the template is rendered (via `ViewTemplate.compile()`, which is triggered by `ViewTemplate.create()` instance method or `ViewTemplate.render()`).\n\nA resulting string using a `createHTML()` function is produced using the `HTMLDirective`s executed for each factory. The behavior is augmented by the previous string from the `html` tag template which determines the aspect if one exists, these aspects are the `@`, `:`, or other binding aspect attached to attributes.\n\nThe `createHTML()` function utilizes a `Markup` attribute which is assigned to a factory's unique ID. The strings are concatenated and passed to a new `ViewTemplate` with all the factories (empty until one is assigned) that act as a dictionary with the unique IDs as the key to look up each factory once it has been created. The string this creates is injected into a `<template>` as `innerHTML`, which allows the browser to create the nodes and placeholder factory IDs, with the only `DOM` node that is explicitly created being the wrapping `<template>` element.\n\n## Directives\n\nThe `HTMLBindingDirective` applies bindings to items identified as various `TemplateValue`s within the `html` tagged template. The `createHTML` step uses the factory associated with the binding to create strings in the markup using the factory's ID.\n\n```mermaid\nflowchart TD\n    A[A <code>new HTMLBindingDirective</code> is created with a data binding which has a policy, options, <code>createObserver</code>, and an evaluate method assigned to the passed arrow function such as <pre>x => x.foo</pre>]\n    B[<code>oneTime</code> binding passes the corresponding tag template argument, an arrow function]\n    C[<code>oneWay</code> binding passes a copy of the corresponding tag template argument, an arrow function]\n    D[An already specified binding such as a <code>repeat</code> or <code>when</code> directive is passed]\n    A --> B\n    A --> C\n    A --> D\n    E[When a <code>createObserver</code> is called, an <code>Observable.binding</code> is created passing the arrow function to be evaluated and the subscriber to be notified]\n    C --> E\n    F[When a <code>createObserver</code> is called, the instance of the one time binding is returned which includes a bind method returning the arrow function executed against the controller source and context]\n    B --> F\n```\n","packages/fast-element/docs/architecture/intro.md":"# Introduction\n\nThis document (and the linked documents) explains how the exports and side effects of `@microsoft/fast-element` are used to create custom elements.\n\n`@microsoft/fast-element` is designed to run in a client-side browser `Window`\nruntime. Its element lifecycle, rendering, and update queue assume browser DOM,\nCustom Elements, Shadow DOM, and `requestAnimationFrame` are available. Workers,\nserver-side JavaScript runtimes, and other non-window hosts are not supported\ntargets for the FAST Element client runtime.\n\n## Glossary\n\n- [Overview](./overview.md): How the `@microsoft/fast-element` should be used by a developer and what code is executed during the first render.\n- [`FASTElement`](./fastelement.md): How the `FASTElement` is architected.\n- [`html` tagged template literal](./html-tagged-template-literal.md): How the `html` tagged template literal takes and converts the contents into a `ViewTemplate`.\n- [`Updates` queue](./updates.md): How updates to attributes and observables are processed.","packages/fast-element/docs/architecture/overview.md":"# General FAST usage\n\n`FASTElement` is an extension of `HTMLElement` which makes use of Custom Element APIs native to the browser. It also supplies the following methods:\n\n- The `define` method combines the Custom Element name, template, style, and other options into a `FASTElementDefinition`, then uses the native Custom Element [`define()`](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define) to register the Custom Element with a Custom Element Registry.\n- The `from` method allows the use of Customized Built-in elements, which extend from native elements such as `HTMLButtonElement`.\n\n### Creating a Custom Element from FASTElement\n\nA basic developer flow for defining a custom element looks like this:\n\n```mermaid\nflowchart TD\n    A[Create a <code>FASTElement</code> web component by extending the <code>FASTElement</code> class] --> F\n    F[Prepare the definition with template and styles] --> G[Define the component in the browser with <code>define()</code>]\n```\n\nLet's take a look at the definition step to see what the FAST architecture is doing at this stage.\n\n### Defining a Custom Element\n\nThe subclass `define()` method creates a new `FASTElementDefinition`, which includes all metadata needed for the element (such as templates, attributes, and styles), and registers it with the configured Custom Element Registry. The resulting object can be retrieved via `ElementController.definition`.\n\n## A Custom Element in JavaScript is sent to the Browser\n\nLet's step back from defining the Custom Element and consider what is happening when we import from the `@microsoft/fast-element` package.\n\nThe FAST Element client runtime is expected to run in the browser `Window`.\nCustom element definition, connection, rendering, and update scheduling all rely\non browser APIs such as the Custom Element Registry, DOM, Shadow DOM, and\n`requestAnimationFrame`.\n\nFirst, a global `FAST` property will be created if one does not already exist, typically in browser on the `window`.\n\nAdditionally, when Custom Elements are included in a script a few things might happen even before a Custom Element gets detected by the browser. First, there are initial side effects caused by the use of decorators. These include the `attr` decorator from `@microsoft/fast-element` and the `observable` decorator from `@microsoft/fast-element`.\n\nHere is a basic flow of what code is executed and when during initial load of a script that contains a FAST defined Custom Element:\n\n```mermaid\nflowchart TD\n    A@{ shape: circle, label: \"The browser loads the JavaScript file containing FAST and FAST Custom Element definitions\" }\n    B@{ shape: rect, label: \"The FAST global is added to the window\" }\n    A --> B\n    C@{ shape: rect, label: \"A Custom Element executes the <code>compose</code> step\"}\n    B --> C\n    D@{ shape: procs, label: \"<ul style='text-align: left'><li>Any defined observable decorators are added to the FAST global</li><li>An attribute decorator locates the associated Custom Elements constructor which it uses to push itself to the Custom Elements attribute collection</li></ul>\"}\n    C --> D\n    F@{ shape: rect, label: \"An HTML tagged template literal is executed for the FAST Custom Element and applied to the definition\" }\n    D --> F\n    G@{ shape: rect, label: \"The <code>define</code> step is hit and the <code>customElement</code> is registered with the Custom Element Registry\" }\n    F --> G\n    H@{ shape: rect, label: \"A Custom Element is detected on the page and the browser initializes it\" }\n    I@{ shape: dbl-circ, label: \"The lifecycle steps for <code>FASTElement</code> are executed\" }\n    G --> H\n    H --> I\n```\n","packages/fast-element/docs/architecture/updates.md":"# `Updates`\n\nThe `Updates` API batches FAST Element DOM work in the client-side browser\n`Window` runtime. Queued work includes updates to attributes, observables, and\nobserved arrays. The async queue is aligned to `requestAnimationFrame`, which is\nexpected to be available in the supported runtime.\n\nFAST Element is not intended to run its client runtime in workers, server-side\nJavaScript runtimes, or other non-window hosts. Code that needs server rendering\nshould generate HTML for the browser, then let the browser window run FAST\nElement, connect custom elements, and process queued updates.\n\n## Attributes\n\nAn attribute change may be queued when the value of the attribute is updated. This change is triggered by `HTMLElement` lifecycle hook `attributeChangedCallback`. The `Updates` queue is used to try to reflect the attribute with the updated value onto the element using `DOM` APIs.\n\n## Observables\n\nThe `Reflect` API is used to override `defineProperty` in order to observe a property on an Custom Element, this overrides the getter and setter, which allows subscribers to be notified of changes. Any changes which `set` the value are passed to the `Updates` queue.","packages/fast-element/docs/arrays/api-report.api.md":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport interface ArrayObserver extends SubscriberSet {\n    addSort(sort: Sort): void;\n    addSplice(splice: Splice): void;\n    flush(): void;\n    readonly lengthObserver: LengthObserver;\n    reset(oldCollection: any[] | undefined): void;\n    readonly sortObserver: SortObserver;\n    strategy: SpliceStrategy | null;\n}\n\n// @public\nexport const ArrayObserver: Readonly<{\n    readonly sorted: 0;\n    readonly enable: () => void;\n}>;\n\n// @public\nexport interface LengthObserver extends Subscriber {\n    length: number;\n}\n\n// @public\nexport function lengthOf<T>(array: readonly T[]): number;\n\n// @public\nexport interface Notifier {\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber, propertyToWatch?: any): void;\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: any): void;\n}\n\n// @public\nexport class Sort {\n    constructor(sorted?: number[] | undefined);\n    // (undocumented)\n    sorted?: number[] | undefined;\n}\n\n// @public\nexport function sortedCount<T>(array: readonly T[]): number;\n\n// @public\nexport interface SortObserver extends Subscriber {\n    sorted: number;\n}\n\n// @public\nexport class Splice {\n    constructor(index: number, removed: any[], addedCount: number);\n    // (undocumented)\n    addedCount: number;\n    adjustTo(array: any[]): this;\n    // (undocumented)\n    index: number;\n    // (undocumented)\n    removed: any[];\n    reset?: boolean;\n}\n\n// @public\nexport interface SpliceStrategy {\n    normalize(previous: unknown[] | undefined, current: unknown[], changes: Splice[] | undefined): readonly Splice[];\n    pop(array: any[], observer: ArrayObserver, pop: typeof Array.prototype.pop, args: any[]): any;\n    push(array: any[], observer: ArrayObserver, push: typeof Array.prototype.push, args: any[]): any;\n    reverse(array: any[], observer: ArrayObserver, reverse: typeof Array.prototype.reverse, args: any[]): any;\n    shift(array: any[], observer: ArrayObserver, shift: typeof Array.prototype.shift, args: any[]): any;\n    sort(array: any[], observer: ArrayObserver, sort: typeof Array.prototype.sort, args: any[]): any[];\n    splice(array: any[], observer: ArrayObserver, splice: typeof Array.prototype.splice, args: any[]): any;\n    readonly support: SpliceStrategySupport;\n    unshift(array: any[], observer: ArrayObserver, unshift: typeof Array.prototype.unshift, args: any[]): any[];\n}\n\n// @public\nexport const SpliceStrategy: Readonly<{\n    readonly reset: Splice[];\n    readonly setDefaultStrategy: (strategy: SpliceStrategy) => void;\n}>;\n\n// @public\nexport const SpliceStrategySupport: Readonly<{\n    readonly reset: 1;\n    readonly splice: 2;\n    readonly optimized: 3;\n}>;\n\n// @public\nexport type SpliceStrategySupport = (typeof SpliceStrategySupport)[keyof typeof SpliceStrategySupport];\n\n// @public\nexport interface Subscriber {\n    handleChange(subject: any, args: any): void;\n}\n\n// @public\nexport class SubscriberSet implements Notifier {\n    constructor(subject: any, initialSubscriber?: Subscriber);\n    has(subscriber: Subscriber): boolean;\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber): void;\n    unsubscribe(subscriber: Subscriber): void;\n}\n\n// (No @packageDocumentation comment for this package)\n\n```\n","packages/fast-element/docs/context/api-report.api.md":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport type Context<T> = {\n    readonly name: string;\n    readonly initialValue?: T;\n};\n\n// @public\nexport const Context: Readonly<{\n    eventType: \"context-request\";\n    for<T = unknown>(name: string): FASTContext<T>;\n    create<T = unknown>(name: string, initialValue?: T): FASTContext<T>;\n    setDefaultRequestStrategy(strategy: FASTContextRequestStrategy): void;\n    get<T extends UnknownContext>(target: EventTarget, context: T): ContextType<T>;\n    request<T extends UnknownContext>(target: EventTarget, context: T, callback: ContextCallback<ContextType<T>>, multiple?: boolean): void;\n    dispatch<T extends UnknownContext>(target: EventTarget, context: T, callback: ContextCallback<ContextType<T>>, multiple?: boolean): void;\n    provide<T extends UnknownContext>(target: EventTarget, context: T, value: ContextType<T>): void;\n    handle<T extends UnknownContext>(target: EventTarget, callback: (event: ContextEvent<T>) => void, context?: T): void;\n    defineProperty<T extends UnknownContext>(target: Constructable<EventTarget> | EventTarget, propertyName: string, context: T): void;\n}>;\n\n// @public\nexport type ContextCallback<ValueType> = (value: ValueType, dispose?: () => void) => void;\n\n// Warning: (ae-forgotten-export) The symbol \"ParameterDecorator_2\" needs to be exported by the entry point context.d.ts\n//\n// @public\nexport type ContextDecorator<T = any> = Readonly<Context<T>> & PropertyDecorator & ParameterDecorator_2;\n\n// @public\nexport class ContextEvent<T extends UnknownContext> extends Event {\n    constructor(context: T, callback: ContextCallback<ContextType<T>>, multiple?: boolean | undefined);\n    // (undocumented)\n    readonly callback: ContextCallback<ContextType<T>>;\n    // (undocumented)\n    readonly context: T;\n    // (undocumented)\n    readonly multiple?: boolean | undefined;\n}\n\n// @public\nexport type ContextType<T extends UnknownContext> = T extends Context<infer Y> ? Y : never;\n\n// @public\nexport type FASTContext<T> = ContextDecorator<T> & {\n    get(target: EventTarget): T;\n    provide(target: EventTarget, value: T): void;\n    request(target: EventTarget, callback: ContextCallback<T>, multiple?: boolean): void;\n    handle(target: EventTarget, callback: (event: ContextEvent<FASTContext<T>>) => void): void;\n};\n\n// @public\nexport type FASTContextRequestStrategy = <T extends UnknownContext>(target: EventTarget, context: T, callback: ContextCallback<ContextType<T>>, multiple: any) => void;\n\n// @public\nexport type UnknownContext = Context<unknown>;\n\n// Warnings were encountered during analysis:\n//\n// dist/dts/context.d.ts:127:5 - (ae-forgotten-export) The symbol \"Constructable\" needs to be exported by the entry point context.d.ts\n\n// (No @packageDocumentation comment for this package)\n\n```\n","packages/fast-element/docs/declarative/api-report.api.md":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport interface AccessCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"access\";\n}\n\n// @public\nexport interface Accessor {\n    getValue(source: any): any;\n    name: string;\n    setValue(source: any, value: any): void;\n}\n\n// @public\nexport type AttributeConfiguration = {\n    property: string;\n    attribute?: string;\n    mode?: AttributeMode;\n    converter?: ValueConverter;\n};\n\n// @public\nexport const AttributeConfiguration: Readonly<{\n    locate: (target: {}) => AttributeConfiguration[];\n}>;\n\n// @public\nexport class AttributeDefinition implements Accessor {\n    constructor(Owner: Function, name: string, attribute?: string, mode?: AttributeMode, converter?: ValueConverter);\n    readonly attribute: string;\n    // @internal\n    static collect(Owner: Function, ...attributeLists: (ReadonlyArray<string | AttributeConfiguration> | undefined)[]): ReadonlyArray<AttributeDefinition>;\n    readonly converter?: ValueConverter;\n    getValue(source: HTMLElement): any;\n    readonly mode: AttributeMode;\n    readonly name: string;\n    // @internal (undocumented)\n    onAttributeChangedCallback(element: HTMLElement, value: any): void;\n    readonly Owner: Function;\n    setValue(source: HTMLElement, newValue: any): void;\n}\n\n// @public\nexport type AttributeMode = \"reflect\" | \"boolean\" | \"fromView\";\n\n// @public\nexport type CachedPath = DefaultCachedPath | RepeatCachedPath | AccessCachedPath | EventCachedPath;\n\n// @public\nexport interface CachedPathCommon {\n    // (undocumented)\n    currentContext: string | null;\n    // (undocumented)\n    parentContext: string | null;\n    // (undocumented)\n    path: string;\n}\n\n// @public\nexport type CachedPathMap = Map<string, Map<string, JSONSchema>>;\n\n// @public\nexport interface CaptureType<TSource = any, TParent = any> {\n}\n\n// @public\nexport interface ChildrenMap {\n    // (undocumented)\n    attributeName: string;\n    // (undocumented)\n    customElementName: string;\n}\n\n// @public\nexport type ComposableStyles = string | ElementStyles | CSSStyleSheet;\n\n// @public\nexport type Constructable<T = {}> = {\n    new (...args: any[]): T;\n};\n\n// @public\nexport type ConstructibleStyleStrategy = {\n    new (styles: (string | CSSStyleSheet)[]): StyleStrategy;\n};\n\n// @public\nexport function declarativeTemplate<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(): FASTElementTemplateResolver<TType>;\n\n// @public\nexport interface DefaultCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"default\";\n}\n\n// @public\nexport const DOMAspect: Readonly<{\n    readonly none: 0;\n    readonly attribute: 1;\n    readonly booleanAttribute: 2;\n    readonly property: 3;\n    readonly content: 4;\n    readonly tokenList: 5;\n    readonly event: 6;\n}>;\n\n// @public\nexport type DOMAspect = (typeof DOMAspect)[Exclude<keyof typeof DOMAspect, \"none\">];\n\n// @public\nexport type DOMAspectGuards = {\n    [DOMAspect.attribute]?: DOMSinkGuards;\n    [DOMAspect.booleanAttribute]?: DOMSinkGuards;\n    [DOMAspect.property]?: DOMSinkGuards;\n    [DOMAspect.content]?: DOMSinkGuards;\n    [DOMAspect.tokenList]?: DOMSinkGuards;\n    [DOMAspect.event]?: DOMSinkGuards;\n};\n\n// @public\nexport type DOMElementGuards = Record<string, DOMAspectGuards>;\n\n// @public\nexport type DOMGuards = {\n    elements: DOMElementGuards;\n    aspects: DOMAspectGuards;\n};\n\n// @public\nexport interface DOMPolicy {\n    createHTML(value: string): string;\n    protect(tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink): DOMSink;\n}\n\n// @public\nexport const DOMPolicy: Readonly<{\n    create(options?: DOMPolicyOptions): Readonly<DOMPolicy>;\n}>;\n\n// @public\nexport type DOMPolicyOptions = {\n    trustedType?: TrustedTypesPolicy;\n    guards?: Partial<DOMGuards>;\n};\n\n// @public\nexport type DOMSink = (target: Node, aspectName: string, value: any, ...args: any[]) => void;\n\n// @public\nexport type DOMSinkGuards = Record<string, (tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink) => DOMSink>;\n\n// @public\nexport class ElementStyles {\n    constructor(styles: ReadonlyArray<ComposableStyles>);\n    // @internal (undocumented)\n    addStylesTo(target: StyleTarget): void;\n    // @internal (undocumented)\n    isAttachedTo(target: StyleTarget): boolean;\n    static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;\n    // @internal (undocumented)\n    removeStylesFrom(target: StyleTarget): void;\n    static setDefaultStrategy(Strategy: ConstructibleStyleStrategy): void;\n    get strategy(): StyleStrategy;\n    // (undocumented)\n    readonly styles: ReadonlyArray<ComposableStyles>;\n    static readonly supportsAdoptedStyleSheets: boolean;\n    withStrategy(Strategy: ConstructibleStyleStrategy): this;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"View\" needs to be exported by the entry point index.d.ts\n//\n// @public\nexport interface ElementView<TSource = any, TParent = any> extends View<TSource, TParent> {\n    appendTo(node: Node): void;\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): any;\n    }): void;\n    // Warning: (ae-forgotten-export) The symbol \"SourceLifetime\" needs to be exported by the entry point index.d.ts\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface ElementViewTemplate<TSource = any, TParent = any> {\n    create(hostBindingTarget: Element): ElementView<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): ElementView<TSource, TParent>;\n}\n\n// @public\nexport interface EventCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"event\";\n}\n\n// @public\nexport class FASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributeLookup: Record<string, AttributeDefinition>;\n    readonly attributes: ReadonlyArray<AttributeDefinition>;\n    static compose<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition<TType>): Promise<FASTElementDefinition<TType>>;\n    define(registry?: CustomElementRegistry, extensions?: FASTElementExtension[]): this;\n    readonly elementOptions: ElementDefinitionOptions;\n    static readonly getByType: (key: Function) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    static readonly getForInstance: (object: any) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    get isDefined(): boolean;\n    readonly name: string;\n    readonly propertyLookup: Record<string, AttributeDefinition>;\n    // @internal\n    static registerBaseType(type: Function): void;\n    readonly registry: CustomElementRegistry;\n    schema?: Schema;\n    shadowOptions?: ShadowRootOptions;\n    readonly styles?: ElementStyles;\n    template?: ElementViewTemplate<InstanceType<TType>>;\n    readonly type: TType;\n}\n\n// @public\nexport type FASTElementExtension = (definition: FASTElementDefinition) => void;\n\n// @public\nexport type FASTElementTemplateResolver<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> = (definition: FASTElementDefinition<TType>) => ElementViewTemplate<InstanceType<TType>> | Promise<ElementViewTemplate<InstanceType<TType>>>;\n\n// @public\nexport interface HTMLTemplateCompilationResult<TSource = any, TParent = any> {\n    createView(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    // Warning: (ae-forgotten-export) The symbol \"CompiledViewBehaviorFactory\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    readonly factories: CompiledViewBehaviorFactory[];\n}\n\n// Warning: (ae-forgotten-export) The symbol \"DefaultExecutionContext\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"SyntheticView\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"ExecutionContext\" needs to be exported by the entry point index.d.ts\n//\n// @public\nexport class HTMLView<TSource = any, TParent = any> extends DefaultExecutionContext<TParent> implements ElementView<TSource, TParent>, SyntheticView<TSource, TParent>, ExecutionContext<TParent> {\n    constructor(fragment: DocumentFragment, factories: ReadonlyArray<CompiledViewBehaviorFactory>, targets: ViewBehaviorTargets);\n    appendTo(node: Node): void;\n    bind(source: TSource, context?: ExecutionContext<TParent>): void;\n    context: ExecutionContext<TParent>;\n    dispose(): void;\n    static disposeContiguousBatch(views: SyntheticView[]): void;\n    firstChild: Node;\n    insertBefore(node: Node): void;\n    isBound: boolean;\n    isHydrated: Promise<boolean>;\n    isPrerendered: Promise<boolean>;\n    lastChild: Node;\n    // (undocumented)\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): void;\n    }): void;\n    remove(): void;\n    // @internal\n    _skipAttrUpdates: boolean;\n    source: TSource | null;\n    readonly sourceLifetime: SourceLifetime;\n    // Warning: (ae-forgotten-export) The symbol \"ViewBehaviorTargets\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    readonly targets: ViewBehaviorTargets;\n    unbind(): void;\n}\n\n// @public\nexport interface JSONSchema extends JSONSchemaCommon {\n    // (undocumented)\n    $defs?: Record<string, JSONSchemaDefinition>;\n    // (undocumented)\n    $id: string;\n    // (undocumented)\n    $schema: string;\n}\n\n// @public\nexport interface JSONSchemaCommon {\n    $observe?: boolean;\n    // (undocumented)\n    $ref?: string;\n    // (undocumented)\n    anyOf?: Array<any>;\n    // (undocumented)\n    items?: any;\n    // (undocumented)\n    properties?: any;\n    // (undocumented)\n    type?: string;\n}\n\n// @public\nexport interface JSONSchemaDefinition extends JSONSchemaCommon {\n    // (undocumented)\n    $fast_context: string;\n    // (undocumented)\n    $fast_parent_contexts: Array<string>;\n}\n\n// @public\nexport interface PartialFASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributes?: (AttributeConfiguration | string)[];\n    readonly elementOptions?: ElementDefinitionOptions;\n    readonly name: string;\n    readonly registry?: CustomElementRegistry;\n    readonly schema?: Schema;\n    readonly shadowOptions?: Partial<ShadowRootOptions> | null;\n    readonly styles?: ComposableStyles | ComposableStyles[];\n    readonly template?: ElementViewTemplate<InstanceType<TType>> | FASTElementTemplateResolver<TType>;\n}\n\n// @public\nexport interface RegisterPathConfig {\n    // (undocumented)\n    childrenMap: ChildrenMap | null;\n    // (undocumented)\n    pathConfig: CachedPath;\n    // (undocumented)\n    rootPropertyName: string;\n}\n\n// @public\nexport interface RepeatCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"repeat\";\n}\n\n// @public\nexport interface ResolvedStringsAndValues {\n    // (undocumented)\n    strings: Array<string>;\n    // (undocumented)\n    values: Array<any>;\n}\n\n// @public\nexport class Schema {\n    constructor(name: string);\n    addPath(config: RegisterPathConfig): void;\n    getRootProperties(): IterableIterator<string>;\n    getSchema(rootPropertyName: string): JSONSchema | null;\n}\n\n// @public\nexport const schemaRegistry: CachedPathMap;\n\n// @public\nexport interface ShadowRootOptions extends ShadowRootInit {\n    // @beta\n    registry?: CustomElementRegistry;\n}\n\n// @public\nexport interface StyleStrategy {\n    addStylesTo(target: StyleTarget): void;\n    removeStylesFrom(target: StyleTarget): void;\n}\n\n// @public\nexport interface StyleTarget extends Pick<Node, \"getRootNode\"> {\n    adoptedStyleSheets?: CSSStyleSheet[];\n    append(styles: HTMLStyleElement): void;\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\n    removeChild(styles: HTMLStyleElement): void;\n}\n\n// @public\nexport interface SyntheticViewTemplate<TSource = any, TParent = any> {\n    create(): SyntheticView<TSource, TParent>;\n    inline(): CaptureType<TSource, TParent>;\n}\n\n// @public\nexport class TemplateParser {\n    createTemplate(strings: Array<string>, values: Array<any>): ViewTemplate<any, any>;\n    parse(innerHTML: string, schema: Schema): ResolvedStringsAndValues;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"Expression\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"Binding\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"HTMLDirective\" needs to be exported by the entry point index.d.ts\n//\n// @public\nexport type TemplateValue<TSource, TParent = any> = Expression<TSource, any, TParent> | Binding<TSource, any, TParent> | HTMLDirective | CaptureType<TSource, TParent>;\n\n// @public\nexport type TrustedTypesPolicy = {\n    createHTML(html: string): string;\n};\n\n// @public\nexport interface ValueConverter {\n    fromView(value: any): any;\n    toView(value: any): any;\n}\n\n// @public\nexport interface ViewBehavior<TSource = any, TParent = any> {\n    bind(controller: ViewController<TSource, TParent>): void;\n}\n\n// @public\nexport interface ViewBehaviorFactory {\n    createBehavior(): ViewBehavior;\n    id?: string;\n    policy?: DOMPolicy;\n    targetNodeId?: string;\n    targetTagName?: string | null;\n}\n\n// @public\nexport class ViewTemplate<TSource = any, TParent = any> implements ElementViewTemplate<TSource, TParent>, SyntheticViewTemplate<TSource, TParent> {\n    constructor(html: string | HTMLTemplateElement, factories?: Record<string, ViewBehaviorFactory>, policy?: DOMPolicy | undefined);\n    // @internal (undocumented)\n    compile(): HTMLTemplateCompilationResult<TSource, TParent>;\n    create(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    static create<TSource = any, TParent = any>(strings: string[], values: TemplateValue<TSource, TParent>[], policy?: DOMPolicy): ViewTemplate<TSource, TParent>;\n    readonly factories: Record<string, ViewBehaviorFactory>;\n    readonly html: string | HTMLTemplateElement;\n    inline(): CaptureType<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    withPolicy(policy: DOMPolicy): this;\n}\n\n// Warnings were encountered during analysis:\n//\n// dist/dts/templating/view.d.ts:45:9 - (ae-forgotten-export) The symbol \"ViewController\" needs to be exported by the entry point index.d.ts\n\n// (No @packageDocumentation comment for this package)\n\n```\n","packages/fast-element/docs/declarative/design.md":"# Declarative HTML Design\n\nThis document is intended for contributors who want to understand the internal\narchitecture of the declarative runtime and schema-driven map extensions in\n`@microsoft/fast-element`. It covers the feature's purpose, core concepts, data\nflow, and its integration with the rest of `@microsoft/fast-element`.\n\n## Table of Contents\n\n1. [Overview](#overview)\n2. [Goals](#goals)\n3. [Core Concepts](#core-concepts)\n4. [Package Structure](#package-structure)\n5. [Exports and Public API](#exports-and-public-api)\n6. [Template Syntax](#template-syntax)\n7. [Data Flow](#data-flow)\n8. [Template Parsing Pipeline](#template-parsing-pipeline)\n9. [Schema and Observer Map](#schema-and-observer-map)\n10. [Lifecycle](#lifecycle)\n11. [Integration with fast-element](#integration-with-fast-element)\n12. [Hydration Model](#hydration-model)\n13. [Testing Architecture](#testing-architecture)\n14. [Further Reading](#further-reading)\n\n---\n\n## Overview\n\n`@microsoft/fast-element` lets you write FAST Web Component\ntemplates as plain HTML rather than JavaScript `html` tagged template literals.\nThe browser-side JS bundle defines FAST's internal native `<f-template>`\npublisher on demand. It parses declarative template markup at runtime and\nreturns a `ViewTemplate` to the waiting FAST element definition through the\nregistry-aware declarative template bridge.\n\n```html\n<!-- Declarative template — stack-agnostic, no JS needed to render -->\n<my-component greeting=\"Hello\">\n    <template shadowrootmode=\"open\">\n        <!--fe:b-->Hello<!--fe:/b-->\n    </template>\n</my-component>\n\n<!-- Template definition — parsed once by the browser bundle -->\n<f-template name=\"my-component\">\n    <template>{{greeting}}</template>\n</f-template>\n```\n\n---\n\n## Goals\n\n| Goal | Description |\n|---|---|\n| **Server-agnostic rendering** | Templates are plain HTML strings with no dependency on Node.js or any specific SSR framework. |\n| **Progressive enhancement** | Components can be server-rendered and then hydrated client-side without a full re-render. |\n| **FAST parity** | The declarative syntax maps 1-to-1 to FAST Element directive helpers (`repeat`, `when`, `slotted`, `children`, `ref`) exported from `@microsoft/fast-element`. |\n| **Minimal authoring overhead** | Component authors write HTML, not tagged template strings, while retaining full reactive capabilities. |\n\n---\n\n## Core Concepts\n\n### `<f-template>` — the internal template publisher\n\n`<f-template>` is an internal custom element implemented as a lightweight native\n`HTMLElement`. It is defined automatically by `declarativeTemplate()` in the same\n`CustomElementRegistry` as the FAST element definition. Consumers should not\nimport, subclass, or define the implementation directly.\n\nWhen connected to the DOM it:\n\n1. Registers itself with the declarative template bridge using its registry and\n   `name` attribute.\n2. Publishes a template when a matching FAST element definition requests one.\n3. Delegates parsing of the inner `<template>` tag to `TemplateParser`, which\n   converts declarative bindings into FAST `ViewTemplate` strings and values.\n4. Runs definition-scoped schema transforms, such as `attributeMap()` and\n   `observerMap()`, before returning the concrete `ViewTemplate`.\n\nWhen multiple connected `<f-template>` publishers share the same `name`, the\nbridge resolves pending definitions from the first connected publisher and keeps\nthe resolved template stable. Later duplicate publishers do not reassign the\ndefinition template.\n\n### `TemplateParser` — declarative HTML parser\n\nA standalone class that converts declarative HTML template markup into the\n`strings` and `values` arrays that `ViewTemplate.create()` consumes. It is used\nby the internal `<f-template>` publisher but can also be used independently for\nprogrammatic template compilation. The parsing pipeline is fully synchronous —\nno promises are allocated during template resolution. A `StringsAccumulator`\ntracks the running concatenation of preceding HTML, eliminating repeated O(N)\n`join(\"\")` calls at each binding site. `createTemplate()` lazily installs the\ndeclarative runtime's debug messages; hydration support is installed only by\n`enableHydration()`.\n\n### `Schema` — JSON schema builder\n\nBuilt during declarative template parsing, one `Schema` instance per\n`<f-template>`. Non-declarative callers can also create and attach a `Schema`\nmanually. It records every binding path discovered in the template or supplied\nby code and constructs a JSON Schema-compatible data structure. This schema:\n\n- Describes the shape of each root property referenced in the template.\n- Tracks repeat context chains (parent/child array relationships).\n- Uses an instance-level `schemaMap` for its own property schemas.\n- Registers itself in the module-level `schemaRegistry` (keyed by custom element name) for cross-element `$ref` resolution.\n\n`FASTElementDefinition.schema` is optional. `declarativeTemplate()` assigns it\nautomatically after parsing; manual schema users can pass `schema` in the\ndefinition object.\n\n### `ObserverMap` — automatic observable setup\n\nAn optional layer that uses the `Schema` to automatically:\n\n- Call `Observable.defineProperty()` for every root property on the element prototype.\n- Install property-change handlers that wrap newly assigned objects/arrays in `Proxy` instances.\n- Propagate deep property mutations back through FAST's observable system so bindings re-render.\n\nEnabled via the `observerMap()` definition extension exported from\n`@microsoft/fast-element/observer-map.js`. Calling `observerMap()` without\narguments observes all root properties discovered in the template or supplied\nschema.\n\n#### Path-level observation control\n\nThe `ObserverMapConfig` interface accepts an optional `schema` for\nnon-declarative/manual schema use and an optional `properties` key that maps\nroot property names to a recursive path tree controlling observation\ngranularity:\n\n```typescript\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [\n        observerMap({\n            properties: {\n                user: {\n                    name: true,          // user.name — observed\n                    details: {\n                        age: true,       // user.details.age — observed\n                        history: false,  // user.details.history — NOT observed\n                    },\n                },\n                // root properties not listed here are skipped\n            },\n        }),\n    ],\n);\n```\n\nEach path entry can be:\n- **`true`** — observe this path and all descendants (unless overridden deeper).\n- **`false`** — skip this path and all descendants (unless overridden deeper).\n- **`ObserverMapPathNode`** — an object with an optional `$observe` boolean and child property overrides, allowing alternating opt-in/opt-out to arbitrary depth.\n\nWhen `properties` is omitted, all root properties are observed. When\n`properties` is present but empty (`{ properties: {} }`), no root properties\nare observed.\n\nObserver-map-managed array updates replace the array reference when `deepMerge`\nreceives a new array. This avoids mutating an existing observed array while it\nmay be notifying subscribers and lets repeat bindings observe the new array\nreference. Replaced arrays are wrapped with the schema for the assigned\nproperty, and array observer subscriptions are installed once per array so\nreprocessing does not duplicate accessors or notification work.\n\nFor non-declarative elements, pass a schema directly to `observerMap()`:\n\n```typescript\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-element\");\nschema.addPath({\n    rootPropertyName: \"user\",\n    pathConfig: {\n        type: \"default\",\n        parentContext: null,\n        currentContext: null,\n        path: \"user.name\",\n    },\n    childrenMap: null,\n});\n\nMyElement.define({ name: \"my-element\" }, [observerMap({ schema })]);\n```\n\nThe resolution algorithm walks the schema and configuration tree in parallel:\n1. If `properties` is present and a root property is not listed, it is skipped.\n2. `true`/`false` booleans apply to the entire subtree.\n3. `$observe` on a node object controls the current level; children inherit when unspecified.\n4. Paths in the config but not in the schema are silently ignored (forward-compatible).\n\n### `AttributeMap` — automatic `@attr` definitions\n\nAn optional layer that uses the `Schema` to automatically register `@attr`-style reactive properties for every **leaf binding** in the template — i.e. simple expressions like `{{foo}}` or `id=\"{{foo-bar}}\"` that have no nested properties, no explicit type, and no child element references.\n\n- By default (`attribute-name-strategy: \"camelCase\"`), the binding key is treated as a camelCase property name and the HTML attribute name is derived by converting it to kebab-case (e.g. `{{fooBar}}` → property `fooBar`, attribute `foo-bar`). This matches the build-time `--attribute-name-strategy` option in `@microsoft/fast-build`.\n- When `attribute-name-strategy` is `\"none\"`, the **attribute name** and **property name** are both the binding key exactly as written in the template (e.g. `{{foo-bar}}` → attribute `foo-bar`, property `foo-bar`). No normalization is applied.\n- Because HTML attributes are case-insensitive, binding keys should use lowercase names (optionally dash-separated) when using the `\"none\"` strategy.\n- Properties already decorated with `@attr` or `@observable` are left untouched.\n- `FASTElementDefinition.attributeLookup` is keyed by the HTML attribute name, and `propertyLookup` is keyed by the JS property name so `attributeChangedCallback` correctly delegates to the new `AttributeDefinition`.\n\nEnabled via the `attributeMap()` definition extension exported from\n`@microsoft/fast-element/attribute-map.js`. Calling `attributeMap()` without\narguments uses the default `\"camelCase\"` strategy. To preserve binding keys\nexactly as written, pass `attributeMap({ \"attribute-name-strategy\": \"none\" })`.\nOutside declarative templates, `attributeMap()` uses the optional `schema` on the\nFAST element definition.\n\n### Syntax constants (`syntax.ts`)\n\nAll delimiters used by the parser are defined in a single `Syntax` interface and exported as named constants from `syntax.ts`. This makes the syntax pluggable and easy to audit.\n\n| Constant | Value | Use |\n|---|---|---|\n| `openExpression` / `closeExpression` | `{{` / `}}` | Default (SSR-compatible) binding |\n| `unescapedOpenExpression` / `unescapedCloseExpression` | `{{{` / `}}}` | Raw HTML binding |\n| `clientSideOpenExpression` / `clientSideCloseExpression` | `{` / `}` | Client-only (event / attribute directive) binding |\n| `repeatDirectiveOpen` / `repeatDirectiveClose` | `<f-repeat` / `</f-repeat>` | Repeat directive |\n| `whenDirectiveOpen` / `whenDirectiveClose` | `<f-when` / `</f-when>` | When directive |\n| `attributeDirectivePrefix` | `f-` | Attribute directive prefix |\n| `eventArgAccessor` | `$e` | DOM event argument |\n| `executionContextAccessor` | `$c` | Execution context argument |\n\n---\n\n## Package Structure\n\n```\npackages/fast-element/\n├── src/\n│   ├── components/\n│   │   ├── schema.ts          # Shared Schema class + schemaRegistry\n│   │   └── definition-schema-transforms.ts # Definition-scoped schema transform storage\n│   ├── declarative/\n│       ├── index.ts           # Public declarative entrypoint implementation\n│       ├── interfaces.ts      # Message enum (error codes)\n│       ├── debug.ts           # Human-readable declarative debug messages\n│       ├── template.ts        # declarativeTemplate(), internal <f-template> publisher, lifecycle orchestration\n│       ├── template-bridge.ts # Registry/name bridge between definitions and publishers\n│       ├── template-parser.ts # TemplateParser — converts declarative HTML to ViewTemplate strings/values\n│       ├── observer-map.ts    # observerMap() implementation\n│       ├── attribute-map.ts   # attributeMap() implementation\n│       ├── observer-map-utilities.ts # Shared observer-map helpers\n│       ├── utilities.ts       # Declarative parsing helpers\n│       └── syntax.ts          # Syntax delimiter constants\n│   └── hydration/\n│       ├── markers.ts         # Default 3.x marker reader and marker strategy contract\n│       └── markers-v2.ts      # Opt-in 2.x indexed marker reader\n├── scripts/\n│   └── declarative/           # Fixture build + webui integration scripts\n└── test/\n    └── declarative/fixtures/  # One directory per feature, each with spec + index.html + main.ts\n```\n\n### Module dependency direction\n\nThe default `declarativeTemplate()` path avoids importing optional map\nimplementations. Map helpers attach schema transforms to the definition only\nwhen the consumer passes them as define extensions.\n\n```\ndeclarative/template.ts ──imports──▶ components/definition-schema-transforms.ts (schema transform reads)\ndeclarative/template.ts ──imports──▶ components/schema.ts (Schema)\ndeclarative/attribute-map.ts ──imports──▶ components/definition-schema-transforms.ts (register attribute-map transform)\ndeclarative/observer-map.ts ──imports──▶ components/definition-schema-transforms.ts (register observer-map transform)\ndeclarative/observer-map.ts ──imports──▶ components/schema.ts (Schema types)\ndeclarative/attribute-map.ts ──imports──▶ components/schema.ts (Schema types)\ndeclarative/utilities.ts ──imports──▶ components/schema.ts (schemaRegistry for cross-element $ref resolution)\n```\n\nSchema transforms run in deterministic order. `attributeMap()` runs before\n`observerMap()`, so generated attributes are available to observer mapping.\n\n---\n\n## Exports and Public API\n\n```typescript\nimport {\n    declarativeTemplate,\n    TemplateParser,\n    type ResolvedStringsAndValues,\n} from \"@microsoft/fast-element/declarative.js\";\nimport {\n    Schema,\n    schemaRegistry,\n    type CachedPathMap,\n    type JSONSchema,\n} from \"@microsoft/fast-element/schema.js\";\nimport { type FASTElementExtension } from \"@microsoft/fast-element\";\nimport {\n    attributeMap,\n    type AttributeMapConfig,\n} from \"@microsoft/fast-element/attribute-map.js\";\nimport {\n    observerMap,\n    type ObserverMapConfig,\n    type ObserverMapPathEntry,\n    type ObserverMapPathNode,\n} from \"@microsoft/fast-element/observer-map.js\";\n```\n\nDeclarative template helpers, map helpers, and their configuration types are\navailable from focused path exports.\n\nPrimary declarative exports intended for application code:\n\n| Export | Purpose |\n|---|---|\n| `declarativeTemplate()` | `@microsoft/fast-element/declarative.js` template resolver for subclass `define()` calls; auto-defines the internal `<f-template>` publisher and waits for the matching template. |\n| `TemplateParser` | `@microsoft/fast-element/declarative.js` standalone parser that converts declarative HTML into `ViewTemplate` strings/values. Can be used independently of `<f-template>` for programmatic template compilation. |\n| `Schema` | `@microsoft/fast-element/schema.js` JSON schema builder that records binding paths discovered during template parsing. Each instance owns its own schema map and registers itself in the `schemaRegistry` for cross-element `$ref` resolution. |\n| `schemaRegistry` | `@microsoft/fast-element/schema.js` module-level `Map<string, Map<string, JSONSchema>>` that indexes schemas by custom element name. Used for cross-element lookups (e.g. nested component `$ref` resolution). |\n\nHydration marker selection is available from\n`@microsoft/fast-element/hydration.js`. FAST Element 3.x data-free markers are\nthe default; `enableHydration({ markers: markers_v2 })` opts into the FAST Element 2.x\nindexed marker reader for staged server/client migrations.\n\nPrimary map extension exports:\n\n| Export | Import path | Purpose |\n|---|---|---|\n| `attributeMap()` | `@microsoft/fast-element/attribute-map.js` | Define extension that registers `@attr`-style properties for leaf bindings discovered during parsing or supplied by `definition.schema`. |\n| `observerMap()` | `@microsoft/fast-element/observer-map.js` | Define extension that defines observable root properties and proxy-based deep change tracking from `config.schema`, `definition.schema`, or a declarative template schema. |\n\nThe implementation element class (`<f-template>`), `TemplateElement.config()`,\n`TemplateElement.options()`, `ElementOptions*`, and\n`HydrationLifecycleCallbacks` are not exported from the public declarative\nentrypoint. Use `declarativeTemplate()`, `attributeMap()`, `observerMap()`, and\n`enableHydration()` instead. The `AttributeMap` and `ObserverMap` implementation\nclasses are available for advanced scenarios, but application code should\nnormally use the extension factories.\n\nAdditionally, `@microsoft/fast-element` exports these types:\n\n| Type | Source Module | Purpose |\n|---|---|---|\n| `FASTElementExtension` | `fast-definitions.ts` | Definition extension callback signature used by `attributeMap()` and `observerMap()`. |\n| `JSONSchema` | `components/schema.ts` | JSON Schema interface used by `Schema` for property structure. |\n| `CachedPathMap` | `components/schema.ts` | `Map<string, Map<string, JSONSchema>>` — the shape of the schema registry. |\n\nThe map configuration types are exported from the same map-specific paths:\n\n| Type | Import path | Purpose |\n|---|---|---|\n| `ObserverMapConfig` | `@microsoft/fast-element/observer-map.js` | Configuration object for `observerMap()`; accepts optional `schema` and `properties` keys. |\n| `ObserverMapPathEntry` | `@microsoft/fast-element/observer-map.js` | `boolean \\| ObserverMapPathNode` — a node in the observation path tree. |\n| `ObserverMapPathNode` | `@microsoft/fast-element/observer-map.js` | Object node with optional `$observe` and child property overrides. |\n| `AttributeMapConfig` | `@microsoft/fast-element/attribute-map.js` | Configuration object for `attributeMap()`; accepts `attribute-name-strategy`. |\n\n---\n\n## Template Syntax\n\nThe declarative syntax is a superset of HTML with three binding delimiters:\n\n| Syntax | Example | Behaviour |\n|---|---|---|\n| `{{expr}}` | `{{greeting}}` | SSR-compatible content / attribute binding |\n| `{{{expr}}}` | `{{{rawHtml}}}` | Unescaped HTML (wraps in `<div :innerHTML>`) |\n| `{expr}` | `@click=\"{handleClick($e)}\"` | Client-only binding (events, attribute directives) |\n\n### Directives\n\nBindings and FAST directive markup inside HTML comments are unsupported. The\nstring-based parsers do not reliably exclude comment contents, so commenting out\nbound markup can still affect binding discovery and hydration. See the\n[HTML comment restrictions](./syntax.md#html-comments).\n\n| Directive | Example |\n|---|---|\n| `<f-when value=\"{{expr}}\">` | Conditional rendering |\n| `<f-repeat value=\"{{item in list}}\">` | List rendering |\n| `f-slotted=\"{prop}\"` | Slotted nodes attribute directive |\n| `f-children=\"{prop}\"` | Children attribute directive |\n| `f-ref=\"{prop}\"` | Element ref attribute directive |\n\nFor full syntax reference see [syntax.md](./syntax.md).\n\n---\n\n## Data Flow\n\nThe high-level data flow from authoring to interactive component:\n\n```mermaid\nflowchart TD\n    A[\"Author writes declarative HTML\nusing f-template with binding expressions\"] --> B[\"Server renders hydratable HTML\nwith fe:b comments and data-fe attributes\"]\n    B --> C[Browser loads JS bundle]\n    C --> D[\"MyElement.define called\nwith template: declarativeTemplate()\"]\n    D --> E[\"declarativeTemplate() defines internal f-template\nin the target registry\"]\n    E --> F[\"f-template connects to DOM\n→ registers publisher with bridge\"]\n    F --> G[\"definition requests template\nvia registry + name bridge\"]\n    G --> H[transformInnerHTML normalises HTML entities]\n    H --> I[\"TemplateParser parses bindings/directives\nbuilds Schema, strings, values\"]\n    I --> J[\"Run definition schema transforms\nattributeMap before observerMap\"]\n    J --> K[\"ViewTemplate.create(strings, values)\nreturned to definition\"]\n    K --> L[\"FASTElementDefinition.define\nregisters element with platform\"]\n    L --> M{\"enableHydration() called?\"}\n    M -- yes --> N[\"ElementController hydrates existing DOM\nvia template.hydrate()\"]\n    M -- no --> O[\"ElementController client-side renders\nexisting DSD is not reused\"]\n    N --> P[Interactive component]\n    O --> P\n```\n\n---\n\n## Template Parsing Pipeline\n\nThe internal `<f-template>` publisher orchestrates the pipeline by creating a\n`TemplateParser` instance and delegating all parsing logic to it. The recursive\nparsing context is encapsulated in a `TemplateResolutionContext` object internal\nto the parser, keeping method signatures lean.\n\n### Architecture\n\nThe parsing pipeline is split across two classes plus definition-scoped\ntransforms:\n\n- **Internal `<f-template>` publisher** (`template.ts`) — Custom element\n  lifecycle, registry/name bridge registration, template publication, and\n  schema-transform execution. It is a native `HTMLElement`, not a `FASTElement`.\n- **`TemplateParser`** (`template-parser.ts`) — Synchronous template parser:\n  converts declarative HTML into `strings`/`values` arrays for\n  `ViewTemplate.create()`. Uses a `StringsAccumulator` to track the running\n  previous-string in O(1) per binding site instead of O(N) `join(\"\")` calls.\n  Independently testable without DOM.\n- **Schema transforms** (`definition-options.ts`) — Extension-provided callbacks run\n  after parsing and before `ViewTemplate.create()`. `attributeMap()` runs before\n  `observerMap()`.\n\n```mermaid\nsequenceDiagram\n    participant DOM\n    participant FTE as internal f-template\n    participant TP as TemplateParser\n    participant U as utilities.ts\n    participant S as Schema\n    participant Transforms as schema transforms\n\n    DOM->>FTE: connectedCallback()\n    FTE->>FTE: register publisher with bridge\n    FTE->>FTE: publishTemplate(definition)\n    FTE->>S: new Schema(name)\n    FTE->>U: transformInnerHTML(this.innerHTML)\n    FTE->>TP: parser.parse(innerHTML, schema)\n    loop getNextBehavior(innerHTML)\n        TP->>U: getNextBehavior()\n        U-->>TP: DataBindingBehaviorConfig | TemplateDirectiveBehaviorConfig\n        alt content binding\n            TP->>TP: resolveContentBinding()\n            TP->>TP: resolveAccessBinding()\n            TP->>U: bindingResolver()\n            U->>S: schema.addPath()\n            U-->>TP: (x,c) => value function\n        else attribute binding\n            TP->>TP: resolveAttributeBinding()\n            alt event (@)\n                TP->>TP: resolveEventBinding()\n            else boolean (?)\n                TP->>U: getBooleanBinding() or resolveAccessBinding()\n            else default\n                TP->>TP: resolveAccessBinding()\n            end\n        else attributeDirective (slotted / children / ref)\n            TP->>TP: resolveAttributeDirectiveBinding()\n        else templateDirective (when / repeat)\n            TP->>TP: resolveTemplateDirective()\n            note over TP: recurses into resolveStringsAndValues\n        end\n    end\n    TP-->>FTE: { strings, values }\n    FTE->>Transforms: attributeMap(), then observerMap()\n    FTE->>TP: parser.createTemplate(strings, values)\n    FTE-->>DOM: return ViewTemplate to definition resolver\n```\n\n### TemplateParser method decomposition\n\n| Method | Visibility | Role |\n|---|---|---|\n| `parse()` | public | Entry point: parses declarative HTML into `{ strings, values }`. |\n| `createTemplate()` | public | Creates a `ViewTemplate` from resolved strings and values, lazily installing declarative debug messages. |\n| `resolveStringsAndValues()` | private | Creates `strings`/`values` arrays and delegates to `resolveInnerHTML()`. |\n| `resolveInnerHTML()` | private | Recursive HTML parser that dispatches to data binding or template directive handlers. |\n| `resolveDataBinding()` | private | Thin dispatcher that routes to `resolveContentBinding()`, `resolveAttributeBinding()`, or `resolveAttributeDirectiveBinding()`. |\n| `resolveContentBinding()` | private | Handles `{{expression}}` in text content. |\n| `resolveAttributeBinding()` | private | Handles `{{expression}}` in HTML attributes; dispatches to `resolveEventBinding()` or `resolveAccessBinding()` based on aspect. |\n| `resolveAttributeDirectiveBinding()` | private | Handles `f-children`, `f-slotted`, `f-ref` directives. |\n| `resolveAccessBinding()` | private | Shared helper for access-type bindings (content, boolean-attribute fallback, default attribute). |\n| `resolveEventBinding()` | private | Handles event bindings (`@event`), including arg parsing and owner resolution. |\n| `resolveTemplateDirective()` | private | Handles `<f-when>` and `<f-repeat>` directives. |\n| `resolveAttributeDirective()` | private | Creates FAST `children()`, `slotted()`, or `ref()` directives. |\n\n### TemplateResolutionContext\n\nThe `TemplateResolutionContext` interface (internal to `TemplateParser`) groups the stable fields that flow through the recursive parsing pipeline:\n\n```typescript\ninterface TemplateResolutionContext {\n    parentContext: string | null;  // Current repeat item alias (e.g. \"item\")\n    level: number;          // Nesting depth for repeat directives\n    schema: Schema;         // JSON schema builder for property tracking\n}\n```\n\n`rootPropertyName` is intentionally kept separate because it is selectively mutated per branch and must not leak across sibling binding resolutions.\n\n### Key parsing functions (utilities.ts)\n\n| Function | Role |\n|---|---|\n| `getNextBehavior(innerHTML)` | Top-level scanner: returns the next `DataBindingBehaviorConfig` or `TemplateDirectiveBehaviorConfig`, or `null` when done. |\n| `getNextDataBindingBehavior(innerHTML)` | Identifies whether the next binding is `{{}}`, `{{{}}}`, or `{}` and classifies it as content/attribute/attributeDirective. |\n| `getNextDirectiveBehavior(innerHTML)` | Finds the next `<f-when>` or `<f-repeat>` and its matching close tag. |\n| `bindingResolver(...)` | Builds a `(x, c) => value` closure for a given path; also calls `schema.addPath()`. |\n| `pathResolver(path, contextPath, level, schema)` | Returns a closure that traverses an object using dot-notation, handling repeat context levels. |\n| `getBooleanBinding(...)` | Returns a `(x, c) => boolean` closure for `<f-when>` expressions. |\n| `assignObservables(schema, rootSchema, data, target, rootProperty)` | Wraps objects/arrays in `Proxy` for deep observation. |\n| `deepMerge(target, source)` | Merges source into an existing proxy, preserving proxy identity and triggering observable notifications. |\n| `transformInnerHTML(html)` | Normalises HTML-encoded operator characters (`&gt;`, `&lt;`, etc.) used in `<f-when>` expressions. |\n| `escapeBracesInCodeElements(html)` | Replaces `{` / `}` characters inside every `<code>` element with `&#123;` / `&#125;` so binding-like syntax in code samples renders literally rather than being interpreted as FAST bindings. Client-side half of a two-stage escape — the brace escape mirrors the server-side pass in `microsoft-fast-build` (necessary client-side because `&#123;` / `&#125;` decode back to literal `{` / `}` in the DOM and `.innerHTML` does not re-encode them). The angle-bracket escape for FAST directive tags (`<f-when>`, `</f-when>`, `<f-repeat>`, `</f-repeat>`) inside `<code>` runs only on the server because the DOM serializer re-encodes `<` / `>` in text content automatically. Real HTML elements (`<button>`) and custom elements inside `<code>` keep their angle brackets and continue to render as live DOM elements. Modeled on Microsoft WebUI's `webui-press` markdown renderer. |\n\n### Binding classification\n\n```\ninnerHTML token\n  ├── {{{ ... }}}  → unescaped content binding  (innerHTML div)\n  ├── {{ ... }}    → default binding\n  │     ├── attr=\"{{expr}}\"    → attribute binding   (aspect: null / \":\" / \"?\")\n  │     └── {{expr}} in text  → content binding\n  └── { ... }      → client-side binding\n        ├── @event=\"{handler(...)}\"  → event binding (aspect \"@\")\n        └── f-dir=\"{prop}\"           → attribute directive binding\n```\n\n---\n\n## Schema and Observer Map\n\nThe `Schema` class accumulates all binding paths discovered during parsing into an instance-level JSON Schema map (`schemaMap`) indexed by `rootPropertyName → JSONSchema`. Each `Schema` instance also registers itself in the module-level `schemaRegistry` (keyed by custom element name) for cross-element `$ref` resolution.\n\n```mermaid\nflowchart LR\n    A[\"Template binding\\nuser.details.age\"] --> B[bindingResolver]\n    B --> C[schema.addPath\\ntype:'access'\\npath:'user.details.age'\\nrootProperty:'user']\n    C --> D[\"schema.schemaMap\\n{'user' => JSONSchema}\"]\n    C --> D2[\"schemaRegistry\\n{'my-el' => schemaMap}\"]\n    D --> E[ObserverMap.defineProperties]\n    E --> E1[\"applyConfigToSchema\\nstamps $observe: false on excluded schema nodes\"]\n    E1 --> F[Observable.defineProperty on prototype\\nfor 'user']\n    E1 --> G[install instanceResolverChanged handler]\n    G --> H[\"when user= is set:\\nassignObservables checks schema.$observe\\n→ Proxy wraps observed paths only\\ndeep mutations → Observable.notify\"]\n```\n\nFor a deep dive into the schema structure, context tracking, and proxy system\nsee\n[schema-observer-map.md](./schema-observer-map.md).\n\n### `$observe` flag on schema nodes\n\nWhen an `ObserverMapConfig` with a `properties` key is provided, `ObserverMap.defineProperties()` calls `applyConfigToSchema()` to stamp `$observe: false` on excluded schema nodes **before** the proxy system runs. This is a one-time pre-processing pass that walks the config and schema trees in parallel:\n\n- `false` in the config → `$observe: false` is stamped recursively on the node and all its descendants.\n- `$observe: false` on a config node → the schema node is stamped, and unlisted children inherit the stamp.\n- `true` in the config → no stamp needed (observed is the default).\n- Config paths not in the schema are silently ignored.\n\n**Convention: stamp-only-when-excluding.** The `$observe` flag is only ever set to `false` — it is never explicitly set to `true`. Absence of `$observe` (i.e. `undefined`) means the node is observed. This means:\n\n- When Observer Map is enabled without a `properties` tree, `applyConfigToSchema`\n  is never called and no schema nodes are mutated — zero overhead for the\n  common case.\n- The proxy system uses `isSchemaExcluded(schema)` (checks `$observe === false` with no observed descendants) as the single predicate for all skip/suppress decisions.\n- Schema nodes without `$observe` are always treated as observed.\n\n### AttributeMap and leaf bindings\n\nWhen `attributeMap()` is enabled with a declarative template, it registers a\ndefinition schema transform. With a manually supplied definition schema, it runs\nimmediately. The extension constructs an `AttributeMap` implementation and calls\n`defineProperties()`. It iterates `Schema.getRootProperties()` and skips any\nproperty whose schema entry contains `properties`, `type`, or `anyOf` — keeping\nonly plain leaf bindings. For each leaf:\n\n1. The schema key is used as the **JS property name**.\n2. The **HTML attribute name** depends on the `attribute-name-strategy`:\n   - `\"camelCase\"` (default): the attribute name is derived by converting the camelCase property name to kebab-case (e.g. `fooBar` → `foo-bar`).\n   - `\"none\"`: the attribute name equals the property name (e.g. `foo-bar` → `foo-bar`).\n3. A new `AttributeDefinition` is registered via `Observable.defineProperty`.\n4. `FASTElementDefinition.attributeLookup` is keyed by the HTML attribute name and `propertyLookup` is keyed by the JS property name so `attributeChangedCallback` can route attribute changes to the correct property.\n\nWhen using the `\"none\"` strategy, property names may contain dashes and must be\naccessed via bracket notation (e.g. `element[\"foo-bar\"]`). When using\n`\"camelCase\"`, property names are standard JS identifiers (e.g.\n`element.fooBar`).\n\nSchema transforms run in deterministic order. When both extensions are supplied,\nattribute mapping runs before observer mapping.\n\n---\n\n## Lifecycle\n\n```mermaid\nsequenceDiagram\n    participant App as Application JS\n    participant FER as FASTElementDefinition\n    participant FTE as internal f-template\n    participant EC as ElementController\n    participant Hydration as enableHydration().whenHydrated()\n\n    App->>Hydration: const hydration = enableHydration() [optional]\n    App->>FER: MyElement.define({name:'my-el', template: declarativeTemplate()}, [attributeMap(), observerMap()])\n    note over FER: definition composed; resolver waits for template\n\n    DOM->>FTE: f-template connected to DOM\n    FTE->>FTE: bridge matches registry + name\n    FTE->>FTE: parse template → schema → transforms → ViewTemplate\n    FTE->>FER: return viewTemplate to resolver\n    FER->>FER: customElements.define('my-el', MyElement)\n\n    DOM->>EC: element instance connects with existing shadow root\n    EC->>EC: isPrerendered = true (existing shadow root detected)\n    alt enableHydration() was called\n        EC->>EC: template.hydrate() — maps existing DOM to binding targets\n        EC->>Hydration: resolve active batch when all pending elements finish\n    else hydration not enabled\n        EC->>EC: client-side render; isHydrated = false\n    end\n```\n\n### Promise readiness reference\n\n| Promise | Import path | Resolves when |\n|---|---|---|\n| `enableHydration().whenHydrated(\"my-element\")` | `@microsoft/fast-element/hydration.js` | Hydration work for that tag name completes. |\n| `enableHydration().whenHydrated()` | `@microsoft/fast-element/hydration.js` | The active hydration batch completes. |\n\nBy default, hydration no-ops for later prerendered batches after the initial\nbatch completes. Set\n`enableHydration({ stopHydration: StopHydration.never })` when Declarative Shadow\nDOM may be streamed into the page after the initial hydration batch. In that\nmode, `enableHydration().whenHydrated()` intentionally remains pending because\nthere is no global completion point.\n\nFor usage examples see\n[lifecycle.md](./lifecycle.md).\n\n---\n\n## Integration with fast-element\n\nThe declarative runtime is a thin orchestration layer on top of\n`@microsoft/fast-element`. It does not re-implement any reactive primitives; it\nconverts declarative HTML syntax into the same data structures that `html`\ntagged templates produce.\n\n| fast-element primitive | How the declarative runtime uses it |\n|---|---|\n| `FASTElement` | Base class for user components; the internal `<f-template>` publisher is a native `HTMLElement` |\n| `FASTElementDefinition.register()` / template resolvers | Deferred element registration — element waits for its template |\n| `FASTElementDefinition.schema` | Optional schema used by schema-driven extensions; assigned automatically by `declarativeTemplate()` and available for manual schemas |\n| `FASTElementExtension` | Extension callback mechanism used by `attributeMap()` and `observerMap()` to attach schema transforms before template resolution or consume manually supplied schemas |\n| `ViewTemplate.create(strings, values)` | Compiles the resolved strings/values arrays into a `ViewTemplate` |\n| `ElementController` | Automatically detects prerendered content (`isPrerendered`) and hydrates server-rendered DOM using `fe-b` comment/dataset markers via `template.hydrate()` |\n| `Observable.defineProperty()` | Defines observable root properties on element prototypes (ObserverMap) |\n| `Observable.getNotifier()` | Triggers change notifications from proxy handlers |\n| `when(expr, template)` | FAST directive used for `<f-when>` |\n| `repeat(expr, template)` | FAST directive used for `<f-repeat>` |\n| `slotted(options)` | FAST directive used for `f-slotted` |\n| `children(prop)` | FAST directive used for `f-children` |\n| `ref(prop)` | FAST directive used for `f-ref` |\n\n### Deferred template attachment via define\n\nStandard subclass `define()` calls return a `Promise` that resolves immediately when a concrete template is provided at definition time. When `template: declarativeTemplate()` is used, the `Promise` resolves after the matching `<f-template>` supplies a concrete template through the bridge. This unified API replaces the previous `defineAsync()` / `composeAsync()` methods.\n\n---\n\n## Hydration Model\n\nWhen declarative templates are used, the server must render:\n\n1. The custom element tag with its attributes and initial state.\n2. A `<template shadowrootmode=\"open\">` containing pre-rendered HTML annotated with FAST's hydration markers.\n3. An `<f-template>` element somewhere in the page that carries the template definition.\n\nWith `declarativeTemplate()`, connection gating happens before platform registration: the resolver waits for the matching `<f-template>` and keeps the definition concrete before elements can connect. Hydration can therefore start immediately when `ElementController.connect()` runs. The `defer-hydration` and `needs-hydration` attributes are no longer needed in server-rendered markup.\n\n### Hydration marker formats\n\n`enableHydration()` uses the FAST Element 3.x data-free marker reader by\ndefault. The marker strategy is shared by target discovery and nested repeat\nhydration so a view uses one consistent format throughout its hydration walk.\nThe optional `markers_v2` strategy contains the legacy indexed-marker parsing logic and\nis selected with `enableHydration({ markers: markers_v2 })`.\n\n**Content bindings** use HTML comments (data-free, matched by string equality):\n\n```\n<!--fe:b-->\n<!--fe:/b-->\n```\n\n**Attribute bindings** use a single `data-fe` dataset attribute with binding count:\n\n```html\n<el data-fe=\"3\">\n```\n\n**Repeat directives** wrap each item in comment pairs:\n```\n<!--fe:r-->\n...item DOM...\n<!--fe:/r-->\n```\n\nFor detailed examples see\n[rendering.md](./rendering.md).\n\n---\n\n## Testing Architecture\n\nEach feature is verified by a **Playwright** integration test against a live\nVite dev server. The `test/declarative/fixtures/` directory contains one\nsubdirectory per feature:\n\n```\ntest/declarative/fixtures/<feature>/\n├── <feature>.spec.ts        # Playwright test\n├── entry.html               # Entry template with root custom elements\n├── fast-build.config.json   # Build configuration for @microsoft/fast-build\n├── index.html               # Pre-rendered page (GENERATED by scripts/declarative/build-fixtures.js — do not edit)\n├── main.ts                  # Component definitions, declarativeTemplate(), extensions, and enableHydration() setup\n├── state.json               # Initial state for server-side rendering\n└── templates.html           # Declarative <f-template> definitions\n```\n\nFixtures are auto-discovered by scanning for directories that contain `entry.html`, `templates.html`, `state.json`, and `fast-build.config.json`. Both the build script and the Vite config pick up new fixtures automatically — no registration step is needed.\n\nFor fixtures that use SSR-style pre-rendered HTML,\n`scripts/declarative/build-fixtures.js` invokes `@microsoft/fast-build` with\n`--config` pointing to each fixture's `fast-build.config.json` to generate\n`index.html` from the configured source files.\n\n### WebUI Integration Tests\n\nA separate integration test suite validates that `@microsoft/webui` can build and render the same fixture templates that `@microsoft/fast-build` processes. This is split into two steps:\n\n1. **Build** (`npm run build:fixtures:webui`) — runs\n   `scripts/declarative/build-fixtures-with-webui.js`, which extracts\n   `<f-template>` elements, converts each component template with\n   `fast convert --syntax=webui-prerelease`, builds each fixture with\n   `webui build --plugin=fast`, renders the protocol with `state.json`, and\n   writes the output alongside `main.ts` and assets to\n   `temp/integrations/webui/fixtures/`.\n2. **Test** (`npm run test:webui-integration`) — builds the fixtures, then runs\n   the same Playwright specs against the webui-rendered output served by a Vite\n   dev server on port 5174 (configured in\n   `playwright.declarative.webui.config.ts`).\n\nFixtures that intentionally contain invalid FAST declarative templates are skipped in\nthe WebUI build because `fast convert` validates and rejects them before WebUI\nrenders. Run locally with `npm run test:webui-integration` or via the\n`ci-webui-integration.yml` GitHub Action on PRs and pushes to `main`.\n\n#### Skipped tests\n\nSome tests are conditionally skipped when running under the webui integration\nconfig. The `playwright.declarative.webui.config.ts` file sets\n`process.env.FAST_WEBUI_INTEGRATION = \"true\"`, and individual tests check this\nvariable with `test.skip()` to opt out of cases that exercise known differences\nbetween `fast-build` and `webui` rendering:\n\n- **`errors.spec.ts` — \"throws an error when no template element is present\"**: webui does not render `<f-template>` elements that lack a `<template>` child, so the expected error is never thrown.\n\n### Hydration readiness\n\nFixtures that exercise prerendered output wait for hydration to complete before\nrunning assertions. Each `main.ts` calls `enableHydration()` and then awaits\nthe returned controller's `whenHydrated()` promise to set a global flag, and each spec file calls\n`page.waitForFunction()` after `page.goto()` to block until the flag is set.\nSee [test/declarative/fixtures/README.md](../../test/declarative/fixtures/README.md)\nfor the implementation pattern.\n\nSee\n[test/declarative/fixtures/WRITING_FIXTURES.md](../../test/declarative/fixtures/WRITING_FIXTURES.md)\nfor the complete fixture authoring guide,\n[test/declarative/fixtures/README.md](../../test/declarative/fixtures/README.md)\nfor a quick reference, and\n[test/declarative/fixtures/extensions/observer-map-deep-merge/README.md](../../test/declarative/fixtures/extensions/observer-map-deep-merge/README.md)\nfor an example of a complex multi-feature fixture.\n\n---\n\n## Further Reading\n\n| Document | Topic |\n|---|---|\n| [syntax.md](./syntax.md) | Installation, syntax reference, hydration promises, usage examples |\n| [rendering.md](./rendering.md) | Hydratable HTML format: comment markers, dataset attributes, directive markers |\n| [lifecycle.md](./lifecycle.md) | Phase-by-phase rendering lifecycle, hydration readiness, performance notes |\n| [schema-observer-map.md](./schema-observer-map.md) | Deep dive into Schema JSON structure, ObserverMap proxy system, debugging |\n| [test/declarative/fixtures/README.md](../../test/declarative/fixtures/README.md) | Quick reference for fixture structure |\n| [test/declarative/fixtures/WRITING_FIXTURES.md](../../test/declarative/fixtures/WRITING_FIXTURES.md) | Complete guide to writing new Playwright fixture tests |\n| [test/declarative/fixtures/extensions/observer-map-deep-merge/README.md](../../test/declarative/fixtures/extensions/observer-map-deep-merge/README.md) | Complex deep-merge fixture: observable arrays, nested repeats, conditionals |\n","packages/fast-element/docs/declarative/lifecycle.md":"# Rendering Lifecycle\n\nThis document describes the declarative rendering lifecycle inside\n`@microsoft/fast-element`.\n\n## Overview\n\nThe FAST Element rendering lifecycle involves a coordinated process between the\ncore runtime and its declarative entrypoint:\n\n- **`@microsoft/fast-element`**: Provides the core `FASTElement` base class and\n  element definition system.\n- **`@microsoft/fast-element/declarative.js`**: Provides the `f-template`\n  custom element that processes HTML templates and attaches them to FAST\n  elements as a `ViewTemplate` in lieu of an `html` template created during\n  a subclass `define()` call. The preferred path uses `declarativeTemplate()` so\n  the subclass `define()` call waits for the matching declarative template and keeps\n  the definition concrete before registration completes.\n\n## Lifecycle Phases\n\nGiven a DOM which includes an `f-template` and a component:\n\n```html\n<my-component text=\"Hello World\">\n    <template shadowrootmode=\"open\">\n        <h1><!--fe:b-->Hello World<!--fe:/b--></h1>\n    </template>\n</my-component>\n\n<f-template name=\"my-component\">\n    <template>\n        <h1>{{text}}</h1>\n    </template>\n</f-template>\n```\n\nThe following phases will then be kicked off once the JavaScript is parsed.\n\n### Phase 1: Definition Resolution\n\nCustom elements begin their lifecycle by composing a definition that points at\n`declarativeTemplate()`. The resolver waits for a matching declarative template\nand returns a concrete `ViewTemplate` before the platform registration step.\n\n```typescript\n// Custom element class definition\nclass MyComponent extends FASTElement {\n    @attr text: string = \"\";\n}\n\n// Register with the declarative template bridge\nMyComponent.define({\n    name: \"my-component\",\n    template: declarativeTemplate(),\n});\n```\n\nKey characteristics of this phase:\n- The element definition stays unresolved until a matching declarative template is available\n- The resolved template is concrete before platform registration completes\n\n### Phase 2: Declarative Template Bridge\n\n`declarativeTemplate()` from `@microsoft/fast-element/declarative.js`\nautomatically ensures that `f-template` is defined in the same registry as the\nFAST element being composed.\n\n### Phase 3: Template Processing and Attachment\n\nWhen an `f-template` element is connected to the DOM, it initiates the template attachment process.\n\nThe lifecycle flow during this phase:\n\n1. **Template Discovery**: The resolver waits for a matching\n   `<f-template name=\"...\">` in the same registry as the element definition.\n2. **Template Element Connection**: The matching `f-template` element's\n   `connectedCallback()` registers it with the declarative template bridge.\n3. **Template Processing**: The bridge reads and transforms the markup, builds\n   the schema, applies `observerMap()` / `attributeMap()` behavior, and resolves\n   data bindings, directives, and other template features into the `ViewTemplate`\n   model which is also used by the `@microsoft/fast-element` `html` tag template.\n4. **Template Attachment**: The concrete `ViewTemplate` is returned to\n   the subclass `define()` call, which assigns it to the definition before platform\n   registration completes.\n\n### Phase 4: Composition Completion\n\nOnce the template is attached to the partial definition, the element completes its composition:\n\n1. **`compose()` Execution**: The element definition internally completes its composition process\n2. **Platform Registration**: The completed element definition is fully registered with the platform's custom element registry\n\n### Phase 5: Element Instantiation and Hydration\n\nWhen custom elements are instantiated in the DOM, the following occurs:\n\n1. **Element Creation**: The platform creates instances of the custom element\n2. **Prerendered Content Detection**: `ElementController` detects the existing shadow root from SSR — `isPrerendered` resolves `true`\n3. **Hydration Check**: If `enableHydration()` was called and the template is hydratable, the element hydrates — `isHydrated` resolves `true`. Otherwise it falls back to client-side rendering.\n4. **Concrete Template Ready**: Because `declarativeTemplate()` resolved during\n   definition, `connect()` starts with the final template already attached.\n5. **Hydration**: `ElementController` uses `template.hydrate()` to create a\n   `HydrationView` that maps existing DOM nodes to binding targets using `fe:b`\n   / `fe:/b` markers\n\nThe DOM after hydration should look like this:\n\n```html\n<my-component text=\"Hello World\">\n    <template shadowrootmode=\"open\">\n        <h1><!---->Hello World<!----></h1>\n    </template>\n</my-component>\n```\n\n## Key Integration Points\n\n### Fast Element Registry\n\nThe `fastElementRegistry` serves as the central coordination point between the\ntwo packages and is available to consumers from\n`@microsoft/fast-element/registry.js`:\n\n- Stores partial element definitions created by `define()`\n- Provides lookup mechanism via `register()` for template attachment\n- Resolves `fastElementRegistry.whenRegistered(tagName)` when a matching\n  definition is registered\n- Maintains the registry of all FAST element definitions\n\n### Observable Pattern\n\nBoth packages use the Observable pattern for coordination:\n\n- Element definition template assignment notifies observers that are waiting for a concrete template\n- Template attachment triggers observable notifications to complete the lifecycle\n\n## Error Handling\n\nThe lifecycle includes error handling for missing components:\n\n- Template elements throw errors if no corresponding element definition is found\n- Element definitions can exist without templates (partial state)\n\n## Performance Considerations\n\nThe asynchronous nature of the lifecycle provides several performance benefits:\n\n- **Progressive Enhancement**: Elements can be registered before templates are loaded\n- **Code Splitting**: Templates can be loaded separately from element definitions  \n- **Reduced Blocking**: Template processing doesn't block element registration\n- **Hydration Optimization**: Server-side rendered content can be hydrated efficiently\n\nThis coordinated lifecycle enables powerful scenarios like server-side rendering, progressive enhancement, and dynamic template loading while maintaining the reactive capabilities of FAST Element.\n\n## Hydration promise APIs\n\nFAST Element exposes promises for hydration readiness points that are useful to\napplication code.\n\nHydration must be explicitly opted into by calling `enableHydration()`. Await\nthe returned controller's `whenHydrated()` promise when code needs to run after\nthe active hydration batch completes. Pass a tag name to `whenHydrated(tagName)`\nwhen code needs to wait for a specific FAST element.\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nconst hydration = enableHydration();\nawait hydration.whenHydrated(\"my-component\");\nawait hydration.whenHydrated();\n```\n\nBy default, hydration no-ops for later prerendered batches after the initial\nbatch completes. Set `stopHydration: StopHydration.never` in\n`enableHydration()` when streaming Declarative Shadow DOM should continue\nhydrating after the initial batch. In that mode, `hydration.whenHydrated()`\nintentionally remains pending because hydration has no global completion point.\n","packages/fast-element/docs/declarative/rendering.md":"# Non-browser HTML rendering\n\n1. [Initial State](#initial-state)\n2. [Hydrating Comments and Datasets](#hydration-comments-and-datasets)\n\nThis document details information on rendering hydratable content and includes some pointers on how Dependency Injection can be used to create services that hydrate a custom elements state. Non-browser rendering in this context means producing HTML that a browser can parse and hydrate later; it does not mean running the FAST Element client runtime in a worker, server-side JavaScript runtime, or other non-window host.\n\n## Initial State\n\nTo create initial state this should be added somewhere accessible by your service, in this example a `<script>` tag can be used to provide a global initial state.\n\nExample:\n```html\n<script>\n    window.__INITIAL_STATE__ = {\n        text: \"Hello world\"\n    }\n</script>\n```\n\nAdd a Dependency Injection service in your bundle to access properties in your state.\n\nSimple example (`initial-state.ts`):\n```typescript\nimport { DI } from \"@microsoft/fast-element/di.js\";\n\ninterface InitialState {\n    text: string;\n}\n\nexport interface IInitialStateService {\n  init(): InitialState;\n}\n\nexport class InitialStateService implements IInitialStateService {\n    private initialState: any;\n\n    constructor() {\n        this.initialState = window.__INITIAL_STATE__;\n    }\n\n    public init(...keys: Array<string>): InitialState {\n        const config: any = {};\n\n        for (let key of keys) {\n            config[key] = this.initialState[key];\n        }\n\n        return config;\n    }\n}\n\nexport const initialStateFactory = DI.createContext<IInitialStateService>(\n  'i-initial-state-service',\n  (x) => x.singleton(InitialStateService)\n);\n```\n\nInclude the DI service to your component.\n\nExample:\n```typescript\nimport { attr, FASTElement, Observable } from \"@microsoft/fast-element\";\nimport {\n    initialStateFactory,\n    InitialStateService,\n    type IInitialStateService,\n} from \"./initial-state.js\";\nimport { inject } from \"@microsoft/fast-element/di.js\";\n\nexport class MyComponent extends FASTElement {\n    @inject(initialStateFactory) initialStateService!: InitialStateService;\n\n    @attr\n    text: string = \"\";\n\n    service!: IInitialStateService;\n\n    connectedCallback() {\n        super.connectedCallback();\n\n        this.loadItemFromInitialState();\n    }\n\n    loadItemFromInitialState(): void {\n        const initialState = this.initialStateService.init([\"text\"]);\n\n        this.text = initialState.text;\n    }\n}\n\nMyComponent.define({\n    name: \"my-component\",\n    template: declarativeTemplate(),\n});\n```\n\nWhen the element connects, `ElementController` automatically detects the\nexisting shadow root from SSR and sets `isPrerendered = true`.\n`declarativeTemplate()` keeps the definition template concrete before\nregistration completes, so the element can hydrate the prerendered shadow root\nimmediately. The `defer-hydration` and `needs-hydration` attributes are no\nlonger needed.\n\n## Hydration Comments and Datasets\n\nWhen hydrating the HTML, FAST uses `ElementController` which detects an\nexisting shadow root (from SSR or declarative shadow DOM) and sets\n`isPrerendered = true`. It then uses `template.hydrate()` to create a\n`HydrationView` that maps existing DOM nodes to binding targets using hydration\n\"markers\" such as comments and dataset attributes. By default the declarative\nruntime in `@microsoft/fast-element` assumes component hydration will occur, so\nrendering hydratable markup is required.\n\n### Bindings\n\n#### Content Bindings\n\nContent binding markers are represented using HTML comments. These comments are used to indicate where dynamic content exists in the template. Markers carry no embedded data — they are fixed strings matched by string equality (not regex).\n\n* Start binding: `<!--fe:b-->`\n* End binding: `<!--fe:/b-->`\n\nBinding pairs are matched using balanced depth counting: each start marker increments a depth counter and each end marker decrements it. When the counter returns to zero the pair is complete.\n\n##### Content Binding Marker Examples\n\n**Note**\nExamples shown below mostly skip the wrapping custom element and the internal template element with `shadowrootmode=\"open\"`.\n\nTypically along with the content from the examples below, the rendering should include:\n\n```html\n<my-component>\n    <template shadowrootmode=\"open\" shadowroot=\"open\">\n        <!-- hydratable content -->\n    </template>\n</my-component>\n```\n\n**Simple content example**\n\nContent bindings such as:\n```html\n<h1>{{text}}</h1>\n```\n\nWhen combined with state such as:\n```json\n{\n    \"text\": \"Hello world\"\n}\n```\n\nShould result in:\n```html\n<h1><!--fe:b-->Hello world<!--fe:/b--></h1>\n```\n\n#### Attribute Bindings\n\nAttribute bindings are tracked using a single dataset attribute: `data-fe=\"N\"` where `N` is the number of attribute bindings on the element.\n\n##### Examples\n\n###### Single attribute example\n\nAttribute binding such as:\n```html\n<h1 greeting=\"{{greeting}}\"></h1>\n```\n\nWhen combined with state such as:\n```json\n{\n    \"greeting\": \"Hello\"\n}\n```\n\nShould result in:\n\n```html\n<h1 data-fe=\"1\" greeting=\"Hello\"></h1>\n```\n\n###### Multiple attribute bindings\n\nWhen multiple attribute bindings exist on the same element:\n```html\n<h1 greeting=\"{{greeting}}\" subtitle=\"{{subtitle}}\" punctuation=\"{{punctuation}}\"></h1>\n```\n\nWhen combined with state such as:\n```json\n{\n    \"greeting\": \"Hello\",\n    \"subtitle\": \"world\",\n    \"punctuation\": \"!\"\n}\n```\n\nShould result in:\n\n```html\n<h1 data-fe=\"3\" greeting=\"Hello\" subtitle=\"world\" punctuation=\"!\"></h1>\n```\n\n**Mixed attribute and content example**\n\nMultiple attributes and content bindings such as:\n```html\n<div show=\"{{show}}\" appearance=\"{{appearance}}\" punctuation=\"{{punctuation}}\">\n    <h1>{{text}}</h1>\n    <span>{{subtitle}}</span>\n    <span>{{punctuation}}</span>\n</div>\n```\n\nShould result in:\n```html\n<div data-fe=\"3\" show appearance=\"large\" punctuation=\"!\">\n    <h1><!--fe:b-->Hello<!--fe:/b--></h1>\n    <span><!--fe:b-->world<!--fe:/b--></span>\n    <span><!--fe:b-->!<!--fe:/b--></span>\n</div>\n```\n\n### Directives\n\nDirectives are treated differently from bindings as they include a template. This means that in addition to the binding used to determine the logic for the directive FAST also requires a separate marker for the directive itself to demarkate the beginning and end of the template.\n\n#### Repeat\n\nExample repeat binding:\n```html\n<f-repeat value=\"{{item in list}}\">\n    <span>{{item}}</span>\n</f-repeat>\n```\n\nCombined with state:\n```json\n[\n    \"Bob\",\n    \"Alice\",\n    \"Sue\"\n]\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<!--fe:r-->\n<span>\n    <!--fe:b-->Bob<!--fe:/b-->\n</span>\n<!--fe:/r-->\n<!--fe:r-->\n<span>\n    <!--fe:b-->Alice<!--fe:/b-->\n</span>\n<!--fe:/r-->\n<!--fe:r-->\n<span>\n    <!--fe:b-->Sue<!--fe:/b-->\n</span>\n<!--fe:/r-->\n<!--fe:/b-->\n```\n\nNote that the repeat markers are data-free — they carry no index or ID. Pairing uses balanced depth counting. Additionally, a binding wraps the repeat markers; even if the array is empty, this binding must be rendered.\n\nExample result of an empty array:\n```html\n<!--fe:b-->\n<!--fe:/b-->\n```\n\n#### When\n\nThe when directive is either present in the DOM or not, and therefore does not need an extra marker for the template.\n\nExample when binding:\n```html\n<f-when value=\"{{show}}\">\n    <span>{{text}}</span>\n</f-when>\n```\n\nCombined with state:\n```json\n{\n    \"show\": true,\n    \"text\": \"Hello world\"\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<span>\n    <!--fe:b-->Hello world<!--fe:/b-->\n</span>\n<!--fe:/b-->\n```\n\nIf the when is evaluated to `falsy` then we can safely leave the binding markers only.\n\nExample state:\n```json\n{\n    \"show\": false,\n    \"text\": \"Hello world\"\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<!--fe:/b-->\n```\n\n### Host attributes from `<f-template>`\n\nBuild-time renderers (e.g. `@microsoft/fast-build`) forward attributes declared on the inner `<template>` element of an `<f-template>` onto the rendered host element opening tag.\n\nExample template:\n```html\n<f-template name=\"my-button\">\n    <template tabindex=\"0\" ?disabled=\"{{isDisabled}}\">\n        <button><slot></slot></button>\n    </template>\n</f-template>\n```\n\nCombined with author HTML `<my-button></my-button>` and state:\n```json\n{\n    \"isDisabled\": true\n}\n```\n\nShould result in:\n```html\n<my-button tabindex=\"0\" disabled defer-hydration needs-hydration>\n    <template shadowrootmode=\"open\" shadowroot=\"open\">\n        <button><slot></slot></button>\n    </template>\n</my-button>\n```\n\nRules:\n- Client-only attributes (`@event`, `:prop`, `f-ref`, `f-slotted`, `f-children`) are skipped — they have no meaning on a server-rendered host element.\n- Author attributes on the host element always win on conflicts (case-insensitive name match; the dedupe key for `?name=\"{{expr}}\"` is the bare `name`).\n- Static `name=\"value\"` is forwarded verbatim (HTML-escaped); static boolean `name` is emitted bare.\n- `name=\"{{expr}}\"` is resolved against the element's initial child state; primitives are emitted as `name=\"value\"`, `Array` / `Object` / `Null` and missing values are stripped.\n- `?name=\"{{expr}}\"` is evaluated as a boolean against the same state; the bare `name` (without `?`) is emitted when truthy and skipped when falsy.\n\n### Client Side Bindings\n\nClient side bindings are bindings which the client needs, but they are not necessary as part of an initial render. These must still be accounted for when creating hydration comments however, as the template needs to know which elements to attach these bindings to. There are two types of client side bindings, events and attribute directives. These do not require state as they are bound to class methods or properties.\n\n#### Event Bindings\n\nEvent bindings such as `@keydown` and `@click` can be represented with hydration comments.\n\nExample event binding:\n```html\n<button @click=\"{handleClick($e)}\">Button</button>\n```\n\nShould result in:\n```html\n<button data-fe=\"1\">Button</button>\n```\n\n#### Attribute Directives\n\nAttribute directives such as `f-slotted` and `f-ref` can be represented with hydration comments.\n\nExample `f-ref` binding:\n```html\n<button f-ref=\"{button}\">Button</button>\n```\n\nShould result in:\n```html\n<button data-fe=\"1\">Button</button>\n```\n\n#### More Examples\n\n##### Nested Whens\n\nExample when binding:\n```html\n<f-when value=\"{{show}}\">\n    <span>{{text}}</span>\n    <f-when value=\"{{showInternal}}\">\n        <span>{{internalText}}</span>\n    </f-when>\n</f-when>\n```\n\nCombined with state:\n```json\n{\n    \"show\": true,\n    \"text\": \"Hello world\",\n    \"showInternal\": true,\n    \"internalText\": \"Hello pluto\"\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<span>\n    <!--fe:b-->Hello world<!--fe:/b-->\n</span>\n    <!--fe:b-->\n    <span>\n        <!--fe:b-->Hello pluto<!--fe:/b-->\n    </span>\n    <!--fe:/b-->\n<!--fe:/b-->\n```\n\n##### Nested Repeats\n\nExample when binding:\n```html\n<f-repeat value=\"{{item in items}}\">\n    <div>\n        <span>{{item.name}}</span>\n        <f-when value=\"{{!!item.nested}}\">\n            <ul>\n                <f-repeat value=\"{{person in item.nested}}\">\n                    <li>{{person.name}}</li>\n                </f-repeat>\n            </ul>\n        </f-when>\n    </div>\n</f-repeat>\n```\n\nCombined with state:\n```json\n{\n    \"items\": [\n        {\n            \"name\": \"Bob\"\n        },\n        {\n            \"name\": \"Alice\"\n        },\n        {\n            \"name\": \"Sue\",\n            \"nested\": [\n                {\n                    \"name\": \"Amy\"\n                },\n                {\n                    \"name\": \"Clarice\"\n                },\n                {\n                    \"name\": \"Lawrence\"\n                }\n            ]\n        }\n    ]\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n    <!--fe:r-->\n    <div>\n        <span><!--fe:b-->Bob<!--fe:/b--></span>\n        <!--fe:b--><!--fe:/b-->\n    </div>\n    <!--fe:/r--><!--fe:r-->\n    <div>\n        <span><!--fe:b-->Alice<!--fe:/b--></span>\n        <!--fe:b--><!--fe:/b-->\n    </div>\n    <!--fe:/r--><!--fe:r-->\n    <div>\n        <span><!--fe:b-->Sue<!--fe:/b--></span>\n        <!--fe:b-->\n            <ul>\n                <!--fe:b-->\n                <!--fe:r-->\n                <li>\n                    <!--fe:b-->Amy<!--fe:/b-->\n                </li>\n                <!--fe:/r-->\n                <!--fe:r-->\n                <li>\n                    <!--fe:b-->Clarice<!--fe:/b-->\n                </li>\n                <!--fe:/r-->\n                <!--fe:r-->\n                <li>\n                    <!--fe:b-->Lawrence<!--fe:/b-->\n                </li>\n                <!--fe:/r-->\n                <!--fe:/b-->\n            </ul>\n        <!--fe:/b-->\n    </div>\n    <!--fe:/r-->\n<!--fe:/b-->\n```\n\n##### Nested components with `<slot>`\n\nThis example shows the wrapping custom element tag as well as the template component with `shadowrootmode=\"open\"` for the sake of illustrating an example that would exist in the DOM.\n\nExample template of component \"nested-component\":\n```html\n<f-when value=\"{{showButton}}\">\n    <my-button appearance=\"{{appearance}}\">{{text}}</my-button>\n</f-when>\n```\n\nExample template of component \"my-button\":\n```html\n<button class=\"{{appearance}}\">\n    <slot></slot>\n</button>\n```\n\nCombined with state:\n```json\n{\n    \"showButton\": true,\n    \"text\": \"Hello world\",\n    \"appearance\": \"fancy\"\n}\n```\n\nShould result in:\n```html\n<nested-components>\n    <template shadowrootmode=\"open\" shadowroot=\"open\">\n        <!--fe:b-->\n        <my-button data-fe=\"1\" appearance=\"fancy\">\n            <template shadowrootmode=\"open\" shadowroot=\"open\">\n                <button class=\"default\" data-fe=\"1\">\n                    <slot></slot>\n                </button>\n            </template>\n            <!--fe:b-->Hello world<!--fe:/b-->\n        </my-button>\n        <!--fe:/b-->\n    </template>\n</nested-components>\n```\n\n## Rendering Lifecycle\n\nFor information about the declarative rendering lifecycle inside\n`@microsoft/fast-element`, see\n[lifecycle.md](./lifecycle.md).\n","packages/fast-element/docs/declarative/schema-observer-map.md":"# Schema and Observer Map Architecture\n\nThis document provides a technical explainer for how the `Schema` and\n`ObserverMap` classes work together to describe data objects and automatically\nobserve them in FAST elements. Declarative `<f-template>` markup creates schemas\nautomatically, but the schema and observer map implementation are factored so\nthey can also be used without declarative templating.\n\n## Table of Contents\n\n1. [Overview](#overview)\n2. [The Schema Class](#the-schema-class)\n3. [The Observer Map Class](#the-observer-map-class)\n4. [Integration with f-template](#integration-with-f-template)\n5. [Initial Path Processing Flow](#initial-path-processing-flow)\n6. [Dynamic Path Processing Updates](#dynamic-path-processing-updates)\n7. [Observable Proxy System](#observable-proxy-system)\n8. [Examples](#examples)\n9. [Technical Details](#technical-details)\n\n## Overview\n\nThe Schema and Observer Map architecture enables automatic observation of complex nested data objects in FAST HTML templates. This system solves the problem of manually tracking all the binding paths used in declarative HTML templates, automatically creating observables for nested properties that are referenced in the template bindings.\n\n**Important**: This system is designed specifically for observable data objects (objects, arrays, and primitives). It explicitly does not handle binding paths that are assumed to be functions, methods, or other non-data constructs like event handlers.\n\n### Key Components\n\n- **Schema Class**: Generates JSON schemas that describe the structure and binding paths of data objects based on template analysis or manually registered paths\n- **Observer Map Class**: Uses the schema information to automatically define observable properties and create proxies for nested object observation\n- **f-template Integration**: Template processing automatically populates schemas and configures observer maps during template compilation\n- **Map helpers**: `@microsoft/fast-element` exposes the map helpers independently from declarative templating\n\n### Supported Data Types\n\nThe system automatically handles:\n- **Objects**: Nested object structures with observable properties\n- **Arrays**: Arrays with observable mutations and nested object elements  \n- **Primitives**: String, number, boolean values as object properties\n\n### Explicitly Not Handled\n\nThe system does not process:\n- **Function bindings**: Event handlers and method calls like `@click=\"{handleClick()}\"`\n- **Context paths**: Bindings using the `$c` prefix (e.g., `$c.parent.showNames`) resolve directly from the `ExecutionContext` and are not part of the data model\n- **Computed expressions**: Complex expressions that evaluate to non-data values\n- **Non-observable constructs**: Any binding assumed to reference functions or non-data objects\n\n## The Schema Class\n\nThe `Schema` class is responsible for building JSON Schema definitions that map the structure of data objects used in template bindings. It analyzes binding paths from template processing and constructs schemas that describe:\n\n- Root properties and their nested structures\n- Array contexts for repeat operations\n- Object property relationships\n- Cross-references to child components\n\n**Important**: Each schema created corresponds to a property that will belong to the custom element's class. The schema describes the expected structure and relationships of data that will be assigned to that property, enabling automatic observation of nested objects and arrays within that property's data structure.\n\n### Core Methods\n\n#### Constructor\n```typescript\nconstructor(name: string)\n```\nCreates a new schema instance for a specific custom element name and initializes an instance-level `schemaMap`. The instance also registers itself in the module-level `schemaRegistry` for cross-element `$ref` resolution. `FASTElementDefinition.schema` is optional; declarative templates assign it after parsing, while manual schema users can pass one in the element definition or directly to `observerMap({ schema })`.\n\n#### addPath\n```typescript\npublic addPath(config: RegisterPathConfig)\n```\nRegisters a binding path discovered during template processing. The configuration includes:\n- `pathConfig`: Describes the path type (`access`, `default`, `repeat`, `event`)\n- `rootPropertyName`: The root property this path belongs to\n- `childrenMap`: Information about child components referenced in this path\n\n**Note**: Only `access`, `default`, and `repeat` path types result in schema entries. Event paths are identified but not processed since they represent function calls rather than observable data.\n\n#### getSchema\n```typescript\npublic getSchema(rootPropertyName: string): JSONSchema | null\n```\nRetrieves the JSON schema for a specific root property.\n\n### Path Types\n\nThe schema handles different types of binding paths:\n\n- **`access`/`default`**: Direct property access like `{{user.name}}`\n- **`repeat`**: Array iteration contexts like `{{item}}` within `<f-repeat>`\n- **`event`**: Event handler bindings like `@click=\"{handleClick()}\"` - **Note: These are explicitly not processed by the schema system as they are assumed to be functions rather than observable data objects**\n\n### Schema Structure\n\nGenerated schemas follow JSON Schema format with FAST-specific extensions:\n\n```typescript\n{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://fast.design/schemas/my-element/users.json\",\n  \"type\": \"array\",\n  \"$ref\": \"#/$defs/user\",\n  \"$defs\": {\n    \"user\": {\n      \"$fast_context\": \"users\",\n      \"$fast_parent_contexts\": [null],\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {},\n        \"details\": {\n          \"type\": \"object\", \n          \"properties\": {\n            \"age\": {}\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n**Note on Property Types**: Properties accessed through binding paths (like `name` and `age` above) are defined with empty objects `{}` rather than specific JSON Schema types. This is because it's not possible to determine the exact primitive type (string, number, boolean, etc.) from the path syntax alone. The system focuses on structural relationships rather than specific data types for leaf properties.\n\n## The Observer Map Class\n\nThe `ObserverMap` class uses schema information to automatically configure observable properties on custom element prototypes. It creates the infrastructure needed to observe nested object changes without manual setup.\n\n### Constructor\n```typescript\nconstructor(classPrototype: any, schema: Schema, config?: ObserverMapConfig)\n```\nCreates an observer map instance that will configure the provided class prototype using the schema information.\n\n### defineProperties\n```typescript\npublic defineProperties(): void\n```\nThe main method that:\n1. Iterates through all root properties defined in the schema (each schema instance contains multiple root property schemas)\n2. Defines observable properties using FAST Element's `Observable.defineProperty` (an alternative to the `@observable` decorator syntax used in custom element classes)\n3. Sets up property change handlers that create proxies for nested objects\n\n### Property Change Handling\n\nWhen a root property transitions from `undefined` to a defined value, the observer map:\n1. Analyzes the schema to understand the expected object structure\n2. Creates proxies using the `assignObservables` utility function\n3. Establishes deep observation of nested properties based on the schema of that root property\n\n## Integration with f-template and manual schemas\n\nThe Schema and Observer Map classes integrate seamlessly with the f-template system, but they are not tied to it:\n\n### Template Processing Flow\n\n1. **Template Parsing**: When an `f-template` element is processed, it creates a `Schema` instance\n2. **Binding Discovery**: As template bindings are processed, paths are registered with `schema.addPath()`\n3. **Observer Map Creation**: If enabled, an `ObserverMap` is instantiated with the populated schema\n4. **Property Definition**: The observer map defines observable properties on the custom element prototype\n\n### Configuration\n\nObserver Map functionality is enabled through the `observerMap()` definition\nextension exported from `@microsoft/fast-element/observer-map.js`:\n\n```typescript\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nMyElement.define(\n  {\n    name: \"my-custom-element\",\n    template: declarativeTemplate(),\n  },\n  [observerMap()]\n);\n```\n\nWhen the `properties` key is omitted, all root properties discovered in the\ntemplate are observed. Add a `properties` object to opt into selective\nobservation behavior.\n\nFor non-declarative/manual schema use, pass the schema in the observer map\nconfiguration:\n\n```typescript\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-custom-element\");\nschema.addPath({\n  rootPropertyName: \"user\",\n  pathConfig: {\n    type: \"default\",\n    parentContext: null,\n    currentContext: null,\n    path: \"user.name\",\n  },\n  childrenMap: null,\n});\n\nMyElement.define(\n  {\n    name: \"my-custom-element\",\n  },\n  [observerMap({ schema })]\n);\n```\n\nYou can also attach a manual schema to the FAST element definition. This is the\npath used automatically by `declarativeTemplate()` after it parses a template:\n\n```typescript\nMyElement.define(\n  {\n    name: \"my-custom-element\",\n    schema,\n  },\n  [observerMap()]\n);\n```\n\n## Initial Path Processing Flow\n\nHere's how binding paths flow through the system during initial template processing:\n\n1. **Template Binding**: `{{user.details.personal.name}}`\n2. **Path Analysis**: Utilities identify root property (`user`) and nested path (`details.personal.name`)\n3. **Type Check**: Confirms this is a data binding (not an event handler like `@click=\"{handleClick()}\"`)\n4. **Schema Registration**: \n   ```typescript\n   schema.addPath({\n     pathConfig: {\n       type: \"access\",\n       currentContext: null,\n       parentContext: null,\n       path: \"user.details.personal.name\"\n     },\n     rootPropertyName: \"user\",\n     childrenMap: null\n   });\n   ```\n5. **Schema Building**: Creates nested object structure in JSON schema\n6. **Observable Definition**: Observer map makes `user` property observable\n7. **Proxy Creation**: When `user` is assigned, proxies are created for deep observation\n\n### Event Handler and Context Path Exclusion\n\nEvent handlers are identified but explicitly excluded from schema processing:\n- **Template Binding**: `@click=\"{handleClick()}\"`\n- **Path Analysis**: Utilities identify this as an event handler\n- **Type Check**: Confirms this is type `\"event\"`\n- **Schema Registration**: **Skipped** - Event handlers are not added to schemas since they represent function calls\n\nContext paths (`$c` prefix) are also excluded from schema processing:\n- **Template Binding**: `{{$c.parent.showNames}}` or `@click=\"{$c.parent.handleClick($c.event)}\"`\n- **Path Analysis**: Utilities detect the `$c.` prefix\n- **Schema Registration**: **Skipped** - These paths resolve from the `ExecutionContext`, not from observable data properties\n\n## Dynamic Path Processing Updates\n\nAfter initial schema creation and observer map setup, the system continues to dynamically update observation as data structures evolve:\n\n### Runtime Object Assignment\n\nWhen nested objects or array items become defined after initial setup:\n\n1. **Property Assignment**: A previously undefined nested property gets assigned a value\n   ```typescript\n   // Initially: user.details was undefined\n   user.details = { age: 30, location: { city: \"Seattle\" } };\n   ```\n\n2. **Schema Consultation**: The system consults the existing schema for this root property to understand expected nested structure\n\n3. **Proxy Creation**: New proxies are automatically created for the newly assigned nested objects based on the schema definition\n\n4. **Deep Observation Extension**: Observation is extended to all nested properties defined in the schema\n\n### Array Item Addition\n\nWhen new items are added to observed arrays:\n\n1. **Array Mutation**: Items are added via push, splice, or direct assignment\n   ```typescript\n   users.push({ name: \"John\", details: { age: 25 } });\n   ```\n\n2. **Array Observer Trigger**: The array proxy detects the mutation and triggers observation setup\n\n3. **Item Processing**: Each new array item is processed according to the array's context schema definition\n\n4. **Nested Object Proxying**: New nested objects within array items are automatically proxied based on the schema structure\n\n## Observable Proxy System\n\nThe proxy system in `utilities.ts` provides the deep observation capabilities:\n\n### assignObservables Function\n\n```typescript\nexport function assignObservables(\n    schema: JSONSchema | JSONSchemaDefinition,\n    rootSchema: JSONSchema,\n    data: any,\n    target: any,\n    rootProperty: string\n): typeof Proxy\n```\n\nThis function:\n- Analyzes the data type (object, array, primitive)\n- Creates proxies for objects and arrays\n- Establishes property observation for nested structures\n- Handles array mutations and object property changes\n\n### Proxy Behavior\n\nProxied objects:\n- Trigger Observable notifications when properties change\n- Automatically proxy newly assigned nested objects\n- Track array mutations and splice operations\n- Maintain references to root properties for change notifications\n\n## Examples\n\n### Basic Object Observation\n\n**Template:**\n```html\n<f-template name=\"user-profile\">\n  <template>\n    <div>{{user.name}} - {{user.details.age}} years old</div>\n    <div>Location: {{user.details.location.city}}</div>\n  </template>\n</f-template>\n```\n\n**Generated Schema Structure:**\n```typescript\n// Root property: \"user\"\n{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://fast.design/schemas/user-profile/user.json\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": {},\n    \"details\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"age\": {},\n        \"location\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"city\": {}\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n### Array with Repeat Context\n\n**Template:**\n```html\n<f-template name=\"user-list\">\n  <template>\n    <f-repeat value=\"{{user in users}}\">\n      <div>{{user.name}} has {{user.posts.length}} posts</div>\n    </f-repeat>\n  </template>\n</f-template>\n```\n\n**Generated Schema Structure:**\n```typescript\n// Root property: \"users\"\n{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://fast.design/schemas/user-list/users.json\",\n  \"type\": \"array\",\n  \"$ref\": \"#/$defs/user\",\n  \"$defs\": {\n    \"user\": {\n      \"$fast_context\": \"users\",\n      \"$fast_parent_contexts\": [null],\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {},\n        \"posts\": {\n          \"type\": \"array\"\n        }\n      }\n    }\n  }\n}\n```\n\n### Nested Repeat Contexts\n\n**Template:**\n```html\n<f-template name=\"complex-data\">\n  <template>\n    <f-repeat value=\"{{user in users}}\">\n      <div>{{user.name}}</div>\n      <f-repeat value=\"{{post in user.posts}}\">\n        <div>{{post.title}} - {{post.metadata.views}} views</div>\n      </f-repeat>\n    </f-repeat>\n  </template>\n</f-template>\n```\n\nThis creates nested context definitions where the `post` context understands its relationship to the parent `user` context.\n\n## Technical Details\n\n### Schema Registry\n\nThe `Schema` module exports a module-level `schemaRegistry`:\n```typescript\nexport const schemaRegistry: CachedPathMap = new Map();\n```\n\nEach `Schema` instance owns an instance-level `schemaMap: Map<string, JSONSchema>` and registers itself in `schemaRegistry` on construction.\n\nThe registry structure is: `Map<customElementName, Map<rootPropertyName, JSONSchema>>`\n\n**Rationale for Module-level Registry**: The registry allows cross-element `$ref` resolution for nested components inside f-templates. When an object or array is passed to another custom element within an f-template, that nested component needs to observe the entire root property's structure based on the binding paths within that nested component. The registry allows all components to access and contribute to the same schema definitions, ensuring consistent observation behavior across component boundaries.\n\n### Context Tracking\n\nThe schema system tracks binding contexts using special metadata:\n- `$fast_context`: The array property name that created this context\n- `$fast_parent_contexts`: Chain of parent contexts leading to the root\n\n### Performance Considerations\n\n- **Lazy Proxy Creation**: Proxies are only created when objects are assigned to observable properties\n- **Weak Map Caching**: The system uses WeakMaps to avoid memory leaks when tracking proxied objects\n- **Schema Reuse**: Schemas are generated once per custom element and reused across instances\n\n### Memory Management\n\n- **WeakMap Usage**: `objectTargetsMap` and `observedArraysMap` use WeakMaps to automatically clean up references\n- **Proxy Identification**: Proxies are marked with `$isProxy` to prevent double-proxying\n- **Reference Tracking**: Target elements and root properties are tracked for proper change notification\n\n## Debugging and Troubleshooting\n\n### Schema Inspection\n\nYou can inspect generated schemas using the module-level `schemaRegistry` import:\n\n```typescript\nimport { schemaRegistry } from \"@microsoft/fast-element\";\n\n// Get all schemas for an element:\nconst elementSchemas = schemaRegistry.get('my-element');\nconst userSchema = elementSchemas?.get('users');\nconsole.log(JSON.stringify(userSchema, null, 2));\n```\n\n### Observer Map Status\n\n`observerMap()` is applied as a definition extension before the element is\nregistered. There is no public `TemplateElement.options()` state to inspect.\nTo verify that observer mapping ran, inspect the generated schema and the\nobservable accessors on the element prototype:\n\n```typescript\nimport { Observable, schemaRegistry } from \"@microsoft/fast-element\";\n\nconst schemas = schemaRegistry.get(\"my-element\");\nconst accessors = Observable.getAccessors(MyElement.prototype).map(a => a.name);\nconsole.log(schemas, accessors);\n```\n\n### Proxy Detection\n\nObjects processed by the system will have a `$isProxy` property:\n```typescript\nconsole.log('Is proxied:', myObject.$isProxy === true);\n```\n","packages/fast-element/docs/declarative/syntax.md":"# FAST Element Declarative HTML\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-element.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-element)\n\nThe declarative entrypoint in `@microsoft/fast-element` interprets FAST\ndeclarative HTML syntax as a template for a FAST web component.\n\nThis document focuses on declarative-runtime implementation details:\ntemplate structure, prerendered markup requirements, hydration promise APIs,\nbinding configuration, syntax, and integration testing.\n\nFor package installation, using `declarativeTemplate()`, extension setup, and\nthe package-level hydration overview, see the\n[FAST Element README](../../README.md#declarative-html) and\n[Prerendered Content Optimization](../../README.md#prerendered-content-optimization).\nFor user-facing guides covering f-template syntax, element definition, and\nserver-side rendering, see the\n[Declarative HTML docs](https://fast.design/docs/3.x/declarative-templates/overview/).\n\n## Template Structure\n\nAfter importing the declarative APIs as shown in the README, templates are\nassociated with an element through\n`<f-template name=\"[custom-element-name]\"><template>...</template></f-template>`.\nThe host custom element should be defined with\n`template: declarativeTemplate()`. This automatically defines `<f-template>` in\nthe relevant registry and waits for the matching declarative template when it is\nalready present or inserted later.\n\nThe `@microsoft/fast-element` entrypoint itself remains\nside-effect free at import time. Declarative APIs lazily install declarative\ndebug messages when they create templates. Hydratable `ViewTemplate` support is\ninstalled only when `enableHydration()` is called from\n`@microsoft/fast-element/hydration.js`.\n\n`observerMap()` and `attributeMap()` are available from\n`@microsoft/fast-element/observer-map.js` and\n`@microsoft/fast-element/attribute-map.js`, including when using the maps\nwithout declarative templates.\n\nExample:\n```html\n<my-custom-element greeting=\"Hello world\">\n    <template shadowrootmode=\"open\">\n        Hello world\n    </template>\n</my-custom-element>\n<f-template name=\"my-custom-element\">\n    <template>{{greeting}}</template>\n</f-template>\n```\n\nThe legacy `defer-hydration` and `needs-hydration` attributes are no longer\nrequired.\n\n## HTML Comments\n\nBindings and FAST directive markup inside HTML comments are unsupported. This\nincludes double-brace and triple-brace bindings, client-only bindings, and\ncommented-out elements containing bindings or directives.\n\nThe declarative parsers scan template strings and do not reliably exclude\ncomments. A comment such as `<!-- {{greeting}} -->` can still contribute a binding,\nleading to unexpected evaluation, rendering errors, or hydration mismatches.\nRemove unused bound markup rather than commenting it out, and keep explanatory\ncomments free of binding syntax and FAST directive tags.\n\n## Non-browser HTML Rendering\n\nOne of the benefits of FAST declarative HTML templates is that the server can\nbe stack agnostic because JavaScript does not need to be interpreted to emit\nthe initial HTML. This does not mean the FAST Element client runtime runs on the\nserver: custom element definition, hydration, client rendering, and reactive\nupdates still run in the browser `Window`. The declarative runtime expects\nhydratable comment markers and datasets when prerendered content is generated.\nFor the required marker format and initial-state application details, see\n[rendering.md](./rendering.md).\n\n## Hydration promise APIs\n\nFAST Element's declarative APIs expose hydration readiness promises that are\nuseful to application code.\n\nHydration is opt-in. Call `enableHydration()` before FAST elements connect when\nyou want prerendered Declarative Shadow DOM to be reused, then await\nthe returned controller's `whenHydrated()` promise when code needs to run after\nthe active hydration batch:\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nconst hydration = enableHydration();\nawait hydration.whenHydrated();\n```\n\nThe hydration hook no-ops for new prerendered elements after the initial\nhydration batch completes by default. Streaming scenarios that append hydratable\nDeclarative Shadow DOM later can keep the hook active:\n\n```typescript\nimport { enableHydration, StopHydration } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({\n    stopHydration: StopHydration.never,\n});\n```\n\nWhen `StopHydration.never` is used, `enableHydration().whenHydrated()`\nintentionally remains pending because hydration has no global completion point.\n\nFAST Element 3.x data-free hydration markers are selected by default. Existing\nserver output that uses FAST Element 2.x indexed markers can be hydrated by\nselecting the v2 marker reader:\n\n```typescript\nimport { enableHydration, markers_v2 } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ markers: markers_v2 });\n```\n\nSet `\"markers_v2\": true` in the matching `@microsoft/fast-build`\nconfiguration so the generated HTML uses the same marker format.\n\n## `observerMap`\n\nWhen the `observerMap()` extension is applied to an element definition,\nit automatically sets up deep reactive observation for root properties\ndiscovered in the template. Declarative templates assign `definition.schema`\nduring template resolution, so `observerMap()` has schema data automatically.\nFor non-declarative/manual schemas, import from\n`@microsoft/fast-element/observer-map.js` and pass `observerMap({ schema })`.\n\n```typescript\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n```\n\nFor finer control, pass a configuration object with a `properties` key that maps root property names to a recursive path tree:\n\n```typescript\nUserProfile.define(\n    {\n        name: \"user-profile\",\n        template: declarativeTemplate(),\n    },\n    [\n        observerMap({\n            properties: {\n                user: {\n                    name: true,          // user.name — observed\n                    details: {\n                        age: true,       // user.details.age — observed\n                        history: false,  // user.details.history — NOT observed\n                    },\n                },\n                // root properties not listed here are skipped\n            },\n        }),\n    ],\n);\n```\n\nEach path entry can be:\n- **`true`** — observe this path and all descendants.\n- **`false`** — skip this path and all descendants.\n- **An object** with an optional `$observe` boolean and child property overrides.\n\nUse `$observe: false` on a node to skip it by default, then re-include specific children:\n\n```typescript\nobserverMap({\n    properties: {\n        analytics: {\n            charts: {\n                $observe: false,       // charts NOT observed by default\n                activeChart: true,     // ...except activeChart IS observed\n            },\n        },\n    },\n});\n```\n\nWhen `properties` is omitted, all root properties are observed. When\n`properties` is present but empty (`{ properties: {} }`), no root properties\nare observed.\n\nWhen observer-map data is updated with `deepMerge`, array properties are replaced\nrather than updated in place. This avoids synchronous reentrant array work and\nallows repeat bindings to observe the new array reference. Replacement arrays\nare processed through observerMap so nested item properties and subsequent array\nmutations remain observable.\n\nManual schema example:\n\n```typescript\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-element\");\nschema.addPath({\n    rootPropertyName: \"user\",\n    pathConfig: {\n        type: \"default\",\n        parentContext: null,\n        currentContext: null,\n        path: \"user.name\",\n    },\n    childrenMap: null,\n});\n\nMyElement.define({ name: \"my-element\" }, [observerMap({ schema })]);\n```\n\n## `attributeMap`\n\nWhen the `attributeMap()` extension is applied to an element definition,\nit automatically creates reactive `@attr` properties for every **leaf binding**\nin the template — simple expressions like `{{foo}}` or `id=\"{{fooBar}}\"` that\nhave no nested properties. Declarative templates provide the schema\nautomatically. For non-declarative/manual schemas, place the optional `schema`\non the FAST element definition and import `attributeMap()` from\n`@microsoft/fast-element`.\n\n```typescript\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\n```\n\nBy default, the binding key is treated as a camelCase property name and the HTML\nattribute name is derived by converting it to kebab-case. Properties already\ndecorated with `@attr` or `@observable` on the class are left untouched.\n\n```typescript\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [attributeMap()],\n);\n```\n\nWith the template:\n\n```html\n<f-template name=\"my-element\">\n    <template>\n        <p>{{greeting}}</p>\n        <p>{{firstName}}</p>\n    </template>\n</f-template>\n```\n\nThis registers `greeting` (attribute `greeting`, property `greeting`) and\n`firstName` (attribute `first-name`, property `firstName`) as `@attr`\nproperties on the element prototype, enabling `setAttribute(\"first-name\",\n\"Jane\")` to trigger a template re-render automatically.\n\n### `attribute-name-strategy`\n\nThe `attribute-name-strategy` configuration option controls how template binding\nkeys map to HTML attribute names. This matches the build-time\n`--attribute-name-strategy` option in `@microsoft/fast-build`.\n\n| Strategy | Behaviour | Example |\n|---|---|---|\n| `\"camelCase\"` (default) | Binding key is the camelCase property; attribute name is derived as kebab-case | `{{fooBar}}` → property `fooBar`, attribute `foo-bar` |\n| `\"none\"` | Binding key used as-is for both property and attribute | `{{foo-bar}}` → property `foo-bar`, attribute `foo-bar` |\n\n```typescript\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [\n        attributeMap({\n            \"attribute-name-strategy\": \"none\",\n        }),\n    ],\n);\n```\n\nWhen using the `\"none\"` strategy, property names may contain dashes and must be\naccessed via bracket notation (e.g. `element[\"foo-bar\"]`).\n\n## Syntax\n\nAll bindings use a handlebars-like syntax.\n\nSome bindings are only relevant to the browser, such as for click handlers or other pieces of dynamic interaction. As such, their bindings use single curly braces `{}`, this is to prevent an intial SSR (Server Side Rendering) or other build time rendering technologies from needing to interpret them.\n\nIf a binding is relevant to both client and the back end rendering engine, it will use `{{}}` or `{{{}}}` depending on what type of data injection is being done.\n\nBrowser-only bindings:\n- Event bindings\n- Attribute directives\n\n### Content binding\n\n```html\n{{text}}\n```\n\n### Event binding\n\nEvent bindings must include the `()` as well as being preceeded by `@` in keeping with the `@microsoft/fast-element` tagged template syntax.\n\n```html\n<button @click=\"{handleClick()}\"></button>\n```\n\nYou can pass the DOM event object, the execution context, or both as arguments. Any other argument is treated as a binding expression and resolved against the current data source.\n\n**`$e` — DOM event object (preferred):**\n```html\n<button @click=\"{handleClick($e)}\"></button>\n```\n\n**`$c` — execution context:**\n```html\n<button @click=\"{handleClick($c)}\"></button>\n```\n\n**`$c.somePath` — a property of the execution context (e.g. `$c.parent`, `$c.event`):**\n```html\n<button @click=\"{handleClick($c.parent)}\"></button>\n```\n\n**Multiple arguments:**\n```html\n<button @click=\"{handleClick($e, $c)}\"></button>\n```\n\n**Arbitrary binding expressions** — any token that is not `$e` or `$c` is resolved as a binding path on the data source:\n```html\n<button @click=\"{handleClick(user.id)}\"></button>\n```\n\nUse `$e` for the DOM event object.\n\n### Directives\n\nDirectives are assumed to be either an attribute directive or a directive that also serves a template. Both are prepended by `f-`. The logic of these directives and what their use cases are is explained in the [FAST html documentation](https://fast.design/docs/getting-started/html-directives).\n\nAttribute directives are part of [client side binding](#syntax) and therefore use the `{}` syntax.\n\nAttribute directives include:\n- **slotted**\n\n    Example:\n    ```html\n    <slot f-slotted=\"{slottedNodes}\"></slot>\n    <slot f-slotted=\"{slottedNodes filter elements()}\"></slot>\n    <slot f-slotted=\"{slottedNodes filter elements(div, p)}\"></slot>\n    ```\n\n- **children**\n\n    Example:\n    ```html\n    <ul f-children=\"{listItems}\"><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    <ul f-children=\"{listItems filter elements()}\"><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    <ul f-children=\"{listItems filter elements(li)}\"><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    ```\n\n- **ref**\n\n    Example:\n    ```html\n    <video f-ref=\"{video}\"></video>\n    ```\n\nTemplate directives include:\n- **when**\n\n    Example:\n    ```html\n    <f-when value=\"{{show}}\">Hello world</f-when>\n    <f-when value=\"{{!show}}\">Goodbye world</f-when>\n    ```\n\nThe following operators can also be used:\n- `==`\n- `!=`\n- `>=`\n- `>`\n- `<=`\n- `<`\n- `||`\n- `&&`\n\nWhere the right operand can be either a reference to a value (string e.g. `{{foo == 'bar'}}`, boolean e.g. `{{foo == true}}`, number e.g. `{{foo == 3}}`) or another binding value.\n\n- **repeat**\n\n    Example:\n    ```html\n    <ul><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    ```\n\n    Bindings inside `<f-repeat>` without a context prefix resolve to the custom element. For example, `{{title}}` below resolves to the host element's `title` property:\n\n    ```html\n    <ul><f-repeat value=\"{{item in list}}\"><li>{{item}} - {{title}}</li></f-repeat></ul>\n    ```\n\n### Execution Context Access\n\nIn imperative fast-element templates, every binding expression receives both the data source and the execution context: `${(x, c) => c.parent.handleClick(c.event)}`. Declarative `<f-template>` expressions can access the same execution context using the `$c` prefix.\n\nThis is particularly useful inside `<f-repeat>`, where `$c.parent` refers to the parent view-model (typically the host element) and `$c.event` provides the DOM event.\n\nEvent handler with context access:\n\n```html\n<f-repeat value=\"{{item in items}}\">\n    <button @click=\"{$c.parent.handleItemClick($c.event)}\">{{item.name}}</button>\n</f-repeat>\n```\n\nConditional rendering using a host property inside a repeat:\n\n```html\n<f-repeat value=\"{{item in items}}\">\n    <f-when value=\"{{$c.parent.showNames}}\">\n        <span>{{item.name}}</span>\n    </f-when>\n</f-repeat>\n```\n\n### Unescaped HTML\n\nYou can add unescaped HTML using triple braces, this will create an additional `div` element as the HTML needs an element to bind to. Where possible it is advisable to not use unescaped HTML and instead use other binding techniques.\n\nExample:\n```html\n{{{html}}}\n```\n\n### Code samples inside `<code>`\n\nAny text or attribute value inside a `<code>` element has its `{` and `}` characters automatically replaced with the HTML numeric character references `&#123;` and `&#125;` before template parsing. As a result, binding delimiters (`{{...}}`, `{{{...}}}`, `{...}`) inside `<code>` are rendered as literal text rather than being interpreted as FAST bindings — making `<code>` blocks safe for embedding code samples that contain binding-like syntax. No marker attribute is needed.\n\nIn addition, the build-time renderer (`@microsoft/fast-build`) entity-escapes the `<` and `>` of every **FAST directive tag** (`<f-when>`, `</f-when>`, `<f-repeat>`, `</f-repeat>`) it finds inside `<code>`, so authors can write the directive literally without manually entity-encoding the angle brackets. Tag-name matching is case-insensitive. Non-directive elements inside `<code>` — real HTML elements such as `<button>` and custom elements such as `<my-widget>` — keep their angle brackets and continue to render as live DOM elements; only brace-binding syntax in their attribute values is neutralised.\n\nThe brace escape is applied symmetrically by both the server-side renderer and the client-side `<f-template>` parser, so binding positions stay in sync between SSR and hydration. The directive-tag angle escape only needs to run on the server: the DOM serializer re-encodes `<`/`>` in text content, so the client-side parser never sees a raw `<f-when>` inside `<code>` regardless of what the page source contained. This behaviour mirrors how Microsoft WebUI's `webui-press` markdown renderer transparently escapes the same characters inside code spans and code fences.\n\nExample:\n```html\n<f-template name=\"docs-page\">\n    <template>\n        <h1>{{title}}</h1>\n        <pre><code>span {{greeting}} /span</code></pre>\n        <pre><code><f-when value=\"{{flag}}\">wrapped</f-when></code></pre>\n        <pre><code>Try: <button class=\"demo\">click</button></code></pre>\n    </template>\n</f-template>\n```\n\nThe `<h1>` binds to `title`, the first `<code>` displays the literal text `span {{greeting}} /span`, the second displays the literal text `<f-when value=\"{{flag}}\">wrapped</f-when>`, and the third renders a live `<button>` element alongside the surrounding sample text.\n\n## Writing Components\n\nWhen writing components with the intention of using the declarative HTML syntax, it is imperative that components are written with styling and rendering of the component to be less reliant on any JavaScript state management. An example of this is relying on `elementInterals` state to style a component.\n\n## WebUI Integration Testing\n\nThe fixture tests in `test/declarative/fixtures/` are also validated against\n[`@microsoft/webui`](https://github.com/microsoft/webui) to ensure\ncross-renderer compatibility. The build step renders each fixture's templates\nwith `webui build --plugin=fast`, then the existing Playwright specs run\nagainst the webui-rendered output.\n\n```shell\n# Build fixtures with webui and run Playwright tests\nnpm run test:webui-integration -w @microsoft/fast-element\n\n# Or run the steps separately\nnpm run build:fixtures:webui -w @microsoft/fast-element\nnpm exec -w @microsoft/fast-element -- playwright test --config=playwright.declarative.webui.config.ts\n```\n\nThis is also run automatically in CI via the `ci-webui-integration.yml` GitHub Action on pull requests and pushes to `main`.\n\nSome tests are conditionally skipped during webui integration runs due to known\nrendering differences between `fast-build` and `webui`. The\n`playwright.declarative.webui.config.ts` file sets\n`FAST_WEBUI_INTEGRATION=true`, and affected tests use `test.skip()` with a\ndescriptive reason. See the WebUI Integration Tests section in\n[design.md](./design.md) for the full list.\n","packages/fast-element/docs/di/api-report.api.md":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport const all: (key: any, searchAncestors?: boolean) => ReturnType<typeof DI.inject>;\n\n// @public\nexport type AsyncRegistrationLocator = (key: Key) => Promise<Registration | null>;\n\n// @public\nexport interface Container extends ServiceLocator {\n    createChild(config?: Partial<Omit<ContainerConfiguration, \"parentLocator\">>): Container;\n    getFactory<T extends Constructable>(key: T): Factory<T>;\n    getResolver<K extends Key, T = K>(key: K | Key, autoRegister?: boolean): Resolver<T> | null;\n    register(...params: any[]): Container;\n    // Warning: (ae-forgotten-export) The symbol \"Constructable\" needs to be exported by the entry point di.d.ts\n    registerFactory<T extends Constructable>(key: T, factory: Factory<T>): void;\n    registerResolver<K extends Key, T = K>(key: K, resolver: Resolver<T>): Resolver<T>;\n    registerTransformer<K extends Key, T = K>(key: K, transformer: Transformer_2<T>): boolean;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"ContextDecorator\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport const Container: ContextDecorator<Container>;\n\n// @public\nexport interface ContainerConfiguration {\n    asyncRegistrationLocator: AsyncRegistrationLocator;\n    defaultResolver(key: Key, handler: Container): Resolver;\n    parentLocator: ParentLocator;\n    responsibleForOwnerRequests: boolean;\n}\n\n// @public\nexport const ContainerConfiguration: Readonly<{\n    default: Readonly<ContainerConfiguration>;\n}>;\n\n// Warning: (ae-internal-missing-underscore) The name \"ContainerImpl\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport class ContainerImpl implements DOMContainer {\n    constructor(owner: any, config: ContainerConfiguration);\n    // (undocumented)\n    protected config: ContainerConfiguration;\n    // (undocumented)\n    createChild(config?: Partial<Omit<ContainerConfiguration, \"parentLocator\">>): Container;\n    // (undocumented)\n    get depth(): number;\n    // (undocumented)\n    get<K extends Key>(key: K): Resolved<K>;\n    // (undocumented)\n    getAll<K extends Key>(key: K, searchAncestors?: boolean): readonly Resolved<K>[];\n    // (undocumented)\n    getAsync<K extends Key>(key: K): Promise<Resolved<K>>;\n    // (undocumented)\n    getFactory<K extends Constructable>(Type: K): Factory<K>;\n    // (undocumented)\n    getResolver<K extends Key, T = K>(key: K | Key, autoRegister?: boolean): Resolver<T> | null;\n    // (undocumented)\n    handleContextRequests(enable: boolean): void;\n    // (undocumented)\n    has<K extends Key>(key: K, searchAncestors?: boolean): boolean;\n    // (undocumented)\n    protected owner: any;\n    // (undocumented)\n    get parent(): ContainerImpl | null;\n    // (undocumented)\n    register(...params: any[]): Container;\n    // (undocumented)\n    registerFactory<K extends Constructable>(key: K, factory: Factory<K>): void;\n    // (undocumented)\n    registerResolver<K extends Key, T = K>(key: K, resolver: Resolver<T>): Resolver<T>;\n    // (undocumented)\n    registerTransformer<K extends Key, T = K>(key: K, transformer: Transformer_2<T>): boolean;\n    // (undocumented)\n    get responsibleForOwnerRequests(): boolean;\n}\n\n// @public\nexport const DefaultResolver: Readonly<{\n    none(key: Key): Resolver;\n    singleton(key: Key): Resolver;\n    transient(key: Key): Resolver;\n}>;\n\n// @public\nexport const DI: Readonly<{\n    installAsContextRequestStrategy(fallback?: () => DOMContainer): void;\n    createContainer(config?: Partial<ContainerConfiguration>): Container;\n    findResponsibleContainer(target: EventTarget, fallback?: () => DOMContainer): DOMContainer;\n    findParentContainer(target: EventTarget, fallback?: () => DOMContainer): DOMContainer;\n    getOrCreateDOMContainer(target?: EventTarget, config?: Partial<Omit<ContainerConfiguration, \"parentLocator\">>): DOMContainer;\n    getDependencies(Type: Constructable | Injectable): Key[];\n    defineProperty(target: {}, propertyName: string, key: Key, respectConnection?: boolean): void;\n    createContext: typeof createContext;\n    inject(...dependencies: Key[]): (target: any, key?: string | number, descriptor?: PropertyDescriptor | number) => void;\n    transient<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;\n    singleton<T extends Constructable>(target: T & Partial<RegisterSelf<T>>, options?: SingletonOptions): T & RegisterSelf<T>;\n}>;\n\n// @public\nexport interface DOMContainer extends Container {\n    // @beta\n    handleContextRequests(enable: boolean): void;\n}\n\n// @public\nexport const DOMContainer: ContextDecorator<DOMContainer>;\n\n// @public\nexport interface Factory<T extends Constructable = any> {\n    construct(container: Container, dynamicDependencies?: Key[]): Resolved<T>;\n    constructAsync(container: Container, dynamicDependencies?: Key[]): Promise<Resolved<T>>;\n    registerTransformer(transformer: Transformer_2<T>): void;\n    readonly Type: T;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"FactoryImpl\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport class FactoryImpl<T extends Constructable = any> implements Factory<T> {\n    constructor(Type: T, dependencies: Key[]);\n    // (undocumented)\n    construct(container: Container, dynamicDependencies?: Key[]): Resolved<T>;\n    // (undocumented)\n    constructAsync(container: Container, dynamicDependencies?: Key[]): Promise<Resolved<T>>;\n    // (undocumented)\n    registerTransformer(transformer: (instance: any) => any): void;\n    // (undocumented)\n    Type: T;\n}\n\n// @public\nexport function ignore(target: Injectable, property?: string | number, descriptor?: PropertyDescriptor | number): void;\n\n// @public\nexport const inject: (...dependencies: Key[]) => (target: any, key?: string | number, descriptor?: PropertyDescriptor | number) => void;\n\n// @public\nexport type Injectable<T = {}> = Constructable<T> & {\n    inject?: Key[];\n};\n\n// @public\nexport interface InterfaceConfiguration {\n    friendlyName?: string;\n    respectConnection?: boolean;\n}\n\n// @public\nexport type Key = PropertyKey | object | ContextDecorator | Constructable | Resolver;\n\n// @public\nexport const lazy: (key: any) => any;\n\n// @public\nexport const newInstanceForScope: (key: any) => any;\n\n// @public\nexport const newInstanceOf: (key: any) => any;\n\n// @public\nexport const optional: (key: any) => any;\n\n// @public\nexport type ParentLocator = (owner: any) => Container | null;\n\n// @public\nexport type RegisterSelf<T extends Constructable> = {\n    register(container: Container): Resolver<InstanceType<T>>;\n    registerInRequestor: boolean;\n};\n\n// @public\nexport interface Registration<K = any> {\n    register(container: Container): Resolver<K>;\n}\n\n// @public\nexport const Registration: Readonly<{\n    instance<T>(key: Key, value: T): Registration<T>;\n    singleton<T extends Constructable>(key: Key, value: T): Registration<InstanceType<T>>;\n    transient<T extends Constructable>(key: Key, value: T): Registration<InstanceType<T>>;\n    callback<T>(key: Key, callback: ResolveCallback<T>): Registration<Resolved<T>>;\n    cachedCallback<T>(key: Key, callback: ResolveCallback<T>): Registration<Resolved<T>>;\n    aliasTo<T>(originalKey: T, aliasKey: Key): Registration<Resolved<T>>;\n}>;\n\n// @public\nexport interface Registry {\n    register(container: Container, ...params: unknown[]): void | Resolver;\n}\n\n// @public\nexport type ResolveCallback<T = any> = (handler: Container, requestor: Container, resolver: Resolver<T>) => T;\n\n// Warning: (ae-forgotten-export) The symbol \"ResolverLike\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport type Resolved<K> = K extends ContextDecorator<infer T> ? T : K extends Constructable ? InstanceType<K> : K extends ResolverLike<any, infer T1> ? T1 extends Constructable ? InstanceType<T1> : T1 : K;\n\n// @public\nexport interface Resolver<K = any> extends ResolverLike<Container, K> {\n}\n\n// @public\nexport class ResolverBuilder<K> {\n    constructor(container: Container, key: Key);\n    aliasTo(destinationKey: Key): Resolver<K>;\n    cachedCallback(value: ResolveCallback<K>): Resolver<K>;\n    callback(value: ResolveCallback<K>): Resolver<K>;\n    instance(value: K): Resolver<K>;\n    singleton(value: Constructable): Resolver<K>;\n    transient(value: Constructable): Resolver<K>;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"ResolverImpl\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport class ResolverImpl implements Resolver, Registration {\n    // (undocumented)\n    get $isResolver(): true;\n    constructor(key: Key, strategy: ResolverStrategy, state: any);\n    // (undocumented)\n    getFactory(container: Container): Factory | null;\n    // (undocumented)\n    key: Key;\n    // (undocumented)\n    register(container: Container): Resolver;\n    // (undocumented)\n    resolve(handler: Container, requestor: Container): any;\n    // (undocumented)\n    resolveAsync(handler: Container, requestor: Container): Promise<any>;\n    // (undocumented)\n    state: any;\n    // (undocumented)\n    strategy: ResolverStrategy;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"ResolverStrategy\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport const enum ResolverStrategy {\n    // (undocumented)\n    alias = 5,\n    // (undocumented)\n    array = 4,\n    // (undocumented)\n    callback = 3,\n    // (undocumented)\n    instance = 0,\n    // (undocumented)\n    singleton = 1,\n    // (undocumented)\n    transient = 2\n}\n\n// @public\nexport interface ServiceLocator {\n    get<K extends Key>(key: K): Resolved<K>;\n    get<K extends Key>(key: Key): Resolved<K>;\n    get<K extends Key>(key: K | Key): Resolved<K>;\n    getAll<K extends Key>(key: K, searchAncestors?: boolean): readonly Resolved<K>[];\n    getAll<K extends Key>(key: Key, searchAncestors?: boolean): readonly Resolved<K>[];\n    getAll<K extends Key>(key: K | Key, searchAncestors?: boolean): readonly Resolved<K>[];\n    getAsync<K extends Key>(key: K): Promise<Resolved<K>>;\n    getAsync<K extends Key>(key: Key): Promise<Resolved<K>>;\n    getAsync<K extends Key>(key: K | Key): Promise<Resolved<K>>;\n    has<K extends Key>(key: K | Key, searchAncestors: boolean): boolean;\n}\n\n// @public\nexport const ServiceLocator: ContextDecorator<ServiceLocator>;\n\n// Warning: (ae-forgotten-export) The symbol \"singletonDecorator\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport function singleton<T extends Constructable>(): typeof singletonDecorator;\n\n// @public (undocumented)\nexport function singleton<T extends Constructable>(options?: SingletonOptions): typeof singletonDecorator;\n\n// @public\nexport function singleton<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;\n\n// @public\ntype Transformer_2<K> = (instance: Resolved<K>) => Resolved<K>;\nexport { Transformer_2 as Transformer }\n\n// Warning: (ae-forgotten-export) The symbol \"transientDecorator\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport function transient<T extends Constructable>(): typeof transientDecorator;\n\n// @public\nexport function transient<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;\n\n// Warning: (ae-internal-missing-underscore) The name \"validateKey\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport function validateKey(key: any): void;\n\n// Warnings were encountered during analysis:\n//\n// dist/dts/di/di.d.ts:479:5 - (ae-forgotten-export) The symbol \"createContext\" needs to be exported by the entry point di.d.ts\n// dist/dts/di/di.d.ts:540:5 - (ae-forgotten-export) The symbol \"SingletonOptions\" needs to be exported by the entry point di.d.ts\n\n// (No @packageDocumentation comment for this package)\n\n```\n","packages/fast-element/docs/migration/fast-element-2.md":"# Changes in FASTElement 2.0\n\n## Breaking Changes\n\n* `HTMLDirective` - The `targetIndex: number` property has been replaced by a `targetId: string` property. The `createBehavior` method no longer takes a target `Node` but instead takes a `BehaviorTargets` instance. The actual target can be looked up on the `BehaviorTargets` instance by indexing with the `targetId` property.\n* `compileTemplate()` - Internals have been significantly changed. The implementation no longer uses a TreeWalker. The return type has change to an `HTMLTemplateCompilationResult` with different properties.\n* `View` and `HTMLView` - Type parameters added to enable strongly typed views based on their data source. The constructor of `HTMLView` has a new signature based on changes to the compiler's output. Internals have been cleaned up and no longer rely on the Range type.\n* `ElementViewTemplate`, `SyntheticViewTemplate`, and `ViewTemplate` - Added type parameters throughout. Logic to instantiate and apply behaviors moved out of the template and into the view where it can be lazily executed. Removed the ability of the `render` method to take a string id of the node to render to. You must provide a node.\n* `DOM` - Tree Walker methods are no longer used and are thus removed. The API for removing child nodes has been removed as well since it was only used in one place and could be inlined. The helper `createCustomAttributePlaceholder()` no longer requires an attribute name. It will be uniquely generated internally.\n* `class` - Bindings to `class` are now more nuanced. Binding directly to `class` will simply set the `className` property. If you need to bind to `class` knowing that manual JS will also manipulate the `classList` in addition to the binding, then you should now bind to `:classList` instead. This allows for performance optimizations in the simple, most common case.\n* `Behavior` and `ViewBehavior` - `Behavior` now requires an `ExecutionContext` for `unbind`. Behaviors can be used for elements or views. `ViewBehavior` has been introduced for use exclusively with views, and provides some optimization opportunities.\n* `RefBehavior` has been replaced with `RefDirective`. The directive also implements `ViewBehavior` allowing a single directive instance to be shared across all template instances that use the ref.\n* Removed `SlottedBehavior` and `ChildrenBehavior` have been replaced with `SlottedDirective` and `ChildrenDirective`. These directives allow a single directive instance to be shared across all template instances that use the ref.\n* Removed `AttachedBehaviorHTMLDirective` and `AttachedBehaviorType` since they are no longer used in the new directive/behavior architecture for ref, slotted, and children.\n* Renamed `Notifier#source` to `Notifier#subject` to align with other observable terminology and prevent name clashes with `BindingObserver` properties.","packages/fast-element/docs/migration/fast-element-3.md":"# Migrating from previous versions\n\n## FASTGlobal version tracking (v2 → v3)\n\n### Removed API\n\n| Removed | Replacement |\n|---|---|\n| `FAST.versions` | No replacement. Multiple FAST versions on the same page are unsupported in v3. |\n\n### Removed configuration\n\n| Removed | Replacement |\n|---|---|\n| `fast-kernel=\"share\"` / `fast-kernel=\"share-v2\"` / `fast-kernel=\"isolate\"` | No replacement. FAST now uses a single shared kernel contract, and multiple FAST versions on the same page are unsupported. |\n\n### Migration steps\n\n1. Remove any runtime checks that read `FAST.versions`.\n2. Fix duplicate FAST installs in your bundler or dependency graph instead of relying on version tracking at runtime.\n3. Remove any `fast-kernel` script attributes. They no longer affect FAST initialization.\n\n## Native globals and scheduler requirements (v2 → v3)\n\n### Changed behavior\n\n- **Browser `Window` runtime required**: `@microsoft/fast-element` is a\n  client-side browser runtime. It expects browser DOM, Custom Elements, Shadow\n  DOM, and scheduling APIs such as `requestAnimationFrame`.\n- **Native `globalThis` required**: `@microsoft/fast-element` no longer installs\n  a `globalThis` polyfill as a side effect.\n- **No idle-callback polyfill**: FAST Element v3 no longer installs or depends\n  on a `requestIdleCallback` / `cancelIdleCallback` fallback. The async\n  `Updates` queue schedules work with `globalThis.requestAnimationFrame`.\n\n### Migration steps\n\n1. Verify that the browsers you support provide native `globalThis` and\n   `requestAnimationFrame`.\n2. If you still target an older browser without `globalThis`, load that polyfill\n   before importing `@microsoft/fast-element`.\n3. Do not import or run the FAST Element client runtime in workers,\n   server-side JavaScript runtimes, or other non-window hosts. SSR tools may\n   emit HTML, but hydration and client rendering run in the browser `Window`.\n4. You do not need to polyfill `requestIdleCallback` or `cancelIdleCallback`\n   for FAST Element itself. Only provide them if your application or another\n   dependency calls those APIs directly.\n\n## Declarative HTML moved into fast-element (v3)\n\nDeclarative HTML APIs now ship from focused `@microsoft/fast-element` package\npath exports instead of the removed `@microsoft/fast-html` package.\n\n### Import changes\n\n| Before | After |\n|---|---|\n| `@microsoft/fast-html` | `@microsoft/fast-element/declarative.js` |\n| `@microsoft/fast-html/utilities.js` | `@microsoft/fast-element/declarative-utilities.js` |\n\nCore FAST Element helpers are available from the root package export:\n\n| API | Import path |\n|---|---|\n| `Updates` | `@microsoft/fast-element` |\n| `Observable`, `observable` | `@microsoft/fast-element` |\n| `attr`, `AttributeDefinition`, converters, `ValueConverter` | `@microsoft/fast-element` |\n| `Binding`, `oneWay`, `oneTime`, `listener` | `@microsoft/fast-element` |\n| `DOM`, `DOMAspect`, `DOMPolicy` | `@microsoft/fast-element` |\n| `Schema`, `schemaRegistry`, schema types | `@microsoft/fast-element` |\n| `css` | `@microsoft/fast-element` |\n| `html`, `ViewTemplate`, `HTMLView` | `@microsoft/fast-element` |\n| `Compiler`, `HTMLDirective`, `htmlDirective`, templating/view types | `@microsoft/fast-element` |\n| `render`, `RenderBehavior`, `RenderDirective` | `@microsoft/fast-element` |\n| `enableHydration`, `deferHydrationAttribute`, `HydrationTracker`, hydration types | `@microsoft/fast-element/hydration.js` |\n| `ArrayObserver` | `@microsoft/fast-element` |\n| `volatile` | `@microsoft/fast-element` |\n| `children` | `@microsoft/fast-element` |\n| `elements`, `NodeObservationDirective` | `@microsoft/fast-element` |\n| `ref` | `@microsoft/fast-element` |\n| `slotted` | `@microsoft/fast-element` |\n| `when` | `@microsoft/fast-element` |\n| `repeat` | `@microsoft/fast-element` |\n\n### Migration steps\n\n1. Update declarative runtime imports to\n   `@microsoft/fast-element/declarative.js`.\n2. Update declarative utility imports such as `deepMerge` to\n   `@microsoft/fast-element/declarative-utilities.js`.\n3. Keep importing FAST Element APIs such as `FASTElement`, `FAST`,\n   `ElementController`, definition/controller types, `attr`, `Schema`, and\n   `observable` from `@microsoft/fast-element`.\n4. Call `enableHydration()` from `@microsoft/fast-element/hydration.js` when\n   prerendered content should be hydrated.\n\n## `deepMerge` array replacement\n\nWhen an array's contents change, `deepMerge` replaces the owning property's\narray rather than mutating the existing array in place. This affects both\n`observerMap()`-managed data and direct consumers of the exported helper.\nPreviously captured array references retain the old data; mutating them no\nlonger updates the owning object. Deeply equal arrays are left unchanged.\n\nRe-read the array from its owner after merging:\n\n```ts\nimport { deepMerge } from \"@microsoft/fast-element/declarative-utilities.js\";\n\nconst user = { orders: [{ id: 101 }] };\nconst oldOrders = user.orders;\n\ndeepMerge(user, { orders: [{ id: 103 }] });\n\n// oldOrders still contains order 101 and is disconnected from user.orders.\nuser.orders.push({ id: 104 });\n```\n\nFor `observerMap()`-managed properties, the owning property's notification\ncauses `f-repeat` bindings to observe the replacement array automatically.\nDirect `deepMerge` consumers must still arrange their own change notifications;\nthe helper does not make plain objects observable.\n\n## Optional helper and removed path exports (v2 → v3)\n\nFAST Element v3 adds focused flat path exports for optional helpers and removes\nolder nested or unused package exports. Root imports for core FAST Element APIs\nremain supported, but code that imports helper APIs from older nested paths must\nmove to the flat path exports.\n\n### Import changes\n\n| Before | After |\n|---|---|\n| `@microsoft/fast-element/binding/two-way.js` | `@microsoft/fast-element/two-way.js` |\n| `@microsoft/fast-element/binding/signal.js` | `@microsoft/fast-element/signal.js` |\n| Deep directive imports | `@microsoft/fast-element/children.js`, `@microsoft/fast-element/repeat.js`, `@microsoft/fast-element/when.js`, `@microsoft/fast-element/ref.js`, `@microsoft/fast-element/slotted.js`, or `@microsoft/fast-element/node-observation.js` |\n| Declarative map helpers from old declarative surfaces | `@microsoft/fast-element/attribute-map.js` and `@microsoft/fast-element/observer-map.js` |\n\n### Removed package exports\n\n| Removed | Replacement |\n|---|---|\n| `@microsoft/fast-element/install-element-hydration.js` | No side-effect import. Call `enableHydration()` from `@microsoft/fast-element/hydration.js` when SSR content should hydrate. |\n| `@microsoft/fast-element/install-hydratable-view-templates.js` | No side-effect import. `enableHydration()` installs hydratable template support. |\n| `@microsoft/fast-element/element-hydration.js` | `@microsoft/fast-element/hydration.js` for public hydration APIs. |\n| `@microsoft/fast-element/metadata.js` | No supported public replacement. |\n| `@microsoft/fast-element/testing.js` | No supported public replacement. |\n| `@microsoft/fast-element/pending-task.js` | No supported public replacement. |\n\n### Migration steps\n\n1. Replace older nested helper imports with the flat path exports shown above.\n2. Remove hydration side-effect imports and call `enableHydration()` before FAST\n   elements connect when SSR content should hydrate.\n3. Remove imports from deleted package exports. If your app depended on one of\n   those internals, move that usage into app-owned code or a supported public\n   API.\n\n## `attribute-name-strategy` default changed (v2 → v3)\n\nThe declarative attribute map default changed from `\"none\"` to `\"camelCase\"`.\nWith the default strategy, a binding key such as `{{firstName}}` maps to the\n`firstName` property and the `first-name` HTML attribute. In v2-style\ndeclarative templates that relied on literal attribute names, this can change\nwhich property receives data.\n\n### Migration steps\n\n1. Audit declarative templates for binding keys that contain hyphens or that\n   intentionally matched attribute names exactly.\n2. If you want the v2 behavior, configure the client definition extension with\n   `attributeMap({ \"attribute-name-strategy\": \"none\" })`.\n3. If server-rendered HTML is generated with `@microsoft/fast-build`, pass\n   `--attribute-name-strategy=none` so server and client mapping agree.\n\n## `TemplateOptions` removal (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `TemplateOptions` | No replacement |\n| `PartialFASTElementDefinition.templateOptions` | No replacement |\n| `FASTElementDefinition.templateOptions` | No replacement |\n\n### Changed behavior\n\n- Subclass `define()` calls no longer use `templateOptions` to delay platform\n  definition or connection.\n- Elements can still be defined before a template is attached; a later\n  `FASTElementDefinition.template` update notifies connected elements so they\n  can render or hydrate with the new template.\n\n### Migration steps\n\n1. Remove `templateOptions` from element definitions.\n2. Continue calling `define({ name })` when a definition needs to exist before\n   its template is attached.\n3. If a template is supplied later, assign `FASTElementDefinition.template` (or\n   use the declarative runtime that does so for you).\n\n## `FASTElementDefinition.isRegistered` removal (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `FASTElementDefinition.isRegistered` | `fastElementRegistry.whenRegistered(tagName)`, `fastElementRegistry.getByType(type)`, or `fastElementRegistry.getForInstance(instance)` |\n\n### Migration steps\n\n1. Import `fastElementRegistry` from `@microsoft/fast-element/registry.js`.\n2. Use `fastElementRegistry.whenRegistered(tagName)` when code needs to wait for\n   a definition by tag name.\n3. Use `fastElementRegistry.getByType(type)` or\n   `fastElementRegistry.getForInstance(instance)` when code already has a\n   constructor or element instance.\n\n## Declarative TemplateElement API removal (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `TemplateElement` public export | `declarativeTemplate()` on each FAST element definition |\n| `TemplateElement.define({ name: \"f-template\" })` | No manual definition; `declarativeTemplate()` defines FAST's internal `<f-template>` publisher in the target registry |\n| `TemplateElement.config(callbacks)` / `HydrationLifecycleCallbacks` | `enableHydration().whenHydrated(tagName)` for tag-specific hydration waits and `enableHydration().whenHydrated()` for the active hydration batch |\n| `TemplateElement.options(...)`, `ElementOptions`, `ElementOptionsDictionary` | Define extensions: `attributeMap(...)` and `observerMap(...)` passed as the second argument to `define()` |\n| `AttributeMap` / `ObserverMap` exports from the old declarative public surface | `attributeMap()` / `observerMap()` extension helpers and their config types |\n\n### Migration steps\n\n1. Replace manual `<f-template>` registration with `template: declarativeTemplate()`:\n\n   ```typescript\n   // Before\n   import { TemplateElement } from \"@microsoft/fast-element\";\n   TemplateElement.define({ name: \"f-template\" });\n\n   MyElement.define({ name: \"my-element\" });\n\n   // After\n   import { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n\n   MyElement.define({\n       name: \"my-element\",\n       template: declarativeTemplate(),\n   });\n   ```\n\n2. Replace `TemplateElement.options()` with definition extensions:\n\n   ```typescript\n   import { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\n   import { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n   import { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\n   MyElement.define(\n       {\n           name: \"my-element\",\n           template: declarativeTemplate(),\n       },\n       [attributeMap(), observerMap()],\n   );\n   ```\n\n   `attributeMap()` is imported from\n   `@microsoft/fast-element/attribute-map.js` and `observerMap()` from\n   `@microsoft/fast-element/observer-map.js` for declarative templates,\n   manually supplied schemas, or both. `FASTElementDefinition.schema` is optional;\n   `declarativeTemplate()` assigns it automatically, and `observerMap()` can\n   take a manual schema with `observerMap({ schema })`.\n\n3. Replace `TemplateElement.config()` with `enableHydration().whenHydrated(tagName)`\n   for tag-specific hydration waits and `enableHydration().whenHydrated()` for the\n   active hydration batch.\n   Hydration is not installed by `declarative.js`; call `enableHydration()`\n   before elements connect when SSR content should hydrate.\n\n## Debug entrypoint explicit enablement (v3)\n\n### Import changes\n\n| Before | After |\n|---|---|\n| `import \"@microsoft/fast-element\";` | `import { enableDebug } from \"@microsoft/fast-element/debug.js\"; enableDebug();` |\n\n### Migration steps\n\n1. Replace setup-only `debug.js` imports with an explicit `enableDebug()` call.\n2. Keep using the root package `development` export or debug rollup bundle when\n   you want debug behavior enabled automatically.\n\n## Declarative event handler `e` removal (v3)\n\n### Removed behavior\n\n| Removed | Replacement |\n|---|---|\n| Bare `e` event arguments in declarative event handlers | `$e` |\n| `TemplateParser.hasDeprecatedEventSyntax` | No replacement |\n\nOnly `$e` and `$c` are reserved event handler arguments in declarative\ntemplates. Bare `e` now resolves like any other binding path on the current\ndata source.\n\n### Migration steps\n\n1. Replace declarative event bindings such as\n   `@click=\"{handleClick(e)}\"` with `@click=\"{handleClick($e)}\"`.\n2. Remove any `TemplateParser.hasDeprecatedEventSyntax` checks or warnings from\n   custom tooling.\n\n## Prerendered Content Optimization (v2 → v3)\n\n### Removed and moved APIs\n\n| 2.x API | 3.x guidance |\n|---|---|\n| `HydratableElementController` | `ElementController` (prerendered path built in) |\n| `HydrationControllerCallbacks` | Call `enableHydration()` and await the returned controller's `whenHydrated()` promise |\n| `needsHydrationAttribute` | No replacement. Existing shadow root detection sets `ElementController.isPrerendered`. |\n| Root `deferHydrationAttribute` export | Import `deferHydrationAttribute` from `@microsoft/fast-element/hydration.js` only if you still need the legacy attribute string. New server-rendered markup should omit `defer-hydration`. |\n\n### Removed side-effect imports\n\n| Import | Replacement |\n|---|---|\n| `@microsoft/fast-element/install-hydration.js` | No replacement needed — prerendered path is built into `ElementController` |\n| `@microsoft/fast-element/install-hydratable-view-templates.js` | No replacement needed — `enableHydration()` installs hydratable template support |\n\nUse `enableHydration()` from `@microsoft/fast-element/hydration.js` when SSR\ncontent should hydrate. The declarative entrypoint no longer installs hydration\nautomatically.\n\n### Changed behavior\n\n- **`attributeChangedCallback` during upgrade**: When `isPrerendered` is true and the element has not yet connected, attribute change callbacks are suppressed. After connection, all attribute changes are processed normally.\n- **Declarative template resolution**: `declarativeTemplate()` waits for the\n  matching `<f-template>` before `define()` completes, so connected elements\n  hydrate with a concrete template. No `defer-hydration` attribute is needed.\n- **Binding evaluation with existing shadow root**: When an existing shadow root is detected, `attribute` and `booleanAttribute` bindings skip their initial DOM update. All other binding types (event, content, property, tokenList) run normally.\n\n### New APIs\n\n- **`ElementController.isPrerendered`** (`Promise<boolean>`): Resolves to `true` when the element had a declarative shadow root at connect time, or `false` when the component was client-side rendered.\n- **`ElementController.isHydrated`** (`Promise<boolean>`): Resolves to `true` only when hydration ran successfully.\n- **`ViewController.isPrerendered`** (`Promise<boolean> | undefined`): Available to custom directives. Resolves to `true` when the view's content was prerendered, `false` otherwise.\n- **`ViewController.isHydrated`** (`Promise<boolean> | undefined`): Available to custom directives. Resolves to `true` only when hydration ran successfully.\n\n### Migration steps\n\n1. Remove `HydratableElementController.install()` calls.\n2. Remove `import \"@microsoft/fast-element/install-hydration.js\"` side-effect imports.\n3. Replace `element.$fastController instanceof HydratableElementController` checks with `await element.$fastController.isPrerendered`.\n4. Remove `defer-hydration` and `needs-hydration` attributes from server-rendered markup.\n\n## Hydration Marker Format (v3)\n\n### Changed format\n\nThe hydration markers embedded in SSR output have been simplified from verbose, index-embedded comment markers to compact, data-free sequential markers.\n\n#### Comment markers\n\n| Marker type | Old format | New format |\n|---|---|---|\n| Content binding start | `<!-- fe-b$$start$$<index>$$<scopeId>$$fe-b -->` | `<!--fe:b-->` |\n| Content binding end | `<!-- fe-b$$end$$<index>$$<scopeId>$$fe-b -->` | `<!--fe:/b-->` |\n| Repeat item start | `<!-- fe-repeat$$start$$<itemIndex>$$fe-repeat -->` | `<!--fe:r-->` |\n| Repeat item end | `<!-- fe-repeat$$end$$<itemIndex>$$fe-repeat -->` | `<!--fe:/r-->` |\n| Element boundary start | `<!-- fe-eb$$start$$<elementId>$$fe-eb -->` | `<!--fe:e-->` |\n| Element boundary end | `<!-- fe-eb$$end$$<elementId>$$fe-eb -->` | `<!--fe:/e-->` |\n\n#### Attribute binding markers\n\n| Old format | New format |\n|---|---|\n| `data-fe-b=\"0 1 2\"` (space-separated indices) | `data-fe=\"N\"` (binding count) |\n| `data-fe-b-0` (enumerated, one per factory) | `data-fe=\"N\"` |\n| `data-fe-c-0-3` (compact, start index + count) | `data-fe=\"N\"` |\n\n### Removed APIs\n\n| Export | Replacement |\n|---|---|\n| `HydrationMarkup.contentBindingStartMarker(index, scopeId)` | `HydrationMarkup.contentBindingStartMarker()` |\n| `HydrationMarkup.contentBindingEndMarker(index, scopeId)` | `HydrationMarkup.contentBindingEndMarker()` |\n| `HydrationMarkup.isContentBindingStartMarker(data)` | `HydrationMarkup.isContentBindingStartMarker(data)` (unchanged signature, new implementation) |\n| `HydrationMarkup.isContentBindingEndMarker(data)` | `HydrationMarkup.isContentBindingEndMarker(data)` (unchanged signature, new implementation) |\n| `HydrationMarkup.parseAttributeBinding(element)` | `HydrationMarkup.parseAttributeBindingCount(element)` |\n| `HydrationMarkup.parseRepeatStartMarker(data)` | `HydrationMarkup.isRepeatViewStartMarker(data)` |\n| `HydrationMarkup.parseRepeatEndMarker(data)` | `HydrationMarkup.isRepeatViewEndMarker(data)` |\n| `HydrationMarkup.parseElementBoundaryStartMarker(content)` | `HydrationMarkup.isElementBoundaryStartMarker(node)` |\n| `HydrationMarkup.parseElementBoundaryEndMarker(content)` | `HydrationMarkup.isElementBoundaryEndMarker(node)` |\n\n### Impact\n\nThis is a **breaking change** for SSR output format. Any system that produces or parses hydration markers must be updated to use the new format. The `@microsoft/fast-build` Rust crate and WASM binary have been updated accordingly.\n\n- Marker parsing uses string equality checks (`data === \"fe:b\"`) instead of regex\n- Start/end pairing uses balanced depth counting instead of embedded IDs\n- The hydration walker uses a sequential factory pointer instead of index-based lookup\n- SSR and client versions must match — mixing old SSR output with new client code (or vice versa) will fail\n\n## Async define/compose/register API (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `FASTElement.defineAsync()` | Subclass `define()` calls |\n| `FASTElement.compose()` and subclass `compose()` calls | Subclass `define()` calls |\n| `FASTElementDefinition.composeAsync()` | Subclass `define()` calls |\n| `FASTElementDefinition.registerAsync()` | `FASTElementDefinition.register()` (same `Promise<Function>` return type) |\n\n### Changed behavior\n\n- Subclass **`define()`** calls return `Promise<TType>` only for code that\n  explicitly needs to observe registration completion. When\n  `template: declarativeTemplate()` is used, that Promise resolves after the\n  matching `<f-template>` supplies the concrete template.\n- Subclass compose helpers are no longer part of the public authoring surface; use subclass `define()` for registration.\n- **`@customElement` decorator** calls `define()` internally but does not return the Promise (fire-and-forget). For complete definitions with a template, the element is registered via a microtask.\n\n### Migration steps\n\n1. Replace `defineAsync()` calls with `define()`:\n\n   ```typescript\n    // Before\n    MyElement.defineAsync({\n        name: \"my-element\",\n        templateOptions: \"defer-and-hydrate\",\n    });\n\n    // After\n    MyElement.define({\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    });\n   ```\n\n2. Replace subclass `compose()` calls that immediately register an element with\n   `define()`:\n\n   ```typescript\n    // Before\n    MyElement.compose({\n        name: \"my-element\",\n        template,\n        styles,\n    }).define();\n\n    // After\n    MyElement.define({\n        name: \"my-element\",\n        template,\n        styles,\n    });\n   ```\n\n3. Replace `FASTElementDefinition.composeAsync()` calls that register an element\n   with subclass `define()`:\n\n   ```typescript\n   // Before\n   (await FASTElementDefinition.composeAsync(MyElement, {\n       name: \"my-element\",\n       template,\n       styles,\n   })).define();\n\n   // After\n   MyElement.define({\n       name: \"my-element\",\n       template,\n       styles,\n   });\n   ```\n\n4. Replace `registerAsync()` calls with `register()`:\n\n   ```typescript\n   // Before\n   const el = await FASTElementDefinition.registerAsync(name);\n\n   // After\n   const el = await FASTElementDefinition.register(name);\n   ```\n\n5. Replace `FASTElementDefinition.compose()` calls that chain `.define()` with\n   subclass `define()`:\n\n   ```typescript\n    // Before\n    FASTElementDefinition.compose(MyElement, options).define();\n\n    // After\n    MyElement.define(options);\n   ```\n\n## Dynamic stylesheet behaviors (v3)\n\n### Removed API\n\n| Removed | Replacement |\n|---|---|\n| `ElementStyles.withBehaviors()` | Move the runtime condition into the element and call `this.$fastController.addStyles()` / `this.$fastController.removeStyles()` directly. |\n| `ElementStyles.behaviors` | Move any runtime behavior out of the stylesheet and into the element or controller lifecycle. |\n| CSS bindings in `css` (for example ``css`color: ${x => x.color}```) | Move the dynamic value into the element and update classes, attributes, or inline styles from element code. |\n| `CSSDirective.createCSS(add)` | Update directives to implement `createCSS()` and return only static CSS content. |\n\n### Changed behavior\n\n- `css` and `css.partial()` no longer compose `HostBehavior`s.\n- `css` no longer accepts function or `Binding` interpolations.\n- `ElementStyles` is now a fully static style container.\n\n### Migration steps\n\n1. Keep the conditional `ElementStyles` in a separate `css` value.\n2. Move the external listener or condition (for example `matchMedia()` or an app event subscription) into the element lifecycle.\n3. Call `this.$fastController.addStyles(styles)` when the condition is active and `this.$fastController.removeStyles(styles)` when it is inactive or during cleanup.\n4. If you previously interpolated bindings or behavior-producing directives into `css`, replace them with element state and standard DOM or controller updates.\n\n## `booleanConverter` aligned with native HTML boolean attribute semantics (v2 → v3)\n\n### Changed behavior\n\n`@attr({ mode: \"boolean\" })` and `booleanConverter` now match how the platform treats native boolean attributes (e.g., `disabled`, `required`):\n\n- **Attribute → property** is presence-based: `setAttribute(name, anyString)` (including the empty string) sets the property to `true`; only `removeAttribute(name)` makes it `false`.\n- **Property → attribute** uses `Boolean()` coercion: any JavaScript truthy value adds the attribute (with value `\"\"`); any falsy value removes it.\n\nThe headline v2 → v3 difference is that `setAttribute(name, \"false\")` now resolves to property `true`, matching `<input disabled=\"false\">` still being disabled.\n\n`booleanConverter` shape:\n\n```ts\ntoView(value: any) {\n    return value ? \"\" : null;\n}\n\nfromView(value: any) {\n    return !!value;\n}\n```\n\n`booleanConverter` v2 → v3 result differences:\n\n| Call | v2 result | v3 result |\n|---|---|---|\n| `fromView(\"false\")` | `false` | `true` |\n| `fromView(\"\")` | `true` | `false` |\n| `fromView(NaN)` | `true` | `false` |\n| `toView(true)` (or any truthy) | `\"true\"` | `\"\"` |\n| `toView(false)` (or any falsy) | `\"false\"` | `null` |\n\n> **Note**: For `mode: \"boolean\"`, FAST writes attributes via `DOM.setBooleanAttribute` (presence-based) and reads them as `value !== null`, so the `mode: \"boolean\"` reflection path does **not** route through `booleanConverter.toView()` or `booleanConverter.fromView()`. The converter methods still apply to property assignment (`el.bool = X` runs `fromView(X)`), explicit calls (`booleanConverter.fromView(x)`), and `booleanConverter` paired with `mode: \"reflect\"` (which calls `toView`).\n\n### Migration steps\n\n1. Audit `boolean`-mode attributes for the literal string `\"false\"` in templates or SSR HTML — the resulting property will be `true`, not `false`. To express the falsy state, omit the attribute entirely (or call `element.removeAttribute(name)`). Setting `element.bool = false` continues to remove the reflected attribute.\n2. Audit code that calls `booleanConverter.toView()` directly or pairs `booleanConverter` with `mode: \"reflect\"`. The output strings are no longer `\"true\"` / `\"false\"`.\n3. If you need a tri-state attribute (`true` / `false` / unset) that preserves an explicit `\"false\"` string value, use `nullableBooleanConverter` with `mode: \"reflect\"` instead of `mode: \"boolean\"`.\n","packages/fast-element/docs/migration/fast-html.md":"# Migrating from previous versions\n\n## Hydration Marker Format (v1-alpha → v1)\n\nThe SSR output format for hydration markers has been simplified. If you have any tooling that inspects or generates hydration markers, update it to use the new format.\n\n| Old marker | New marker |\n|---|---|\n| `<!-- fe-b$$start$$...$$fe-b -->` | `<!--fe:b-->` |\n| `<!-- fe-b$$end$$...$$fe-b -->` | `<!--fe:/b-->` |\n| `<!-- fe-repeat$$start$$...$$fe-repeat -->` | `<!--fe:r-->` |\n| `<!-- fe-repeat$$end$$...$$fe-repeat -->` | `<!--fe:/r-->` |\n| `data-fe-b=\"0 1 2\"` / `data-fe-b-0` / `data-fe-c-0-3` | `data-fe=\"N\"` |\n\nThe `@microsoft/fast-build` WASM binary emits the new markers automatically. Rebuild all fixtures and SSR output after upgrading.\n\nSee the [`@microsoft/fast-element` migration guide](./fast-element-3.md#hydration-marker-format-v3) for full details on API changes.\n\n## Prerendered Content Optimization (v1-alpha → v1)\n\n### Removed exports\n\n| Export | Replacement |\n|---|---|\n| `RenderableFASTElement` | Extend `FASTElement` |\n\n### Removed concepts\n\n| Concept | Replacement |\n|---|---|\n| `prepare()` lifecycle hook | Set state in `connectedCallback`; the reactive system updates the DOM |\n| `defer-hydration` attribute in rendered markup | Template-pending guard in `ElementController.connect()` |\n| `needs-hydration` attribute in rendered markup | `hasExistingShadowRoot` detection in `ElementController` |\n| `waitForAncestorHydration()` | Not needed — prerendered content is correct regardless of connection order |\n\n### Migration steps\n\n1. Replace `RenderableFASTElement(MyComponent).defineAsync({...})` with\n   `MyComponent.define({...})` and use `declarativeTemplate()` for declarative\n   templates. If code explicitly observes the Promise returned by `define()`,\n   it resolves after the matching `<f-template>` supplies the concrete template.\n\n   ```typescript\n   // Before\n   import { RenderableFASTElement } from \"@microsoft/fast-html\";\n   RenderableFASTElement(MyComponent).defineAsync({\n       name: \"my-component\",\n       templateOptions: \"defer-and-hydrate\",\n   });\n\n   // After\n   MyComponent.define({\n       name: \"my-component\",\n       template: declarativeTemplate(),\n   });\n   ```\n\n2. Remove `prepare()` methods. Move any initialization logic to `connectedCallback`:\n\n   ```typescript\n   // Before\n   class MyComponent extends FASTElement {\n       async prepare() {\n           this.data = await fetchData();\n       }\n   }\n\n   // After\n   class MyComponent extends FASTElement {\n       connectedCallback() {\n           super.connectedCallback();\n           this.loadData();\n       }\n       async loadData() {\n           this.data = await fetchData();\n       }\n   }\n   ```\n\n3. Remove `defer-hydration` and `needs-hydration` attributes from server-rendered markup:\n\n   ```html\n   <!-- Before -->\n   <my-component defer-hydration needs-hydration text=\"Hello\">\n       <template shadowrootmode=\"open\">...</template>\n   </my-component>\n\n   <!-- After -->\n   <my-component text=\"Hello\">\n       <template shadowrootmode=\"open\">...</template>\n   </my-component>\n   ```\n\n4. Await `$fastController.isPrerendered` to detect prerendered components:\n\n   ```typescript\n   connectedCallback() {\n       super.connectedCallback();\n       this.$fastController.isPrerendered.then(prerendered => {\n           if (!prerendered) {\n               this.fetchData();\n           }\n       });\n   }\n   ```\n\n## Modularize Schema, ObserverMap, and AttributeMap\n\n### Import changes\n\nConfiguration types have moved from `template.ts` to their owning modules. If you import types directly from internal paths, update your imports:\n\n| Before | After |\n|---|---|\n| `import type { ObserverMapConfig } from \"./template.js\"` | `import type { ObserverMapConfig } from \"./observer-map.js\"` |\n| `import type { AttributeMapConfig } from \"./template.js\"` | `import type { AttributeMapConfig } from \"./attribute-map.js\"` |\n\nPublic declarative imports now come from\n`@microsoft/fast-element/declarative.js` rather than\n`@microsoft/fast-html`, and declarative utilities come from\n`@microsoft/fast-element/declarative-utilities.js`. Map extensions come from\n`@microsoft/fast-element/attribute-map.js` and\n`@microsoft/fast-element/observer-map.js`.\n\n### Schema changes\n\n`Schema.jsonSchemaMap` (static property) has been replaced by:\n- An instance-level `schemaMap` on each `Schema` instance (private)\n- A module-level `schemaRegistry` export for cross-element lookups\n\n| Before | After |\n|---|---|\n| `Schema.jsonSchemaMap.get('my-element')` | `import { schemaRegistry } from \"@microsoft/fast-element\"; schemaRegistry.get('my-element')` |\n\n### Public exports\n\nThe public entrypoint exports the functional declarative API:\n\n| Export | Purpose |\n|---|---|\n| `declarativeTemplate()` | Resolves `<f-template>` markup for a FAST element definition |\n| `attributeMap()` | Definition extension for automatic `@attr` property registration |\n| `observerMap()` | Definition extension for automatic deep observation |\n| `Schema` | JSON schema builder class |\n| `schemaRegistry` | Module-level registry for cross-element schema lookups |\n| `JSONSchema` | JSON Schema type interface |\n| `CachedPathMap` | Schema registry map type |\n\n## Simplified ObserverMap and AttributeMap defaults\n\nThe explicit `ObserverMapOption.all` and `AttributeMapOption.all` constants have\nbeen removed. Calling `observerMap()` with no arguments observes every\ndiscovered root property, and calling `attributeMap()` with no arguments maps\nevery discovered leaf binding.\n\n| Before | After |\n|---|---|\n| `observerMap(ObserverMapOption.all)` | `observerMap()` |\n| `attributeMap(AttributeMapOption.all)` | `attributeMap()` |\n\n## Attribute name strategy default changed\n\nThe default `attribute-name-strategy` for declarative attribute mapping is now\n`\"camelCase\"` instead of `\"none\"`. A binding key such as `{{firstName}}` maps to\nthe `firstName` property and the `first-name` HTML attribute by default. If your\ntemplates depended on literal attribute names, opt back in to the old behavior:\n\n```ts\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\n\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [attributeMap({ \"attribute-name-strategy\": \"none\" })],\n);\n```\n\nWhen using `@microsoft/fast-build`, keep the server and client settings aligned:\n\n```bash\nfast build --attribute-name-strategy=none\n```\n\n## Declarative TemplateElement API removal\n\nThe public declarative API is now the functional API. The `<f-template>`\nimplementation is internal and is defined automatically by `declarativeTemplate()`.\n\n| Removed | Replacement |\n|---|---|\n| `TemplateElement` public export | `declarativeTemplate()` on each FAST element definition |\n| `TemplateElement.define({ name: \"f-template\" })` | No manual definition; `declarativeTemplate()` defines the internal publisher in the target registry |\n| `TemplateElement.config(callbacks)` / `HydrationLifecycleCallbacks` | `enableHydration().whenHydrated(tagName)` for tag-specific hydration waits and `enableHydration().whenHydrated()` for the active hydration batch |\n| `TemplateElement.options({ \"my-el\": { attributeMap, observerMap } })` | Define extensions: `MyElement.define(definition, [attributeMap(...), observerMap(...)])` |\n| `ElementOptions` / `ElementOptionsDictionary` | No replacement |\n| `AttributeMap` / `ObserverMap` class exports from the old declarative public surface | `attributeMap()` / `observerMap()` extension helpers and their config types |\n\nHydration is also no longer installed by `@microsoft/fast-element`.\nCall `enableHydration()` from `@microsoft/fast-element/hydration.js` before FAST\nelements connect when prerendered Declarative Shadow DOM should be reused.\n\n## Schema-driven maps and optional definition schema\n\n`attributeMap()` and `observerMap()` are now schema-driven extensions that are\nfactored away from declarative templating. Import them from\n`@microsoft/fast-element` for declarative or non-declarative use:\n\n```ts\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n```\n\n`FASTElementDefinition.schema` is optional. `declarativeTemplate()` assigns it\nautomatically when it parses `<f-template>` markup. Manual schema users can pass\na schema in the element definition, and `observerMap()` can also take a schema\ndirectly in configuration:\n\n```ts\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-element\");\nschema.addPath({\n    rootPropertyName: \"user\",\n    pathConfig: {\n        type: \"default\",\n        parentContext: null,\n        currentContext: null,\n        path: \"user.name\",\n    },\n    childrenMap: null,\n});\n\nMyElement.define({ name: \"my-element\" }, [observerMap({ schema })]);\n```\n","packages/fast-element/docs/styles/api-report.api.md":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport type ComposableStyles = string | ElementStyles | CSSStyleSheet;\n\n// @public\nexport type Constructable<T = {}> = {\n    new (...args: any[]): T;\n};\n\n// @public\nexport type ConstructibleStyleStrategy = {\n    new (styles: (string | CSSStyleSheet)[]): StyleStrategy;\n};\n\n// @public\nexport interface CSSDirective {\n    createCSS(): ComposableStyles;\n}\n\n// @public\nexport const CSSDirective: Readonly<{\n    getForInstance: (object: any) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    getByType: (key: Function) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    define<TType extends Constructable<CSSDirective>>(type: any): TType;\n}>;\n\n// @public\nexport function cssDirective(): (type: Constructable<CSSDirective>) => void;\n\n// @public\nexport interface CSSDirectiveDefinition<TType extends Constructable<CSSDirective> = Constructable<CSSDirective>> {\n    readonly type: TType;\n}\n\n// @public\nexport class ElementStyles {\n    constructor(styles: ReadonlyArray<ComposableStyles>);\n    // @internal (undocumented)\n    addStylesTo(target: StyleTarget): void;\n    // @internal (undocumented)\n    isAttachedTo(target: StyleTarget): boolean;\n    static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;\n    // @internal (undocumented)\n    removeStylesFrom(target: StyleTarget): void;\n    static setDefaultStrategy(Strategy: ConstructibleStyleStrategy): void;\n    get strategy(): StyleStrategy;\n    // (undocumented)\n    readonly styles: ReadonlyArray<ComposableStyles>;\n    static readonly supportsAdoptedStyleSheets: boolean;\n    withStrategy(Strategy: ConstructibleStyleStrategy): this;\n}\n\n// @public\nexport interface ExecutionContext<TParent = any> {\n    readonly event: Event;\n    eventDetail<TDetail>(): TDetail;\n    eventTarget<TTarget extends EventTarget>(): TTarget;\n    index: number;\n    readonly isEven: boolean;\n    readonly isFirst: boolean;\n    readonly isInMiddle: boolean;\n    readonly isLast: boolean;\n    readonly isOdd: boolean;\n    length: number;\n    parent: TParent;\n    parentContext: ExecutionContext<TParent>;\n}\n\n// @public\nexport const ExecutionContext: Readonly<{\n    default: ExecutionContext;\n    getEvent(): Event | null;\n    setEvent(event: Event | null): void;\n}>;\n\n// @public\nexport interface ExpressionController<TSource = any, TParent = any> {\n    readonly context: ExecutionContext<TParent>;\n    readonly isBound: boolean;\n    onUnbind(behavior: {\n        unbind(controller: ExpressionController<TSource, TParent>): any;\n    }): void;\n    readonly source: TSource;\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface HostBehavior<TSource = any> {\n    addedCallback?(controller: HostController<TSource>): void;\n    connectedCallback?(controller: HostController<TSource>): void;\n    disconnectedCallback?(controller: HostController<TSource>): void;\n    removedCallback?(controller: HostController<TSource>): void;\n}\n\n// @public\nexport interface HostController<TSource = any> extends ExpressionController<TSource> {\n    addBehavior(behavior: HostBehavior<TSource>): void;\n    addStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    readonly isConnected: boolean;\n    mainStyles: ElementStyles | null;\n    removeBehavior(behavior: HostBehavior<TSource>, force?: boolean): void;\n    removeStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n}\n\n// @public\nexport const SourceLifetime: Readonly<{\n    readonly unknown: undefined;\n    readonly coupled: 1;\n}>;\n\n// @public\nexport type SourceLifetime = (typeof SourceLifetime)[keyof typeof SourceLifetime];\n\n// @public\nexport interface StyleStrategy {\n    addStylesTo(target: StyleTarget): void;\n    removeStylesFrom(target: StyleTarget): void;\n}\n\n// @public\nexport interface StyleTarget extends Pick<Node, \"getRootNode\"> {\n    adoptedStyleSheets?: CSSStyleSheet[];\n    append(styles: HTMLStyleElement): void;\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\n    removeChild(styles: HTMLStyleElement): void;\n}\n\n// (No @packageDocumentation comment for this package)\n\n```\n","packages/fast-element/docs/template-bindings.md":"# FAST Element Template Bindings Architecture\n\nThis document explains how the FAST Element `html` tagged template system stores bindings, applies them to DOM elements, triggers updates on data changes, and handles HTML-specific behaviors like event listeners.\n\n## Overview\n\nThe template binding pipeline has five major stages:\n\n1. **Template Authoring** – The `html` tagged template collects binding expressions and builds placeholder-marked HTML.\n2. **Compilation** – The compiler parses the placeholder HTML into a `DocumentFragment`, walks the DOM tree, and records where each binding targets.\n3. **View Creation** – The compiled result clones the fragment and creates a *targets* object that maps each binding to its DOM node.\n4. **Binding (first render)** – Each factory creates a behavior that attaches to its target node: adding event listeners, setting attributes, or observing expressions.\n5. **Reactive Updates** – When observed data changes, one-way binding observers notify their directive, which re-evaluates the expression and pushes the new value to the DOM through a \"sink\" function.\n\n---\n\n## Mermaid Diagrams\n\n### 1. Template Creation & Storage\n\nThis diagram shows how the `html` tagged template literal processes interpolated values and stores them as factories keyed by unique IDs.\n\n```mermaid\nflowchart TD\n    A[\"html`&lt;div class='${expr}'&gt;${text}&lt;/div&gt;`\"] --> B[\"ViewTemplate.create(strings, values)\"]\n    B --> C{\"For each interpolated value\"}\n    C -->|Function| D[\"Wrap in oneWay() → HTMLBindingDirective\"]\n    C -->|Binding instance| E[\"Wrap in HTMLBindingDirective\"]\n    C -->|HTMLDirective| F[\"Use directly\"]\n    C -->|Static value| G[\"Wrap in oneTime() → HTMLBindingDirective\"]\n    D --> H[\"directive.createHTML(add)\"]\n    E --> H\n    F --> H\n    G --> H\n    H --> I[\"add(factory) assigns unique ID\"]\n    I --> J[\"factories Record&lt;string, ViewBehaviorFactory&gt;\"]\n    I --> K[\"Returns placeholder marker in HTML string\"]\n    K --> L[\"Aspect Detection via lastAttributeNameRegex\"]\n    L -->|In attribute context| M[\"HTMLDirective.assignAspect(directive, attrName)\"]\n    L -->|In text content| N[\"aspectType = DOMAspect.content\"]\n    M --> O{\"Attribute prefix\"}\n    O -->|No prefix| P[\"DOMAspect.attribute\"]\n    O -->|: prefix| Q[\"DOMAspect.property\"]\n    O -->|? prefix| R[\"DOMAspect.booleanAttribute\"]\n    O -->|\"@\" prefix| S[\"DOMAspect.event\"]\n    O -->|:classList| T[\"DOMAspect.tokenList\"]\n    J --> U[\"new ViewTemplate(html, factories)\"]\n```\n\n### 2. Compilation – Walking the DOM & Storing Target Locations\n\nThe compiler transforms the placeholder-laden HTML into a `DocumentFragment` and builds a prototype with lazy property descriptors that navigate to target nodes by child index.\n\n```mermaid\nflowchart TD\n    A[\"ViewTemplate.compile()\"] --> B[\"Compiler.compile(html, factories, policy)\"]\n    B --> C[\"Create HTMLTemplateElement\"]\n    C --> D[\"template.innerHTML = policy.createHTML(html)\"]\n    D --> E[\"document.adoptNode(template.content) → fragment\"]\n    E --> F[\"new CompilationContext(fragment, factories, policy)\"]\n    F --> G[\"compileAttributes(context, template, 'h') — host bindings\"]\n    G --> H[\"compileChildren(context, fragment, 'r') — root\"]\n\n    H --> I{\"For each child node\"}\n    I -->|Element node type=1| J[\"compileAttributes: parse each attribute value\"]\n    J --> K{\"Parser.parse finds placeholders?\"}\n    K -->|Yes| L[\"Remove attribute from DOM\"]\n    L --> M[\"context.addFactory(factory, parentId, nodeId, index, tagName)\"]\n    I -->|Element node| N[\"compileChildren recursively\"]\n    I -->|Text node type=3| O[\"compileContent: Parser.parse text\"]\n    O --> P{\"Placeholders found?\"}\n    P -->|Yes| Q[\"Split text node, insert new text nodes\"]\n    Q --> R[\"context.addFactory for each directive part\"]\n    I -->|Comment node type=8| S[\"Parser.parse comment data\"]\n    S --> T[\"context.addFactory for structural directives\"]\n\n    M --> U[\"addTargetDescriptor(parentId, nodeId, childIndex)\"]\n    U --> V[\"Lazy getter: this[parentId].childNodes[childIndex]\"]\n    V --> W[\"Stored in descriptors → prototype via Object.create\"]\n\n    subgraph \"Target Node ID Scheme\"\n        X[\"Root: 'r'\"]\n        Y[\"Host: 'h'\"]\n        Z[\"Children: 'r.0', 'r.1', 'r.0.2'\"]\n        AA[\"Encodes DOM tree path via dot-separated child indices\"]\n    end\n\n    W --> AB[\"context.freeze() → compilation result\"]\n```\n\n### 3. View Creation – Cloning the Fragment & Resolving Targets\n\n```mermaid\nflowchart TD\n    A[\"compilationResult.createView(hostBindingTarget?)\"] --> B[\"fragment.cloneNode(true) → new DocumentFragment\"]\n    B --> C[\"targets = Object.create(proto)\"]\n    C --> D[\"targets.r = fragment (root)\"]\n    D --> E[\"targets.h = hostBindingTarget (host element)\"]\n    E --> F{\"For each registered nodeId\"}\n    F --> G[\"Access targets[nodeId] — triggers lazy getter chain\"]\n    G --> H[\"Getter resolves: this[parentId].childNodes[childIndex]\"]\n    H --> I[\"Caches result in targets._nodeId field\"]\n    I --> J[\"new HTMLView(fragment, factories, targets)\"]\n\n    subgraph \"HTMLView Structure\"\n        K[\"fragment: DocumentFragment with cloned DOM\"]\n        L[\"factories: CompiledViewBehaviorFactory[]\"]\n        M[\"targets: ViewBehaviorTargets {nodeId → Node}\"]\n        N[\"firstChild / lastChild: boundary nodes\"]\n        O[\"source: null (until bound)\"]\n        P[\"behaviors: null (created on first bind)\"]\n    end\n    J --> K\n    J --> L\n    J --> M\n```\n\n### 4. Binding – Attaching Behaviors to DOM Nodes\n\n```mermaid\nflowchart TD\n    A[\"view.bind(source)\"] --> B{\"First bind?\"}\n    B -->|Yes| C[\"Set view.source = source\"]\n    C --> D[\"Create behaviors array\"]\n    D --> E{\"For each factory\"}\n    E --> F[\"factory.createBehavior()\"]\n    F --> G[\"Select sink from sinkLookup based on aspectType\"]\n    G --> H[\"Wrap sink through policy.protect()\"]\n    H --> I[\"behavior.bind(controller/view)\"]\n\n    B -->|Subsequent| J[\"Unbind previous, set new source\"]\n    J --> K[\"Re-bind existing behaviors\"]\n\n    I --> L{\"aspectType?\"}\n\n    L -->|DOMAspect.event| M[\"Store controller ref on target node\"]\n    M --> N[\"target.addEventListener(targetAspect, directive, options)\"]\n    N --> O[\"directive IS the EventListener via handleEvent()\"]\n\n    L -->|DOMAspect.content| P[\"Register unbind handler\"]\n    P --> Q[\"Create observer via dataBinding.createObserver()\"]\n\n    L -->|attribute / property / etc.| Q\n\n    Q --> R[\"observer.bind(controller) → evaluates expression\"]\n    R --> S[\"updateTarget(target, aspect, value, controller)\"]\n\n    subgraph \"Sink Functions (sinkLookup)\"\n        S1[\"attribute → DOM.setAttribute(target, name, value)\"]\n        S2[\"booleanAttribute → DOM.setBooleanAttribute(target, name, value)\"]\n        S3[\"property → target[name] = value\"]\n        S4[\"content → updateContent() — manages text or composed views\"]\n        S5[\"tokenList → updateTokenList() — classList with versioning\"]\n        S6[\"event → no-op (handled via addEventListener)\"]\n    end\n```\n\n### 5. Reactive Update Cycle – Change Detection & DOM Updates\n\n```mermaid\nsequenceDiagram\n    participant Source as Data Source\n    participant Observable as Observable System\n    participant Observer as ExpressionObserver (OneWayBinding)\n    participant Directive as HTMLBindingDirective\n    participant Sink as UpdateTarget (sink fn)\n    participant DOM as Target DOM Node\n\n    Note over Source,DOM: Initial Bind\n    Directive->>Observer: dataBinding.createObserver(directive, directive)\n    Observer->>Source: Evaluate expression (tracks property access)\n    Source-->>Observer: Return value + record dependencies\n    Directive->>Sink: updateTarget(target, aspect, value, controller)\n    Sink->>DOM: Apply value (setAttribute, textContent, etc.)\n\n    Note over Source,DOM: Data Change\n    Source->>Observable: Property setter triggered\n    Observable->>Observer: Notify subscriber of change\n    Observer->>Directive: handleChange(binding, observer)\n    Directive->>Observer: observer.bind(controller) — re-evaluate\n    Observer->>Source: Re-evaluate expression\n    Source-->>Observer: Return new value\n    Directive->>Sink: updateTarget(target, aspect, newValue, controller)\n    Sink->>DOM: Update DOM with new value\n```\n\n### 6. Event Handling – Click Events and Other DOM Events\n\n```mermaid\nsequenceDiagram\n    participant User as User Interaction\n    participant DOM as Target DOM Element\n    participant Directive as HTMLBindingDirective (EventListener)\n    participant Context as ExecutionContext\n    participant Binding as dataBinding.evaluate()\n    participant Source as Component Source\n\n    Note over DOM: During bind: target.addEventListener(\"click\", directive)\n    Note over DOM: directive stores controller ref on target[data]\n\n    User->>DOM: Click event fires\n    DOM->>Directive: handleEvent(event)\n    Directive->>DOM: Read controller from event.currentTarget[data]\n    Directive->>Directive: Check controller.isBound\n    Directive->>Context: ExecutionContext.setEvent(event)\n    Directive->>Binding: evaluate(controller.source, controller.context)\n    Binding->>Source: Execute handler: (s, c) => s.handleClick(c.event)\n    Source-->>Binding: Return result\n    Binding-->>Directive: Return result\n    alt result !== true\n        Directive->>DOM: event.preventDefault()\n    end\n    Directive->>Context: ExecutionContext.setEvent(null)\n```\n\n### 7. Content Binding – Template Composition\n\nWhen a binding expression returns a `ContentTemplate` (e.g., another `ViewTemplate`), the content update sink composes a child view into the DOM.\n\n```mermaid\nflowchart TD\n    A[\"updateContent(target, aspect, value, controller)\"] --> B{\"value is null/undefined?\"}\n    B -->|Yes| C[\"Treat as empty string\"]\n    B -->|No| D{\"value.create exists? (ContentTemplate)\"}\n\n    D -->|Yes — Template| E[\"Clear target.textContent\"]\n    E --> F{\"Existing view on target.$fastView?\"}\n    F -->|No| G[\"view = value.create()\"]\n    F -->|Yes, same template| H[\"Reuse existing view\"]\n    F -->|Yes, different template| I[\"Remove old view, create new\"]\n    G --> J[\"view.bind(source, context)\"]\n    I --> J\n    J --> K[\"view.insertBefore(target)\"]\n    K --> L[\"Cache: target.$fastView = view, target.$fastTemplate = value\"]\n\n    D -->|No — Primitive| M{\"Existing composed view?\"}\n    M -->|Yes| N[\"view.remove(), view.unbind()\"]\n    N --> O[\"target.textContent = value\"]\n    M -->|No| O\n```\n\n---\n\n## Key Data Structures\n\n| Structure | Location | Purpose |\n|---|---|---|\n| `ViewTemplate` | template.ts | Holds raw HTML + factories record. Entry point for compilation. |\n| `factories: Record<string, ViewBehaviorFactory>` | template.ts | Maps unique IDs to binding factories (directives). |\n| `CompilationContext` | compiler.ts | Accumulates factories and builds the target prototype during compilation. |\n| `targets: ViewBehaviorTargets` | view.ts / html-directive.ts | Maps node IDs (e.g., `\"r.0.2\"`) to actual DOM nodes in a cloned fragment. |\n| `HTMLView` | view.ts | The live view instance: holds the fragment, factories, targets, behaviors, and source. |\n| `HTMLBindingDirective` | html-binding-directive.ts | The core binding: acts as factory, behavior, and event listener. |\n| `sinkLookup` | html-binding-directive.ts | Maps `DOMAspect` types to DOM update functions. |\n| `Binding` (abstract) | binding/binding.ts | Wraps an expression with policy, volatility, and observer creation. |\n| `ExpressionObserver` | observation/observable.ts | Tracks dependencies during expression evaluation and notifies on change. |\n\n## Binding Type Summary\n\n| Markup Syntax | Aspect Type | Sink Function | Example |\n|---|---|---|---|\n| `attr=\"${x => x.val}\"` | `attribute` | `DOM.setAttribute` | `class=\"${x => x.cls}\"` |\n| `?attr=\"${x => x.val}\"` | `booleanAttribute` | `DOM.setBooleanAttribute` | `?disabled=\"${x => x.off}\"` |\n| `:prop=\"${x => x.val}\"` | `property` | `target[prop] = value` | `:value=\"${x => x.name}\"` |\n| `:classList=\"${x => x.val}\"` | `tokenList` | `updateTokenList` | `:classList=\"${x => x.classes}\"` |\n| `@event=\"${x => x.handler}\"` | `event` | addEventListener | `@click=\"${(x,c) => x.onClick(c.event)}\"` |\n| `${x => x.val}` (in text) | `content` | `updateContent` | `<p>${x => x.msg}</p>` |\n\n---\n\n## Hydration: Attaching Bindings to Server-Rendered DOM\n\nWhen a page is server-side rendered (SSR) with Declarative Shadow DOM, the HTML arrives in the browser fully formed. Instead of creating new DOM nodes, FAST's hydration system **reuses the existing DOM** and attaches reactive bindings to it. This section explains how hydration markers in the SSR output guide the client-side binding process.\n\n### Enabling Hydration\n\nHydration is an opt-in feature. Calling `enableHydration()` patches\n`ViewTemplate.prototype` with:\n1. A `Hydratable` symbol — marks the template as hydration-capable (checked via `isHydratable()`).\n2. A `hydrate(firstChild, lastChild, hostBindingTarget?)` method — creates a `HydrationView` instead of an `HTMLView`.\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration();\n```\n\n### Hydration Marker Format\n\nThe SSR renderer embeds comment nodes and data attributes into the HTML to mark where bindings should attach. These markers encode the **factory index** (position in the compiled factories array) so the client can map each marker back to its corresponding `ViewBehaviorFactory`.\n\n#### Attribute Binding Markers\n\nElements with attribute/property/event bindings receive a `data-fe` attribute with the binding count:\n\n```html\n<!-- SSR output for: <div class=\"${x => x.cls}\" :value=\"${x => x.val}\"> -->\n<div data-fe=\"2\">server-rendered content</div>\n```\n\nThe attribute marker format is:\n\n| Attribute | Example | Description |\n|---|---|---|\n| `data-fe` | `data-fe=\"3\"` | Binding count — the number of attribute bindings on the element |\n\n#### Content Binding Markers\n\nText/template content bindings are wrapped in paired data-free comment nodes (matched by string equality, paired by balanced depth counting):\n\n```html\n<!--fe:b-->\nHello, World!\n<!--fe:/b-->\n```\n\n#### Repeat Directive Markers\n\nEach repeated item is bracketed by data-free repeat markers:\n\n```html\n<!--fe:r-->\n<li>First item</li>\n<!--fe:/r-->\n<!--fe:r-->\n<li>Second item</li>\n<!--fe:/r-->\n```\n\n#### Element Boundary Markers\n\nNested custom elements that also need hydration are demarcated so the parent's walker can skip over them:\n\n```html\n<!--fe:e-->\n<child-element>\n  <template shadowrootmode=\"open\">...child shadow DOM...</template>\n</child-element>\n<!--fe:/e-->\n```\n\n### Hydration Binding Flow\n\n`hydration/traversal.ts` owns pointer navigation and its live Range fallback.\n`hydration/target-builder.ts` consumes that traversal to map factories, keeping\ndirect native marker reads inline. `HydrationView` uses the same range utility\nwhen producing diagnostic fragments, without coupling it to target discovery.\n\n`enableHydration()` replaces the small core `components/element-registration.ts`\nstrategy with `hydration/attribute-observation.ts`. Client-only `FASTElement`\nbundles do not include observation tracking. Immediately before FAST's platform\nregistration, tracking records only a boolean proving that `data-fe` is\nunobserved, after extensions and asynchronous template resolution. The proof is\navailable during synchronous upgrades and restored if registration fails.\nEarlier untracked registrations remain conservative; calling `enableHydration()`\nagain does not reset existing proof. Hydration never reconstructs the platform\nsnapshot by rereading `constructor.observedAttributes`.\n\nFor a known unobserved `data-fe` attribute and native attribute methods, removal\ncannot invoke an attribute-change callback, so pointers remain active.\nRegistration/lifecycle accessors, custom attribute iterators, unknown registry\nwrappers, customized built-ins, and overridden attribute methods remain\nconservative. Legacy/custom marker cleanup still captures live boundaries from\nthe outset. Marker removal is not deferred and callback order is unchanged.\n\n```mermaid\nflowchart TD\n    A[\"Server renders HTML with Declarative Shadow DOM\"] --> B[\"Browser parses HTML, creates DOM + shadow roots\"]\n    B --> C[\"Custom element connects, HydratableElementController activates\"]\n    C --> D{\"Has 'defer-hydration' attribute?\"}\n    D -->|Yes| E[\"Wait until attribute is removed\"]\n    D -->|No| F[\"template.hydrate(firstChild, lastChild, hostBindingTarget)\"]\n    E -->|Attribute removed| F\n    F --> G[\"new HydrationView(firstChild, lastChild, sourceTemplate)\"]\n    G --> H[\"HydrationView.bind(source)\"]\n    H --> I[\"Stage: unhydrated → hydrating\"]\n    I --> J[\"buildViewBindingTargets(firstChild, lastChild, factories)\"]\n\n    J --> K[\"Pointer DFS for ordered sibling endpoints; live Range fallback otherwise or before mutating cleanup\"]\n    K --> L{\"Walk each node\"}\n\n    L -->|Element node| M[\"Parse data-fe attribute\"]\n    M --> N[\"Consume N sequential factories directly via targetFactory(); generic resolution for legacy markers\"]\n    N --> O[\"Remove data-fe marker attribute\"]\n\n    L -->|Comment: content marker| P[\"Match fe:b start marker by string equality\"]\n    P --> Q[\"Walk siblings to find matching fe:/b end marker\\nusing balanced depth counting\"]\n    Q --> R{\"Content between markers?\"}\n    R -->|Single text node| S[\"Target factory to text node directly\"]\n    R -->|Multiple nodes / template| T[\"Store boundaries in ViewBehaviorBoundaries\"]\n    T --> U[\"Insert dummy text node as target for future string updates\"]\n    R -->|Empty null/false binding| U\n    L -->|Comment: element boundary| V[\"Clear fe:e start marker data\\nSkip to matching fe:/e end marker\\nusing balanced depth counting\\nClear fe:/e end marker data\\nThrow if end marker not found\"]\n    L -->|Other| W[\"Continue walking\"]\n    J --> X[\"Return { targets, boundaries }\"]\n    X --> Y[\"Create behaviors from factories\"]\n    Y --> Z[\"behavior.bind(hydrationView)\"]\n    Z --> AA[\"Stage: hydrating → hydrated\"]\n\n    subgraph \"Host Binding Offset\"\n        BB[\"Host bindings (targetNodeId='h') are at the start of the factories array\"]\n        CC[\"getHydrationIndexOffset() counts host bindings to skip\"]\n        DD[\"SSR markers use indices relative to non-host factories\"]\n    end\n```\n\n### HydrationView vs HTMLView\n\n```mermaid\nflowchart LR\n    subgraph \"HTMLView (client-rendered)\"\n        A1[\"Compiler produces DocumentFragment\"] --> A2[\"fragment.cloneNode(true)\"]\n        A2 --> A3[\"Resolve targets via prototype getter chain\"]\n        A3 --> A4[\"Create behaviors & bind\"]\n    end\n\n    subgraph \"HydrationView (server-rendered)\"\n        B1[\"DOM already exists in shadow root\"] --> B2[\"Bounded pointer DFS scans markers; live Range fallback when needed\"]\n        B2 --> B3[\"buildViewBindingTargets maps markers → nodes\"]\n        B3 --> B4[\"Create behaviors & bind to existing nodes\"]\n        B4 --> B5[\"Marker comments cleared (data set to empty string)\"]\n    end\n```\n\n| Aspect | HTMLView | HydrationView |\n|---|---|---|\n| **DOM source** | Clones compiled DocumentFragment | Reuses server-rendered DOM in place |\n| **Target resolution** | Prototype getters via childNodes indices | Pointer DFS + sequential markers; live Range / generic-strategy fallback |\n| **Node creation** | Creates all DOM nodes from scratch | No node creation (reuses existing) |\n| **Fragment** | Holds cloned fragment, moved into host | No fragment initially (created only on remove) |\n| **Lifecycle** | Ready immediately after creation | Transitions through unhydrated → hydrating → hydrated |\n| **Validation** | Compilation guarantees structure | Must validate markers match factories (throws HydrationBindingError) |\n| **Boundaries** | Not needed (compiler tracks structure) | `bindingViewBoundaries` stores first/last node pairs for structural directives |\n\n### Content Binding Hydration\n\nWhen `HTMLBindingDirective.bind()` runs during hydration and the binding returns a `ContentTemplate`, the `updateContent` sink checks for pre-rendered boundaries:\n\n```mermaid\nsequenceDiagram\n    participant Directive as HTMLBindingDirective\n    participant Controller as HydrationView (controller)\n    participant Sink as updateContent()\n    participant Template as ContentTemplate\n\n    Directive->>Controller: bind(controller)\n    Note over Directive: aspectType = DOMAspect.content\n    Directive->>Sink: updateTarget(target, aspect, value, controller)\n    Sink->>Sink: value is ContentTemplate?\n\n    alt Hydrating & boundaries exist\n        Sink->>Controller: Check bindingViewBoundaries[targetNodeId]\n        Controller-->>Sink: { first: Node, last: Node }\n        Sink->>Template: value.hydrate(first, last)\n        Template-->>Sink: HydrationView (reuses existing nodes)\n        Sink->>Sink: view.bind(source, context) — attaches to pre-rendered DOM\n    else Already hydrated or no boundaries\n        Sink->>Template: value.create()\n        Template-->>Sink: HTMLView (creates new nodes)\n        Sink->>Sink: view.bind + view.insertBefore\n    end\n```\n\n### Repeat Directive Hydration\n\nThe repeat directive scans **forward** from its own content boundary to its\nlocation, pairing top-level ranges with a stack. This avoids reverse collection\nand rescanning prefixes belonging to earlier adjacent repeats. Nested markers\nremain untouched until child views hydrate. Both unmatched starts and unmatched\nends throw before repeat markers are cleared.\n\nThe read-only `collectHydrationRepeatRanges()` helper in\n`hydration/repeat-ranges.ts` owns this discovery and validation. `RepeatBehavior`\nsupplies its own binding boundaries, then clears top-level markers and hydrates,\ncreates, or removes views. The discovery helper does not alter marker data or\nbind views.\n\n```mermaid\nflowchart TD\n    A[\"RepeatBehavior.bind(controller)\"] --> B{\"isHydratable(template) && hydrating?\"}\n    B -->|Yes| C[\"hydrateViews(template)\"]\n    B -->|No| D[\"refreshAllViews() — normal client path\"]\n\n    C --> E[\"Allocate views array sized to items.length\"]\n    E --> F[\"Scan bindingViewBoundaries[targetNodeId].first through location\"]\n    F --> G{\"Repeat marker?\"}\n    G -->|Start| H[\"Push start marker\"]\n    G -->|End| I[\"Pop start; throw if absent\"]\n    I --> J{\"Stack empty?\"}\n    J -->|Yes| K[\"Append top-level range in item order\"]\n    J -->|No| F\n    H --> F\n    K --> F\n    G -->|Other node| F\n    F -->|Reached location| L[\"Throw if stack nonempty; otherwise clear top-level markers\"]\n    L --> M[\"Hydrate overlapping SSR/client ranges in order\"]\n    M --> N[\"Create missing client views and remove excess server ranges\"]\n\n    subgraph \"Result\"\n        S[\"Each array item mapped to a HydrationView\"]\n        T[\"Views reuse server-rendered DOM between markers\"]\n        U[\"Markers cleared to empty strings (invisible in DOM)\"]\n    end\n```\n\n### Hydration CPU regression coverage\n\n`src/hydration/hydration-performance.pw.spec.ts` instruments Range/TreeWalker\ncreation and native factory-index array allocation across 500 sibling-bounded\nviews. Those counters must all be zero on the ordinary native path. It also\nasserts exact linear repeat predicate visits (four starts and two ends per\nfour-comment nested item), scope isolation from earlier siblings, nested marker\npreservation, malformed-marker diagnostics, installed `markers_v2`, empty items,\nand missing/excess reconciliation. Existing target-builder tests compare live\nendpoint mutations with the legacy Range walker. The declarative repeat fixture\nchecks SSR node identity, three nested repeat levels, an empty inner list, and an\nadjacent repeat before exercising reactive updates. The co-located\n`src/hydration/repeat-ranges.pw.spec.ts` also verifies that successful discovery\nleaves native and legacy marker data unchanged and excludes adjacent ranges.\n\n`src/hydration/native-marker-cleanup.pw.spec.ts` exercises a 1,000-record,\nthree-repeat-level workload with 20 adjacent prefix items: 4,021 FAST elements,\n4,020 native attribute markers, and 8,041 hydrated views. Range/TreeWalker setup,\n`comparePoint`, and `intersectsNode` counts are all zero; all 7,020 SSR descendant\nelements retain their identity. Mutation fixtures require the fallback and\nverify immediate insertion/removal, endpoint moves, unstable observation\nmetadata, method accessors, customized built-ins, and legacy/custom strategies.\nRegistration-order cases cover disabled tracking, enabling after registration,\nrepeated enablement after observation changes, and platform registration deferred\nuntil after asynchronous template resolution.\nThe declarative repeat fixture includes bound FAST child elements, checks zero\nlive traversal setup, and exercises reactive updates after hydration.\n\nRun focused correctness coverage from the monorepo root:\n\n```sh\nnpm exec -w @microsoft/fast-element -- playwright test src/hydration/target-builder.pw.spec.ts src/hydration/hydration-performance.pw.spec.ts src/hydration/native-marker-cleanup.pw.spec.ts src/hydration/repeat-ranges.pw.spec.ts src/templating/repeat.pw.spec.ts --project=chromium\n```\n\nCPU timings live separately in `src/hydration/hydration-benchmark.pw.spec.ts`\nand are opt-in rather than flaky wall-clock CI gates:\n\n```sh\nFAST_HYDRATION_BENCHMARK=1 npm exec -w @microsoft/fast-element -- playwright test src/hydration/hydration-benchmark.pw.spec.ts --project=chromium --retries=0\n```\n\nThe workloads measure 4,000 marker-free sibling views, 4,000 native\nattribute/content marker groups, 4,000 nested repeat ranges with stubbed child\nhydration, 20 adjacent repeats with 200 flat item ranges each, and a combined\n1,000-record page with three repeat levels, 4,000 minimal native custom elements,\nand 8,001 hydrated views. Setup, custom-element registration, and template\nconstruction are outside the timed interval; repeat workloads include bind and unbind. Each\nworkload has one warm-up and ten recorded samples, each in a fresh document so\nlive Ranges from earlier samples cannot amplify later DOM mutation costs.\nCompare the same test on the base and changed revisions on the same browser and\nmachine. To attribute improvements, also compare traversal-only, native-only,\nand repeat-only source variants in an isolated worktree, reversing variant order\nfor a second pass. The combined workload includes conservative live-Range\nfallbacks for custom-element attribute cleanup, not just ordinary element views.\nThese microbenchmarks time template hydration, not the issue's application\nregistration or hydration-completion tracking, and should not be presented as\nthat application's hydration timings.\n\nThe separate native FAST workload times bind/unbind for the 4,021-element /\n8,041-view case above. Setup and registration are excluded, identity and marker\nremoval are verified after every sample, and the same fresh-document sampling\nrules apply. Use this workload to compare the known-unobserved cleanup path;\nthe original combined workload intentionally registers ordinary custom elements\noutside FAST and therefore retains its conservative fallback.\n\n### Hydration Stage Lifecycle\n\n```mermaid\nstateDiagram-v2\n    [*] --> unhydrated: HydrationView created\n\n    unhydrated --> hydrating: bind() called\n    note right of hydrating\n        buildViewBindingTargets() scans DOM\n        Markers parsed, targets resolved\n        Behaviors created and bound\n        Attribute bindings skip DOM update\n        (server already set correct values)\n    end note\n\n    hydrating --> hydrated: All behaviors bound\n    note right of hydrated\n        Subsequent bind() calls\n        behave like normal HTMLView rebind\n        (re-evaluate expressions, update DOM)\n    end note\n\n    hydrated --> hydrated: rebind with new source\n```\n\nDuring the `hydrating` stage, attribute and boolean-attribute bindings **skip their initial DOM update** (the server already rendered the correct value). This avoids unnecessary DOM writes during hydration:\n\n```typescript\n// In HTMLBindingDirective.bind(), during hydration:\nif (isHydrating && (this.aspectType === DOMAspect.attribute ||\n                    this.aspectType === DOMAspect.booleanAttribute)) {\n    observer.bind(controller);  // Set up observation only\n    break;                      // Skip updateTarget — server value is current\n}\n```\n\n### Error Handling\n\nWhen the server-rendered DOM doesn't match the client template, hydration throws descriptive errors:\n\n| Error | Cause | Contains |\n|---|---|---|\n| `HydrationTargetElementError` | `data-fe` specifies a binding count that cannot be satisfied, more content binding markers exist than factories, or an element boundary end marker is missing | Factories array, target node; with `hydrationDebugger()` installed: structured `expected` (string or `HydrationMismatchExpectation`) describing what the walk wanted next, and `received` (`HydrationMismatchActual`) containing an HTML snippet of the offending DOM |\n| `HydrationBindingError` | A factory's `targetNodeId` has no matching entry in targets after the SSR DOM walk completes | Factory, cloned fragment, template string; with `hydrationDebugger()` installed: structured `expected` (`HydrationMismatchExpectation` with `tagName` and human-readable `aspect`) and `received` (`HydrationMismatchActual` with an HTML snippet of the SSR view range) |\n| `HydrationRepeatError` | A repeat view slot is unexpectedly `null` / `undefined` during rebind or unbind (internal invariant violation). SSR/client item-count mismatches are no longer surfaced as errors — they are reconciled silently by `RepeatBehavior.hydrateViews()` (missing client views are created, extra SSR ranges are removed) | Hydration stage, items length, view states |\n| `FAST.error(1210)` | `data-fe` attribute contains a non-numeric or non-positive value | Attribute value |\n\nThese errors typically indicate a mismatch between the server-rendered HTML and the client-side template definition.\n\nBy default, both errors emit a minimal one-line message that points at the opt-in `hydrationDebugger()`. Install the debugger from `@microsoft/fast-element/hydration.js` and pass it to `enableHydration` to swap in the rich format:\n\n```ts\nimport { enableHydration, hydrationDebugger } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ debugger: hydrationDebugger() });\n```\n\nWith the debugger installed, both errors format their message as:\n\n```\nHydration mismatch in <host-element>.\n  Expected: <tag> with <aspect> binding   (or a structural description)\n  Received: <SSR HTML snippet>\n```\n\nand expose the same information programmatically through the `expected` and `received` fields so tooling can read the structured description without parsing the message string. Keeping the debugger out of the import graph saves ~0.5 KB on the production hydration bundle.\n","packages/fast-router/README.md":"# FAST Router\n\nThe `@microsoft/fast-router` package contains a history-based navigation and routing solution designed around Web Components. By using `fast-router`, you can create multi-page and full application experiences. The router works with any Web Components, but has special support for Web Components built on FAST.\n\n## Installation\n\n### From NPM\n\nTo install the `fast-router` library using `npm`:\n\n```shell\nnpm install --save @microsoft/fast-router\n```\n\nWithin your JavaScript or TypeScript code, you can then import library APIs like this:\n\n```ts\nimport { FASTRouter } from '@microsoft/fast-router';\n```\n\nLooking for a setup that integrates with a particular front-end framework or bundler? Check out [our integration docs](https://fast.design/docs/integrations/introduction).\n\n## Configuration at a Glance\n\nThe router is currently in `alpha` while we address a few bugs, finish up some final polish, and write the full documentation. Below is a quick sample of how to configure the router, to help get you going while we complete the full documentation.\n\n#### A Sample Route Configuration\n\n```ts\nimport { RouterConfiguration, Route } from '@microsoft/fast-router';\nimport { HomeScreen } from './home';\nimport { AccountLogin } from './account/login';\nimport { AccountSignup } from './account/signup';\nimport { ConfirmEmail } from './account/confirm-email';\nimport { Session } from './account/session';\nimport { AccountSettings } from './account/settings';\nimport { StoreArea } from './store/store-area';\nimport { NotFound } from './not-found';\nimport { pageLayout } from './layouts/page-layout';\nimport { anonymousLayout } from './layouts/anonymous-layout';\n\ntype RouteSettings = {\n  public?: boolean\n};\n\nexport class AppRouterConfiguration extends RouterConfiguration<RouteSettings> {\n  public configure() {\n    this.title = 'My App';\n    this.defaultLayout = pageLayout;\n    this.routes.map(\n      { path: '', redirect: 'home' },\n      { path: 'home', title: 'Home', element: HomeScreen },\n      { \n        path: 'account', \n        layout: anonymousLayout, \n        title: 'Account',\n        settings: { public: true }, \n        children: [\n          { path: \"login\", title: 'Login', element: AccountLogin, name: 'login' },\n          { path: 'signup' title: 'Signup', element: AccountSignup },\n          { path: 'confirm/{confirmation:Confirmation}', title: 'Confirm', element: ConfirmEmail },\n          { path: 'settings', title: 'Settings', element: AccountSettings, layout: pageLayout, settings: { public: false } },\n        ] \n      },\n      { path: 'store', title: 'Store', element: StoreArea, childRouters: true },\n      { path: 'not-found', title: 'Not Found', element: NotFound }\n    );\n\n    this.routes.fallback(\n      () => Session.isLoggedIn\n        ? { redirect: 'not-found' }\n        : { redirect: 'login' }\n    );\n\n    this.routes.converter(\"Confirmation\", async (confirmationId) => {\n      // ...fetch confirmation from web service...\n      return confirmation;\n    });\n\n    this.contributors.push({\n      navigate(phase) {\n        const settings = phase.route.settings;\n  \n        if (settings && settings.public) {\n          return;\n        }\n  \n        if (Session.loggedIn) {\n          return;\n        }\n  \n        phase.cancel(() => {\n          Session.returnUrl = Route.path.current;\n          Route.name.replace(phase.router, 'login');\n        });\n      }\n    });\n  }\n}\n```\n\n#### Using the Configuration with a Router\n\n```ts\nimport { FASTElement, customElement } from '@microsoft/fast-element/fast-element.js';\nimport { css } from '@microsoft/fast-element/css.js';\nimport { html } from '@microsoft/fast-element/html.js';\nimport { FASTRouter } from '@microsoft/fast-router';\nimport { AppRouterConfiguration } from './routes';\n\nFASTRouter;\n\nconst template = html<MainApplication>`\n    <fast-router :config=${x => x.routerConfiguration}></fast-router>\n`;\n\nconst styles = css`\n  :host {\n    contain: content;\n  }\n\n  :host, fast-router {  \n    display: block;\n    width: 100%;\n    height: 100%;\n  }\n`;\n\n@customElement({\n  name: 'main-application',\n  template,\n  styles\n})\nexport class MainApplication extends FASTElement {\n  routerConfiguration = new AppRouterConfiguration();\n}\n```\n","packages/fast-router/docs/api-report.api.md":"## API Report File for \"@microsoft/fast-router\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\nimport { AddViewBehaviorFactory } from '@microsoft/fast-element';\nimport { ComposableStyles } from '@microsoft/fast-element';\nimport { Constructable } from '@microsoft/fast-element';\nimport { ExecutionContext } from '@microsoft/fast-element';\nimport { FASTElement } from '@microsoft/fast-element';\nimport { ViewBehavior } from '@microsoft/fast-element';\nimport { ViewBehaviorFactory } from '@microsoft/fast-element';\nimport { ViewController } from '@microsoft/fast-element';\nimport { ViewTemplate } from '@microsoft/fast-element';\n\n// Warning: (ae-internal-missing-underscore) The name \"childRouteParameter\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport const childRouteParameter = \"fast-child-route\";\n\n// @beta (undocumented)\nexport type CommandFallbackRouteDefinition<TSettings = any> = HasCommand & SupportsSettings<TSettings> & HasTitle;\n\n// @beta (undocumented)\nexport type CommandRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings> & HasCommand & HasTitle;\n\n// @beta (undocumented)\nexport class ConfigurableRoute implements Route {\n    constructor(path: string, name: string, caseSensitive: boolean);\n    // (undocumented)\n    readonly caseSensitive: boolean;\n    // (undocumented)\n    readonly name: string;\n    // (undocumented)\n    readonly path: string;\n}\n\n// @beta (undocumented)\nexport type ContributorOptions = {\n    lifecycle?: boolean;\n    parameters?: boolean;\n};\n\n// @beta (undocumented)\nexport class DefaultLinkHandler implements LinkHandler {\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n}\n\n// @beta (undocumented)\nexport class DefaultNavigationProcess<TSettings> {\n    // Warning: (ae-forgotten-export) The symbol \"NavigationPhaseImpl\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    commit(phase: NavigationPhaseImpl): void;\n    // (undocumented)\n    run(router: Router, message: NavigationMessage): Promise<void>;\n}\n\n// @beta (undocumented)\nexport class DefaultNavigationQueue implements NavigationQueue, NavigationHandler {\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n    // (undocumented)\n    enqueue(msg: NavigationMessage): void;\n    // (undocumented)\n    handleEvent(event: PopStateEvent): void;\n    // (undocumented)\n    receive(): Promise<NavigationMessage>;\n}\n\n// @beta (undocumented)\nexport class DefaultRouter implements Router {\n    constructor(host: HTMLElement);\n    // (undocumented)\n    addContributor(contributor: NavigationContributor): void;\n    // (undocumented)\n    beginRender(route: RecognizedRoute, command: RenderCommand): Promise<{\n        commit: () => Promise<void>;\n        rollback: () => Promise<void>;\n    }>;\n    // (undocumented)\n    get config(): RouterConfiguration | null;\n    set config(value: RouterConfiguration | null);\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n    // (undocumented)\n    readonly host: HTMLElement;\n    // (undocumented)\n    get level(): number;\n    // (undocumented)\n    get parent(): Router<any> | null;\n    // (undocumented)\n    removeContributor(contributor: NavigationContributor): void;\n    // (undocumented)\n    route: RecognizedRoute | null;\n    // (undocumented)\n    shouldRender(route: RecognizedRoute): boolean;\n}\n\n// @beta (undocumented)\nexport class DefaultRouteRecognizer<TSettings> implements RouteRecognizer<TSettings> {\n    // (undocumented)\n    add(routeOrRoutes: Route | readonly Route[], settings?: TSettings): void;\n    generateFromName(name: string, params: object): string | null;\n    generateFromPath(path: string, params: object): string | null;\n    // (undocumented)\n    recognize(path: string, converters?: Readonly<Record<string, RouteParameterConverter>>): Promise<RecognizedRoute<TSettings> | null>;\n}\n\n// @beta (undocumented)\nexport type DefinitionCallback = () => Promise<FallbackRouteDefinition> | FallbackRouteDefinition;\n\n// @beta (undocumented)\nexport type ElementFallbackRouteDefinition<TSettings = any> = LayoutAndTransitionRouteDefinition & HasElement & SupportsSettings<TSettings> & HasTitle;\n\n// @beta (undocumented)\nexport type ElementRouteDefinition<TSettings = any> = NavigableRouteDefinition<TSettings> & HasElement;\n\n// @beta (undocumented)\nexport class Endpoint<TSettings = any> {\n    constructor(route: ConfigurableRoute, paramNames: readonly string[], paramTypes: readonly string[], settings: TSettings | null);\n    // (undocumented)\n    readonly paramNames: readonly string[];\n    // (undocumented)\n    readonly paramTypes: readonly string[];\n    // (undocumented)\n    get path(): string;\n    // (undocumented)\n    readonly route: ConfigurableRoute;\n    // (undocumented)\n    readonly settings: TSettings | null;\n}\n\n// @beta (undocumented)\nexport type FallbackRouteDefinition<TSettings = any> = ElementFallbackRouteDefinition<TSettings> | TemplateFallbackRouteDefinition<TSettings> | Pick<RedirectRouteDefinition<TSettings>, \"redirect\"> | CommandFallbackRouteDefinition<TSettings>;\n\n// @beta (undocumented)\nexport type FASTElementConstructor = new () => FASTElement;\n\n// @beta (undocumented)\nexport class FASTElementLayout implements Layout {\n    constructor(template?: ViewTemplate | null, styles?: ComposableStyles | ComposableStyles[] | undefined, runBeforeCommit?: boolean);\n    // (undocumented)\n    afterCommit(routerElement: HTMLElement): Promise<void>;\n    // (undocumented)\n    beforeCommit(routerElement: HTMLElement): Promise<void>;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"FASTRouter_base\" needs to be exported by the entry point index.d.ts\n//\n// @beta (undocumented)\nexport class FASTRouter extends FASTRouter_base {\n}\n\n// @beta (undocumented)\nexport type HasCommand = {\n    command: NavigationCommand;\n};\n\n// @beta (undocumented)\nexport type HasElement = {\n    element: string | FASTElementConstructor | HTMLElement | (() => Promise<string | FASTElementConstructor | HTMLElement>);\n};\n\n// @beta (undocumented)\nexport type HasTemplate = {\n    template: ViewTemplate | (() => Promise<ViewTemplate>);\n};\n\n// @beta (undocumented)\nexport type HasTitle = {\n    title?: string;\n};\n\n// @beta (undocumented)\nexport type IgnorableRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings>;\n\n// @beta (undocumented)\nexport class Ignore implements NavigationCommand {\n    // (undocumented)\n    createContributor(): Promise<{\n        navigate(phase: NavigationPhase): Promise<void>;\n    }>;\n}\n\n// @beta (undocumented)\nexport function isFASTElementHost(host: HTMLElement): host is HTMLElement & FASTElement;\n\n// @beta (undocumented)\nexport function isNavigationPhaseContributor<T extends NavigationPhaseName>(object: any, phase: T): object is Record<T, NavigationPhaseHook>;\n\n// @beta (undocumented)\nexport interface Layout {\n    // (undocumented)\n    afterCommit(routerElement: HTMLElement): Promise<void>;\n    // (undocumented)\n    beforeCommit(routerElement: HTMLElement): Promise<void>;\n}\n\n// @beta (undocumented)\nexport const Layout: Readonly<{\n    default: Readonly<Layout>;\n}>;\n\n// @beta (undocumented)\nexport type LayoutAndTransitionRouteDefinition = {\n    layout?: Layout | ViewTemplate;\n    transition?: Transition;\n};\n\n// @beta (undocumented)\nexport interface LinkHandler {\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n}\n\n// @beta (undocumented)\nexport type MappableRouteDefinition<TSettings = any> = RenderableRouteDefinition<TSettings> | RedirectRouteDefinition<TSettings> | CommandRouteDefinition<TSettings> | ParentRouteDefinition<TSettings>;\n\n// @beta (undocumented)\nexport type NavigableRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings> & LayoutAndTransitionRouteDefinition & HasTitle & {\n    childRouters?: boolean;\n};\n\n// @beta (undocumented)\nexport interface NavigationCommand {\n    // (undocumented)\n    createContributor(router: Router, route: RecognizedRoute): Promise<NavigationContributor>;\n}\n\n// @beta (undocumented)\nexport interface NavigationCommitPhase<TSettings = any> extends Omit<NavigationPhase<TSettings>, \"cancel\" | \"canceled\" | \"onCancel\"> {\n    // (undocumented)\n    setTitle(title: string): void;\n}\n\n// @beta (undocumented)\nexport type NavigationCommitPhaseHook<TSettings = any> = (phase: NavigationCommitPhase<TSettings>) => Promise<any> | any;\n\n// @beta (undocumented)\nexport type NavigationContributor<TSettings = any> = Partial<Record<Exclude<NavigationPhaseName, \"commit\">, NavigationPhaseHook<TSettings>>> & {\n    commit?: NavigationCommitPhaseHook<TSettings>;\n};\n\n// Warning: (ae-forgotten-export) The symbol \"NavigationContributorDirective\" needs to be exported by the entry point index.d.ts\n//\n// @beta (undocumented)\nexport function navigationContributor(options?: ContributorOptions): NavigationContributorDirective;\n\n// @beta (undocumented)\nexport interface NavigationHandler {\n    // (undocumented)\n    enqueue(msg: NavigationMessage): void;\n}\n\n// @beta (undocumented)\nexport const NavigationHandler: Readonly<{\n    register(handler: NavigationHandler): void;\n    unregister(handler: NavigationHandler): void;\n}>;\n\n// @beta (undocumented)\nexport class NavigationMessage {\n    constructor(path: string);\n    // (undocumented)\n    path: string;\n}\n\n// @beta (undocumented)\nexport interface NavigationPhase<TSettings = any> {\n    // (undocumented)\n    cancel(callback?: NavigationPhaseFollowupAction): void;\n    // (undocumented)\n    readonly canceled: boolean;\n    // (undocumented)\n    evaluateContributor(contributor: any, route?: RecognizedRoute<TSettings>, router?: Router<TSettings>): Promise<void>;\n    // (undocumented)\n    readonly name: NavigationPhaseName;\n    // (undocumented)\n    onCancel(callback: NavigationPhaseFollowupAction): void;\n    // (undocumented)\n    onCommit(callback: NavigationPhaseFollowupAction): void;\n    // (undocumented)\n    readonly route: RecognizedRoute<TSettings>;\n    // (undocumented)\n    readonly router: Router<TSettings>;\n}\n\n// @beta (undocumented)\nexport type NavigationPhaseFollowupAction = () => Promise<any> | any;\n\n// @beta (undocumented)\nexport type NavigationPhaseHook<TSettings = any> = (phase: NavigationPhase<TSettings>) => Promise<any> | any;\n\n// @beta (undocumented)\nexport type NavigationPhaseName = \"navigate\" | \"leave\" | \"construct\" | \"enter\" | \"commit\";\n\n// @beta (undocumented)\nexport interface NavigationProcess {\n    // (undocumented)\n    run(router: Router, message: NavigationMessage): Promise<void>;\n}\n\n// @beta (undocumented)\nexport interface NavigationQueue {\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n    // (undocumented)\n    receive(): Promise<NavigationMessage>;\n}\n\n// @beta (undocumented)\nexport type ParameterConverter = RouteParameterConverter | RouteParameterConverterObject | Constructable<RouteParameterConverterObject>;\n\n// @beta (undocumented)\nexport type ParentRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings> & LayoutAndTransitionRouteDefinition & {\n    children: MappableRouteDefinition<TSettings>[];\n};\n\n// @beta (undocumented)\nexport type PathedRouteDefinition<TSettings = any> = SupportsSettings<TSettings> & Route;\n\n// @beta (undocumented)\nexport const QueryString: Readonly<{\n    readonly current: string;\n    build(params: Record<string, string>, traditional?: boolean): string;\n    separate(path: string): Readonly<{\n        path: string;\n        queryString: string;\n    }>;\n    parse(queryString: string): Readonly<Record<string, string>>;\n}>;\n\n// @beta (undocumented)\nexport class RecognizedRoute<TSettings = any> {\n    constructor(endpoint: Endpoint<TSettings>, params: Readonly<Record<string, string | undefined>>, typedParams: Readonly<Record<string, any>>, queryParams: Readonly<Record<string, string>>);\n    // (undocumented)\n    readonly allParams: Readonly<Record<string, string | undefined>>;\n    // (undocumented)\n    readonly allTypedParams: Readonly<Record<string, any>>;\n    // (undocumented)\n    readonly endpoint: Endpoint<TSettings>;\n    // (undocumented)\n    readonly params: Readonly<Record<string, string | undefined>>;\n    // (undocumented)\n    readonly queryParams: Readonly<Record<string, string>>;\n    // (undocumented)\n    get settings(): TSettings | null;\n    // (undocumented)\n    readonly typedParams: Readonly<Record<string, any>>;\n}\n\n// @beta (undocumented)\nexport class Redirect implements NavigationCommand {\n    constructor(redirect: string);\n    // (undocumented)\n    createContributor(): Promise<{\n        navigate(phase: NavigationPhase): Promise<void>;\n    }>;\n}\n\n// @beta (undocumented)\nexport type RedirectRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings> & {\n    redirect: string;\n};\n\n// @beta (undocumented)\nexport class Render implements RenderCommand {\n    constructor(owner: RouterConfiguration, createView: () => Promise<RouteView>);\n    // Warning: (ae-forgotten-export) The symbol \"RenderContributor\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    createContributor(router: Router, route: RecognizedRoute): Promise<RenderContributor>;\n    // (undocumented)\n    createView: () => Promise<RouteView>;\n    // (undocumented)\n    static fromDefinition(owner: RouterConfiguration, definition: ElementRouteDefinition | TemplateRouteDefinition | ElementFallbackRouteDefinition | TemplateFallbackRouteDefinition): Render;\n    // (undocumented)\n    get layout(): Layout;\n    set layout(value: Layout);\n    // (undocumented)\n    title: string;\n    // (undocumented)\n    get transition(): Transition;\n    set transition(value: Transition);\n}\n\n// @beta (undocumented)\nexport type RenderableRouteDefinition<TSettings = any> = ElementRouteDefinition<TSettings> | TemplateRouteDefinition<TSettings>;\n\n// @beta (undocumented)\nexport interface RenderCommand extends NavigationCommand {\n    // (undocumented)\n    createView(): Promise<RouteView>;\n    // (undocumented)\n    layout: Layout;\n    // (undocumented)\n    transition: Transition;\n}\n\n// @beta (undocumented)\nexport interface RenderOperation {\n    // (undocumented)\n    commit(): Promise<void>;\n    // (undocumented)\n    rollback(): Promise<void>;\n}\n\n// @beta (undocumented)\nexport interface Route {\n    // (undocumented)\n    readonly caseSensitive?: boolean;\n    // (undocumented)\n    readonly name?: string;\n    // (undocumented)\n    readonly path: string;\n}\n\n// @beta (undocumented)\nexport const Route: Readonly<{\n    path: Readonly<{\n        readonly current: string;\n        generateRoute(relativeTo: HTMLElement | Router, path: string, params?: Object): Promise<string | null>;\n        push(path: string, trigger?: boolean): void;\n        replace(path: string, trigger?: boolean): void;\n        trigger(path: string): void;\n    }>;\n    name: Readonly<{\n        generateRoute(relativeTo: HTMLElement | Router, name: string, params?: Object): Promise<string | null>;\n        push(relativeTo: HTMLElement | Router, name: string, params?: Object, trigger?: boolean): Promise<void>;\n        replace(relativeTo: HTMLElement | Router, name: string, params?: Object, trigger?: boolean): Promise<void>;\n        trigger(relativeTo: HTMLElement | Router, name: string, params?: Object): Promise<void>;\n    }>;\n}>;\n\n// @beta (undocumented)\nexport class RouteCollection<TSettings = any> {\n    constructor(owner: RouterConfiguration);\n    // (undocumented)\n    converter(name: string, converter: ParameterConverter): void;\n    // (undocumented)\n    fallback(definitionOrCallback: FallbackRouteDefinition<TSettings> | DefinitionCallback): void;\n    generateFromName(name: string, params: object): string | null;\n    generateFromPath(path: string, params: object): string | null;\n    // (undocumented)\n    ignore(definitionOrString: IgnorableRouteDefinition<TSettings> | string): void;\n    // (undocumented)\n    map(...routes: MappableRouteDefinition<TSettings>[]): void;\n    // (undocumented)\n    recognize(path: string): Promise<RouteMatch<TSettings> | null>;\n}\n\n// @beta (undocumented)\nexport type RouteMatch<TSettings = any> = {\n    route: RecognizedRoute<TSettings>;\n    command: NavigationCommand;\n};\n\n// @beta (undocumented)\nexport type RouteParameterConverter = (name: string, value: string | undefined, context: RouteParameterConverterContext) => any | Promise<any>;\n\n// @beta (undocumented)\nexport interface RouteParameterConverterContext<TSettings = any> {\n    // (undocumented)\n    readonly endpoint: Endpoint<TSettings>;\n    // (undocumented)\n    readonly params: Readonly<Record<string, string | undefined>>;\n    // (undocumented)\n    readonly queryParams: Record<string, string>;\n    // (undocumented)\n    readonly typedParams: Record<string, any>;\n}\n\n// @beta (undocumented)\nexport type RouteParameterConverterObject = {\n    convert: RouteParameterConverter;\n};\n\n// @beta (undocumented)\nexport interface Router<TSettings = any> {\n    // (undocumented)\n    addContributor(contributor: NavigationContributor): void;\n    // (undocumented)\n    beginRender(route: RecognizedRoute<TSettings>, command: RenderCommand): Promise<RenderOperation>;\n    // (undocumented)\n    config: RouterConfiguration | null;\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n    // (undocumented)\n    readonly level: number;\n    // (undocumented)\n    readonly parent: Router | null;\n    // (undocumented)\n    removeContributor(contributor: NavigationContributor): void;\n    // (undocumented)\n    readonly route: RecognizedRoute | null;\n    // (undocumented)\n    shouldRender(route: RecognizedRoute<TSettings>): boolean;\n}\n\n// @beta (undocumented)\nexport const Router: Readonly<{\n    getOrCreateFor(element: HTMLElement): Router<any>;\n    find(element: HTMLElement): Router | null;\n    from<TBase extends typeof HTMLElement>(BaseType: TBase): {\n        new (): InstanceType<TBase> & RouterElement;\n    };\n}>;\n\n// @beta (undocumented)\nexport abstract class RouterConfiguration<TSettings = any> {\n    // (undocumented)\n    protected cached(ElementType: new () => HTMLElement): () => Promise<HTMLElement>;\n    // (undocumented)\n    protected abstract configure(): Promise<void> | void;\n    // (undocumented)\n    construct<T>(Type: Constructable<T>): T;\n    // (undocumented)\n    readonly contributors: NavigationContributor<TSettings>[];\n    // Warning: (ae-forgotten-export) The symbol \"RoutingEventSink\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    createEventSink(): RoutingEventSink;\n    // (undocumented)\n    createLinkHandler(): LinkHandler;\n    // (undocumented)\n    createNavigationProcess(): NavigationProcess;\n    // (undocumented)\n    createNavigationQueue(): NavigationQueue;\n    // (undocumented)\n    createRouteRecognizer(): RouteRecognizer<TSettings>;\n    // Warning: (ae-forgotten-export) The symbol \"TitleBuilder\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    createTitleBuilder(): TitleBuilder;\n    // (undocumented)\n    defaultLayout: Layout;\n    // (undocumented)\n    defaultTransition: Readonly<Transition>;\n    // (undocumented)\n    findContributors<T extends NavigationPhaseName>(phase: T): Record<T, NavigationPhaseHook<TSettings>>[];\n    generateRouteFromName(name: string, params: object): Promise<string | null>;\n    generateRouteFromPath(path: string, params: object): Promise<string | null>;\n    // (undocumented)\n    parent: RouterConfiguration<TSettings> | null;\n    // (undocumented)\n    recognizeRoute(path: string): Promise<RouteMatch<TSettings> | null>;\n    // (undocumented)\n    readonly routes: RouteCollection<TSettings>;\n    // (undocumented)\n    title: string;\n}\n\n// @beta (undocumented)\nexport interface RouteRecognizer<TSettings> {\n    // (undocumented)\n    add(routeOrRoutes: Route | readonly Route[], settings?: TSettings): void;\n    // (undocumented)\n    generateFromName(name: string, params: object): string | null;\n    // (undocumented)\n    generateFromPath(path: string, params: object): string | null;\n    // (undocumented)\n    recognize(path: string, converters?: Readonly<Record<string, RouteParameterConverter>>): Promise<RecognizedRoute<TSettings> | null>;\n}\n\n// @beta (undocumented)\nexport interface RouterElement extends HTMLElement {\n    // Warning: (ae-forgotten-export) The symbol \"routerProperty\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    readonly [routerProperty]: Router;\n    // (undocumented)\n    config: RouterConfiguration | null;\n    // (undocumented)\n    connectedCallback(): void;\n    // (undocumented)\n    disconnectedCallback(): void;\n}\n\n// @beta (undocumented)\nexport type RouterExecutionContext = ExecutionContext & {\n    router?: Router;\n};\n\n// @beta (undocumented)\nexport interface RouteView {\n    // (undocumented)\n    appendTo(host: HTMLElement): void;\n    // (undocumented)\n    bind(allTypedParams: Readonly<Record<string, any>>): void;\n    // (undocumented)\n    context: RouterExecutionContext;\n    // (undocumented)\n    dispose(): void;\n}\n\n// @beta (undocumented)\nexport type SupportsSettings<TSettings = any> = {\n    settings?: TSettings;\n};\n\n// @beta (undocumented)\nexport type TemplateFallbackRouteDefinition<TSettings = any> = LayoutAndTransitionRouteDefinition & HasTemplate & SupportsSettings<TSettings> & HasTitle;\n\n// @beta (undocumented)\nexport type TemplateRouteDefinition<TSettings = any> = NavigableRouteDefinition<TSettings> & HasTemplate;\n\n// @beta (undocumented)\nexport interface Transition {\n    // (undocumented)\n    begin(host: HTMLElement, prev: RouteView | null, next: RouteView): Promise<void>;\n    // (undocumented)\n    commit(host: HTMLElement, prev: RouteView | null, next: RouteView): Promise<void>;\n    // (undocumented)\n    rollback(host: HTMLElement, prev: RouteView | null, next: RouteView): Promise<void>;\n}\n\n// @beta (undocumented)\nexport const Transition: Readonly<{\n    default: Readonly<Transition>;\n}>;\n\n// (No @packageDocumentation comment for this package)\n\n```\n","packages/fast-test-harness/README.md":"# FAST Test Harness\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nThe `fast-test-harness` package is a Playwright testing harness for FAST Element web components with CSR and SSR support.\n\n## Requirements\n\n- Node.js 22.18 or later\n- Playwright 1.56 or later\n\n## Installation\n\nTo install `fast-test-harness` using `npm`:\n\n```shell\nnpm install --save-dev @microsoft/fast-test-harness\n```\n\n## Test directory setup\n\nThe harness serves a Vite dev server from a `test/` directory in your project. CSR and SSR modes use different entry points from the same directory.\n\n```\ntest/\n├── index.html              # CSR: loads main.ts\n├── ssr.html                # SSR: template with comment placeholders\n├── vite.config.ts          # Vite config (shared by both modes)\n└── src/\n    ├── main.ts             # CSR: registers components, applies theme\n    ├── entry-client.ts     # SSR: registers components for hydration\n    └── entry-server.ts     # SSR: exports render() for fixture generation\n```\n\n## Writing tests\n\nImport `test` and `expect` from the harness. Configure the component tag name with `test.use()`, then call `fastPage.setTemplate()` in each test to render it.\n\n```ts\nimport { expect, test } from \"@microsoft/fast-test-harness\";\n\ntest.describe(\"Button\", () => {\n    test.use({ tagName: \"my-button\", innerHTML: \"Click me\" });\n\n    test(\"should render\", async ({ fastPage }) => {\n        await fastPage.setTemplate();\n        await expect(fastPage.element).toBeVisible();\n    });\n\n    test(\"should accept attributes\", async ({ fastPage }) => {\n        await fastPage.setTemplate({\n            attributes: { appearance: \"primary\", disabled: true },\n        });\n        await expect(fastPage.element).toHaveAttribute(\"appearance\", \"primary\");\n    });\n\n    test(\"should work inside a form\", async ({ fastPage }) => {\n        await fastPage.setTemplate(`\n            <form>\n                <my-button type=\"submit\">Submit</my-button>\n            </form>\n        `);\n        await expect(fastPage.element).toBeVisible();\n    });\n});\n```\n\nUse `updateTemplate()` to modify attributes or innerHTML after the initial render without navigating away from the page:\n\n```ts\nawait fastPage.setTemplate();\nawait fastPage.updateTemplate(fastPage.element, { attributes: { disabled: true } });\n```\n\nThe `toHaveCustomState` assertion checks `ElementInternals` custom states:\n\n```ts\nawait expect(element).toHaveCustomState(\"checked\");\n```\n\n## Fixture options\n\n| Option | Type | Default | Description |\n| -------- | ------ | --------- | ------------- |\n| `base` | `string` | `\"/\"` | Base path for the test page and SSR endpoint |\n| `tagName` | `string` | `\"\"` | Custom element tag name |\n| `innerHTML` | `string` | `\"\"` | Default inner HTML |\n| `waitFor` | `string[]` | `[]` | Additional elements to wait for before testing |\n| `ssr` | `boolean` | `false` | Use SSR mode (or set `PLAYWRIGHT_TEST_SSR=true`) |\n\n### CSR files\n\n**`index.html`** loads a script that registers your components:\n\n```html\n<!doctype html>\n<html lang=\"en\">\n    <head><meta charset=\"UTF-8\" /></head>\n    <body>\n        <script type=\"module\" src=\"/src/main.ts\"></script>\n    </body>\n</html>\n```\n\n**`main.ts`** registers components and applies global config. The body starts empty; `setTemplate()` injects HTML per test.\n\n```ts\nimport \"./define-all.js\";\nimport { setTheme } from \"./theme.js\";\nsetTheme(lightTheme);\n```\n\n### SSR files\n\n**`ssr.html`** contains comment placeholders the server fills in per request:\n\n```html\n<!doctype html>\n<html lang=\"en\">\n    <head>\n        <title><!--fixturetitle--></title>\n        <!--stylespreload-->\n    </head>\n    <body>\n        <!--fixture-->\n        <!--templates-->\n        <script type=\"module\" src=\"/src/entry-client.ts\"></script>\n    </body>\n</html>\n```\n\n**`entry-client.ts`** imports the harness SSR entry (which enables hydration) and registers components. Component definition modules should use `template: declarativeTemplate()`; this automatically defines FAST's internal `<f-template>` publisher.\n\n```ts\nimport \"@microsoft/fast-test-harness/ssr/entry-client.js\";\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n\nimport { MyButton, definition } from \"../../src/button/index.js\";\n\nMyButton.define({\n    name: definition.name,\n    template: declarativeTemplate(),\n});\n```\n\n**`entry-server.ts`** exports a `render()` function that the server calls for each `setTemplate()` request. It returns three strings that get injected into `ssr.html`:\n\n```ts\nexport function render(queryObj: Record<string, string>): {\n    template: string;    // <f-template> HTML → <!--templates-->\n    fixture: string;     // rendered element HTML → <!--fixture-->\n    preloadLinks: string; // <link> tags → <!--stylespreload-->\n};\n```\n\nUse `createSSRRenderer` from the harness to build the `render()` function. It scans for component build artifacts (f-templates, stylesheets) and uses the `@microsoft/fast-build` WASM renderer to produce declarative shadow DOM on each request.\n\n**Multi-component package** (all components in one package):\n\n```ts\nimport { createSSRRenderer } from \"@microsoft/fast-test-harness/ssr/render.js\";\n\nconst { render } = createSSRRenderer({\n    packageName: \"@my-scope/web-components\",\n    tagPrefix: \"my\",\n});\n\nexport { render };\n```\n\n**Per-component packages** (each component is a separate npm package):\n\n```ts\nimport { createSSRRenderer } from \"@microsoft/fast-test-harness/ssr/render.js\";\n\nconst { render } = createSSRRenderer({\n    tagPrefix: \"my\",\n    components: [\n        { name: \"button\", packageName: \"@my-scope/button\" },\n        { name: \"checkbox\", packageName: \"@my-scope/checkbox\" },\n    ],\n});\n\nexport { render };\n```\n\n## Server\n\nThe package includes a Node.js HTTP server with Vite middleware that handles both CSR page serving and SSR fixture generation. Run it directly or let Playwright manage it via `webServer`:\n\n```ts\n// playwright.config.ts\nexport default defineConfig({\n    webServer: {\n        command: \"fast-test-harness\",\n        port: 3278,\n        reuseExistingServer: true,\n    },\n});\n```\n\nFor custom setup, import `startServer`:\n\n```ts\nimport { startServer } from \"@microsoft/fast-test-harness/server.mjs\";\nawait startServer(process.cwd(), \"./test\", \"./test/vite.config.ts\", {\n    port: 4000,\n    debug: true,\n});\n```\n\nOne server can host several test directories at separate paths. Set the matching\n`base` fixture option for each test group.\n\n```ts\nawait startServer(process.cwd(), process.cwd(), \"./vite.config.ts\", {\n    routes: [\n        { base: \"/button/\", root: \"./packages/button/test\" },\n        { base: \"/dialog/\", root: \"./packages/dialog/test\" },\n    ],\n});\n\ntest.use({ base: \"/button/\", tagName: \"my-button\" });\n```\n\n| Parameter | Default | Description |\n| --------- | ------- | ----------- |\n| `cwd` | `process.cwd()` | Static file serving root |\n| `root` | `<cwd>/test` | Vite root (contains `index.html`, `ssr.html`) |\n| `configFile` | Vite auto-discovery | Vite config path |\n| `options.port` | `3278` | Server port |\n| `options.base` | `/` | Base URL path |\n| `options.debug` | `false` | Write SSR fixtures to `temp/` for inspection |\n| `options.routes` | Single route from `root` and `base` | Test roots keyed by URL base path |\n\n### CLI flags\n\n```\nfast-test-harness [command] [options]\n\nCommands:\n  serve                    Start the test harness dev server (default)\n  generate-templates       Generate <f-template> HTML files from compiled templates\n  generate-stylesheets     Generate CSS files from compiled ElementStyles\n  generate-webui-templates Generate WebUI-compatible DSD templates\n\nServe options:\n  -p, --port <number>    Server port (default: 3278)\n  -b, --base <path>      Base URL path (default: /)\n  -r, --root <path>      Vite root directory (default: <cwd>/test)\n  -c, --config <path>    Vite config file path (default: Vite auto-discovery)\n  -d, --debug            Write SSR fixtures to temp/ for inspection\n  -v, --version          Show version number\n  -h, --help             Show help message\n```\n\nCLI flags take precedence over environment variables.\n\n`generate-templates` preserves browser-valid `<template>` wrappers and strips\nstatic wrappers even when the opening or closing tag includes ASCII whitespace\nbefore `>`.\n\n| Environment variable | Default | Description |\n| -------------------- | ------- | ----------- |\n| `PORT` | `3278` | Server port (overridden by `--port`) |\n| `BASE` | `/` | Base URL path (overridden by `--base`) |\n| `FAST_DEBUG` | — | Set `\"true\"` to enable debug mode (overridden by `--debug`) |\n| `PLAYWRIGHT_TEST_SSR` | — | Set `\"true\"` for SSR mode |\n\n## SSR renderer\n\n**`createSSRRenderer(options)`** scans for component build artifacts and returns a `{ render }` object compatible with the server's `entry-server.ts` contract. It uses the `@microsoft/fast-build` WASM module to parse f-templates and render them into declarative shadow DOM, including wrapper tags whose opening or closing `>` is preceded by ASCII whitespace.\n\n| Option | Type | Description |\n| -------- | ------ | ------------- |\n| `tagPrefix` | `string` | Tag name prefix for custom elements (e.g., `\"fluent\"`, `\"contoso\"`) |\n| `packageName` | `string?` | Monolithic package name — scans subdirectories for component artifacts. Mutually exclusive with `components`. |\n| `components` | `ComponentRegistration[]?` | Explicit list of per-component packages. Mutually exclusive with `packageName`. |\n| `distDir` | `string?` | Artifact directory relative to the package root (default: `\"dist/esm\"`). Only used with `packageName`. |\n| `themeStylesheet` | `string?` | URL or package specifier for a global theme stylesheet. |\n\n## Exports\n\n| Specifier | Contents |\n| ----------- | ---------- |\n| `@microsoft/fast-test-harness` | `test`, `expect`, `CSRFixture`, `SSRFixture`, `toHaveCustomState`, `installDomShim`, `createSSRRenderer` |\n| `@microsoft/fast-test-harness/build/*.js` | `installDomShim`, `generateStylesheets`, `generateFTemplates`, `generateWebuiTemplates`, `definitionAsyncResolver`, `shadowOptionsToAttributes`, `ShadowOptionsResolver` |\n| `@microsoft/fast-test-harness/fixtures/*.js` | `CSRFixture`, `SSRFixture`, `toHaveCustomState`, extended `test` and `expect` |\n| `@microsoft/fast-test-harness/ssr/render.js` | `createSSRRenderer`, `renderTemplate`, `buildEntryHtml`, `buildState` |\n| `@microsoft/fast-test-harness/ssr/entry-client.js` | Enables FAST Element hydration for SSR pages |\n| `@microsoft/fast-test-harness/server.mjs` | `startServer` |\n| `@microsoft/fast-test-harness/playwright.config.mjs` | Shared Playwright configuration |\n| `@microsoft/fast-test-harness/vite.config.mjs` | Shared Vite configuration |\n| `@microsoft/fast-test-harness/public/*` | Static assets (base CSS) |\n","sites/website/src/docs/1.x/tools/component-explorer.md":"---\nid: component-explorer\ntitle: Component Explorer\neleventyNavigation:\n  key: component-explorer1x\n  parent: tools1x\n  title: Component Explorer\nnavigationOptions:\n  activeKey: component-explorer1x\ndescription: Launch our Component Explorer to experience our FAST Components and development tools.\nkeywords:\n  - component explorer\nlayout: 1x\n---\n\nLaunch our [Component Explorer](https://explore.fast.design) to experience our [FAST Components](https://www.npmjs.com/package/@microsoft/fast-components) and development tools.","sites/website/src/docs/1.x/tools/hot-module-reload.md":"---\nid: hot-module-reload\ntitle: Hot Module Reload\neleventyNavigation:\n  key: hot-module-reload1x\n  parent: tools1x\n  title: Hot Module Reload\nnavigationOptions:\n  activeKey: hot-module-reload1x\ndescription: Hot Module Replacement (HMR) allows your web components to be updated as you develop, without needing a full refresh of the browser.\nkeywords:\n  - hot module reload\nlayout: 1x\n---\n\nHot Module Replacement (HMR) allows your web components to be updated as you develop, without needing a full refresh of the browser. The [Open Web Components](https://open-wc.org/) project maintains a number of tools and libraries for working with Web Components, including a plugin for enabling HMR with FAST Web Components.\n\nTo learn more about HMR for Web Components and to see how to setup HMR in your own FAST projects, [please see the Open Web Components HMR documentation](https://open-wc.org/docs/development/hot-module-replacement/).\n\n:::note\nHMR is limited in what it can update for a given component. So, full-page refreshes are still needed in certain cases. Changes to constructor logic or adding new `@attr` properties are notable examples of HMR's update limitations. However, template and style changes should be handled automatically without needing a full refresh.\n:::","sites/website/src/docs/1.x/tools/vscode.md":"---\nid: vscode\ntitle: Visual Studio Code\neleventyNavigation:\n  key: vscode1x\n  parent: tools1x\n  title: Visual Studio Code\nnavigationOptions:\n  activeKey: vscode1x\ndescription: You can use any code editor you like when working with FAST. One of our favorites is Visual Studio Code.\nkeywords:\n  - visual studio code\nlayout: 1x\n---\n\nYou can use any code editor you like when working with FAST. One of our favorites is [Visual Studio Code](https://code.visualstudio.com/). VS Code has great support for API autocomplete for TypeScript and JavaScript APIs, as well as a rich ecosystem of plugins.\n\nWhen working with VS Code, we recommend using these plugins:\n\n* [FAST Snippets](https://marketplace.visualstudio.com/items?itemName=kingoftac.fast-snippets) to get commonly used conventions when creating `FAST Components`.\n* [literally-html](https://marketplace.visualstudio.com/items?itemName=webreflection.literally-html) to get syntax highlighting and documentation in your `html` blocks.\n* [es6-string-css](https://marketplace.visualstudio.com/items?itemName=bashmish.es6-string-css) to get syntax highlighting in your `css` blocks.",".cursorrules (fastapi-production-architecture-cursorrules-prompt-file.mdc)":"---\ndescription: \"Cursor rules for FastAPI services with router/service/repository boundaries, typed provider adapters, bulkhead isolation, idempotency, and domain exceptions.\"\nglobs: **/*\nalwaysApply: false\n---\n# FastAPI Production Architecture Rules\n# Principles for production-ready FastAPI services.\n\n## LAYER ARCHITECTURE (Principles A1-A8)\n\nThis codebase follows strict 4-layer architecture: Router → Service → Repository → ORM/HTTP/Storage.\nImports flow downward only. Each layer has hard boundaries you must NOT cross.\n\n### Router rules (app/routers/**)\n- Handlers are THIN: ≤10 lines of executable code per handler\n- Allowed imports: fastapi, app.schemas.*, app.core.deps, app.services.*\n- FORBIDDEN imports: sqlalchemy, httpx, boto3, app.models.*, app.repositories.*\n- Every endpoint declares response_model= for OpenAPI fidelity\n- Every protected/business endpoint requires user_id: str = Depends(get_current_user_id)\n- Public endpoints (health checks, webhooks, callbacks) are exempt from auth\n- Business logic lives in services. Routers parse input, call one service method, return response.\n\nGOOD:\n@router.post(\"/wallet/charge\", response_model=WalletResponse, status_code=201)\nasync def charge(\n    req: ChargeRequest,\n    user_id: str = Depends(get_current_user_id),\n    svc: WalletUserService = Depends(get_wallet_service),\n) -> WalletResponse:\n    wallet = await svc.charge(\n        user_id=user_id,\n        amount=req.amount,\n        idempotency_key=req.idempotency_key,\n    )\n    return WalletResponse.from_domain(wallet)\n\nBAD (business logic + SQL in router):\n@router.post(\"/wallet/charge\")\nasync def charge(req: ChargeRequest, db: Session = Depends(get_db)):\n    wallet = db.query(Wallet).filter(Wallet.user_id == user_id).with_for_update().one()\n    ...\n\n### Service rules (app/services/**)\n- FORBIDDEN imports: sqlalchemy, httpx, boto3, redis, FastAPI Request/Response/HTTPException\n- Constructor injects Protocol-typed dependencies, not concrete classes\n- Raise domain exceptions (InsufficientFundsError), not HTTPException\n\nGOOD:\nfrom app.repositories.protocols import WalletRepoProtocol\nclass WalletUserService:\n    def __init__(self, repo: WalletRepoProtocol):  # Protocol, not SQLAlchemy Session\n        self._repo = repo\n\nBAD:\nfrom sqlalchemy.orm import Session\nclass WalletUserService:\n    def __init__(self, db: Session): ...  # Wrong — service depends on infrastructure\n\n### Repository rules (app/repositories/**)\n- ONLY layer allowed to import sqlalchemy\n- Implements Protocol from app/repositories/protocols.py\n- Returns domain objects, not ORM models\n- Every query scoped by user_id (multi-tenancy)\n\n### Provider rules (app/providers/**)\n- ONLY layer allowed to import httpx directly\n- Returns GenerateResult | ProviderError — NEVER raw dict\n- Uses per-provider httpx.AsyncClient (bulkhead pattern)\n\n## FILE SIZE RULES (Principle A1)\n\n| LOC      | State  | Action                                      |\n|----------|--------|---------------------------------------------|\n| 0–399    | Green  | None.                                       |\n| 400–599  | Yellow | Plan split. Add TODO(decompose) header.     |\n| 600+     | Red    | BLOCK merge. Decompose first.               |\n\nConvert file to package when ANY is true:\n- Crosses 400 LOC and next change pushes past 500\n- Contains 2+ disjoint sub-domains (image vs video, user vs admin)\n- Mixes HTTP handlers with worker handlers\n- Has 2+ callers each importing only one symbol\n\nSafe split pattern (atomic PR):\n1. Create <file>/__init__.py (empty for now)\n2. Move pieces to sub-files (a.py, b.py, c.py)\n3. Re-export old public names from __init__.py\n4. Run tests — must pass without changes\n5. Follow-up PR to migrate callers off legacy alias\n\n__init__.py pattern:\nfrom .user import WalletUserService\nfrom .admin import WalletAdminService\nWalletService = WalletUserService  # backwards-compat alias\n__all__ = [\"WalletUserService\", \"WalletAdminService\", \"WalletService\"]\n\n## EXTERNAL INTEGRATION RULES (Principles B1-B10)\n\n### Rule 1: Anti-Corruption Layer (ACL)\nProviders return GenerateResult | ProviderError, never dict.\n\nfrom dataclasses import dataclass\nfrom decimal import Decimal\n\n@dataclass(frozen=True)\nclass GenerateResult:\n    url: str\n    cost_usd: Decimal\n    latency_ms: int\n    provider_request_id: str\n\nclass ProviderError(Exception):\n    def __init__(self, message: str, *, retryable: bool, code: str | None = None):\n        super().__init__(message); self.retryable = retryable; self.code = code\n\nclass ProviderTimeout(ProviderError):\n    def __init__(self, message: str): super().__init__(message, retryable=True, code=\"timeout\")\n\n### Rule 2: Per-Provider Bulkhead\nEach external provider has its OWN httpx.AsyncClient with its OWN Limits. NEVER share.\n\nGOOD:\nFAL_HTTP = httpx.AsyncClient(\n    base_url=settings.FAL_BASE_URL,\n    timeout=httpx.Timeout(connect=5.0, read=60.0, write=10.0, pool=5.0),\n    limits=httpx.Limits(max_connections=20, max_keepalive_connections=10),\n)\nOPENAI_HTTP = httpx.AsyncClient(\n    base_url=\"https://api.openai.com/v1\",\n    limits=httpx.Limits(max_connections=50, max_keepalive_connections=20),\n)\n\nBAD:\nHTTP = httpx.AsyncClient()  # shared across all providers — no bulkhead isolation\n\n# Shutdown cleanup — close all provider clients in FastAPI lifespan\nfrom contextlib import asynccontextmanager\n\n@asynccontextmanager\nasync def lifespan(app):\n    yield  # app startup\n    await FAL_HTTP.aclose()\n    await OPENAI_HTTP.aclose()\n\napp = FastAPI(lifespan=lifespan)\n# Or on_event(\"shutdown\"):\n# @app.on_event(\"shutdown\")\n# async def close_http_clients() -> None:\n#     await FAL_HTTP.aclose()\n#     await OPENAI_HTTP.aclose()\n\n### Rule 3: Idempotency Keys\nEvery side-effect operation accepts an idempotency_key: UUID. Look up before retrying.\n\n### Rule 4: Structured Logging with contextvars\nUse ContextVar to thread provider, user_id, request_id through async call stacks.\n\nimport contextvars\n\nprovider_var   = contextvars.ContextVar[str | None](\"provider\", default=None)\nuser_id_var    = contextvars.ContextVar[str | None](\"user_id\", default=None)\nrequest_id_var = contextvars.ContextVar[str | None](\"request_id\", default=None)\n\n# Read in logs: provider_var.get(), user_id_var.get(), request_id_var.get()\n# JSON formatter picks these up automatically via extra={} or ContextVar.get()\n\n### Rule 5: Single-Writer Principle (Principle B10)\nFor safety-critical state: exactly ONE service-layer module does the writing.\nOnly the designated writer service for a domain may call repo.hold().\nRouters and providers must NOT call repo.hold() directly.\nAdmin services implemented in the service layer may call repo.hold() only\nif they are the designated writer for that domain.\nEnforce via: code-review grep check (`grep -r \"repo\\.hold(\" --include=\"*.py\"`)\nand unit tests that assert call-origin of repo.hold().\n\n## ANTI-PATTERNS — REJECT ON SIGHT\n\n1. def some_method(self, db: Session, ...) → use Protocol-typed repo\n2. from app.models.user import User inside a service → return domain types from repo\n3. httpx.AsyncClient() instantiated inside a function → use shared per-provider client\n4. raise HTTPException(...) inside a service → raise domain exception\n5. db.query(...) inside a router → move to service then repo\n6. async def call(self, req) -> dict: return resp.json() → ACL violation\n7. HTTP = httpx.AsyncClient() shared → bulkhead violation\n8. result[\"vendor_field\"][\"nested\"] in service code → ACL violation\n9. logger.info(f\"{user_id} did X\") → use structured logging with extra={}\n10. Side-effect operation without idempotency_key → double-charge risk\n\n## DEPENDENCY INJECTION\n\nUse FastAPI Depends() + factory functions in app/core/deps.py.\nDo NOT install dependency-injector, punq, or any DI container.\n\ndef get_wallet_service(db: Session = Depends(get_db)) -> WalletUserService:\n    return WalletUserService(repo=SQLAlchemyWalletRepo(db))\n\n## DOMAIN EXCEPTIONS PATTERN\n\nServices raise domain errors. Routers map to HTTP.\n\n# services/wallet/exceptions.py\nclass InsufficientFundsError(Exception): ...\nclass WalletNotFoundError(Exception): ...\n\n# routers/wallet.py\ntry:\n    wallet = await svc.charge(...)\nexcept InsufficientFundsError:\n    raise HTTPException(402, detail=\"insufficient funds\")\n"},"files":{".github/copilot-instructions.md":"---\nname: FAST Instructions\ndescription: This file describes the general instructions for working with the FAST monorepo, including repository structure, code style, tooling, and contribution guidelines.\napplyTo: '**/*'\n---\n\n# Instructions for FAST\n\n## General\n\n- **Explicit instruction only**: Do not take any action unless explicitly instructed. Wait for clear direction before making changes, running commands, or modifying files.\n\n## Repository Overview\n\nFAST (`@microsoft/fast`) is a Microsoft open-source monorepo for building W3C-standards-compliant Web Components. The core package is `@microsoft/fast-element` — a lightweight, performant Web Component authoring library with a declarative HTML entrypoint. Additional packages provide routing plus declarative build and test tooling.\n\n## Packages\n\nEach package includes a DESIGN.md file, read that to gain a general understanding of the code for that package.\n\n| Package | Status | Purpose |\n|---|---|---|\n| `@microsoft/fast-element` | Stable (v2) | Core Web Component library, including declarative HTML via `@microsoft/fast-element/declarative.js` |\n| `@microsoft/fast-router` | Alpha | Web Component router |\n| `@microsoft/fast-build` | Prerelease | Declarative HTML server side renderer |\n| `@microsoft/fast-test-harness` | Prerelease | Testing utilities for FASTElement components |\n\n### Sites\n\n| Package | Status | Purpose |\n|---|---|---|\n| `sites/website` | Private (not published as a package) | Documentation website source |\n| `sites/benchmarks` | Private (not published as a package) | Benchmarking site |\n\n### Example projects\n\n- `examples/design-system/` — Shared semantic design tokens (`@microsoft/fast-examples-design-system`) consumed by all example apps.\n- `examples/csr/todo-app/` — A simple To-Do app demonstrating FAST usage patterns and using the shared `@microsoft/fast-examples-design-system` tokens.\n- `examples/csr/todo-mobx-app/` — A To-Do app demonstrating how to integrate MobX state with `@microsoft/fast-element` using a single `autorun` per component (no custom bridge code).\n- `examples/ssr/chat-app/` — A declarative FAST chat demo that pre-renders with `@microsoft/fast-build` and streams canned assistant replies into the transcript. Dark theme.\n- `examples/ssr/webui-todo-app/` — A To-Do app demonstrating FAST declarative HTML with `@microsoft/webui` prerendering and `@microsoft/fast-element/declarative.js` hydration. Light theme.\n\n## Skills\n\nThese contain domain-specific guidance. Read when performing related tasks:\n\n- [TypeScript](./skills/typescript/SKILL.md) — compiler constraints, import/export conventions, decorator usage, testing patterns.\n- [Rust](./skills/rust/SKILL.md) — general guidance on performing updates between the crate and package.\n- [Shipping](./skills/shipping/SKILL.md) — pull request format, change file generation, documentation updates.\n- [Pull Request](./skills/fast-pull-request/SKILL.md) — generate a pull request description from the branch diff.\n- [Bug Report](./skills/fast-bug-report/SKILL.md) — generate a bug report issue from conversation context.\n- [Feature Request](./skills/fast-feature-request/SKILL.md) — generate a feature request issue from conversation context.\n- [Testing](./skills/testing/SKILL.md) — running tests locally and in CI, writing Playwright fixture tests.\n- [Documentation](./skills/documentation/SKILL.md) — adding documentation in code, markdown files in each package/crate, and the website.\n\n## Commands\n\nRun all commands from the monorepo root. Use workspace flags to target a single package.\n\n| Task | Command |\n|---|---|\n| Install | `npm ci` |\n| Build all | `npm run build` |\n| Build one package | `npm run build -w @microsoft/fast-element` |\n| Test all | `npm run test` |\n| Test one package | `npm run test -w @microsoft/fast-element` |\n| Test Chromium only | `npm run test:chromium` |\n| Build/test changed only | `lage build --since origin/main` |\n| Test changed only | `lage test:node test:chromium --since origin/main` |\n| Lint | `npm run lint` |\n| Lint fix | `npm run lint:fix` |\n| Format check | `npm run format:check` |\n| Format fix | `npm run format` |\n| Check (lint + format + imports) | `npm run biome:check` |\n| Check fix | `npm run biome:fix` |\n| CI check (read-only) | `npm run biome:ci` |\n| Generate change file | `npm run change` |\n| Check change files | `npm run checkchange` |\n| API docs | `npm run doc -w @microsoft/fast-element` |\n\nBuild and test commands use [Lage](https://microsoft.github.io/lage/) for dependency-aware task execution. Lage respects the package dependency graph and can run incrementally with `--since <ref>` to only build/test changed packages and their dependents. The CI pipelines use `--since` for pull requests to skip unchanged packages.\n\nAll `lint`, `biome:check`, `biome:fix`, and `biome:ci` commands use `biome-changed`, which runs biome only on files with uncommitted git changes. The `format:check` and `format` commands use biome's own `--changed` flag to compare against the default branch.\n\n## Project Structure\n\n```\npackages/<package>/\n  src/                    # Source code\n    index.ts              # Main barrel (re-exports)\n    <feature>/            # Feature directories\n      <feature>.ts        # Implementation\n      <feature>.pw.spec.ts # Co-located Playwright test\n  test/                   # Test harness (Vite dev server, fixtures)\n  dist/                   # Build output (ESM + declarations)\n  docs/                   # API reports (api-extractor)\n  DESIGN.md               # Code documentation for the package or crate\n  README.md               # README for published package use\n```\n\n- Source files use **kebab-case**: `element-controller.ts`, `update-queue.ts`.\n- Playwright test files use `*.pw.spec.ts` suffix, co-located next to the source they test.\n- Node test files use `*.spec.ts` suffix.\n\n## Code Style\n\n### Formatting & Linting (Biome)\n\n- 90-character print width, 4-space indent, double quotes, trailing commas.\n- Single-arg arrow functions omit parens: `x => x + 1`.\n- Import ordering enforced via `organizeImports`.\n- No `I` prefix on interfaces.\n- `any` is permitted (`noExplicitAny: off`).\n- Config: [`biome.jsonc`](../biome.jsonc).\n\n### Naming Conventions\n\n| Element | Convention | Examples |\n|---|---|---|\n| Classes | PascalCase | `ElementController`, `FASTElementDefinition` |\n| Interfaces/Types | PascalCase, no `I` prefix | `Accessor`, `Disposable`, `Expression` |\n| Methods/functions | camelCase | `getValue()`, `handleChange()` |\n| Constants | PascalCase frozen objects or camelCase | `SourceLifetime`, `emptyArray` |\n| Private fields | `_` prefix | `_template`, `_shadowRootOptions` |\n| Files | kebab-case | `element-controller.ts`, `observer-map.ts` |\n| Change callbacks | `${prop}Changed` | `childChanged()`, `templateChanged()` |\n\n### TypeScript\n\nKey constraints (details in [TypeScript skill](./skills/typescript/SKILL.md)):\n\n- ESM only (`\"type\": \"module\"`) — imports use `.js` extensions.\n- `import type { ... }` required for type-only imports (`verbatimModuleSyntax`).\n- Named exports only — no default exports.\n- Legacy decorators enabled (`experimentalDecorators: true`).\n- `strictNullChecks` and `noImplicitAny` enabled.\n\n## Tooling\n\n| Tool | Purpose |\n|---|---|\n| npm workspaces | Package management |\n| Lage | Task runner — dependency-aware builds and incremental testing |\n| TypeScript | Compilation |\n| Rollup | Bundling (`fast-element` only) |\n| Playwright | Testing |\n| Vite | Test dev server |\n| api-extractor | API documentation + `.d.ts` rollup |\n| beachball | Change files, versioning, publishing |\n| Biome | Formatting + Linting |\n| lefthook | Pre-commit hooks (runs `biome:check` and `checkchange` on staged files) |\n| Rust | Rendering Declarative templates (`fast-build` package and `microsoft-fast-build` crate only) |\n\n## Acceptance Checklist\n\nBefore finishing any change, run these commands from the monorepo root and confirm they pass:\n\n- [ ] `npm run build` — all packages build successfully\n- [ ] `npm run test` — all tests pass\n- [ ] `npm run biome:check` — Biome linting and formatting pass\n- [ ] `npm run checkchange` — beachball change files exist for any `packages/*` changes\n\nRead the [shipping skill](./skills/shipping/SKILL.md) and ensure you have updated everything outlined in that file.\n",".github/skills/documentation/SKILL.md":"---\nname: documentation\ndescription: Add documentation for contributors and developers.\n---\n\nDocumentation exists in 3 forms, code comments, design/architectural documentation that is made up of markdown files describing code flow and core concepts (such as DESIGN.md), and the documentation website.\n\nDesign/architectural documentation such as DESIGN.md should always be kept up-to-date.\n\nThe website captures the documentation primarily for the `@microsoft/fast-element` package. Other packages are treated as tangential, so testing packages or other utilities should have their own sections.\n\nThe website has been written in 11ty and primarily consists of markdown files. When making changes, ensure that the website has been scanned on whichever latest major version is available. These are organized by folder, so if 1.x/2.x/3.x folders are available, you will update the documentation in the 3.x folder.\n\nIf you are making a breaking change, ensure the migration document has been updated.\n\nAll markdown documentation aside from the package/crate level DESIGN.md files are in that package/crates docs folder.\n\nAny documentation created for the website should be written with the developer implementing the package in mind, it is not intended for other audiences.\n",".github/skills/fast-bug-report/SKILL.md":"---\nname: fast-bug-report\ndescription: Generate a bug report issue for the FAST repository using the provided template.\n---\nThis prompt only applies to generating Bug Report issues for the FAST repository.\n\nDo not create or modify any existing Github issues. This skill is only for\ngenerating the markdown content for a new issue based on the provided template.\n\nBased on the conversation context, generate a bug report as a markdown code\nblock using the template located at\n[../../ISSUE_TEMPLATE/bug-report.md](../../ISSUE_TEMPLATE/bug-report.md).\n\nThe summary should clearly state what the bug is and which part of the system\nis affected.\n\nRepro or Code Sample should provide clear, minimal steps to reproduce the issue.\nInclude a code snippet, repository link, or gist if possible.\n\nExpected Behavior should describe what the correct behavior should be.\n\nCurrent Behavior should explain what actually happens instead. Include the full\nerror message and stack trace if applicable. Mention screenshots if they would\nhelp illustrate the problem.\n\nPossible Solution is optional. Include it only if there is a concrete idea about\nthe cause or fix. Mention if the reporter is willing to contribute a fix.\n\nContext should explain how the bug affects the user and what they are trying to\naccomplish. This helps prioritize and design the right solution.\n\nYour Environment should capture relevant details: OS, device, browser, and\npackage version.\n\nSearch for existing open or closed issues that overlap with this bug report.\nIf duplicates or related issues exist, mention them in the Context section.\n\nSuggest a concise issue title in the format `fix: [what is the issue?] in [where is the issue?]`.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nAny comments in the template can be removed since they're only meant to provide\nguidance on how to fill out the template, and are not intended to be part of the\nfinal issue body.\n",".github/skills/fast-feature-request/SKILL.md":"---\nname: fast-feature-request\ndescription: Generate a feature request issue for the FAST repository using the provided template.\n---\nThis prompt only applies to generating Feature Request issues for the FAST repository.\n\nDo not create or modify any existing Github issues. This skill is only for\ngenerating the markdown content for a new issue based on the provided template.\n\nBased on the conversation context, generate a feature request as a markdown code\nblock using the template located at\n[../../ISSUE_TEMPLATE/feature-request.md](../../ISSUE_TEMPLATE/feature-request.md).\n\nThe summary should clearly state what the feature is and why it matters, focusing\non user value rather than implementation details.\n\nExpected Behavior should describe how the feature would work from an end-user or\ndeveloper perspective. Be specific about the desired outcome.\n\nCurrent Behavior should explain the gap — what exists today and how the absence of\nthis feature affects users. If there is a workaround, mention it briefly.\n\nPossible Solution is optional. Include it only if there is a concrete implementation\nidea worth capturing. Prefer high-level direction over prescriptive code.\n\nContext should explain the motivation — what the user is trying to accomplish\nand why this feature would help. Mention alternatives that were considered, if any.\n\nExamples is optional. Include it when code snippets, screenshots, or usage\nscenarios would clarify the request.\n\nSearch for existing open or closed issues that overlap with this feature request.\nIf duplicates or related issues exist, mention them in the Context section.\n\nSuggest a concise issue title in the format `feat: add [what] to/in [where]`.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nAny comments in the template can be removed since they're only meant to provide\nguidance on how to fill out the template, and are not intended to be part of the\nfinal issue body.\n",".github/skills/fast-pull-request/SKILL.md":"---\nname: fast-pull-request\ndescription: Generate a pull request description for the FAST repository using the provided template.\n---\nThis skill only applies to generating Pull Request descriptions for the FAST repository.\n\nDo not create or modify any existing Github pull requests. This skill is only for\ngenerating the markdown content for a pull request description based on the provided template.\n\nBased on the conversation context, generate a pull request description as a markdown code\nblock using the template located at\n[../../pull_request_template.md](../../pull_request_template.md).\n\nUse the Pull Request Template to generate a markdown code block for the most\nrelevant work on this git branch, compared to `main`.\n\nThe Description should be either a summary description of the content of the branch,\nor a list of the most relevant changes made in the branch. The goal is to address\nthe purpose of the pull request in a concise manner, rather than detailing every change. \"Why\"\nand \"what\" over \"how\".\n\nDetermine if any current github issues are being addressed by this work, and\nlist them in the Issues section with links. If none are found, remove the Issues section.\n\nThe reviewer notes section is optional. Include it only if there are specific\nareas where you would like feedback or attention from the reviewer.\n\nThe Test Plan section should outline any issues that need to be verified before merging,\nor steps to reproduce the behavior locally. Even a brief note is helpful, such as \"All existing tests pass\".\n\nThe checklist section should be completed to indicate the status of various\naspects of the pull request.\n\nIf there are change files that have been added to the PR, check the box labeled \"I have included a change request file using `$ npm run change`\".\n\nIf any new tests have been added, check the box labeled \"I have added tests for my changes.\"\n\nCheck the terminal output for evidence of passing tests, and check the box labeled \"I have tested my changes.\" if tests have been run and are passing. If not, leave the box unchecked.\n\nIf any doc blocks have been added or modified, or if any documentation files have been added or modified, check the box labeled \"I have updated the project documentation to reflect my changes.\" This also applies to any changes made to api-report files.\n\nThe final checkbox must be checked by the pull request author. It should never be checked when generating this PR description.\n\nThe Next Steps section is optional. Include it only if there are specific follow-up tasks\nor work items that should be addressed after merging this PR, such as updating documentation, adding new tests, or performing code cleanup. If any existing issues are being addressed by the next steps, reference them here.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nAny comments in the template can be removed since they're only meant to provide\nguidance on how to fill out the template, and are not intended to be part of the\nfinal PR description.\n",".github/skills/rust/SKILL.md":"---\ndescription: Use this guide when working on Rust changes in the FAST monorepo.\nname: rust\n---\n\n# Working with the Rust crate and the Rust NodeJS CLI\n\nThe primary location for the Rust logic should exist within a crate. If the logic is made accessible in the NodeJS environment via wrapping the crate and using a wasm bindgen, as much as possible any logic that exists in Rust should not be duplicated in JavaScript/TypeScript.\n\n## Breaking changes\n\nUnderstand [semver](https://semver.org/) and check the crate and package version. If the version is currently in a prerelease state, update the APIs with breaking changes as necessary and ensure that any generated pull request descriptions capture this.\n",".github/skills/shipping/SKILL.md":"---\ndescription: Use this skill when contributing changes to the FAST monorepo — creating pull requests, generating change files, writing PR descriptions, and keeping documentation up to date.\nname: shipping\n---\n\n# Shipping Patterns for FAST\n\nUse this guide when shipping changes in the FAST monorepo — writing PR descriptions, generating change files, and keeping documentation up to date.\n\n# Guardrails\n\nDo NOT perform any of the following actions autonomously. These require explicit human action:\n\n- **Do not merge or close pull requests** — no `gh pr merge`, `gh pr close`, or equivalent.\n- **Do not publish packages** — no `npm publish`, `beachball publish`, or release operations.\n- **Do not modify branch protection or repository settings**.\n\n## Key references\n\nRead these documents for additional context when needed:\n\n- [`.github/pull_request_template.md`](../../pull_request_template.md) — PR description template (source of truth for PR structure).\n- [`CONTRIBUTING.md`](../../../CONTRIBUTING.md) — Full contributor guide (machine setup, branching, governance).\n- [`BRANCH_GUIDE.md`](../../../BRANCH_GUIDE.md) — Branch management conventions.\n- [`beachball.config.js`](../../../beachball.config.js) — Beachball configuration (ignored patterns, publish settings).\n- [`CODE_OF_CONDUCT.md`](../../../CODE_OF_CONDUCT.md) — Community standards.\n\n### Package/Crate references\n\nRead these documents, they are located at the root of the specific package or crate, e.g. `packages/<package>/<file>.md` and relate to the package/crates they are located in. When making changes in the package/crate afterwards update these files if necessary.\n\n- `DESIGN.md` - Explains the code patterns.\n- `README.md` - Explains how a developer/agent would use this package/crate.\n\n# Commit and PR title conventions\n\nUse [conventional commit](https://www.conventionalcommits.org/) format for PR titles and merge commit messages:\n\n```\n<type>: <short summary>\n```\n\nCommon types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`.\n\nExamples:\n- `feat: add shadow DOM support to declarative templates`\n- `fix: resolve memory leak in template binding`\n- `chore: update dev dependencies`\n\n# Pull requests\n\nUse the repository's PR template at [`.github/pull_request_template.md`](../../pull_request_template.md) as the basis for all pull request descriptions.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nThe comments in the template can be removed since they're only meant to provide guidance on how to fill out the template, and are not intended to be part of the final PR description.\n\nFill out each section as detailed below.\n\n## Description\n\nThe Description should be either a summary description of the content of the branch,\nor a list of the most relevant changes made in the branch. The goal is to address\nthe purpose of the pull request in a concise manner, rather than detailing every change. \"Why\"\nand \"what\" over \"how\".\n\n## Issues\n\nDetermine if any current github issues are being addressed by this work, and\nlist them in the Issues section with links. If none are found, remove the Issues section.\n\n## Reviewer Notes\n\nThe reviewer notes section is optional. Include it only if there are specific\nareas where you would like feedback or attention from the reviewer.\n\n## Test Plan\n\nThe Test Plan section should outline any issues that need to be verified before merging,\nor steps to reproduce the behavior locally. Even a brief note is helpful, such as \"All existing tests pass\".\n\n## Checklist\n\nThe checklist section should be completed to indicate the status of various\naspects of the pull request.\n\nIf there are change files that have been added to the PR, check the box labeled \"I have included a change request file using `$ npm run change`\".\n\nIf any new tests have been added, check the box labeled \"I have added tests for my changes.\"\n\nCheck the terminal output for evidence of passing tests, and check the box labeled \"I have tested my changes.\" if tests have been run and are passing. If not, leave the box unchecked.\n\nIf any doc blocks have been added or modified, or if any documentation files have been added or modified, check the box labeled \"I have updated the project documentation to reflect my changes.\" This also applies to any changes made to api-report files.\n\nThe final checkbox must be checked by the pull request author. It should never be checked when generating this PR description.\n\n## Next Steps\n\nThe Next Steps section is optional. Include it only if there are specific follow-up tasks\nor work items that should be addressed after merging this PR, such as updating documentation, adding new tests, or performing code cleanup. If any existing issues are being addressed by the next steps, reference them here.\n\n# Acceptance checklist\n\nBefore making a change, if the change is addressing a bug make sure you write a test first and ensure that it is failing:\n\n```bash\nnpm run build            # all packages build successfully\nnpm run test             # test fails\n```\n\nBefore finishing any change, run these commands from the monorepo root and confirm they pass:\n\n```bash\nnpm run build            # all packages build successfully\nnpm run test             # all tests pass\nnpm run format:check     # Prettier formatting is correct\nnpm run checkchange      # Beachball change files exist for packages/* changes\n```\n\n# Change files\n\nAfter completing a change to any package under `packages/`, generate a Beachball change file:\n\n```bash\n# This should be run from the monorepo root\nnpm run change\n```\n\nThis walks through the steps to create a change description file that is required for versioning and publishing. The CI gate `npm run checkchange` will fail if a change file is missing for a modified package.\n\n## Change comments\n\nWrite the `comment` field as release-note text, not as a commit message. Use a\nconcise sentence that starts with a capital letter and ends with a period. Do not\nprefix comments with conventional commit types such as `fix:`, `feat:`, or\n`chore:`.\n\nBeachball uses change-file comments to generate package changelogs and release\nnotes. Sentence-style comments read cleanly in those user-facing outputs, while\ncommit-style prefixes duplicate the separate change type metadata and add noise.\n\n## Change types\n\nWhen prompted, select the appropriate change type:\n\n| Type | When to use |\n|---|---|\n| `major` | Breaking changes to public API |\n| `minor` | New features, non-breaking additions |\n| `patch` | Bug fixes, minor corrections |\n| `none` | Changes that don't affect the published package (tests, docs, tooling) |\n\n## When change files are NOT required\n\nThe Beachball config ([`beachball.config.js`](../../../beachball.config.js)) ignores these paths — changes limited to them do not need change files:\n\n- `.github/` — CI configs, templates, skills\n- Test files (`src/e2e/`, `src/tests/`, `src/fixtures/`)\n- `package-lock.json`\n- `.vscode/`, `.prettierrc`\n\nAdditionally, [`build/scripts/checkchange.mjs`](../../../build/scripts/checkchange.mjs) (which wraps `beachball check` for the `checkchange` npm script) skips the check entirely on **manual version bump** branches authored by a repo admin. Specifically, both of the following must be true for the current run:\n\n1. Branch name matches `^publish_\\d+$` (beachball's documented publish-branch convention).\n2. The actor (`$GITHUB_ACTOR` in CI; locally, the user from `gh api user`) has the `admin` role on `microsoft/fast`, verified via the GitHub REST API.\n\nIf either condition fails, the change-file requirement applies as before. See [`CONTRIBUTING.md` > Manual version bumps](../../../CONTRIBUTING.md#manual-version-bumps) for the full rationale and reviewer expectations.\n\n## Cross-branch targeting\n\nWhen working across feature branches, target the branch explicitly:\n\n```bash\nnpm run change -- --branch origin/{branch-name}\n```\n\n## Multiple unrelated changes\n\nIf addressing multiple unrelated issues, prefer separate pull requests.\n\n# Breaking changes\n\nWhen introducing breaking changes:\n\n1. Select `major` as the change type when running `npm run change`.\n2. Document the migration strategy in `packages/<package>/docs/migration/<migration-name>.md`.\n\nFormat for a migration document:\n\n```md\n# Migrating from previous versions\n\n## v1 to v2\n\n- Export `Foo` has been renamed to `Bar`.\n- `Bat` has been updated to use the new API [`BatConfig`](link/to/api).\n```\n\nIf the breaking change is significant or requires multiple PRs, open a [discussion](https://github.com/microsoft/fast/discussions) first.\n\n# Documentation\n\nAfter any changes ensure that the documentation is up to date, this includes the files DESIGN.md and README.md files for any packages/crates that have been modified. If your changes update or add to the public API, update the sites/website/src/docs/ files. Only update the latest version, these are denoted by major versions in their folder names inside the docs folder, 1.x, 2.x, etc., find the latest version of the docs and modify them if necessary.\n\nWhen adding or modifying exported APIs, run the website prebuild script to regenerate API documentation from the api-extractor output:\n\n```bash\nnpm run prebuild -w sites/website\n```\n\nThis runs [`sites/website/scripts/generate-docs.cjs`](../../../sites/website/scripts/generate-docs.cjs), which copies API documentation from each package's extracted API reports into the website source. Run this after building packages to ensure generated documentation stays in sync with the codebase.\n",".github/skills/testing/SKILL.md":"---\nname: testing\ndescription: Use this skill when running or writing tests in the FAST monorepo — local test execution, CI workflows, Playwright fixtures, and WebUI integration testing.\n---\n\n# Testing Patterns for FAST\n\nUse this guide when running or writing tests in the FAST monorepo. FAST uses [Playwright](https://playwright.dev/) for integration testing with a [Vite](https://vitejs.dev/) dev server.\n\n## Running tests\n\n### Locally\n\n#### First-time setup\n\nAfter cloning and installing dependencies (`npm ci`), install Playwright browsers:\n\n```bash\nnpx playwright install --with-deps\n```\n\n#### Commands\n\nAll commands are run from the **monorepo root**. Use `-w` to target a specific package.\n\n| Task | Command |\n|---|---|\n| Run all tests (all browsers) | `npm run test` |\n| Run all tests (Chromium only) | `npm run test:chromium` |\n| Test a single package (all browsers) | `npm run test -w @microsoft/fast-element` |\n| Test a single package (Chromium only) | `npm run test:chromium -w @microsoft/fast-element` |\n| Test changed packages only | `npx lage test:node test:chromium --since origin/main` |\n\n#### Interactive / debug workflows\n\nFor FAST declarative tests in `@microsoft/fast-element`, these additional scripts are available:\n\n| Task | Command |\n|---|---|\n| Playwright UI mode | `npm run test:ui:declarative -w @microsoft/fast-element` |\n| Start declarative source server | `npm run test-server:declarative -w @microsoft/fast-element` |\n| Rebuild fixtures | `npm run build:fixtures -w @microsoft/fast-element` |\n| Build fixtures with webui | `npm run build:fixtures:webui -w @microsoft/fast-element` |\n| Run webui integration tests | `npm run test:webui-integration -w @microsoft/fast-element` |\n\n**Playwright UI mode** (`test:ui`) starts a visual test runner where you can select and debug individual tests, view traces, and inspect DOM snapshots.\n\n**Declarative browser workflows** resolve `@microsoft/fast-element` package imports directly to `src` and let Vite transpile TypeScript on demand. Vite does not type-check these modules; the package build remains responsible for type checking, while `test:exports` imports every emitted package export.\n\n### Through GitHub Actions\n\nThe repository uses several CI workflows to validate changes.\n\n#### PR validation (ci-validate-pr.yml)\n\nRuns on every pull request targeting `main`, `releases/*`, or `features/*` branches. Tests run on **Ubuntu with Chromium only** for fast feedback.\n\nKey steps:\n- Checks for change files (`npm run checkchange`)\n- Biome lint/format check\n- Builds affected packages (incremental with `--since`)\n- Runs `test:node` and `test:chromium` for affected packages\n\n#### Cross-platform validation (ci-validate-platforms.yml)\n\nRuns on pushes to `main`, PRs targeting `main`, and on a weekly schedule. Tests run on **Ubuntu, Windows, and macOS** with **Chromium, Firefox, and Safari**.\n\nThis ensures cross-platform and cross-browser compatibility.\n\n#### WebUI integration testing (ci-webui-integration.yml)\n\nA dedicated workflow for validating FAST's integration with `@microsoft/webui`. This workflow runs on:\n\n- **Manual dispatch** (`workflow_dispatch`)\n- **Pushes to `webui/*` branches**\n\n> **Note:** This workflow does _not_ run on regular pull requests. It is scoped to `webui/*` branches to test integration changes in isolation before they land on `main`.\n\nThe workflow builds all packages, installs Playwright Chromium, and runs:\n\n```bash\nnpm run test:webui-integration -w @microsoft/fast-element\n```\n\nThis builds each fixture with `webui build --plugin=fast`, renders the protocol with the fixture's `state.json`, and runs the same Playwright specs against the webui-rendered output.\n\nTo trigger WebUI integration tests for your changes:\n\n1. Create a branch with the `webui/` prefix (e.g., `webui/my-integration-change`).\n2. Push the branch — the workflow runs automatically.\n3. Alternatively, trigger the workflow manually from the Actions tab using `workflow_dispatch`.\n\n#### Azure Pipelines (azure-pipelines-ci.yml)\n\nThe repository also has an Azure DevOps pipeline that runs on PRs to `main`. This pipeline runs in a 1ES-managed environment and includes SDL compliance checks in addition to building and testing.\n\n## Writing tests\n\nFAST tests are [Playwright](https://playwright.dev/) integration tests that run against fixture pages served by Vite.\n\n### Test file conventions\n\n- Test files use the `*.spec.ts` suffix (specifically `*.pw.spec.ts` for package `src/` tests).\n- Tests for developer-authored declarative markup and directives live in the matching\n  `test/declarative/fixtures/<category>/<feature>/<feature>.spec.ts` fixture.\n- Tests for implementation APIs and lifecycle behavior are co-located with their source as\n  `src/<feature>/<feature>.pw.spec.ts`.\n\n### Writing declarative fixture tests\n\nFixture tests in `@microsoft/fast-element/test/declarative/fixtures` are the primary way to verify declarative template features. Each fixture is a self-contained test case with its own HTML, state, templates, and component definitions.\n\nWhen changing declarative syntax, directive parsing, template generation, hydration behavior, or other user-authored template behavior, add or update a declarative fixture and exercise it in browser. Source-level parser tests may supplement narrow parsing edge cases, but they should not be the only coverage for syntax that users write in `entry.html` or `templates.html`. Use the local README files under `packages/fast-element/test/declarative/fixtures/` and each fixture category to choose the right fixture type and follow category-specific examples.\n\nFor a complete guide on creating fixtures — including how to write `entry.html`, `state.json`, `templates.html`, `main.ts`, and spec files — see:\n\n📄 **[Writing Fixtures](../../../packages/fast-element/test/declarative/fixtures/WRITING_FIXTURES.md)**\n\n### Quick example\n\n```typescript\nimport { expect, test } from \"@playwright/test\";\n\ntest.describe(\"my-feature\", async () => {\n    test(\"renders correctly\", async ({ page }) => {\n        await page.goto(\"/fixtures/bindings/my-feature/\");\n\n        const element = page.locator(\"my-element\");\n        await expect(element).toHaveText(\"Hello\");\n    });\n});\n```\n",".github/skills/typescript/SKILL.md":"---\ndescription: Use this guide when working on TypeScript changes in the FAST monorepo — authoring Web Components, writing templates and styles, working with the observable/reactive system, and testing.\nname: typescript\n---\n\n# TypeScript Patterns for FAST\n\n## Modules\n\n`fast-element` enables `verbatimModuleSyntax`, so type-only imports must use `import type`\nor the inline `type` qualifier:\n\n```ts\nimport type { Notifier, Subscriber } from \"./notifier.js\";\nimport { type Constructable, isFunction } from \"../interfaces.js\";\n```\n\nSub-entry-points expose focused APIs through the `exports` map:\n\n```ts\nimport { twoWay } from \"@microsoft/fast-element/two-way.js\";\nimport { reactive } from \"@microsoft/fast-element/state.js\";\n```\n\nThe barrel `index.ts` explicitly lists every re-export grouped by subsystem — no\n`export *` statements.\n\nAside from the `index.ts` or `index.*.ts` files there should be no barrel exports.\n\n## Side Effects\n\nDo not add side effectful code and do not add `sideEffects` to `package.json` files.\nAPIs added should import named exports.\n\n## Browser APIs\n\n### Do not use\n\nOur stance as a framework library is that certain browser APIs are best avoided by\nthe framework. We may facilitate the use of them through our provided APIs.\n\nList of APIs to avoid implementing in FAST packages:\n- `requestIdleCallback`\n- `setTimeout`\n- `setInterval`\n\n### Avoid\n\nSome browser APIs can be used but should be avoided as a developer may encounter\nedge cases with task queuing or other logic their app is executing.\n\nList of APIs to avoid in FAST packages:\n- `requestAnimationFrame`\n- `queueMicrotask`\n\n## Custom elements\n\nElements extend `FASTElement`. Do **not** use the `@customElement` decorator.\n\nUse `define()` for registration. `define()` returns a `Promise` that resolves\nimmediately when a template is provided:\n\nExample define.ts (side-effect import):\n```ts\nexport class MyElement extends FASTElement {\n    @observable items: string[] = [];\n}\n\nawait MyElement.define({\n    name: \"my-element\",\n    template,\n    styles,\n});\n```\n\n## Templates\n\nTemplates use the `html` tagged template literal typed to the element class:\n\n```ts\nimport { html } from \"@microsoft/fast-element/html.js\";\nimport { repeat } from \"@microsoft/fast-element/repeat.js\";\nimport { when } from \"@microsoft/fast-element/when.js\";\nimport type { MyElement } from \"./my-element.js\";\n\nexport const template = html<MyElement>`\n    <h1>${x => x.title}</h1>\n    ${when(x => x.showList, html<MyElement>`\n        <ul>\n            ${repeat(\n                x => x.items,\n                html<string>`<li>${x => x}</li>`\n            )}\n        </ul>\n    `)}\n`;\n```\n\n### Binding syntax\n\n| Prefix | Purpose | Example |\n|---|---|---|\n| `${x => ...}` | Content or attribute | `${x => x.name}` |\n| `@event` | Event listener | `@click=${x => x.handleClick()}` |\n| `@event` | Event with context | `@click=${(x, c) => c.parent.remove(x)}` |\n| `:prop` | DOM property | `:value=${twoWay(x => x.description)}` |\n| `?attr` | Boolean attribute | `?disabled=${x => !x.isValid}` |\n\nTwo-way bindings require a sub-entry-point import:\n\n```ts\nimport { twoWay } from \"@microsoft/fast-element/two-way.js\";\n```\n\n### Partial HTML\n\nUse `html.partial()` to inject pre-built HTML strings into a template without creating\na full `ViewTemplate`:\n\n```ts\nhtml<MyElement>`\n    <div>${html.partial(\"<span>static markup</span>\")}</div>\n`;\n```\n\n## Styles\n\nStyles use the `css` tagged template literal. They attach through the element definition's\n`styles` property:\n\n```ts\nimport { css } from \"@microsoft/fast-element/css.js\";\n\nexport const styles = css`\n    :host {\n        display: block;\n        padding: 16px;\n    }\n`;\n```\n\nFor declarative HTML definitions, styles live in a separate `.styles.css` file linked from\nboth the initial shadow root template and the `<f-template>`:\n\n```html\n<f-template name=\"my-element\">\n    <template>\n        <link rel=\"stylesheet\" href=\"./my-element.styles.css\">\n    </template>\n</f-template>\n```\n\n`css.partial()` works the same way as `html.partial()` — injecting raw CSS strings.\n\n## Reactivity\n\n`@attr` maps HTML attributes to properties. `@observable` creates reactive properties\ntracked by templates. `@volatile` marks getters whose dependencies change between calls:\n\n```ts\nimport { FASTElement } from \"@microsoft/fast-element/fast-element.js\";\nimport { attr, nullableNumberConverter } from \"@microsoft/fast-element/attr.js\";\nimport { Observable, observable } from \"@microsoft/fast-element/observable.js\";\nimport { volatile } from \"@microsoft/fast-element/volatile.js\";\n\nclass MyElement extends FASTElement {\n    @attr label?: string;\n    @attr({ mode: \"boolean\" }) active?: boolean;\n    @attr({ converter: nullableNumberConverter }) count?: number;\n\n    @observable private _items: string[] = [];\n\n    // Convention: ${propertyName}Changed\n    labelChanged(prev: string | undefined, next: string | undefined) {}\n\n    @volatile\n    get sortedItems(): readonly string[] {\n        return [...this._items].sort();\n    }\n}\n```\n\nNotify the system after in-place mutations that it cannot detect automatically:\n\n```ts\nthis._items.splice(index, 1);\nObservable.notify(this, \"_items\");\n```\n\nMake plain objects observable via the state sub-entry-point:\n\n```ts\nimport { reactive } from \"@microsoft/fast-element/state.js\";\nconst todo = reactive({ description: \"Buy milk\", done: false });\n```\n\n## Testing\n\nTests use Playwright Test (`*.pw.spec.ts`) and combine two patterns within the same file.\n\n### Direct-import tests\n\nFor logic that does not need browser APIs — the test callback takes no parameters:\n\n```ts\nimport { expect, test } from \"@playwright/test\";\nimport { Observable } from \"./observable.js\";\n\ntest.describe(\"Observable\", () => {\n    test(\"can get a notifier\", () => {\n        const notifier = Observable.getNotifier(new Model());\n        expect(notifier).toBeInstanceOf(PropertyChangeNotifier);\n    });\n});\n```\n\n### Browser-evaluated tests\n\nFor tests requiring DOM APIs, navigate to the Vite dev server and import via\n`\"/main.js\"`. The `@ts-expect-error` comment is required because TypeScript cannot\nresolve the URL-based import:\n\n```ts\ntest(\"renders element\", async ({ page }) => {\n    await page.goto(\"/\");\n\n    const result = await page.evaluate(async () => {\n        // @ts-expect-error: Client module.\n        const { FASTElement, html, uniqueElementName } = await import(\"/main.js\");\n        // ... test logic ...\n        return someSerializableValue;\n    });\n\n    expect(result).toBe(expected);\n});\n```\n\nOnly serializable values can cross the `page.evaluate` boundary — run `expect()`\nassertions outside it on the returned data.\n\nThe test harness at `packages/<package>/test/main.ts` re-exports source modules for\nbrowser tests. When adding new package exports, add them there too.\n\n## TypeScript idioms\n\n### Const-type merging for enumerations\n\nFrozen const objects paired with a type extracted from their values replace TypeScript\n`enum`:\n\n```ts\nexport const SourceLifetime = {\n    default: undefined,\n    couple: 1,\n} as const;\n\nexport type SourceLifetime =\n    (typeof SourceLifetime)[keyof typeof SourceLifetime];\n```\n\n### Interface-const merging\n\n`FASTElement` is both an interface (instance shape) and a const (constructor). Static\nmethods use `typeof` to carry overloaded signatures:\n\n```ts\nexport const FASTElement: {\n    new (): FASTElement;\n    define: typeof define;\n} = Object.assign(createFASTElement(HTMLElement), { define });\n```\n\n### Tagged template intersection types\n\n`html` and `css` are typed as intersections of a tagged template function and a\n`.partial()` method:\n\n```ts\ntype HTMLTemplateTag = (<TSource, TParent>(\n    strings: TemplateStringsArray,\n    ...values: TemplateValue<TSource, TParent>[]\n) => ViewTemplate<TSource, TParent>) & {\n    partial(html: string): InlineTemplateDirective;\n};\n```\n","packages/README.md":"# FAST Packages\n\nOur web component packages.\n\n## `@microsoft/fast-element`\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-element.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-element)\n\nThe `@microsoft/fast-element` library is a lightweight means to easily build performant, memory-efficient, standards-compliant Web Components. FAST Elements work in every major browser and can be used in combination with any front-end framework or even without a framework. To get up and running with `@microsoft/fast-element` see [the Getting Started guide](https://fast.design/docs/getting-started/quick-start).\n\n## `@microsoft/fast-router`\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-foundation.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-router)\n\nThe `@microsoft/fast-router` package contains a history-based navigation and routing solution designed around Web Components. By using `fast-router`, you can create multi-page and full application experiences. The router works with any Web Components, but has special support for Web Components built on FAST.","packages/fast-build/README.md":"# FAST Build\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-build.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-build)\n\nThe `fast-build` package renders the declarative HTML template syntax of [`@microsoft/fast-element`](https://www.npmjs.com/package/@microsoft/fast-element), primarily for use in testing environments. It is powered by a WebAssembly core with zero runtime npm dependencies.\n\n> **Note:** For production server-side rendering, we recommend using the [`@microsoft/webui`](https://github.com/microsoft/webui) project instead.\n\n## Installation\n\n### From NPM\n\nTo install the latest `@microsoft/fast-build` package using `npm`:\n\n```shell\nnpm install --save @microsoft/fast-build\n```\n\nWithin your JavaScript or TypeScript code, you can then import library APIs like this:\n\n```ts\nimport { render } from '@microsoft/fast-build';\n```\n\n## CLI usage\n\nOnce installed, the `fast` binary is available. Use the `build` subcommand to render an HTML template with an optional JSON state file, or `convert` to convert a FAST declarative HTML template to another supported syntax:\n\n```shell\nfast build [options]\nfast convert [options]\n```\n\n### Build options\n\n| Option | Default | Description |\n|---|---|---|\n| `--entry=\"<path>\"` | `index.html` | Entry HTML template to render |\n| `--state=\"<path>\"` | `{}` when omitted | JSON file containing the template state. If omitted, no state file is loaded and rendering uses an empty state object. If `--state` is provided, the file must exist. |\n| `--output=\"<path>\"` | `output.html` | Where to write the rendered HTML |\n| `--templates=\"<glob>\"` | _(none)_ | Glob pattern(s) for custom element template HTML files. Separate multiple patterns with commas. A warning is printed if not provided in non-streaming mode or if no files match a pattern. |\n| `--attribute-name-strategy=\"<strategy>\"` | `camelCase` | Strategy for mapping HTML attribute names to state property names on custom elements. `\"camelCase\"` converts dashes to camelCase (e.g. `foo-bar` → `fooBar`). `\"none\"` preserves dashes (e.g. `foo-bar` → `foo-bar`). See [Attribute name strategy](#attribute-name-strategy). |\n| `--markers_v2[=true/false]` | `false` | Emit FAST Element 2.x indexed hydration markers instead of the default FAST Element 3.x data-free markers. |\n| `--config=\"<path>\"` | `fast-build.config.json` | Path to a JSON configuration file. If omitted, `fast-build.config.json` in the current directory is used when present. CLI arguments take precedence over config values. See [Configuration file](#configuration-file). |\n| `--stream[=true/false]` | `false` | Write rendered HTML chunks directly to stdout instead of writing `--output`. Valueless `--stream` is treated as `true`. |\n\n### Example\n\nGiven an `index.html`:\n\n```html\n<html>\n  <body>\n    <h1>{{title}}</h1>\n    <p>{{description}}</p>\n  </body>\n</html>\n```\n\nAnd a `state.json`:\n\n```json\n{\n  \"title\": \"Hello FAST\",\n  \"description\": \"Server-side rendered with WebAssembly.\"\n}\n```\n\nRun:\n\n```shell\nfast build --entry=index.html --state=state.json --output=output.html\n```\n\nProduces `output.html`:\n\n```html\n<html>\n  <body>\n    <h1>Hello FAST</h1>\n    <p>Server-side rendered with WebAssembly.</p>\n  </body>\n</html>\n```\n\n### Streaming output\n\nPass `--stream`, `--stream=true`, or `--stream=false`, or set\n`\"stream\": true` in `fast-build.config.json`, to control stdout streaming. When\nstreaming is enabled, the CLI writes raw rendered HTML chunks to stdout, does\nnot write the `--output` file, and does not print the normal `Built: ...`\nmessage.\n\n```shell\nfast build --entry=index.html --state=state.json --stream\n```\n\nStreaming is simulated by the WebAssembly renderer: chunks are prepared in\nmemory, returned to JavaScript as a JSON array, parsed by the CLI, and then\nwritten to stdout. `--stream` uses the same entry renderer with its stream flag\nenabled and passes an empty templates map when no `--templates` glob is\nprovided. Chunk boundaries are safe for HTML parsing:\n\n- Attribute bindings stay within complete opening tag chunks.\n- Custom element opening chunks include the complete Declarative Shadow DOM\n  template.\n- Streamed output uses the same renderer preprocessing and custom-element host\n  attribute propagation as normal output.\n- Empty chunks are omitted.\n- Concatenating all chunks matches the normal non-streamed render.\n\n### Performance benchmarks for contributors\n\nThe renderer discovers tags and bindings in a forward scan, eliminating repeated\nremaining-suffix searches for adjacent custom elements and plain tags. Existing\nWASM exports, rendered bytes, default markers, and `markers_v2` remain compatible.\nRendering is still synchronous, and `--stream` still buffers all chunks in WASM.\n\nFrom a FAST repository checkout, not an installed npm package:\n\n```shell\nnpm run build -w @microsoft/fast-build\nnpm run bench:render -w @microsoft/fast-build -- --case=url_sink_siblings --output=/tmp/fast-render.json\nnpm run bench:render -w @microsoft/fast-build -- --case=url_sink_siblings --check-scaling\n```\n\nThe runner benchmarks the actual packaged WASM in fresh child processes in both\nmarker modes, recording timing, CPU, output hashes, throughput, and peak RSS.\nUse `--case`, `--counts`, `--samples`, or `--compare=<baseline.json>` to narrow\nor compare a run. Output files are never overwritten. Normal tests verify the\nsame fixtures against pre-optimization hashes without flaky timing thresholds.\nSee the [benchmark guide](../../crates/microsoft-fast-build/benchmark-baselines/README.md)\nfor native Criterion benchmarks, fixture sizes, methodology, and limitations.\n\nThe guide includes post-scanner repeat/state-heavy and many-definition profiles.\nStart expensive repeat cases with `--counts=250,1000 --warmup-count=250`;\nstate-overlay controls and separate native phases help identify the next\noptimization without running an unbounded matrix. Native CPU samples are not\nWASM allocation measurements, and no production rendering behavior is changed.\n\nThe guide also includes an opt-in native allocation baseline and a fresh-process\nmatrix command: `node crates/microsoft-fast-build/benches/profile-allocations.mjs\n--output=/tmp/fast-allocations.json` from the repository root. Its counters are\ndevelopment-only Rust tooling, not part of the npm CLI or WASM; native peak\nnewly-live heap is not process RSS.\n\n### Missing or omitted state\n\nState is optional. When `--state` is omitted and no `state` path is provided by config, `fast build` does not look for `state.json`; rendering uses an empty object (`{}`). An explicit `--state` path, or a `state` path from config, must exist or the command exits with an error.\n\n> **Breaking change:** Earlier versions implicitly loaded `state.json` from the current working directory when `--state` was omitted. To use a state file, pass `--state=state.json` or set `\"state\": \"state.json\"` in `fast-build.config.json`.\n\nWhen a binding value is not present in state:\n\n- Content bindings render nothing, including unresolved dot paths: `<p>{{foo.bar}}</p>` becomes `<p></p>`.\n- Attribute bindings omit the entire attribute, including unresolved dot paths: `<div class=\"{{foo.bar}}\"></div>` becomes `<div></div>`.\n- `<f-repeat>` treats a missing list binding, including unresolved dot paths, as an empty array and renders zero iterations. If the binding is present but is not an array, rendering still errors.\n\nExplicit `null` also omits an attribute, even in an interpolated attribute\nvalue. Empty strings remain present. Known HTML boolean attributes bound to\nJSON booleans use presence/absence; ordinary attributes (including ARIA)\nretain textual booleans. Use `?name` for browser-side truthy/falsy bindings.\nAuthor bindings resolving to absence still override template-host defaults.\nThese intentional output changes are described in the\n[plugin migration guide](./docs/migration/plugin-integrations.md).\n\n### APIs for build-time plugins\n\nImport the actual exported WASM subpath; do not slice rendered host HTML:\n\n```js\nimport {\n    parse_f_templates,\n    render_shadow_root,\n} from \"@microsoft/fast-build/wasm/microsoft_fast_build.js\";\n\nconst definitions = JSON.parse(parse_f_templates(templateHtml));\nconst templates = Object.fromEntries(\n    definitions.filter(definition => definition.name !== null)\n        .map(definition => [definition.name, definition]),\n);\nconst shadowRootHtml = render_shadow_root(\n    \"my-card\", JSON.stringify(templates), JSON.stringify(componentState),\n);\n```\n\nThe result is the complete DSD `<template>` fragment, with hydration markers\nand nested components, but no host, host defaults, or light DOM. Pass resolved\ncomponent state; the API does not derive it from caller-owned host attributes.\nIt accepts the existing attribute-name strategy and v2 marker options.\n\nParsed records add `formatVersion: 1` and `bindings` without changing the array\nshape. Binding records expose `name` (null for compound expressions),\n`expression`, syntax `kind`, lexical `paths`, and outer-to-inner repeat\n`scope` frames. `type` is null except for repeat collections (`\"array\"`);\n`optional` is null because required state declarations are not inferable.\n`$index` paths refer to the active repeat frame, not a root state key.\nClient expressions are described lexically, not fully JavaScript-type-checked.\nCode samples are excluded; metadata is not full syntax or state validation.\nGenerated WASM declarations expose these JSON interfaces.\n\n#### Authored binding source spans\n\nEach binding occurrence includes `span: { start, end }`. Both positions contain\n`offset`, `line`, and `column`, relative to the **complete HTML string passed to\n`parse_f_templates`**, not the extracted or trimmed template body. Duplicate\nexpressions have separate spans, including occurrences in host attributes,\ninterpolated attribute values, and nested directives.\n\n- `offset` is a zero-based UTF-16 code-unit offset, compatible with JavaScript\n  string slicing. It is not a UTF-8 byte offset.\n- `line` and `column` are one-based. Columns count UTF-16 code units, not visual\n  width or Unicode code points; a tab counts as one and a non-BMP character\n  counts as two.\n- Ranges are half-open: `start` is inclusive and `end` is exclusive. They cover\n  the trimmed expression, excluding braces and surrounding whitespace.\n- CRLF counts as one line break but two offset units. Lone CR and LF each count\n  as one line break. Input line endings are not normalized.\n- Repeat bindings locate the iterable expression, not the alias or `in` keyword,\n  matching their existing `expression` field. Nested `scope` frames are unchanged.\n\n```js\nconst [definition] = JSON.parse(parse_f_templates(templateHtml));\nfor (const binding of definition.bindings) {\n    const { start, end } = binding.span;\n    const authoredExpression = templateHtml.slice(start.offset, end.offset);\n    console.log(`${start.line}:${start.column}`, authoredExpression);\n}\n```\n\nPositions refer to the original, entity-encoded attribute text. No entity decoding\nis introduced. Code samples remain excluded without shifting subsequent spans.\nCallers associate the input with its file name and must regenerate metadata after\nediting that input. Bindings and directives inside HTML comments remain unsupported.\n\nRender exports reject unsupported/malformed explicit versions before rendering.\nLegacy unversioned maps and string definitions remain supported. The CLI keeps\nversion/binding fields when assembling a map; persisted metadata should do the\nsame instead of discarding them.\n\n#### Structured errors\n\nFailing render, conversion, composition, and metadata-validation APIs throw actual\nJavaScript `Error` objects, retaining the existing human-readable `message`.\nBoth WASM modules export this TypeScript interface (not a runtime constructor):\n\n```ts\ninterface FastBuildError extends Error {\n    code: string;\n    line?: number;\n    column?: number;\n    length?: number;\n    templateName?: string;\n}\n```\n\nUse `code`, such as `unclosed-binding`, `repeat-not-array`, or `missing-template`,\ninstead of parsing messages. The complete code lists are documented with the\n[renderer errors](../../crates/microsoft-fast-build/README.md#error-handling)\nand [converter errors](../../crates/microsoft-fast-convert/README.md#error-codes).\n\nLocations use one-based lines and UTF-16 columns, with a UTF-16 highlight `length`.\nTabs count as one unit, non-BMP characters as two; CRLF is one line break and lone\nCR/LF are also line breaks. A highlight covers the offending opening tag or\nbinding including its delimiters; an unclosed binding highlights its opening\ndelimiters. Unlike successful binding metadata, these are error-token ranges,\nnot trimmed expression ranges.\n\nEntry-render and conversion coordinates refer to the original HTML argument,\neven after code-sample escaping, inner-template extraction, or publisher-attribute\nrewriting. Light DOM remains in its caller's source. Errors in separately supplied\ncustom-element definitions include `templateName` and use coordinates within that\ndefinition's supplied `content`, not the entry HTML or the full file it was\nextracted from. Maintain a name-to-source mapping when presenting these locations.\nFor a missing inner template, the highlight identifies its containing\n`<f-template>`; duplicate-wrapper errors identify the second wrapper.\n\nCoordinates are absent when there is no meaningful HTML position: invalid state\nJSON, malformed metadata/options, missing template definitions or outer wrappers,\nfilesystem errors, and unsafe separately supplied CSS. A known `templateName`\ncan still be present without coordinates. `parse_f_templates` remains permissive:\nit does not gain strict syntax validation or new failures.\n\nFor a direct `render(html, stateJson)` call, an integration can report:\n\n```js\ntry {\n    render(html, stateJson);\n} catch (error) {\n    if (!(error instanceof Error)) throw error;\n    const location = error.line === undefined\n        ? inputPath\n        : `${inputPath}:${error.line}:${error.column}`;\n    console.error(`${location} [${error.code}]: ${error.message}`);\n}\n```\n\nSee the [migration guide](./docs/migration/plugin-integrations.md#structured-errors)\nwhen updating consumers that previously caught strings.\n\n### Custom element templates\n\nPass a glob pattern (or comma-separated list of patterns) to `--templates` to expand custom elements into [Declarative Shadow DOM](https://developer.chrome.com/docs/css-ui/declarative-shadow-dom):\n\n```shell\nfast build \\\n  --templates=\"./components/**/*.html\" \\\n  --entry=index.html \\\n  --state=state.json \\\n  --output=output.html\n```\n\nEach matched `.html` file is scanned for `<f-template>` elements. The `name` attribute of each `<f-template>` determines the custom element name. A single file may contain multiple templates.\n\nTemplate files must use the following format:\n\n```html\n<f-template name=\"my-button\">\n    <template>\n        <button>{{label}}</button>\n    </template>\n</f-template>\n```\n\nIf an `<f-template>` element has no `name` attribute, a warning is printed and it is ignored. Exact file paths (no wildcards) are also accepted as patterns, making it possible to register a single template file. The parser follows browser tag boundaries for the `<f-template>` and inner `<template>` wrappers, including ASCII whitespace before `>` in opening and closing tags.\n\nAny `shadowroot*` attributes on `<f-template>` are forwarded to the rendered Declarative Shadow DOM `<template>`. The CLI normalizes `shadowrootmode` and legacy `shadowroot` for compatibility: when neither has a non-empty value, it emits `shadowrootmode=\"open\" shadowroot=\"open\"`; when exactly one has a non-empty value, that value is mirrored to the other; when both have explicit non-empty values, both are preserved as authored, even if they conflict.\n\n### Attribute name strategy\n\nThe `--attribute-name-strategy` option controls how HTML attribute names on custom elements are mapped to state property names in their shadow templates.\n\n| Strategy | Behaviour | Template binding |\n|---|---|---|\n| `camelCase` (default) | Dashed attribute names converted to camelCase | `foo-bar` → `{{fooBar}}` |\n| `none` | Attribute names lowercased as-is, dashes preserved | `foo-bar` → `{{foo-bar}}` |\n\nThe `camelCase` strategy only affects \"plain\" custom element attributes. It does **not** change:\n- `data-*` attributes (always use `dataset.*` grouping)\n- `aria-*` attributes (always use ARIA reflection lookup)\n- HTML global attributes with known property names (e.g. `tabindex` → `tabIndex`)\n\n```shell\nfast build \\\n  --templates=\"./components/**/*.html\" \\\n  --attribute-name-strategy=camelCase \\\n  --entry=index.html \\\n  --state=state.json \\\n  --output=output.html\n```\n\n### Configuration file\n\nInstead of passing every option on the command line, you can place a `fast-build.config.json` file alongside your project files:\n\n```json\n{\n    \"entry\": \"index.html\",\n    \"state\": \"state.json\",\n    \"output\": \"output.html\",\n    \"templates\": \"./components/**/*.html\",\n    \"markers_v2\": true\n}\n```\n\nThe CLI automatically loads `fast-build.config.json` from the current directory when it exists. To use a different file, pass `--config`:\n\n```shell\nfast build --config=configs/my-build.json\n```\n\n**Precedence:** CLI arguments always override config file values. For example, `--output=other.html` will override the `output` value in the config file.\n\n**Path resolution:** File paths in the config file (`entry`, `state`, `output`, `templates`) are resolved relative to the config file's directory, not the current working directory. This ensures the config works correctly regardless of where the CLI is invoked.\n\nAll keys are optional. Only the following keys are allowed: `entry`, `state`, `output`, `templates`, `attribute-name-strategy`, `markers_v2`, and `stream`. Unknown keys produce an error. Values must be strings except `markers_v2` and `stream`, which must be JSON booleans (`true` or `false`). If `state` is omitted, rendering uses `{}`; if `state` is present, the referenced file must exist. CLI arguments always override config values, including `--stream=false` overriding `\"stream\": true`.\n\n## Convert\n\n`fast convert` converts FAST declarative template files using the converter WASM module in `wasm/convert/`. Supported syntax names, output extensions, and default output suffixes are read from the converter WASM metadata so the Rust converter remains the source of truth for syntax targets.\n\n```shell\nfast convert --syntax=webui-prerelease --templates=example.html\nfast convert --syntax=fast-v3-ts --templates=example.html --output=../*.template.ts\nfast convert --syntax=fast-v3-ts --templates=\"src/**/*.html\" --output=generated/*.template.ts\nfast convert --syntax=fast-v3-ts --templates=example.html \\\n    --type-source=MyElement --type-source-import=./my-element.js\n```\n\n### Convert options\n\n| Option | Default | Description |\n|---|---|---|\n| `--syntax=\"<syntax>\"` | _(required)_ | Target syntax: `webui-prerelease`, `webui-framework-prerelease`, or `fast-v3-ts` |\n| `--templates=\"<glob>\"` | _(required)_ | Comma-separated glob pattern(s) matching `.html` templates to convert. An exact single file path is also accepted. Loads the converter WASM module once for the whole batch. |\n| `--output=\"<path>\"` | Next to source | Output file path. `webui-prerelease` defaults to `*.webui.html`; `webui-framework-prerelease` defaults to `*.webui-framework.html`; `fast-v3-ts` defaults to `*.template.ts`. Any `*` in the output path is replaced with the input basename without extension. Every file matched by `--templates` is written under `--output`'s directory (or next to its source if `--output` is omitted). |\n| `--overwrite` | `false` | Allow replacing an existing output file. CLI presence always means `true`. |\n| `--typed[=true/false]` | `false` | Only for `fast-v3-ts`. Add an explicit `ElementViewTemplate<TSource>` export annotation and type-only import. Explicit false overrides configured true. |\n| `--type-source=\"<Name>\"` | _(none)_ | Only valid with `--syntax=fast-v3-ts`. Emits `export const template = html<Name>\\`…\\`;` instead of the untyped `html` call. Must be a dotted TypeScript identifier (e.g. `MyElement` or `Namespace.MyElement`). |\n| `--type-source-import=\"<module>\"` | _(none)_ | Requires `--type-source`. Also emits `import type { <Name> } from \"<module>\";` alongside the helper imports. |\n| `--config=\"<path>\"` | `fast-convert.config.json` | Path to a JSON configuration file. If omitted, `fast-convert.config.json` in the current directory is used when present. CLI arguments take precedence over config values. |\n\nOnly matched `.html` files are converted; non-`.html` files and directories are never matched. The output extension must match the selected syntax: `.html` for `webui-prerelease`/`webui-framework-prerelease` and `.ts` for `fast-v3-ts`. The output parent directory is created automatically if it doesn't exist (`mkdir -p` semantics), and an existing output file is rejected unless `--overwrite` or `\"overwrite\": true` is used. When a `--templates` pattern matches zero files, a warning is printed but the command does not fail unless every pattern matches zero files.\n\n`webui-framework-prerelease` converts FAST's declarative syntax into the Microsoft WebUI Framework's own declarative runtime syntax (`webui-prerelease` remains unchanged — it emits HTML for WebUI's separate FAST parser plugin instead). When `webui-framework-prerelease` strips an unsupported `f-slotted`/`f-children` directive, the CLI prints `Warning: <message>` to stderr for each stripped directive without failing the command.\n\n`--type-source` exists so templates that combine more than one differently-named\n`ref`/`children`/`slotted` directive (which otherwise fail to type-check once a\nreal `TSource` is supplied, because `html<TSource, TParent>` infers a single\n`TSource` for the whole tagged template) can be generated already type-checked\nagainst a concrete element type. See\n[`microsoft-fast-convert` DESIGN.md](../../crates/microsoft-fast-convert/DESIGN.md#explicit-tsource-generic).\n\n### Convert configuration file\n\n`fast-convert.config.json` follows the same precedence and path-resolution rules as `fast-build.config.json`: CLI arguments override config values, and `templates`/`output` paths from config are resolved relative to the config file directory.\n\n```json\n{\n    \"syntax\": \"fast-v3-ts\",\n    \"templates\": \"src/**/*.html\",\n    \"output\": \"generated/*.template.ts\",\n    \"overwrite\": false,\n    \"type-source\": \"MyElement\",\n    \"type-source-import\": \"./my-element.js\"\n}\n```\n\nOnly `syntax`, `templates`, `output`, `overwrite`, `type-source`,\n`type-source-import`, and `typed` are allowed. Values must be strings except\n`overwrite` and `typed`, which must be JSON booleans.\n\nFor declaration-emitting consumers, use `--typed --type-source=MyElement`.\nThe converter WASM's `convert_template_with_options` accepts an appended\noptional `typed` boolean. `convert_stylesheet(css, \"fast-v3-ts\", \"styles\",\ntrue)` emits an `ElementStyles` annotation. Existing calls remain untyped;\ntyped exports are tested with TypeScript `isolatedDeclarations`.\n\n### Running converter fixtures locally\n\nBuild the package WASM, then run the fixture validation:\n\n```shell\nnpm run build -w @microsoft/fast-build\nnpm run test:fixtures:convert -w @microsoft/fast-build\n```\n\nThe fixture tests run `fast convert` from fixture directories that contain\n`fast-convert.config.json`, so they verify the same default config discovery used\nby `fast build`. Generated fixture output is written under\n`packages/fast-build/test/.fixture-output/` and removed by the tests.\n`test/fixtures/convert/type-source.test.js` additionally type-checks\n`--type-source` output with the TypeScript compiler API against a companion\nelement type, using a separate `test/.fixture-output-type-source/` directory.\n\n## Template syntax\n\nBindings and FAST directive markup inside HTML comments are unsupported.\nCommenting out bound markup does not reliably disable its bindings and can cause\nrendering errors or client hydration mismatches. Remove unused bound markup\ninstead, and keep explanatory comments free of binding syntax and FAST directive\ntags.\n\nTemplate syntax follows the FAST declarative HTML format. See the\n[`@microsoft/fast-element` declarative documentation](../fast-element/docs/declarative/syntax.md)\nfor full documentation on bindings, conditionals, repeats, and directives.\n","packages/fast-build/docs/migration/plugin-integrations.md":"# Migrating plugin integration pipelines\n\n## Structured errors\n\nWASM failures now throw JavaScript `Error` objects rather than strings. Read\n`error.message` for the previous human-readable text; `String(error)` now has the\nstandard `Error: ` prefix. Replace message matching with stable `error.code`\nchecks. Both WASM declaration modules export a `FastBuildError` interface extending\n`Error`; it is a type only, not an exported constructor.\n\nOptional `line`/`column` are one-based UTF-16 coordinates, and `length` is a UTF-16\nerror-token highlight length. CRLF is one break; lone CR/LF also break lines.\nEntry and conversion coordinates refer to the complete supplied HTML. A named\ncustom-element render failure instead refers to its separately supplied `content`.\nUse `templateName` to select that source, rather than attaching its coordinates\nto the entry or to a full file from which `content` was extracted. Older metadata\ndoes not carry enough provenance to reconstruct those full-file positions.\nDo not fabricate HTML locations when these fields are absent (JSON/options,\nmissing sources, filesystem errors, or separate CSS).\n\nNative Rust `RenderError` and `ConvertError` expose `code()`, `location()` returning\nan optional `ErrorLocation`, `template_name()`, and `kind()`. Source-annotated\nvalidation errors may use the new `Located` variant; match `error.kind()` to\ninspect the underlying variant. Context fields now use boxed `ErrorContext`\ninstead of `String`; use `context.to_string()` to read the unchanged snippet and\n`String::into()` when constructing a context without source provenance.\nUpdate exhaustive enum matches for `Located`. These are intentional pre-1.0\nnative API changes. Successful rendering/conversion, warnings, missing-state\nbehavior, and permissive `parse_f_templates` parsing are unchanged.\n\n## Attribute output changes\n\nMissing and explicit `null` bindings now omit the entire attribute, including\nmixed literal/binding values. To intentionally keep `href=\"\"`, provide `\"\"`\ninstead of null. JSON booleans on known HTML boolean attributes use presence:\nfalse omits `disabled`, true emits it. ARIA/ordinary attribute booleans remain\ntextual. Use FAST's `?name` syntax for matching client-side truthy/falsy behavior.\nAuthor bindings resolving to absence suppress matching template-host defaults.\nRemove wrapper regular expressions that strip empty values: they would erase\nintentional empty strings. Hydration slot counts remain unchanged.\n\n## Typed converter output\n\nThe default output remains unchanged. Opt into `typed: true` (or `--typed`)\nfor explicit `ElementViewTemplate<TSource>` / `ElementStyles` annotations and\ntype-only imports, then remove wrapper string replacements. Supply\n`type_source`/`--type-source` when strict source-property checking is required.\nRust `ConvertOptions` struct literals must include the new `typed` field or\nuse `..ConvertOptions::default()`.\nThe pre-1.0 native error enums also gain integration-related variants; update\nexhaustive `RenderError` / `ConvertError` matches accordingly.\n\n## Caller-owned host markup\n\nReplace throwaway-host rendering and substring extraction with\n`render_shadow_root` (WASM) or `render_shadow_root_*_with_locator` (Rust).\nPass resolved component state and insert the returned complete DSD `<template>`\ninto the host you own. The fragment does not include host/default attributes\nor light-DOM children.\n\n## Persisted template metadata\n\n`parse_f_templates` keeps its JSON array shape and existing fields, adding\nper-record `formatVersion: 1` and `bindings`. Preserve these fields when\npersisting or constructing a keyed map. Unsupported/malformed explicit versions\nnow fail before rendering. Unversioned legacy maps remain supported, but cannot\nreceive stale-version protection. Regenerate metadata on format changes rather\nthan rewriting a version number onto incompatible data.\n\nBindings describe names, expression kinds, paths, and repeat scopes. Unknown\ntypes and state optionality are explicitly null, not inferred declarations.\nRepeat collections alone have a known array requirement. Complex/client\nreferences are lexical descriptions; metadata is not a full state schema or\nsyntax-validation certificate. Use application declarations for definitive\ntype/requiredness checks.\n\nEach newly parsed binding now includes an authored `span` with half-open `start`\nand `end` positions in the complete input string. Offsets are zero-based UTF-16;\nlines and UTF-16 columns are one-based. Use the original input, not the returned\ntrimmed `content`, when slicing or attaching diagnostics. The range covers the\ntrimmed expression without braces; repeat bindings locate only the iterable.\nCRLF counts as one line break and two offset units; lone CR and LF each count\nas a line break. Raw attribute entities are not decoded.\n\nFormat version 1 is unchanged, and renderers still accept older records without\nspans. Regenerate persisted metadata to obtain authored locations; preserve spans\nwhen mapping or serializing records. Native `BindingMetadata` struct literals\nmust now supply the public `span: SourceSpan` field; prefer `parse_f_templates`\nto constructing descriptive metadata manually. Generated WASM declarations expose\n`TemplateSourceSpan` and `TemplateSourcePosition`.\n","packages/fast-element/README.md":"# FAST Element\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-element.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-element)\n\nThe `fast-element` library is a lightweight means to easily build performant, memory-efficient, standards-compliant Web Components. FAST Elements work in every major browser and can be used in combination with any front-end framework or even without a framework.\n\n## Installation\n\n### From NPM\n\nTo install the latest `fast-element` library using `npm`:\n\n```shell\nnpm install --save @microsoft/fast-element\n```\n\nWithin your JavaScript or TypeScript code, you can then import library APIs like this:\n\n```ts\nimport { FASTElement } from '@microsoft/fast-element';\n```\n\n### From CDN\n\nA pre-bundled script that contains all APIs needed to build web components with FAST Element is available on CDN. You can use this script by adding [`type=\"module\"`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to the script element and then importing from the CDN.\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <script type=\"module\">\n          import { FASTElement } from \"https://cdn.jsdelivr.net/npm/@microsoft/fast-element/dist/fast-element.min.js\";\n\n          // your code here\n        </script>\n    </head>\n    <!-- ... -->\n</html>\n```\n\nThe markup above always references the latest release. When deploying to production, you will want to ship with a specific version. Here's an example of the markup for that:\n\n```html\n<script type=\"module\" src=\"https://cdn.jsdelivr.net/npm/@microsoft/fast-element@1.6.2/dist/fast-element.min.js\"></script>\n```\n\n:::note\nFor simplicity, examples throughout the documentation will assume the library has been installed from NPM, but you can always replace the import location with the CDN URL.\n:::\n\n:::tip\nLooking for a quick guide on building components?  Check out [our Cheat Sheet](../resources/cheat-sheet.md#building-components).\n:::\n\n## Browser Requirements\n\nFAST Element v3 assumes a client-side browser `Window` runtime with native\n`globalThis`, Custom Elements, DOM, Shadow DOM, and `requestAnimationFrame`.\nThe `FAST` object is now a module-scoped export (not on `globalThis`). If you\nneed to support an older browser without `globalThis`, load that polyfill before\nimporting `@microsoft/fast-element`.\n\nThe FAST Element client runtime is not intended to execute in workers,\nserver-side JavaScript runtimes, or other non-window hosts. Use server-side\nrendering tools to produce HTML for the browser, and run FAST Element in the\nclient window where custom elements connect, render, update, and hydrate.\n\n## Debug entrypoint\n\nThe declarative attribute fixture covers server-side omission of null/missing\nattributes and subsequent hydration updates. Explicit empty strings remain\npresent, and omitted attributes retain binding slots. See the\n[server-rendering guide](https://www.fast.design/docs/3.x/declarative-templates/server-rendering/)\nfor the rendering contract.\n\n`@microsoft/fast-element/debug.js` exports `enableDebug()` instead of configuring\nFAST at import time. The development root export and debug rollup bundle still\nenable debug behavior automatically.\n\n```ts\nimport { enableDebug } from \"@microsoft/fast-element/debug.js\";\n\nenableDebug();\n```\n\n## Server-rendered hydration\n\nCall `enableHydration()` from `@microsoft/fast-element/hydration.js` before\ncomponents connect to reuse their server-rendered DOM. Ordered sibling-bounded\nviews use pointer traversal and consume native markers without factory-index\narrays; unusual boundaries and potentially mutating cleanup retain the live\nRange fallback. Nested and adjacent repeats pair only their own server ranges,\npreserving SSR nodes while reconciling missing or excess items.\n\nCall `enableHydration()` before components are registered with the platform to\nalso enable pointer-only native marker cleanup for FAST components that do not\nobserve `data-fe`. Observation tracking is opt-in and excluded from client-only\n`FASTElement` bundles. Earlier registrations still hydrate correctly through\nthe conservative fallback, as do unknown registration, observed markers,\ncustomized built-ins, and overridden attribute methods. Cleanup remains\nsynchronous.\n\nExisting FAST 3 marker output and opt-in `markers_v2` remain supported without\napplication changes. See the [server-rendering guide](https://www.fast.design/docs/3.x/declarative-templates/server-rendering/)\nand [contributor performance workloads](./docs/template-bindings.md#hydration-cpu-regression-coverage).\nContributor-facing internals separate DOM traversal, binding target mapping,\nand repeat-range discovery; the opt-in benchmark spec is independent of the\ndeterministic correctness and allocation regression spec.\n\n## Export Sizes\n\nBundle sizes for each tree-shakeable export are tracked in [`SIZES.md`](./SIZES.md) and regenerated on every build. See the [Export Sizes](https://www.fast.design/docs/3.x/resources/export-sizes/) documentation page for the latest numbers.\n\n## Root Imports and Path Exports\n\nThe root `@microsoft/fast-element` entrypoint exports the FAST Element\nimplementation APIs, including the element base class, kernel, controller,\ndefinition APIs, template APIs, binding helpers, directives, styles, and schema\nhelpers. The FAST element registry is also available from\n`@microsoft/fast-element/registry.js` for focused definition lookups and\n`fastElementRegistry.whenRegistered(tagName)` registration promises.\nDeclarative, hydration, context, and dependency injection APIs are available\nfrom their focused path exports.\n\nFocused package path exports remain available for consumers that want to import\na narrower entrypoint directly. The website's\n[Path Exports](https://www.fast.design/docs/3.x/advanced/path-exports/) page is\ngenerated from `package.json` and lists each supported path.\n\n## Dynamic Style Application\n\nImport `css`, `CSSTemplateTag`, `CSSValue`, and style APIs such as\n`ElementStyles`, `CSSDirective`, `cssDirective`, `ComposableStyles`,\n`HostBehavior`, `HostController`, `StyleStrategy`, and `StyleTarget` from\n`@microsoft/fast-element`:\n\n```ts\nimport { ElementStyles, css } from \"@microsoft/fast-element\";\n```\n\nWhen runtime state or external signals need to add or remove styles, create the\n`ElementStyles` with `css` and toggle it through\n`this.$fastController.addStyles()` / `this.$fastController.removeStyles()` from\nthe element lifecycle or change handlers.\n\n`css` templates remain static style definitions. Runtime CSS bindings and\nbehavior-producing CSS directives are no longer supported; keep the condition on\nthe element and toggle a separate `ElementStyles` instance through the\ncontroller when styles need to change.\n\n## Declarative HTML\n\nBindings and FAST directive markup inside HTML comments are unsupported in\ndeclarative templates. Commenting out bound markup does not reliably disable its\nbindings; remove unused markup instead. See the\n[template syntax restrictions](./docs/declarative/syntax.md#html-comments).\n\nFAST Element publishes its declarative HTML runtime from\n`@microsoft/fast-element/declarative.js`. This entrypoint exports the\nfunctional APIs for declarative templates: `declarativeTemplate()`,\n`TemplateParser`, and related configuration types. `attributeMap()` and\n`observerMap()` are available from their own focused path exports. The\ndeclarative runtime is pure at import time; declarative APIs lazily install only\ndeclarative debug messages. Hydration is separate and remains opt-in through\n`enableHydration()` from `@microsoft/fast-element/hydration.js`.\n\n```ts\nimport { FASTElement } from \"@microsoft/fast-element\";\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n\nclass MyElement extends FASTElement {}\n\nMyElement.define({\n    name: \"my-element\",\n    template: declarativeTemplate(),\n});\n```\n\n`declarativeTemplate()` automatically defines FAST's internal native\n`<f-template>` publisher in the relevant registry, resolves the matching\n`<f-template name=\"my-element\">`, and keeps the definition template concrete\nbefore `define()` resolves. If multiple matching `<f-template>` elements are\nconnected, the first connected element supplies the template and later duplicates\ndo not reassign it. Consumers should not import or define the `<f-template>`\nimplementation directly.\n\nDeclarative schema behavior is enabled with define extensions:\n\n```ts\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [attributeMap(), observerMap()],\n);\n```\n\n`attributeMap()` creates `@attr`-style accessors for leaf bindings, and\n`observerMap()` creates deep observable accessors for discovered root\nproperties. Declarative templates assign `definition.schema` during template\nresolution so these extensions always have schema data when used with\n`declarativeTemplate()`. For non-declarative/manual schema use, import `Schema`\nfrom `@microsoft/fast-element` and pass it on the element definition;\n`observerMap()` can also receive\n`observerMap({ schema })` directly. When both extensions are present, attribute\nmapping runs before observer mapping.\n\nDeclarative utilities such as `deepMerge` are available from\n`@microsoft/fast-element/declarative-utilities.js`. See\n[`docs/declarative/syntax.md`](./docs/declarative/syntax.md) for declarative implementation\ndetails and the\n[Declarative HTML docs](https://fast.design/docs/3.x/declarative-templates/overview/)\nfor guides on writing f-templates, defining declarative elements, and\nserver-side rendering. Declarative event bindings use `$e` for the DOM event\nobject and `$c` for the execution context.\n\n## Prerendered Content Optimization\n\nHydration of prerendered content is **opt-in**. Call `enableHydration()` from `@microsoft/fast-element/hydration.js` before any FAST elements connect to activate the hydration path:\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nconst hydration = enableHydration();\n\nawait hydration.whenHydrated();\nconsole.log(\"hydration complete\");\n```\n\nBy default, hydration handles the initial prerendered batch and then no-ops\nafter the active hydration batch completes. If your app streams Declarative\nShadow DOM after the initial batch, keep the hydration hook active. In this\nmode, `enableHydration().whenHydrated()` intentionally remains pending because\nhydration never reaches a global completion point.\n\n```typescript\nimport { enableHydration, StopHydration } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({\n    stopHydration: StopHydration.never,\n});\n```\n\nFAST Element 3.x data-free hydration markers are the only format recognized\nby default. Server output that still emits the legacy FAST Element 2.x\nindexed markers will fail to hydrate unless you opt into that reader on its\ndedicated export path — an interoperability enhancement for backend systems\nthat have not yet adopted the data-free format:\n\n```typescript\nimport { enableHydration, markers_v2 } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ markers: markers_v2 });\n```\n\nBecause `markers_v2` is only referenced when explicitly imported, its legacy\nparsing logic is tree-shaken out of the bundle for consumers who don't use it.\n\nWhen using `@microsoft/fast-build`, set `\"markers_v2\": true` in\n`fast-build.config.json` so the renderer and client use the same format.\n\nWhen hydration is enabled and a FAST element connects with an existing shadow root (from server-side rendering or declarative shadow DOM), `ElementController` detects this and hydrates instead of re-rendering. Two properties on the controller let you inspect the result:\n\n- **`isPrerendered: Promise<boolean>`** — resolves `true` when the element had a declarative shadow root (DSD) at connect time, regardless of whether hydration ran.\n- **`isHydrated: Promise<boolean>`** — resolves `true` only when hydration actually ran successfully.\n\nThis enables several optimizations:\n\n- **Hydration instead of re-render**: The template uses `hydrate()` to map existing DOM nodes to binding targets rather than cloning new DOM.\n- **Declarative template resolution**: `declarativeTemplate()` waits for the\n  matching `<f-template>` before `define()` completes, so connected elements\n  hydrate with a concrete template.\n- **Attribute skip**: `onAttributeChangedCallback()` skips processing during initial upgrade when the element is prerendered, since server-rendered attribute values are already correct.\n- **Binding skip**: `HTMLBindingDirective.bind()` skips `updateTarget` for `attribute` and `booleanAttribute` aspect types when the view is prerendered.\n\n### Hydration Mismatch Diagnostics\n\nIf a prerendered DOM diverges from the client template in a way FAST cannot\nreconcile (the `render()` empty-boundary and `repeat()` count-mismatch cases\nrecover silently), `HydrationBindingError` or `HydrationTargetElementError` is\nthrown. By default the message is a single line pointing at the opt-in\n`hydrationDebugger()`. Install the debugger to get a rich\n\"Expected … / Received …\" report with the SSR HTML snippet and structured\n`expected` / `received` fields on the thrown error:\n\n```typescript\nimport { enableHydration, hydrationDebugger } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ debugger: hydrationDebugger() });\n```\n\nThe debugger module is tree-shaken out of production hydration bundles when\nnot imported, so the rich diagnostic helpers only land in builds that opt in.\n\nComponent authors can await both promises to distinguish prerendered content from successful hydration:\n\n```typescript\nconst controller = this.$fastController;\nconst prerendered = await controller.isPrerendered;\nconst hydrated = await controller.isHydrated;\n\nif (prerendered && !hydrated) {\n    // Had DSD but hydration wasn't enabled — client-side rendered\n}\n```\n\nCustom directives can also await `controller.isPrerendered` and `controller.isHydrated` (both `Promise<boolean>` on the `ViewController` interface) to determine how the view's content was rendered.\n\n## Define Extensions\n\nThe static `define()` method on a `FASTElement` subclass accepts an optional second argument — an array of extension callbacks that are invoked with the resolved element definition before the element is registered with the platform. This enables a plugin pattern where reusable behaviors can hook into element registration.\n\n```typescript\nimport { FASTElement, type FASTElementExtension } from \"@microsoft/fast-element\";\n\nfunction logger(): FASTElementExtension {\n    return definition => {\n        console.log(`Defining element: ${definition.name}`);\n    };\n}\n\nclass MyComponent extends FASTElement {\n    // component code\n}\n\nMyComponent.define({ name: \"my-component\", template, styles }, [logger()]);\n```\nEach extension receives the full `FASTElementDefinition`, which includes the resolved element name, type, template, styles, and attribute metadata. Extensions run before `customElements.define()`, so any setup they perform is available when existing DOM elements are upgraded.\n","packages/fast-element/docs/ACKNOWLEDGEMENTS.md":"# Acknowledgements\n\nThere are many great open source projects that have inspired us and enabled us to build FAST. Below are a few that stand out.\n\n* [.NET](https://dotnet.microsoft.com/) - Many thanks to the .NET team for sharing their policies and practices upon which our issue management and release planning docs and practices were based.\n* [asap](https://github.com/kriskowal/asap) - An awesome, time-tested async task queue implementation that heavily inspired our DOM update system.\n* [Aurelia 1 and Aurelia 2](https://aurelia.io/) - Various details of Aurelia 2's decorator and metadata model inspired us in the design of `fast-element`. Additionally, Aurelia 1's mechanisms for array observation, binding, and template compilation also guided us in our work.\n* [faastjs](https://github.com/faastjs) - A project with a similar name but a very different purpose. Their API documentation approach leveraging [api-extractor](https://api-extractor.com/) was a huge help to us.\n* [Knockout](https://knockoutjs.com/) - One of the first JavaScript libraries (if not the first) to implement an observer system. The original techniques for observables and computed observables have influenced many libraries over the years. Re-interpreting these ideas in terms of modern JavaScript and DOM has helped us to build a powerful and robust system.\n* [lit-html](https://lit-html.polymer-project.org/) - One of the first libraries to leverage standard JavaScript tagged template literals for HTML templates. We were inspired by this technique and wanted to explore whether it could be combined with our idea of arrow function binding expressions.\n* [Polymer](https://www.polymer-project.org/) - One of the first libraries (if not the first) to embrace Web Components.\n* [Vue](https://vuejs.org/) - We liked the terseness of the `:` and `@` syntax in templates, so we adapted it along with some modifications in our templates.\n","packages/fast-element/docs/api-report.api.md":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport interface AccessCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"access\";\n}\n\n// @public\nexport interface Accessor {\n    getValue(source: any): any;\n    name: string;\n    setValue(source: any, value: any): void;\n}\n\n// @public\nexport type AddViewBehaviorFactory = (factory: ViewBehaviorFactory) => string;\n\n// @public\nexport interface ArrayObserver extends SubscriberSet {\n    addSort(sort: Sort): void;\n    addSplice(splice: Splice): void;\n    flush(): void;\n    readonly lengthObserver: LengthObserver;\n    reset(oldCollection: any[] | undefined): void;\n    readonly sortObserver: SortObserver;\n    strategy: SpliceStrategy | null;\n}\n\n// @public\nexport const ArrayObserver: Readonly<{\n    readonly sorted: 0;\n    readonly enable: () => void;\n}>;\n\n// @public\nexport interface Aspected {\n    aspectType: DOMAspect;\n    dataBinding?: Binding;\n    sourceAspect: string;\n    targetAspect: string;\n}\n\n// @public\nexport function attr(config?: DecoratorAttributeConfiguration): (target: {}, property: string) => void;\n\n// @public\nexport function attr(target: {}, prop: string): void;\n\n// @public\nexport type AttributeConfiguration = {\n    property: string;\n    attribute?: string;\n    mode?: AttributeMode;\n    converter?: ValueConverter;\n};\n\n// @public\nexport const AttributeConfiguration: Readonly<{\n    locate: (target: {}) => AttributeConfiguration[];\n}>;\n\n// @public\nexport class AttributeDefinition implements Accessor {\n    constructor(Owner: Function, name: string, attribute?: string, mode?: AttributeMode, converter?: ValueConverter);\n    readonly attribute: string;\n    // @internal\n    static collect(Owner: Function, ...attributeLists: (ReadonlyArray<string | AttributeConfiguration> | undefined)[]): ReadonlyArray<AttributeDefinition>;\n    readonly converter?: ValueConverter;\n    getValue(source: HTMLElement): any;\n    readonly mode: AttributeMode;\n    readonly name: string;\n    // @internal (undocumented)\n    onAttributeChangedCallback(element: HTMLElement, value: any): void;\n    readonly Owner: Function;\n    setValue(source: HTMLElement, newValue: any): void;\n}\n\n// @public\nexport type AttributeMode = \"reflect\" | \"boolean\" | \"fromView\";\n\n// @public\nexport abstract class Binding<TSource = any, TReturn = any, TParent = any> {\n    constructor(evaluate: Expression<TSource, TReturn, TParent>, policy?: DOMPolicy, isVolatile?: boolean);\n    abstract createObserver(subscriber: Subscriber, directive: BindingDirective): ExpressionObserver<TSource, TReturn, TParent>;\n    evaluate: Expression<TSource, TReturn, TParent>;\n    isVolatile: boolean;\n    options?: any;\n    policy?: DOMPolicy;\n}\n\n// @public\nexport interface BindingDirective {\n    readonly aspectType?: DOMAspect;\n    readonly dataBinding: Binding;\n    readonly targetAspect?: string;\n}\n\n// @public\nexport const booleanConverter: ValueConverter;\n\n// @public\nexport type CachedPath = DefaultCachedPath | RepeatCachedPath | AccessCachedPath | EventCachedPath;\n\n// @public\nexport interface CachedPathCommon {\n    // (undocumented)\n    currentContext: string | null;\n    // (undocumented)\n    parentContext: string | null;\n    // (undocumented)\n    path: string;\n}\n\n// @public\nexport type CachedPathMap = Map<string, Map<string, JSONSchema>>;\n\n// @public\nexport type Callable = typeof Function.prototype.call | {\n    call(): void;\n};\n\n// @public\nexport interface CaptureType<TSource = any, TParent = any> {\n}\n\n// @public\nexport interface ChildListDirectiveOptions<T = any> extends NodeBehaviorOptions<T>, Omit<MutationObserverInit, \"subtree\" | \"childList\"> {\n}\n\n// @public\nexport function children<TSource = any, TParent = any>(propertyOrOptions: (keyof TSource & string) | ChildrenDirectiveOptions<keyof TSource & string>): CaptureType<TSource, TParent>;\n\n// @public\nexport class ChildrenDirective extends NodeObservationDirective<ChildrenDirectiveOptions> {\n    constructor(options: ChildrenDirectiveOptions);\n    disconnect(target: any): void;\n    getNodes(target: Element): Node[];\n    observe(target: any): void;\n}\n\n// @public\nexport type ChildrenDirectiveOptions<T = any> = ChildListDirectiveOptions<T> | SubtreeDirectiveOptions<T>;\n\n// @public\nexport interface ChildrenMap {\n    // (undocumented)\n    attributeName: string;\n    // (undocumented)\n    customElementName: string;\n}\n\n// @public\nexport type Class<T, C = {}> = C & Constructable<T> & {\n    readonly prototype: T;\n};\n\n// @public\nexport type CompilationStrategy = (\nhtml: string | HTMLTemplateElement,\nfactories: Record<string, ViewBehaviorFactory>,\npolicy: DOMPolicy) => HTMLTemplateCompilationResult;\n\n// @public\nexport type CompiledViewBehaviorFactory = Required<ViewBehaviorFactory>;\n\n// @public\nexport const Compiler: {\n    compile<TSource = any, TParent = any>(html: string | HTMLTemplateElement, factories: Record<string, ViewBehaviorFactory>, policy?: DOMPolicy): HTMLTemplateCompilationResult<TSource, TParent>;\n    setDefaultStrategy(strategy: CompilationStrategy): void;\n    aggregate(parts: (string | ViewBehaviorFactory)[], policy?: DOMPolicy): ViewBehaviorFactory;\n};\n\n// @public\nexport type ComposableStyles = string | ElementStyles | CSSStyleSheet;\n\n// @public\nexport function composedContains(reference: HTMLElement, test: HTMLElement): boolean;\n\n// @public\nexport function composedParent<T extends HTMLElement>(element: T): HTMLElement | null;\n\n// @beta\nexport type ComputedBuilder = {\n    on: {\n        setup(callback: ComputedSetupCallback): void;\n    };\n};\n\n// @beta\nexport type ComputedInitializer<T> = (builder: ComputedBuilder) => () => T;\n\n// @beta\nexport type ComputedSetupCallback = () => (() => void) | void;\n\n// @beta\nexport type ComputedState<T> = ReadonlyState<T> & Disposable & {\n    subscribe(subscriber: Subscriber): void;\n    unsubscribe(subscriber: Subscriber): void;\n};\n\n// @beta\nexport function computedState<T>(initialize: ComputedInitializer<T>, name?: string): ComputedState<T>;\n\n// @public\nexport type Constructable<T = {}> = {\n    new (...args: any[]): T;\n};\n\n// @public\nexport type ConstructibleStyleStrategy = {\n    new (styles: (string | CSSStyleSheet)[]): StyleStrategy;\n};\n\n// @public\nexport interface ContentTemplate {\n    create(): ContentView;\n}\n\n// @public\nexport interface ContentView {\n    bind(source: any, context?: ExecutionContext): void;\n    // (undocumented)\n    readonly context: ExecutionContext;\n    insertBefore(node: Node): void;\n    remove(): void;\n    unbind(): void;\n}\n\n// @public\nexport const css: CSSTemplateTag;\n\n// @public\nexport interface CSSDirective {\n    createCSS(): ComposableStyles;\n}\n\n// @public\nexport const CSSDirective: Readonly<{\n    getForInstance: (object: any) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    getByType: (key: Function) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    define<TType extends Constructable<CSSDirective>>(type: any): TType;\n}>;\n\n// @public\nexport function cssDirective(): (type: Constructable<CSSDirective>) => void;\n\n// @public\nexport interface CSSDirectiveDefinition<TType extends Constructable<CSSDirective> = Constructable<CSSDirective>> {\n    readonly type: TType;\n}\n\n// @public\nexport type CSSTemplateTag = ((strings: TemplateStringsArray, ...values: CSSValue[]) => ElementStyles) & {\n    partial(strings: TemplateStringsArray, ...values: CSSValue[]): CSSDirective;\n};\n\n// @public\nexport type CSSValue = ComposableStyles | CSSDirective;\n\n// @public\nexport function customElement(nameOrDef: string | PartialFASTElementDefinition): (type: Constructable<HTMLElement>) => void;\n\n// @public\nexport type DecoratorAttributeConfiguration = Omit<AttributeConfiguration, \"property\">;\n\n// @public\nexport interface DefaultCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"default\";\n}\n\n// @public\nexport class DefaultExecutionContext<TParent> implements ExecutionContext<TParent> {\n    get event(): Event;\n    eventDetail<TDetail>(): TDetail;\n    eventTarget<TTarget extends EventTarget>(): TTarget;\n    index: number;\n    get isEven(): boolean;\n    get isFirst(): boolean;\n    get isInMiddle(): boolean;\n    get isLast(): boolean;\n    get isOdd(): boolean;\n    length: number;\n    readonly parent: TParent;\n    readonly parentContext: ExecutionContext<TParent>;\n}\n\n// @public\nexport interface Disposable {\n    dispose(): void;\n}\n\n// @public\nexport const DOM: Readonly<{\n    readonly policy: DOMPolicy;\n    setPolicy(value: DOMPolicy): void;\n    setAttribute(element: HTMLElement, attributeName: string, value: any): void;\n    setBooleanAttribute(element: HTMLElement, attributeName: string, value: boolean): void;\n}>;\n\n// @public\nexport const DOMAspect: Readonly<{\n    readonly none: 0;\n    readonly attribute: 1;\n    readonly booleanAttribute: 2;\n    readonly property: 3;\n    readonly content: 4;\n    readonly tokenList: 5;\n    readonly event: 6;\n}>;\n\n// @public\nexport type DOMAspect = (typeof DOMAspect)[Exclude<keyof typeof DOMAspect, \"none\">];\n\n// @public\nexport type DOMAspectGuards = {\n    [DOMAspect.attribute]?: DOMSinkGuards;\n    [DOMAspect.booleanAttribute]?: DOMSinkGuards;\n    [DOMAspect.property]?: DOMSinkGuards;\n    [DOMAspect.content]?: DOMSinkGuards;\n    [DOMAspect.tokenList]?: DOMSinkGuards;\n    [DOMAspect.event]?: DOMSinkGuards;\n};\n\n// @public\nexport type DOMElementGuards = Record<string, DOMAspectGuards>;\n\n// @public\nexport type DOMGuards = {\n    elements: DOMElementGuards;\n    aspects: DOMAspectGuards;\n};\n\n// @public\nexport interface DOMPolicy {\n    createHTML(value: string): string;\n    protect(tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink): DOMSink;\n}\n\n// @public\nexport const DOMPolicy: Readonly<{\n    create(options?: DOMPolicyOptions): Readonly<DOMPolicy>;\n}>;\n\n// @public\nexport type DOMPolicyOptions = {\n    trustedType?: TrustedTypesPolicy;\n    guards?: Partial<DOMGuards>;\n};\n\n// @public\nexport type DOMSink = (target: Node, aspectName: string, value: any, ...args: any[]) => void;\n\n// @public\nexport type DOMSinkGuards = Record<string, (tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink) => DOMSink>;\n\n// @public\nexport class ElementController<TElement extends HTMLElement = HTMLElement> implements Notifier, HostController<TElement> {\n    // @internal\n    constructor(element: TElement, definition: FASTElementDefinition);\n    addBehavior(behavior: HostBehavior<TElement>): void;\n    addStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    protected behaviors: Map<HostBehavior<TElement>, number> | null;\n    protected bindObservables(): void;\n    protected captureBoundObservables(): void;\n    connect(): void;\n    protected connectBehaviors(): void;\n    get context(): ExecutionContext;\n    readonly definition: FASTElementDefinition;\n    disconnect(): void;\n    protected disconnectBehaviors(): void;\n    emit(type: string, detail?: any, options?: Omit<CustomEventInit, \"detail\">): void | boolean;\n    static forCustomElement(element: HTMLElement, override?: boolean): ElementController;\n    protected hasExistingShadowRoot: boolean;\n    // @internal\n    static installHydrationHook(hook: (controller: ElementController, template: ElementViewTemplate, element: HTMLElement, host: Node) => boolean): void;\n    get isBound(): boolean;\n    get isConnected(): boolean;\n    readonly isHydrated: Promise<boolean>;\n    readonly isPrerendered: Promise<boolean>;\n    get mainStyles(): ElementStyles | null;\n    set mainStyles(value: ElementStyles | null);\n    protected needsInitialization: boolean;\n    notify(args: any): void;\n    protected observeLateAttributes(): void;\n    onAttributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;\n    onUnbind(behavior: {\n        unbind(controller: ExpressionController<TElement>): any;\n    }): void;\n    removeBehavior(behavior: HostBehavior<TElement>, force?: boolean): void;\n    removeStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    protected renderTemplate(template: ElementViewTemplate | null | undefined): void;\n    static setStrategy(strategy: ElementControllerStrategy): void;\n    get shadowOptions(): ShadowRootOptions | undefined;\n    set shadowOptions(value: ShadowRootOptions | undefined);\n    readonly source: TElement;\n    get sourceLifetime(): SourceLifetime | undefined;\n    protected stage: Stages;\n    get subject(): TElement;\n    subscribe(subscriber: Subscriber, propertyToWatch?: any): void;\n    protected syncLateAttributes(): void;\n    get template(): ElementViewTemplate<TElement> | null;\n    set template(value: ElementViewTemplate<TElement> | null);\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: any): void;\n    readonly view: ElementView<TElement> | null;\n}\n\n// @public\nexport interface ElementControllerStrategy {\n    // (undocumented)\n    new (element: HTMLElement, definition: FASTElementDefinition): ElementController;\n}\n\n// @public\nexport const elements: (selector?: string) => ElementsFilter;\n\n// @public\nexport type ElementsFilter = (value: Node, index?: number, array?: Node[]) => boolean;\n\n// @public\nexport class ElementStyles {\n    constructor(styles: ReadonlyArray<ComposableStyles>);\n    // @internal (undocumented)\n    addStylesTo(target: StyleTarget): void;\n    // @internal (undocumented)\n    isAttachedTo(target: StyleTarget): boolean;\n    static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;\n    // @internal (undocumented)\n    removeStylesFrom(target: StyleTarget): void;\n    static setDefaultStrategy(Strategy: ConstructibleStyleStrategy): void;\n    get strategy(): StyleStrategy;\n    // (undocumented)\n    readonly styles: ReadonlyArray<ComposableStyles>;\n    static readonly supportsAdoptedStyleSheets: boolean;\n    withStrategy(Strategy: ConstructibleStyleStrategy): this;\n}\n\n// @public\nexport interface ElementView<TSource = any, TParent = any> extends View<TSource, TParent> {\n    appendTo(node: Node): void;\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): any;\n    }): void;\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface ElementViewTemplate<TSource = any, TParent = any> {\n    create(hostBindingTarget: Element): ElementView<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): ElementView<TSource, TParent>;\n}\n\n// @public\nexport const emptyArray: readonly never[];\n\n// @public\nexport function enableDebug(): void;\n\n// @public\nexport interface EventCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"event\";\n}\n\n// @public\nexport interface ExecutionContext<TParent = any> {\n    readonly event: Event;\n    eventDetail<TDetail>(): TDetail;\n    eventTarget<TTarget extends EventTarget>(): TTarget;\n    index: number;\n    readonly isEven: boolean;\n    readonly isFirst: boolean;\n    readonly isInMiddle: boolean;\n    readonly isLast: boolean;\n    readonly isOdd: boolean;\n    length: number;\n    parent: TParent;\n    parentContext: ExecutionContext<TParent>;\n}\n\n// @public\nexport const ExecutionContext: Readonly<{\n    default: ExecutionContext;\n    getEvent(): Event | null;\n    setEvent(event: Event | null): void;\n}>;\n\n// @public\nexport type Expression<TSource = any, TReturn = any, TParent = any> = (source: TSource, context: ExecutionContext<TParent>) => TReturn;\n\n// @public\nexport interface ExpressionController<TSource = any, TParent = any> {\n    readonly context: ExecutionContext<TParent>;\n    readonly isBound: boolean;\n    onUnbind(behavior: {\n        unbind(controller: ExpressionController<TSource, TParent>): any;\n    }): void;\n    readonly source: TSource;\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface ExpressionNotifier<TSource = any, TReturn = any, TParent = any> extends Notifier, ExpressionObserver<TSource, TReturn, TParent>, Disposable {\n    observe(source: TSource, context?: ExecutionContext): TReturn;\n    records(): IterableIterator<ObservationRecord>;\n    setMode(isAsync: boolean): void;\n}\n\n// @public\nexport interface ExpressionObserver<TSource = any, TReturn = any, TParent = any> {\n    bind(controller: ExpressionController<TSource, TParent>): TReturn;\n}\n\n// @public\nexport const FAST: {\n    warn(_code: number, _values?: Record<string, any>): void;\n    error(code: number, _values?: Record<string, any>): Error;\n    addMessages(messages: Record<number, string>): void;\n};\n\n// @public\nexport interface FASTElement extends HTMLElement {\n    $emit(type: string, detail?: any, options?: Omit<CustomEventInit, \"detail\">): boolean | void;\n    readonly $fastController: ElementController;\n    attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;\n    connectedCallback(): void;\n    disconnectedCallback(): void;\n}\n\n// @public\nexport const FASTElement: FASTElementConstructor;\n\n// @public\nexport interface FASTElementConstructor {\n    new (): FASTElement;\n    define<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(this: TType, nameOrDef: string | PartialFASTElementDefinition<TType>, extensions?: FASTElementExtension[]): Promise<TType>;\n    define<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition<TType>, extensions?: FASTElementExtension[]): Promise<TType>;\n    from<TBase extends typeof HTMLElement>(BaseType: TBase): {\n        new (): InstanceType<TBase> & FASTElement;\n    };\n}\n\n// @public\nexport class FASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributeLookup: Record<string, AttributeDefinition>;\n    readonly attributes: ReadonlyArray<AttributeDefinition>;\n    static compose<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition<TType>): Promise<FASTElementDefinition<TType>>;\n    define(registry?: CustomElementRegistry, extensions?: FASTElementExtension[]): this;\n    readonly elementOptions: ElementDefinitionOptions;\n    static readonly getByType: (key: Function) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    static readonly getForInstance: (object: any) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    get isDefined(): boolean;\n    readonly name: string;\n    readonly propertyLookup: Record<string, AttributeDefinition>;\n    // @internal\n    static registerBaseType(type: Function): void;\n    readonly registry: CustomElementRegistry;\n    schema?: Schema;\n    shadowOptions?: ShadowRootOptions;\n    readonly styles?: ElementStyles;\n    template?: ElementViewTemplate<InstanceType<TType>>;\n    readonly type: TType;\n}\n\n// @public\nexport type FASTElementExtension = (definition: FASTElementDefinition) => void;\n\n// @public\nexport interface FASTElementRegistry extends TypeRegistry<FASTElementDefinition> {\n    whenRegistered(name: string, registry?: CustomElementRegistry): Promise<FASTElementDefinition>;\n}\n\n// @public\nexport const fastElementRegistry: FASTElementRegistry;\n\n// @public\nexport type FASTElementTemplateResolver<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> = (definition: FASTElementDefinition<TType>) => ElementViewTemplate<InstanceType<TType>> | Promise<ElementViewTemplate<InstanceType<TType>>>;\n\n// @public\nexport interface HostBehavior<TSource = any> {\n    addedCallback?(controller: HostController<TSource>): void;\n    connectedCallback?(controller: HostController<TSource>): void;\n    disconnectedCallback?(controller: HostController<TSource>): void;\n    removedCallback?(controller: HostController<TSource>): void;\n}\n\n// @public\nexport interface HostController<TSource = any> extends ExpressionController<TSource> {\n    addBehavior(behavior: HostBehavior<TSource>): void;\n    addStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    readonly isConnected: boolean;\n    mainStyles: ElementStyles | null;\n    removeBehavior(behavior: HostBehavior<TSource>, force?: boolean): void;\n    removeStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n}\n\n// @public\nexport const html: HTMLTemplateTag;\n\n// @public\nexport class HTMLBindingDirective implements HTMLDirective, ViewBehaviorFactory, ViewBehavior, Aspected, BindingDirective {\n    constructor(dataBinding: Binding);\n    aspectType: DOMAspect;\n    // @internal\n    bind(controller: ViewController): void;\n    createBehavior(): ViewBehavior;\n    createHTML(add: AddViewBehaviorFactory): string;\n    dataBinding: Binding;\n    // @internal\n    handleChange(binding: Expression, observer: ExpressionObserver): void;\n    // @internal\n    handleEvent(event: Event): void;\n    id: string;\n    policy: DOMPolicy;\n    sourceAspect: string;\n    targetAspect: string;\n    targetNodeId: string;\n    targetTagName: string | null;\n    // @internal (undocumented)\n    unbind(controller: ViewController): void;\n}\n\n// @public\nexport interface HTMLDirective {\n    createHTML(add: AddViewBehaviorFactory): string;\n}\n\n// @public\nexport const HTMLDirective: Readonly<{\n    getForInstance: (object: any) => HTMLDirectiveDefinition<Constructable<HTMLDirective>> | undefined;\n    getByType: (key: Function) => HTMLDirectiveDefinition<Constructable<HTMLDirective>> | undefined;\n    define<TType extends Constructable<HTMLDirective>>(type: TType, options?: PartialHTMLDirectiveDefinition): TType;\n    assignAspect(directive: Aspected, value?: string): void;\n}>;\n\n// @public\nexport function htmlDirective(options?: PartialHTMLDirectiveDefinition): (type: Constructable<HTMLDirective>) => void;\n\n// @public\nexport interface HTMLDirectiveDefinition<TType extends Constructable<HTMLDirective> = Constructable<HTMLDirective>> extends Required<PartialHTMLDirectiveDefinition> {\n    readonly type: TType;\n}\n\n// @public\nexport interface HTMLTemplateCompilationResult<TSource = any, TParent = any> {\n    createView(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    // (undocumented)\n    readonly factories: CompiledViewBehaviorFactory[];\n}\n\n// @public\nexport type HTMLTemplateTag = (<TSource = any, TParent = any>(strings: TemplateStringsArray, ...values: TemplateValue<TSource, TParent>[]) => ViewTemplate<TSource, TParent>) & {\n    partial(html: string): InlineTemplateDirective;\n};\n\n// @public\nexport class HTMLView<TSource = any, TParent = any> extends DefaultExecutionContext<TParent> implements ElementView<TSource, TParent>, SyntheticView<TSource, TParent>, ExecutionContext<TParent> {\n    constructor(fragment: DocumentFragment, factories: ReadonlyArray<CompiledViewBehaviorFactory>, targets: ViewBehaviorTargets);\n    appendTo(node: Node): void;\n    bind(source: TSource, context?: ExecutionContext<TParent>): void;\n    context: ExecutionContext<TParent>;\n    dispose(): void;\n    static disposeContiguousBatch(views: SyntheticView[]): void;\n    firstChild: Node;\n    insertBefore(node: Node): void;\n    isBound: boolean;\n    isHydrated: Promise<boolean>;\n    isPrerendered: Promise<boolean>;\n    lastChild: Node;\n    // (undocumented)\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): void;\n    }): void;\n    remove(): void;\n    // @internal\n    _skipAttrUpdates: boolean;\n    source: TSource | null;\n    readonly sourceLifetime: SourceLifetime;\n    // (undocumented)\n    readonly targets: ViewBehaviorTargets;\n    unbind(): void;\n}\n\n// @public\nexport class InlineTemplateDirective implements HTMLDirective {\n    constructor(html: string, factories?: Record<string, ViewBehaviorFactory>);\n    createHTML(add: AddViewBehaviorFactory): string;\n    static readonly empty: InlineTemplateDirective;\n}\n\n// @public\nexport interface JSONSchema extends JSONSchemaCommon {\n    // (undocumented)\n    $defs?: Record<string, JSONSchemaDefinition>;\n    // (undocumented)\n    $id: string;\n    // (undocumented)\n    $schema: string;\n}\n\n// @public\nexport interface JSONSchemaCommon {\n    $observe?: boolean;\n    // (undocumented)\n    $ref?: string;\n    // (undocumented)\n    anyOf?: Array<any>;\n    // (undocumented)\n    items?: any;\n    // (undocumented)\n    properties?: any;\n    // (undocumented)\n    type?: string;\n}\n\n// @public\nexport interface JSONSchemaDefinition extends JSONSchemaCommon {\n    // (undocumented)\n    $fast_context: string;\n    // (undocumented)\n    $fast_parent_contexts: Array<string>;\n}\n\n// @public\nexport interface LengthObserver extends Subscriber {\n    length: number;\n}\n\n// @public\nexport function lengthOf<T>(array: readonly T[]): number;\n\n// @public\nexport function listener<T = any>(expression: Expression<T>, options?: AddEventListenerOptions): Binding<T>;\n\n// @public\nexport const Markup: Readonly<{\n    interpolation: (id: string) => string;\n    attribute: (id: string) => string;\n    comment: (id: string) => string;\n}>;\n\n// @public\nexport interface NodeBehaviorOptions<T = any> {\n    filter?: ElementsFilter;\n    property: T;\n}\n\n// @public\nexport abstract class NodeObservationDirective<T extends NodeBehaviorOptions> extends StatelessAttachedAttributeDirective<T> {\n    bind(controller: ViewController): void;\n    protected computeNodes(target: any): Node[];\n    protected abstract disconnect(target: any): void;\n    protected abstract getNodes(target: any): Node[];\n    protected getSource(target: Node): any;\n    get id(): string;\n    set id(value: string);\n    protected abstract observe(target: any): void;\n    targetNodeId: string;\n    unbind(controller: ViewController): void;\n    protected updateTarget(source: any, value: ReadonlyArray<any>): void;\n}\n\n// @public\nexport function normalizeBinding<TSource = any, TReturn = any, TParent = any>(value: Expression<TSource, TReturn, TParent> | Binding<TSource, TReturn, TParent> | {}): Binding<TSource, TReturn, TParent>;\n\n// @public\nexport interface Notifier {\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber, propertyToWatch?: any): void;\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: any): void;\n}\n\n// @public\nexport const nullableBooleanConverter: ValueConverter;\n\n// @public\nexport const nullableNumberConverter: ValueConverter;\n\n// @public\nexport const Observable: Readonly<{\n    setArrayObserverFactory(factory: (collection: any[]) => Notifier): void;\n    getNotifier: <T extends Notifier = Notifier>(source: any) => T;\n    track(source: unknown, propertyName: string): void;\n    trackVolatile(): void;\n    notify(source: unknown, args: any): void;\n    defineProperty(target: {}, nameOrAccessor: string | Accessor): void;\n    getAccessors: (target: {}) => Accessor[];\n    binding<TSource = any, TReturn = any>(expression: Expression<TSource, TReturn>, initialSubscriber?: Subscriber, isVolatileBinding?: boolean): ExpressionNotifier<TSource, TReturn>;\n    isVolatileBinding<TSource = any, TReturn = any>(expression: Expression<TSource, TReturn>): boolean;\n}>;\n\n// @public\nexport function observable(target: {}, nameOrAccessor: string | Accessor): void;\n\n// @public\nexport interface ObservationRecord {\n    propertyName: string;\n    propertySource: any;\n}\n\n// @public\nexport function oneTime<T = any>(expression: Expression<T>, policy?: DOMPolicy): Binding<T>;\n\n// @public\nexport function oneWay<T = any>(expression: Expression<T>, policy?: DOMPolicy, isVolatile?: boolean): Binding<T>;\n\n// @beta\nexport type OwnedState<T> = ReadonlyOwnedState<T> & {\n    set(owner: any, value: T): void;\n    asReadonly(): ReadonlyOwnedState<T>;\n};\n\n// @beta\nexport function ownedState<T>(value: T | (() => T), options?: string | StateOptions): OwnedState<T>;\n\n// @public\nexport const Parser: Readonly<{\n    parse(value: string, factories: Record<string, ViewBehaviorFactory>): (string | ViewBehaviorFactory)[] | null;\n}>;\n\n// @public\nexport interface PartialFASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributes?: (AttributeConfiguration | string)[];\n    readonly elementOptions?: ElementDefinitionOptions;\n    readonly name: string;\n    readonly registry?: CustomElementRegistry;\n    readonly schema?: Schema;\n    readonly shadowOptions?: Partial<ShadowRootOptions> | null;\n    readonly styles?: ComposableStyles | ComposableStyles[];\n    readonly template?: ElementViewTemplate<InstanceType<TType>> | FASTElementTemplateResolver<TType>;\n}\n\n// @public\nexport interface PartialHTMLDirectiveDefinition {\n    aspected?: boolean;\n}\n\n// @public\nexport class PropertyChangeNotifier implements Notifier {\n    constructor(subject: any);\n    notify(propertyName: string): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber, propertyToWatch?: string): void;\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: string): void;\n}\n\n// @beta\nexport function reactive<T>(object: T, deep?: boolean): T;\n\n// @beta\nexport type ReadonlyOwnedState<T> = {\n    (owner: any): T;\n};\n\n// @beta\nexport type ReadonlyState<T> = {\n    (): T;\n    readonly current: T;\n};\n\n// @public\nexport const ref: <TSource = any, TParent = any>(propertyName: keyof TSource & string) => CaptureType<TSource, TParent>;\n\n// @public\nexport class RefDirective extends StatelessAttachedAttributeDirective<string> {\n    bind(controller: ViewController): void;\n    targetNodeId: string;\n}\n\n// @public\nexport interface RegisterPathConfig {\n    // (undocumented)\n    childrenMap: ChildrenMap | null;\n    // (undocumented)\n    pathConfig: CachedPath;\n    // (undocumented)\n    rootPropertyName: string;\n}\n\n// @public\nexport function render<TSource = any, TItem = any, TParent = any>(value?: Expression<TSource, TItem> | Binding<TSource, TItem> | {}, template?: ContentTemplate | string | Expression<TSource, ContentTemplate | string | Node, TParent> | Binding<TSource, ContentTemplate | string | Node, TParent>): CaptureType<TSource, TParent>;\n\n// @public\nexport class RenderBehavior<TSource = any> implements ViewBehavior, Subscriber {\n    constructor(directive: RenderDirective);\n    bind(controller: ViewController): void;\n    // @internal\n    handleChange(source: any, observer: ExpressionObserver): void;\n    unbind(controller: ViewController): void;\n}\n\n// @public\nexport class RenderDirective<TSource = any> implements HTMLDirective, ViewBehaviorFactory, BindingDirective {\n    constructor(dataBinding: Binding<TSource>, templateBinding: Binding<TSource, ContentTemplate>, templateBindingDependsOnData: boolean);\n    createBehavior(): RenderBehavior<TSource>;\n    createHTML(add: AddViewBehaviorFactory): string;\n    // (undocumented)\n    readonly dataBinding: Binding<TSource>;\n    targetNodeId: string;\n    // (undocumented)\n    readonly templateBinding: Binding<TSource, ContentTemplate>;\n    // (undocumented)\n    readonly templateBindingDependsOnData: boolean;\n}\n\n// @public\nexport function repeat<TSource = any, TArray extends ReadonlyArray<any> = ReadonlyArray<any>, TParent = any>(items: Expression<TSource, TArray, TParent> | Binding<TSource, TArray, TParent> | ReadonlyArray<any>, template: Expression<TSource, ViewTemplate<any, TSource>> | Binding<TSource, ViewTemplate<any, TSource>> | ViewTemplate<any, TSource>, options?: RepeatOptions): CaptureType<TSource, TParent>;\n\n// @public\nexport class RepeatBehavior<TSource = any> implements ViewBehavior, Subscriber {\n    constructor(directive: RepeatDirective);\n    bind(controller: ViewController): void;\n    handleChange(source: any, args: Splice[] | Sort[] | ExpressionObserver): void;\n    unbind(): void;\n    // @internal (undocumented)\n    views: SyntheticView[];\n}\n\n// @public\nexport interface RepeatCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"repeat\";\n}\n\n// @public\nexport class RepeatDirective<TSource = any> implements HTMLDirective, ViewBehaviorFactory, BindingDirective {\n    constructor(dataBinding: Binding<TSource>, templateBinding: Binding<TSource, SyntheticViewTemplate>, options: RepeatOptions);\n    createBehavior(): RepeatBehavior<TSource>;\n    createHTML(add: AddViewBehaviorFactory): string;\n    // (undocumented)\n    readonly dataBinding: Binding<TSource>;\n    // (undocumented)\n    readonly options: RepeatOptions;\n    targetNodeId: string;\n    // (undocumented)\n    readonly templateBinding: Binding<TSource, SyntheticViewTemplate>;\n}\n\n// @public\nexport interface RepeatOptions {\n    positioning?: boolean;\n    recycle?: boolean;\n}\n\n// @public\nexport class Schema {\n    constructor(name: string);\n    addPath(config: RegisterPathConfig): void;\n    getRootProperties(): IterableIterator<string>;\n    getSchema(rootPropertyName: string): JSONSchema | null;\n}\n\n// @public\nexport const schemaRegistry: CachedPathMap;\n\n// @public\nexport interface ShadowRootOptions extends ShadowRootInit {\n    // @beta\n    registry?: CustomElementRegistry;\n}\n\n// @public\nexport const Signal: Readonly<{\n    subscribe(signal: string, subscriber: Subscriber): void;\n    unsubscribe(signal: string, subscriber: Subscriber): void;\n    send(signal: string): void;\n}>;\n\n// @public\nexport function signal<T = any>(expression: Expression<T>, options: string | Expression<T>, policy?: DOMPolicy): Binding<T>;\n\n// @public\nexport function slotted<TSource = any, TParent = any>(propertyOrOptions: (keyof TSource & string) | SlottedDirectiveOptions<keyof TSource & string>): CaptureType<TSource, TParent>;\n\n// @public\nexport class SlottedDirective extends NodeObservationDirective<SlottedDirectiveOptions> {\n    disconnect(target: EventSource): void;\n    getNodes(target: HTMLSlotElement): Node[];\n    // @internal (undocumented)\n    handleEvent(event: Event): void;\n    observe(target: EventSource): void;\n}\n\n// @public\nexport interface SlottedDirectiveOptions<T = any> extends NodeBehaviorOptions<T>, AssignedNodesOptions {\n}\n\n// @public\nexport class Sort {\n    constructor(sorted?: number[] | undefined);\n    // (undocumented)\n    sorted?: number[] | undefined;\n}\n\n// @public\nexport function sortedCount<T>(array: readonly T[]): number;\n\n// @public\nexport interface SortObserver extends Subscriber {\n    sorted: number;\n}\n\n// @public\nexport const SourceLifetime: Readonly<{\n    readonly unknown: undefined;\n    readonly coupled: 1;\n}>;\n\n// @public\nexport type SourceLifetime = (typeof SourceLifetime)[keyof typeof SourceLifetime];\n\n// @public\nexport class Splice {\n    constructor(index: number, removed: any[], addedCount: number);\n    // (undocumented)\n    addedCount: number;\n    adjustTo(array: any[]): this;\n    // (undocumented)\n    index: number;\n    // (undocumented)\n    removed: any[];\n    reset?: boolean;\n}\n\n// @public\nexport interface SpliceStrategy {\n    normalize(previous: unknown[] | undefined, current: unknown[], changes: Splice[] | undefined): readonly Splice[];\n    pop(array: any[], observer: ArrayObserver, pop: typeof Array.prototype.pop, args: any[]): any;\n    push(array: any[], observer: ArrayObserver, push: typeof Array.prototype.push, args: any[]): any;\n    reverse(array: any[], observer: ArrayObserver, reverse: typeof Array.prototype.reverse, args: any[]): any;\n    shift(array: any[], observer: ArrayObserver, shift: typeof Array.prototype.shift, args: any[]): any;\n    sort(array: any[], observer: ArrayObserver, sort: typeof Array.prototype.sort, args: any[]): any[];\n    splice(array: any[], observer: ArrayObserver, splice: typeof Array.prototype.splice, args: any[]): any;\n    readonly support: SpliceStrategySupport;\n    unshift(array: any[], observer: ArrayObserver, unshift: typeof Array.prototype.unshift, args: any[]): any[];\n}\n\n// @public\nexport const SpliceStrategy: Readonly<{\n    readonly reset: Splice[];\n    readonly setDefaultStrategy: (strategy: SpliceStrategy) => void;\n}>;\n\n// @public\nexport const SpliceStrategySupport: Readonly<{\n    readonly reset: 1;\n    readonly splice: 2;\n    readonly optimized: 3;\n}>;\n\n// @public\nexport type SpliceStrategySupport = (typeof SpliceStrategySupport)[keyof typeof SpliceStrategySupport];\n\n// @public\nexport const enum Stages {\n    connected = 1,\n    connecting = 0,\n    disconnected = 3,\n    disconnecting = 2\n}\n\n// @beta\nexport type State<T> = ReadonlyState<T> & {\n    current: T;\n    set(value: T): void;\n    asReadonly(): ReadonlyState<T>;\n};\n\n// @beta\nexport function state<T>(value: T, options?: string | StateOptions): State<T>;\n\n// @public\nexport abstract class StatelessAttachedAttributeDirective<TOptions> implements HTMLDirective, ViewBehaviorFactory, ViewBehavior {\n    constructor(options: TOptions);\n    abstract bind(controller: ViewController): void;\n    createBehavior(): ViewBehavior;\n    createHTML(add: AddViewBehaviorFactory): string;\n    // (undocumented)\n    protected options: TOptions;\n}\n\n// @beta\nexport type StateOptions = {\n    deep?: boolean;\n    name?: string;\n};\n\n// @public\nexport interface StyleStrategy {\n    addStylesTo(target: StyleTarget): void;\n    removeStylesFrom(target: StyleTarget): void;\n}\n\n// @public\nexport interface StyleTarget extends Pick<Node, \"getRootNode\"> {\n    adoptedStyleSheets?: CSSStyleSheet[];\n    append(styles: HTMLStyleElement): void;\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\n    removeChild(styles: HTMLStyleElement): void;\n}\n\n// @public\nexport interface Subscriber {\n    handleChange(subject: any, args: any): void;\n}\n\n// @public\nexport class SubscriberSet implements Notifier {\n    constructor(subject: any, initialSubscriber?: Subscriber);\n    has(subscriber: Subscriber): boolean;\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber): void;\n    unsubscribe(subscriber: Subscriber): void;\n}\n\n// @public\nexport interface SubtreeDirectiveOptions<T = any> extends NodeBehaviorOptions<T>, Omit<MutationObserverInit, \"subtree\" | \"childList\"> {\n    selector: string;\n    subtree: boolean;\n}\n\n// @public\nexport interface SyntheticView<TSource = any, TParent = any> extends View<TSource, TParent> {\n    readonly firstChild: Node;\n    insertBefore(node: Node): void;\n    readonly lastChild: Node;\n    remove(): void;\n}\n\n// @public\nexport interface SyntheticViewTemplate<TSource = any, TParent = any> {\n    create(): SyntheticView<TSource, TParent>;\n    inline(): CaptureType<TSource, TParent>;\n}\n\n// @public\nexport type TemplateValue<TSource, TParent = any> = Expression<TSource, any, TParent> | Binding<TSource, any, TParent> | HTMLDirective | CaptureType<TSource, TParent>;\n\n// @public\nexport type TrustedTypesPolicy = {\n    createHTML(html: string): string;\n};\n\n// @public\nexport function twoWay<T = any>(expression: Expression<T>, optionsOrChangeEvent?: TwoWayBindingOptions | string, policy?: DOMPolicy, isBindingVolatile?: boolean): Binding<T>;\n\n// @public\nexport type TwoWayBindingOptions = {\n    changeEvent?: string;\n    fromView?: (value: any) => any;\n};\n\n// @public\nexport interface TwoWaySettings {\n    determineChangeEvent(bindingSource: BindingDirective, target: HTMLElement): string;\n}\n\n// @public\nexport const TwoWaySettings: Readonly<{\n    configure(settings: TwoWaySettings): void;\n}>;\n\n// @public\nexport interface TypeDefinition {\n    type: Function;\n}\n\n// @public\nexport interface TypeRegistry<TDefinition extends TypeDefinition> {\n    getByType(key: Function): TDefinition | undefined;\n    getForInstance(object: any): TDefinition | undefined;\n    register(definition: TDefinition): boolean;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"UnobservableMutationObserver\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal\nexport class UnobservableMutationObserver extends MutationObserver {\n    constructor(callback: MutationCallback);\n    // (undocumented)\n    observe(target: Node, options?: MutationObserverInit | undefined): void;\n    // (undocumented)\n    unobserve(target: Node): void;\n}\n\n// @public\nexport interface UpdateQueue {\n    enqueue(callable: Callable): void;\n    next(): Promise<void>;\n    process(): void;\n    setMode(isAsync: boolean): void;\n}\n\n// @public\nexport const Updates: UpdateQueue;\n\n// @public\nexport interface ValueConverter {\n    fromView(value: any): any;\n    toView(value: any): any;\n}\n\n// @public\nexport interface View<TSource = any, TParent = any> extends Disposable {\n    bind(source: TSource, context?: ExecutionContext<TParent>): void;\n    readonly context: ExecutionContext<TParent>;\n    readonly isBound: boolean;\n    readonly source: TSource | null;\n    unbind(): void;\n}\n\n// @public\nexport interface ViewBehavior<TSource = any, TParent = any> {\n    bind(controller: ViewController<TSource, TParent>): void;\n}\n\n// @public\nexport interface ViewBehaviorFactory {\n    createBehavior(): ViewBehavior;\n    id?: string;\n    policy?: DOMPolicy;\n    targetNodeId?: string;\n    targetTagName?: string | null;\n}\n\n// @public\nexport interface ViewBehaviorOrchestrator<TSource = any, TParent = any> extends ViewController<TSource, TParent>, HostBehavior<TSource> {\n    addBehavior(behavior: ViewBehavior): void;\n    addBehaviorFactory(factory: ViewBehaviorFactory, target: Node): void;\n    // (undocumented)\n    addTarget(nodeId: string, target: Node): void;\n}\n\n// @public\nexport const ViewBehaviorOrchestrator: Readonly<{\n    create<TSource = any, TParent = any>(source: TSource): ViewBehaviorOrchestrator<TSource, TParent>;\n}>;\n\n// @public\nexport type ViewBehaviorTargets = {\n    [id: string]: Node;\n};\n\n// @public\nexport interface ViewController<TSource = any, TParent = any> extends ExpressionController<TSource, TParent> {\n    readonly isHydrated?: Promise<boolean>;\n    readonly isPrerendered?: Promise<boolean>;\n    // @internal\n    readonly _skipAttrUpdates?: boolean;\n    readonly targets: ViewBehaviorTargets;\n}\n\n// @public\nexport class ViewTemplate<TSource = any, TParent = any> implements ElementViewTemplate<TSource, TParent>, SyntheticViewTemplate<TSource, TParent> {\n    constructor(html: string | HTMLTemplateElement, factories?: Record<string, ViewBehaviorFactory>, policy?: DOMPolicy | undefined);\n    // @internal (undocumented)\n    compile(): HTMLTemplateCompilationResult<TSource, TParent>;\n    create(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    static create<TSource = any, TParent = any>(strings: string[], values: TemplateValue<TSource, TParent>[], policy?: DOMPolicy): ViewTemplate<TSource, TParent>;\n    readonly factories: Record<string, ViewBehaviorFactory>;\n    readonly html: string | HTMLTemplateElement;\n    inline(): CaptureType<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    withPolicy(policy: DOMPolicy): this;\n}\n\n// @public\nexport function volatile(target: {}, name: string | Accessor, descriptor: PropertyDescriptor): PropertyDescriptor;\n\n// @beta\nexport function watch(object: any, subscriber: Subscriber | ((subject: any, args: any) => void)): Disposable;\n\n// @public\nexport function when<TSource = any, TReturn = any, TParent = any>(condition: Expression<TSource, TReturn, TParent> | boolean, templateOrTemplateBinding: SyntheticViewTemplate<TSource, TParent> | Expression<TSource, SyntheticViewTemplate<TSource, TParent>, TParent>, elseTemplateOrTemplateBinding?: SyntheticViewTemplate<TSource, TParent> | Expression<TSource, SyntheticViewTemplate<TSource, TParent>, TParent>): CaptureType<TSource, TParent>;\n\n```\n","packages/fast-element/docs/architecture/fastelement.md":"# FASTElement\n\nThe `FASTElement` is our extension of the `HTMLElement`. As such it leverages the lifecycles but also requires additional setup before before the class `constructor` or the `connectedCallback` method is executed which are explained in the [overview](./overview.md). This document explains specifically what `FASTElement` leverages inside the `HTMLElement`s lifecycle hooks.\n\nFor an explanation into `HTMLElement` lifecycle hooks refer to the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks).\n\nBecause `FASTElement` extends `HTMLElement`, it is a browser `Window` runtime\nAPI. It is not intended to execute in workers, server-side JavaScript runtimes,\nor other non-window hosts where custom element lifecycle callbacks and animation\nframe scheduling are unavailable.\n\n## A Custom Element is Detected by the Browser\n\nBecause the `FASTElement` is an extension of the `HTMLElement`, it makes use of the same lifecycle hooks and extends them with `$fastController`. It also initializes using another class `ElementController`, the methods this are called during the custom elements native `constructor`, `connectedCallback`, `disconnectedCallback`, and `attributeChangedCallback` lifecycle hooks.\n\n### 🔄 **Lifecycle**: Initialization\n\n```mermaid\nflowchart TD\n    A[A <code>FASTElement</code> web component is added to the <code>DOM</code>] --> B\n    B[<code>FASTElement</code> initializes the <code>ElementController.forCustomElement</code> passing the Custom Element instance] --> C\n    B --> F[Observables applied to the <code>FASTElement</code> are updated on the FAST global without values]\n    C{Is an <code>ElementController</code> available?}\n    C --> |yes|E\n    C --> |no|D\n    D[Initialize a new <code>ElementController</code> referred to as setting an element controller strategy]\n    D --> F\n    E[<code>ElementController</code> captures the Custom Element instance and the definition and attaches them to the <code>$fastController</code> which is then attached to the instance]\n```\n\n### 🔄 **Lifecycle**: Component is connected\n\n```mermaid\nflowchart TD\n    A[browser <code>HTMLElement</code>'s <code>connectedCallback</code> is called] --> B\n    B[<code>this.$fastController.connect</code> in FASTElement is called] --> C\n    B --> D\n    B --> E\n    B --> F\n    C[bind observables by capturing public own Custom Element properties and setting those values through the matching accessors]\n    D[connect behaviors by call the <code>connectedCallback</code> on all behaviors]\n    E[render template, execute an <code>ElementViewTemplate</code>'s render method]\n    F[add styles either as an appended <code>StyleElement</code> node or an <code>adoptedStylesheet</code> which may include and attach behaviors]\n```\n\n#### Render Template\n\nThe rendering of the template on the `ElementController` is by the `renderTemplate` method which is called during the `ElementController.connect` method which is triggered by `HTMLElement`s `connectedCallback` lifecycle.\n\nThe `renderTemplate` identifies the Custom Element, and the shadow root associated with the Custom Element. This then places a rendering of the template (an `ElementView`) onto the internal `view` of the controller. When creating the `ElementView`/`HTMLView` using the `ViewTemplate.render`, the `Compiler.compile()` method identifies a `DocumentFragment` either by using an existing `<template>` tag, or creating one to wrap the contents of the shadow root. A new `CompilationContext` is created and the `compileAttributes` function is called, this results in the replacement of the placeholder attributes initally set-up during the pre-render step with their values if a value has been assigned. The factories with the associated nodes identified are then passed to the context. The view then binds all behaviors to the source element. The `CompilationContext.createView` is executed with the `DocumentFragment` as the root, and returns an `HTMLView`. This `HTMLView` includes an `appendTo` method to attach the fragment to the host element, which it then does. It should be noted that the compiled HTML is a `string`, which when set on the `DocumentFragment` as `innerHTML`, this allows the browser to dictate the creation of HTML nodes.\n\n### 🔄 **Lifecycle**: Component is disconnected\n\nWhen a component is disconnected, a cleanup step is created to remove associated behaviors.\n\n### 🔄 **Lifecycle**: Attribute has been changed\n\nAttributes have an `AttributeDefinition` which allows for converters, attachment of the `<attributName>Changed` aspect of the `@attr` decorator among other capabilities.\n\n```mermaid\nflowchart TD\n    A[The browser <code>HTMLElement</code>'s <code>attributeChangedCallback</code> is called] --> B\n    B[<code>this.$fastController.onAttributeChangedCallback</code> in <code>FASTElement</code> is called] --> C\n    C[calls the attribute definitions <code>onAttributeChangedCallback</code> method with the updated value] --> D\n    D[An <code>Updates.enqueue</code> is called which places the update in the task queue which is then executed, these are performed async unless otherwise specified]\n```\n\nThese changes are observed and similar to the way `Observables` work, they utilize an `Accessor` pattern which has a `getValue` and `setValue` in which DOM updates are applied.\n\nObservable backing slots such as `_foo` are FAST-owned internal state. The\ncontroller's connection-time observable binding only replays public own\nproperties that shadow prototype accessors; it does not normalize backing slots\ninto public property assignments. This keeps attribute converter output in its\nalready-converted model form while preserving pre-upgrade public property\nassignments and opt-in extension behavior.","packages/fast-element/docs/architecture/html-tagged-template-literal.md":"# `html` tagged template literal\n\nThe `html` export from `@microsoft/fast-element` is used to create the template logic for the custom element.\n\n## Pre-processing the `html` tagged template literal contents\n\nBefore the template can be used it goes through a step to convert it into a `ViewTemplate` which it does via the `ViewTemplate.create()` method. This is then used during the `compose` step, before `FASTElement` is instantiated.\n\nDuring the static `ViewTemplate.create()` method (called by the `html` tag), the following happens for each string:\n- Factories with unique IDs are created for each tag template literal argument (or `TemplateValue`) which matches with the corresponding string\n- A binding is created from the `TemplateValue`\n\nThe `Compiler.compile()` method is called lazily the first time the template is rendered (via `ViewTemplate.compile()`, which is triggered by `ViewTemplate.create()` instance method or `ViewTemplate.render()`).\n\nA resulting string using a `createHTML()` function is produced using the `HTMLDirective`s executed for each factory. The behavior is augmented by the previous string from the `html` tag template which determines the aspect if one exists, these aspects are the `@`, `:`, or other binding aspect attached to attributes.\n\nThe `createHTML()` function utilizes a `Markup` attribute which is assigned to a factory's unique ID. The strings are concatenated and passed to a new `ViewTemplate` with all the factories (empty until one is assigned) that act as a dictionary with the unique IDs as the key to look up each factory once it has been created. The string this creates is injected into a `<template>` as `innerHTML`, which allows the browser to create the nodes and placeholder factory IDs, with the only `DOM` node that is explicitly created being the wrapping `<template>` element.\n\n## Directives\n\nThe `HTMLBindingDirective` applies bindings to items identified as various `TemplateValue`s within the `html` tagged template. The `createHTML` step uses the factory associated with the binding to create strings in the markup using the factory's ID.\n\n```mermaid\nflowchart TD\n    A[A <code>new HTMLBindingDirective</code> is created with a data binding which has a policy, options, <code>createObserver</code>, and an evaluate method assigned to the passed arrow function such as <pre>x => x.foo</pre>]\n    B[<code>oneTime</code> binding passes the corresponding tag template argument, an arrow function]\n    C[<code>oneWay</code> binding passes a copy of the corresponding tag template argument, an arrow function]\n    D[An already specified binding such as a <code>repeat</code> or <code>when</code> directive is passed]\n    A --> B\n    A --> C\n    A --> D\n    E[When a <code>createObserver</code> is called, an <code>Observable.binding</code> is created passing the arrow function to be evaluated and the subscriber to be notified]\n    C --> E\n    F[When a <code>createObserver</code> is called, the instance of the one time binding is returned which includes a bind method returning the arrow function executed against the controller source and context]\n    B --> F\n```\n","packages/fast-element/docs/architecture/intro.md":"# Introduction\n\nThis document (and the linked documents) explains how the exports and side effects of `@microsoft/fast-element` are used to create custom elements.\n\n`@microsoft/fast-element` is designed to run in a client-side browser `Window`\nruntime. Its element lifecycle, rendering, and update queue assume browser DOM,\nCustom Elements, Shadow DOM, and `requestAnimationFrame` are available. Workers,\nserver-side JavaScript runtimes, and other non-window hosts are not supported\ntargets for the FAST Element client runtime.\n\n## Glossary\n\n- [Overview](./overview.md): How the `@microsoft/fast-element` should be used by a developer and what code is executed during the first render.\n- [`FASTElement`](./fastelement.md): How the `FASTElement` is architected.\n- [`html` tagged template literal](./html-tagged-template-literal.md): How the `html` tagged template literal takes and converts the contents into a `ViewTemplate`.\n- [`Updates` queue](./updates.md): How updates to attributes and observables are processed.","packages/fast-element/docs/architecture/overview.md":"# General FAST usage\n\n`FASTElement` is an extension of `HTMLElement` which makes use of Custom Element APIs native to the browser. It also supplies the following methods:\n\n- The `define` method combines the Custom Element name, template, style, and other options into a `FASTElementDefinition`, then uses the native Custom Element [`define()`](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define) to register the Custom Element with a Custom Element Registry.\n- The `from` method allows the use of Customized Built-in elements, which extend from native elements such as `HTMLButtonElement`.\n\n### Creating a Custom Element from FASTElement\n\nA basic developer flow for defining a custom element looks like this:\n\n```mermaid\nflowchart TD\n    A[Create a <code>FASTElement</code> web component by extending the <code>FASTElement</code> class] --> F\n    F[Prepare the definition with template and styles] --> G[Define the component in the browser with <code>define()</code>]\n```\n\nLet's take a look at the definition step to see what the FAST architecture is doing at this stage.\n\n### Defining a Custom Element\n\nThe subclass `define()` method creates a new `FASTElementDefinition`, which includes all metadata needed for the element (such as templates, attributes, and styles), and registers it with the configured Custom Element Registry. The resulting object can be retrieved via `ElementController.definition`.\n\n## A Custom Element in JavaScript is sent to the Browser\n\nLet's step back from defining the Custom Element and consider what is happening when we import from the `@microsoft/fast-element` package.\n\nThe FAST Element client runtime is expected to run in the browser `Window`.\nCustom element definition, connection, rendering, and update scheduling all rely\non browser APIs such as the Custom Element Registry, DOM, Shadow DOM, and\n`requestAnimationFrame`.\n\nFirst, a global `FAST` property will be created if one does not already exist, typically in browser on the `window`.\n\nAdditionally, when Custom Elements are included in a script a few things might happen even before a Custom Element gets detected by the browser. First, there are initial side effects caused by the use of decorators. These include the `attr` decorator from `@microsoft/fast-element` and the `observable` decorator from `@microsoft/fast-element`.\n\nHere is a basic flow of what code is executed and when during initial load of a script that contains a FAST defined Custom Element:\n\n```mermaid\nflowchart TD\n    A@{ shape: circle, label: \"The browser loads the JavaScript file containing FAST and FAST Custom Element definitions\" }\n    B@{ shape: rect, label: \"The FAST global is added to the window\" }\n    A --> B\n    C@{ shape: rect, label: \"A Custom Element executes the <code>compose</code> step\"}\n    B --> C\n    D@{ shape: procs, label: \"<ul style='text-align: left'><li>Any defined observable decorators are added to the FAST global</li><li>An attribute decorator locates the associated Custom Elements constructor which it uses to push itself to the Custom Elements attribute collection</li></ul>\"}\n    C --> D\n    F@{ shape: rect, label: \"An HTML tagged template literal is executed for the FAST Custom Element and applied to the definition\" }\n    D --> F\n    G@{ shape: rect, label: \"The <code>define</code> step is hit and the <code>customElement</code> is registered with the Custom Element Registry\" }\n    F --> G\n    H@{ shape: rect, label: \"A Custom Element is detected on the page and the browser initializes it\" }\n    I@{ shape: dbl-circ, label: \"The lifecycle steps for <code>FASTElement</code> are executed\" }\n    G --> H\n    H --> I\n```\n","packages/fast-element/docs/architecture/updates.md":"# `Updates`\n\nThe `Updates` API batches FAST Element DOM work in the client-side browser\n`Window` runtime. Queued work includes updates to attributes, observables, and\nobserved arrays. The async queue is aligned to `requestAnimationFrame`, which is\nexpected to be available in the supported runtime.\n\nFAST Element is not intended to run its client runtime in workers, server-side\nJavaScript runtimes, or other non-window hosts. Code that needs server rendering\nshould generate HTML for the browser, then let the browser window run FAST\nElement, connect custom elements, and process queued updates.\n\n## Attributes\n\nAn attribute change may be queued when the value of the attribute is updated. This change is triggered by `HTMLElement` lifecycle hook `attributeChangedCallback`. The `Updates` queue is used to try to reflect the attribute with the updated value onto the element using `DOM` APIs.\n\n## Observables\n\nThe `Reflect` API is used to override `defineProperty` in order to observe a property on an Custom Element, this overrides the getter and setter, which allows subscribers to be notified of changes. Any changes which `set` the value are passed to the `Updates` queue.","packages/fast-element/docs/arrays/api-report.api.md":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport interface ArrayObserver extends SubscriberSet {\n    addSort(sort: Sort): void;\n    addSplice(splice: Splice): void;\n    flush(): void;\n    readonly lengthObserver: LengthObserver;\n    reset(oldCollection: any[] | undefined): void;\n    readonly sortObserver: SortObserver;\n    strategy: SpliceStrategy | null;\n}\n\n// @public\nexport const ArrayObserver: Readonly<{\n    readonly sorted: 0;\n    readonly enable: () => void;\n}>;\n\n// @public\nexport interface LengthObserver extends Subscriber {\n    length: number;\n}\n\n// @public\nexport function lengthOf<T>(array: readonly T[]): number;\n\n// @public\nexport interface Notifier {\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber, propertyToWatch?: any): void;\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: any): void;\n}\n\n// @public\nexport class Sort {\n    constructor(sorted?: number[] | undefined);\n    // (undocumented)\n    sorted?: number[] | undefined;\n}\n\n// @public\nexport function sortedCount<T>(array: readonly T[]): number;\n\n// @public\nexport interface SortObserver extends Subscriber {\n    sorted: number;\n}\n\n// @public\nexport class Splice {\n    constructor(index: number, removed: any[], addedCount: number);\n    // (undocumented)\n    addedCount: number;\n    adjustTo(array: any[]): this;\n    // (undocumented)\n    index: number;\n    // (undocumented)\n    removed: any[];\n    reset?: boolean;\n}\n\n// @public\nexport interface SpliceStrategy {\n    normalize(previous: unknown[] | undefined, current: unknown[], changes: Splice[] | undefined): readonly Splice[];\n    pop(array: any[], observer: ArrayObserver, pop: typeof Array.prototype.pop, args: any[]): any;\n    push(array: any[], observer: ArrayObserver, push: typeof Array.prototype.push, args: any[]): any;\n    reverse(array: any[], observer: ArrayObserver, reverse: typeof Array.prototype.reverse, args: any[]): any;\n    shift(array: any[], observer: ArrayObserver, shift: typeof Array.prototype.shift, args: any[]): any;\n    sort(array: any[], observer: ArrayObserver, sort: typeof Array.prototype.sort, args: any[]): any[];\n    splice(array: any[], observer: ArrayObserver, splice: typeof Array.prototype.splice, args: any[]): any;\n    readonly support: SpliceStrategySupport;\n    unshift(array: any[], observer: ArrayObserver, unshift: typeof Array.prototype.unshift, args: any[]): any[];\n}\n\n// @public\nexport const SpliceStrategy: Readonly<{\n    readonly reset: Splice[];\n    readonly setDefaultStrategy: (strategy: SpliceStrategy) => void;\n}>;\n\n// @public\nexport const SpliceStrategySupport: Readonly<{\n    readonly reset: 1;\n    readonly splice: 2;\n    readonly optimized: 3;\n}>;\n\n// @public\nexport type SpliceStrategySupport = (typeof SpliceStrategySupport)[keyof typeof SpliceStrategySupport];\n\n// @public\nexport interface Subscriber {\n    handleChange(subject: any, args: any): void;\n}\n\n// @public\nexport class SubscriberSet implements Notifier {\n    constructor(subject: any, initialSubscriber?: Subscriber);\n    has(subscriber: Subscriber): boolean;\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber): void;\n    unsubscribe(subscriber: Subscriber): void;\n}\n\n// (No @packageDocumentation comment for this package)\n\n```\n","packages/fast-element/docs/context/api-report.api.md":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport type Context<T> = {\n    readonly name: string;\n    readonly initialValue?: T;\n};\n\n// @public\nexport const Context: Readonly<{\n    eventType: \"context-request\";\n    for<T = unknown>(name: string): FASTContext<T>;\n    create<T = unknown>(name: string, initialValue?: T): FASTContext<T>;\n    setDefaultRequestStrategy(strategy: FASTContextRequestStrategy): void;\n    get<T extends UnknownContext>(target: EventTarget, context: T): ContextType<T>;\n    request<T extends UnknownContext>(target: EventTarget, context: T, callback: ContextCallback<ContextType<T>>, multiple?: boolean): void;\n    dispatch<T extends UnknownContext>(target: EventTarget, context: T, callback: ContextCallback<ContextType<T>>, multiple?: boolean): void;\n    provide<T extends UnknownContext>(target: EventTarget, context: T, value: ContextType<T>): void;\n    handle<T extends UnknownContext>(target: EventTarget, callback: (event: ContextEvent<T>) => void, context?: T): void;\n    defineProperty<T extends UnknownContext>(target: Constructable<EventTarget> | EventTarget, propertyName: string, context: T): void;\n}>;\n\n// @public\nexport type ContextCallback<ValueType> = (value: ValueType, dispose?: () => void) => void;\n\n// Warning: (ae-forgotten-export) The symbol \"ParameterDecorator_2\" needs to be exported by the entry point context.d.ts\n//\n// @public\nexport type ContextDecorator<T = any> = Readonly<Context<T>> & PropertyDecorator & ParameterDecorator_2;\n\n// @public\nexport class ContextEvent<T extends UnknownContext> extends Event {\n    constructor(context: T, callback: ContextCallback<ContextType<T>>, multiple?: boolean | undefined);\n    // (undocumented)\n    readonly callback: ContextCallback<ContextType<T>>;\n    // (undocumented)\n    readonly context: T;\n    // (undocumented)\n    readonly multiple?: boolean | undefined;\n}\n\n// @public\nexport type ContextType<T extends UnknownContext> = T extends Context<infer Y> ? Y : never;\n\n// @public\nexport type FASTContext<T> = ContextDecorator<T> & {\n    get(target: EventTarget): T;\n    provide(target: EventTarget, value: T): void;\n    request(target: EventTarget, callback: ContextCallback<T>, multiple?: boolean): void;\n    handle(target: EventTarget, callback: (event: ContextEvent<FASTContext<T>>) => void): void;\n};\n\n// @public\nexport type FASTContextRequestStrategy = <T extends UnknownContext>(target: EventTarget, context: T, callback: ContextCallback<ContextType<T>>, multiple: any) => void;\n\n// @public\nexport type UnknownContext = Context<unknown>;\n\n// Warnings were encountered during analysis:\n//\n// dist/dts/context.d.ts:127:5 - (ae-forgotten-export) The symbol \"Constructable\" needs to be exported by the entry point context.d.ts\n\n// (No @packageDocumentation comment for this package)\n\n```\n","packages/fast-element/docs/declarative/api-report.api.md":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport interface AccessCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"access\";\n}\n\n// @public\nexport interface Accessor {\n    getValue(source: any): any;\n    name: string;\n    setValue(source: any, value: any): void;\n}\n\n// @public\nexport type AttributeConfiguration = {\n    property: string;\n    attribute?: string;\n    mode?: AttributeMode;\n    converter?: ValueConverter;\n};\n\n// @public\nexport const AttributeConfiguration: Readonly<{\n    locate: (target: {}) => AttributeConfiguration[];\n}>;\n\n// @public\nexport class AttributeDefinition implements Accessor {\n    constructor(Owner: Function, name: string, attribute?: string, mode?: AttributeMode, converter?: ValueConverter);\n    readonly attribute: string;\n    // @internal\n    static collect(Owner: Function, ...attributeLists: (ReadonlyArray<string | AttributeConfiguration> | undefined)[]): ReadonlyArray<AttributeDefinition>;\n    readonly converter?: ValueConverter;\n    getValue(source: HTMLElement): any;\n    readonly mode: AttributeMode;\n    readonly name: string;\n    // @internal (undocumented)\n    onAttributeChangedCallback(element: HTMLElement, value: any): void;\n    readonly Owner: Function;\n    setValue(source: HTMLElement, newValue: any): void;\n}\n\n// @public\nexport type AttributeMode = \"reflect\" | \"boolean\" | \"fromView\";\n\n// @public\nexport type CachedPath = DefaultCachedPath | RepeatCachedPath | AccessCachedPath | EventCachedPath;\n\n// @public\nexport interface CachedPathCommon {\n    // (undocumented)\n    currentContext: string | null;\n    // (undocumented)\n    parentContext: string | null;\n    // (undocumented)\n    path: string;\n}\n\n// @public\nexport type CachedPathMap = Map<string, Map<string, JSONSchema>>;\n\n// @public\nexport interface CaptureType<TSource = any, TParent = any> {\n}\n\n// @public\nexport interface ChildrenMap {\n    // (undocumented)\n    attributeName: string;\n    // (undocumented)\n    customElementName: string;\n}\n\n// @public\nexport type ComposableStyles = string | ElementStyles | CSSStyleSheet;\n\n// @public\nexport type Constructable<T = {}> = {\n    new (...args: any[]): T;\n};\n\n// @public\nexport type ConstructibleStyleStrategy = {\n    new (styles: (string | CSSStyleSheet)[]): StyleStrategy;\n};\n\n// @public\nexport function declarativeTemplate<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(): FASTElementTemplateResolver<TType>;\n\n// @public\nexport interface DefaultCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"default\";\n}\n\n// @public\nexport const DOMAspect: Readonly<{\n    readonly none: 0;\n    readonly attribute: 1;\n    readonly booleanAttribute: 2;\n    readonly property: 3;\n    readonly content: 4;\n    readonly tokenList: 5;\n    readonly event: 6;\n}>;\n\n// @public\nexport type DOMAspect = (typeof DOMAspect)[Exclude<keyof typeof DOMAspect, \"none\">];\n\n// @public\nexport type DOMAspectGuards = {\n    [DOMAspect.attribute]?: DOMSinkGuards;\n    [DOMAspect.booleanAttribute]?: DOMSinkGuards;\n    [DOMAspect.property]?: DOMSinkGuards;\n    [DOMAspect.content]?: DOMSinkGuards;\n    [DOMAspect.tokenList]?: DOMSinkGuards;\n    [DOMAspect.event]?: DOMSinkGuards;\n};\n\n// @public\nexport type DOMElementGuards = Record<string, DOMAspectGuards>;\n\n// @public\nexport type DOMGuards = {\n    elements: DOMElementGuards;\n    aspects: DOMAspectGuards;\n};\n\n// @public\nexport interface DOMPolicy {\n    createHTML(value: string): string;\n    protect(tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink): DOMSink;\n}\n\n// @public\nexport const DOMPolicy: Readonly<{\n    create(options?: DOMPolicyOptions): Readonly<DOMPolicy>;\n}>;\n\n// @public\nexport type DOMPolicyOptions = {\n    trustedType?: TrustedTypesPolicy;\n    guards?: Partial<DOMGuards>;\n};\n\n// @public\nexport type DOMSink = (target: Node, aspectName: string, value: any, ...args: any[]) => void;\n\n// @public\nexport type DOMSinkGuards = Record<string, (tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink) => DOMSink>;\n\n// @public\nexport class ElementStyles {\n    constructor(styles: ReadonlyArray<ComposableStyles>);\n    // @internal (undocumented)\n    addStylesTo(target: StyleTarget): void;\n    // @internal (undocumented)\n    isAttachedTo(target: StyleTarget): boolean;\n    static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;\n    // @internal (undocumented)\n    removeStylesFrom(target: StyleTarget): void;\n    static setDefaultStrategy(Strategy: ConstructibleStyleStrategy): void;\n    get strategy(): StyleStrategy;\n    // (undocumented)\n    readonly styles: ReadonlyArray<ComposableStyles>;\n    static readonly supportsAdoptedStyleSheets: boolean;\n    withStrategy(Strategy: ConstructibleStyleStrategy): this;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"View\" needs to be exported by the entry point index.d.ts\n//\n// @public\nexport interface ElementView<TSource = any, TParent = any> extends View<TSource, TParent> {\n    appendTo(node: Node): void;\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): any;\n    }): void;\n    // Warning: (ae-forgotten-export) The symbol \"SourceLifetime\" needs to be exported by the entry point index.d.ts\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface ElementViewTemplate<TSource = any, TParent = any> {\n    create(hostBindingTarget: Element): ElementView<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): ElementView<TSource, TParent>;\n}\n\n// @public\nexport interface EventCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"event\";\n}\n\n// @public\nexport class FASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributeLookup: Record<string, AttributeDefinition>;\n    readonly attributes: ReadonlyArray<AttributeDefinition>;\n    static compose<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition<TType>): Promise<FASTElementDefinition<TType>>;\n    define(registry?: CustomElementRegistry, extensions?: FASTElementExtension[]): this;\n    readonly elementOptions: ElementDefinitionOptions;\n    static readonly getByType: (key: Function) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    static readonly getForInstance: (object: any) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    get isDefined(): boolean;\n    readonly name: string;\n    readonly propertyLookup: Record<string, AttributeDefinition>;\n    // @internal\n    static registerBaseType(type: Function): void;\n    readonly registry: CustomElementRegistry;\n    schema?: Schema;\n    shadowOptions?: ShadowRootOptions;\n    readonly styles?: ElementStyles;\n    template?: ElementViewTemplate<InstanceType<TType>>;\n    readonly type: TType;\n}\n\n// @public\nexport type FASTElementExtension = (definition: FASTElementDefinition) => void;\n\n// @public\nexport type FASTElementTemplateResolver<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> = (definition: FASTElementDefinition<TType>) => ElementViewTemplate<InstanceType<TType>> | Promise<ElementViewTemplate<InstanceType<TType>>>;\n\n// @public\nexport interface HTMLTemplateCompilationResult<TSource = any, TParent = any> {\n    createView(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    // Warning: (ae-forgotten-export) The symbol \"CompiledViewBehaviorFactory\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    readonly factories: CompiledViewBehaviorFactory[];\n}\n\n// Warning: (ae-forgotten-export) The symbol \"DefaultExecutionContext\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"SyntheticView\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"ExecutionContext\" needs to be exported by the entry point index.d.ts\n//\n// @public\nexport class HTMLView<TSource = any, TParent = any> extends DefaultExecutionContext<TParent> implements ElementView<TSource, TParent>, SyntheticView<TSource, TParent>, ExecutionContext<TParent> {\n    constructor(fragment: DocumentFragment, factories: ReadonlyArray<CompiledViewBehaviorFactory>, targets: ViewBehaviorTargets);\n    appendTo(node: Node): void;\n    bind(source: TSource, context?: ExecutionContext<TParent>): void;\n    context: ExecutionContext<TParent>;\n    dispose(): void;\n    static disposeContiguousBatch(views: SyntheticView[]): void;\n    firstChild: Node;\n    insertBefore(node: Node): void;\n    isBound: boolean;\n    isHydrated: Promise<boolean>;\n    isPrerendered: Promise<boolean>;\n    lastChild: Node;\n    // (undocumented)\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): void;\n    }): void;\n    remove(): void;\n    // @internal\n    _skipAttrUpdates: boolean;\n    source: TSource | null;\n    readonly sourceLifetime: SourceLifetime;\n    // Warning: (ae-forgotten-export) The symbol \"ViewBehaviorTargets\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    readonly targets: ViewBehaviorTargets;\n    unbind(): void;\n}\n\n// @public\nexport interface JSONSchema extends JSONSchemaCommon {\n    // (undocumented)\n    $defs?: Record<string, JSONSchemaDefinition>;\n    // (undocumented)\n    $id: string;\n    // (undocumented)\n    $schema: string;\n}\n\n// @public\nexport interface JSONSchemaCommon {\n    $observe?: boolean;\n    // (undocumented)\n    $ref?: string;\n    // (undocumented)\n    anyOf?: Array<any>;\n    // (undocumented)\n    items?: any;\n    // (undocumented)\n    properties?: any;\n    // (undocumented)\n    type?: string;\n}\n\n// @public\nexport interface JSONSchemaDefinition extends JSONSchemaCommon {\n    // (undocumented)\n    $fast_context: string;\n    // (undocumented)\n    $fast_parent_contexts: Array<string>;\n}\n\n// @public\nexport interface PartialFASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributes?: (AttributeConfiguration | string)[];\n    readonly elementOptions?: ElementDefinitionOptions;\n    readonly name: string;\n    readonly registry?: CustomElementRegistry;\n    readonly schema?: Schema;\n    readonly shadowOptions?: Partial<ShadowRootOptions> | null;\n    readonly styles?: ComposableStyles | ComposableStyles[];\n    readonly template?: ElementViewTemplate<InstanceType<TType>> | FASTElementTemplateResolver<TType>;\n}\n\n// @public\nexport interface RegisterPathConfig {\n    // (undocumented)\n    childrenMap: ChildrenMap | null;\n    // (undocumented)\n    pathConfig: CachedPath;\n    // (undocumented)\n    rootPropertyName: string;\n}\n\n// @public\nexport interface RepeatCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"repeat\";\n}\n\n// @public\nexport interface ResolvedStringsAndValues {\n    // (undocumented)\n    strings: Array<string>;\n    // (undocumented)\n    values: Array<any>;\n}\n\n// @public\nexport class Schema {\n    constructor(name: string);\n    addPath(config: RegisterPathConfig): void;\n    getRootProperties(): IterableIterator<string>;\n    getSchema(rootPropertyName: string): JSONSchema | null;\n}\n\n// @public\nexport const schemaRegistry: CachedPathMap;\n\n// @public\nexport interface ShadowRootOptions extends ShadowRootInit {\n    // @beta\n    registry?: CustomElementRegistry;\n}\n\n// @public\nexport interface StyleStrategy {\n    addStylesTo(target: StyleTarget): void;\n    removeStylesFrom(target: StyleTarget): void;\n}\n\n// @public\nexport interface StyleTarget extends Pick<Node, \"getRootNode\"> {\n    adoptedStyleSheets?: CSSStyleSheet[];\n    append(styles: HTMLStyleElement): void;\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\n    removeChild(styles: HTMLStyleElement): void;\n}\n\n// @public\nexport interface SyntheticViewTemplate<TSource = any, TParent = any> {\n    create(): SyntheticView<TSource, TParent>;\n    inline(): CaptureType<TSource, TParent>;\n}\n\n// @public\nexport class TemplateParser {\n    createTemplate(strings: Array<string>, values: Array<any>): ViewTemplate<any, any>;\n    parse(innerHTML: string, schema: Schema): ResolvedStringsAndValues;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"Expression\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"Binding\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"HTMLDirective\" needs to be exported by the entry point index.d.ts\n//\n// @public\nexport type TemplateValue<TSource, TParent = any> = Expression<TSource, any, TParent> | Binding<TSource, any, TParent> | HTMLDirective | CaptureType<TSource, TParent>;\n\n// @public\nexport type TrustedTypesPolicy = {\n    createHTML(html: string): string;\n};\n\n// @public\nexport interface ValueConverter {\n    fromView(value: any): any;\n    toView(value: any): any;\n}\n\n// @public\nexport interface ViewBehavior<TSource = any, TParent = any> {\n    bind(controller: ViewController<TSource, TParent>): void;\n}\n\n// @public\nexport interface ViewBehaviorFactory {\n    createBehavior(): ViewBehavior;\n    id?: string;\n    policy?: DOMPolicy;\n    targetNodeId?: string;\n    targetTagName?: string | null;\n}\n\n// @public\nexport class ViewTemplate<TSource = any, TParent = any> implements ElementViewTemplate<TSource, TParent>, SyntheticViewTemplate<TSource, TParent> {\n    constructor(html: string | HTMLTemplateElement, factories?: Record<string, ViewBehaviorFactory>, policy?: DOMPolicy | undefined);\n    // @internal (undocumented)\n    compile(): HTMLTemplateCompilationResult<TSource, TParent>;\n    create(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    static create<TSource = any, TParent = any>(strings: string[], values: TemplateValue<TSource, TParent>[], policy?: DOMPolicy): ViewTemplate<TSource, TParent>;\n    readonly factories: Record<string, ViewBehaviorFactory>;\n    readonly html: string | HTMLTemplateElement;\n    inline(): CaptureType<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    withPolicy(policy: DOMPolicy): this;\n}\n\n// Warnings were encountered during analysis:\n//\n// dist/dts/templating/view.d.ts:45:9 - (ae-forgotten-export) The symbol \"ViewController\" needs to be exported by the entry point index.d.ts\n\n// (No @packageDocumentation comment for this package)\n\n```\n","packages/fast-element/docs/declarative/design.md":"# Declarative HTML Design\n\nThis document is intended for contributors who want to understand the internal\narchitecture of the declarative runtime and schema-driven map extensions in\n`@microsoft/fast-element`. It covers the feature's purpose, core concepts, data\nflow, and its integration with the rest of `@microsoft/fast-element`.\n\n## Table of Contents\n\n1. [Overview](#overview)\n2. [Goals](#goals)\n3. [Core Concepts](#core-concepts)\n4. [Package Structure](#package-structure)\n5. [Exports and Public API](#exports-and-public-api)\n6. [Template Syntax](#template-syntax)\n7. [Data Flow](#data-flow)\n8. [Template Parsing Pipeline](#template-parsing-pipeline)\n9. [Schema and Observer Map](#schema-and-observer-map)\n10. [Lifecycle](#lifecycle)\n11. [Integration with fast-element](#integration-with-fast-element)\n12. [Hydration Model](#hydration-model)\n13. [Testing Architecture](#testing-architecture)\n14. [Further Reading](#further-reading)\n\n---\n\n## Overview\n\n`@microsoft/fast-element` lets you write FAST Web Component\ntemplates as plain HTML rather than JavaScript `html` tagged template literals.\nThe browser-side JS bundle defines FAST's internal native `<f-template>`\npublisher on demand. It parses declarative template markup at runtime and\nreturns a `ViewTemplate` to the waiting FAST element definition through the\nregistry-aware declarative template bridge.\n\n```html\n<!-- Declarative template — stack-agnostic, no JS needed to render -->\n<my-component greeting=\"Hello\">\n    <template shadowrootmode=\"open\">\n        <!--fe:b-->Hello<!--fe:/b-->\n    </template>\n</my-component>\n\n<!-- Template definition — parsed once by the browser bundle -->\n<f-template name=\"my-component\">\n    <template>{{greeting}}</template>\n</f-template>\n```\n\n---\n\n## Goals\n\n| Goal | Description |\n|---|---|\n| **Server-agnostic rendering** | Templates are plain HTML strings with no dependency on Node.js or any specific SSR framework. |\n| **Progressive enhancement** | Components can be server-rendered and then hydrated client-side without a full re-render. |\n| **FAST parity** | The declarative syntax maps 1-to-1 to FAST Element directive helpers (`repeat`, `when`, `slotted`, `children`, `ref`) exported from `@microsoft/fast-element`. |\n| **Minimal authoring overhead** | Component authors write HTML, not tagged template strings, while retaining full reactive capabilities. |\n\n---\n\n## Core Concepts\n\n### `<f-template>` — the internal template publisher\n\n`<f-template>` is an internal custom element implemented as a lightweight native\n`HTMLElement`. It is defined automatically by `declarativeTemplate()` in the same\n`CustomElementRegistry` as the FAST element definition. Consumers should not\nimport, subclass, or define the implementation directly.\n\nWhen connected to the DOM it:\n\n1. Registers itself with the declarative template bridge using its registry and\n   `name` attribute.\n2. Publishes a template when a matching FAST element definition requests one.\n3. Delegates parsing of the inner `<template>` tag to `TemplateParser`, which\n   converts declarative bindings into FAST `ViewTemplate` strings and values.\n4. Runs definition-scoped schema transforms, such as `attributeMap()` and\n   `observerMap()`, before returning the concrete `ViewTemplate`.\n\nWhen multiple connected `<f-template>` publishers share the same `name`, the\nbridge resolves pending definitions from the first connected publisher and keeps\nthe resolved template stable. Later duplicate publishers do not reassign the\ndefinition template.\n\n### `TemplateParser` — declarative HTML parser\n\nA standalone class that converts declarative HTML template markup into the\n`strings` and `values` arrays that `ViewTemplate.create()` consumes. It is used\nby the internal `<f-template>` publisher but can also be used independently for\nprogrammatic template compilation. The parsing pipeline is fully synchronous —\nno promises are allocated during template resolution. A `StringsAccumulator`\ntracks the running concatenation of preceding HTML, eliminating repeated O(N)\n`join(\"\")` calls at each binding site. `createTemplate()` lazily installs the\ndeclarative runtime's debug messages; hydration support is installed only by\n`enableHydration()`.\n\n### `Schema` — JSON schema builder\n\nBuilt during declarative template parsing, one `Schema` instance per\n`<f-template>`. Non-declarative callers can also create and attach a `Schema`\nmanually. It records every binding path discovered in the template or supplied\nby code and constructs a JSON Schema-compatible data structure. This schema:\n\n- Describes the shape of each root property referenced in the template.\n- Tracks repeat context chains (parent/child array relationships).\n- Uses an instance-level `schemaMap` for its own property schemas.\n- Registers itself in the module-level `schemaRegistry` (keyed by custom element name) for cross-element `$ref` resolution.\n\n`FASTElementDefinition.schema` is optional. `declarativeTemplate()` assigns it\nautomatically after parsing; manual schema users can pass `schema` in the\ndefinition object.\n\n### `ObserverMap` — automatic observable setup\n\nAn optional layer that uses the `Schema` to automatically:\n\n- Call `Observable.defineProperty()` for every root property on the element prototype.\n- Install property-change handlers that wrap newly assigned objects/arrays in `Proxy` instances.\n- Propagate deep property mutations back through FAST's observable system so bindings re-render.\n\nEnabled via the `observerMap()` definition extension exported from\n`@microsoft/fast-element/observer-map.js`. Calling `observerMap()` without\narguments observes all root properties discovered in the template or supplied\nschema.\n\n#### Path-level observation control\n\nThe `ObserverMapConfig` interface accepts an optional `schema` for\nnon-declarative/manual schema use and an optional `properties` key that maps\nroot property names to a recursive path tree controlling observation\ngranularity:\n\n```typescript\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [\n        observerMap({\n            properties: {\n                user: {\n                    name: true,          // user.name — observed\n                    details: {\n                        age: true,       // user.details.age — observed\n                        history: false,  // user.details.history — NOT observed\n                    },\n                },\n                // root properties not listed here are skipped\n            },\n        }),\n    ],\n);\n```\n\nEach path entry can be:\n- **`true`** — observe this path and all descendants (unless overridden deeper).\n- **`false`** — skip this path and all descendants (unless overridden deeper).\n- **`ObserverMapPathNode`** — an object with an optional `$observe` boolean and child property overrides, allowing alternating opt-in/opt-out to arbitrary depth.\n\nWhen `properties` is omitted, all root properties are observed. When\n`properties` is present but empty (`{ properties: {} }`), no root properties\nare observed.\n\nObserver-map-managed array updates replace the array reference when `deepMerge`\nreceives a new array. This avoids mutating an existing observed array while it\nmay be notifying subscribers and lets repeat bindings observe the new array\nreference. Replaced arrays are wrapped with the schema for the assigned\nproperty, and array observer subscriptions are installed once per array so\nreprocessing does not duplicate accessors or notification work.\n\nFor non-declarative elements, pass a schema directly to `observerMap()`:\n\n```typescript\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-element\");\nschema.addPath({\n    rootPropertyName: \"user\",\n    pathConfig: {\n        type: \"default\",\n        parentContext: null,\n        currentContext: null,\n        path: \"user.name\",\n    },\n    childrenMap: null,\n});\n\nMyElement.define({ name: \"my-element\" }, [observerMap({ schema })]);\n```\n\nThe resolution algorithm walks the schema and configuration tree in parallel:\n1. If `properties` is present and a root property is not listed, it is skipped.\n2. `true`/`false` booleans apply to the entire subtree.\n3. `$observe` on a node object controls the current level; children inherit when unspecified.\n4. Paths in the config but not in the schema are silently ignored (forward-compatible).\n\n### `AttributeMap` — automatic `@attr` definitions\n\nAn optional layer that uses the `Schema` to automatically register `@attr`-style reactive properties for every **leaf binding** in the template — i.e. simple expressions like `{{foo}}` or `id=\"{{foo-bar}}\"` that have no nested properties, no explicit type, and no child element references.\n\n- By default (`attribute-name-strategy: \"camelCase\"`), the binding key is treated as a camelCase property name and the HTML attribute name is derived by converting it to kebab-case (e.g. `{{fooBar}}` → property `fooBar`, attribute `foo-bar`). This matches the build-time `--attribute-name-strategy` option in `@microsoft/fast-build`.\n- When `attribute-name-strategy` is `\"none\"`, the **attribute name** and **property name** are both the binding key exactly as written in the template (e.g. `{{foo-bar}}` → attribute `foo-bar`, property `foo-bar`). No normalization is applied.\n- Because HTML attributes are case-insensitive, binding keys should use lowercase names (optionally dash-separated) when using the `\"none\"` strategy.\n- Properties already decorated with `@attr` or `@observable` are left untouched.\n- `FASTElementDefinition.attributeLookup` is keyed by the HTML attribute name, and `propertyLookup` is keyed by the JS property name so `attributeChangedCallback` correctly delegates to the new `AttributeDefinition`.\n\nEnabled via the `attributeMap()` definition extension exported from\n`@microsoft/fast-element/attribute-map.js`. Calling `attributeMap()` without\narguments uses the default `\"camelCase\"` strategy. To preserve binding keys\nexactly as written, pass `attributeMap({ \"attribute-name-strategy\": \"none\" })`.\nOutside declarative templates, `attributeMap()` uses the optional `schema` on the\nFAST element definition.\n\n### Syntax constants (`syntax.ts`)\n\nAll delimiters used by the parser are defined in a single `Syntax` interface and exported as named constants from `syntax.ts`. This makes the syntax pluggable and easy to audit.\n\n| Constant | Value | Use |\n|---|---|---|\n| `openExpression` / `closeExpression` | `{{` / `}}` | Default (SSR-compatible) binding |\n| `unescapedOpenExpression` / `unescapedCloseExpression` | `{{{` / `}}}` | Raw HTML binding |\n| `clientSideOpenExpression` / `clientSideCloseExpression` | `{` / `}` | Client-only (event / attribute directive) binding |\n| `repeatDirectiveOpen` / `repeatDirectiveClose` | `<f-repeat` / `</f-repeat>` | Repeat directive |\n| `whenDirectiveOpen` / `whenDirectiveClose` | `<f-when` / `</f-when>` | When directive |\n| `attributeDirectivePrefix` | `f-` | Attribute directive prefix |\n| `eventArgAccessor` | `$e` | DOM event argument |\n| `executionContextAccessor` | `$c` | Execution context argument |\n\n---\n\n## Package Structure\n\n```\npackages/fast-element/\n├── src/\n│   ├── components/\n│   │   ├── schema.ts          # Shared Schema class + schemaRegistry\n│   │   └── definition-schema-transforms.ts # Definition-scoped schema transform storage\n│   ├── declarative/\n│       ├── index.ts           # Public declarative entrypoint implementation\n│       ├── interfaces.ts      # Message enum (error codes)\n│       ├── debug.ts           # Human-readable declarative debug messages\n│       ├── template.ts        # declarativeTemplate(), internal <f-template> publisher, lifecycle orchestration\n│       ├── template-bridge.ts # Registry/name bridge between definitions and publishers\n│       ├── template-parser.ts # TemplateParser — converts declarative HTML to ViewTemplate strings/values\n│       ├── observer-map.ts    # observerMap() implementation\n│       ├── attribute-map.ts   # attributeMap() implementation\n│       ├── observer-map-utilities.ts # Shared observer-map helpers\n│       ├── utilities.ts       # Declarative parsing helpers\n│       └── syntax.ts          # Syntax delimiter constants\n│   └── hydration/\n│       ├── markers.ts         # Default 3.x marker reader and marker strategy contract\n│       └── markers-v2.ts      # Opt-in 2.x indexed marker reader\n├── scripts/\n│   └── declarative/           # Fixture build + webui integration scripts\n└── test/\n    └── declarative/fixtures/  # One directory per feature, each with spec + index.html + main.ts\n```\n\n### Module dependency direction\n\nThe default `declarativeTemplate()` path avoids importing optional map\nimplementations. Map helpers attach schema transforms to the definition only\nwhen the consumer passes them as define extensions.\n\n```\ndeclarative/template.ts ──imports──▶ components/definition-schema-transforms.ts (schema transform reads)\ndeclarative/template.ts ──imports──▶ components/schema.ts (Schema)\ndeclarative/attribute-map.ts ──imports──▶ components/definition-schema-transforms.ts (register attribute-map transform)\ndeclarative/observer-map.ts ──imports──▶ components/definition-schema-transforms.ts (register observer-map transform)\ndeclarative/observer-map.ts ──imports──▶ components/schema.ts (Schema types)\ndeclarative/attribute-map.ts ──imports──▶ components/schema.ts (Schema types)\ndeclarative/utilities.ts ──imports──▶ components/schema.ts (schemaRegistry for cross-element $ref resolution)\n```\n\nSchema transforms run in deterministic order. `attributeMap()` runs before\n`observerMap()`, so generated attributes are available to observer mapping.\n\n---\n\n## Exports and Public API\n\n```typescript\nimport {\n    declarativeTemplate,\n    TemplateParser,\n    type ResolvedStringsAndValues,\n} from \"@microsoft/fast-element/declarative.js\";\nimport {\n    Schema,\n    schemaRegistry,\n    type CachedPathMap,\n    type JSONSchema,\n} from \"@microsoft/fast-element/schema.js\";\nimport { type FASTElementExtension } from \"@microsoft/fast-element\";\nimport {\n    attributeMap,\n    type AttributeMapConfig,\n} from \"@microsoft/fast-element/attribute-map.js\";\nimport {\n    observerMap,\n    type ObserverMapConfig,\n    type ObserverMapPathEntry,\n    type ObserverMapPathNode,\n} from \"@microsoft/fast-element/observer-map.js\";\n```\n\nDeclarative template helpers, map helpers, and their configuration types are\navailable from focused path exports.\n\nPrimary declarative exports intended for application code:\n\n| Export | Purpose |\n|---|---|\n| `declarativeTemplate()` | `@microsoft/fast-element/declarative.js` template resolver for subclass `define()` calls; auto-defines the internal `<f-template>` publisher and waits for the matching template. |\n| `TemplateParser` | `@microsoft/fast-element/declarative.js` standalone parser that converts declarative HTML into `ViewTemplate` strings/values. Can be used independently of `<f-template>` for programmatic template compilation. |\n| `Schema` | `@microsoft/fast-element/schema.js` JSON schema builder that records binding paths discovered during template parsing. Each instance owns its own schema map and registers itself in the `schemaRegistry` for cross-element `$ref` resolution. |\n| `schemaRegistry` | `@microsoft/fast-element/schema.js` module-level `Map<string, Map<string, JSONSchema>>` that indexes schemas by custom element name. Used for cross-element lookups (e.g. nested component `$ref` resolution). |\n\nHydration marker selection is available from\n`@microsoft/fast-element/hydration.js`. FAST Element 3.x data-free markers are\nthe default; `enableHydration({ markers: markers_v2 })` opts into the FAST Element 2.x\nindexed marker reader for staged server/client migrations.\n\nPrimary map extension exports:\n\n| Export | Import path | Purpose |\n|---|---|---|\n| `attributeMap()` | `@microsoft/fast-element/attribute-map.js` | Define extension that registers `@attr`-style properties for leaf bindings discovered during parsing or supplied by `definition.schema`. |\n| `observerMap()` | `@microsoft/fast-element/observer-map.js` | Define extension that defines observable root properties and proxy-based deep change tracking from `config.schema`, `definition.schema`, or a declarative template schema. |\n\nThe implementation element class (`<f-template>`), `TemplateElement.config()`,\n`TemplateElement.options()`, `ElementOptions*`, and\n`HydrationLifecycleCallbacks` are not exported from the public declarative\nentrypoint. Use `declarativeTemplate()`, `attributeMap()`, `observerMap()`, and\n`enableHydration()` instead. The `AttributeMap` and `ObserverMap` implementation\nclasses are available for advanced scenarios, but application code should\nnormally use the extension factories.\n\nAdditionally, `@microsoft/fast-element` exports these types:\n\n| Type | Source Module | Purpose |\n|---|---|---|\n| `FASTElementExtension` | `fast-definitions.ts` | Definition extension callback signature used by `attributeMap()` and `observerMap()`. |\n| `JSONSchema` | `components/schema.ts` | JSON Schema interface used by `Schema` for property structure. |\n| `CachedPathMap` | `components/schema.ts` | `Map<string, Map<string, JSONSchema>>` — the shape of the schema registry. |\n\nThe map configuration types are exported from the same map-specific paths:\n\n| Type | Import path | Purpose |\n|---|---|---|\n| `ObserverMapConfig` | `@microsoft/fast-element/observer-map.js` | Configuration object for `observerMap()`; accepts optional `schema` and `properties` keys. |\n| `ObserverMapPathEntry` | `@microsoft/fast-element/observer-map.js` | `boolean \\| ObserverMapPathNode` — a node in the observation path tree. |\n| `ObserverMapPathNode` | `@microsoft/fast-element/observer-map.js` | Object node with optional `$observe` and child property overrides. |\n| `AttributeMapConfig` | `@microsoft/fast-element/attribute-map.js` | Configuration object for `attributeMap()`; accepts `attribute-name-strategy`. |\n\n---\n\n## Template Syntax\n\nThe declarative syntax is a superset of HTML with three binding delimiters:\n\n| Syntax | Example | Behaviour |\n|---|---|---|\n| `{{expr}}` | `{{greeting}}` | SSR-compatible content / attribute binding |\n| `{{{expr}}}` | `{{{rawHtml}}}` | Unescaped HTML (wraps in `<div :innerHTML>`) |\n| `{expr}` | `@click=\"{handleClick($e)}\"` | Client-only binding (events, attribute directives) |\n\n### Directives\n\nBindings and FAST directive markup inside HTML comments are unsupported. The\nstring-based parsers do not reliably exclude comment contents, so commenting out\nbound markup can still affect binding discovery and hydration. See the\n[HTML comment restrictions](./syntax.md#html-comments).\n\n| Directive | Example |\n|---|---|\n| `<f-when value=\"{{expr}}\">` | Conditional rendering |\n| `<f-repeat value=\"{{item in list}}\">` | List rendering |\n| `f-slotted=\"{prop}\"` | Slotted nodes attribute directive |\n| `f-children=\"{prop}\"` | Children attribute directive |\n| `f-ref=\"{prop}\"` | Element ref attribute directive |\n\nFor full syntax reference see [syntax.md](./syntax.md).\n\n---\n\n## Data Flow\n\nThe high-level data flow from authoring to interactive component:\n\n```mermaid\nflowchart TD\n    A[\"Author writes declarative HTML\nusing f-template with binding expressions\"] --> B[\"Server renders hydratable HTML\nwith fe:b comments and data-fe attributes\"]\n    B --> C[Browser loads JS bundle]\n    C --> D[\"MyElement.define called\nwith template: declarativeTemplate()\"]\n    D --> E[\"declarativeTemplate() defines internal f-template\nin the target registry\"]\n    E --> F[\"f-template connects to DOM\n→ registers publisher with bridge\"]\n    F --> G[\"definition requests template\nvia registry + name bridge\"]\n    G --> H[transformInnerHTML normalises HTML entities]\n    H --> I[\"TemplateParser parses bindings/directives\nbuilds Schema, strings, values\"]\n    I --> J[\"Run definition schema transforms\nattributeMap before observerMap\"]\n    J --> K[\"ViewTemplate.create(strings, values)\nreturned to definition\"]\n    K --> L[\"FASTElementDefinition.define\nregisters element with platform\"]\n    L --> M{\"enableHydration() called?\"}\n    M -- yes --> N[\"ElementController hydrates existing DOM\nvia template.hydrate()\"]\n    M -- no --> O[\"ElementController client-side renders\nexisting DSD is not reused\"]\n    N --> P[Interactive component]\n    O --> P\n```\n\n---\n\n## Template Parsing Pipeline\n\nThe internal `<f-template>` publisher orchestrates the pipeline by creating a\n`TemplateParser` instance and delegating all parsing logic to it. The recursive\nparsing context is encapsulated in a `TemplateResolutionContext` object internal\nto the parser, keeping method signatures lean.\n\n### Architecture\n\nThe parsing pipeline is split across two classes plus definition-scoped\ntransforms:\n\n- **Internal `<f-template>` publisher** (`template.ts`) — Custom element\n  lifecycle, registry/name bridge registration, template publication, and\n  schema-transform execution. It is a native `HTMLElement`, not a `FASTElement`.\n- **`TemplateParser`** (`template-parser.ts`) — Synchronous template parser:\n  converts declarative HTML into `strings`/`values` arrays for\n  `ViewTemplate.create()`. Uses a `StringsAccumulator` to track the running\n  previous-string in O(1) per binding site instead of O(N) `join(\"\")` calls.\n  Independently testable without DOM.\n- **Schema transforms** (`definition-options.ts`) — Extension-provided callbacks run\n  after parsing and before `ViewTemplate.create()`. `attributeMap()` runs before\n  `observerMap()`.\n\n```mermaid\nsequenceDiagram\n    participant DOM\n    participant FTE as internal f-template\n    participant TP as TemplateParser\n    participant U as utilities.ts\n    participant S as Schema\n    participant Transforms as schema transforms\n\n    DOM->>FTE: connectedCallback()\n    FTE->>FTE: register publisher with bridge\n    FTE->>FTE: publishTemplate(definition)\n    FTE->>S: new Schema(name)\n    FTE->>U: transformInnerHTML(this.innerHTML)\n    FTE->>TP: parser.parse(innerHTML, schema)\n    loop getNextBehavior(innerHTML)\n        TP->>U: getNextBehavior()\n        U-->>TP: DataBindingBehaviorConfig | TemplateDirectiveBehaviorConfig\n        alt content binding\n            TP->>TP: resolveContentBinding()\n            TP->>TP: resolveAccessBinding()\n            TP->>U: bindingResolver()\n            U->>S: schema.addPath()\n            U-->>TP: (x,c) => value function\n        else attribute binding\n            TP->>TP: resolveAttributeBinding()\n            alt event (@)\n                TP->>TP: resolveEventBinding()\n            else boolean (?)\n                TP->>U: getBooleanBinding() or resolveAccessBinding()\n            else default\n                TP->>TP: resolveAccessBinding()\n            end\n        else attributeDirective (slotted / children / ref)\n            TP->>TP: resolveAttributeDirectiveBinding()\n        else templateDirective (when / repeat)\n            TP->>TP: resolveTemplateDirective()\n            note over TP: recurses into resolveStringsAndValues\n        end\n    end\n    TP-->>FTE: { strings, values }\n    FTE->>Transforms: attributeMap(), then observerMap()\n    FTE->>TP: parser.createTemplate(strings, values)\n    FTE-->>DOM: return ViewTemplate to definition resolver\n```\n\n### TemplateParser method decomposition\n\n| Method | Visibility | Role |\n|---|---|---|\n| `parse()` | public | Entry point: parses declarative HTML into `{ strings, values }`. |\n| `createTemplate()` | public | Creates a `ViewTemplate` from resolved strings and values, lazily installing declarative debug messages. |\n| `resolveStringsAndValues()` | private | Creates `strings`/`values` arrays and delegates to `resolveInnerHTML()`. |\n| `resolveInnerHTML()` | private | Recursive HTML parser that dispatches to data binding or template directive handlers. |\n| `resolveDataBinding()` | private | Thin dispatcher that routes to `resolveContentBinding()`, `resolveAttributeBinding()`, or `resolveAttributeDirectiveBinding()`. |\n| `resolveContentBinding()` | private | Handles `{{expression}}` in text content. |\n| `resolveAttributeBinding()` | private | Handles `{{expression}}` in HTML attributes; dispatches to `resolveEventBinding()` or `resolveAccessBinding()` based on aspect. |\n| `resolveAttributeDirectiveBinding()` | private | Handles `f-children`, `f-slotted`, `f-ref` directives. |\n| `resolveAccessBinding()` | private | Shared helper for access-type bindings (content, boolean-attribute fallback, default attribute). |\n| `resolveEventBinding()` | private | Handles event bindings (`@event`), including arg parsing and owner resolution. |\n| `resolveTemplateDirective()` | private | Handles `<f-when>` and `<f-repeat>` directives. |\n| `resolveAttributeDirective()` | private | Creates FAST `children()`, `slotted()`, or `ref()` directives. |\n\n### TemplateResolutionContext\n\nThe `TemplateResolutionContext` interface (internal to `TemplateParser`) groups the stable fields that flow through the recursive parsing pipeline:\n\n```typescript\ninterface TemplateResolutionContext {\n    parentContext: string | null;  // Current repeat item alias (e.g. \"item\")\n    level: number;          // Nesting depth for repeat directives\n    schema: Schema;         // JSON schema builder for property tracking\n}\n```\n\n`rootPropertyName` is intentionally kept separate because it is selectively mutated per branch and must not leak across sibling binding resolutions.\n\n### Key parsing functions (utilities.ts)\n\n| Function | Role |\n|---|---|\n| `getNextBehavior(innerHTML)` | Top-level scanner: returns the next `DataBindingBehaviorConfig` or `TemplateDirectiveBehaviorConfig`, or `null` when done. |\n| `getNextDataBindingBehavior(innerHTML)` | Identifies whether the next binding is `{{}}`, `{{{}}}`, or `{}` and classifies it as content/attribute/attributeDirective. |\n| `getNextDirectiveBehavior(innerHTML)` | Finds the next `<f-when>` or `<f-repeat>` and its matching close tag. |\n| `bindingResolver(...)` | Builds a `(x, c) => value` closure for a given path; also calls `schema.addPath()`. |\n| `pathResolver(path, contextPath, level, schema)` | Returns a closure that traverses an object using dot-notation, handling repeat context levels. |\n| `getBooleanBinding(...)` | Returns a `(x, c) => boolean` closure for `<f-when>` expressions. |\n| `assignObservables(schema, rootSchema, data, target, rootProperty)` | Wraps objects/arrays in `Proxy` for deep observation. |\n| `deepMerge(target, source)` | Merges source into an existing proxy, preserving proxy identity and triggering observable notifications. |\n| `transformInnerHTML(html)` | Normalises HTML-encoded operator characters (`&gt;`, `&lt;`, etc.) used in `<f-when>` expressions. |\n| `escapeBracesInCodeElements(html)` | Replaces `{` / `}` characters inside every `<code>` element with `&#123;` / `&#125;` so binding-like syntax in code samples renders literally rather than being interpreted as FAST bindings. Client-side half of a two-stage escape — the brace escape mirrors the server-side pass in `microsoft-fast-build` (necessary client-side because `&#123;` / `&#125;` decode back to literal `{` / `}` in the DOM and `.innerHTML` does not re-encode them). The angle-bracket escape for FAST directive tags (`<f-when>`, `</f-when>`, `<f-repeat>`, `</f-repeat>`) inside `<code>` runs only on the server because the DOM serializer re-encodes `<` / `>` in text content automatically. Real HTML elements (`<button>`) and custom elements inside `<code>` keep their angle brackets and continue to render as live DOM elements. Modeled on Microsoft WebUI's `webui-press` markdown renderer. |\n\n### Binding classification\n\n```\ninnerHTML token\n  ├── {{{ ... }}}  → unescaped content binding  (innerHTML div)\n  ├── {{ ... }}    → default binding\n  │     ├── attr=\"{{expr}}\"    → attribute binding   (aspect: null / \":\" / \"?\")\n  │     └── {{expr}} in text  → content binding\n  └── { ... }      → client-side binding\n        ├── @event=\"{handler(...)}\"  → event binding (aspect \"@\")\n        └── f-dir=\"{prop}\"           → attribute directive binding\n```\n\n---\n\n## Schema and Observer Map\n\nThe `Schema` class accumulates all binding paths discovered during parsing into an instance-level JSON Schema map (`schemaMap`) indexed by `rootPropertyName → JSONSchema`. Each `Schema` instance also registers itself in the module-level `schemaRegistry` (keyed by custom element name) for cross-element `$ref` resolution.\n\n```mermaid\nflowchart LR\n    A[\"Template binding\\nuser.details.age\"] --> B[bindingResolver]\n    B --> C[schema.addPath\\ntype:'access'\\npath:'user.details.age'\\nrootProperty:'user']\n    C --> D[\"schema.schemaMap\\n{'user' => JSONSchema}\"]\n    C --> D2[\"schemaRegistry\\n{'my-el' => schemaMap}\"]\n    D --> E[ObserverMap.defineProperties]\n    E --> E1[\"applyConfigToSchema\\nstamps $observe: false on excluded schema nodes\"]\n    E1 --> F[Observable.defineProperty on prototype\\nfor 'user']\n    E1 --> G[install instanceResolverChanged handler]\n    G --> H[\"when user= is set:\\nassignObservables checks schema.$observe\\n→ Proxy wraps observed paths only\\ndeep mutations → Observable.notify\"]\n```\n\nFor a deep dive into the schema structure, context tracking, and proxy system\nsee\n[schema-observer-map.md](./schema-observer-map.md).\n\n### `$observe` flag on schema nodes\n\nWhen an `ObserverMapConfig` with a `properties` key is provided, `ObserverMap.defineProperties()` calls `applyConfigToSchema()` to stamp `$observe: false` on excluded schema nodes **before** the proxy system runs. This is a one-time pre-processing pass that walks the config and schema trees in parallel:\n\n- `false` in the config → `$observe: false` is stamped recursively on the node and all its descendants.\n- `$observe: false` on a config node → the schema node is stamped, and unlisted children inherit the stamp.\n- `true` in the config → no stamp needed (observed is the default).\n- Config paths not in the schema are silently ignored.\n\n**Convention: stamp-only-when-excluding.** The `$observe` flag is only ever set to `false` — it is never explicitly set to `true`. Absence of `$observe` (i.e. `undefined`) means the node is observed. This means:\n\n- When Observer Map is enabled without a `properties` tree, `applyConfigToSchema`\n  is never called and no schema nodes are mutated — zero overhead for the\n  common case.\n- The proxy system uses `isSchemaExcluded(schema)` (checks `$observe === false` with no observed descendants) as the single predicate for all skip/suppress decisions.\n- Schema nodes without `$observe` are always treated as observed.\n\n### AttributeMap and leaf bindings\n\nWhen `attributeMap()` is enabled with a declarative template, it registers a\ndefinition schema transform. With a manually supplied definition schema, it runs\nimmediately. The extension constructs an `AttributeMap` implementation and calls\n`defineProperties()`. It iterates `Schema.getRootProperties()` and skips any\nproperty whose schema entry contains `properties`, `type`, or `anyOf` — keeping\nonly plain leaf bindings. For each leaf:\n\n1. The schema key is used as the **JS property name**.\n2. The **HTML attribute name** depends on the `attribute-name-strategy`:\n   - `\"camelCase\"` (default): the attribute name is derived by converting the camelCase property name to kebab-case (e.g. `fooBar` → `foo-bar`).\n   - `\"none\"`: the attribute name equals the property name (e.g. `foo-bar` → `foo-bar`).\n3. A new `AttributeDefinition` is registered via `Observable.defineProperty`.\n4. `FASTElementDefinition.attributeLookup` is keyed by the HTML attribute name and `propertyLookup` is keyed by the JS property name so `attributeChangedCallback` can route attribute changes to the correct property.\n\nWhen using the `\"none\"` strategy, property names may contain dashes and must be\naccessed via bracket notation (e.g. `element[\"foo-bar\"]`). When using\n`\"camelCase\"`, property names are standard JS identifiers (e.g.\n`element.fooBar`).\n\nSchema transforms run in deterministic order. When both extensions are supplied,\nattribute mapping runs before observer mapping.\n\n---\n\n## Lifecycle\n\n```mermaid\nsequenceDiagram\n    participant App as Application JS\n    participant FER as FASTElementDefinition\n    participant FTE as internal f-template\n    participant EC as ElementController\n    participant Hydration as enableHydration().whenHydrated()\n\n    App->>Hydration: const hydration = enableHydration() [optional]\n    App->>FER: MyElement.define({name:'my-el', template: declarativeTemplate()}, [attributeMap(), observerMap()])\n    note over FER: definition composed; resolver waits for template\n\n    DOM->>FTE: f-template connected to DOM\n    FTE->>FTE: bridge matches registry + name\n    FTE->>FTE: parse template → schema → transforms → ViewTemplate\n    FTE->>FER: return viewTemplate to resolver\n    FER->>FER: customElements.define('my-el', MyElement)\n\n    DOM->>EC: element instance connects with existing shadow root\n    EC->>EC: isPrerendered = true (existing shadow root detected)\n    alt enableHydration() was called\n        EC->>EC: template.hydrate() — maps existing DOM to binding targets\n        EC->>Hydration: resolve active batch when all pending elements finish\n    else hydration not enabled\n        EC->>EC: client-side render; isHydrated = false\n    end\n```\n\n### Promise readiness reference\n\n| Promise | Import path | Resolves when |\n|---|---|---|\n| `enableHydration().whenHydrated(\"my-element\")` | `@microsoft/fast-element/hydration.js` | Hydration work for that tag name completes. |\n| `enableHydration().whenHydrated()` | `@microsoft/fast-element/hydration.js` | The active hydration batch completes. |\n\nBy default, hydration no-ops for later prerendered batches after the initial\nbatch completes. Set\n`enableHydration({ stopHydration: StopHydration.never })` when Declarative Shadow\nDOM may be streamed into the page after the initial hydration batch. In that\nmode, `enableHydration().whenHydrated()` intentionally remains pending because\nthere is no global completion point.\n\nFor usage examples see\n[lifecycle.md](./lifecycle.md).\n\n---\n\n## Integration with fast-element\n\nThe declarative runtime is a thin orchestration layer on top of\n`@microsoft/fast-element`. It does not re-implement any reactive primitives; it\nconverts declarative HTML syntax into the same data structures that `html`\ntagged templates produce.\n\n| fast-element primitive | How the declarative runtime uses it |\n|---|---|\n| `FASTElement` | Base class for user components; the internal `<f-template>` publisher is a native `HTMLElement` |\n| `FASTElementDefinition.register()` / template resolvers | Deferred element registration — element waits for its template |\n| `FASTElementDefinition.schema` | Optional schema used by schema-driven extensions; assigned automatically by `declarativeTemplate()` and available for manual schemas |\n| `FASTElementExtension` | Extension callback mechanism used by `attributeMap()` and `observerMap()` to attach schema transforms before template resolution or consume manually supplied schemas |\n| `ViewTemplate.create(strings, values)` | Compiles the resolved strings/values arrays into a `ViewTemplate` |\n| `ElementController` | Automatically detects prerendered content (`isPrerendered`) and hydrates server-rendered DOM using `fe-b` comment/dataset markers via `template.hydrate()` |\n| `Observable.defineProperty()` | Defines observable root properties on element prototypes (ObserverMap) |\n| `Observable.getNotifier()` | Triggers change notifications from proxy handlers |\n| `when(expr, template)` | FAST directive used for `<f-when>` |\n| `repeat(expr, template)` | FAST directive used for `<f-repeat>` |\n| `slotted(options)` | FAST directive used for `f-slotted` |\n| `children(prop)` | FAST directive used for `f-children` |\n| `ref(prop)` | FAST directive used for `f-ref` |\n\n### Deferred template attachment via define\n\nStandard subclass `define()` calls return a `Promise` that resolves immediately when a concrete template is provided at definition time. When `template: declarativeTemplate()` is used, the `Promise` resolves after the matching `<f-template>` supplies a concrete template through the bridge. This unified API replaces the previous `defineAsync()` / `composeAsync()` methods.\n\n---\n\n## Hydration Model\n\nWhen declarative templates are used, the server must render:\n\n1. The custom element tag with its attributes and initial state.\n2. A `<template shadowrootmode=\"open\">` containing pre-rendered HTML annotated with FAST's hydration markers.\n3. An `<f-template>` element somewhere in the page that carries the template definition.\n\nWith `declarativeTemplate()`, connection gating happens before platform registration: the resolver waits for the matching `<f-template>` and keeps the definition concrete before elements can connect. Hydration can therefore start immediately when `ElementController.connect()` runs. The `defer-hydration` and `needs-hydration` attributes are no longer needed in server-rendered markup.\n\n### Hydration marker formats\n\n`enableHydration()` uses the FAST Element 3.x data-free marker reader by\ndefault. The marker strategy is shared by target discovery and nested repeat\nhydration so a view uses one consistent format throughout its hydration walk.\nThe optional `markers_v2` strategy contains the legacy indexed-marker parsing logic and\nis selected with `enableHydration({ markers: markers_v2 })`.\n\n**Content bindings** use HTML comments (data-free, matched by string equality):\n\n```\n<!--fe:b-->\n<!--fe:/b-->\n```\n\n**Attribute bindings** use a single `data-fe` dataset attribute with binding count:\n\n```html\n<el data-fe=\"3\">\n```\n\n**Repeat directives** wrap each item in comment pairs:\n```\n<!--fe:r-->\n...item DOM...\n<!--fe:/r-->\n```\n\nFor detailed examples see\n[rendering.md](./rendering.md).\n\n---\n\n## Testing Architecture\n\nEach feature is verified by a **Playwright** integration test against a live\nVite dev server. The `test/declarative/fixtures/` directory contains one\nsubdirectory per feature:\n\n```\ntest/declarative/fixtures/<feature>/\n├── <feature>.spec.ts        # Playwright test\n├── entry.html               # Entry template with root custom elements\n├── fast-build.config.json   # Build configuration for @microsoft/fast-build\n├── index.html               # Pre-rendered page (GENERATED by scripts/declarative/build-fixtures.js — do not edit)\n├── main.ts                  # Component definitions, declarativeTemplate(), extensions, and enableHydration() setup\n├── state.json               # Initial state for server-side rendering\n└── templates.html           # Declarative <f-template> definitions\n```\n\nFixtures are auto-discovered by scanning for directories that contain `entry.html`, `templates.html`, `state.json`, and `fast-build.config.json`. Both the build script and the Vite config pick up new fixtures automatically — no registration step is needed.\n\nFor fixtures that use SSR-style pre-rendered HTML,\n`scripts/declarative/build-fixtures.js` invokes `@microsoft/fast-build` with\n`--config` pointing to each fixture's `fast-build.config.json` to generate\n`index.html` from the configured source files.\n\n### WebUI Integration Tests\n\nA separate integration test suite validates that `@microsoft/webui` can build and render the same fixture templates that `@microsoft/fast-build` processes. This is split into two steps:\n\n1. **Build** (`npm run build:fixtures:webui`) — runs\n   `scripts/declarative/build-fixtures-with-webui.js`, which extracts\n   `<f-template>` elements, converts each component template with\n   `fast convert --syntax=webui-prerelease`, builds each fixture with\n   `webui build --plugin=fast`, renders the protocol with `state.json`, and\n   writes the output alongside `main.ts` and assets to\n   `temp/integrations/webui/fixtures/`.\n2. **Test** (`npm run test:webui-integration`) — builds the fixtures, then runs\n   the same Playwright specs against the webui-rendered output served by a Vite\n   dev server on port 5174 (configured in\n   `playwright.declarative.webui.config.ts`).\n\nFixtures that intentionally contain invalid FAST declarative templates are skipped in\nthe WebUI build because `fast convert` validates and rejects them before WebUI\nrenders. Run locally with `npm run test:webui-integration` or via the\n`ci-webui-integration.yml` GitHub Action on PRs and pushes to `main`.\n\n#### Skipped tests\n\nSome tests are conditionally skipped when running under the webui integration\nconfig. The `playwright.declarative.webui.config.ts` file sets\n`process.env.FAST_WEBUI_INTEGRATION = \"true\"`, and individual tests check this\nvariable with `test.skip()` to opt out of cases that exercise known differences\nbetween `fast-build` and `webui` rendering:\n\n- **`errors.spec.ts` — \"throws an error when no template element is present\"**: webui does not render `<f-template>` elements that lack a `<template>` child, so the expected error is never thrown.\n\n### Hydration readiness\n\nFixtures that exercise prerendered output wait for hydration to complete before\nrunning assertions. Each `main.ts` calls `enableHydration()` and then awaits\nthe returned controller's `whenHydrated()` promise to set a global flag, and each spec file calls\n`page.waitForFunction()` after `page.goto()` to block until the flag is set.\nSee [test/declarative/fixtures/README.md](../../test/declarative/fixtures/README.md)\nfor the implementation pattern.\n\nSee\n[test/declarative/fixtures/WRITING_FIXTURES.md](../../test/declarative/fixtures/WRITING_FIXTURES.md)\nfor the complete fixture authoring guide,\n[test/declarative/fixtures/README.md](../../test/declarative/fixtures/README.md)\nfor a quick reference, and\n[test/declarative/fixtures/extensions/observer-map-deep-merge/README.md](../../test/declarative/fixtures/extensions/observer-map-deep-merge/README.md)\nfor an example of a complex multi-feature fixture.\n\n---\n\n## Further Reading\n\n| Document | Topic |\n|---|---|\n| [syntax.md](./syntax.md) | Installation, syntax reference, hydration promises, usage examples |\n| [rendering.md](./rendering.md) | Hydratable HTML format: comment markers, dataset attributes, directive markers |\n| [lifecycle.md](./lifecycle.md) | Phase-by-phase rendering lifecycle, hydration readiness, performance notes |\n| [schema-observer-map.md](./schema-observer-map.md) | Deep dive into Schema JSON structure, ObserverMap proxy system, debugging |\n| [test/declarative/fixtures/README.md](../../test/declarative/fixtures/README.md) | Quick reference for fixture structure |\n| [test/declarative/fixtures/WRITING_FIXTURES.md](../../test/declarative/fixtures/WRITING_FIXTURES.md) | Complete guide to writing new Playwright fixture tests |\n| [test/declarative/fixtures/extensions/observer-map-deep-merge/README.md](../../test/declarative/fixtures/extensions/observer-map-deep-merge/README.md) | Complex deep-merge fixture: observable arrays, nested repeats, conditionals |\n","packages/fast-element/docs/declarative/lifecycle.md":"# Rendering Lifecycle\n\nThis document describes the declarative rendering lifecycle inside\n`@microsoft/fast-element`.\n\n## Overview\n\nThe FAST Element rendering lifecycle involves a coordinated process between the\ncore runtime and its declarative entrypoint:\n\n- **`@microsoft/fast-element`**: Provides the core `FASTElement` base class and\n  element definition system.\n- **`@microsoft/fast-element/declarative.js`**: Provides the `f-template`\n  custom element that processes HTML templates and attaches them to FAST\n  elements as a `ViewTemplate` in lieu of an `html` template created during\n  a subclass `define()` call. The preferred path uses `declarativeTemplate()` so\n  the subclass `define()` call waits for the matching declarative template and keeps\n  the definition concrete before registration completes.\n\n## Lifecycle Phases\n\nGiven a DOM which includes an `f-template` and a component:\n\n```html\n<my-component text=\"Hello World\">\n    <template shadowrootmode=\"open\">\n        <h1><!--fe:b-->Hello World<!--fe:/b--></h1>\n    </template>\n</my-component>\n\n<f-template name=\"my-component\">\n    <template>\n        <h1>{{text}}</h1>\n    </template>\n</f-template>\n```\n\nThe following phases will then be kicked off once the JavaScript is parsed.\n\n### Phase 1: Definition Resolution\n\nCustom elements begin their lifecycle by composing a definition that points at\n`declarativeTemplate()`. The resolver waits for a matching declarative template\nand returns a concrete `ViewTemplate` before the platform registration step.\n\n```typescript\n// Custom element class definition\nclass MyComponent extends FASTElement {\n    @attr text: string = \"\";\n}\n\n// Register with the declarative template bridge\nMyComponent.define({\n    name: \"my-component\",\n    template: declarativeTemplate(),\n});\n```\n\nKey characteristics of this phase:\n- The element definition stays unresolved until a matching declarative template is available\n- The resolved template is concrete before platform registration completes\n\n### Phase 2: Declarative Template Bridge\n\n`declarativeTemplate()` from `@microsoft/fast-element/declarative.js`\nautomatically ensures that `f-template` is defined in the same registry as the\nFAST element being composed.\n\n### Phase 3: Template Processing and Attachment\n\nWhen an `f-template` element is connected to the DOM, it initiates the template attachment process.\n\nThe lifecycle flow during this phase:\n\n1. **Template Discovery**: The resolver waits for a matching\n   `<f-template name=\"...\">` in the same registry as the element definition.\n2. **Template Element Connection**: The matching `f-template` element's\n   `connectedCallback()` registers it with the declarative template bridge.\n3. **Template Processing**: The bridge reads and transforms the markup, builds\n   the schema, applies `observerMap()` / `attributeMap()` behavior, and resolves\n   data bindings, directives, and other template features into the `ViewTemplate`\n   model which is also used by the `@microsoft/fast-element` `html` tag template.\n4. **Template Attachment**: The concrete `ViewTemplate` is returned to\n   the subclass `define()` call, which assigns it to the definition before platform\n   registration completes.\n\n### Phase 4: Composition Completion\n\nOnce the template is attached to the partial definition, the element completes its composition:\n\n1. **`compose()` Execution**: The element definition internally completes its composition process\n2. **Platform Registration**: The completed element definition is fully registered with the platform's custom element registry\n\n### Phase 5: Element Instantiation and Hydration\n\nWhen custom elements are instantiated in the DOM, the following occurs:\n\n1. **Element Creation**: The platform creates instances of the custom element\n2. **Prerendered Content Detection**: `ElementController` detects the existing shadow root from SSR — `isPrerendered` resolves `true`\n3. **Hydration Check**: If `enableHydration()` was called and the template is hydratable, the element hydrates — `isHydrated` resolves `true`. Otherwise it falls back to client-side rendering.\n4. **Concrete Template Ready**: Because `declarativeTemplate()` resolved during\n   definition, `connect()` starts with the final template already attached.\n5. **Hydration**: `ElementController` uses `template.hydrate()` to create a\n   `HydrationView` that maps existing DOM nodes to binding targets using `fe:b`\n   / `fe:/b` markers\n\nThe DOM after hydration should look like this:\n\n```html\n<my-component text=\"Hello World\">\n    <template shadowrootmode=\"open\">\n        <h1><!---->Hello World<!----></h1>\n    </template>\n</my-component>\n```\n\n## Key Integration Points\n\n### Fast Element Registry\n\nThe `fastElementRegistry` serves as the central coordination point between the\ntwo packages and is available to consumers from\n`@microsoft/fast-element/registry.js`:\n\n- Stores partial element definitions created by `define()`\n- Provides lookup mechanism via `register()` for template attachment\n- Resolves `fastElementRegistry.whenRegistered(tagName)` when a matching\n  definition is registered\n- Maintains the registry of all FAST element definitions\n\n### Observable Pattern\n\nBoth packages use the Observable pattern for coordination:\n\n- Element definition template assignment notifies observers that are waiting for a concrete template\n- Template attachment triggers observable notifications to complete the lifecycle\n\n## Error Handling\n\nThe lifecycle includes error handling for missing components:\n\n- Template elements throw errors if no corresponding element definition is found\n- Element definitions can exist without templates (partial state)\n\n## Performance Considerations\n\nThe asynchronous nature of the lifecycle provides several performance benefits:\n\n- **Progressive Enhancement**: Elements can be registered before templates are loaded\n- **Code Splitting**: Templates can be loaded separately from element definitions  \n- **Reduced Blocking**: Template processing doesn't block element registration\n- **Hydration Optimization**: Server-side rendered content can be hydrated efficiently\n\nThis coordinated lifecycle enables powerful scenarios like server-side rendering, progressive enhancement, and dynamic template loading while maintaining the reactive capabilities of FAST Element.\n\n## Hydration promise APIs\n\nFAST Element exposes promises for hydration readiness points that are useful to\napplication code.\n\nHydration must be explicitly opted into by calling `enableHydration()`. Await\nthe returned controller's `whenHydrated()` promise when code needs to run after\nthe active hydration batch completes. Pass a tag name to `whenHydrated(tagName)`\nwhen code needs to wait for a specific FAST element.\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nconst hydration = enableHydration();\nawait hydration.whenHydrated(\"my-component\");\nawait hydration.whenHydrated();\n```\n\nBy default, hydration no-ops for later prerendered batches after the initial\nbatch completes. Set `stopHydration: StopHydration.never` in\n`enableHydration()` when streaming Declarative Shadow DOM should continue\nhydrating after the initial batch. In that mode, `hydration.whenHydrated()`\nintentionally remains pending because hydration has no global completion point.\n","packages/fast-element/docs/declarative/rendering.md":"# Non-browser HTML rendering\n\n1. [Initial State](#initial-state)\n2. [Hydrating Comments and Datasets](#hydration-comments-and-datasets)\n\nThis document details information on rendering hydratable content and includes some pointers on how Dependency Injection can be used to create services that hydrate a custom elements state. Non-browser rendering in this context means producing HTML that a browser can parse and hydrate later; it does not mean running the FAST Element client runtime in a worker, server-side JavaScript runtime, or other non-window host.\n\n## Initial State\n\nTo create initial state this should be added somewhere accessible by your service, in this example a `<script>` tag can be used to provide a global initial state.\n\nExample:\n```html\n<script>\n    window.__INITIAL_STATE__ = {\n        text: \"Hello world\"\n    }\n</script>\n```\n\nAdd a Dependency Injection service in your bundle to access properties in your state.\n\nSimple example (`initial-state.ts`):\n```typescript\nimport { DI } from \"@microsoft/fast-element/di.js\";\n\ninterface InitialState {\n    text: string;\n}\n\nexport interface IInitialStateService {\n  init(): InitialState;\n}\n\nexport class InitialStateService implements IInitialStateService {\n    private initialState: any;\n\n    constructor() {\n        this.initialState = window.__INITIAL_STATE__;\n    }\n\n    public init(...keys: Array<string>): InitialState {\n        const config: any = {};\n\n        for (let key of keys) {\n            config[key] = this.initialState[key];\n        }\n\n        return config;\n    }\n}\n\nexport const initialStateFactory = DI.createContext<IInitialStateService>(\n  'i-initial-state-service',\n  (x) => x.singleton(InitialStateService)\n);\n```\n\nInclude the DI service to your component.\n\nExample:\n```typescript\nimport { attr, FASTElement, Observable } from \"@microsoft/fast-element\";\nimport {\n    initialStateFactory,\n    InitialStateService,\n    type IInitialStateService,\n} from \"./initial-state.js\";\nimport { inject } from \"@microsoft/fast-element/di.js\";\n\nexport class MyComponent extends FASTElement {\n    @inject(initialStateFactory) initialStateService!: InitialStateService;\n\n    @attr\n    text: string = \"\";\n\n    service!: IInitialStateService;\n\n    connectedCallback() {\n        super.connectedCallback();\n\n        this.loadItemFromInitialState();\n    }\n\n    loadItemFromInitialState(): void {\n        const initialState = this.initialStateService.init([\"text\"]);\n\n        this.text = initialState.text;\n    }\n}\n\nMyComponent.define({\n    name: \"my-component\",\n    template: declarativeTemplate(),\n});\n```\n\nWhen the element connects, `ElementController` automatically detects the\nexisting shadow root from SSR and sets `isPrerendered = true`.\n`declarativeTemplate()` keeps the definition template concrete before\nregistration completes, so the element can hydrate the prerendered shadow root\nimmediately. The `defer-hydration` and `needs-hydration` attributes are no\nlonger needed.\n\n## Hydration Comments and Datasets\n\nWhen hydrating the HTML, FAST uses `ElementController` which detects an\nexisting shadow root (from SSR or declarative shadow DOM) and sets\n`isPrerendered = true`. It then uses `template.hydrate()` to create a\n`HydrationView` that maps existing DOM nodes to binding targets using hydration\n\"markers\" such as comments and dataset attributes. By default the declarative\nruntime in `@microsoft/fast-element` assumes component hydration will occur, so\nrendering hydratable markup is required.\n\n### Bindings\n\n#### Content Bindings\n\nContent binding markers are represented using HTML comments. These comments are used to indicate where dynamic content exists in the template. Markers carry no embedded data — they are fixed strings matched by string equality (not regex).\n\n* Start binding: `<!--fe:b-->`\n* End binding: `<!--fe:/b-->`\n\nBinding pairs are matched using balanced depth counting: each start marker increments a depth counter and each end marker decrements it. When the counter returns to zero the pair is complete.\n\n##### Content Binding Marker Examples\n\n**Note**\nExamples shown below mostly skip the wrapping custom element and the internal template element with `shadowrootmode=\"open\"`.\n\nTypically along with the content from the examples below, the rendering should include:\n\n```html\n<my-component>\n    <template shadowrootmode=\"open\" shadowroot=\"open\">\n        <!-- hydratable content -->\n    </template>\n</my-component>\n```\n\n**Simple content example**\n\nContent bindings such as:\n```html\n<h1>{{text}}</h1>\n```\n\nWhen combined with state such as:\n```json\n{\n    \"text\": \"Hello world\"\n}\n```\n\nShould result in:\n```html\n<h1><!--fe:b-->Hello world<!--fe:/b--></h1>\n```\n\n#### Attribute Bindings\n\nAttribute bindings are tracked using a single dataset attribute: `data-fe=\"N\"` where `N` is the number of attribute bindings on the element.\n\n##### Examples\n\n###### Single attribute example\n\nAttribute binding such as:\n```html\n<h1 greeting=\"{{greeting}}\"></h1>\n```\n\nWhen combined with state such as:\n```json\n{\n    \"greeting\": \"Hello\"\n}\n```\n\nShould result in:\n\n```html\n<h1 data-fe=\"1\" greeting=\"Hello\"></h1>\n```\n\n###### Multiple attribute bindings\n\nWhen multiple attribute bindings exist on the same element:\n```html\n<h1 greeting=\"{{greeting}}\" subtitle=\"{{subtitle}}\" punctuation=\"{{punctuation}}\"></h1>\n```\n\nWhen combined with state such as:\n```json\n{\n    \"greeting\": \"Hello\",\n    \"subtitle\": \"world\",\n    \"punctuation\": \"!\"\n}\n```\n\nShould result in:\n\n```html\n<h1 data-fe=\"3\" greeting=\"Hello\" subtitle=\"world\" punctuation=\"!\"></h1>\n```\n\n**Mixed attribute and content example**\n\nMultiple attributes and content bindings such as:\n```html\n<div show=\"{{show}}\" appearance=\"{{appearance}}\" punctuation=\"{{punctuation}}\">\n    <h1>{{text}}</h1>\n    <span>{{subtitle}}</span>\n    <span>{{punctuation}}</span>\n</div>\n```\n\nShould result in:\n```html\n<div data-fe=\"3\" show appearance=\"large\" punctuation=\"!\">\n    <h1><!--fe:b-->Hello<!--fe:/b--></h1>\n    <span><!--fe:b-->world<!--fe:/b--></span>\n    <span><!--fe:b-->!<!--fe:/b--></span>\n</div>\n```\n\n### Directives\n\nDirectives are treated differently from bindings as they include a template. This means that in addition to the binding used to determine the logic for the directive FAST also requires a separate marker for the directive itself to demarkate the beginning and end of the template.\n\n#### Repeat\n\nExample repeat binding:\n```html\n<f-repeat value=\"{{item in list}}\">\n    <span>{{item}}</span>\n</f-repeat>\n```\n\nCombined with state:\n```json\n[\n    \"Bob\",\n    \"Alice\",\n    \"Sue\"\n]\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<!--fe:r-->\n<span>\n    <!--fe:b-->Bob<!--fe:/b-->\n</span>\n<!--fe:/r-->\n<!--fe:r-->\n<span>\n    <!--fe:b-->Alice<!--fe:/b-->\n</span>\n<!--fe:/r-->\n<!--fe:r-->\n<span>\n    <!--fe:b-->Sue<!--fe:/b-->\n</span>\n<!--fe:/r-->\n<!--fe:/b-->\n```\n\nNote that the repeat markers are data-free — they carry no index or ID. Pairing uses balanced depth counting. Additionally, a binding wraps the repeat markers; even if the array is empty, this binding must be rendered.\n\nExample result of an empty array:\n```html\n<!--fe:b-->\n<!--fe:/b-->\n```\n\n#### When\n\nThe when directive is either present in the DOM or not, and therefore does not need an extra marker for the template.\n\nExample when binding:\n```html\n<f-when value=\"{{show}}\">\n    <span>{{text}}</span>\n</f-when>\n```\n\nCombined with state:\n```json\n{\n    \"show\": true,\n    \"text\": \"Hello world\"\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<span>\n    <!--fe:b-->Hello world<!--fe:/b-->\n</span>\n<!--fe:/b-->\n```\n\nIf the when is evaluated to `falsy` then we can safely leave the binding markers only.\n\nExample state:\n```json\n{\n    \"show\": false,\n    \"text\": \"Hello world\"\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<!--fe:/b-->\n```\n\n### Host attributes from `<f-template>`\n\nBuild-time renderers (e.g. `@microsoft/fast-build`) forward attributes declared on the inner `<template>` element of an `<f-template>` onto the rendered host element opening tag.\n\nExample template:\n```html\n<f-template name=\"my-button\">\n    <template tabindex=\"0\" ?disabled=\"{{isDisabled}}\">\n        <button><slot></slot></button>\n    </template>\n</f-template>\n```\n\nCombined with author HTML `<my-button></my-button>` and state:\n```json\n{\n    \"isDisabled\": true\n}\n```\n\nShould result in:\n```html\n<my-button tabindex=\"0\" disabled defer-hydration needs-hydration>\n    <template shadowrootmode=\"open\" shadowroot=\"open\">\n        <button><slot></slot></button>\n    </template>\n</my-button>\n```\n\nRules:\n- Client-only attributes (`@event`, `:prop`, `f-ref`, `f-slotted`, `f-children`) are skipped — they have no meaning on a server-rendered host element.\n- Author attributes on the host element always win on conflicts (case-insensitive name match; the dedupe key for `?name=\"{{expr}}\"` is the bare `name`).\n- Static `name=\"value\"` is forwarded verbatim (HTML-escaped); static boolean `name` is emitted bare.\n- `name=\"{{expr}}\"` is resolved against the element's initial child state; primitives are emitted as `name=\"value\"`, `Array` / `Object` / `Null` and missing values are stripped.\n- `?name=\"{{expr}}\"` is evaluated as a boolean against the same state; the bare `name` (without `?`) is emitted when truthy and skipped when falsy.\n\n### Client Side Bindings\n\nClient side bindings are bindings which the client needs, but they are not necessary as part of an initial render. These must still be accounted for when creating hydration comments however, as the template needs to know which elements to attach these bindings to. There are two types of client side bindings, events and attribute directives. These do not require state as they are bound to class methods or properties.\n\n#### Event Bindings\n\nEvent bindings such as `@keydown` and `@click` can be represented with hydration comments.\n\nExample event binding:\n```html\n<button @click=\"{handleClick($e)}\">Button</button>\n```\n\nShould result in:\n```html\n<button data-fe=\"1\">Button</button>\n```\n\n#### Attribute Directives\n\nAttribute directives such as `f-slotted` and `f-ref` can be represented with hydration comments.\n\nExample `f-ref` binding:\n```html\n<button f-ref=\"{button}\">Button</button>\n```\n\nShould result in:\n```html\n<button data-fe=\"1\">Button</button>\n```\n\n#### More Examples\n\n##### Nested Whens\n\nExample when binding:\n```html\n<f-when value=\"{{show}}\">\n    <span>{{text}}</span>\n    <f-when value=\"{{showInternal}}\">\n        <span>{{internalText}}</span>\n    </f-when>\n</f-when>\n```\n\nCombined with state:\n```json\n{\n    \"show\": true,\n    \"text\": \"Hello world\",\n    \"showInternal\": true,\n    \"internalText\": \"Hello pluto\"\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<span>\n    <!--fe:b-->Hello world<!--fe:/b-->\n</span>\n    <!--fe:b-->\n    <span>\n        <!--fe:b-->Hello pluto<!--fe:/b-->\n    </span>\n    <!--fe:/b-->\n<!--fe:/b-->\n```\n\n##### Nested Repeats\n\nExample when binding:\n```html\n<f-repeat value=\"{{item in items}}\">\n    <div>\n        <span>{{item.name}}</span>\n        <f-when value=\"{{!!item.nested}}\">\n            <ul>\n                <f-repeat value=\"{{person in item.nested}}\">\n                    <li>{{person.name}}</li>\n                </f-repeat>\n            </ul>\n        </f-when>\n    </div>\n</f-repeat>\n```\n\nCombined with state:\n```json\n{\n    \"items\": [\n        {\n            \"name\": \"Bob\"\n        },\n        {\n            \"name\": \"Alice\"\n        },\n        {\n            \"name\": \"Sue\",\n            \"nested\": [\n                {\n                    \"name\": \"Amy\"\n                },\n                {\n                    \"name\": \"Clarice\"\n                },\n                {\n                    \"name\": \"Lawrence\"\n                }\n            ]\n        }\n    ]\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n    <!--fe:r-->\n    <div>\n        <span><!--fe:b-->Bob<!--fe:/b--></span>\n        <!--fe:b--><!--fe:/b-->\n    </div>\n    <!--fe:/r--><!--fe:r-->\n    <div>\n        <span><!--fe:b-->Alice<!--fe:/b--></span>\n        <!--fe:b--><!--fe:/b-->\n    </div>\n    <!--fe:/r--><!--fe:r-->\n    <div>\n        <span><!--fe:b-->Sue<!--fe:/b--></span>\n        <!--fe:b-->\n            <ul>\n                <!--fe:b-->\n                <!--fe:r-->\n                <li>\n                    <!--fe:b-->Amy<!--fe:/b-->\n                </li>\n                <!--fe:/r-->\n                <!--fe:r-->\n                <li>\n                    <!--fe:b-->Clarice<!--fe:/b-->\n                </li>\n                <!--fe:/r-->\n                <!--fe:r-->\n                <li>\n                    <!--fe:b-->Lawrence<!--fe:/b-->\n                </li>\n                <!--fe:/r-->\n                <!--fe:/b-->\n            </ul>\n        <!--fe:/b-->\n    </div>\n    <!--fe:/r-->\n<!--fe:/b-->\n```\n\n##### Nested components with `<slot>`\n\nThis example shows the wrapping custom element tag as well as the template component with `shadowrootmode=\"open\"` for the sake of illustrating an example that would exist in the DOM.\n\nExample template of component \"nested-component\":\n```html\n<f-when value=\"{{showButton}}\">\n    <my-button appearance=\"{{appearance}}\">{{text}}</my-button>\n</f-when>\n```\n\nExample template of component \"my-button\":\n```html\n<button class=\"{{appearance}}\">\n    <slot></slot>\n</button>\n```\n\nCombined with state:\n```json\n{\n    \"showButton\": true,\n    \"text\": \"Hello world\",\n    \"appearance\": \"fancy\"\n}\n```\n\nShould result in:\n```html\n<nested-components>\n    <template shadowrootmode=\"open\" shadowroot=\"open\">\n        <!--fe:b-->\n        <my-button data-fe=\"1\" appearance=\"fancy\">\n            <template shadowrootmode=\"open\" shadowroot=\"open\">\n                <button class=\"default\" data-fe=\"1\">\n                    <slot></slot>\n                </button>\n            </template>\n            <!--fe:b-->Hello world<!--fe:/b-->\n        </my-button>\n        <!--fe:/b-->\n    </template>\n</nested-components>\n```\n\n## Rendering Lifecycle\n\nFor information about the declarative rendering lifecycle inside\n`@microsoft/fast-element`, see\n[lifecycle.md](./lifecycle.md).\n","packages/fast-element/docs/declarative/schema-observer-map.md":"# Schema and Observer Map Architecture\n\nThis document provides a technical explainer for how the `Schema` and\n`ObserverMap` classes work together to describe data objects and automatically\nobserve them in FAST elements. Declarative `<f-template>` markup creates schemas\nautomatically, but the schema and observer map implementation are factored so\nthey can also be used without declarative templating.\n\n## Table of Contents\n\n1. [Overview](#overview)\n2. [The Schema Class](#the-schema-class)\n3. [The Observer Map Class](#the-observer-map-class)\n4. [Integration with f-template](#integration-with-f-template)\n5. [Initial Path Processing Flow](#initial-path-processing-flow)\n6. [Dynamic Path Processing Updates](#dynamic-path-processing-updates)\n7. [Observable Proxy System](#observable-proxy-system)\n8. [Examples](#examples)\n9. [Technical Details](#technical-details)\n\n## Overview\n\nThe Schema and Observer Map architecture enables automatic observation of complex nested data objects in FAST HTML templates. This system solves the problem of manually tracking all the binding paths used in declarative HTML templates, automatically creating observables for nested properties that are referenced in the template bindings.\n\n**Important**: This system is designed specifically for observable data objects (objects, arrays, and primitives). It explicitly does not handle binding paths that are assumed to be functions, methods, or other non-data constructs like event handlers.\n\n### Key Components\n\n- **Schema Class**: Generates JSON schemas that describe the structure and binding paths of data objects based on template analysis or manually registered paths\n- **Observer Map Class**: Uses the schema information to automatically define observable properties and create proxies for nested object observation\n- **f-template Integration**: Template processing automatically populates schemas and configures observer maps during template compilation\n- **Map helpers**: `@microsoft/fast-element` exposes the map helpers independently from declarative templating\n\n### Supported Data Types\n\nThe system automatically handles:\n- **Objects**: Nested object structures with observable properties\n- **Arrays**: Arrays with observable mutations and nested object elements  \n- **Primitives**: String, number, boolean values as object properties\n\n### Explicitly Not Handled\n\nThe system does not process:\n- **Function bindings**: Event handlers and method calls like `@click=\"{handleClick()}\"`\n- **Context paths**: Bindings using the `$c` prefix (e.g., `$c.parent.showNames`) resolve directly from the `ExecutionContext` and are not part of the data model\n- **Computed expressions**: Complex expressions that evaluate to non-data values\n- **Non-observable constructs**: Any binding assumed to reference functions or non-data objects\n\n## The Schema Class\n\nThe `Schema` class is responsible for building JSON Schema definitions that map the structure of data objects used in template bindings. It analyzes binding paths from template processing and constructs schemas that describe:\n\n- Root properties and their nested structures\n- Array contexts for repeat operations\n- Object property relationships\n- Cross-references to child components\n\n**Important**: Each schema created corresponds to a property that will belong to the custom element's class. The schema describes the expected structure and relationships of data that will be assigned to that property, enabling automatic observation of nested objects and arrays within that property's data structure.\n\n### Core Methods\n\n#### Constructor\n```typescript\nconstructor(name: string)\n```\nCreates a new schema instance for a specific custom element name and initializes an instance-level `schemaMap`. The instance also registers itself in the module-level `schemaRegistry` for cross-element `$ref` resolution. `FASTElementDefinition.schema` is optional; declarative templates assign it after parsing, while manual schema users can pass one in the element definition or directly to `observerMap({ schema })`.\n\n#### addPath\n```typescript\npublic addPath(config: RegisterPathConfig)\n```\nRegisters a binding path discovered during template processing. The configuration includes:\n- `pathConfig`: Describes the path type (`access`, `default`, `repeat`, `event`)\n- `rootPropertyName`: The root property this path belongs to\n- `childrenMap`: Information about child components referenced in this path\n\n**Note**: Only `access`, `default`, and `repeat` path types result in schema entries. Event paths are identified but not processed since they represent function calls rather than observable data.\n\n#### getSchema\n```typescript\npublic getSchema(rootPropertyName: string): JSONSchema | null\n```\nRetrieves the JSON schema for a specific root property.\n\n### Path Types\n\nThe schema handles different types of binding paths:\n\n- **`access`/`default`**: Direct property access like `{{user.name}}`\n- **`repeat`**: Array iteration contexts like `{{item}}` within `<f-repeat>`\n- **`event`**: Event handler bindings like `@click=\"{handleClick()}\"` - **Note: These are explicitly not processed by the schema system as they are assumed to be functions rather than observable data objects**\n\n### Schema Structure\n\nGenerated schemas follow JSON Schema format with FAST-specific extensions:\n\n```typescript\n{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://fast.design/schemas/my-element/users.json\",\n  \"type\": \"array\",\n  \"$ref\": \"#/$defs/user\",\n  \"$defs\": {\n    \"user\": {\n      \"$fast_context\": \"users\",\n      \"$fast_parent_contexts\": [null],\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {},\n        \"details\": {\n          \"type\": \"object\", \n          \"properties\": {\n            \"age\": {}\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n**Note on Property Types**: Properties accessed through binding paths (like `name` and `age` above) are defined with empty objects `{}` rather than specific JSON Schema types. This is because it's not possible to determine the exact primitive type (string, number, boolean, etc.) from the path syntax alone. The system focuses on structural relationships rather than specific data types for leaf properties.\n\n## The Observer Map Class\n\nThe `ObserverMap` class uses schema information to automatically configure observable properties on custom element prototypes. It creates the infrastructure needed to observe nested object changes without manual setup.\n\n### Constructor\n```typescript\nconstructor(classPrototype: any, schema: Schema, config?: ObserverMapConfig)\n```\nCreates an observer map instance that will configure the provided class prototype using the schema information.\n\n### defineProperties\n```typescript\npublic defineProperties(): void\n```\nThe main method that:\n1. Iterates through all root properties defined in the schema (each schema instance contains multiple root property schemas)\n2. Defines observable properties using FAST Element's `Observable.defineProperty` (an alternative to the `@observable` decorator syntax used in custom element classes)\n3. Sets up property change handlers that create proxies for nested objects\n\n### Property Change Handling\n\nWhen a root property transitions from `undefined` to a defined value, the observer map:\n1. Analyzes the schema to understand the expected object structure\n2. Creates proxies using the `assignObservables` utility function\n3. Establishes deep observation of nested properties based on the schema of that root property\n\n## Integration with f-template and manual schemas\n\nThe Schema and Observer Map classes integrate seamlessly with the f-template system, but they are not tied to it:\n\n### Template Processing Flow\n\n1. **Template Parsing**: When an `f-template` element is processed, it creates a `Schema` instance\n2. **Binding Discovery**: As template bindings are processed, paths are registered with `schema.addPath()`\n3. **Observer Map Creation**: If enabled, an `ObserverMap` is instantiated with the populated schema\n4. **Property Definition**: The observer map defines observable properties on the custom element prototype\n\n### Configuration\n\nObserver Map functionality is enabled through the `observerMap()` definition\nextension exported from `@microsoft/fast-element/observer-map.js`:\n\n```typescript\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nMyElement.define(\n  {\n    name: \"my-custom-element\",\n    template: declarativeTemplate(),\n  },\n  [observerMap()]\n);\n```\n\nWhen the `properties` key is omitted, all root properties discovered in the\ntemplate are observed. Add a `properties` object to opt into selective\nobservation behavior.\n\nFor non-declarative/manual schema use, pass the schema in the observer map\nconfiguration:\n\n```typescript\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-custom-element\");\nschema.addPath({\n  rootPropertyName: \"user\",\n  pathConfig: {\n    type: \"default\",\n    parentContext: null,\n    currentContext: null,\n    path: \"user.name\",\n  },\n  childrenMap: null,\n});\n\nMyElement.define(\n  {\n    name: \"my-custom-element\",\n  },\n  [observerMap({ schema })]\n);\n```\n\nYou can also attach a manual schema to the FAST element definition. This is the\npath used automatically by `declarativeTemplate()` after it parses a template:\n\n```typescript\nMyElement.define(\n  {\n    name: \"my-custom-element\",\n    schema,\n  },\n  [observerMap()]\n);\n```\n\n## Initial Path Processing Flow\n\nHere's how binding paths flow through the system during initial template processing:\n\n1. **Template Binding**: `{{user.details.personal.name}}`\n2. **Path Analysis**: Utilities identify root property (`user`) and nested path (`details.personal.name`)\n3. **Type Check**: Confirms this is a data binding (not an event handler like `@click=\"{handleClick()}\"`)\n4. **Schema Registration**: \n   ```typescript\n   schema.addPath({\n     pathConfig: {\n       type: \"access\",\n       currentContext: null,\n       parentContext: null,\n       path: \"user.details.personal.name\"\n     },\n     rootPropertyName: \"user\",\n     childrenMap: null\n   });\n   ```\n5. **Schema Building**: Creates nested object structure in JSON schema\n6. **Observable Definition**: Observer map makes `user` property observable\n7. **Proxy Creation**: When `user` is assigned, proxies are created for deep observation\n\n### Event Handler and Context Path Exclusion\n\nEvent handlers are identified but explicitly excluded from schema processing:\n- **Template Binding**: `@click=\"{handleClick()}\"`\n- **Path Analysis**: Utilities identify this as an event handler\n- **Type Check**: Confirms this is type `\"event\"`\n- **Schema Registration**: **Skipped** - Event handlers are not added to schemas since they represent function calls\n\nContext paths (`$c` prefix) are also excluded from schema processing:\n- **Template Binding**: `{{$c.parent.showNames}}` or `@click=\"{$c.parent.handleClick($c.event)}\"`\n- **Path Analysis**: Utilities detect the `$c.` prefix\n- **Schema Registration**: **Skipped** - These paths resolve from the `ExecutionContext`, not from observable data properties\n\n## Dynamic Path Processing Updates\n\nAfter initial schema creation and observer map setup, the system continues to dynamically update observation as data structures evolve:\n\n### Runtime Object Assignment\n\nWhen nested objects or array items become defined after initial setup:\n\n1. **Property Assignment**: A previously undefined nested property gets assigned a value\n   ```typescript\n   // Initially: user.details was undefined\n   user.details = { age: 30, location: { city: \"Seattle\" } };\n   ```\n\n2. **Schema Consultation**: The system consults the existing schema for this root property to understand expected nested structure\n\n3. **Proxy Creation**: New proxies are automatically created for the newly assigned nested objects based on the schema definition\n\n4. **Deep Observation Extension**: Observation is extended to all nested properties defined in the schema\n\n### Array Item Addition\n\nWhen new items are added to observed arrays:\n\n1. **Array Mutation**: Items are added via push, splice, or direct assignment\n   ```typescript\n   users.push({ name: \"John\", details: { age: 25 } });\n   ```\n\n2. **Array Observer Trigger**: The array proxy detects the mutation and triggers observation setup\n\n3. **Item Processing**: Each new array item is processed according to the array's context schema definition\n\n4. **Nested Object Proxying**: New nested objects within array items are automatically proxied based on the schema structure\n\n## Observable Proxy System\n\nThe proxy system in `utilities.ts` provides the deep observation capabilities:\n\n### assignObservables Function\n\n```typescript\nexport function assignObservables(\n    schema: JSONSchema | JSONSchemaDefinition,\n    rootSchema: JSONSchema,\n    data: any,\n    target: any,\n    rootProperty: string\n): typeof Proxy\n```\n\nThis function:\n- Analyzes the data type (object, array, primitive)\n- Creates proxies for objects and arrays\n- Establishes property observation for nested structures\n- Handles array mutations and object property changes\n\n### Proxy Behavior\n\nProxied objects:\n- Trigger Observable notifications when properties change\n- Automatically proxy newly assigned nested objects\n- Track array mutations and splice operations\n- Maintain references to root properties for change notifications\n\n## Examples\n\n### Basic Object Observation\n\n**Template:**\n```html\n<f-template name=\"user-profile\">\n  <template>\n    <div>{{user.name}} - {{user.details.age}} years old</div>\n    <div>Location: {{user.details.location.city}}</div>\n  </template>\n</f-template>\n```\n\n**Generated Schema Structure:**\n```typescript\n// Root property: \"user\"\n{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://fast.design/schemas/user-profile/user.json\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": {},\n    \"details\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"age\": {},\n        \"location\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"city\": {}\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n### Array with Repeat Context\n\n**Template:**\n```html\n<f-template name=\"user-list\">\n  <template>\n    <f-repeat value=\"{{user in users}}\">\n      <div>{{user.name}} has {{user.posts.length}} posts</div>\n    </f-repeat>\n  </template>\n</f-template>\n```\n\n**Generated Schema Structure:**\n```typescript\n// Root property: \"users\"\n{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://fast.design/schemas/user-list/users.json\",\n  \"type\": \"array\",\n  \"$ref\": \"#/$defs/user\",\n  \"$defs\": {\n    \"user\": {\n      \"$fast_context\": \"users\",\n      \"$fast_parent_contexts\": [null],\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {},\n        \"posts\": {\n          \"type\": \"array\"\n        }\n      }\n    }\n  }\n}\n```\n\n### Nested Repeat Contexts\n\n**Template:**\n```html\n<f-template name=\"complex-data\">\n  <template>\n    <f-repeat value=\"{{user in users}}\">\n      <div>{{user.name}}</div>\n      <f-repeat value=\"{{post in user.posts}}\">\n        <div>{{post.title}} - {{post.metadata.views}} views</div>\n      </f-repeat>\n    </f-repeat>\n  </template>\n</f-template>\n```\n\nThis creates nested context definitions where the `post` context understands its relationship to the parent `user` context.\n\n## Technical Details\n\n### Schema Registry\n\nThe `Schema` module exports a module-level `schemaRegistry`:\n```typescript\nexport const schemaRegistry: CachedPathMap = new Map();\n```\n\nEach `Schema` instance owns an instance-level `schemaMap: Map<string, JSONSchema>` and registers itself in `schemaRegistry` on construction.\n\nThe registry structure is: `Map<customElementName, Map<rootPropertyName, JSONSchema>>`\n\n**Rationale for Module-level Registry**: The registry allows cross-element `$ref` resolution for nested components inside f-templates. When an object or array is passed to another custom element within an f-template, that nested component needs to observe the entire root property's structure based on the binding paths within that nested component. The registry allows all components to access and contribute to the same schema definitions, ensuring consistent observation behavior across component boundaries.\n\n### Context Tracking\n\nThe schema system tracks binding contexts using special metadata:\n- `$fast_context`: The array property name that created this context\n- `$fast_parent_contexts`: Chain of parent contexts leading to the root\n\n### Performance Considerations\n\n- **Lazy Proxy Creation**: Proxies are only created when objects are assigned to observable properties\n- **Weak Map Caching**: The system uses WeakMaps to avoid memory leaks when tracking proxied objects\n- **Schema Reuse**: Schemas are generated once per custom element and reused across instances\n\n### Memory Management\n\n- **WeakMap Usage**: `objectTargetsMap` and `observedArraysMap` use WeakMaps to automatically clean up references\n- **Proxy Identification**: Proxies are marked with `$isProxy` to prevent double-proxying\n- **Reference Tracking**: Target elements and root properties are tracked for proper change notification\n\n## Debugging and Troubleshooting\n\n### Schema Inspection\n\nYou can inspect generated schemas using the module-level `schemaRegistry` import:\n\n```typescript\nimport { schemaRegistry } from \"@microsoft/fast-element\";\n\n// Get all schemas for an element:\nconst elementSchemas = schemaRegistry.get('my-element');\nconst userSchema = elementSchemas?.get('users');\nconsole.log(JSON.stringify(userSchema, null, 2));\n```\n\n### Observer Map Status\n\n`observerMap()` is applied as a definition extension before the element is\nregistered. There is no public `TemplateElement.options()` state to inspect.\nTo verify that observer mapping ran, inspect the generated schema and the\nobservable accessors on the element prototype:\n\n```typescript\nimport { Observable, schemaRegistry } from \"@microsoft/fast-element\";\n\nconst schemas = schemaRegistry.get(\"my-element\");\nconst accessors = Observable.getAccessors(MyElement.prototype).map(a => a.name);\nconsole.log(schemas, accessors);\n```\n\n### Proxy Detection\n\nObjects processed by the system will have a `$isProxy` property:\n```typescript\nconsole.log('Is proxied:', myObject.$isProxy === true);\n```\n","packages/fast-element/docs/declarative/syntax.md":"# FAST Element Declarative HTML\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-element.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-element)\n\nThe declarative entrypoint in `@microsoft/fast-element` interprets FAST\ndeclarative HTML syntax as a template for a FAST web component.\n\nThis document focuses on declarative-runtime implementation details:\ntemplate structure, prerendered markup requirements, hydration promise APIs,\nbinding configuration, syntax, and integration testing.\n\nFor package installation, using `declarativeTemplate()`, extension setup, and\nthe package-level hydration overview, see the\n[FAST Element README](../../README.md#declarative-html) and\n[Prerendered Content Optimization](../../README.md#prerendered-content-optimization).\nFor user-facing guides covering f-template syntax, element definition, and\nserver-side rendering, see the\n[Declarative HTML docs](https://fast.design/docs/3.x/declarative-templates/overview/).\n\n## Template Structure\n\nAfter importing the declarative APIs as shown in the README, templates are\nassociated with an element through\n`<f-template name=\"[custom-element-name]\"><template>...</template></f-template>`.\nThe host custom element should be defined with\n`template: declarativeTemplate()`. This automatically defines `<f-template>` in\nthe relevant registry and waits for the matching declarative template when it is\nalready present or inserted later.\n\nThe `@microsoft/fast-element` entrypoint itself remains\nside-effect free at import time. Declarative APIs lazily install declarative\ndebug messages when they create templates. Hydratable `ViewTemplate` support is\ninstalled only when `enableHydration()` is called from\n`@microsoft/fast-element/hydration.js`.\n\n`observerMap()` and `attributeMap()` are available from\n`@microsoft/fast-element/observer-map.js` and\n`@microsoft/fast-element/attribute-map.js`, including when using the maps\nwithout declarative templates.\n\nExample:\n```html\n<my-custom-element greeting=\"Hello world\">\n    <template shadowrootmode=\"open\">\n        Hello world\n    </template>\n</my-custom-element>\n<f-template name=\"my-custom-element\">\n    <template>{{greeting}}</template>\n</f-template>\n```\n\nThe legacy `defer-hydration` and `needs-hydration` attributes are no longer\nrequired.\n\n## HTML Comments\n\nBindings and FAST directive markup inside HTML comments are unsupported. This\nincludes double-brace and triple-brace bindings, client-only bindings, and\ncommented-out elements containing bindings or directives.\n\nThe declarative parsers scan template strings and do not reliably exclude\ncomments. A comment such as `<!-- {{greeting}} -->` can still contribute a binding,\nleading to unexpected evaluation, rendering errors, or hydration mismatches.\nRemove unused bound markup rather than commenting it out, and keep explanatory\ncomments free of binding syntax and FAST directive tags.\n\n## Non-browser HTML Rendering\n\nOne of the benefits of FAST declarative HTML templates is that the server can\nbe stack agnostic because JavaScript does not need to be interpreted to emit\nthe initial HTML. This does not mean the FAST Element client runtime runs on the\nserver: custom element definition, hydration, client rendering, and reactive\nupdates still run in the browser `Window`. The declarative runtime expects\nhydratable comment markers and datasets when prerendered content is generated.\nFor the required marker format and initial-state application details, see\n[rendering.md](./rendering.md).\n\n## Hydration promise APIs\n\nFAST Element's declarative APIs expose hydration readiness promises that are\nuseful to application code.\n\nHydration is opt-in. Call `enableHydration()` before FAST elements connect when\nyou want prerendered Declarative Shadow DOM to be reused, then await\nthe returned controller's `whenHydrated()` promise when code needs to run after\nthe active hydration batch:\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nconst hydration = enableHydration();\nawait hydration.whenHydrated();\n```\n\nThe hydration hook no-ops for new prerendered elements after the initial\nhydration batch completes by default. Streaming scenarios that append hydratable\nDeclarative Shadow DOM later can keep the hook active:\n\n```typescript\nimport { enableHydration, StopHydration } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({\n    stopHydration: StopHydration.never,\n});\n```\n\nWhen `StopHydration.never` is used, `enableHydration().whenHydrated()`\nintentionally remains pending because hydration has no global completion point.\n\nFAST Element 3.x data-free hydration markers are selected by default. Existing\nserver output that uses FAST Element 2.x indexed markers can be hydrated by\nselecting the v2 marker reader:\n\n```typescript\nimport { enableHydration, markers_v2 } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ markers: markers_v2 });\n```\n\nSet `\"markers_v2\": true` in the matching `@microsoft/fast-build`\nconfiguration so the generated HTML uses the same marker format.\n\n## `observerMap`\n\nWhen the `observerMap()` extension is applied to an element definition,\nit automatically sets up deep reactive observation for root properties\ndiscovered in the template. Declarative templates assign `definition.schema`\nduring template resolution, so `observerMap()` has schema data automatically.\nFor non-declarative/manual schemas, import from\n`@microsoft/fast-element/observer-map.js` and pass `observerMap({ schema })`.\n\n```typescript\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n```\n\nFor finer control, pass a configuration object with a `properties` key that maps root property names to a recursive path tree:\n\n```typescript\nUserProfile.define(\n    {\n        name: \"user-profile\",\n        template: declarativeTemplate(),\n    },\n    [\n        observerMap({\n            properties: {\n                user: {\n                    name: true,          // user.name — observed\n                    details: {\n                        age: true,       // user.details.age — observed\n                        history: false,  // user.details.history — NOT observed\n                    },\n                },\n                // root properties not listed here are skipped\n            },\n        }),\n    ],\n);\n```\n\nEach path entry can be:\n- **`true`** — observe this path and all descendants.\n- **`false`** — skip this path and all descendants.\n- **An object** with an optional `$observe` boolean and child property overrides.\n\nUse `$observe: false` on a node to skip it by default, then re-include specific children:\n\n```typescript\nobserverMap({\n    properties: {\n        analytics: {\n            charts: {\n                $observe: false,       // charts NOT observed by default\n                activeChart: true,     // ...except activeChart IS observed\n            },\n        },\n    },\n});\n```\n\nWhen `properties` is omitted, all root properties are observed. When\n`properties` is present but empty (`{ properties: {} }`), no root properties\nare observed.\n\nWhen observer-map data is updated with `deepMerge`, array properties are replaced\nrather than updated in place. This avoids synchronous reentrant array work and\nallows repeat bindings to observe the new array reference. Replacement arrays\nare processed through observerMap so nested item properties and subsequent array\nmutations remain observable.\n\nManual schema example:\n\n```typescript\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-element\");\nschema.addPath({\n    rootPropertyName: \"user\",\n    pathConfig: {\n        type: \"default\",\n        parentContext: null,\n        currentContext: null,\n        path: \"user.name\",\n    },\n    childrenMap: null,\n});\n\nMyElement.define({ name: \"my-element\" }, [observerMap({ schema })]);\n```\n\n## `attributeMap`\n\nWhen the `attributeMap()` extension is applied to an element definition,\nit automatically creates reactive `@attr` properties for every **leaf binding**\nin the template — simple expressions like `{{foo}}` or `id=\"{{fooBar}}\"` that\nhave no nested properties. Declarative templates provide the schema\nautomatically. For non-declarative/manual schemas, place the optional `schema`\non the FAST element definition and import `attributeMap()` from\n`@microsoft/fast-element`.\n\n```typescript\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\n```\n\nBy default, the binding key is treated as a camelCase property name and the HTML\nattribute name is derived by converting it to kebab-case. Properties already\ndecorated with `@attr` or `@observable` on the class are left untouched.\n\n```typescript\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [attributeMap()],\n);\n```\n\nWith the template:\n\n```html\n<f-template name=\"my-element\">\n    <template>\n        <p>{{greeting}}</p>\n        <p>{{firstName}}</p>\n    </template>\n</f-template>\n```\n\nThis registers `greeting` (attribute `greeting`, property `greeting`) and\n`firstName` (attribute `first-name`, property `firstName`) as `@attr`\nproperties on the element prototype, enabling `setAttribute(\"first-name\",\n\"Jane\")` to trigger a template re-render automatically.\n\n### `attribute-name-strategy`\n\nThe `attribute-name-strategy` configuration option controls how template binding\nkeys map to HTML attribute names. This matches the build-time\n`--attribute-name-strategy` option in `@microsoft/fast-build`.\n\n| Strategy | Behaviour | Example |\n|---|---|---|\n| `\"camelCase\"` (default) | Binding key is the camelCase property; attribute name is derived as kebab-case | `{{fooBar}}` → property `fooBar`, attribute `foo-bar` |\n| `\"none\"` | Binding key used as-is for both property and attribute | `{{foo-bar}}` → property `foo-bar`, attribute `foo-bar` |\n\n```typescript\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [\n        attributeMap({\n            \"attribute-name-strategy\": \"none\",\n        }),\n    ],\n);\n```\n\nWhen using the `\"none\"` strategy, property names may contain dashes and must be\naccessed via bracket notation (e.g. `element[\"foo-bar\"]`).\n\n## Syntax\n\nAll bindings use a handlebars-like syntax.\n\nSome bindings are only relevant to the browser, such as for click handlers or other pieces of dynamic interaction. As such, their bindings use single curly braces `{}`, this is to prevent an intial SSR (Server Side Rendering) or other build time rendering technologies from needing to interpret them.\n\nIf a binding is relevant to both client and the back end rendering engine, it will use `{{}}` or `{{{}}}` depending on what type of data injection is being done.\n\nBrowser-only bindings:\n- Event bindings\n- Attribute directives\n\n### Content binding\n\n```html\n{{text}}\n```\n\n### Event binding\n\nEvent bindings must include the `()` as well as being preceeded by `@` in keeping with the `@microsoft/fast-element` tagged template syntax.\n\n```html\n<button @click=\"{handleClick()}\"></button>\n```\n\nYou can pass the DOM event object, the execution context, or both as arguments. Any other argument is treated as a binding expression and resolved against the current data source.\n\n**`$e` — DOM event object (preferred):**\n```html\n<button @click=\"{handleClick($e)}\"></button>\n```\n\n**`$c` — execution context:**\n```html\n<button @click=\"{handleClick($c)}\"></button>\n```\n\n**`$c.somePath` — a property of the execution context (e.g. `$c.parent`, `$c.event`):**\n```html\n<button @click=\"{handleClick($c.parent)}\"></button>\n```\n\n**Multiple arguments:**\n```html\n<button @click=\"{handleClick($e, $c)}\"></button>\n```\n\n**Arbitrary binding expressions** — any token that is not `$e` or `$c` is resolved as a binding path on the data source:\n```html\n<button @click=\"{handleClick(user.id)}\"></button>\n```\n\nUse `$e` for the DOM event object.\n\n### Directives\n\nDirectives are assumed to be either an attribute directive or a directive that also serves a template. Both are prepended by `f-`. The logic of these directives and what their use cases are is explained in the [FAST html documentation](https://fast.design/docs/getting-started/html-directives).\n\nAttribute directives are part of [client side binding](#syntax) and therefore use the `{}` syntax.\n\nAttribute directives include:\n- **slotted**\n\n    Example:\n    ```html\n    <slot f-slotted=\"{slottedNodes}\"></slot>\n    <slot f-slotted=\"{slottedNodes filter elements()}\"></slot>\n    <slot f-slotted=\"{slottedNodes filter elements(div, p)}\"></slot>\n    ```\n\n- **children**\n\n    Example:\n    ```html\n    <ul f-children=\"{listItems}\"><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    <ul f-children=\"{listItems filter elements()}\"><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    <ul f-children=\"{listItems filter elements(li)}\"><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    ```\n\n- **ref**\n\n    Example:\n    ```html\n    <video f-ref=\"{video}\"></video>\n    ```\n\nTemplate directives include:\n- **when**\n\n    Example:\n    ```html\n    <f-when value=\"{{show}}\">Hello world</f-when>\n    <f-when value=\"{{!show}}\">Goodbye world</f-when>\n    ```\n\nThe following operators can also be used:\n- `==`\n- `!=`\n- `>=`\n- `>`\n- `<=`\n- `<`\n- `||`\n- `&&`\n\nWhere the right operand can be either a reference to a value (string e.g. `{{foo == 'bar'}}`, boolean e.g. `{{foo == true}}`, number e.g. `{{foo == 3}}`) or another binding value.\n\n- **repeat**\n\n    Example:\n    ```html\n    <ul><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    ```\n\n    Bindings inside `<f-repeat>` without a context prefix resolve to the custom element. For example, `{{title}}` below resolves to the host element's `title` property:\n\n    ```html\n    <ul><f-repeat value=\"{{item in list}}\"><li>{{item}} - {{title}}</li></f-repeat></ul>\n    ```\n\n### Execution Context Access\n\nIn imperative fast-element templates, every binding expression receives both the data source and the execution context: `${(x, c) => c.parent.handleClick(c.event)}`. Declarative `<f-template>` expressions can access the same execution context using the `$c` prefix.\n\nThis is particularly useful inside `<f-repeat>`, where `$c.parent` refers to the parent view-model (typically the host element) and `$c.event` provides the DOM event.\n\nEvent handler with context access:\n\n```html\n<f-repeat value=\"{{item in items}}\">\n    <button @click=\"{$c.parent.handleItemClick($c.event)}\">{{item.name}}</button>\n</f-repeat>\n```\n\nConditional rendering using a host property inside a repeat:\n\n```html\n<f-repeat value=\"{{item in items}}\">\n    <f-when value=\"{{$c.parent.showNames}}\">\n        <span>{{item.name}}</span>\n    </f-when>\n</f-repeat>\n```\n\n### Unescaped HTML\n\nYou can add unescaped HTML using triple braces, this will create an additional `div` element as the HTML needs an element to bind to. Where possible it is advisable to not use unescaped HTML and instead use other binding techniques.\n\nExample:\n```html\n{{{html}}}\n```\n\n### Code samples inside `<code>`\n\nAny text or attribute value inside a `<code>` element has its `{` and `}` characters automatically replaced with the HTML numeric character references `&#123;` and `&#125;` before template parsing. As a result, binding delimiters (`{{...}}`, `{{{...}}}`, `{...}`) inside `<code>` are rendered as literal text rather than being interpreted as FAST bindings — making `<code>` blocks safe for embedding code samples that contain binding-like syntax. No marker attribute is needed.\n\nIn addition, the build-time renderer (`@microsoft/fast-build`) entity-escapes the `<` and `>` of every **FAST directive tag** (`<f-when>`, `</f-when>`, `<f-repeat>`, `</f-repeat>`) it finds inside `<code>`, so authors can write the directive literally without manually entity-encoding the angle brackets. Tag-name matching is case-insensitive. Non-directive elements inside `<code>` — real HTML elements such as `<button>` and custom elements such as `<my-widget>` — keep their angle brackets and continue to render as live DOM elements; only brace-binding syntax in their attribute values is neutralised.\n\nThe brace escape is applied symmetrically by both the server-side renderer and the client-side `<f-template>` parser, so binding positions stay in sync between SSR and hydration. The directive-tag angle escape only needs to run on the server: the DOM serializer re-encodes `<`/`>` in text content, so the client-side parser never sees a raw `<f-when>` inside `<code>` regardless of what the page source contained. This behaviour mirrors how Microsoft WebUI's `webui-press` markdown renderer transparently escapes the same characters inside code spans and code fences.\n\nExample:\n```html\n<f-template name=\"docs-page\">\n    <template>\n        <h1>{{title}}</h1>\n        <pre><code>span {{greeting}} /span</code></pre>\n        <pre><code><f-when value=\"{{flag}}\">wrapped</f-when></code></pre>\n        <pre><code>Try: <button class=\"demo\">click</button></code></pre>\n    </template>\n</f-template>\n```\n\nThe `<h1>` binds to `title`, the first `<code>` displays the literal text `span {{greeting}} /span`, the second displays the literal text `<f-when value=\"{{flag}}\">wrapped</f-when>`, and the third renders a live `<button>` element alongside the surrounding sample text.\n\n## Writing Components\n\nWhen writing components with the intention of using the declarative HTML syntax, it is imperative that components are written with styling and rendering of the component to be less reliant on any JavaScript state management. An example of this is relying on `elementInterals` state to style a component.\n\n## WebUI Integration Testing\n\nThe fixture tests in `test/declarative/fixtures/` are also validated against\n[`@microsoft/webui`](https://github.com/microsoft/webui) to ensure\ncross-renderer compatibility. The build step renders each fixture's templates\nwith `webui build --plugin=fast`, then the existing Playwright specs run\nagainst the webui-rendered output.\n\n```shell\n# Build fixtures with webui and run Playwright tests\nnpm run test:webui-integration -w @microsoft/fast-element\n\n# Or run the steps separately\nnpm run build:fixtures:webui -w @microsoft/fast-element\nnpm exec -w @microsoft/fast-element -- playwright test --config=playwright.declarative.webui.config.ts\n```\n\nThis is also run automatically in CI via the `ci-webui-integration.yml` GitHub Action on pull requests and pushes to `main`.\n\nSome tests are conditionally skipped during webui integration runs due to known\nrendering differences between `fast-build` and `webui`. The\n`playwright.declarative.webui.config.ts` file sets\n`FAST_WEBUI_INTEGRATION=true`, and affected tests use `test.skip()` with a\ndescriptive reason. See the WebUI Integration Tests section in\n[design.md](./design.md) for the full list.\n","packages/fast-element/docs/di/api-report.api.md":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport const all: (key: any, searchAncestors?: boolean) => ReturnType<typeof DI.inject>;\n\n// @public\nexport type AsyncRegistrationLocator = (key: Key) => Promise<Registration | null>;\n\n// @public\nexport interface Container extends ServiceLocator {\n    createChild(config?: Partial<Omit<ContainerConfiguration, \"parentLocator\">>): Container;\n    getFactory<T extends Constructable>(key: T): Factory<T>;\n    getResolver<K extends Key, T = K>(key: K | Key, autoRegister?: boolean): Resolver<T> | null;\n    register(...params: any[]): Container;\n    // Warning: (ae-forgotten-export) The symbol \"Constructable\" needs to be exported by the entry point di.d.ts\n    registerFactory<T extends Constructable>(key: T, factory: Factory<T>): void;\n    registerResolver<K extends Key, T = K>(key: K, resolver: Resolver<T>): Resolver<T>;\n    registerTransformer<K extends Key, T = K>(key: K, transformer: Transformer_2<T>): boolean;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"ContextDecorator\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport const Container: ContextDecorator<Container>;\n\n// @public\nexport interface ContainerConfiguration {\n    asyncRegistrationLocator: AsyncRegistrationLocator;\n    defaultResolver(key: Key, handler: Container): Resolver;\n    parentLocator: ParentLocator;\n    responsibleForOwnerRequests: boolean;\n}\n\n// @public\nexport const ContainerConfiguration: Readonly<{\n    default: Readonly<ContainerConfiguration>;\n}>;\n\n// Warning: (ae-internal-missing-underscore) The name \"ContainerImpl\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport class ContainerImpl implements DOMContainer {\n    constructor(owner: any, config: ContainerConfiguration);\n    // (undocumented)\n    protected config: ContainerConfiguration;\n    // (undocumented)\n    createChild(config?: Partial<Omit<ContainerConfiguration, \"parentLocator\">>): Container;\n    // (undocumented)\n    get depth(): number;\n    // (undocumented)\n    get<K extends Key>(key: K): Resolved<K>;\n    // (undocumented)\n    getAll<K extends Key>(key: K, searchAncestors?: boolean): readonly Resolved<K>[];\n    // (undocumented)\n    getAsync<K extends Key>(key: K): Promise<Resolved<K>>;\n    // (undocumented)\n    getFactory<K extends Constructable>(Type: K): Factory<K>;\n    // (undocumented)\n    getResolver<K extends Key, T = K>(key: K | Key, autoRegister?: boolean): Resolver<T> | null;\n    // (undocumented)\n    handleContextRequests(enable: boolean): void;\n    // (undocumented)\n    has<K extends Key>(key: K, searchAncestors?: boolean): boolean;\n    // (undocumented)\n    protected owner: any;\n    // (undocumented)\n    get parent(): ContainerImpl | null;\n    // (undocumented)\n    register(...params: any[]): Container;\n    // (undocumented)\n    registerFactory<K extends Constructable>(key: K, factory: Factory<K>): void;\n    // (undocumented)\n    registerResolver<K extends Key, T = K>(key: K, resolver: Resolver<T>): Resolver<T>;\n    // (undocumented)\n    registerTransformer<K extends Key, T = K>(key: K, transformer: Transformer_2<T>): boolean;\n    // (undocumented)\n    get responsibleForOwnerRequests(): boolean;\n}\n\n// @public\nexport const DefaultResolver: Readonly<{\n    none(key: Key): Resolver;\n    singleton(key: Key): Resolver;\n    transient(key: Key): Resolver;\n}>;\n\n// @public\nexport const DI: Readonly<{\n    installAsContextRequestStrategy(fallback?: () => DOMContainer): void;\n    createContainer(config?: Partial<ContainerConfiguration>): Container;\n    findResponsibleContainer(target: EventTarget, fallback?: () => DOMContainer): DOMContainer;\n    findParentContainer(target: EventTarget, fallback?: () => DOMContainer): DOMContainer;\n    getOrCreateDOMContainer(target?: EventTarget, config?: Partial<Omit<ContainerConfiguration, \"parentLocator\">>): DOMContainer;\n    getDependencies(Type: Constructable | Injectable): Key[];\n    defineProperty(target: {}, propertyName: string, key: Key, respectConnection?: boolean): void;\n    createContext: typeof createContext;\n    inject(...dependencies: Key[]): (target: any, key?: string | number, descriptor?: PropertyDescriptor | number) => void;\n    transient<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;\n    singleton<T extends Constructable>(target: T & Partial<RegisterSelf<T>>, options?: SingletonOptions): T & RegisterSelf<T>;\n}>;\n\n// @public\nexport interface DOMContainer extends Container {\n    // @beta\n    handleContextRequests(enable: boolean): void;\n}\n\n// @public\nexport const DOMContainer: ContextDecorator<DOMContainer>;\n\n// @public\nexport interface Factory<T extends Constructable = any> {\n    construct(container: Container, dynamicDependencies?: Key[]): Resolved<T>;\n    constructAsync(container: Container, dynamicDependencies?: Key[]): Promise<Resolved<T>>;\n    registerTransformer(transformer: Transformer_2<T>): void;\n    readonly Type: T;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"FactoryImpl\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport class FactoryImpl<T extends Constructable = any> implements Factory<T> {\n    constructor(Type: T, dependencies: Key[]);\n    // (undocumented)\n    construct(container: Container, dynamicDependencies?: Key[]): Resolved<T>;\n    // (undocumented)\n    constructAsync(container: Container, dynamicDependencies?: Key[]): Promise<Resolved<T>>;\n    // (undocumented)\n    registerTransformer(transformer: (instance: any) => any): void;\n    // (undocumented)\n    Type: T;\n}\n\n// @public\nexport function ignore(target: Injectable, property?: string | number, descriptor?: PropertyDescriptor | number): void;\n\n// @public\nexport const inject: (...dependencies: Key[]) => (target: any, key?: string | number, descriptor?: PropertyDescriptor | number) => void;\n\n// @public\nexport type Injectable<T = {}> = Constructable<T> & {\n    inject?: Key[];\n};\n\n// @public\nexport interface InterfaceConfiguration {\n    friendlyName?: string;\n    respectConnection?: boolean;\n}\n\n// @public\nexport type Key = PropertyKey | object | ContextDecorator | Constructable | Resolver;\n\n// @public\nexport const lazy: (key: any) => any;\n\n// @public\nexport const newInstanceForScope: (key: any) => any;\n\n// @public\nexport const newInstanceOf: (key: any) => any;\n\n// @public\nexport const optional: (key: any) => any;\n\n// @public\nexport type ParentLocator = (owner: any) => Container | null;\n\n// @public\nexport type RegisterSelf<T extends Constructable> = {\n    register(container: Container): Resolver<InstanceType<T>>;\n    registerInRequestor: boolean;\n};\n\n// @public\nexport interface Registration<K = any> {\n    register(container: Container): Resolver<K>;\n}\n\n// @public\nexport const Registration: Readonly<{\n    instance<T>(key: Key, value: T): Registration<T>;\n    singleton<T extends Constructable>(key: Key, value: T): Registration<InstanceType<T>>;\n    transient<T extends Constructable>(key: Key, value: T): Registration<InstanceType<T>>;\n    callback<T>(key: Key, callback: ResolveCallback<T>): Registration<Resolved<T>>;\n    cachedCallback<T>(key: Key, callback: ResolveCallback<T>): Registration<Resolved<T>>;\n    aliasTo<T>(originalKey: T, aliasKey: Key): Registration<Resolved<T>>;\n}>;\n\n// @public\nexport interface Registry {\n    register(container: Container, ...params: unknown[]): void | Resolver;\n}\n\n// @public\nexport type ResolveCallback<T = any> = (handler: Container, requestor: Container, resolver: Resolver<T>) => T;\n\n// Warning: (ae-forgotten-export) The symbol \"ResolverLike\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport type Resolved<K> = K extends ContextDecorator<infer T> ? T : K extends Constructable ? InstanceType<K> : K extends ResolverLike<any, infer T1> ? T1 extends Constructable ? InstanceType<T1> : T1 : K;\n\n// @public\nexport interface Resolver<K = any> extends ResolverLike<Container, K> {\n}\n\n// @public\nexport class ResolverBuilder<K> {\n    constructor(container: Container, key: Key);\n    aliasTo(destinationKey: Key): Resolver<K>;\n    cachedCallback(value: ResolveCallback<K>): Resolver<K>;\n    callback(value: ResolveCallback<K>): Resolver<K>;\n    instance(value: K): Resolver<K>;\n    singleton(value: Constructable): Resolver<K>;\n    transient(value: Constructable): Resolver<K>;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"ResolverImpl\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport class ResolverImpl implements Resolver, Registration {\n    // (undocumented)\n    get $isResolver(): true;\n    constructor(key: Key, strategy: ResolverStrategy, state: any);\n    // (undocumented)\n    getFactory(container: Container): Factory | null;\n    // (undocumented)\n    key: Key;\n    // (undocumented)\n    register(container: Container): Resolver;\n    // (undocumented)\n    resolve(handler: Container, requestor: Container): any;\n    // (undocumented)\n    resolveAsync(handler: Container, requestor: Container): Promise<any>;\n    // (undocumented)\n    state: any;\n    // (undocumented)\n    strategy: ResolverStrategy;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"ResolverStrategy\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport const enum ResolverStrategy {\n    // (undocumented)\n    alias = 5,\n    // (undocumented)\n    array = 4,\n    // (undocumented)\n    callback = 3,\n    // (undocumented)\n    instance = 0,\n    // (undocumented)\n    singleton = 1,\n    // (undocumented)\n    transient = 2\n}\n\n// @public\nexport interface ServiceLocator {\n    get<K extends Key>(key: K): Resolved<K>;\n    get<K extends Key>(key: Key): Resolved<K>;\n    get<K extends Key>(key: K | Key): Resolved<K>;\n    getAll<K extends Key>(key: K, searchAncestors?: boolean): readonly Resolved<K>[];\n    getAll<K extends Key>(key: Key, searchAncestors?: boolean): readonly Resolved<K>[];\n    getAll<K extends Key>(key: K | Key, searchAncestors?: boolean): readonly Resolved<K>[];\n    getAsync<K extends Key>(key: K): Promise<Resolved<K>>;\n    getAsync<K extends Key>(key: Key): Promise<Resolved<K>>;\n    getAsync<K extends Key>(key: K | Key): Promise<Resolved<K>>;\n    has<K extends Key>(key: K | Key, searchAncestors: boolean): boolean;\n}\n\n// @public\nexport const ServiceLocator: ContextDecorator<ServiceLocator>;\n\n// Warning: (ae-forgotten-export) The symbol \"singletonDecorator\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport function singleton<T extends Constructable>(): typeof singletonDecorator;\n\n// @public (undocumented)\nexport function singleton<T extends Constructable>(options?: SingletonOptions): typeof singletonDecorator;\n\n// @public\nexport function singleton<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;\n\n// @public\ntype Transformer_2<K> = (instance: Resolved<K>) => Resolved<K>;\nexport { Transformer_2 as Transformer }\n\n// Warning: (ae-forgotten-export) The symbol \"transientDecorator\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport function transient<T extends Constructable>(): typeof transientDecorator;\n\n// @public\nexport function transient<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;\n\n// Warning: (ae-internal-missing-underscore) The name \"validateKey\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport function validateKey(key: any): void;\n\n// Warnings were encountered during analysis:\n//\n// dist/dts/di/di.d.ts:479:5 - (ae-forgotten-export) The symbol \"createContext\" needs to be exported by the entry point di.d.ts\n// dist/dts/di/di.d.ts:540:5 - (ae-forgotten-export) The symbol \"SingletonOptions\" needs to be exported by the entry point di.d.ts\n\n// (No @packageDocumentation comment for this package)\n\n```\n","packages/fast-element/docs/migration/fast-element-2.md":"# Changes in FASTElement 2.0\n\n## Breaking Changes\n\n* `HTMLDirective` - The `targetIndex: number` property has been replaced by a `targetId: string` property. The `createBehavior` method no longer takes a target `Node` but instead takes a `BehaviorTargets` instance. The actual target can be looked up on the `BehaviorTargets` instance by indexing with the `targetId` property.\n* `compileTemplate()` - Internals have been significantly changed. The implementation no longer uses a TreeWalker. The return type has change to an `HTMLTemplateCompilationResult` with different properties.\n* `View` and `HTMLView` - Type parameters added to enable strongly typed views based on their data source. The constructor of `HTMLView` has a new signature based on changes to the compiler's output. Internals have been cleaned up and no longer rely on the Range type.\n* `ElementViewTemplate`, `SyntheticViewTemplate`, and `ViewTemplate` - Added type parameters throughout. Logic to instantiate and apply behaviors moved out of the template and into the view where it can be lazily executed. Removed the ability of the `render` method to take a string id of the node to render to. You must provide a node.\n* `DOM` - Tree Walker methods are no longer used and are thus removed. The API for removing child nodes has been removed as well since it was only used in one place and could be inlined. The helper `createCustomAttributePlaceholder()` no longer requires an attribute name. It will be uniquely generated internally.\n* `class` - Bindings to `class` are now more nuanced. Binding directly to `class` will simply set the `className` property. If you need to bind to `class` knowing that manual JS will also manipulate the `classList` in addition to the binding, then you should now bind to `:classList` instead. This allows for performance optimizations in the simple, most common case.\n* `Behavior` and `ViewBehavior` - `Behavior` now requires an `ExecutionContext` for `unbind`. Behaviors can be used for elements or views. `ViewBehavior` has been introduced for use exclusively with views, and provides some optimization opportunities.\n* `RefBehavior` has been replaced with `RefDirective`. The directive also implements `ViewBehavior` allowing a single directive instance to be shared across all template instances that use the ref.\n* Removed `SlottedBehavior` and `ChildrenBehavior` have been replaced with `SlottedDirective` and `ChildrenDirective`. These directives allow a single directive instance to be shared across all template instances that use the ref.\n* Removed `AttachedBehaviorHTMLDirective` and `AttachedBehaviorType` since they are no longer used in the new directive/behavior architecture for ref, slotted, and children.\n* Renamed `Notifier#source` to `Notifier#subject` to align with other observable terminology and prevent name clashes with `BindingObserver` properties.","packages/fast-element/docs/migration/fast-element-3.md":"# Migrating from previous versions\n\n## FASTGlobal version tracking (v2 → v3)\n\n### Removed API\n\n| Removed | Replacement |\n|---|---|\n| `FAST.versions` | No replacement. Multiple FAST versions on the same page are unsupported in v3. |\n\n### Removed configuration\n\n| Removed | Replacement |\n|---|---|\n| `fast-kernel=\"share\"` / `fast-kernel=\"share-v2\"` / `fast-kernel=\"isolate\"` | No replacement. FAST now uses a single shared kernel contract, and multiple FAST versions on the same page are unsupported. |\n\n### Migration steps\n\n1. Remove any runtime checks that read `FAST.versions`.\n2. Fix duplicate FAST installs in your bundler or dependency graph instead of relying on version tracking at runtime.\n3. Remove any `fast-kernel` script attributes. They no longer affect FAST initialization.\n\n## Native globals and scheduler requirements (v2 → v3)\n\n### Changed behavior\n\n- **Browser `Window` runtime required**: `@microsoft/fast-element` is a\n  client-side browser runtime. It expects browser DOM, Custom Elements, Shadow\n  DOM, and scheduling APIs such as `requestAnimationFrame`.\n- **Native `globalThis` required**: `@microsoft/fast-element` no longer installs\n  a `globalThis` polyfill as a side effect.\n- **No idle-callback polyfill**: FAST Element v3 no longer installs or depends\n  on a `requestIdleCallback` / `cancelIdleCallback` fallback. The async\n  `Updates` queue schedules work with `globalThis.requestAnimationFrame`.\n\n### Migration steps\n\n1. Verify that the browsers you support provide native `globalThis` and\n   `requestAnimationFrame`.\n2. If you still target an older browser without `globalThis`, load that polyfill\n   before importing `@microsoft/fast-element`.\n3. Do not import or run the FAST Element client runtime in workers,\n   server-side JavaScript runtimes, or other non-window hosts. SSR tools may\n   emit HTML, but hydration and client rendering run in the browser `Window`.\n4. You do not need to polyfill `requestIdleCallback` or `cancelIdleCallback`\n   for FAST Element itself. Only provide them if your application or another\n   dependency calls those APIs directly.\n\n## Declarative HTML moved into fast-element (v3)\n\nDeclarative HTML APIs now ship from focused `@microsoft/fast-element` package\npath exports instead of the removed `@microsoft/fast-html` package.\n\n### Import changes\n\n| Before | After |\n|---|---|\n| `@microsoft/fast-html` | `@microsoft/fast-element/declarative.js` |\n| `@microsoft/fast-html/utilities.js` | `@microsoft/fast-element/declarative-utilities.js` |\n\nCore FAST Element helpers are available from the root package export:\n\n| API | Import path |\n|---|---|\n| `Updates` | `@microsoft/fast-element` |\n| `Observable`, `observable` | `@microsoft/fast-element` |\n| `attr`, `AttributeDefinition`, converters, `ValueConverter` | `@microsoft/fast-element` |\n| `Binding`, `oneWay`, `oneTime`, `listener` | `@microsoft/fast-element` |\n| `DOM`, `DOMAspect`, `DOMPolicy` | `@microsoft/fast-element` |\n| `Schema`, `schemaRegistry`, schema types | `@microsoft/fast-element` |\n| `css` | `@microsoft/fast-element` |\n| `html`, `ViewTemplate`, `HTMLView` | `@microsoft/fast-element` |\n| `Compiler`, `HTMLDirective`, `htmlDirective`, templating/view types | `@microsoft/fast-element` |\n| `render`, `RenderBehavior`, `RenderDirective` | `@microsoft/fast-element` |\n| `enableHydration`, `deferHydrationAttribute`, `HydrationTracker`, hydration types | `@microsoft/fast-element/hydration.js` |\n| `ArrayObserver` | `@microsoft/fast-element` |\n| `volatile` | `@microsoft/fast-element` |\n| `children` | `@microsoft/fast-element` |\n| `elements`, `NodeObservationDirective` | `@microsoft/fast-element` |\n| `ref` | `@microsoft/fast-element` |\n| `slotted` | `@microsoft/fast-element` |\n| `when` | `@microsoft/fast-element` |\n| `repeat` | `@microsoft/fast-element` |\n\n### Migration steps\n\n1. Update declarative runtime imports to\n   `@microsoft/fast-element/declarative.js`.\n2. Update declarative utility imports such as `deepMerge` to\n   `@microsoft/fast-element/declarative-utilities.js`.\n3. Keep importing FAST Element APIs such as `FASTElement`, `FAST`,\n   `ElementController`, definition/controller types, `attr`, `Schema`, and\n   `observable` from `@microsoft/fast-element`.\n4. Call `enableHydration()` from `@microsoft/fast-element/hydration.js` when\n   prerendered content should be hydrated.\n\n## `deepMerge` array replacement\n\nWhen an array's contents change, `deepMerge` replaces the owning property's\narray rather than mutating the existing array in place. This affects both\n`observerMap()`-managed data and direct consumers of the exported helper.\nPreviously captured array references retain the old data; mutating them no\nlonger updates the owning object. Deeply equal arrays are left unchanged.\n\nRe-read the array from its owner after merging:\n\n```ts\nimport { deepMerge } from \"@microsoft/fast-element/declarative-utilities.js\";\n\nconst user = { orders: [{ id: 101 }] };\nconst oldOrders = user.orders;\n\ndeepMerge(user, { orders: [{ id: 103 }] });\n\n// oldOrders still contains order 101 and is disconnected from user.orders.\nuser.orders.push({ id: 104 });\n```\n\nFor `observerMap()`-managed properties, the owning property's notification\ncauses `f-repeat` bindings to observe the replacement array automatically.\nDirect `deepMerge` consumers must still arrange their own change notifications;\nthe helper does not make plain objects observable.\n\n## Optional helper and removed path exports (v2 → v3)\n\nFAST Element v3 adds focused flat path exports for optional helpers and removes\nolder nested or unused package exports. Root imports for core FAST Element APIs\nremain supported, but code that imports helper APIs from older nested paths must\nmove to the flat path exports.\n\n### Import changes\n\n| Before | After |\n|---|---|\n| `@microsoft/fast-element/binding/two-way.js` | `@microsoft/fast-element/two-way.js` |\n| `@microsoft/fast-element/binding/signal.js` | `@microsoft/fast-element/signal.js` |\n| Deep directive imports | `@microsoft/fast-element/children.js`, `@microsoft/fast-element/repeat.js`, `@microsoft/fast-element/when.js`, `@microsoft/fast-element/ref.js`, `@microsoft/fast-element/slotted.js`, or `@microsoft/fast-element/node-observation.js` |\n| Declarative map helpers from old declarative surfaces | `@microsoft/fast-element/attribute-map.js` and `@microsoft/fast-element/observer-map.js` |\n\n### Removed package exports\n\n| Removed | Replacement |\n|---|---|\n| `@microsoft/fast-element/install-element-hydration.js` | No side-effect import. Call `enableHydration()` from `@microsoft/fast-element/hydration.js` when SSR content should hydrate. |\n| `@microsoft/fast-element/install-hydratable-view-templates.js` | No side-effect import. `enableHydration()` installs hydratable template support. |\n| `@microsoft/fast-element/element-hydration.js` | `@microsoft/fast-element/hydration.js` for public hydration APIs. |\n| `@microsoft/fast-element/metadata.js` | No supported public replacement. |\n| `@microsoft/fast-element/testing.js` | No supported public replacement. |\n| `@microsoft/fast-element/pending-task.js` | No supported public replacement. |\n\n### Migration steps\n\n1. Replace older nested helper imports with the flat path exports shown above.\n2. Remove hydration side-effect imports and call `enableHydration()` before FAST\n   elements connect when SSR content should hydrate.\n3. Remove imports from deleted package exports. If your app depended on one of\n   those internals, move that usage into app-owned code or a supported public\n   API.\n\n## `attribute-name-strategy` default changed (v2 → v3)\n\nThe declarative attribute map default changed from `\"none\"` to `\"camelCase\"`.\nWith the default strategy, a binding key such as `{{firstName}}` maps to the\n`firstName` property and the `first-name` HTML attribute. In v2-style\ndeclarative templates that relied on literal attribute names, this can change\nwhich property receives data.\n\n### Migration steps\n\n1. Audit declarative templates for binding keys that contain hyphens or that\n   intentionally matched attribute names exactly.\n2. If you want the v2 behavior, configure the client definition extension with\n   `attributeMap({ \"attribute-name-strategy\": \"none\" })`.\n3. If server-rendered HTML is generated with `@microsoft/fast-build`, pass\n   `--attribute-name-strategy=none` so server and client mapping agree.\n\n## `TemplateOptions` removal (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `TemplateOptions` | No replacement |\n| `PartialFASTElementDefinition.templateOptions` | No replacement |\n| `FASTElementDefinition.templateOptions` | No replacement |\n\n### Changed behavior\n\n- Subclass `define()` calls no longer use `templateOptions` to delay platform\n  definition or connection.\n- Elements can still be defined before a template is attached; a later\n  `FASTElementDefinition.template` update notifies connected elements so they\n  can render or hydrate with the new template.\n\n### Migration steps\n\n1. Remove `templateOptions` from element definitions.\n2. Continue calling `define({ name })` when a definition needs to exist before\n   its template is attached.\n3. If a template is supplied later, assign `FASTElementDefinition.template` (or\n   use the declarative runtime that does so for you).\n\n## `FASTElementDefinition.isRegistered` removal (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `FASTElementDefinition.isRegistered` | `fastElementRegistry.whenRegistered(tagName)`, `fastElementRegistry.getByType(type)`, or `fastElementRegistry.getForInstance(instance)` |\n\n### Migration steps\n\n1. Import `fastElementRegistry` from `@microsoft/fast-element/registry.js`.\n2. Use `fastElementRegistry.whenRegistered(tagName)` when code needs to wait for\n   a definition by tag name.\n3. Use `fastElementRegistry.getByType(type)` or\n   `fastElementRegistry.getForInstance(instance)` when code already has a\n   constructor or element instance.\n\n## Declarative TemplateElement API removal (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `TemplateElement` public export | `declarativeTemplate()` on each FAST element definition |\n| `TemplateElement.define({ name: \"f-template\" })` | No manual definition; `declarativeTemplate()` defines FAST's internal `<f-template>` publisher in the target registry |\n| `TemplateElement.config(callbacks)` / `HydrationLifecycleCallbacks` | `enableHydration().whenHydrated(tagName)` for tag-specific hydration waits and `enableHydration().whenHydrated()` for the active hydration batch |\n| `TemplateElement.options(...)`, `ElementOptions`, `ElementOptionsDictionary` | Define extensions: `attributeMap(...)` and `observerMap(...)` passed as the second argument to `define()` |\n| `AttributeMap` / `ObserverMap` exports from the old declarative public surface | `attributeMap()` / `observerMap()` extension helpers and their config types |\n\n### Migration steps\n\n1. Replace manual `<f-template>` registration with `template: declarativeTemplate()`:\n\n   ```typescript\n   // Before\n   import { TemplateElement } from \"@microsoft/fast-element\";\n   TemplateElement.define({ name: \"f-template\" });\n\n   MyElement.define({ name: \"my-element\" });\n\n   // After\n   import { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n\n   MyElement.define({\n       name: \"my-element\",\n       template: declarativeTemplate(),\n   });\n   ```\n\n2. Replace `TemplateElement.options()` with definition extensions:\n\n   ```typescript\n   import { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\n   import { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n   import { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\n   MyElement.define(\n       {\n           name: \"my-element\",\n           template: declarativeTemplate(),\n       },\n       [attributeMap(), observerMap()],\n   );\n   ```\n\n   `attributeMap()` is imported from\n   `@microsoft/fast-element/attribute-map.js` and `observerMap()` from\n   `@microsoft/fast-element/observer-map.js` for declarative templates,\n   manually supplied schemas, or both. `FASTElementDefinition.schema` is optional;\n   `declarativeTemplate()` assigns it automatically, and `observerMap()` can\n   take a manual schema with `observerMap({ schema })`.\n\n3. Replace `TemplateElement.config()` with `enableHydration().whenHydrated(tagName)`\n   for tag-specific hydration waits and `enableHydration().whenHydrated()` for the\n   active hydration batch.\n   Hydration is not installed by `declarative.js`; call `enableHydration()`\n   before elements connect when SSR content should hydrate.\n\n## Debug entrypoint explicit enablement (v3)\n\n### Import changes\n\n| Before | After |\n|---|---|\n| `import \"@microsoft/fast-element\";` | `import { enableDebug } from \"@microsoft/fast-element/debug.js\"; enableDebug();` |\n\n### Migration steps\n\n1. Replace setup-only `debug.js` imports with an explicit `enableDebug()` call.\n2. Keep using the root package `development` export or debug rollup bundle when\n   you want debug behavior enabled automatically.\n\n## Declarative event handler `e` removal (v3)\n\n### Removed behavior\n\n| Removed | Replacement |\n|---|---|\n| Bare `e` event arguments in declarative event handlers | `$e` |\n| `TemplateParser.hasDeprecatedEventSyntax` | No replacement |\n\nOnly `$e` and `$c` are reserved event handler arguments in declarative\ntemplates. Bare `e` now resolves like any other binding path on the current\ndata source.\n\n### Migration steps\n\n1. Replace declarative event bindings such as\n   `@click=\"{handleClick(e)}\"` with `@click=\"{handleClick($e)}\"`.\n2. Remove any `TemplateParser.hasDeprecatedEventSyntax` checks or warnings from\n   custom tooling.\n\n## Prerendered Content Optimization (v2 → v3)\n\n### Removed and moved APIs\n\n| 2.x API | 3.x guidance |\n|---|---|\n| `HydratableElementController` | `ElementController` (prerendered path built in) |\n| `HydrationControllerCallbacks` | Call `enableHydration()` and await the returned controller's `whenHydrated()` promise |\n| `needsHydrationAttribute` | No replacement. Existing shadow root detection sets `ElementController.isPrerendered`. |\n| Root `deferHydrationAttribute` export | Import `deferHydrationAttribute` from `@microsoft/fast-element/hydration.js` only if you still need the legacy attribute string. New server-rendered markup should omit `defer-hydration`. |\n\n### Removed side-effect imports\n\n| Import | Replacement |\n|---|---|\n| `@microsoft/fast-element/install-hydration.js` | No replacement needed — prerendered path is built into `ElementController` |\n| `@microsoft/fast-element/install-hydratable-view-templates.js` | No replacement needed — `enableHydration()` installs hydratable template support |\n\nUse `enableHydration()` from `@microsoft/fast-element/hydration.js` when SSR\ncontent should hydrate. The declarative entrypoint no longer installs hydration\nautomatically.\n\n### Changed behavior\n\n- **`attributeChangedCallback` during upgrade**: When `isPrerendered` is true and the element has not yet connected, attribute change callbacks are suppressed. After connection, all attribute changes are processed normally.\n- **Declarative template resolution**: `declarativeTemplate()` waits for the\n  matching `<f-template>` before `define()` completes, so connected elements\n  hydrate with a concrete template. No `defer-hydration` attribute is needed.\n- **Binding evaluation with existing shadow root**: When an existing shadow root is detected, `attribute` and `booleanAttribute` bindings skip their initial DOM update. All other binding types (event, content, property, tokenList) run normally.\n\n### New APIs\n\n- **`ElementController.isPrerendered`** (`Promise<boolean>`): Resolves to `true` when the element had a declarative shadow root at connect time, or `false` when the component was client-side rendered.\n- **`ElementController.isHydrated`** (`Promise<boolean>`): Resolves to `true` only when hydration ran successfully.\n- **`ViewController.isPrerendered`** (`Promise<boolean> | undefined`): Available to custom directives. Resolves to `true` when the view's content was prerendered, `false` otherwise.\n- **`ViewController.isHydrated`** (`Promise<boolean> | undefined`): Available to custom directives. Resolves to `true` only when hydration ran successfully.\n\n### Migration steps\n\n1. Remove `HydratableElementController.install()` calls.\n2. Remove `import \"@microsoft/fast-element/install-hydration.js\"` side-effect imports.\n3. Replace `element.$fastController instanceof HydratableElementController` checks with `await element.$fastController.isPrerendered`.\n4. Remove `defer-hydration` and `needs-hydration` attributes from server-rendered markup.\n\n## Hydration Marker Format (v3)\n\n### Changed format\n\nThe hydration markers embedded in SSR output have been simplified from verbose, index-embedded comment markers to compact, data-free sequential markers.\n\n#### Comment markers\n\n| Marker type | Old format | New format |\n|---|---|---|\n| Content binding start | `<!-- fe-b$$start$$<index>$$<scopeId>$$fe-b -->` | `<!--fe:b-->` |\n| Content binding end | `<!-- fe-b$$end$$<index>$$<scopeId>$$fe-b -->` | `<!--fe:/b-->` |\n| Repeat item start | `<!-- fe-repeat$$start$$<itemIndex>$$fe-repeat -->` | `<!--fe:r-->` |\n| Repeat item end | `<!-- fe-repeat$$end$$<itemIndex>$$fe-repeat -->` | `<!--fe:/r-->` |\n| Element boundary start | `<!-- fe-eb$$start$$<elementId>$$fe-eb -->` | `<!--fe:e-->` |\n| Element boundary end | `<!-- fe-eb$$end$$<elementId>$$fe-eb -->` | `<!--fe:/e-->` |\n\n#### Attribute binding markers\n\n| Old format | New format |\n|---|---|\n| `data-fe-b=\"0 1 2\"` (space-separated indices) | `data-fe=\"N\"` (binding count) |\n| `data-fe-b-0` (enumerated, one per factory) | `data-fe=\"N\"` |\n| `data-fe-c-0-3` (compact, start index + count) | `data-fe=\"N\"` |\n\n### Removed APIs\n\n| Export | Replacement |\n|---|---|\n| `HydrationMarkup.contentBindingStartMarker(index, scopeId)` | `HydrationMarkup.contentBindingStartMarker()` |\n| `HydrationMarkup.contentBindingEndMarker(index, scopeId)` | `HydrationMarkup.contentBindingEndMarker()` |\n| `HydrationMarkup.isContentBindingStartMarker(data)` | `HydrationMarkup.isContentBindingStartMarker(data)` (unchanged signature, new implementation) |\n| `HydrationMarkup.isContentBindingEndMarker(data)` | `HydrationMarkup.isContentBindingEndMarker(data)` (unchanged signature, new implementation) |\n| `HydrationMarkup.parseAttributeBinding(element)` | `HydrationMarkup.parseAttributeBindingCount(element)` |\n| `HydrationMarkup.parseRepeatStartMarker(data)` | `HydrationMarkup.isRepeatViewStartMarker(data)` |\n| `HydrationMarkup.parseRepeatEndMarker(data)` | `HydrationMarkup.isRepeatViewEndMarker(data)` |\n| `HydrationMarkup.parseElementBoundaryStartMarker(content)` | `HydrationMarkup.isElementBoundaryStartMarker(node)` |\n| `HydrationMarkup.parseElementBoundaryEndMarker(content)` | `HydrationMarkup.isElementBoundaryEndMarker(node)` |\n\n### Impact\n\nThis is a **breaking change** for SSR output format. Any system that produces or parses hydration markers must be updated to use the new format. The `@microsoft/fast-build` Rust crate and WASM binary have been updated accordingly.\n\n- Marker parsing uses string equality checks (`data === \"fe:b\"`) instead of regex\n- Start/end pairing uses balanced depth counting instead of embedded IDs\n- The hydration walker uses a sequential factory pointer instead of index-based lookup\n- SSR and client versions must match — mixing old SSR output with new client code (or vice versa) will fail\n\n## Async define/compose/register API (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `FASTElement.defineAsync()` | Subclass `define()` calls |\n| `FASTElement.compose()` and subclass `compose()` calls | Subclass `define()` calls |\n| `FASTElementDefinition.composeAsync()` | Subclass `define()` calls |\n| `FASTElementDefinition.registerAsync()` | `FASTElementDefinition.register()` (same `Promise<Function>` return type) |\n\n### Changed behavior\n\n- Subclass **`define()`** calls return `Promise<TType>` only for code that\n  explicitly needs to observe registration completion. When\n  `template: declarativeTemplate()` is used, that Promise resolves after the\n  matching `<f-template>` supplies the concrete template.\n- Subclass compose helpers are no longer part of the public authoring surface; use subclass `define()` for registration.\n- **`@customElement` decorator** calls `define()` internally but does not return the Promise (fire-and-forget). For complete definitions with a template, the element is registered via a microtask.\n\n### Migration steps\n\n1. Replace `defineAsync()` calls with `define()`:\n\n   ```typescript\n    // Before\n    MyElement.defineAsync({\n        name: \"my-element\",\n        templateOptions: \"defer-and-hydrate\",\n    });\n\n    // After\n    MyElement.define({\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    });\n   ```\n\n2. Replace subclass `compose()` calls that immediately register an element with\n   `define()`:\n\n   ```typescript\n    // Before\n    MyElement.compose({\n        name: \"my-element\",\n        template,\n        styles,\n    }).define();\n\n    // After\n    MyElement.define({\n        name: \"my-element\",\n        template,\n        styles,\n    });\n   ```\n\n3. Replace `FASTElementDefinition.composeAsync()` calls that register an element\n   with subclass `define()`:\n\n   ```typescript\n   // Before\n   (await FASTElementDefinition.composeAsync(MyElement, {\n       name: \"my-element\",\n       template,\n       styles,\n   })).define();\n\n   // After\n   MyElement.define({\n       name: \"my-element\",\n       template,\n       styles,\n   });\n   ```\n\n4. Replace `registerAsync()` calls with `register()`:\n\n   ```typescript\n   // Before\n   const el = await FASTElementDefinition.registerAsync(name);\n\n   // After\n   const el = await FASTElementDefinition.register(name);\n   ```\n\n5. Replace `FASTElementDefinition.compose()` calls that chain `.define()` with\n   subclass `define()`:\n\n   ```typescript\n    // Before\n    FASTElementDefinition.compose(MyElement, options).define();\n\n    // After\n    MyElement.define(options);\n   ```\n\n## Dynamic stylesheet behaviors (v3)\n\n### Removed API\n\n| Removed | Replacement |\n|---|---|\n| `ElementStyles.withBehaviors()` | Move the runtime condition into the element and call `this.$fastController.addStyles()` / `this.$fastController.removeStyles()` directly. |\n| `ElementStyles.behaviors` | Move any runtime behavior out of the stylesheet and into the element or controller lifecycle. |\n| CSS bindings in `css` (for example ``css`color: ${x => x.color}```) | Move the dynamic value into the element and update classes, attributes, or inline styles from element code. |\n| `CSSDirective.createCSS(add)` | Update directives to implement `createCSS()` and return only static CSS content. |\n\n### Changed behavior\n\n- `css` and `css.partial()` no longer compose `HostBehavior`s.\n- `css` no longer accepts function or `Binding` interpolations.\n- `ElementStyles` is now a fully static style container.\n\n### Migration steps\n\n1. Keep the conditional `ElementStyles` in a separate `css` value.\n2. Move the external listener or condition (for example `matchMedia()` or an app event subscription) into the element lifecycle.\n3. Call `this.$fastController.addStyles(styles)` when the condition is active and `this.$fastController.removeStyles(styles)` when it is inactive or during cleanup.\n4. If you previously interpolated bindings or behavior-producing directives into `css`, replace them with element state and standard DOM or controller updates.\n\n## `booleanConverter` aligned with native HTML boolean attribute semantics (v2 → v3)\n\n### Changed behavior\n\n`@attr({ mode: \"boolean\" })` and `booleanConverter` now match how the platform treats native boolean attributes (e.g., `disabled`, `required`):\n\n- **Attribute → property** is presence-based: `setAttribute(name, anyString)` (including the empty string) sets the property to `true`; only `removeAttribute(name)` makes it `false`.\n- **Property → attribute** uses `Boolean()` coercion: any JavaScript truthy value adds the attribute (with value `\"\"`); any falsy value removes it.\n\nThe headline v2 → v3 difference is that `setAttribute(name, \"false\")` now resolves to property `true`, matching `<input disabled=\"false\">` still being disabled.\n\n`booleanConverter` shape:\n\n```ts\ntoView(value: any) {\n    return value ? \"\" : null;\n}\n\nfromView(value: any) {\n    return !!value;\n}\n```\n\n`booleanConverter` v2 → v3 result differences:\n\n| Call | v2 result | v3 result |\n|---|---|---|\n| `fromView(\"false\")` | `false` | `true` |\n| `fromView(\"\")` | `true` | `false` |\n| `fromView(NaN)` | `true` | `false` |\n| `toView(true)` (or any truthy) | `\"true\"` | `\"\"` |\n| `toView(false)` (or any falsy) | `\"false\"` | `null` |\n\n> **Note**: For `mode: \"boolean\"`, FAST writes attributes via `DOM.setBooleanAttribute` (presence-based) and reads them as `value !== null`, so the `mode: \"boolean\"` reflection path does **not** route through `booleanConverter.toView()` or `booleanConverter.fromView()`. The converter methods still apply to property assignment (`el.bool = X` runs `fromView(X)`), explicit calls (`booleanConverter.fromView(x)`), and `booleanConverter` paired with `mode: \"reflect\"` (which calls `toView`).\n\n### Migration steps\n\n1. Audit `boolean`-mode attributes for the literal string `\"false\"` in templates or SSR HTML — the resulting property will be `true`, not `false`. To express the falsy state, omit the attribute entirely (or call `element.removeAttribute(name)`). Setting `element.bool = false` continues to remove the reflected attribute.\n2. Audit code that calls `booleanConverter.toView()` directly or pairs `booleanConverter` with `mode: \"reflect\"`. The output strings are no longer `\"true\"` / `\"false\"`.\n3. If you need a tri-state attribute (`true` / `false` / unset) that preserves an explicit `\"false\"` string value, use `nullableBooleanConverter` with `mode: \"reflect\"` instead of `mode: \"boolean\"`.\n","packages/fast-element/docs/migration/fast-html.md":"# Migrating from previous versions\n\n## Hydration Marker Format (v1-alpha → v1)\n\nThe SSR output format for hydration markers has been simplified. If you have any tooling that inspects or generates hydration markers, update it to use the new format.\n\n| Old marker | New marker |\n|---|---|\n| `<!-- fe-b$$start$$...$$fe-b -->` | `<!--fe:b-->` |\n| `<!-- fe-b$$end$$...$$fe-b -->` | `<!--fe:/b-->` |\n| `<!-- fe-repeat$$start$$...$$fe-repeat -->` | `<!--fe:r-->` |\n| `<!-- fe-repeat$$end$$...$$fe-repeat -->` | `<!--fe:/r-->` |\n| `data-fe-b=\"0 1 2\"` / `data-fe-b-0` / `data-fe-c-0-3` | `data-fe=\"N\"` |\n\nThe `@microsoft/fast-build` WASM binary emits the new markers automatically. Rebuild all fixtures and SSR output after upgrading.\n\nSee the [`@microsoft/fast-element` migration guide](./fast-element-3.md#hydration-marker-format-v3) for full details on API changes.\n\n## Prerendered Content Optimization (v1-alpha → v1)\n\n### Removed exports\n\n| Export | Replacement |\n|---|---|\n| `RenderableFASTElement` | Extend `FASTElement` |\n\n### Removed concepts\n\n| Concept | Replacement |\n|---|---|\n| `prepare()` lifecycle hook | Set state in `connectedCallback`; the reactive system updates the DOM |\n| `defer-hydration` attribute in rendered markup | Template-pending guard in `ElementController.connect()` |\n| `needs-hydration` attribute in rendered markup | `hasExistingShadowRoot` detection in `ElementController` |\n| `waitForAncestorHydration()` | Not needed — prerendered content is correct regardless of connection order |\n\n### Migration steps\n\n1. Replace `RenderableFASTElement(MyComponent).defineAsync({...})` with\n   `MyComponent.define({...})` and use `declarativeTemplate()` for declarative\n   templates. If code explicitly observes the Promise returned by `define()`,\n   it resolves after the matching `<f-template>` supplies the concrete template.\n\n   ```typescript\n   // Before\n   import { RenderableFASTElement } from \"@microsoft/fast-html\";\n   RenderableFASTElement(MyComponent).defineAsync({\n       name: \"my-component\",\n       templateOptions: \"defer-and-hydrate\",\n   });\n\n   // After\n   MyComponent.define({\n       name: \"my-component\",\n       template: declarativeTemplate(),\n   });\n   ```\n\n2. Remove `prepare()` methods. Move any initialization logic to `connectedCallback`:\n\n   ```typescript\n   // Before\n   class MyComponent extends FASTElement {\n       async prepare() {\n           this.data = await fetchData();\n       }\n   }\n\n   // After\n   class MyComponent extends FASTElement {\n       connectedCallback() {\n           super.connectedCallback();\n           this.loadData();\n       }\n       async loadData() {\n           this.data = await fetchData();\n       }\n   }\n   ```\n\n3. Remove `defer-hydration` and `needs-hydration` attributes from server-rendered markup:\n\n   ```html\n   <!-- Before -->\n   <my-component defer-hydration needs-hydration text=\"Hello\">\n       <template shadowrootmode=\"open\">...</template>\n   </my-component>\n\n   <!-- After -->\n   <my-component text=\"Hello\">\n       <template shadowrootmode=\"open\">...</template>\n   </my-component>\n   ```\n\n4. Await `$fastController.isPrerendered` to detect prerendered components:\n\n   ```typescript\n   connectedCallback() {\n       super.connectedCallback();\n       this.$fastController.isPrerendered.then(prerendered => {\n           if (!prerendered) {\n               this.fetchData();\n           }\n       });\n   }\n   ```\n\n## Modularize Schema, ObserverMap, and AttributeMap\n\n### Import changes\n\nConfiguration types have moved from `template.ts` to their owning modules. If you import types directly from internal paths, update your imports:\n\n| Before | After |\n|---|---|\n| `import type { ObserverMapConfig } from \"./template.js\"` | `import type { ObserverMapConfig } from \"./observer-map.js\"` |\n| `import type { AttributeMapConfig } from \"./template.js\"` | `import type { AttributeMapConfig } from \"./attribute-map.js\"` |\n\nPublic declarative imports now come from\n`@microsoft/fast-element/declarative.js` rather than\n`@microsoft/fast-html`, and declarative utilities come from\n`@microsoft/fast-element/declarative-utilities.js`. Map extensions come from\n`@microsoft/fast-element/attribute-map.js` and\n`@microsoft/fast-element/observer-map.js`.\n\n### Schema changes\n\n`Schema.jsonSchemaMap` (static property) has been replaced by:\n- An instance-level `schemaMap` on each `Schema` instance (private)\n- A module-level `schemaRegistry` export for cross-element lookups\n\n| Before | After |\n|---|---|\n| `Schema.jsonSchemaMap.get('my-element')` | `import { schemaRegistry } from \"@microsoft/fast-element\"; schemaRegistry.get('my-element')` |\n\n### Public exports\n\nThe public entrypoint exports the functional declarative API:\n\n| Export | Purpose |\n|---|---|\n| `declarativeTemplate()` | Resolves `<f-template>` markup for a FAST element definition |\n| `attributeMap()` | Definition extension for automatic `@attr` property registration |\n| `observerMap()` | Definition extension for automatic deep observation |\n| `Schema` | JSON schema builder class |\n| `schemaRegistry` | Module-level registry for cross-element schema lookups |\n| `JSONSchema` | JSON Schema type interface |\n| `CachedPathMap` | Schema registry map type |\n\n## Simplified ObserverMap and AttributeMap defaults\n\nThe explicit `ObserverMapOption.all` and `AttributeMapOption.all` constants have\nbeen removed. Calling `observerMap()` with no arguments observes every\ndiscovered root property, and calling `attributeMap()` with no arguments maps\nevery discovered leaf binding.\n\n| Before | After |\n|---|---|\n| `observerMap(ObserverMapOption.all)` | `observerMap()` |\n| `attributeMap(AttributeMapOption.all)` | `attributeMap()` |\n\n## Attribute name strategy default changed\n\nThe default `attribute-name-strategy` for declarative attribute mapping is now\n`\"camelCase\"` instead of `\"none\"`. A binding key such as `{{firstName}}` maps to\nthe `firstName` property and the `first-name` HTML attribute by default. If your\ntemplates depended on literal attribute names, opt back in to the old behavior:\n\n```ts\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\n\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [attributeMap({ \"attribute-name-strategy\": \"none\" })],\n);\n```\n\nWhen using `@microsoft/fast-build`, keep the server and client settings aligned:\n\n```bash\nfast build --attribute-name-strategy=none\n```\n\n## Declarative TemplateElement API removal\n\nThe public declarative API is now the functional API. The `<f-template>`\nimplementation is internal and is defined automatically by `declarativeTemplate()`.\n\n| Removed | Replacement |\n|---|---|\n| `TemplateElement` public export | `declarativeTemplate()` on each FAST element definition |\n| `TemplateElement.define({ name: \"f-template\" })` | No manual definition; `declarativeTemplate()` defines the internal publisher in the target registry |\n| `TemplateElement.config(callbacks)` / `HydrationLifecycleCallbacks` | `enableHydration().whenHydrated(tagName)` for tag-specific hydration waits and `enableHydration().whenHydrated()` for the active hydration batch |\n| `TemplateElement.options({ \"my-el\": { attributeMap, observerMap } })` | Define extensions: `MyElement.define(definition, [attributeMap(...), observerMap(...)])` |\n| `ElementOptions` / `ElementOptionsDictionary` | No replacement |\n| `AttributeMap` / `ObserverMap` class exports from the old declarative public surface | `attributeMap()` / `observerMap()` extension helpers and their config types |\n\nHydration is also no longer installed by `@microsoft/fast-element`.\nCall `enableHydration()` from `@microsoft/fast-element/hydration.js` before FAST\nelements connect when prerendered Declarative Shadow DOM should be reused.\n\n## Schema-driven maps and optional definition schema\n\n`attributeMap()` and `observerMap()` are now schema-driven extensions that are\nfactored away from declarative templating. Import them from\n`@microsoft/fast-element` for declarative or non-declarative use:\n\n```ts\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n```\n\n`FASTElementDefinition.schema` is optional. `declarativeTemplate()` assigns it\nautomatically when it parses `<f-template>` markup. Manual schema users can pass\na schema in the element definition, and `observerMap()` can also take a schema\ndirectly in configuration:\n\n```ts\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-element\");\nschema.addPath({\n    rootPropertyName: \"user\",\n    pathConfig: {\n        type: \"default\",\n        parentContext: null,\n        currentContext: null,\n        path: \"user.name\",\n    },\n    childrenMap: null,\n});\n\nMyElement.define({ name: \"my-element\" }, [observerMap({ schema })]);\n```\n","packages/fast-element/docs/styles/api-report.api.md":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport type ComposableStyles = string | ElementStyles | CSSStyleSheet;\n\n// @public\nexport type Constructable<T = {}> = {\n    new (...args: any[]): T;\n};\n\n// @public\nexport type ConstructibleStyleStrategy = {\n    new (styles: (string | CSSStyleSheet)[]): StyleStrategy;\n};\n\n// @public\nexport interface CSSDirective {\n    createCSS(): ComposableStyles;\n}\n\n// @public\nexport const CSSDirective: Readonly<{\n    getForInstance: (object: any) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    getByType: (key: Function) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    define<TType extends Constructable<CSSDirective>>(type: any): TType;\n}>;\n\n// @public\nexport function cssDirective(): (type: Constructable<CSSDirective>) => void;\n\n// @public\nexport interface CSSDirectiveDefinition<TType extends Constructable<CSSDirective> = Constructable<CSSDirective>> {\n    readonly type: TType;\n}\n\n// @public\nexport class ElementStyles {\n    constructor(styles: ReadonlyArray<ComposableStyles>);\n    // @internal (undocumented)\n    addStylesTo(target: StyleTarget): void;\n    // @internal (undocumented)\n    isAttachedTo(target: StyleTarget): boolean;\n    static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;\n    // @internal (undocumented)\n    removeStylesFrom(target: StyleTarget): void;\n    static setDefaultStrategy(Strategy: ConstructibleStyleStrategy): void;\n    get strategy(): StyleStrategy;\n    // (undocumented)\n    readonly styles: ReadonlyArray<ComposableStyles>;\n    static readonly supportsAdoptedStyleSheets: boolean;\n    withStrategy(Strategy: ConstructibleStyleStrategy): this;\n}\n\n// @public\nexport interface ExecutionContext<TParent = any> {\n    readonly event: Event;\n    eventDetail<TDetail>(): TDetail;\n    eventTarget<TTarget extends EventTarget>(): TTarget;\n    index: number;\n    readonly isEven: boolean;\n    readonly isFirst: boolean;\n    readonly isInMiddle: boolean;\n    readonly isLast: boolean;\n    readonly isOdd: boolean;\n    length: number;\n    parent: TParent;\n    parentContext: ExecutionContext<TParent>;\n}\n\n// @public\nexport const ExecutionContext: Readonly<{\n    default: ExecutionContext;\n    getEvent(): Event | null;\n    setEvent(event: Event | null): void;\n}>;\n\n// @public\nexport interface ExpressionController<TSource = any, TParent = any> {\n    readonly context: ExecutionContext<TParent>;\n    readonly isBound: boolean;\n    onUnbind(behavior: {\n        unbind(controller: ExpressionController<TSource, TParent>): any;\n    }): void;\n    readonly source: TSource;\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface HostBehavior<TSource = any> {\n    addedCallback?(controller: HostController<TSource>): void;\n    connectedCallback?(controller: HostController<TSource>): void;\n    disconnectedCallback?(controller: HostController<TSource>): void;\n    removedCallback?(controller: HostController<TSource>): void;\n}\n\n// @public\nexport interface HostController<TSource = any> extends ExpressionController<TSource> {\n    addBehavior(behavior: HostBehavior<TSource>): void;\n    addStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    readonly isConnected: boolean;\n    mainStyles: ElementStyles | null;\n    removeBehavior(behavior: HostBehavior<TSource>, force?: boolean): void;\n    removeStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n}\n\n// @public\nexport const SourceLifetime: Readonly<{\n    readonly unknown: undefined;\n    readonly coupled: 1;\n}>;\n\n// @public\nexport type SourceLifetime = (typeof SourceLifetime)[keyof typeof SourceLifetime];\n\n// @public\nexport interface StyleStrategy {\n    addStylesTo(target: StyleTarget): void;\n    removeStylesFrom(target: StyleTarget): void;\n}\n\n// @public\nexport interface StyleTarget extends Pick<Node, \"getRootNode\"> {\n    adoptedStyleSheets?: CSSStyleSheet[];\n    append(styles: HTMLStyleElement): void;\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\n    removeChild(styles: HTMLStyleElement): void;\n}\n\n// (No @packageDocumentation comment for this package)\n\n```\n","packages/fast-element/docs/template-bindings.md":"# FAST Element Template Bindings Architecture\n\nThis document explains how the FAST Element `html` tagged template system stores bindings, applies them to DOM elements, triggers updates on data changes, and handles HTML-specific behaviors like event listeners.\n\n## Overview\n\nThe template binding pipeline has five major stages:\n\n1. **Template Authoring** – The `html` tagged template collects binding expressions and builds placeholder-marked HTML.\n2. **Compilation** – The compiler parses the placeholder HTML into a `DocumentFragment`, walks the DOM tree, and records where each binding targets.\n3. **View Creation** – The compiled result clones the fragment and creates a *targets* object that maps each binding to its DOM node.\n4. **Binding (first render)** – Each factory creates a behavior that attaches to its target node: adding event listeners, setting attributes, or observing expressions.\n5. **Reactive Updates** – When observed data changes, one-way binding observers notify their directive, which re-evaluates the expression and pushes the new value to the DOM through a \"sink\" function.\n\n---\n\n## Mermaid Diagrams\n\n### 1. Template Creation & Storage\n\nThis diagram shows how the `html` tagged template literal processes interpolated values and stores them as factories keyed by unique IDs.\n\n```mermaid\nflowchart TD\n    A[\"html`&lt;div class='${expr}'&gt;${text}&lt;/div&gt;`\"] --> B[\"ViewTemplate.create(strings, values)\"]\n    B --> C{\"For each interpolated value\"}\n    C -->|Function| D[\"Wrap in oneWay() → HTMLBindingDirective\"]\n    C -->|Binding instance| E[\"Wrap in HTMLBindingDirective\"]\n    C -->|HTMLDirective| F[\"Use directly\"]\n    C -->|Static value| G[\"Wrap in oneTime() → HTMLBindingDirective\"]\n    D --> H[\"directive.createHTML(add)\"]\n    E --> H\n    F --> H\n    G --> H\n    H --> I[\"add(factory) assigns unique ID\"]\n    I --> J[\"factories Record&lt;string, ViewBehaviorFactory&gt;\"]\n    I --> K[\"Returns placeholder marker in HTML string\"]\n    K --> L[\"Aspect Detection via lastAttributeNameRegex\"]\n    L -->|In attribute context| M[\"HTMLDirective.assignAspect(directive, attrName)\"]\n    L -->|In text content| N[\"aspectType = DOMAspect.content\"]\n    M --> O{\"Attribute prefix\"}\n    O -->|No prefix| P[\"DOMAspect.attribute\"]\n    O -->|: prefix| Q[\"DOMAspect.property\"]\n    O -->|? prefix| R[\"DOMAspect.booleanAttribute\"]\n    O -->|\"@\" prefix| S[\"DOMAspect.event\"]\n    O -->|:classList| T[\"DOMAspect.tokenList\"]\n    J --> U[\"new ViewTemplate(html, factories)\"]\n```\n\n### 2. Compilation – Walking the DOM & Storing Target Locations\n\nThe compiler transforms the placeholder-laden HTML into a `DocumentFragment` and builds a prototype with lazy property descriptors that navigate to target nodes by child index.\n\n```mermaid\nflowchart TD\n    A[\"ViewTemplate.compile()\"] --> B[\"Compiler.compile(html, factories, policy)\"]\n    B --> C[\"Create HTMLTemplateElement\"]\n    C --> D[\"template.innerHTML = policy.createHTML(html)\"]\n    D --> E[\"document.adoptNode(template.content) → fragment\"]\n    E --> F[\"new CompilationContext(fragment, factories, policy)\"]\n    F --> G[\"compileAttributes(context, template, 'h') — host bindings\"]\n    G --> H[\"compileChildren(context, fragment, 'r') — root\"]\n\n    H --> I{\"For each child node\"}\n    I -->|Element node type=1| J[\"compileAttributes: parse each attribute value\"]\n    J --> K{\"Parser.parse finds placeholders?\"}\n    K -->|Yes| L[\"Remove attribute from DOM\"]\n    L --> M[\"context.addFactory(factory, parentId, nodeId, index, tagName)\"]\n    I -->|Element node| N[\"compileChildren recursively\"]\n    I -->|Text node type=3| O[\"compileContent: Parser.parse text\"]\n    O --> P{\"Placeholders found?\"}\n    P -->|Yes| Q[\"Split text node, insert new text nodes\"]\n    Q --> R[\"context.addFactory for each directive part\"]\n    I -->|Comment node type=8| S[\"Parser.parse comment data\"]\n    S --> T[\"context.addFactory for structural directives\"]\n\n    M --> U[\"addTargetDescriptor(parentId, nodeId, childIndex)\"]\n    U --> V[\"Lazy getter: this[parentId].childNodes[childIndex]\"]\n    V --> W[\"Stored in descriptors → prototype via Object.create\"]\n\n    subgraph \"Target Node ID Scheme\"\n        X[\"Root: 'r'\"]\n        Y[\"Host: 'h'\"]\n        Z[\"Children: 'r.0', 'r.1', 'r.0.2'\"]\n        AA[\"Encodes DOM tree path via dot-separated child indices\"]\n    end\n\n    W --> AB[\"context.freeze() → compilation result\"]\n```\n\n### 3. View Creation – Cloning the Fragment & Resolving Targets\n\n```mermaid\nflowchart TD\n    A[\"compilationResult.createView(hostBindingTarget?)\"] --> B[\"fragment.cloneNode(true) → new DocumentFragment\"]\n    B --> C[\"targets = Object.create(proto)\"]\n    C --> D[\"targets.r = fragment (root)\"]\n    D --> E[\"targets.h = hostBindingTarget (host element)\"]\n    E --> F{\"For each registered nodeId\"}\n    F --> G[\"Access targets[nodeId] — triggers lazy getter chain\"]\n    G --> H[\"Getter resolves: this[parentId].childNodes[childIndex]\"]\n    H --> I[\"Caches result in targets._nodeId field\"]\n    I --> J[\"new HTMLView(fragment, factories, targets)\"]\n\n    subgraph \"HTMLView Structure\"\n        K[\"fragment: DocumentFragment with cloned DOM\"]\n        L[\"factories: CompiledViewBehaviorFactory[]\"]\n        M[\"targets: ViewBehaviorTargets {nodeId → Node}\"]\n        N[\"firstChild / lastChild: boundary nodes\"]\n        O[\"source: null (until bound)\"]\n        P[\"behaviors: null (created on first bind)\"]\n    end\n    J --> K\n    J --> L\n    J --> M\n```\n\n### 4. Binding – Attaching Behaviors to DOM Nodes\n\n```mermaid\nflowchart TD\n    A[\"view.bind(source)\"] --> B{\"First bind?\"}\n    B -->|Yes| C[\"Set view.source = source\"]\n    C --> D[\"Create behaviors array\"]\n    D --> E{\"For each factory\"}\n    E --> F[\"factory.createBehavior()\"]\n    F --> G[\"Select sink from sinkLookup based on aspectType\"]\n    G --> H[\"Wrap sink through policy.protect()\"]\n    H --> I[\"behavior.bind(controller/view)\"]\n\n    B -->|Subsequent| J[\"Unbind previous, set new source\"]\n    J --> K[\"Re-bind existing behaviors\"]\n\n    I --> L{\"aspectType?\"}\n\n    L -->|DOMAspect.event| M[\"Store controller ref on target node\"]\n    M --> N[\"target.addEventListener(targetAspect, directive, options)\"]\n    N --> O[\"directive IS the EventListener via handleEvent()\"]\n\n    L -->|DOMAspect.content| P[\"Register unbind handler\"]\n    P --> Q[\"Create observer via dataBinding.createObserver()\"]\n\n    L -->|attribute / property / etc.| Q\n\n    Q --> R[\"observer.bind(controller) → evaluates expression\"]\n    R --> S[\"updateTarget(target, aspect, value, controller)\"]\n\n    subgraph \"Sink Functions (sinkLookup)\"\n        S1[\"attribute → DOM.setAttribute(target, name, value)\"]\n        S2[\"booleanAttribute → DOM.setBooleanAttribute(target, name, value)\"]\n        S3[\"property → target[name] = value\"]\n        S4[\"content → updateContent() — manages text or composed views\"]\n        S5[\"tokenList → updateTokenList() — classList with versioning\"]\n        S6[\"event → no-op (handled via addEventListener)\"]\n    end\n```\n\n### 5. Reactive Update Cycle – Change Detection & DOM Updates\n\n```mermaid\nsequenceDiagram\n    participant Source as Data Source\n    participant Observable as Observable System\n    participant Observer as ExpressionObserver (OneWayBinding)\n    participant Directive as HTMLBindingDirective\n    participant Sink as UpdateTarget (sink fn)\n    participant DOM as Target DOM Node\n\n    Note over Source,DOM: Initial Bind\n    Directive->>Observer: dataBinding.createObserver(directive, directive)\n    Observer->>Source: Evaluate expression (tracks property access)\n    Source-->>Observer: Return value + record dependencies\n    Directive->>Sink: updateTarget(target, aspect, value, controller)\n    Sink->>DOM: Apply value (setAttribute, textContent, etc.)\n\n    Note over Source,DOM: Data Change\n    Source->>Observable: Property setter triggered\n    Observable->>Observer: Notify subscriber of change\n    Observer->>Directive: handleChange(binding, observer)\n    Directive->>Observer: observer.bind(controller) — re-evaluate\n    Observer->>Source: Re-evaluate expression\n    Source-->>Observer: Return new value\n    Directive->>Sink: updateTarget(target, aspect, newValue, controller)\n    Sink->>DOM: Update DOM with new value\n```\n\n### 6. Event Handling – Click Events and Other DOM Events\n\n```mermaid\nsequenceDiagram\n    participant User as User Interaction\n    participant DOM as Target DOM Element\n    participant Directive as HTMLBindingDirective (EventListener)\n    participant Context as ExecutionContext\n    participant Binding as dataBinding.evaluate()\n    participant Source as Component Source\n\n    Note over DOM: During bind: target.addEventListener(\"click\", directive)\n    Note over DOM: directive stores controller ref on target[data]\n\n    User->>DOM: Click event fires\n    DOM->>Directive: handleEvent(event)\n    Directive->>DOM: Read controller from event.currentTarget[data]\n    Directive->>Directive: Check controller.isBound\n    Directive->>Context: ExecutionContext.setEvent(event)\n    Directive->>Binding: evaluate(controller.source, controller.context)\n    Binding->>Source: Execute handler: (s, c) => s.handleClick(c.event)\n    Source-->>Binding: Return result\n    Binding-->>Directive: Return result\n    alt result !== true\n        Directive->>DOM: event.preventDefault()\n    end\n    Directive->>Context: ExecutionContext.setEvent(null)\n```\n\n### 7. Content Binding – Template Composition\n\nWhen a binding expression returns a `ContentTemplate` (e.g., another `ViewTemplate`), the content update sink composes a child view into the DOM.\n\n```mermaid\nflowchart TD\n    A[\"updateContent(target, aspect, value, controller)\"] --> B{\"value is null/undefined?\"}\n    B -->|Yes| C[\"Treat as empty string\"]\n    B -->|No| D{\"value.create exists? (ContentTemplate)\"}\n\n    D -->|Yes — Template| E[\"Clear target.textContent\"]\n    E --> F{\"Existing view on target.$fastView?\"}\n    F -->|No| G[\"view = value.create()\"]\n    F -->|Yes, same template| H[\"Reuse existing view\"]\n    F -->|Yes, different template| I[\"Remove old view, create new\"]\n    G --> J[\"view.bind(source, context)\"]\n    I --> J\n    J --> K[\"view.insertBefore(target)\"]\n    K --> L[\"Cache: target.$fastView = view, target.$fastTemplate = value\"]\n\n    D -->|No — Primitive| M{\"Existing composed view?\"}\n    M -->|Yes| N[\"view.remove(), view.unbind()\"]\n    N --> O[\"target.textContent = value\"]\n    M -->|No| O\n```\n\n---\n\n## Key Data Structures\n\n| Structure | Location | Purpose |\n|---|---|---|\n| `ViewTemplate` | template.ts | Holds raw HTML + factories record. Entry point for compilation. |\n| `factories: Record<string, ViewBehaviorFactory>` | template.ts | Maps unique IDs to binding factories (directives). |\n| `CompilationContext` | compiler.ts | Accumulates factories and builds the target prototype during compilation. |\n| `targets: ViewBehaviorTargets` | view.ts / html-directive.ts | Maps node IDs (e.g., `\"r.0.2\"`) to actual DOM nodes in a cloned fragment. |\n| `HTMLView` | view.ts | The live view instance: holds the fragment, factories, targets, behaviors, and source. |\n| `HTMLBindingDirective` | html-binding-directive.ts | The core binding: acts as factory, behavior, and event listener. |\n| `sinkLookup` | html-binding-directive.ts | Maps `DOMAspect` types to DOM update functions. |\n| `Binding` (abstract) | binding/binding.ts | Wraps an expression with policy, volatility, and observer creation. |\n| `ExpressionObserver` | observation/observable.ts | Tracks dependencies during expression evaluation and notifies on change. |\n\n## Binding Type Summary\n\n| Markup Syntax | Aspect Type | Sink Function | Example |\n|---|---|---|---|\n| `attr=\"${x => x.val}\"` | `attribute` | `DOM.setAttribute` | `class=\"${x => x.cls}\"` |\n| `?attr=\"${x => x.val}\"` | `booleanAttribute` | `DOM.setBooleanAttribute` | `?disabled=\"${x => x.off}\"` |\n| `:prop=\"${x => x.val}\"` | `property` | `target[prop] = value` | `:value=\"${x => x.name}\"` |\n| `:classList=\"${x => x.val}\"` | `tokenList` | `updateTokenList` | `:classList=\"${x => x.classes}\"` |\n| `@event=\"${x => x.handler}\"` | `event` | addEventListener | `@click=\"${(x,c) => x.onClick(c.event)}\"` |\n| `${x => x.val}` (in text) | `content` | `updateContent` | `<p>${x => x.msg}</p>` |\n\n---\n\n## Hydration: Attaching Bindings to Server-Rendered DOM\n\nWhen a page is server-side rendered (SSR) with Declarative Shadow DOM, the HTML arrives in the browser fully formed. Instead of creating new DOM nodes, FAST's hydration system **reuses the existing DOM** and attaches reactive bindings to it. This section explains how hydration markers in the SSR output guide the client-side binding process.\n\n### Enabling Hydration\n\nHydration is an opt-in feature. Calling `enableHydration()` patches\n`ViewTemplate.prototype` with:\n1. A `Hydratable` symbol — marks the template as hydration-capable (checked via `isHydratable()`).\n2. A `hydrate(firstChild, lastChild, hostBindingTarget?)` method — creates a `HydrationView` instead of an `HTMLView`.\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration();\n```\n\n### Hydration Marker Format\n\nThe SSR renderer embeds comment nodes and data attributes into the HTML to mark where bindings should attach. These markers encode the **factory index** (position in the compiled factories array) so the client can map each marker back to its corresponding `ViewBehaviorFactory`.\n\n#### Attribute Binding Markers\n\nElements with attribute/property/event bindings receive a `data-fe` attribute with the binding count:\n\n```html\n<!-- SSR output for: <div class=\"${x => x.cls}\" :value=\"${x => x.val}\"> -->\n<div data-fe=\"2\">server-rendered content</div>\n```\n\nThe attribute marker format is:\n\n| Attribute | Example | Description |\n|---|---|---|\n| `data-fe` | `data-fe=\"3\"` | Binding count — the number of attribute bindings on the element |\n\n#### Content Binding Markers\n\nText/template content bindings are wrapped in paired data-free comment nodes (matched by string equality, paired by balanced depth counting):\n\n```html\n<!--fe:b-->\nHello, World!\n<!--fe:/b-->\n```\n\n#### Repeat Directive Markers\n\nEach repeated item is bracketed by data-free repeat markers:\n\n```html\n<!--fe:r-->\n<li>First item</li>\n<!--fe:/r-->\n<!--fe:r-->\n<li>Second item</li>\n<!--fe:/r-->\n```\n\n#### Element Boundary Markers\n\nNested custom elements that also need hydration are demarcated so the parent's walker can skip over them:\n\n```html\n<!--fe:e-->\n<child-element>\n  <template shadowrootmode=\"open\">...child shadow DOM...</template>\n</child-element>\n<!--fe:/e-->\n```\n\n### Hydration Binding Flow\n\n`hydration/traversal.ts` owns pointer navigation and its live Range fallback.\n`hydration/target-builder.ts` consumes that traversal to map factories, keeping\ndirect native marker reads inline. `HydrationView` uses the same range utility\nwhen producing diagnostic fragments, without coupling it to target discovery.\n\n`enableHydration()` replaces the small core `components/element-registration.ts`\nstrategy with `hydration/attribute-observation.ts`. Client-only `FASTElement`\nbundles do not include observation tracking. Immediately before FAST's platform\nregistration, tracking records only a boolean proving that `data-fe` is\nunobserved, after extensions and asynchronous template resolution. The proof is\navailable during synchronous upgrades and restored if registration fails.\nEarlier untracked registrations remain conservative; calling `enableHydration()`\nagain does not reset existing proof. Hydration never reconstructs the platform\nsnapshot by rereading `constructor.observedAttributes`.\n\nFor a known unobserved `data-fe` attribute and native attribute methods, removal\ncannot invoke an attribute-change callback, so pointers remain active.\nRegistration/lifecycle accessors, custom attribute iterators, unknown registry\nwrappers, customized built-ins, and overridden attribute methods remain\nconservative. Legacy/custom marker cleanup still captures live boundaries from\nthe outset. Marker removal is not deferred and callback order is unchanged.\n\n```mermaid\nflowchart TD\n    A[\"Server renders HTML with Declarative Shadow DOM\"] --> B[\"Browser parses HTML, creates DOM + shadow roots\"]\n    B --> C[\"Custom element connects, HydratableElementController activates\"]\n    C --> D{\"Has 'defer-hydration' attribute?\"}\n    D -->|Yes| E[\"Wait until attribute is removed\"]\n    D -->|No| F[\"template.hydrate(firstChild, lastChild, hostBindingTarget)\"]\n    E -->|Attribute removed| F\n    F --> G[\"new HydrationView(firstChild, lastChild, sourceTemplate)\"]\n    G --> H[\"HydrationView.bind(source)\"]\n    H --> I[\"Stage: unhydrated → hydrating\"]\n    I --> J[\"buildViewBindingTargets(firstChild, lastChild, factories)\"]\n\n    J --> K[\"Pointer DFS for ordered sibling endpoints; live Range fallback otherwise or before mutating cleanup\"]\n    K --> L{\"Walk each node\"}\n\n    L -->|Element node| M[\"Parse data-fe attribute\"]\n    M --> N[\"Consume N sequential factories directly via targetFactory(); generic resolution for legacy markers\"]\n    N --> O[\"Remove data-fe marker attribute\"]\n\n    L -->|Comment: content marker| P[\"Match fe:b start marker by string equality\"]\n    P --> Q[\"Walk siblings to find matching fe:/b end marker\\nusing balanced depth counting\"]\n    Q --> R{\"Content between markers?\"}\n    R -->|Single text node| S[\"Target factory to text node directly\"]\n    R -->|Multiple nodes / template| T[\"Store boundaries in ViewBehaviorBoundaries\"]\n    T --> U[\"Insert dummy text node as target for future string updates\"]\n    R -->|Empty null/false binding| U\n    L -->|Comment: element boundary| V[\"Clear fe:e start marker data\\nSkip to matching fe:/e end marker\\nusing balanced depth counting\\nClear fe:/e end marker data\\nThrow if end marker not found\"]\n    L -->|Other| W[\"Continue walking\"]\n    J --> X[\"Return { targets, boundaries }\"]\n    X --> Y[\"Create behaviors from factories\"]\n    Y --> Z[\"behavior.bind(hydrationView)\"]\n    Z --> AA[\"Stage: hydrating → hydrated\"]\n\n    subgraph \"Host Binding Offset\"\n        BB[\"Host bindings (targetNodeId='h') are at the start of the factories array\"]\n        CC[\"getHydrationIndexOffset() counts host bindings to skip\"]\n        DD[\"SSR markers use indices relative to non-host factories\"]\n    end\n```\n\n### HydrationView vs HTMLView\n\n```mermaid\nflowchart LR\n    subgraph \"HTMLView (client-rendered)\"\n        A1[\"Compiler produces DocumentFragment\"] --> A2[\"fragment.cloneNode(true)\"]\n        A2 --> A3[\"Resolve targets via prototype getter chain\"]\n        A3 --> A4[\"Create behaviors & bind\"]\n    end\n\n    subgraph \"HydrationView (server-rendered)\"\n        B1[\"DOM already exists in shadow root\"] --> B2[\"Bounded pointer DFS scans markers; live Range fallback when needed\"]\n        B2 --> B3[\"buildViewBindingTargets maps markers → nodes\"]\n        B3 --> B4[\"Create behaviors & bind to existing nodes\"]\n        B4 --> B5[\"Marker comments cleared (data set to empty string)\"]\n    end\n```\n\n| Aspect | HTMLView | HydrationView |\n|---|---|---|\n| **DOM source** | Clones compiled DocumentFragment | Reuses server-rendered DOM in place |\n| **Target resolution** | Prototype getters via childNodes indices | Pointer DFS + sequential markers; live Range / generic-strategy fallback |\n| **Node creation** | Creates all DOM nodes from scratch | No node creation (reuses existing) |\n| **Fragment** | Holds cloned fragment, moved into host | No fragment initially (created only on remove) |\n| **Lifecycle** | Ready immediately after creation | Transitions through unhydrated → hydrating → hydrated |\n| **Validation** | Compilation guarantees structure | Must validate markers match factories (throws HydrationBindingError) |\n| **Boundaries** | Not needed (compiler tracks structure) | `bindingViewBoundaries` stores first/last node pairs for structural directives |\n\n### Content Binding Hydration\n\nWhen `HTMLBindingDirective.bind()` runs during hydration and the binding returns a `ContentTemplate`, the `updateContent` sink checks for pre-rendered boundaries:\n\n```mermaid\nsequenceDiagram\n    participant Directive as HTMLBindingDirective\n    participant Controller as HydrationView (controller)\n    participant Sink as updateContent()\n    participant Template as ContentTemplate\n\n    Directive->>Controller: bind(controller)\n    Note over Directive: aspectType = DOMAspect.content\n    Directive->>Sink: updateTarget(target, aspect, value, controller)\n    Sink->>Sink: value is ContentTemplate?\n\n    alt Hydrating & boundaries exist\n        Sink->>Controller: Check bindingViewBoundaries[targetNodeId]\n        Controller-->>Sink: { first: Node, last: Node }\n        Sink->>Template: value.hydrate(first, last)\n        Template-->>Sink: HydrationView (reuses existing nodes)\n        Sink->>Sink: view.bind(source, context) — attaches to pre-rendered DOM\n    else Already hydrated or no boundaries\n        Sink->>Template: value.create()\n        Template-->>Sink: HTMLView (creates new nodes)\n        Sink->>Sink: view.bind + view.insertBefore\n    end\n```\n\n### Repeat Directive Hydration\n\nThe repeat directive scans **forward** from its own content boundary to its\nlocation, pairing top-level ranges with a stack. This avoids reverse collection\nand rescanning prefixes belonging to earlier adjacent repeats. Nested markers\nremain untouched until child views hydrate. Both unmatched starts and unmatched\nends throw before repeat markers are cleared.\n\nThe read-only `collectHydrationRepeatRanges()` helper in\n`hydration/repeat-ranges.ts` owns this discovery and validation. `RepeatBehavior`\nsupplies its own binding boundaries, then clears top-level markers and hydrates,\ncreates, or removes views. The discovery helper does not alter marker data or\nbind views.\n\n```mermaid\nflowchart TD\n    A[\"RepeatBehavior.bind(controller)\"] --> B{\"isHydratable(template) && hydrating?\"}\n    B -->|Yes| C[\"hydrateViews(template)\"]\n    B -->|No| D[\"refreshAllViews() — normal client path\"]\n\n    C --> E[\"Allocate views array sized to items.length\"]\n    E --> F[\"Scan bindingViewBoundaries[targetNodeId].first through location\"]\n    F --> G{\"Repeat marker?\"}\n    G -->|Start| H[\"Push start marker\"]\n    G -->|End| I[\"Pop start; throw if absent\"]\n    I --> J{\"Stack empty?\"}\n    J -->|Yes| K[\"Append top-level range in item order\"]\n    J -->|No| F\n    H --> F\n    K --> F\n    G -->|Other node| F\n    F -->|Reached location| L[\"Throw if stack nonempty; otherwise clear top-level markers\"]\n    L --> M[\"Hydrate overlapping SSR/client ranges in order\"]\n    M --> N[\"Create missing client views and remove excess server ranges\"]\n\n    subgraph \"Result\"\n        S[\"Each array item mapped to a HydrationView\"]\n        T[\"Views reuse server-rendered DOM between markers\"]\n        U[\"Markers cleared to empty strings (invisible in DOM)\"]\n    end\n```\n\n### Hydration CPU regression coverage\n\n`src/hydration/hydration-performance.pw.spec.ts` instruments Range/TreeWalker\ncreation and native factory-index array allocation across 500 sibling-bounded\nviews. Those counters must all be zero on the ordinary native path. It also\nasserts exact linear repeat predicate visits (four starts and two ends per\nfour-comment nested item), scope isolation from earlier siblings, nested marker\npreservation, malformed-marker diagnostics, installed `markers_v2`, empty items,\nand missing/excess reconciliation. Existing target-builder tests compare live\nendpoint mutations with the legacy Range walker. The declarative repeat fixture\nchecks SSR node identity, three nested repeat levels, an empty inner list, and an\nadjacent repeat before exercising reactive updates. The co-located\n`src/hydration/repeat-ranges.pw.spec.ts` also verifies that successful discovery\nleaves native and legacy marker data unchanged and excludes adjacent ranges.\n\n`src/hydration/native-marker-cleanup.pw.spec.ts` exercises a 1,000-record,\nthree-repeat-level workload with 20 adjacent prefix items: 4,021 FAST elements,\n4,020 native attribute markers, and 8,041 hydrated views. Range/TreeWalker setup,\n`comparePoint`, and `intersectsNode` counts are all zero; all 7,020 SSR descendant\nelements retain their identity. Mutation fixtures require the fallback and\nverify immediate insertion/removal, endpoint moves, unstable observation\nmetadata, method accessors, customized built-ins, and legacy/custom strategies.\nRegistration-order cases cover disabled tracking, enabling after registration,\nrepeated enablement after observation changes, and platform registration deferred\nuntil after asynchronous template resolution.\nThe declarative repeat fixture includes bound FAST child elements, checks zero\nlive traversal setup, and exercises reactive updates after hydration.\n\nRun focused correctness coverage from the monorepo root:\n\n```sh\nnpm exec -w @microsoft/fast-element -- playwright test src/hydration/target-builder.pw.spec.ts src/hydration/hydration-performance.pw.spec.ts src/hydration/native-marker-cleanup.pw.spec.ts src/hydration/repeat-ranges.pw.spec.ts src/templating/repeat.pw.spec.ts --project=chromium\n```\n\nCPU timings live separately in `src/hydration/hydration-benchmark.pw.spec.ts`\nand are opt-in rather than flaky wall-clock CI gates:\n\n```sh\nFAST_HYDRATION_BENCHMARK=1 npm exec -w @microsoft/fast-element -- playwright test src/hydration/hydration-benchmark.pw.spec.ts --project=chromium --retries=0\n```\n\nThe workloads measure 4,000 marker-free sibling views, 4,000 native\nattribute/content marker groups, 4,000 nested repeat ranges with stubbed child\nhydration, 20 adjacent repeats with 200 flat item ranges each, and a combined\n1,000-record page with three repeat levels, 4,000 minimal native custom elements,\nand 8,001 hydrated views. Setup, custom-element registration, and template\nconstruction are outside the timed interval; repeat workloads include bind and unbind. Each\nworkload has one warm-up and ten recorded samples, each in a fresh document so\nlive Ranges from earlier samples cannot amplify later DOM mutation costs.\nCompare the same test on the base and changed revisions on the same browser and\nmachine. To attribute improvements, also compare traversal-only, native-only,\nand repeat-only source variants in an isolated worktree, reversing variant order\nfor a second pass. The combined workload includes conservative live-Range\nfallbacks for custom-element attribute cleanup, not just ordinary element views.\nThese microbenchmarks time template hydration, not the issue's application\nregistration or hydration-completion tracking, and should not be presented as\nthat application's hydration timings.\n\nThe separate native FAST workload times bind/unbind for the 4,021-element /\n8,041-view case above. Setup and registration are excluded, identity and marker\nremoval are verified after every sample, and the same fresh-document sampling\nrules apply. Use this workload to compare the known-unobserved cleanup path;\nthe original combined workload intentionally registers ordinary custom elements\noutside FAST and therefore retains its conservative fallback.\n\n### Hydration Stage Lifecycle\n\n```mermaid\nstateDiagram-v2\n    [*] --> unhydrated: HydrationView created\n\n    unhydrated --> hydrating: bind() called\n    note right of hydrating\n        buildViewBindingTargets() scans DOM\n        Markers parsed, targets resolved\n        Behaviors created and bound\n        Attribute bindings skip DOM update\n        (server already set correct values)\n    end note\n\n    hydrating --> hydrated: All behaviors bound\n    note right of hydrated\n        Subsequent bind() calls\n        behave like normal HTMLView rebind\n        (re-evaluate expressions, update DOM)\n    end note\n\n    hydrated --> hydrated: rebind with new source\n```\n\nDuring the `hydrating` stage, attribute and boolean-attribute bindings **skip their initial DOM update** (the server already rendered the correct value). This avoids unnecessary DOM writes during hydration:\n\n```typescript\n// In HTMLBindingDirective.bind(), during hydration:\nif (isHydrating && (this.aspectType === DOMAspect.attribute ||\n                    this.aspectType === DOMAspect.booleanAttribute)) {\n    observer.bind(controller);  // Set up observation only\n    break;                      // Skip updateTarget — server value is current\n}\n```\n\n### Error Handling\n\nWhen the server-rendered DOM doesn't match the client template, hydration throws descriptive errors:\n\n| Error | Cause | Contains |\n|---|---|---|\n| `HydrationTargetElementError` | `data-fe` specifies a binding count that cannot be satisfied, more content binding markers exist than factories, or an element boundary end marker is missing | Factories array, target node; with `hydrationDebugger()` installed: structured `expected` (string or `HydrationMismatchExpectation`) describing what the walk wanted next, and `received` (`HydrationMismatchActual`) containing an HTML snippet of the offending DOM |\n| `HydrationBindingError` | A factory's `targetNodeId` has no matching entry in targets after the SSR DOM walk completes | Factory, cloned fragment, template string; with `hydrationDebugger()` installed: structured `expected` (`HydrationMismatchExpectation` with `tagName` and human-readable `aspect`) and `received` (`HydrationMismatchActual` with an HTML snippet of the SSR view range) |\n| `HydrationRepeatError` | A repeat view slot is unexpectedly `null` / `undefined` during rebind or unbind (internal invariant violation). SSR/client item-count mismatches are no longer surfaced as errors — they are reconciled silently by `RepeatBehavior.hydrateViews()` (missing client views are created, extra SSR ranges are removed) | Hydration stage, items length, view states |\n| `FAST.error(1210)` | `data-fe` attribute contains a non-numeric or non-positive value | Attribute value |\n\nThese errors typically indicate a mismatch between the server-rendered HTML and the client-side template definition.\n\nBy default, both errors emit a minimal one-line message that points at the opt-in `hydrationDebugger()`. Install the debugger from `@microsoft/fast-element/hydration.js` and pass it to `enableHydration` to swap in the rich format:\n\n```ts\nimport { enableHydration, hydrationDebugger } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ debugger: hydrationDebugger() });\n```\n\nWith the debugger installed, both errors format their message as:\n\n```\nHydration mismatch in <host-element>.\n  Expected: <tag> with <aspect> binding   (or a structural description)\n  Received: <SSR HTML snippet>\n```\n\nand expose the same information programmatically through the `expected` and `received` fields so tooling can read the structured description without parsing the message string. Keeping the debugger out of the import graph saves ~0.5 KB on the production hydration bundle.\n","packages/fast-router/README.md":"# FAST Router\n\nThe `@microsoft/fast-router` package contains a history-based navigation and routing solution designed around Web Components. By using `fast-router`, you can create multi-page and full application experiences. The router works with any Web Components, but has special support for Web Components built on FAST.\n\n## Installation\n\n### From NPM\n\nTo install the `fast-router` library using `npm`:\n\n```shell\nnpm install --save @microsoft/fast-router\n```\n\nWithin your JavaScript or TypeScript code, you can then import library APIs like this:\n\n```ts\nimport { FASTRouter } from '@microsoft/fast-router';\n```\n\nLooking for a setup that integrates with a particular front-end framework or bundler? Check out [our integration docs](https://fast.design/docs/integrations/introduction).\n\n## Configuration at a Glance\n\nThe router is currently in `alpha` while we address a few bugs, finish up some final polish, and write the full documentation. Below is a quick sample of how to configure the router, to help get you going while we complete the full documentation.\n\n#### A Sample Route Configuration\n\n```ts\nimport { RouterConfiguration, Route } from '@microsoft/fast-router';\nimport { HomeScreen } from './home';\nimport { AccountLogin } from './account/login';\nimport { AccountSignup } from './account/signup';\nimport { ConfirmEmail } from './account/confirm-email';\nimport { Session } from './account/session';\nimport { AccountSettings } from './account/settings';\nimport { StoreArea } from './store/store-area';\nimport { NotFound } from './not-found';\nimport { pageLayout } from './layouts/page-layout';\nimport { anonymousLayout } from './layouts/anonymous-layout';\n\ntype RouteSettings = {\n  public?: boolean\n};\n\nexport class AppRouterConfiguration extends RouterConfiguration<RouteSettings> {\n  public configure() {\n    this.title = 'My App';\n    this.defaultLayout = pageLayout;\n    this.routes.map(\n      { path: '', redirect: 'home' },\n      { path: 'home', title: 'Home', element: HomeScreen },\n      { \n        path: 'account', \n        layout: anonymousLayout, \n        title: 'Account',\n        settings: { public: true }, \n        children: [\n          { path: \"login\", title: 'Login', element: AccountLogin, name: 'login' },\n          { path: 'signup' title: 'Signup', element: AccountSignup },\n          { path: 'confirm/{confirmation:Confirmation}', title: 'Confirm', element: ConfirmEmail },\n          { path: 'settings', title: 'Settings', element: AccountSettings, layout: pageLayout, settings: { public: false } },\n        ] \n      },\n      { path: 'store', title: 'Store', element: StoreArea, childRouters: true },\n      { path: 'not-found', title: 'Not Found', element: NotFound }\n    );\n\n    this.routes.fallback(\n      () => Session.isLoggedIn\n        ? { redirect: 'not-found' }\n        : { redirect: 'login' }\n    );\n\n    this.routes.converter(\"Confirmation\", async (confirmationId) => {\n      // ...fetch confirmation from web service...\n      return confirmation;\n    });\n\n    this.contributors.push({\n      navigate(phase) {\n        const settings = phase.route.settings;\n  \n        if (settings && settings.public) {\n          return;\n        }\n  \n        if (Session.loggedIn) {\n          return;\n        }\n  \n        phase.cancel(() => {\n          Session.returnUrl = Route.path.current;\n          Route.name.replace(phase.router, 'login');\n        });\n      }\n    });\n  }\n}\n```\n\n#### Using the Configuration with a Router\n\n```ts\nimport { FASTElement, customElement } from '@microsoft/fast-element/fast-element.js';\nimport { css } from '@microsoft/fast-element/css.js';\nimport { html } from '@microsoft/fast-element/html.js';\nimport { FASTRouter } from '@microsoft/fast-router';\nimport { AppRouterConfiguration } from './routes';\n\nFASTRouter;\n\nconst template = html<MainApplication>`\n    <fast-router :config=${x => x.routerConfiguration}></fast-router>\n`;\n\nconst styles = css`\n  :host {\n    contain: content;\n  }\n\n  :host, fast-router {  \n    display: block;\n    width: 100%;\n    height: 100%;\n  }\n`;\n\n@customElement({\n  name: 'main-application',\n  template,\n  styles\n})\nexport class MainApplication extends FASTElement {\n  routerConfiguration = new AppRouterConfiguration();\n}\n```\n","packages/fast-router/docs/api-report.api.md":"## API Report File for \"@microsoft/fast-router\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\nimport { AddViewBehaviorFactory } from '@microsoft/fast-element';\nimport { ComposableStyles } from '@microsoft/fast-element';\nimport { Constructable } from '@microsoft/fast-element';\nimport { ExecutionContext } from '@microsoft/fast-element';\nimport { FASTElement } from '@microsoft/fast-element';\nimport { ViewBehavior } from '@microsoft/fast-element';\nimport { ViewBehaviorFactory } from '@microsoft/fast-element';\nimport { ViewController } from '@microsoft/fast-element';\nimport { ViewTemplate } from '@microsoft/fast-element';\n\n// Warning: (ae-internal-missing-underscore) The name \"childRouteParameter\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport const childRouteParameter = \"fast-child-route\";\n\n// @beta (undocumented)\nexport type CommandFallbackRouteDefinition<TSettings = any> = HasCommand & SupportsSettings<TSettings> & HasTitle;\n\n// @beta (undocumented)\nexport type CommandRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings> & HasCommand & HasTitle;\n\n// @beta (undocumented)\nexport class ConfigurableRoute implements Route {\n    constructor(path: string, name: string, caseSensitive: boolean);\n    // (undocumented)\n    readonly caseSensitive: boolean;\n    // (undocumented)\n    readonly name: string;\n    // (undocumented)\n    readonly path: string;\n}\n\n// @beta (undocumented)\nexport type ContributorOptions = {\n    lifecycle?: boolean;\n    parameters?: boolean;\n};\n\n// @beta (undocumented)\nexport class DefaultLinkHandler implements LinkHandler {\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n}\n\n// @beta (undocumented)\nexport class DefaultNavigationProcess<TSettings> {\n    // Warning: (ae-forgotten-export) The symbol \"NavigationPhaseImpl\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    commit(phase: NavigationPhaseImpl): void;\n    // (undocumented)\n    run(router: Router, message: NavigationMessage): Promise<void>;\n}\n\n// @beta (undocumented)\nexport class DefaultNavigationQueue implements NavigationQueue, NavigationHandler {\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n    // (undocumented)\n    enqueue(msg: NavigationMessage): void;\n    // (undocumented)\n    handleEvent(event: PopStateEvent): void;\n    // (undocumented)\n    receive(): Promise<NavigationMessage>;\n}\n\n// @beta (undocumented)\nexport class DefaultRouter implements Router {\n    constructor(host: HTMLElement);\n    // (undocumented)\n    addContributor(contributor: NavigationContributor): void;\n    // (undocumented)\n    beginRender(route: RecognizedRoute, command: RenderCommand): Promise<{\n        commit: () => Promise<void>;\n        rollback: () => Promise<void>;\n    }>;\n    // (undocumented)\n    get config(): RouterConfiguration | null;\n    set config(value: RouterConfiguration | null);\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n    // (undocumented)\n    readonly host: HTMLElement;\n    // (undocumented)\n    get level(): number;\n    // (undocumented)\n    get parent(): Router<any> | null;\n    // (undocumented)\n    removeContributor(contributor: NavigationContributor): void;\n    // (undocumented)\n    route: RecognizedRoute | null;\n    // (undocumented)\n    shouldRender(route: RecognizedRoute): boolean;\n}\n\n// @beta (undocumented)\nexport class DefaultRouteRecognizer<TSettings> implements RouteRecognizer<TSettings> {\n    // (undocumented)\n    add(routeOrRoutes: Route | readonly Route[], settings?: TSettings): void;\n    generateFromName(name: string, params: object): string | null;\n    generateFromPath(path: string, params: object): string | null;\n    // (undocumented)\n    recognize(path: string, converters?: Readonly<Record<string, RouteParameterConverter>>): Promise<RecognizedRoute<TSettings> | null>;\n}\n\n// @beta (undocumented)\nexport type DefinitionCallback = () => Promise<FallbackRouteDefinition> | FallbackRouteDefinition;\n\n// @beta (undocumented)\nexport type ElementFallbackRouteDefinition<TSettings = any> = LayoutAndTransitionRouteDefinition & HasElement & SupportsSettings<TSettings> & HasTitle;\n\n// @beta (undocumented)\nexport type ElementRouteDefinition<TSettings = any> = NavigableRouteDefinition<TSettings> & HasElement;\n\n// @beta (undocumented)\nexport class Endpoint<TSettings = any> {\n    constructor(route: ConfigurableRoute, paramNames: readonly string[], paramTypes: readonly string[], settings: TSettings | null);\n    // (undocumented)\n    readonly paramNames: readonly string[];\n    // (undocumented)\n    readonly paramTypes: readonly string[];\n    // (undocumented)\n    get path(): string;\n    // (undocumented)\n    readonly route: ConfigurableRoute;\n    // (undocumented)\n    readonly settings: TSettings | null;\n}\n\n// @beta (undocumented)\nexport type FallbackRouteDefinition<TSettings = any> = ElementFallbackRouteDefinition<TSettings> | TemplateFallbackRouteDefinition<TSettings> | Pick<RedirectRouteDefinition<TSettings>, \"redirect\"> | CommandFallbackRouteDefinition<TSettings>;\n\n// @beta (undocumented)\nexport type FASTElementConstructor = new () => FASTElement;\n\n// @beta (undocumented)\nexport class FASTElementLayout implements Layout {\n    constructor(template?: ViewTemplate | null, styles?: ComposableStyles | ComposableStyles[] | undefined, runBeforeCommit?: boolean);\n    // (undocumented)\n    afterCommit(routerElement: HTMLElement): Promise<void>;\n    // (undocumented)\n    beforeCommit(routerElement: HTMLElement): Promise<void>;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"FASTRouter_base\" needs to be exported by the entry point index.d.ts\n//\n// @beta (undocumented)\nexport class FASTRouter extends FASTRouter_base {\n}\n\n// @beta (undocumented)\nexport type HasCommand = {\n    command: NavigationCommand;\n};\n\n// @beta (undocumented)\nexport type HasElement = {\n    element: string | FASTElementConstructor | HTMLElement | (() => Promise<string | FASTElementConstructor | HTMLElement>);\n};\n\n// @beta (undocumented)\nexport type HasTemplate = {\n    template: ViewTemplate | (() => Promise<ViewTemplate>);\n};\n\n// @beta (undocumented)\nexport type HasTitle = {\n    title?: string;\n};\n\n// @beta (undocumented)\nexport type IgnorableRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings>;\n\n// @beta (undocumented)\nexport class Ignore implements NavigationCommand {\n    // (undocumented)\n    createContributor(): Promise<{\n        navigate(phase: NavigationPhase): Promise<void>;\n    }>;\n}\n\n// @beta (undocumented)\nexport function isFASTElementHost(host: HTMLElement): host is HTMLElement & FASTElement;\n\n// @beta (undocumented)\nexport function isNavigationPhaseContributor<T extends NavigationPhaseName>(object: any, phase: T): object is Record<T, NavigationPhaseHook>;\n\n// @beta (undocumented)\nexport interface Layout {\n    // (undocumented)\n    afterCommit(routerElement: HTMLElement): Promise<void>;\n    // (undocumented)\n    beforeCommit(routerElement: HTMLElement): Promise<void>;\n}\n\n// @beta (undocumented)\nexport const Layout: Readonly<{\n    default: Readonly<Layout>;\n}>;\n\n// @beta (undocumented)\nexport type LayoutAndTransitionRouteDefinition = {\n    layout?: Layout | ViewTemplate;\n    transition?: Transition;\n};\n\n// @beta (undocumented)\nexport interface LinkHandler {\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n}\n\n// @beta (undocumented)\nexport type MappableRouteDefinition<TSettings = any> = RenderableRouteDefinition<TSettings> | RedirectRouteDefinition<TSettings> | CommandRouteDefinition<TSettings> | ParentRouteDefinition<TSettings>;\n\n// @beta (undocumented)\nexport type NavigableRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings> & LayoutAndTransitionRouteDefinition & HasTitle & {\n    childRouters?: boolean;\n};\n\n// @beta (undocumented)\nexport interface NavigationCommand {\n    // (undocumented)\n    createContributor(router: Router, route: RecognizedRoute): Promise<NavigationContributor>;\n}\n\n// @beta (undocumented)\nexport interface NavigationCommitPhase<TSettings = any> extends Omit<NavigationPhase<TSettings>, \"cancel\" | \"canceled\" | \"onCancel\"> {\n    // (undocumented)\n    setTitle(title: string): void;\n}\n\n// @beta (undocumented)\nexport type NavigationCommitPhaseHook<TSettings = any> = (phase: NavigationCommitPhase<TSettings>) => Promise<any> | any;\n\n// @beta (undocumented)\nexport type NavigationContributor<TSettings = any> = Partial<Record<Exclude<NavigationPhaseName, \"commit\">, NavigationPhaseHook<TSettings>>> & {\n    commit?: NavigationCommitPhaseHook<TSettings>;\n};\n\n// Warning: (ae-forgotten-export) The symbol \"NavigationContributorDirective\" needs to be exported by the entry point index.d.ts\n//\n// @beta (undocumented)\nexport function navigationContributor(options?: ContributorOptions): NavigationContributorDirective;\n\n// @beta (undocumented)\nexport interface NavigationHandler {\n    // (undocumented)\n    enqueue(msg: NavigationMessage): void;\n}\n\n// @beta (undocumented)\nexport const NavigationHandler: Readonly<{\n    register(handler: NavigationHandler): void;\n    unregister(handler: NavigationHandler): void;\n}>;\n\n// @beta (undocumented)\nexport class NavigationMessage {\n    constructor(path: string);\n    // (undocumented)\n    path: string;\n}\n\n// @beta (undocumented)\nexport interface NavigationPhase<TSettings = any> {\n    // (undocumented)\n    cancel(callback?: NavigationPhaseFollowupAction): void;\n    // (undocumented)\n    readonly canceled: boolean;\n    // (undocumented)\n    evaluateContributor(contributor: any, route?: RecognizedRoute<TSettings>, router?: Router<TSettings>): Promise<void>;\n    // (undocumented)\n    readonly name: NavigationPhaseName;\n    // (undocumented)\n    onCancel(callback: NavigationPhaseFollowupAction): void;\n    // (undocumented)\n    onCommit(callback: NavigationPhaseFollowupAction): void;\n    // (undocumented)\n    readonly route: RecognizedRoute<TSettings>;\n    // (undocumented)\n    readonly router: Router<TSettings>;\n}\n\n// @beta (undocumented)\nexport type NavigationPhaseFollowupAction = () => Promise<any> | any;\n\n// @beta (undocumented)\nexport type NavigationPhaseHook<TSettings = any> = (phase: NavigationPhase<TSettings>) => Promise<any> | any;\n\n// @beta (undocumented)\nexport type NavigationPhaseName = \"navigate\" | \"leave\" | \"construct\" | \"enter\" | \"commit\";\n\n// @beta (undocumented)\nexport interface NavigationProcess {\n    // (undocumented)\n    run(router: Router, message: NavigationMessage): Promise<void>;\n}\n\n// @beta (undocumented)\nexport interface NavigationQueue {\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n    // (undocumented)\n    receive(): Promise<NavigationMessage>;\n}\n\n// @beta (undocumented)\nexport type ParameterConverter = RouteParameterConverter | RouteParameterConverterObject | Constructable<RouteParameterConverterObject>;\n\n// @beta (undocumented)\nexport type ParentRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings> & LayoutAndTransitionRouteDefinition & {\n    children: MappableRouteDefinition<TSettings>[];\n};\n\n// @beta (undocumented)\nexport type PathedRouteDefinition<TSettings = any> = SupportsSettings<TSettings> & Route;\n\n// @beta (undocumented)\nexport const QueryString: Readonly<{\n    readonly current: string;\n    build(params: Record<string, string>, traditional?: boolean): string;\n    separate(path: string): Readonly<{\n        path: string;\n        queryString: string;\n    }>;\n    parse(queryString: string): Readonly<Record<string, string>>;\n}>;\n\n// @beta (undocumented)\nexport class RecognizedRoute<TSettings = any> {\n    constructor(endpoint: Endpoint<TSettings>, params: Readonly<Record<string, string | undefined>>, typedParams: Readonly<Record<string, any>>, queryParams: Readonly<Record<string, string>>);\n    // (undocumented)\n    readonly allParams: Readonly<Record<string, string | undefined>>;\n    // (undocumented)\n    readonly allTypedParams: Readonly<Record<string, any>>;\n    // (undocumented)\n    readonly endpoint: Endpoint<TSettings>;\n    // (undocumented)\n    readonly params: Readonly<Record<string, string | undefined>>;\n    // (undocumented)\n    readonly queryParams: Readonly<Record<string, string>>;\n    // (undocumented)\n    get settings(): TSettings | null;\n    // (undocumented)\n    readonly typedParams: Readonly<Record<string, any>>;\n}\n\n// @beta (undocumented)\nexport class Redirect implements NavigationCommand {\n    constructor(redirect: string);\n    // (undocumented)\n    createContributor(): Promise<{\n        navigate(phase: NavigationPhase): Promise<void>;\n    }>;\n}\n\n// @beta (undocumented)\nexport type RedirectRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings> & {\n    redirect: string;\n};\n\n// @beta (undocumented)\nexport class Render implements RenderCommand {\n    constructor(owner: RouterConfiguration, createView: () => Promise<RouteView>);\n    // Warning: (ae-forgotten-export) The symbol \"RenderContributor\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    createContributor(router: Router, route: RecognizedRoute): Promise<RenderContributor>;\n    // (undocumented)\n    createView: () => Promise<RouteView>;\n    // (undocumented)\n    static fromDefinition(owner: RouterConfiguration, definition: ElementRouteDefinition | TemplateRouteDefinition | ElementFallbackRouteDefinition | TemplateFallbackRouteDefinition): Render;\n    // (undocumented)\n    get layout(): Layout;\n    set layout(value: Layout);\n    // (undocumented)\n    title: string;\n    // (undocumented)\n    get transition(): Transition;\n    set transition(value: Transition);\n}\n\n// @beta (undocumented)\nexport type RenderableRouteDefinition<TSettings = any> = ElementRouteDefinition<TSettings> | TemplateRouteDefinition<TSettings>;\n\n// @beta (undocumented)\nexport interface RenderCommand extends NavigationCommand {\n    // (undocumented)\n    createView(): Promise<RouteView>;\n    // (undocumented)\n    layout: Layout;\n    // (undocumented)\n    transition: Transition;\n}\n\n// @beta (undocumented)\nexport interface RenderOperation {\n    // (undocumented)\n    commit(): Promise<void>;\n    // (undocumented)\n    rollback(): Promise<void>;\n}\n\n// @beta (undocumented)\nexport interface Route {\n    // (undocumented)\n    readonly caseSensitive?: boolean;\n    // (undocumented)\n    readonly name?: string;\n    // (undocumented)\n    readonly path: string;\n}\n\n// @beta (undocumented)\nexport const Route: Readonly<{\n    path: Readonly<{\n        readonly current: string;\n        generateRoute(relativeTo: HTMLElement | Router, path: string, params?: Object): Promise<string | null>;\n        push(path: string, trigger?: boolean): void;\n        replace(path: string, trigger?: boolean): void;\n        trigger(path: string): void;\n    }>;\n    name: Readonly<{\n        generateRoute(relativeTo: HTMLElement | Router, name: string, params?: Object): Promise<string | null>;\n        push(relativeTo: HTMLElement | Router, name: string, params?: Object, trigger?: boolean): Promise<void>;\n        replace(relativeTo: HTMLElement | Router, name: string, params?: Object, trigger?: boolean): Promise<void>;\n        trigger(relativeTo: HTMLElement | Router, name: string, params?: Object): Promise<void>;\n    }>;\n}>;\n\n// @beta (undocumented)\nexport class RouteCollection<TSettings = any> {\n    constructor(owner: RouterConfiguration);\n    // (undocumented)\n    converter(name: string, converter: ParameterConverter): void;\n    // (undocumented)\n    fallback(definitionOrCallback: FallbackRouteDefinition<TSettings> | DefinitionCallback): void;\n    generateFromName(name: string, params: object): string | null;\n    generateFromPath(path: string, params: object): string | null;\n    // (undocumented)\n    ignore(definitionOrString: IgnorableRouteDefinition<TSettings> | string): void;\n    // (undocumented)\n    map(...routes: MappableRouteDefinition<TSettings>[]): void;\n    // (undocumented)\n    recognize(path: string): Promise<RouteMatch<TSettings> | null>;\n}\n\n// @beta (undocumented)\nexport type RouteMatch<TSettings = any> = {\n    route: RecognizedRoute<TSettings>;\n    command: NavigationCommand;\n};\n\n// @beta (undocumented)\nexport type RouteParameterConverter = (name: string, value: string | undefined, context: RouteParameterConverterContext) => any | Promise<any>;\n\n// @beta (undocumented)\nexport interface RouteParameterConverterContext<TSettings = any> {\n    // (undocumented)\n    readonly endpoint: Endpoint<TSettings>;\n    // (undocumented)\n    readonly params: Readonly<Record<string, string | undefined>>;\n    // (undocumented)\n    readonly queryParams: Record<string, string>;\n    // (undocumented)\n    readonly typedParams: Record<string, any>;\n}\n\n// @beta (undocumented)\nexport type RouteParameterConverterObject = {\n    convert: RouteParameterConverter;\n};\n\n// @beta (undocumented)\nexport interface Router<TSettings = any> {\n    // (undocumented)\n    addContributor(contributor: NavigationContributor): void;\n    // (undocumented)\n    beginRender(route: RecognizedRoute<TSettings>, command: RenderCommand): Promise<RenderOperation>;\n    // (undocumented)\n    config: RouterConfiguration | null;\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n    // (undocumented)\n    readonly level: number;\n    // (undocumented)\n    readonly parent: Router | null;\n    // (undocumented)\n    removeContributor(contributor: NavigationContributor): void;\n    // (undocumented)\n    readonly route: RecognizedRoute | null;\n    // (undocumented)\n    shouldRender(route: RecognizedRoute<TSettings>): boolean;\n}\n\n// @beta (undocumented)\nexport const Router: Readonly<{\n    getOrCreateFor(element: HTMLElement): Router<any>;\n    find(element: HTMLElement): Router | null;\n    from<TBase extends typeof HTMLElement>(BaseType: TBase): {\n        new (): InstanceType<TBase> & RouterElement;\n    };\n}>;\n\n// @beta (undocumented)\nexport abstract class RouterConfiguration<TSettings = any> {\n    // (undocumented)\n    protected cached(ElementType: new () => HTMLElement): () => Promise<HTMLElement>;\n    // (undocumented)\n    protected abstract configure(): Promise<void> | void;\n    // (undocumented)\n    construct<T>(Type: Constructable<T>): T;\n    // (undocumented)\n    readonly contributors: NavigationContributor<TSettings>[];\n    // Warning: (ae-forgotten-export) The symbol \"RoutingEventSink\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    createEventSink(): RoutingEventSink;\n    // (undocumented)\n    createLinkHandler(): LinkHandler;\n    // (undocumented)\n    createNavigationProcess(): NavigationProcess;\n    // (undocumented)\n    createNavigationQueue(): NavigationQueue;\n    // (undocumented)\n    createRouteRecognizer(): RouteRecognizer<TSettings>;\n    // Warning: (ae-forgotten-export) The symbol \"TitleBuilder\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    createTitleBuilder(): TitleBuilder;\n    // (undocumented)\n    defaultLayout: Layout;\n    // (undocumented)\n    defaultTransition: Readonly<Transition>;\n    // (undocumented)\n    findContributors<T extends NavigationPhaseName>(phase: T): Record<T, NavigationPhaseHook<TSettings>>[];\n    generateRouteFromName(name: string, params: object): Promise<string | null>;\n    generateRouteFromPath(path: string, params: object): Promise<string | null>;\n    // (undocumented)\n    parent: RouterConfiguration<TSettings> | null;\n    // (undocumented)\n    recognizeRoute(path: string): Promise<RouteMatch<TSettings> | null>;\n    // (undocumented)\n    readonly routes: RouteCollection<TSettings>;\n    // (undocumented)\n    title: string;\n}\n\n// @beta (undocumented)\nexport interface RouteRecognizer<TSettings> {\n    // (undocumented)\n    add(routeOrRoutes: Route | readonly Route[], settings?: TSettings): void;\n    // (undocumented)\n    generateFromName(name: string, params: object): string | null;\n    // (undocumented)\n    generateFromPath(path: string, params: object): string | null;\n    // (undocumented)\n    recognize(path: string, converters?: Readonly<Record<string, RouteParameterConverter>>): Promise<RecognizedRoute<TSettings> | null>;\n}\n\n// @beta (undocumented)\nexport interface RouterElement extends HTMLElement {\n    // Warning: (ae-forgotten-export) The symbol \"routerProperty\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    readonly [routerProperty]: Router;\n    // (undocumented)\n    config: RouterConfiguration | null;\n    // (undocumented)\n    connectedCallback(): void;\n    // (undocumented)\n    disconnectedCallback(): void;\n}\n\n// @beta (undocumented)\nexport type RouterExecutionContext = ExecutionContext & {\n    router?: Router;\n};\n\n// @beta (undocumented)\nexport interface RouteView {\n    // (undocumented)\n    appendTo(host: HTMLElement): void;\n    // (undocumented)\n    bind(allTypedParams: Readonly<Record<string, any>>): void;\n    // (undocumented)\n    context: RouterExecutionContext;\n    // (undocumented)\n    dispose(): void;\n}\n\n// @beta (undocumented)\nexport type SupportsSettings<TSettings = any> = {\n    settings?: TSettings;\n};\n\n// @beta (undocumented)\nexport type TemplateFallbackRouteDefinition<TSettings = any> = LayoutAndTransitionRouteDefinition & HasTemplate & SupportsSettings<TSettings> & HasTitle;\n\n// @beta (undocumented)\nexport type TemplateRouteDefinition<TSettings = any> = NavigableRouteDefinition<TSettings> & HasTemplate;\n\n// @beta (undocumented)\nexport interface Transition {\n    // (undocumented)\n    begin(host: HTMLElement, prev: RouteView | null, next: RouteView): Promise<void>;\n    // (undocumented)\n    commit(host: HTMLElement, prev: RouteView | null, next: RouteView): Promise<void>;\n    // (undocumented)\n    rollback(host: HTMLElement, prev: RouteView | null, next: RouteView): Promise<void>;\n}\n\n// @beta (undocumented)\nexport const Transition: Readonly<{\n    default: Readonly<Transition>;\n}>;\n\n// (No @packageDocumentation comment for this package)\n\n```\n","packages/fast-test-harness/README.md":"# FAST Test Harness\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nThe `fast-test-harness` package is a Playwright testing harness for FAST Element web components with CSR and SSR support.\n\n## Requirements\n\n- Node.js 22.18 or later\n- Playwright 1.56 or later\n\n## Installation\n\nTo install `fast-test-harness` using `npm`:\n\n```shell\nnpm install --save-dev @microsoft/fast-test-harness\n```\n\n## Test directory setup\n\nThe harness serves a Vite dev server from a `test/` directory in your project. CSR and SSR modes use different entry points from the same directory.\n\n```\ntest/\n├── index.html              # CSR: loads main.ts\n├── ssr.html                # SSR: template with comment placeholders\n├── vite.config.ts          # Vite config (shared by both modes)\n└── src/\n    ├── main.ts             # CSR: registers components, applies theme\n    ├── entry-client.ts     # SSR: registers components for hydration\n    └── entry-server.ts     # SSR: exports render() for fixture generation\n```\n\n## Writing tests\n\nImport `test` and `expect` from the harness. Configure the component tag name with `test.use()`, then call `fastPage.setTemplate()` in each test to render it.\n\n```ts\nimport { expect, test } from \"@microsoft/fast-test-harness\";\n\ntest.describe(\"Button\", () => {\n    test.use({ tagName: \"my-button\", innerHTML: \"Click me\" });\n\n    test(\"should render\", async ({ fastPage }) => {\n        await fastPage.setTemplate();\n        await expect(fastPage.element).toBeVisible();\n    });\n\n    test(\"should accept attributes\", async ({ fastPage }) => {\n        await fastPage.setTemplate({\n            attributes: { appearance: \"primary\", disabled: true },\n        });\n        await expect(fastPage.element).toHaveAttribute(\"appearance\", \"primary\");\n    });\n\n    test(\"should work inside a form\", async ({ fastPage }) => {\n        await fastPage.setTemplate(`\n            <form>\n                <my-button type=\"submit\">Submit</my-button>\n            </form>\n        `);\n        await expect(fastPage.element).toBeVisible();\n    });\n});\n```\n\nUse `updateTemplate()` to modify attributes or innerHTML after the initial render without navigating away from the page:\n\n```ts\nawait fastPage.setTemplate();\nawait fastPage.updateTemplate(fastPage.element, { attributes: { disabled: true } });\n```\n\nThe `toHaveCustomState` assertion checks `ElementInternals` custom states:\n\n```ts\nawait expect(element).toHaveCustomState(\"checked\");\n```\n\n## Fixture options\n\n| Option | Type | Default | Description |\n| -------- | ------ | --------- | ------------- |\n| `base` | `string` | `\"/\"` | Base path for the test page and SSR endpoint |\n| `tagName` | `string` | `\"\"` | Custom element tag name |\n| `innerHTML` | `string` | `\"\"` | Default inner HTML |\n| `waitFor` | `string[]` | `[]` | Additional elements to wait for before testing |\n| `ssr` | `boolean` | `false` | Use SSR mode (or set `PLAYWRIGHT_TEST_SSR=true`) |\n\n### CSR files\n\n**`index.html`** loads a script that registers your components:\n\n```html\n<!doctype html>\n<html lang=\"en\">\n    <head><meta charset=\"UTF-8\" /></head>\n    <body>\n        <script type=\"module\" src=\"/src/main.ts\"></script>\n    </body>\n</html>\n```\n\n**`main.ts`** registers components and applies global config. The body starts empty; `setTemplate()` injects HTML per test.\n\n```ts\nimport \"./define-all.js\";\nimport { setTheme } from \"./theme.js\";\nsetTheme(lightTheme);\n```\n\n### SSR files\n\n**`ssr.html`** contains comment placeholders the server fills in per request:\n\n```html\n<!doctype html>\n<html lang=\"en\">\n    <head>\n        <title><!--fixturetitle--></title>\n        <!--stylespreload-->\n    </head>\n    <body>\n        <!--fixture-->\n        <!--templates-->\n        <script type=\"module\" src=\"/src/entry-client.ts\"></script>\n    </body>\n</html>\n```\n\n**`entry-client.ts`** imports the harness SSR entry (which enables hydration) and registers components. Component definition modules should use `template: declarativeTemplate()`; this automatically defines FAST's internal `<f-template>` publisher.\n\n```ts\nimport \"@microsoft/fast-test-harness/ssr/entry-client.js\";\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n\nimport { MyButton, definition } from \"../../src/button/index.js\";\n\nMyButton.define({\n    name: definition.name,\n    template: declarativeTemplate(),\n});\n```\n\n**`entry-server.ts`** exports a `render()` function that the server calls for each `setTemplate()` request. It returns three strings that get injected into `ssr.html`:\n\n```ts\nexport function render(queryObj: Record<string, string>): {\n    template: string;    // <f-template> HTML → <!--templates-->\n    fixture: string;     // rendered element HTML → <!--fixture-->\n    preloadLinks: string; // <link> tags → <!--stylespreload-->\n};\n```\n\nUse `createSSRRenderer` from the harness to build the `render()` function. It scans for component build artifacts (f-templates, stylesheets) and uses the `@microsoft/fast-build` WASM renderer to produce declarative shadow DOM on each request.\n\n**Multi-component package** (all components in one package):\n\n```ts\nimport { createSSRRenderer } from \"@microsoft/fast-test-harness/ssr/render.js\";\n\nconst { render } = createSSRRenderer({\n    packageName: \"@my-scope/web-components\",\n    tagPrefix: \"my\",\n});\n\nexport { render };\n```\n\n**Per-component packages** (each component is a separate npm package):\n\n```ts\nimport { createSSRRenderer } from \"@microsoft/fast-test-harness/ssr/render.js\";\n\nconst { render } = createSSRRenderer({\n    tagPrefix: \"my\",\n    components: [\n        { name: \"button\", packageName: \"@my-scope/button\" },\n        { name: \"checkbox\", packageName: \"@my-scope/checkbox\" },\n    ],\n});\n\nexport { render };\n```\n\n## Server\n\nThe package includes a Node.js HTTP server with Vite middleware that handles both CSR page serving and SSR fixture generation. Run it directly or let Playwright manage it via `webServer`:\n\n```ts\n// playwright.config.ts\nexport default defineConfig({\n    webServer: {\n        command: \"fast-test-harness\",\n        port: 3278,\n        reuseExistingServer: true,\n    },\n});\n```\n\nFor custom setup, import `startServer`:\n\n```ts\nimport { startServer } from \"@microsoft/fast-test-harness/server.mjs\";\nawait startServer(process.cwd(), \"./test\", \"./test/vite.config.ts\", {\n    port: 4000,\n    debug: true,\n});\n```\n\nOne server can host several test directories at separate paths. Set the matching\n`base` fixture option for each test group.\n\n```ts\nawait startServer(process.cwd(), process.cwd(), \"./vite.config.ts\", {\n    routes: [\n        { base: \"/button/\", root: \"./packages/button/test\" },\n        { base: \"/dialog/\", root: \"./packages/dialog/test\" },\n    ],\n});\n\ntest.use({ base: \"/button/\", tagName: \"my-button\" });\n```\n\n| Parameter | Default | Description |\n| --------- | ------- | ----------- |\n| `cwd` | `process.cwd()` | Static file serving root |\n| `root` | `<cwd>/test` | Vite root (contains `index.html`, `ssr.html`) |\n| `configFile` | Vite auto-discovery | Vite config path |\n| `options.port` | `3278` | Server port |\n| `options.base` | `/` | Base URL path |\n| `options.debug` | `false` | Write SSR fixtures to `temp/` for inspection |\n| `options.routes` | Single route from `root` and `base` | Test roots keyed by URL base path |\n\n### CLI flags\n\n```\nfast-test-harness [command] [options]\n\nCommands:\n  serve                    Start the test harness dev server (default)\n  generate-templates       Generate <f-template> HTML files from compiled templates\n  generate-stylesheets     Generate CSS files from compiled ElementStyles\n  generate-webui-templates Generate WebUI-compatible DSD templates\n\nServe options:\n  -p, --port <number>    Server port (default: 3278)\n  -b, --base <path>      Base URL path (default: /)\n  -r, --root <path>      Vite root directory (default: <cwd>/test)\n  -c, --config <path>    Vite config file path (default: Vite auto-discovery)\n  -d, --debug            Write SSR fixtures to temp/ for inspection\n  -v, --version          Show version number\n  -h, --help             Show help message\n```\n\nCLI flags take precedence over environment variables.\n\n`generate-templates` preserves browser-valid `<template>` wrappers and strips\nstatic wrappers even when the opening or closing tag includes ASCII whitespace\nbefore `>`.\n\n| Environment variable | Default | Description |\n| -------------------- | ------- | ----------- |\n| `PORT` | `3278` | Server port (overridden by `--port`) |\n| `BASE` | `/` | Base URL path (overridden by `--base`) |\n| `FAST_DEBUG` | — | Set `\"true\"` to enable debug mode (overridden by `--debug`) |\n| `PLAYWRIGHT_TEST_SSR` | — | Set `\"true\"` for SSR mode |\n\n## SSR renderer\n\n**`createSSRRenderer(options)`** scans for component build artifacts and returns a `{ render }` object compatible with the server's `entry-server.ts` contract. It uses the `@microsoft/fast-build` WASM module to parse f-templates and render them into declarative shadow DOM, including wrapper tags whose opening or closing `>` is preceded by ASCII whitespace.\n\n| Option | Type | Description |\n| -------- | ------ | ------------- |\n| `tagPrefix` | `string` | Tag name prefix for custom elements (e.g., `\"fluent\"`, `\"contoso\"`) |\n| `packageName` | `string?` | Monolithic package name — scans subdirectories for component artifacts. Mutually exclusive with `components`. |\n| `components` | `ComponentRegistration[]?` | Explicit list of per-component packages. Mutually exclusive with `packageName`. |\n| `distDir` | `string?` | Artifact directory relative to the package root (default: `\"dist/esm\"`). Only used with `packageName`. |\n| `themeStylesheet` | `string?` | URL or package specifier for a global theme stylesheet. |\n\n## Exports\n\n| Specifier | Contents |\n| ----------- | ---------- |\n| `@microsoft/fast-test-harness` | `test`, `expect`, `CSRFixture`, `SSRFixture`, `toHaveCustomState`, `installDomShim`, `createSSRRenderer` |\n| `@microsoft/fast-test-harness/build/*.js` | `installDomShim`, `generateStylesheets`, `generateFTemplates`, `generateWebuiTemplates`, `definitionAsyncResolver`, `shadowOptionsToAttributes`, `ShadowOptionsResolver` |\n| `@microsoft/fast-test-harness/fixtures/*.js` | `CSRFixture`, `SSRFixture`, `toHaveCustomState`, extended `test` and `expect` |\n| `@microsoft/fast-test-harness/ssr/render.js` | `createSSRRenderer`, `renderTemplate`, `buildEntryHtml`, `buildState` |\n| `@microsoft/fast-test-harness/ssr/entry-client.js` | Enables FAST Element hydration for SSR pages |\n| `@microsoft/fast-test-harness/server.mjs` | `startServer` |\n| `@microsoft/fast-test-harness/playwright.config.mjs` | Shared Playwright configuration |\n| `@microsoft/fast-test-harness/vite.config.mjs` | Shared Vite configuration |\n| `@microsoft/fast-test-harness/public/*` | Static assets (base CSS) |\n","sites/website/src/docs/1.x/tools/component-explorer.md":"---\nid: component-explorer\ntitle: Component Explorer\neleventyNavigation:\n  key: component-explorer1x\n  parent: tools1x\n  title: Component Explorer\nnavigationOptions:\n  activeKey: component-explorer1x\ndescription: Launch our Component Explorer to experience our FAST Components and development tools.\nkeywords:\n  - component explorer\nlayout: 1x\n---\n\nLaunch our [Component Explorer](https://explore.fast.design) to experience our [FAST Components](https://www.npmjs.com/package/@microsoft/fast-components) and development tools.","sites/website/src/docs/1.x/tools/hot-module-reload.md":"---\nid: hot-module-reload\ntitle: Hot Module Reload\neleventyNavigation:\n  key: hot-module-reload1x\n  parent: tools1x\n  title: Hot Module Reload\nnavigationOptions:\n  activeKey: hot-module-reload1x\ndescription: Hot Module Replacement (HMR) allows your web components to be updated as you develop, without needing a full refresh of the browser.\nkeywords:\n  - hot module reload\nlayout: 1x\n---\n\nHot Module Replacement (HMR) allows your web components to be updated as you develop, without needing a full refresh of the browser. The [Open Web Components](https://open-wc.org/) project maintains a number of tools and libraries for working with Web Components, including a plugin for enabling HMR with FAST Web Components.\n\nTo learn more about HMR for Web Components and to see how to setup HMR in your own FAST projects, [please see the Open Web Components HMR documentation](https://open-wc.org/docs/development/hot-module-replacement/).\n\n:::note\nHMR is limited in what it can update for a given component. So, full-page refreshes are still needed in certain cases. Changes to constructor logic or adding new `@attr` properties are notable examples of HMR's update limitations. However, template and style changes should be handled automatically without needing a full refresh.\n:::","sites/website/src/docs/1.x/tools/vscode.md":"---\nid: vscode\ntitle: Visual Studio Code\neleventyNavigation:\n  key: vscode1x\n  parent: tools1x\n  title: Visual Studio Code\nnavigationOptions:\n  activeKey: vscode1x\ndescription: You can use any code editor you like when working with FAST. One of our favorites is Visual Studio Code.\nkeywords:\n  - visual studio code\nlayout: 1x\n---\n\nYou can use any code editor you like when working with FAST. One of our favorites is [Visual Studio Code](https://code.visualstudio.com/). VS Code has great support for API autocomplete for TypeScript and JavaScript APIs, as well as a rich ecosystem of plugins.\n\nWhen working with VS Code, we recommend using these plugins:\n\n* [FAST Snippets](https://marketplace.visualstudio.com/items?itemName=kingoftac.fast-snippets) to get commonly used conventions when creating `FAST Components`.\n* [literally-html](https://marketplace.visualstudio.com/items?itemName=webreflection.literally-html) to get syntax highlighting and documentation in your `html` blocks.\n* [es6-string-css](https://marketplace.visualstudio.com/items?itemName=bashmish.es6-string-css) to get syntax highlighting in your `css` blocks.",".cursorrules (fastapi-production-architecture-cursorrules-prompt-file.mdc)":"---\ndescription: \"Cursor rules for FastAPI services with router/service/repository boundaries, typed provider adapters, bulkhead isolation, idempotency, and domain exceptions.\"\nglobs: **/*\nalwaysApply: false\n---\n# FastAPI Production Architecture Rules\n# Principles for production-ready FastAPI services.\n\n## LAYER ARCHITECTURE (Principles A1-A8)\n\nThis codebase follows strict 4-layer architecture: Router → Service → Repository → ORM/HTTP/Storage.\nImports flow downward only. Each layer has hard boundaries you must NOT cross.\n\n### Router rules (app/routers/**)\n- Handlers are THIN: ≤10 lines of executable code per handler\n- Allowed imports: fastapi, app.schemas.*, app.core.deps, app.services.*\n- FORBIDDEN imports: sqlalchemy, httpx, boto3, app.models.*, app.repositories.*\n- Every endpoint declares response_model= for OpenAPI fidelity\n- Every protected/business endpoint requires user_id: str = Depends(get_current_user_id)\n- Public endpoints (health checks, webhooks, callbacks) are exempt from auth\n- Business logic lives in services. Routers parse input, call one service method, return response.\n\nGOOD:\n@router.post(\"/wallet/charge\", response_model=WalletResponse, status_code=201)\nasync def charge(\n    req: ChargeRequest,\n    user_id: str = Depends(get_current_user_id),\n    svc: WalletUserService = Depends(get_wallet_service),\n) -> WalletResponse:\n    wallet = await svc.charge(\n        user_id=user_id,\n        amount=req.amount,\n        idempotency_key=req.idempotency_key,\n    )\n    return WalletResponse.from_domain(wallet)\n\nBAD (business logic + SQL in router):\n@router.post(\"/wallet/charge\")\nasync def charge(req: ChargeRequest, db: Session = Depends(get_db)):\n    wallet = db.query(Wallet).filter(Wallet.user_id == user_id).with_for_update().one()\n    ...\n\n### Service rules (app/services/**)\n- FORBIDDEN imports: sqlalchemy, httpx, boto3, redis, FastAPI Request/Response/HTTPException\n- Constructor injects Protocol-typed dependencies, not concrete classes\n- Raise domain exceptions (InsufficientFundsError), not HTTPException\n\nGOOD:\nfrom app.repositories.protocols import WalletRepoProtocol\nclass WalletUserService:\n    def __init__(self, repo: WalletRepoProtocol):  # Protocol, not SQLAlchemy Session\n        self._repo = repo\n\nBAD:\nfrom sqlalchemy.orm import Session\nclass WalletUserService:\n    def __init__(self, db: Session): ...  # Wrong — service depends on infrastructure\n\n### Repository rules (app/repositories/**)\n- ONLY layer allowed to import sqlalchemy\n- Implements Protocol from app/repositories/protocols.py\n- Returns domain objects, not ORM models\n- Every query scoped by user_id (multi-tenancy)\n\n### Provider rules (app/providers/**)\n- ONLY layer allowed to import httpx directly\n- Returns GenerateResult | ProviderError — NEVER raw dict\n- Uses per-provider httpx.AsyncClient (bulkhead pattern)\n\n## FILE SIZE RULES (Principle A1)\n\n| LOC      | State  | Action                                      |\n|----------|--------|---------------------------------------------|\n| 0–399    | Green  | None.                                       |\n| 400–599  | Yellow | Plan split. Add TODO(decompose) header.     |\n| 600+     | Red    | BLOCK merge. Decompose first.               |\n\nConvert file to package when ANY is true:\n- Crosses 400 LOC and next change pushes past 500\n- Contains 2+ disjoint sub-domains (image vs video, user vs admin)\n- Mixes HTTP handlers with worker handlers\n- Has 2+ callers each importing only one symbol\n\nSafe split pattern (atomic PR):\n1. Create <file>/__init__.py (empty for now)\n2. Move pieces to sub-files (a.py, b.py, c.py)\n3. Re-export old public names from __init__.py\n4. Run tests — must pass without changes\n5. Follow-up PR to migrate callers off legacy alias\n\n__init__.py pattern:\nfrom .user import WalletUserService\nfrom .admin import WalletAdminService\nWalletService = WalletUserService  # backwards-compat alias\n__all__ = [\"WalletUserService\", \"WalletAdminService\", \"WalletService\"]\n\n## EXTERNAL INTEGRATION RULES (Principles B1-B10)\n\n### Rule 1: Anti-Corruption Layer (ACL)\nProviders return GenerateResult | ProviderError, never dict.\n\nfrom dataclasses import dataclass\nfrom decimal import Decimal\n\n@dataclass(frozen=True)\nclass GenerateResult:\n    url: str\n    cost_usd: Decimal\n    latency_ms: int\n    provider_request_id: str\n\nclass ProviderError(Exception):\n    def __init__(self, message: str, *, retryable: bool, code: str | None = None):\n        super().__init__(message); self.retryable = retryable; self.code = code\n\nclass ProviderTimeout(ProviderError):\n    def __init__(self, message: str): super().__init__(message, retryable=True, code=\"timeout\")\n\n### Rule 2: Per-Provider Bulkhead\nEach external provider has its OWN httpx.AsyncClient with its OWN Limits. NEVER share.\n\nGOOD:\nFAL_HTTP = httpx.AsyncClient(\n    base_url=settings.FAL_BASE_URL,\n    timeout=httpx.Timeout(connect=5.0, read=60.0, write=10.0, pool=5.0),\n    limits=httpx.Limits(max_connections=20, max_keepalive_connections=10),\n)\nOPENAI_HTTP = httpx.AsyncClient(\n    base_url=\"https://api.openai.com/v1\",\n    limits=httpx.Limits(max_connections=50, max_keepalive_connections=20),\n)\n\nBAD:\nHTTP = httpx.AsyncClient()  # shared across all providers — no bulkhead isolation\n\n# Shutdown cleanup — close all provider clients in FastAPI lifespan\nfrom contextlib import asynccontextmanager\n\n@asynccontextmanager\nasync def lifespan(app):\n    yield  # app startup\n    await FAL_HTTP.aclose()\n    await OPENAI_HTTP.aclose()\n\napp = FastAPI(lifespan=lifespan)\n# Or on_event(\"shutdown\"):\n# @app.on_event(\"shutdown\")\n# async def close_http_clients() -> None:\n#     await FAL_HTTP.aclose()\n#     await OPENAI_HTTP.aclose()\n\n### Rule 3: Idempotency Keys\nEvery side-effect operation accepts an idempotency_key: UUID. Look up before retrying.\n\n### Rule 4: Structured Logging with contextvars\nUse ContextVar to thread provider, user_id, request_id through async call stacks.\n\nimport contextvars\n\nprovider_var   = contextvars.ContextVar[str | None](\"provider\", default=None)\nuser_id_var    = contextvars.ContextVar[str | None](\"user_id\", default=None)\nrequest_id_var = contextvars.ContextVar[str | None](\"request_id\", default=None)\n\n# Read in logs: provider_var.get(), user_id_var.get(), request_id_var.get()\n# JSON formatter picks these up automatically via extra={} or ContextVar.get()\n\n### Rule 5: Single-Writer Principle (Principle B10)\nFor safety-critical state: exactly ONE service-layer module does the writing.\nOnly the designated writer service for a domain may call repo.hold().\nRouters and providers must NOT call repo.hold() directly.\nAdmin services implemented in the service layer may call repo.hold() only\nif they are the designated writer for that domain.\nEnforce via: code-review grep check (`grep -r \"repo\\.hold(\" --include=\"*.py\"`)\nand unit tests that assert call-origin of repo.hold().\n\n## ANTI-PATTERNS — REJECT ON SIGHT\n\n1. def some_method(self, db: Session, ...) → use Protocol-typed repo\n2. from app.models.user import User inside a service → return domain types from repo\n3. httpx.AsyncClient() instantiated inside a function → use shared per-provider client\n4. raise HTTPException(...) inside a service → raise domain exception\n5. db.query(...) inside a router → move to service then repo\n6. async def call(self, req) -> dict: return resp.json() → ACL violation\n7. HTTP = httpx.AsyncClient() shared → bulkhead violation\n8. result[\"vendor_field\"][\"nested\"] in service code → ACL violation\n9. logger.info(f\"{user_id} did X\") → use structured logging with extra={}\n10. Side-effect operation without idempotency_key → double-charge risk\n\n## DEPENDENCY INJECTION\n\nUse FastAPI Depends() + factory functions in app/core/deps.py.\nDo NOT install dependency-injector, punq, or any DI container.\n\ndef get_wallet_service(db: Session = Depends(get_db)) -> WalletUserService:\n    return WalletUserService(repo=SQLAlchemyWalletRepo(db))\n\n## DOMAIN EXCEPTIONS PATTERN\n\nServices raise domain errors. Routers map to HTTP.\n\n# services/wallet/exceptions.py\nclass InsufficientFundsError(Exception): ...\nclass WalletNotFoundError(Exception): ...\n\n# routers/wallet.py\ntry:\n    wallet = await svc.charge(...)\nexcept InsufficientFundsError:\n    raise HTTPException(402, detail=\"insufficient funds\")\n"},"items":[{"name":"copilot-instructions.md","path":".github/copilot-instructions.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/.github/copilot-instructions.md","title":"FAST Instructions","category":"copilot-instructions","format":"markdown","content":"---\nname: FAST Instructions\ndescription: This file describes the general instructions for working with the FAST monorepo, including repository structure, code style, tooling, and contribution guidelines.\napplyTo: '**/*'\n---\n\n# Instructions for FAST\n\n## General\n\n- **Explicit instruction only**: Do not take any action unless explicitly instructed. Wait for clear direction before making changes, running commands, or modifying files.\n\n## Repository Overview\n\nFAST (`@microsoft/fast`) is a Microsoft open-source monorepo for building W3C-standards-compliant Web Components. The core package is `@microsoft/fast-element` — a lightweight, performant Web Component authoring library with a declarative HTML entrypoint. Additional packages provide routing plus declarative build and test tooling.\n\n## Packages\n\nEach package includes a DESIGN.md file, read that to gain a general understanding of the code for that package.\n\n| Package | Status | Purpose |\n|---|---|---|\n| `@microsoft/fast-element` | Stable (v2) | Core Web Component library, including declarative HTML via `@microsoft/fast-element/declarative.js` |\n| `@microsoft/fast-router` | Alpha | Web Component router |\n| `@microsoft/fast-build` | Prerelease | Declarative HTML server side renderer |\n| `@microsoft/fast-test-harness` | Prerelease | Testing utilities for FASTElement components |\n\n### Sites\n\n| Package | Status | Purpose |\n|---|---|---|\n| `sites/website` | Private (not published as a package) | Documentation website source |\n| `sites/benchmarks` | Private (not published as a package) | Benchmarking site |\n\n### Example projects\n\n- `examples/design-system/` — Shared semantic design tokens (`@microsoft/fast-examples-design-system`) consumed by all example apps.\n- `examples/csr/todo-app/` — A simple To-Do app demonstrating FAST usage patterns and using the shared `@microsoft/fast-examples-design-system` tokens.\n- `examples/csr/todo-mobx-app/` — A To-Do app demonstrating how to integrate MobX state with `@microsoft/fast-element` using a single `autorun` per component (no custom bridge code).\n- `examples/ssr/chat-app/` — A declarative FAST chat demo that pre-renders with `@microsoft/fast-build` and streams canned assistant replies into the transcript. Dark theme.\n- `examples/ssr/webui-todo-app/` — A To-Do app demonstrating FAST declarative HTML with `@microsoft/webui` prerendering and `@microsoft/fast-element/declarative.js` hydration. Light theme.\n\n## Skills\n\nThese contain domain-specific guidance. Read when performing related tasks:\n\n- [TypeScript](./skills/typescript/SKILL.md) — compiler constraints, import/export conventions, decorator usage, testing patterns.\n- [Rust](./skills/rust/SKILL.md) — general guidance on performing updates between the crate and package.\n- [Shipping](./skills/shipping/SKILL.md) — pull request format, change file generation, documentation updates.\n- [Pull Request](./skills/fast-pull-request/SKILL.md) — generate a pull request description from the branch diff.\n- [Bug Report](./skills/fast-bug-report/SKILL.md) — generate a bug report issue from conversation context.\n- [Feature Request](./skills/fast-feature-request/SKILL.md) — generate a feature request issue from conversation context.\n- [Testing](./skills/testing/SKILL.md) — running tests locally and in CI, writing Playwright fixture tests.\n- [Documentation](./skills/documentation/SKILL.md) — adding documentation in code, markdown files in each package/crate, and the website.\n\n## Commands\n\nRun all commands from the monorepo root. Use workspace flags to target a single package.\n\n| Task | Command |\n|---|---|\n| Install | `npm ci` |\n| Build all | `npm run build` |\n| Build one package | `npm run build -w @microsoft/fast-element` |\n| Test all | `npm run test` |\n| Test one package | `npm run test -w @microsoft/fast-element` |\n| Test Chromium only | `npm run test:chromium` |\n| Build/test changed only | `lage build --since origin/main` |\n| Test changed only | `lage test:node test:chromium --since origin/main` |\n| Lint | `npm run lint` |\n| Lint fix | `npm run lint:fix` |\n| Format check | `npm run format:check` |\n| Format fix | `npm run format` |\n| Check (lint + format + imports) | `npm run biome:check` |\n| Check fix | `npm run biome:fix` |\n| CI check (read-only) | `npm run biome:ci` |\n| Generate change file | `npm run change` |\n| Check change files | `npm run checkchange` |\n| API docs | `npm run doc -w @microsoft/fast-element` |\n\nBuild and test commands use [Lage](https://microsoft.github.io/lage/) for dependency-aware task execution. Lage respects the package dependency graph and can run incrementally with `--since <ref>` to only build/test changed packages and their dependents. The CI pipelines use `--since` for pull requests to skip unchanged packages.\n\nAll `lint`, `biome:check`, `biome:fix`, and `biome:ci` commands use `biome-changed`, which runs biome only on files with uncommitted git changes. The `format:check` and `format` commands use biome's own `--changed` flag to compare against the default branch.\n\n## Project Structure\n\n```\npackages/<package>/\n  src/                    # Source code\n    index.ts              # Main barrel (re-exports)\n    <feature>/            # Feature directories\n      <feature>.ts        # Implementation\n      <feature>.pw.spec.ts # Co-located Playwright test\n  test/                   # Test harness (Vite dev server, fixtures)\n  dist/                   # Build output (ESM + declarations)\n  docs/                   # API reports (api-extractor)\n  DESIGN.md               # Code documentation for the package or crate\n  README.md               # README for published package use\n```\n\n- Source files use **kebab-case**: `element-controller.ts`, `update-queue.ts`.\n- Playwright test files use `*.pw.spec.ts` suffix, co-located next to the source they test.\n- Node test files use `*.spec.ts` suffix.\n\n## Code Style\n\n### Formatting & Linting (Biome)\n\n- 90-character print width, 4-space indent, double quotes, trailing commas.\n- Single-arg arrow functions omit parens: `x => x + 1`.\n- Import ordering enforced via `organizeImports`.\n- No `I` prefix on interfaces.\n- `any` is permitted (`noExplicitAny: off`).\n- Config: [`biome.jsonc`](../biome.jsonc).\n\n### Naming Conventions\n\n| Element | Convention | Examples |\n|---|---|---|\n| Classes | PascalCase | `ElementController`, `FASTElementDefinition` |\n| Interfaces/Types | PascalCase, no `I` prefix | `Accessor`, `Disposable`, `Expression` |\n| Methods/functions | camelCase | `getValue()`, `handleChange()` |\n| Constants | PascalCase frozen objects or camelCase | `SourceLifetime`, `emptyArray` |\n| Private fields | `_` prefix | `_template`, `_shadowRootOptions` |\n| Files | kebab-case | `element-controller.ts`, `observer-map.ts` |\n| Change callbacks | `${prop}Changed` | `childChanged()`, `templateChanged()` |\n\n### TypeScript\n\nKey constraints (details in [TypeScript skill](./skills/typescript/SKILL.md)):\n\n- ESM only (`\"type\": \"module\"`) — imports use `.js` extensions.\n- `import type { ... }` required for type-only imports (`verbatimModuleSyntax`).\n- Named exports only — no default exports.\n- Legacy decorators enabled (`experimentalDecorators: true`).\n- `strictNullChecks` and `noImplicitAny` enabled.\n\n## Tooling\n\n| Tool | Purpose |\n|---|---|\n| npm workspaces | Package management |\n| Lage | Task runner — dependency-aware builds and incremental testing |\n| TypeScript | Compilation |\n| Rollup | Bundling (`fast-element` only) |\n| Playwright | Testing |\n| Vite | Test dev server |\n| api-extractor | API documentation + `.d.ts` rollup |\n| beachball | Change files, versioning, publishing |\n| Biome | Formatting + Linting |\n| lefthook | Pre-commit hooks (runs `biome:check` and `checkchange` on staged files) |\n| Rust | Rendering Declarative templates (`fast-build` package and `microsoft-fast-build` crate only) |\n\n## Acceptance Checklist\n\nBefore finishing any change, run these commands from the monorepo root and confirm they pass:\n\n- [ ] `npm run build` — all packages build successfully\n- [ ] `npm run test` — all tests pass\n- [ ] `npm run biome:check` — Biome linting and formatting pass\n- [ ] `npm run checkchange` — beachball change files exist for any `packages/*` changes\n\nRead the [shipping skill](./skills/shipping/SKILL.md) and ensure you have updated everything outlined in that file.\n","frontmatter":{"name":"FAST Instructions","description":"This file describes the general instructions for working with the FAST monorepo, including repository structure, code style, tooling, and contribution guidelines.","applyTo":"**/*"},"isInternal":false,"tokens":2004,"sizeBytes":8328},{"name":"SKILL.md","path":".github/skills/documentation/SKILL.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/.github/skills/documentation/SKILL.md","title":"documentation","category":"anthropic-skill","format":"markdown","content":"---\nname: documentation\ndescription: Add documentation for contributors and developers.\n---\n\nDocumentation exists in 3 forms, code comments, design/architectural documentation that is made up of markdown files describing code flow and core concepts (such as DESIGN.md), and the documentation website.\n\nDesign/architectural documentation such as DESIGN.md should always be kept up-to-date.\n\nThe website captures the documentation primarily for the `@microsoft/fast-element` package. Other packages are treated as tangential, so testing packages or other utilities should have their own sections.\n\nThe website has been written in 11ty and primarily consists of markdown files. When making changes, ensure that the website has been scanned on whichever latest major version is available. These are organized by folder, so if 1.x/2.x/3.x folders are available, you will update the documentation in the 3.x folder.\n\nIf you are making a breaking change, ensure the migration document has been updated.\n\nAll markdown documentation aside from the package/crate level DESIGN.md files are in that package/crates docs folder.\n\nAny documentation created for the website should be written with the developer implementing the package in mind, it is not intended for other audiences.\n","frontmatter":{"name":"documentation","description":"Add documentation for contributors and developers."},"isInternal":false,"tokens":240,"sizeBytes":1269},{"name":"SKILL.md","path":".github/skills/fast-bug-report/SKILL.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/.github/skills/fast-bug-report/SKILL.md","title":"fast-bug-report","category":"anthropic-skill","format":"markdown","content":"---\nname: fast-bug-report\ndescription: Generate a bug report issue for the FAST repository using the provided template.\n---\nThis prompt only applies to generating Bug Report issues for the FAST repository.\n\nDo not create or modify any existing Github issues. This skill is only for\ngenerating the markdown content for a new issue based on the provided template.\n\nBased on the conversation context, generate a bug report as a markdown code\nblock using the template located at\n[../../ISSUE_TEMPLATE/bug-report.md](../../ISSUE_TEMPLATE/bug-report.md).\n\nThe summary should clearly state what the bug is and which part of the system\nis affected.\n\nRepro or Code Sample should provide clear, minimal steps to reproduce the issue.\nInclude a code snippet, repository link, or gist if possible.\n\nExpected Behavior should describe what the correct behavior should be.\n\nCurrent Behavior should explain what actually happens instead. Include the full\nerror message and stack trace if applicable. Mention screenshots if they would\nhelp illustrate the problem.\n\nPossible Solution is optional. Include it only if there is a concrete idea about\nthe cause or fix. Mention if the reporter is willing to contribute a fix.\n\nContext should explain how the bug affects the user and what they are trying to\naccomplish. This helps prioritize and design the right solution.\n\nYour Environment should capture relevant details: OS, device, browser, and\npackage version.\n\nSearch for existing open or closed issues that overlap with this bug report.\nIf duplicates or related issues exist, mention them in the Context section.\n\nSuggest a concise issue title in the format `fix: [what is the issue?] in [where is the issue?]`.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nAny comments in the template can be removed since they're only meant to provide\nguidance on how to fill out the template, and are not intended to be part of the\nfinal issue body.\n","frontmatter":{"name":"fast-bug-report","description":"Generate a bug report issue for the FAST repository using the provided template."},"isInternal":false,"tokens":389,"sizeBytes":1963},{"name":"SKILL.md","path":".github/skills/fast-feature-request/SKILL.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/.github/skills/fast-feature-request/SKILL.md","title":"fast-feature-request","category":"anthropic-skill","format":"markdown","content":"---\nname: fast-feature-request\ndescription: Generate a feature request issue for the FAST repository using the provided template.\n---\nThis prompt only applies to generating Feature Request issues for the FAST repository.\n\nDo not create or modify any existing Github issues. This skill is only for\ngenerating the markdown content for a new issue based on the provided template.\n\nBased on the conversation context, generate a feature request as a markdown code\nblock using the template located at\n[../../ISSUE_TEMPLATE/feature-request.md](../../ISSUE_TEMPLATE/feature-request.md).\n\nThe summary should clearly state what the feature is and why it matters, focusing\non user value rather than implementation details.\n\nExpected Behavior should describe how the feature would work from an end-user or\ndeveloper perspective. Be specific about the desired outcome.\n\nCurrent Behavior should explain the gap — what exists today and how the absence of\nthis feature affects users. If there is a workaround, mention it briefly.\n\nPossible Solution is optional. Include it only if there is a concrete implementation\nidea worth capturing. Prefer high-level direction over prescriptive code.\n\nContext should explain the motivation — what the user is trying to accomplish\nand why this feature would help. Mention alternatives that were considered, if any.\n\nExamples is optional. Include it when code snippets, screenshots, or usage\nscenarios would clarify the request.\n\nSearch for existing open or closed issues that overlap with this feature request.\nIf duplicates or related issues exist, mention them in the Context section.\n\nSuggest a concise issue title in the format `feat: add [what] to/in [where]`.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nAny comments in the template can be removed since they're only meant to provide\nguidance on how to fill out the template, and are not intended to be part of the\nfinal issue body.\n","frontmatter":{"name":"fast-feature-request","description":"Generate a feature request issue for the FAST repository using the provided template."},"isInternal":false,"tokens":374,"sizeBytes":1961},{"name":"SKILL.md","path":".github/skills/fast-pull-request/SKILL.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/.github/skills/fast-pull-request/SKILL.md","title":"fast-pull-request","category":"anthropic-skill","format":"markdown","content":"---\nname: fast-pull-request\ndescription: Generate a pull request description for the FAST repository using the provided template.\n---\nThis skill only applies to generating Pull Request descriptions for the FAST repository.\n\nDo not create or modify any existing Github pull requests. This skill is only for\ngenerating the markdown content for a pull request description based on the provided template.\n\nBased on the conversation context, generate a pull request description as a markdown code\nblock using the template located at\n[../../pull_request_template.md](../../pull_request_template.md).\n\nUse the Pull Request Template to generate a markdown code block for the most\nrelevant work on this git branch, compared to `main`.\n\nThe Description should be either a summary description of the content of the branch,\nor a list of the most relevant changes made in the branch. The goal is to address\nthe purpose of the pull request in a concise manner, rather than detailing every change. \"Why\"\nand \"what\" over \"how\".\n\nDetermine if any current github issues are being addressed by this work, and\nlist them in the Issues section with links. If none are found, remove the Issues section.\n\nThe reviewer notes section is optional. Include it only if there are specific\nareas where you would like feedback or attention from the reviewer.\n\nThe Test Plan section should outline any issues that need to be verified before merging,\nor steps to reproduce the behavior locally. Even a brief note is helpful, such as \"All existing tests pass\".\n\nThe checklist section should be completed to indicate the status of various\naspects of the pull request.\n\nIf there are change files that have been added to the PR, check the box labeled \"I have included a change request file using `$ npm run change`\".\n\nIf any new tests have been added, check the box labeled \"I have added tests for my changes.\"\n\nCheck the terminal output for evidence of passing tests, and check the box labeled \"I have tested my changes.\" if tests have been run and are passing. If not, leave the box unchecked.\n\nIf any doc blocks have been added or modified, or if any documentation files have been added or modified, check the box labeled \"I have updated the project documentation to reflect my changes.\" This also applies to any changes made to api-report files.\n\nThe final checkbox must be checked by the pull request author. It should never be checked when generating this PR description.\n\nThe Next Steps section is optional. Include it only if there are specific follow-up tasks\nor work items that should be addressed after merging this PR, such as updating documentation, adding new tests, or performing code cleanup. If any existing issues are being addressed by the next steps, reference them here.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nAny comments in the template can be removed since they're only meant to provide\nguidance on how to fill out the template, and are not intended to be part of the\nfinal PR description.\n","frontmatter":{"name":"fast-pull-request","description":"Generate a pull request description for the FAST repository using the provided template."},"isInternal":false,"tokens":596,"sizeBytes":3027},{"name":"SKILL.md","path":".github/skills/rust/SKILL.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/.github/skills/rust/SKILL.md","title":"rust","category":"anthropic-skill","format":"markdown","content":"---\ndescription: Use this guide when working on Rust changes in the FAST monorepo.\nname: rust\n---\n\n# Working with the Rust crate and the Rust NodeJS CLI\n\nThe primary location for the Rust logic should exist within a crate. If the logic is made accessible in the NodeJS environment via wrapping the crate and using a wasm bindgen, as much as possible any logic that exists in Rust should not be duplicated in JavaScript/TypeScript.\n\n## Breaking changes\n\nUnderstand [semver](https://semver.org/) and check the crate and package version. If the version is currently in a prerelease state, update the APIs with breaking changes as necessary and ensure that any generated pull request descriptions capture this.\n","frontmatter":{"description":"Use this guide when working on Rust changes in the FAST monorepo.","name":"rust"},"isInternal":false,"tokens":145,"sizeBytes":707},{"name":"SKILL.md","path":".github/skills/shipping/SKILL.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/.github/skills/shipping/SKILL.md","title":"shipping","category":"anthropic-skill","format":"markdown","content":"---\ndescription: Use this skill when contributing changes to the FAST monorepo — creating pull requests, generating change files, writing PR descriptions, and keeping documentation up to date.\nname: shipping\n---\n\n# Shipping Patterns for FAST\n\nUse this guide when shipping changes in the FAST monorepo — writing PR descriptions, generating change files, and keeping documentation up to date.\n\n# Guardrails\n\nDo NOT perform any of the following actions autonomously. These require explicit human action:\n\n- **Do not merge or close pull requests** — no `gh pr merge`, `gh pr close`, or equivalent.\n- **Do not publish packages** — no `npm publish`, `beachball publish`, or release operations.\n- **Do not modify branch protection or repository settings**.\n\n## Key references\n\nRead these documents for additional context when needed:\n\n- [`.github/pull_request_template.md`](../../pull_request_template.md) — PR description template (source of truth for PR structure).\n- [`CONTRIBUTING.md`](../../../CONTRIBUTING.md) — Full contributor guide (machine setup, branching, governance).\n- [`BRANCH_GUIDE.md`](../../../BRANCH_GUIDE.md) — Branch management conventions.\n- [`beachball.config.js`](../../../beachball.config.js) — Beachball configuration (ignored patterns, publish settings).\n- [`CODE_OF_CONDUCT.md`](../../../CODE_OF_CONDUCT.md) — Community standards.\n\n### Package/Crate references\n\nRead these documents, they are located at the root of the specific package or crate, e.g. `packages/<package>/<file>.md` and relate to the package/crates they are located in. When making changes in the package/crate afterwards update these files if necessary.\n\n- `DESIGN.md` - Explains the code patterns.\n- `README.md` - Explains how a developer/agent would use this package/crate.\n\n# Commit and PR title conventions\n\nUse [conventional commit](https://www.conventionalcommits.org/) format for PR titles and merge commit messages:\n\n```\n<type>: <short summary>\n```\n\nCommon types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`.\n\nExamples:\n- `feat: add shadow DOM support to declarative templates`\n- `fix: resolve memory leak in template binding`\n- `chore: update dev dependencies`\n\n# Pull requests\n\nUse the repository's PR template at [`.github/pull_request_template.md`](../../pull_request_template.md) as the basis for all pull request descriptions.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nThe comments in the template can be removed since they're only meant to provide guidance on how to fill out the template, and are not intended to be part of the final PR description.\n\nFill out each section as detailed below.\n\n## Description\n\nThe Description should be either a summary description of the content of the branch,\nor a list of the most relevant changes made in the branch. The goal is to address\nthe purpose of the pull request in a concise manner, rather than detailing every change. \"Why\"\nand \"what\" over \"how\".\n\n## Issues\n\nDetermine if any current github issues are being addressed by this work, and\nlist them in the Issues section with links. If none are found, remove the Issues section.\n\n## Reviewer Notes\n\nThe reviewer notes section is optional. Include it only if there are specific\nareas where you would like feedback or attention from the reviewer.\n\n## Test Plan\n\nThe Test Plan section should outline any issues that need to be verified before merging,\nor steps to reproduce the behavior locally. Even a brief note is helpful, such as \"All existing tests pass\".\n\n## Checklist\n\nThe checklist section should be completed to indicate the status of various\naspects of the pull request.\n\nIf there are change files that have been added to the PR, check the box labeled \"I have included a change request file using `$ npm run change`\".\n\nIf any new tests have been added, check the box labeled \"I have added tests for my changes.\"\n\nCheck the terminal output for evidence of passing tests, and check the box labeled \"I have tested my changes.\" if tests have been run and are passing. If not, leave the box unchecked.\n\nIf any doc blocks have been added or modified, or if any documentation files have been added or modified, check the box labeled \"I have updated the project documentation to reflect my changes.\" This also applies to any changes made to api-report files.\n\nThe final checkbox must be checked by the pull request author. It should never be checked when generating this PR description.\n\n## Next Steps\n\nThe Next Steps section is optional. Include it only if there are specific follow-up tasks\nor work items that should be addressed after merging this PR, such as updating documentation, adding new tests, or performing code cleanup. If any existing issues are being addressed by the next steps, reference them here.\n\n# Acceptance checklist\n\nBefore making a change, if the change is addressing a bug make sure you write a test first and ensure that it is failing:\n\n```bash\nnpm run build            # all packages build successfully\nnpm run test             # test fails\n```\n\nBefore finishing any change, run these commands from the monorepo root and confirm they pass:\n\n```bash\nnpm run build            # all packages build successfully\nnpm run test             # all tests pass\nnpm run format:check     # Prettier formatting is correct\nnpm run checkchange      # Beachball change files exist for packages/* changes\n```\n\n# Change files\n\nAfter completing a change to any package under `packages/`, generate a Beachball change file:\n\n```bash\n# This should be run from the monorepo root\nnpm run change\n```\n\nThis walks through the steps to create a change description file that is required for versioning and publishing. The CI gate `npm run checkchange` will fail if a change file is missing for a modified package.\n\n## Change comments\n\nWrite the `comment` field as release-note text, not as a commit message. Use a\nconcise sentence that starts with a capital letter and ends with a period. Do not\nprefix comments with conventional commit types such as `fix:`, `feat:`, or\n`chore:`.\n\nBeachball uses change-file comments to generate package changelogs and release\nnotes. Sentence-style comments read cleanly in those user-facing outputs, while\ncommit-style prefixes duplicate the separate change type metadata and add noise.\n\n## Change types\n\nWhen prompted, select the appropriate change type:\n\n| Type | When to use |\n|---|---|\n| `major` | Breaking changes to public API |\n| `minor` | New features, non-breaking additions |\n| `patch` | Bug fixes, minor corrections |\n| `none` | Changes that don't affect the published package (tests, docs, tooling) |\n\n## When change files are NOT required\n\nThe Beachball config ([`beachball.config.js`](../../../beachball.config.js)) ignores these paths — changes limited to them do not need change files:\n\n- `.github/` — CI configs, templates, skills\n- Test files (`src/e2e/`, `src/tests/`, `src/fixtures/`)\n- `package-lock.json`\n- `.vscode/`, `.prettierrc`\n\nAdditionally, [`build/scripts/checkchange.mjs`](../../../build/scripts/checkchange.mjs) (which wraps `beachball check` for the `checkchange` npm script) skips the check entirely on **manual version bump** branches authored by a repo admin. Specifically, both of the following must be true for the current run:\n\n1. Branch name matches `^publish_\\d+$` (beachball's documented publish-branch convention).\n2. The actor (`$GITHUB_ACTOR` in CI; locally, the user from `gh api user`) has the `admin` role on `microsoft/fast`, verified via the GitHub REST API.\n\nIf either condition fails, the change-file requirement applies as before. See [`CONTRIBUTING.md` > Manual version bumps](../../../CONTRIBUTING.md#manual-version-bumps) for the full rationale and reviewer expectations.\n\n## Cross-branch targeting\n\nWhen working across feature branches, target the branch explicitly:\n\n```bash\nnpm run change -- --branch origin/{branch-name}\n```\n\n## Multiple unrelated changes\n\nIf addressing multiple unrelated issues, prefer separate pull requests.\n\n# Breaking changes\n\nWhen introducing breaking changes:\n\n1. Select `major` as the change type when running `npm run change`.\n2. Document the migration strategy in `packages/<package>/docs/migration/<migration-name>.md`.\n\nFormat for a migration document:\n\n```md\n# Migrating from previous versions\n\n## v1 to v2\n\n- Export `Foo` has been renamed to `Bar`.\n- `Bat` has been updated to use the new API [`BatConfig`](link/to/api).\n```\n\nIf the breaking change is significant or requires multiple PRs, open a [discussion](https://github.com/microsoft/fast/discussions) first.\n\n# Documentation\n\nAfter any changes ensure that the documentation is up to date, this includes the files DESIGN.md and README.md files for any packages/crates that have been modified. If your changes update or add to the public API, update the sites/website/src/docs/ files. Only update the latest version, these are denoted by major versions in their folder names inside the docs folder, 1.x, 2.x, etc., find the latest version of the docs and modify them if necessary.\n\nWhen adding or modifying exported APIs, run the website prebuild script to regenerate API documentation from the api-extractor output:\n\n```bash\nnpm run prebuild -w sites/website\n```\n\nThis runs [`sites/website/scripts/generate-docs.cjs`](../../../sites/website/scripts/generate-docs.cjs), which copies API documentation from each package's extracted API reports into the website source. Run this after building packages to ensure generated documentation stays in sync with the codebase.\n","frontmatter":{"description":"Use this skill when contributing changes to the FAST monorepo — creating pull requests, generating change files, writing PR descriptions, and keeping documentation up to date.","name":"shipping"},"isInternal":false,"tokens":2065,"sizeBytes":9530},{"name":"SKILL.md","path":".github/skills/testing/SKILL.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/.github/skills/testing/SKILL.md","title":"testing","category":"anthropic-skill","format":"markdown","content":"---\nname: testing\ndescription: Use this skill when running or writing tests in the FAST monorepo — local test execution, CI workflows, Playwright fixtures, and WebUI integration testing.\n---\n\n# Testing Patterns for FAST\n\nUse this guide when running or writing tests in the FAST monorepo. FAST uses [Playwright](https://playwright.dev/) for integration testing with a [Vite](https://vitejs.dev/) dev server.\n\n## Running tests\n\n### Locally\n\n#### First-time setup\n\nAfter cloning and installing dependencies (`npm ci`), install Playwright browsers:\n\n```bash\nnpx playwright install --with-deps\n```\n\n#### Commands\n\nAll commands are run from the **monorepo root**. Use `-w` to target a specific package.\n\n| Task | Command |\n|---|---|\n| Run all tests (all browsers) | `npm run test` |\n| Run all tests (Chromium only) | `npm run test:chromium` |\n| Test a single package (all browsers) | `npm run test -w @microsoft/fast-element` |\n| Test a single package (Chromium only) | `npm run test:chromium -w @microsoft/fast-element` |\n| Test changed packages only | `npx lage test:node test:chromium --since origin/main` |\n\n#### Interactive / debug workflows\n\nFor FAST declarative tests in `@microsoft/fast-element`, these additional scripts are available:\n\n| Task | Command |\n|---|---|\n| Playwright UI mode | `npm run test:ui:declarative -w @microsoft/fast-element` |\n| Start declarative source server | `npm run test-server:declarative -w @microsoft/fast-element` |\n| Rebuild fixtures | `npm run build:fixtures -w @microsoft/fast-element` |\n| Build fixtures with webui | `npm run build:fixtures:webui -w @microsoft/fast-element` |\n| Run webui integration tests | `npm run test:webui-integration -w @microsoft/fast-element` |\n\n**Playwright UI mode** (`test:ui`) starts a visual test runner where you can select and debug individual tests, view traces, and inspect DOM snapshots.\n\n**Declarative browser workflows** resolve `@microsoft/fast-element` package imports directly to `src` and let Vite transpile TypeScript on demand. Vite does not type-check these modules; the package build remains responsible for type checking, while `test:exports` imports every emitted package export.\n\n### Through GitHub Actions\n\nThe repository uses several CI workflows to validate changes.\n\n#### PR validation (ci-validate-pr.yml)\n\nRuns on every pull request targeting `main`, `releases/*`, or `features/*` branches. Tests run on **Ubuntu with Chromium only** for fast feedback.\n\nKey steps:\n- Checks for change files (`npm run checkchange`)\n- Biome lint/format check\n- Builds affected packages (incremental with `--since`)\n- Runs `test:node` and `test:chromium` for affected packages\n\n#### Cross-platform validation (ci-validate-platforms.yml)\n\nRuns on pushes to `main`, PRs targeting `main`, and on a weekly schedule. Tests run on **Ubuntu, Windows, and macOS** with **Chromium, Firefox, and Safari**.\n\nThis ensures cross-platform and cross-browser compatibility.\n\n#### WebUI integration testing (ci-webui-integration.yml)\n\nA dedicated workflow for validating FAST's integration with `@microsoft/webui`. This workflow runs on:\n\n- **Manual dispatch** (`workflow_dispatch`)\n- **Pushes to `webui/*` branches**\n\n> **Note:** This workflow does _not_ run on regular pull requests. It is scoped to `webui/*` branches to test integration changes in isolation before they land on `main`.\n\nThe workflow builds all packages, installs Playwright Chromium, and runs:\n\n```bash\nnpm run test:webui-integration -w @microsoft/fast-element\n```\n\nThis builds each fixture with `webui build --plugin=fast`, renders the protocol with the fixture's `state.json`, and runs the same Playwright specs against the webui-rendered output.\n\nTo trigger WebUI integration tests for your changes:\n\n1. Create a branch with the `webui/` prefix (e.g., `webui/my-integration-change`).\n2. Push the branch — the workflow runs automatically.\n3. Alternatively, trigger the workflow manually from the Actions tab using `workflow_dispatch`.\n\n#### Azure Pipelines (azure-pipelines-ci.yml)\n\nThe repository also has an Azure DevOps pipeline that runs on PRs to `main`. This pipeline runs in a 1ES-managed environment and includes SDL compliance checks in addition to building and testing.\n\n## Writing tests\n\nFAST tests are [Playwright](https://playwright.dev/) integration tests that run against fixture pages served by Vite.\n\n### Test file conventions\n\n- Test files use the `*.spec.ts` suffix (specifically `*.pw.spec.ts` for package `src/` tests).\n- Tests for developer-authored declarative markup and directives live in the matching\n  `test/declarative/fixtures/<category>/<feature>/<feature>.spec.ts` fixture.\n- Tests for implementation APIs and lifecycle behavior are co-located with their source as\n  `src/<feature>/<feature>.pw.spec.ts`.\n\n### Writing declarative fixture tests\n\nFixture tests in `@microsoft/fast-element/test/declarative/fixtures` are the primary way to verify declarative template features. Each fixture is a self-contained test case with its own HTML, state, templates, and component definitions.\n\nWhen changing declarative syntax, directive parsing, template generation, hydration behavior, or other user-authored template behavior, add or update a declarative fixture and exercise it in browser. Source-level parser tests may supplement narrow parsing edge cases, but they should not be the only coverage for syntax that users write in `entry.html` or `templates.html`. Use the local README files under `packages/fast-element/test/declarative/fixtures/` and each fixture category to choose the right fixture type and follow category-specific examples.\n\nFor a complete guide on creating fixtures — including how to write `entry.html`, `state.json`, `templates.html`, `main.ts`, and spec files — see:\n\n📄 **[Writing Fixtures](../../../packages/fast-element/test/declarative/fixtures/WRITING_FIXTURES.md)**\n\n### Quick example\n\n```typescript\nimport { expect, test } from \"@playwright/test\";\n\ntest.describe(\"my-feature\", async () => {\n    test(\"renders correctly\", async ({ page }) => {\n        await page.goto(\"/fixtures/bindings/my-feature/\");\n\n        const element = page.locator(\"my-element\");\n        await expect(element).toHaveText(\"Hello\");\n    });\n});\n```\n","frontmatter":{"name":"testing","description":"Use this skill when running or writing tests in the FAST monorepo — local test execution, CI workflows, Playwright fixtures, and WebUI integration testing."},"isInternal":false,"tokens":1403,"sizeBytes":6219},{"name":"SKILL.md","path":".github/skills/typescript/SKILL.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/.github/skills/typescript/SKILL.md","title":"typescript","category":"anthropic-skill","format":"markdown","content":"---\ndescription: Use this guide when working on TypeScript changes in the FAST monorepo — authoring Web Components, writing templates and styles, working with the observable/reactive system, and testing.\nname: typescript\n---\n\n# TypeScript Patterns for FAST\n\n## Modules\n\n`fast-element` enables `verbatimModuleSyntax`, so type-only imports must use `import type`\nor the inline `type` qualifier:\n\n```ts\nimport type { Notifier, Subscriber } from \"./notifier.js\";\nimport { type Constructable, isFunction } from \"../interfaces.js\";\n```\n\nSub-entry-points expose focused APIs through the `exports` map:\n\n```ts\nimport { twoWay } from \"@microsoft/fast-element/two-way.js\";\nimport { reactive } from \"@microsoft/fast-element/state.js\";\n```\n\nThe barrel `index.ts` explicitly lists every re-export grouped by subsystem — no\n`export *` statements.\n\nAside from the `index.ts` or `index.*.ts` files there should be no barrel exports.\n\n## Side Effects\n\nDo not add side effectful code and do not add `sideEffects` to `package.json` files.\nAPIs added should import named exports.\n\n## Browser APIs\n\n### Do not use\n\nOur stance as a framework library is that certain browser APIs are best avoided by\nthe framework. We may facilitate the use of them through our provided APIs.\n\nList of APIs to avoid implementing in FAST packages:\n- `requestIdleCallback`\n- `setTimeout`\n- `setInterval`\n\n### Avoid\n\nSome browser APIs can be used but should be avoided as a developer may encounter\nedge cases with task queuing or other logic their app is executing.\n\nList of APIs to avoid in FAST packages:\n- `requestAnimationFrame`\n- `queueMicrotask`\n\n## Custom elements\n\nElements extend `FASTElement`. Do **not** use the `@customElement` decorator.\n\nUse `define()` for registration. `define()` returns a `Promise` that resolves\nimmediately when a template is provided:\n\nExample define.ts (side-effect import):\n```ts\nexport class MyElement extends FASTElement {\n    @observable items: string[] = [];\n}\n\nawait MyElement.define({\n    name: \"my-element\",\n    template,\n    styles,\n});\n```\n\n## Templates\n\nTemplates use the `html` tagged template literal typed to the element class:\n\n```ts\nimport { html } from \"@microsoft/fast-element/html.js\";\nimport { repeat } from \"@microsoft/fast-element/repeat.js\";\nimport { when } from \"@microsoft/fast-element/when.js\";\nimport type { MyElement } from \"./my-element.js\";\n\nexport const template = html<MyElement>`\n    <h1>${x => x.title}</h1>\n    ${when(x => x.showList, html<MyElement>`\n        <ul>\n            ${repeat(\n                x => x.items,\n                html<string>`<li>${x => x}</li>`\n            )}\n        </ul>\n    `)}\n`;\n```\n\n### Binding syntax\n\n| Prefix | Purpose | Example |\n|---|---|---|\n| `${x => ...}` | Content or attribute | `${x => x.name}` |\n| `@event` | Event listener | `@click=${x => x.handleClick()}` |\n| `@event` | Event with context | `@click=${(x, c) => c.parent.remove(x)}` |\n| `:prop` | DOM property | `:value=${twoWay(x => x.description)}` |\n| `?attr` | Boolean attribute | `?disabled=${x => !x.isValid}` |\n\nTwo-way bindings require a sub-entry-point import:\n\n```ts\nimport { twoWay } from \"@microsoft/fast-element/two-way.js\";\n```\n\n### Partial HTML\n\nUse `html.partial()` to inject pre-built HTML strings into a template without creating\na full `ViewTemplate`:\n\n```ts\nhtml<MyElement>`\n    <div>${html.partial(\"<span>static markup</span>\")}</div>\n`;\n```\n\n## Styles\n\nStyles use the `css` tagged template literal. They attach through the element definition's\n`styles` property:\n\n```ts\nimport { css } from \"@microsoft/fast-element/css.js\";\n\nexport const styles = css`\n    :host {\n        display: block;\n        padding: 16px;\n    }\n`;\n```\n\nFor declarative HTML definitions, styles live in a separate `.styles.css` file linked from\nboth the initial shadow root template and the `<f-template>`:\n\n```html\n<f-template name=\"my-element\">\n    <template>\n        <link rel=\"stylesheet\" href=\"./my-element.styles.css\">\n    </template>\n</f-template>\n```\n\n`css.partial()` works the same way as `html.partial()` — injecting raw CSS strings.\n\n## Reactivity\n\n`@attr` maps HTML attributes to properties. `@observable` creates reactive properties\ntracked by templates. `@volatile` marks getters whose dependencies change between calls:\n\n```ts\nimport { FASTElement } from \"@microsoft/fast-element/fast-element.js\";\nimport { attr, nullableNumberConverter } from \"@microsoft/fast-element/attr.js\";\nimport { Observable, observable } from \"@microsoft/fast-element/observable.js\";\nimport { volatile } from \"@microsoft/fast-element/volatile.js\";\n\nclass MyElement extends FASTElement {\n    @attr label?: string;\n    @attr({ mode: \"boolean\" }) active?: boolean;\n    @attr({ converter: nullableNumberConverter }) count?: number;\n\n    @observable private _items: string[] = [];\n\n    // Convention: ${propertyName}Changed\n    labelChanged(prev: string | undefined, next: string | undefined) {}\n\n    @volatile\n    get sortedItems(): readonly string[] {\n        return [...this._items].sort();\n    }\n}\n```\n\nNotify the system after in-place mutations that it cannot detect automatically:\n\n```ts\nthis._items.splice(index, 1);\nObservable.notify(this, \"_items\");\n```\n\nMake plain objects observable via the state sub-entry-point:\n\n```ts\nimport { reactive } from \"@microsoft/fast-element/state.js\";\nconst todo = reactive({ description: \"Buy milk\", done: false });\n```\n\n## Testing\n\nTests use Playwright Test (`*.pw.spec.ts`) and combine two patterns within the same file.\n\n### Direct-import tests\n\nFor logic that does not need browser APIs — the test callback takes no parameters:\n\n```ts\nimport { expect, test } from \"@playwright/test\";\nimport { Observable } from \"./observable.js\";\n\ntest.describe(\"Observable\", () => {\n    test(\"can get a notifier\", () => {\n        const notifier = Observable.getNotifier(new Model());\n        expect(notifier).toBeInstanceOf(PropertyChangeNotifier);\n    });\n});\n```\n\n### Browser-evaluated tests\n\nFor tests requiring DOM APIs, navigate to the Vite dev server and import via\n`\"/main.js\"`. The `@ts-expect-error` comment is required because TypeScript cannot\nresolve the URL-based import:\n\n```ts\ntest(\"renders element\", async ({ page }) => {\n    await page.goto(\"/\");\n\n    const result = await page.evaluate(async () => {\n        // @ts-expect-error: Client module.\n        const { FASTElement, html, uniqueElementName } = await import(\"/main.js\");\n        // ... test logic ...\n        return someSerializableValue;\n    });\n\n    expect(result).toBe(expected);\n});\n```\n\nOnly serializable values can cross the `page.evaluate` boundary — run `expect()`\nassertions outside it on the returned data.\n\nThe test harness at `packages/<package>/test/main.ts` re-exports source modules for\nbrowser tests. When adding new package exports, add them there too.\n\n## TypeScript idioms\n\n### Const-type merging for enumerations\n\nFrozen const objects paired with a type extracted from their values replace TypeScript\n`enum`:\n\n```ts\nexport const SourceLifetime = {\n    default: undefined,\n    couple: 1,\n} as const;\n\nexport type SourceLifetime =\n    (typeof SourceLifetime)[keyof typeof SourceLifetime];\n```\n\n### Interface-const merging\n\n`FASTElement` is both an interface (instance shape) and a const (constructor). Static\nmethods use `typeof` to carry overloaded signatures:\n\n```ts\nexport const FASTElement: {\n    new (): FASTElement;\n    define: typeof define;\n} = Object.assign(createFASTElement(HTMLElement), { define });\n```\n\n### Tagged template intersection types\n\n`html` and `css` are typed as intersections of a tagged template function and a\n`.partial()` method:\n\n```ts\ntype HTMLTemplateTag = (<TSource, TParent>(\n    strings: TemplateStringsArray,\n    ...values: TemplateValue<TSource, TParent>[]\n) => ViewTemplate<TSource, TParent>) & {\n    partial(html: string): InlineTemplateDirective;\n};\n```\n","frontmatter":{"description":"Use this guide when working on TypeScript changes in the FAST monorepo — authoring Web Components, writing templates and styles, working with the observable/reactive system, and testing.","name":"typescript"},"isInternal":false,"tokens":1806,"sizeBytes":7825},{"name":"plugin-integrations.md","path":"packages/fast-build/docs/migration/plugin-integrations.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-build/docs/migration/plugin-integrations.md","title":"Migration Skill","category":"anthropic-skill","format":"markdown","content":"# Migrating plugin integration pipelines\n\n## Structured errors\n\nWASM failures now throw JavaScript `Error` objects rather than strings. Read\n`error.message` for the previous human-readable text; `String(error)` now has the\nstandard `Error: ` prefix. Replace message matching with stable `error.code`\nchecks. Both WASM declaration modules export a `FastBuildError` interface extending\n`Error`; it is a type only, not an exported constructor.\n\nOptional `line`/`column` are one-based UTF-16 coordinates, and `length` is a UTF-16\nerror-token highlight length. CRLF is one break; lone CR/LF also break lines.\nEntry and conversion coordinates refer to the complete supplied HTML. A named\ncustom-element render failure instead refers to its separately supplied `content`.\nUse `templateName` to select that source, rather than attaching its coordinates\nto the entry or to a full file from which `content` was extracted. Older metadata\ndoes not carry enough provenance to reconstruct those full-file positions.\nDo not fabricate HTML locations when these fields are absent (JSON/options,\nmissing sources, filesystem errors, or separate CSS).\n\nNative Rust `RenderError` and `ConvertError` expose `code()`, `location()` returning\nan optional `ErrorLocation`, `template_name()`, and `kind()`. Source-annotated\nvalidation errors may use the new `Located` variant; match `error.kind()` to\ninspect the underlying variant. Context fields now use boxed `ErrorContext`\ninstead of `String`; use `context.to_string()` to read the unchanged snippet and\n`String::into()` when constructing a context without source provenance.\nUpdate exhaustive enum matches for `Located`. These are intentional pre-1.0\nnative API changes. Successful rendering/conversion, warnings, missing-state\nbehavior, and permissive `parse_f_templates` parsing are unchanged.\n\n## Attribute output changes\n\nMissing and explicit `null` bindings now omit the entire attribute, including\nmixed literal/binding values. To intentionally keep `href=\"\"`, provide `\"\"`\ninstead of null. JSON booleans on known HTML boolean attributes use presence:\nfalse omits `disabled`, true emits it. ARIA/ordinary attribute booleans remain\ntextual. Use FAST's `?name` syntax for matching client-side truthy/falsy behavior.\nAuthor bindings resolving to absence suppress matching template-host defaults.\nRemove wrapper regular expressions that strip empty values: they would erase\nintentional empty strings. Hydration slot counts remain unchanged.\n\n## Typed converter output\n\nThe default output remains unchanged. Opt into `typed: true` (or `--typed`)\nfor explicit `ElementViewTemplate<TSource>` / `ElementStyles` annotations and\ntype-only imports, then remove wrapper string replacements. Supply\n`type_source`/`--type-source` when strict source-property checking is required.\nRust `ConvertOptions` struct literals must include the new `typed` field or\nuse `..ConvertOptions::default()`.\nThe pre-1.0 native error enums also gain integration-related variants; update\nexhaustive `RenderError` / `ConvertError` matches accordingly.\n\n## Caller-owned host markup\n\nReplace throwaway-host rendering and substring extraction with\n`render_shadow_root` (WASM) or `render_shadow_root_*_with_locator` (Rust).\nPass resolved component state and insert the returned complete DSD `<template>`\ninto the host you own. The fragment does not include host/default attributes\nor light-DOM children.\n\n## Persisted template metadata\n\n`parse_f_templates` keeps its JSON array shape and existing fields, adding\nper-record `formatVersion: 1` and `bindings`. Preserve these fields when\npersisting or constructing a keyed map. Unsupported/malformed explicit versions\nnow fail before rendering. Unversioned legacy maps remain supported, but cannot\nreceive stale-version protection. Regenerate metadata on format changes rather\nthan rewriting a version number onto incompatible data.\n\nBindings describe names, expression kinds, paths, and repeat scopes. Unknown\ntypes and state optionality are explicitly null, not inferred declarations.\nRepeat collections alone have a known array requirement. Complex/client\nreferences are lexical descriptions; metadata is not a full state schema or\nsyntax-validation certificate. Use application declarations for definitive\ntype/requiredness checks.\n\nEach newly parsed binding now includes an authored `span` with half-open `start`\nand `end` positions in the complete input string. Offsets are zero-based UTF-16;\nlines and UTF-16 columns are one-based. Use the original input, not the returned\ntrimmed `content`, when slicing or attaching diagnostics. The range covers the\ntrimmed expression without braces; repeat bindings locate only the iterable.\nCRLF counts as one line break and two offset units; lone CR and LF each count\nas a line break. Raw attribute entities are not decoded.\n\nFormat version 1 is unchanged, and renderers still accept older records without\nspans. Regenerate persisted metadata to obtain authored locations; preserve spans\nwhen mapping or serializing records. Native `BindingMetadata` struct literals\nmust now supply the public `span: SourceSpan` field; prefer `parse_f_templates`\nto constructing descriptive metadata manually. Generated WASM declarations expose\n`TemplateSourceSpan` and `TemplateSourcePosition`.\n","isInternal":false,"tokens":1088,"sizeBytes":5268},{"name":"ACKNOWLEDGEMENTS.md","path":"packages/fast-element/docs/ACKNOWLEDGEMENTS.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/ACKNOWLEDGEMENTS.md","title":"Docs Skill","category":"anthropic-skill","format":"markdown","content":"# Acknowledgements\n\nThere are many great open source projects that have inspired us and enabled us to build FAST. Below are a few that stand out.\n\n* [.NET](https://dotnet.microsoft.com/) - Many thanks to the .NET team for sharing their policies and practices upon which our issue management and release planning docs and practices were based.\n* [asap](https://github.com/kriskowal/asap) - An awesome, time-tested async task queue implementation that heavily inspired our DOM update system.\n* [Aurelia 1 and Aurelia 2](https://aurelia.io/) - Various details of Aurelia 2's decorator and metadata model inspired us in the design of `fast-element`. Additionally, Aurelia 1's mechanisms for array observation, binding, and template compilation also guided us in our work.\n* [faastjs](https://github.com/faastjs) - A project with a similar name but a very different purpose. Their API documentation approach leveraging [api-extractor](https://api-extractor.com/) was a huge help to us.\n* [Knockout](https://knockoutjs.com/) - One of the first JavaScript libraries (if not the first) to implement an observer system. The original techniques for observables and computed observables have influenced many libraries over the years. Re-interpreting these ideas in terms of modern JavaScript and DOM has helped us to build a powerful and robust system.\n* [lit-html](https://lit-html.polymer-project.org/) - One of the first libraries to leverage standard JavaScript tagged template literals for HTML templates. We were inspired by this technique and wanted to explore whether it could be combined with our idea of arrow function binding expressions.\n* [Polymer](https://www.polymer-project.org/) - One of the first libraries (if not the first) to embrace Web Components.\n* [Vue](https://vuejs.org/) - We liked the terseness of the `:` and `@` syntax in templates, so we adapted it along with some modifications in our templates.\n","isInternal":false,"tokens":423,"sizeBytes":1918},{"name":"api-report.api.md","path":"packages/fast-element/docs/api-report.api.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/api-report.api.md","title":"Docs Skill","category":"anthropic-skill","format":"markdown","content":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport interface AccessCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"access\";\n}\n\n// @public\nexport interface Accessor {\n    getValue(source: any): any;\n    name: string;\n    setValue(source: any, value: any): void;\n}\n\n// @public\nexport type AddViewBehaviorFactory = (factory: ViewBehaviorFactory) => string;\n\n// @public\nexport interface ArrayObserver extends SubscriberSet {\n    addSort(sort: Sort): void;\n    addSplice(splice: Splice): void;\n    flush(): void;\n    readonly lengthObserver: LengthObserver;\n    reset(oldCollection: any[] | undefined): void;\n    readonly sortObserver: SortObserver;\n    strategy: SpliceStrategy | null;\n}\n\n// @public\nexport const ArrayObserver: Readonly<{\n    readonly sorted: 0;\n    readonly enable: () => void;\n}>;\n\n// @public\nexport interface Aspected {\n    aspectType: DOMAspect;\n    dataBinding?: Binding;\n    sourceAspect: string;\n    targetAspect: string;\n}\n\n// @public\nexport function attr(config?: DecoratorAttributeConfiguration): (target: {}, property: string) => void;\n\n// @public\nexport function attr(target: {}, prop: string): void;\n\n// @public\nexport type AttributeConfiguration = {\n    property: string;\n    attribute?: string;\n    mode?: AttributeMode;\n    converter?: ValueConverter;\n};\n\n// @public\nexport const AttributeConfiguration: Readonly<{\n    locate: (target: {}) => AttributeConfiguration[];\n}>;\n\n// @public\nexport class AttributeDefinition implements Accessor {\n    constructor(Owner: Function, name: string, attribute?: string, mode?: AttributeMode, converter?: ValueConverter);\n    readonly attribute: string;\n    // @internal\n    static collect(Owner: Function, ...attributeLists: (ReadonlyArray<string | AttributeConfiguration> | undefined)[]): ReadonlyArray<AttributeDefinition>;\n    readonly converter?: ValueConverter;\n    getValue(source: HTMLElement): any;\n    readonly mode: AttributeMode;\n    readonly name: string;\n    // @internal (undocumented)\n    onAttributeChangedCallback(element: HTMLElement, value: any): void;\n    readonly Owner: Function;\n    setValue(source: HTMLElement, newValue: any): void;\n}\n\n// @public\nexport type AttributeMode = \"reflect\" | \"boolean\" | \"fromView\";\n\n// @public\nexport abstract class Binding<TSource = any, TReturn = any, TParent = any> {\n    constructor(evaluate: Expression<TSource, TReturn, TParent>, policy?: DOMPolicy, isVolatile?: boolean);\n    abstract createObserver(subscriber: Subscriber, directive: BindingDirective): ExpressionObserver<TSource, TReturn, TParent>;\n    evaluate: Expression<TSource, TReturn, TParent>;\n    isVolatile: boolean;\n    options?: any;\n    policy?: DOMPolicy;\n}\n\n// @public\nexport interface BindingDirective {\n    readonly aspectType?: DOMAspect;\n    readonly dataBinding: Binding;\n    readonly targetAspect?: string;\n}\n\n// @public\nexport const booleanConverter: ValueConverter;\n\n// @public\nexport type CachedPath = DefaultCachedPath | RepeatCachedPath | AccessCachedPath | EventCachedPath;\n\n// @public\nexport interface CachedPathCommon {\n    // (undocumented)\n    currentContext: string | null;\n    // (undocumented)\n    parentContext: string | null;\n    // (undocumented)\n    path: string;\n}\n\n// @public\nexport type CachedPathMap = Map<string, Map<string, JSONSchema>>;\n\n// @public\nexport type Callable = typeof Function.prototype.call | {\n    call(): void;\n};\n\n// @public\nexport interface CaptureType<TSource = any, TParent = any> {\n}\n\n// @public\nexport interface ChildListDirectiveOptions<T = any> extends NodeBehaviorOptions<T>, Omit<MutationObserverInit, \"subtree\" | \"childList\"> {\n}\n\n// @public\nexport function children<TSource = any, TParent = any>(propertyOrOptions: (keyof TSource & string) | ChildrenDirectiveOptions<keyof TSource & string>): CaptureType<TSource, TParent>;\n\n// @public\nexport class ChildrenDirective extends NodeObservationDirective<ChildrenDirectiveOptions> {\n    constructor(options: ChildrenDirectiveOptions);\n    disconnect(target: any): void;\n    getNodes(target: Element): Node[];\n    observe(target: any): void;\n}\n\n// @public\nexport type ChildrenDirectiveOptions<T = any> = ChildListDirectiveOptions<T> | SubtreeDirectiveOptions<T>;\n\n// @public\nexport interface ChildrenMap {\n    // (undocumented)\n    attributeName: string;\n    // (undocumented)\n    customElementName: string;\n}\n\n// @public\nexport type Class<T, C = {}> = C & Constructable<T> & {\n    readonly prototype: T;\n};\n\n// @public\nexport type CompilationStrategy = (\nhtml: string | HTMLTemplateElement,\nfactories: Record<string, ViewBehaviorFactory>,\npolicy: DOMPolicy) => HTMLTemplateCompilationResult;\n\n// @public\nexport type CompiledViewBehaviorFactory = Required<ViewBehaviorFactory>;\n\n// @public\nexport const Compiler: {\n    compile<TSource = any, TParent = any>(html: string | HTMLTemplateElement, factories: Record<string, ViewBehaviorFactory>, policy?: DOMPolicy): HTMLTemplateCompilationResult<TSource, TParent>;\n    setDefaultStrategy(strategy: CompilationStrategy): void;\n    aggregate(parts: (string | ViewBehaviorFactory)[], policy?: DOMPolicy): ViewBehaviorFactory;\n};\n\n// @public\nexport type ComposableStyles = string | ElementStyles | CSSStyleSheet;\n\n// @public\nexport function composedContains(reference: HTMLElement, test: HTMLElement): boolean;\n\n// @public\nexport function composedParent<T extends HTMLElement>(element: T): HTMLElement | null;\n\n// @beta\nexport type ComputedBuilder = {\n    on: {\n        setup(callback: ComputedSetupCallback): void;\n    };\n};\n\n// @beta\nexport type ComputedInitializer<T> = (builder: ComputedBuilder) => () => T;\n\n// @beta\nexport type ComputedSetupCallback = () => (() => void) | void;\n\n// @beta\nexport type ComputedState<T> = ReadonlyState<T> & Disposable & {\n    subscribe(subscriber: Subscriber): void;\n    unsubscribe(subscriber: Subscriber): void;\n};\n\n// @beta\nexport function computedState<T>(initialize: ComputedInitializer<T>, name?: string): ComputedState<T>;\n\n// @public\nexport type Constructable<T = {}> = {\n    new (...args: any[]): T;\n};\n\n// @public\nexport type ConstructibleStyleStrategy = {\n    new (styles: (string | CSSStyleSheet)[]): StyleStrategy;\n};\n\n// @public\nexport interface ContentTemplate {\n    create(): ContentView;\n}\n\n// @public\nexport interface ContentView {\n    bind(source: any, context?: ExecutionContext): void;\n    // (undocumented)\n    readonly context: ExecutionContext;\n    insertBefore(node: Node): void;\n    remove(): void;\n    unbind(): void;\n}\n\n// @public\nexport const css: CSSTemplateTag;\n\n// @public\nexport interface CSSDirective {\n    createCSS(): ComposableStyles;\n}\n\n// @public\nexport const CSSDirective: Readonly<{\n    getForInstance: (object: any) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    getByType: (key: Function) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    define<TType extends Constructable<CSSDirective>>(type: any): TType;\n}>;\n\n// @public\nexport function cssDirective(): (type: Constructable<CSSDirective>) => void;\n\n// @public\nexport interface CSSDirectiveDefinition<TType extends Constructable<CSSDirective> = Constructable<CSSDirective>> {\n    readonly type: TType;\n}\n\n// @public\nexport type CSSTemplateTag = ((strings: TemplateStringsArray, ...values: CSSValue[]) => ElementStyles) & {\n    partial(strings: TemplateStringsArray, ...values: CSSValue[]): CSSDirective;\n};\n\n// @public\nexport type CSSValue = ComposableStyles | CSSDirective;\n\n// @public\nexport function customElement(nameOrDef: string | PartialFASTElementDefinition): (type: Constructable<HTMLElement>) => void;\n\n// @public\nexport type DecoratorAttributeConfiguration = Omit<AttributeConfiguration, \"property\">;\n\n// @public\nexport interface DefaultCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"default\";\n}\n\n// @public\nexport class DefaultExecutionContext<TParent> implements ExecutionContext<TParent> {\n    get event(): Event;\n    eventDetail<TDetail>(): TDetail;\n    eventTarget<TTarget extends EventTarget>(): TTarget;\n    index: number;\n    get isEven(): boolean;\n    get isFirst(): boolean;\n    get isInMiddle(): boolean;\n    get isLast(): boolean;\n    get isOdd(): boolean;\n    length: number;\n    readonly parent: TParent;\n    readonly parentContext: ExecutionContext<TParent>;\n}\n\n// @public\nexport interface Disposable {\n    dispose(): void;\n}\n\n// @public\nexport const DOM: Readonly<{\n    readonly policy: DOMPolicy;\n    setPolicy(value: DOMPolicy): void;\n    setAttribute(element: HTMLElement, attributeName: string, value: any): void;\n    setBooleanAttribute(element: HTMLElement, attributeName: string, value: boolean): void;\n}>;\n\n// @public\nexport const DOMAspect: Readonly<{\n    readonly none: 0;\n    readonly attribute: 1;\n    readonly booleanAttribute: 2;\n    readonly property: 3;\n    readonly content: 4;\n    readonly tokenList: 5;\n    readonly event: 6;\n}>;\n\n// @public\nexport type DOMAspect = (typeof DOMAspect)[Exclude<keyof typeof DOMAspect, \"none\">];\n\n// @public\nexport type DOMAspectGuards = {\n    [DOMAspect.attribute]?: DOMSinkGuards;\n    [DOMAspect.booleanAttribute]?: DOMSinkGuards;\n    [DOMAspect.property]?: DOMSinkGuards;\n    [DOMAspect.content]?: DOMSinkGuards;\n    [DOMAspect.tokenList]?: DOMSinkGuards;\n    [DOMAspect.event]?: DOMSinkGuards;\n};\n\n// @public\nexport type DOMElementGuards = Record<string, DOMAspectGuards>;\n\n// @public\nexport type DOMGuards = {\n    elements: DOMElementGuards;\n    aspects: DOMAspectGuards;\n};\n\n// @public\nexport interface DOMPolicy {\n    createHTML(value: string): string;\n    protect(tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink): DOMSink;\n}\n\n// @public\nexport const DOMPolicy: Readonly<{\n    create(options?: DOMPolicyOptions): Readonly<DOMPolicy>;\n}>;\n\n// @public\nexport type DOMPolicyOptions = {\n    trustedType?: TrustedTypesPolicy;\n    guards?: Partial<DOMGuards>;\n};\n\n// @public\nexport type DOMSink = (target: Node, aspectName: string, value: any, ...args: any[]) => void;\n\n// @public\nexport type DOMSinkGuards = Record<string, (tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink) => DOMSink>;\n\n// @public\nexport class ElementController<TElement extends HTMLElement = HTMLElement> implements Notifier, HostController<TElement> {\n    // @internal\n    constructor(element: TElement, definition: FASTElementDefinition);\n    addBehavior(behavior: HostBehavior<TElement>): void;\n    addStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    protected behaviors: Map<HostBehavior<TElement>, number> | null;\n    protected bindObservables(): void;\n    protected captureBoundObservables(): void;\n    connect(): void;\n    protected connectBehaviors(): void;\n    get context(): ExecutionContext;\n    readonly definition: FASTElementDefinition;\n    disconnect(): void;\n    protected disconnectBehaviors(): void;\n    emit(type: string, detail?: any, options?: Omit<CustomEventInit, \"detail\">): void | boolean;\n    static forCustomElement(element: HTMLElement, override?: boolean): ElementController;\n    protected hasExistingShadowRoot: boolean;\n    // @internal\n    static installHydrationHook(hook: (controller: ElementController, template: ElementViewTemplate, element: HTMLElement, host: Node) => boolean): void;\n    get isBound(): boolean;\n    get isConnected(): boolean;\n    readonly isHydrated: Promise<boolean>;\n    readonly isPrerendered: Promise<boolean>;\n    get mainStyles(): ElementStyles | null;\n    set mainStyles(value: ElementStyles | null);\n    protected needsInitialization: boolean;\n    notify(args: any): void;\n    protected observeLateAttributes(): void;\n    onAttributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;\n    onUnbind(behavior: {\n        unbind(controller: ExpressionController<TElement>): any;\n    }): void;\n    removeBehavior(behavior: HostBehavior<TElement>, force?: boolean): void;\n    removeStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    protected renderTemplate(template: ElementViewTemplate | null | undefined): void;\n    static setStrategy(strategy: ElementControllerStrategy): void;\n    get shadowOptions(): ShadowRootOptions | undefined;\n    set shadowOptions(value: ShadowRootOptions | undefined);\n    readonly source: TElement;\n    get sourceLifetime(): SourceLifetime | undefined;\n    protected stage: Stages;\n    get subject(): TElement;\n    subscribe(subscriber: Subscriber, propertyToWatch?: any): void;\n    protected syncLateAttributes(): void;\n    get template(): ElementViewTemplate<TElement> | null;\n    set template(value: ElementViewTemplate<TElement> | null);\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: any): void;\n    readonly view: ElementView<TElement> | null;\n}\n\n// @public\nexport interface ElementControllerStrategy {\n    // (undocumented)\n    new (element: HTMLElement, definition: FASTElementDefinition): ElementController;\n}\n\n// @public\nexport const elements: (selector?: string) => ElementsFilter;\n\n// @public\nexport type ElementsFilter = (value: Node, index?: number, array?: Node[]) => boolean;\n\n// @public\nexport class ElementStyles {\n    constructor(styles: ReadonlyArray<ComposableStyles>);\n    // @internal (undocumented)\n    addStylesTo(target: StyleTarget): void;\n    // @internal (undocumented)\n    isAttachedTo(target: StyleTarget): boolean;\n    static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;\n    // @internal (undocumented)\n    removeStylesFrom(target: StyleTarget): void;\n    static setDefaultStrategy(Strategy: ConstructibleStyleStrategy): void;\n    get strategy(): StyleStrategy;\n    // (undocumented)\n    readonly styles: ReadonlyArray<ComposableStyles>;\n    static readonly supportsAdoptedStyleSheets: boolean;\n    withStrategy(Strategy: ConstructibleStyleStrategy): this;\n}\n\n// @public\nexport interface ElementView<TSource = any, TParent = any> extends View<TSource, TParent> {\n    appendTo(node: Node): void;\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): any;\n    }): void;\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface ElementViewTemplate<TSource = any, TParent = any> {\n    create(hostBindingTarget: Element): ElementView<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): ElementView<TSource, TParent>;\n}\n\n// @public\nexport const emptyArray: readonly never[];\n\n// @public\nexport function enableDebug(): void;\n\n// @public\nexport interface EventCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"event\";\n}\n\n// @public\nexport interface ExecutionContext<TParent = any> {\n    readonly event: Event;\n    eventDetail<TDetail>(): TDetail;\n    eventTarget<TTarget extends EventTarget>(): TTarget;\n    index: number;\n    readonly isEven: boolean;\n    readonly isFirst: boolean;\n    readonly isInMiddle: boolean;\n    readonly isLast: boolean;\n    readonly isOdd: boolean;\n    length: number;\n    parent: TParent;\n    parentContext: ExecutionContext<TParent>;\n}\n\n// @public\nexport const ExecutionContext: Readonly<{\n    default: ExecutionContext;\n    getEvent(): Event | null;\n    setEvent(event: Event | null): void;\n}>;\n\n// @public\nexport type Expression<TSource = any, TReturn = any, TParent = any> = (source: TSource, context: ExecutionContext<TParent>) => TReturn;\n\n// @public\nexport interface ExpressionController<TSource = any, TParent = any> {\n    readonly context: ExecutionContext<TParent>;\n    readonly isBound: boolean;\n    onUnbind(behavior: {\n        unbind(controller: ExpressionController<TSource, TParent>): any;\n    }): void;\n    readonly source: TSource;\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface ExpressionNotifier<TSource = any, TReturn = any, TParent = any> extends Notifier, ExpressionObserver<TSource, TReturn, TParent>, Disposable {\n    observe(source: TSource, context?: ExecutionContext): TReturn;\n    records(): IterableIterator<ObservationRecord>;\n    setMode(isAsync: boolean): void;\n}\n\n// @public\nexport interface ExpressionObserver<TSource = any, TReturn = any, TParent = any> {\n    bind(controller: ExpressionController<TSource, TParent>): TReturn;\n}\n\n// @public\nexport const FAST: {\n    warn(_code: number, _values?: Record<string, any>): void;\n    error(code: number, _values?: Record<string, any>): Error;\n    addMessages(messages: Record<number, string>): void;\n};\n\n// @public\nexport interface FASTElement extends HTMLElement {\n    $emit(type: string, detail?: any, options?: Omit<CustomEventInit, \"detail\">): boolean | void;\n    readonly $fastController: ElementController;\n    attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;\n    connectedCallback(): void;\n    disconnectedCallback(): void;\n}\n\n// @public\nexport const FASTElement: FASTElementConstructor;\n\n// @public\nexport interface FASTElementConstructor {\n    new (): FASTElement;\n    define<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(this: TType, nameOrDef: string | PartialFASTElementDefinition<TType>, extensions?: FASTElementExtension[]): Promise<TType>;\n    define<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition<TType>, extensions?: FASTElementExtension[]): Promise<TType>;\n    from<TBase extends typeof HTMLElement>(BaseType: TBase): {\n        new (): InstanceType<TBase> & FASTElement;\n    };\n}\n\n// @public\nexport class FASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributeLookup: Record<string, AttributeDefinition>;\n    readonly attributes: ReadonlyArray<AttributeDefinition>;\n    static compose<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition<TType>): Promise<FASTElementDefinition<TType>>;\n    define(registry?: CustomElementRegistry, extensions?: FASTElementExtension[]): this;\n    readonly elementOptions: ElementDefinitionOptions;\n    static readonly getByType: (key: Function) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    static readonly getForInstance: (object: any) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    get isDefined(): boolean;\n    readonly name: string;\n    readonly propertyLookup: Record<string, AttributeDefinition>;\n    // @internal\n    static registerBaseType(type: Function): void;\n    readonly registry: CustomElementRegistry;\n    schema?: Schema;\n    shadowOptions?: ShadowRootOptions;\n    readonly styles?: ElementStyles;\n    template?: ElementViewTemplate<InstanceType<TType>>;\n    readonly type: TType;\n}\n\n// @public\nexport type FASTElementExtension = (definition: FASTElementDefinition) => void;\n\n// @public\nexport interface FASTElementRegistry extends TypeRegistry<FASTElementDefinition> {\n    whenRegistered(name: string, registry?: CustomElementRegistry): Promise<FASTElementDefinition>;\n}\n\n// @public\nexport const fastElementRegistry: FASTElementRegistry;\n\n// @public\nexport type FASTElementTemplateResolver<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> = (definition: FASTElementDefinition<TType>) => ElementViewTemplate<InstanceType<TType>> | Promise<ElementViewTemplate<InstanceType<TType>>>;\n\n// @public\nexport interface HostBehavior<TSource = any> {\n    addedCallback?(controller: HostController<TSource>): void;\n    connectedCallback?(controller: HostController<TSource>): void;\n    disconnectedCallback?(controller: HostController<TSource>): void;\n    removedCallback?(controller: HostController<TSource>): void;\n}\n\n// @public\nexport interface HostController<TSource = any> extends ExpressionController<TSource> {\n    addBehavior(behavior: HostBehavior<TSource>): void;\n    addStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    readonly isConnected: boolean;\n    mainStyles: ElementStyles | null;\n    removeBehavior(behavior: HostBehavior<TSource>, force?: boolean): void;\n    removeStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n}\n\n// @public\nexport const html: HTMLTemplateTag;\n\n// @public\nexport class HTMLBindingDirective implements HTMLDirective, ViewBehaviorFactory, ViewBehavior, Aspected, BindingDirective {\n    constructor(dataBinding: Binding);\n    aspectType: DOMAspect;\n    // @internal\n    bind(controller: ViewController): void;\n    createBehavior(): ViewBehavior;\n    createHTML(add: AddViewBehaviorFactory): string;\n    dataBinding: Binding;\n    // @internal\n    handleChange(binding: Expression, observer: ExpressionObserver): void;\n    // @internal\n    handleEvent(event: Event): void;\n    id: string;\n    policy: DOMPolicy;\n    sourceAspect: string;\n    targetAspect: string;\n    targetNodeId: string;\n    targetTagName: string | null;\n    // @internal (undocumented)\n    unbind(controller: ViewController): void;\n}\n\n// @public\nexport interface HTMLDirective {\n    createHTML(add: AddViewBehaviorFactory): string;\n}\n\n// @public\nexport const HTMLDirective: Readonly<{\n    getForInstance: (object: any) => HTMLDirectiveDefinition<Constructable<HTMLDirective>> | undefined;\n    getByType: (key: Function) => HTMLDirectiveDefinition<Constructable<HTMLDirective>> | undefined;\n    define<TType extends Constructable<HTMLDirective>>(type: TType, options?: PartialHTMLDirectiveDefinition): TType;\n    assignAspect(directive: Aspected, value?: string): void;\n}>;\n\n// @public\nexport function htmlDirective(options?: PartialHTMLDirectiveDefinition): (type: Constructable<HTMLDirective>) => void;\n\n// @public\nexport interface HTMLDirectiveDefinition<TType extends Constructable<HTMLDirective> = Constructable<HTMLDirective>> extends Required<PartialHTMLDirectiveDefinition> {\n    readonly type: TType;\n}\n\n// @public\nexport interface HTMLTemplateCompilationResult<TSource = any, TParent = any> {\n    createView(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    // (undocumented)\n    readonly factories: CompiledViewBehaviorFactory[];\n}\n\n// @public\nexport type HTMLTemplateTag = (<TSource = any, TParent = any>(strings: TemplateStringsArray, ...values: TemplateValue<TSource, TParent>[]) => ViewTemplate<TSource, TParent>) & {\n    partial(html: string): InlineTemplateDirective;\n};\n\n// @public\nexport class HTMLView<TSource = any, TParent = any> extends DefaultExecutionContext<TParent> implements ElementView<TSource, TParent>, SyntheticView<TSource, TParent>, ExecutionContext<TParent> {\n    constructor(fragment: DocumentFragment, factories: ReadonlyArray<CompiledViewBehaviorFactory>, targets: ViewBehaviorTargets);\n    appendTo(node: Node): void;\n    bind(source: TSource, context?: ExecutionContext<TParent>): void;\n    context: ExecutionContext<TParent>;\n    dispose(): void;\n    static disposeContiguousBatch(views: SyntheticView[]): void;\n    firstChild: Node;\n    insertBefore(node: Node): void;\n    isBound: boolean;\n    isHydrated: Promise<boolean>;\n    isPrerendered: Promise<boolean>;\n    lastChild: Node;\n    // (undocumented)\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): void;\n    }): void;\n    remove(): void;\n    // @internal\n    _skipAttrUpdates: boolean;\n    source: TSource | null;\n    readonly sourceLifetime: SourceLifetime;\n    // (undocumented)\n    readonly targets: ViewBehaviorTargets;\n    unbind(): void;\n}\n\n// @public\nexport class InlineTemplateDirective implements HTMLDirective {\n    constructor(html: string, factories?: Record<string, ViewBehaviorFactory>);\n    createHTML(add: AddViewBehaviorFactory): string;\n    static readonly empty: InlineTemplateDirective;\n}\n\n// @public\nexport interface JSONSchema extends JSONSchemaCommon {\n    // (undocumented)\n    $defs?: Record<string, JSONSchemaDefinition>;\n    // (undocumented)\n    $id: string;\n    // (undocumented)\n    $schema: string;\n}\n\n// @public\nexport interface JSONSchemaCommon {\n    $observe?: boolean;\n    // (undocumented)\n    $ref?: string;\n    // (undocumented)\n    anyOf?: Array<any>;\n    // (undocumented)\n    items?: any;\n    // (undocumented)\n    properties?: any;\n    // (undocumented)\n    type?: string;\n}\n\n// @public\nexport interface JSONSchemaDefinition extends JSONSchemaCommon {\n    // (undocumented)\n    $fast_context: string;\n    // (undocumented)\n    $fast_parent_contexts: Array<string>;\n}\n\n// @public\nexport interface LengthObserver extends Subscriber {\n    length: number;\n}\n\n// @public\nexport function lengthOf<T>(array: readonly T[]): number;\n\n// @public\nexport function listener<T = any>(expression: Expression<T>, options?: AddEventListenerOptions): Binding<T>;\n\n// @public\nexport const Markup: Readonly<{\n    interpolation: (id: string) => string;\n    attribute: (id: string) => string;\n    comment: (id: string) => string;\n}>;\n\n// @public\nexport interface NodeBehaviorOptions<T = any> {\n    filter?: ElementsFilter;\n    property: T;\n}\n\n// @public\nexport abstract class NodeObservationDirective<T extends NodeBehaviorOptions> extends StatelessAttachedAttributeDirective<T> {\n    bind(controller: ViewController): void;\n    protected computeNodes(target: any): Node[];\n    protected abstract disconnect(target: any): void;\n    protected abstract getNodes(target: any): Node[];\n    protected getSource(target: Node): any;\n    get id(): string;\n    set id(value: string);\n    protected abstract observe(target: any): void;\n    targetNodeId: string;\n    unbind(controller: ViewController): void;\n    protected updateTarget(source: any, value: ReadonlyArray<any>): void;\n}\n\n// @public\nexport function normalizeBinding<TSource = any, TReturn = any, TParent = any>(value: Expression<TSource, TReturn, TParent> | Binding<TSource, TReturn, TParent> | {}): Binding<TSource, TReturn, TParent>;\n\n// @public\nexport interface Notifier {\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber, propertyToWatch?: any): void;\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: any): void;\n}\n\n// @public\nexport const nullableBooleanConverter: ValueConverter;\n\n// @public\nexport const nullableNumberConverter: ValueConverter;\n\n// @public\nexport const Observable: Readonly<{\n    setArrayObserverFactory(factory: (collection: any[]) => Notifier): void;\n    getNotifier: <T extends Notifier = Notifier>(source: any) => T;\n    track(source: unknown, propertyName: string): void;\n    trackVolatile(): void;\n    notify(source: unknown, args: any): void;\n    defineProperty(target: {}, nameOrAccessor: string | Accessor): void;\n    getAccessors: (target: {}) => Accessor[];\n    binding<TSource = any, TReturn = any>(expression: Expression<TSource, TReturn>, initialSubscriber?: Subscriber, isVolatileBinding?: boolean): ExpressionNotifier<TSource, TReturn>;\n    isVolatileBinding<TSource = any, TReturn = any>(expression: Expression<TSource, TReturn>): boolean;\n}>;\n\n// @public\nexport function observable(target: {}, nameOrAccessor: string | Accessor): void;\n\n// @public\nexport interface ObservationRecord {\n    propertyName: string;\n    propertySource: any;\n}\n\n// @public\nexport function oneTime<T = any>(expression: Expression<T>, policy?: DOMPolicy): Binding<T>;\n\n// @public\nexport function oneWay<T = any>(expression: Expression<T>, policy?: DOMPolicy, isVolatile?: boolean): Binding<T>;\n\n// @beta\nexport type OwnedState<T> = ReadonlyOwnedState<T> & {\n    set(owner: any, value: T): void;\n    asReadonly(): ReadonlyOwnedState<T>;\n};\n\n// @beta\nexport function ownedState<T>(value: T | (() => T), options?: string | StateOptions): OwnedState<T>;\n\n// @public\nexport const Parser: Readonly<{\n    parse(value: string, factories: Record<string, ViewBehaviorFactory>): (string | ViewBehaviorFactory)[] | null;\n}>;\n\n// @public\nexport interface PartialFASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributes?: (AttributeConfiguration | string)[];\n    readonly elementOptions?: ElementDefinitionOptions;\n    readonly name: string;\n    readonly registry?: CustomElementRegistry;\n    readonly schema?: Schema;\n    readonly shadowOptions?: Partial<ShadowRootOptions> | null;\n    readonly styles?: ComposableStyles | ComposableStyles[];\n    readonly template?: ElementViewTemplate<InstanceType<TType>> | FASTElementTemplateResolver<TType>;\n}\n\n// @public\nexport interface PartialHTMLDirectiveDefinition {\n    aspected?: boolean;\n}\n\n// @public\nexport class PropertyChangeNotifier implements Notifier {\n    constructor(subject: any);\n    notify(propertyName: string): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber, propertyToWatch?: string): void;\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: string): void;\n}\n\n// @beta\nexport function reactive<T>(object: T, deep?: boolean): T;\n\n// @beta\nexport type ReadonlyOwnedState<T> = {\n    (owner: any): T;\n};\n\n// @beta\nexport type ReadonlyState<T> = {\n    (): T;\n    readonly current: T;\n};\n\n// @public\nexport const ref: <TSource = any, TParent = any>(propertyName: keyof TSource & string) => CaptureType<TSource, TParent>;\n\n// @public\nexport class RefDirective extends StatelessAttachedAttributeDirective<string> {\n    bind(controller: ViewController): void;\n    targetNodeId: string;\n}\n\n// @public\nexport interface RegisterPathConfig {\n    // (undocumented)\n    childrenMap: ChildrenMap | null;\n    // (undocumented)\n    pathConfig: CachedPath;\n    // (undocumented)\n    rootPropertyName: string;\n}\n\n// @public\nexport function render<TSource = any, TItem = any, TParent = any>(value?: Expression<TSource, TItem> | Binding<TSource, TItem> | {}, template?: ContentTemplate | string | Expression<TSource, ContentTemplate | string | Node, TParent> | Binding<TSource, ContentTemplate | string | Node, TParent>): CaptureType<TSource, TParent>;\n\n// @public\nexport class RenderBehavior<TSource = any> implements ViewBehavior, Subscriber {\n    constructor(directive: RenderDirective);\n    bind(controller: ViewController): void;\n    // @internal\n    handleChange(source: any, observer: ExpressionObserver): void;\n    unbind(controller: ViewController): void;\n}\n\n// @public\nexport class RenderDirective<TSource = any> implements HTMLDirective, ViewBehaviorFactory, BindingDirective {\n    constructor(dataBinding: Binding<TSource>, templateBinding: Binding<TSource, ContentTemplate>, templateBindingDependsOnData: boolean);\n    createBehavior(): RenderBehavior<TSource>;\n    createHTML(add: AddViewBehaviorFactory): string;\n    // (undocumented)\n    readonly dataBinding: Binding<TSource>;\n    targetNodeId: string;\n    // (undocumented)\n    readonly templateBinding: Binding<TSource, ContentTemplate>;\n    // (undocumented)\n    readonly templateBindingDependsOnData: boolean;\n}\n\n// @public\nexport function repeat<TSource = any, TArray extends ReadonlyArray<any> = ReadonlyArray<any>, TParent = any>(items: Expression<TSource, TArray, TParent> | Binding<TSource, TArray, TParent> | ReadonlyArray<any>, template: Expression<TSource, ViewTemplate<any, TSource>> | Binding<TSource, ViewTemplate<any, TSource>> | ViewTemplate<any, TSource>, options?: RepeatOptions): CaptureType<TSource, TParent>;\n\n// @public\nexport class RepeatBehavior<TSource = any> implements ViewBehavior, Subscriber {\n    constructor(directive: RepeatDirective);\n    bind(controller: ViewController): void;\n    handleChange(source: any, args: Splice[] | Sort[] | ExpressionObserver): void;\n    unbind(): void;\n    // @internal (undocumented)\n    views: SyntheticView[];\n}\n\n// @public\nexport interface RepeatCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"repeat\";\n}\n\n// @public\nexport class RepeatDirective<TSource = any> implements HTMLDirective, ViewBehaviorFactory, BindingDirective {\n    constructor(dataBinding: Binding<TSource>, templateBinding: Binding<TSource, SyntheticViewTemplate>, options: RepeatOptions);\n    createBehavior(): RepeatBehavior<TSource>;\n    createHTML(add: AddViewBehaviorFactory): string;\n    // (undocumented)\n    readonly dataBinding: Binding<TSource>;\n    // (undocumented)\n    readonly options: RepeatOptions;\n    targetNodeId: string;\n    // (undocumented)\n    readonly templateBinding: Binding<TSource, SyntheticViewTemplate>;\n}\n\n// @public\nexport interface RepeatOptions {\n    positioning?: boolean;\n    recycle?: boolean;\n}\n\n// @public\nexport class Schema {\n    constructor(name: string);\n    addPath(config: RegisterPathConfig): void;\n    getRootProperties(): IterableIterator<string>;\n    getSchema(rootPropertyName: string): JSONSchema | null;\n}\n\n// @public\nexport const schemaRegistry: CachedPathMap;\n\n// @public\nexport interface ShadowRootOptions extends ShadowRootInit {\n    // @beta\n    registry?: CustomElementRegistry;\n}\n\n// @public\nexport const Signal: Readonly<{\n    subscribe(signal: string, subscriber: Subscriber): void;\n    unsubscribe(signal: string, subscriber: Subscriber): void;\n    send(signal: string): void;\n}>;\n\n// @public\nexport function signal<T = any>(expression: Expression<T>, options: string | Expression<T>, policy?: DOMPolicy): Binding<T>;\n\n// @public\nexport function slotted<TSource = any, TParent = any>(propertyOrOptions: (keyof TSource & string) | SlottedDirectiveOptions<keyof TSource & string>): CaptureType<TSource, TParent>;\n\n// @public\nexport class SlottedDirective extends NodeObservationDirective<SlottedDirectiveOptions> {\n    disconnect(target: EventSource): void;\n    getNodes(target: HTMLSlotElement): Node[];\n    // @internal (undocumented)\n    handleEvent(event: Event): void;\n    observe(target: EventSource): void;\n}\n\n// @public\nexport interface SlottedDirectiveOptions<T = any> extends NodeBehaviorOptions<T>, AssignedNodesOptions {\n}\n\n// @public\nexport class Sort {\n    constructor(sorted?: number[] | undefined);\n    // (undocumented)\n    sorted?: number[] | undefined;\n}\n\n// @public\nexport function sortedCount<T>(array: readonly T[]): number;\n\n// @public\nexport interface SortObserver extends Subscriber {\n    sorted: number;\n}\n\n// @public\nexport const SourceLifetime: Readonly<{\n    readonly unknown: undefined;\n    readonly coupled: 1;\n}>;\n\n// @public\nexport type SourceLifetime = (typeof SourceLifetime)[keyof typeof SourceLifetime];\n\n// @public\nexport class Splice {\n    constructor(index: number, removed: any[], addedCount: number);\n    // (undocumented)\n    addedCount: number;\n    adjustTo(array: any[]): this;\n    // (undocumented)\n    index: number;\n    // (undocumented)\n    removed: any[];\n    reset?: boolean;\n}\n\n// @public\nexport interface SpliceStrategy {\n    normalize(previous: unknown[] | undefined, current: unknown[], changes: Splice[] | undefined): readonly Splice[];\n    pop(array: any[], observer: ArrayObserver, pop: typeof Array.prototype.pop, args: any[]): any;\n    push(array: any[], observer: ArrayObserver, push: typeof Array.prototype.push, args: any[]): any;\n    reverse(array: any[], observer: ArrayObserver, reverse: typeof Array.prototype.reverse, args: any[]): any;\n    shift(array: any[], observer: ArrayObserver, shift: typeof Array.prototype.shift, args: any[]): any;\n    sort(array: any[], observer: ArrayObserver, sort: typeof Array.prototype.sort, args: any[]): any[];\n    splice(array: any[], observer: ArrayObserver, splice: typeof Array.prototype.splice, args: any[]): any;\n    readonly support: SpliceStrategySupport;\n    unshift(array: any[], observer: ArrayObserver, unshift: typeof Array.prototype.unshift, args: any[]): any[];\n}\n\n// @public\nexport const SpliceStrategy: Readonly<{\n    readonly reset: Splice[];\n    readonly setDefaultStrategy: (strategy: SpliceStrategy) => void;\n}>;\n\n// @public\nexport const SpliceStrategySupport: Readonly<{\n    readonly reset: 1;\n    readonly splice: 2;\n    readonly optimized: 3;\n}>;\n\n// @public\nexport type SpliceStrategySupport = (typeof SpliceStrategySupport)[keyof typeof SpliceStrategySupport];\n\n// @public\nexport const enum Stages {\n    connected = 1,\n    connecting = 0,\n    disconnected = 3,\n    disconnecting = 2\n}\n\n// @beta\nexport type State<T> = ReadonlyState<T> & {\n    current: T;\n    set(value: T): void;\n    asReadonly(): ReadonlyState<T>;\n};\n\n// @beta\nexport function state<T>(value: T, options?: string | StateOptions): State<T>;\n\n// @public\nexport abstract class StatelessAttachedAttributeDirective<TOptions> implements HTMLDirective, ViewBehaviorFactory, ViewBehavior {\n    constructor(options: TOptions);\n    abstract bind(controller: ViewController): void;\n    createBehavior(): ViewBehavior;\n    createHTML(add: AddViewBehaviorFactory): string;\n    // (undocumented)\n    protected options: TOptions;\n}\n\n// @beta\nexport type StateOptions = {\n    deep?: boolean;\n    name?: string;\n};\n\n// @public\nexport interface StyleStrategy {\n    addStylesTo(target: StyleTarget): void;\n    removeStylesFrom(target: StyleTarget): void;\n}\n\n// @public\nexport interface StyleTarget extends Pick<Node, \"getRootNode\"> {\n    adoptedStyleSheets?: CSSStyleSheet[];\n    append(styles: HTMLStyleElement): void;\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\n    removeChild(styles: HTMLStyleElement): void;\n}\n\n// @public\nexport interface Subscriber {\n    handleChange(subject: any, args: any): void;\n}\n\n// @public\nexport class SubscriberSet implements Notifier {\n    constructor(subject: any, initialSubscriber?: Subscriber);\n    has(subscriber: Subscriber): boolean;\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber): void;\n    unsubscribe(subscriber: Subscriber): void;\n}\n\n// @public\nexport interface SubtreeDirectiveOptions<T = any> extends NodeBehaviorOptions<T>, Omit<MutationObserverInit, \"subtree\" | \"childList\"> {\n    selector: string;\n    subtree: boolean;\n}\n\n// @public\nexport interface SyntheticView<TSource = any, TParent = any> extends View<TSource, TParent> {\n    readonly firstChild: Node;\n    insertBefore(node: Node): void;\n    readonly lastChild: Node;\n    remove(): void;\n}\n\n// @public\nexport interface SyntheticViewTemplate<TSource = any, TParent = any> {\n    create(): SyntheticView<TSource, TParent>;\n    inline(): CaptureType<TSource, TParent>;\n}\n\n// @public\nexport type TemplateValue<TSource, TParent = any> = Expression<TSource, any, TParent> | Binding<TSource, any, TParent> | HTMLDirective | CaptureType<TSource, TParent>;\n\n// @public\nexport type TrustedTypesPolicy = {\n    createHTML(html: string): string;\n};\n\n// @public\nexport function twoWay<T = any>(expression: Expression<T>, optionsOrChangeEvent?: TwoWayBindingOptions | string, policy?: DOMPolicy, isBindingVolatile?: boolean): Binding<T>;\n\n// @public\nexport type TwoWayBindingOptions = {\n    changeEvent?: string;\n    fromView?: (value: any) => any;\n};\n\n// @public\nexport interface TwoWaySettings {\n    determineChangeEvent(bindingSource: BindingDirective, target: HTMLElement): string;\n}\n\n// @public\nexport const TwoWaySettings: Readonly<{\n    configure(settings: TwoWaySettings): void;\n}>;\n\n// @public\nexport interface TypeDefinition {\n    type: Function;\n}\n\n// @public\nexport interface TypeRegistry<TDefinition extends TypeDefinition> {\n    getByType(key: Function): TDefinition | undefined;\n    getForInstance(object: any): TDefinition | undefined;\n    register(definition: TDefinition): boolean;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"UnobservableMutationObserver\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal\nexport class UnobservableMutationObserver extends MutationObserver {\n    constructor(callback: MutationCallback);\n    // (undocumented)\n    observe(target: Node, options?: MutationObserverInit | undefined): void;\n    // (undocumented)\n    unobserve(target: Node): void;\n}\n\n// @public\nexport interface UpdateQueue {\n    enqueue(callable: Callable): void;\n    next(): Promise<void>;\n    process(): void;\n    setMode(isAsync: boolean): void;\n}\n\n// @public\nexport const Updates: UpdateQueue;\n\n// @public\nexport interface ValueConverter {\n    fromView(value: any): any;\n    toView(value: any): any;\n}\n\n// @public\nexport interface View<TSource = any, TParent = any> extends Disposable {\n    bind(source: TSource, context?: ExecutionContext<TParent>): void;\n    readonly context: ExecutionContext<TParent>;\n    readonly isBound: boolean;\n    readonly source: TSource | null;\n    unbind(): void;\n}\n\n// @public\nexport interface ViewBehavior<TSource = any, TParent = any> {\n    bind(controller: ViewController<TSource, TParent>): void;\n}\n\n// @public\nexport interface ViewBehaviorFactory {\n    createBehavior(): ViewBehavior;\n    id?: string;\n    policy?: DOMPolicy;\n    targetNodeId?: string;\n    targetTagName?: string | null;\n}\n\n// @public\nexport interface ViewBehaviorOrchestrator<TSource = any, TParent = any> extends ViewController<TSource, TParent>, HostBehavior<TSource> {\n    addBehavior(behavior: ViewBehavior): void;\n    addBehaviorFactory(factory: ViewBehaviorFactory, target: Node): void;\n    // (undocumented)\n    addTarget(nodeId: string, target: Node): void;\n}\n\n// @public\nexport const ViewBehaviorOrchestrator: Readonly<{\n    create<TSource = any, TParent = any>(source: TSource): ViewBehaviorOrchestrator<TSource, TParent>;\n}>;\n\n// @public\nexport type ViewBehaviorTargets = {\n    [id: string]: Node;\n};\n\n// @public\nexport interface ViewController<TSource = any, TParent = any> extends ExpressionController<TSource, TParent> {\n    readonly isHydrated?: Promise<boolean>;\n    readonly isPrerendered?: Promise<boolean>;\n    // @internal\n    readonly _skipAttrUpdates?: boolean;\n    readonly targets: ViewBehaviorTargets;\n}\n\n// @public\nexport class ViewTemplate<TSource = any, TParent = any> implements ElementViewTemplate<TSource, TParent>, SyntheticViewTemplate<TSource, TParent> {\n    constructor(html: string | HTMLTemplateElement, factories?: Record<string, ViewBehaviorFactory>, policy?: DOMPolicy | undefined);\n    // @internal (undocumented)\n    compile(): HTMLTemplateCompilationResult<TSource, TParent>;\n    create(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    static create<TSource = any, TParent = any>(strings: string[], values: TemplateValue<TSource, TParent>[], policy?: DOMPolicy): ViewTemplate<TSource, TParent>;\n    readonly factories: Record<string, ViewBehaviorFactory>;\n    readonly html: string | HTMLTemplateElement;\n    inline(): CaptureType<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    withPolicy(policy: DOMPolicy): this;\n}\n\n// @public\nexport function volatile(target: {}, name: string | Accessor, descriptor: PropertyDescriptor): PropertyDescriptor;\n\n// @beta\nexport function watch(object: any, subscriber: Subscriber | ((subject: any, args: any) => void)): Disposable;\n\n// @public\nexport function when<TSource = any, TReturn = any, TParent = any>(condition: Expression<TSource, TReturn, TParent> | boolean, templateOrTemplateBinding: SyntheticViewTemplate<TSource, TParent> | Expression<TSource, SyntheticViewTemplate<TSource, TParent>, TParent>, elseTemplateOrTemplateBinding?: SyntheticViewTemplate<TSource, TParent> | Expression<TSource, SyntheticViewTemplate<TSource, TParent>, TParent>): CaptureType<TSource, TParent>;\n\n```\n","isInternal":false,"tokens":9696,"sizeBytes":43192},{"name":"fastelement.md","path":"packages/fast-element/docs/architecture/fastelement.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/architecture/fastelement.md","title":"Architecture Skill","category":"anthropic-skill","format":"markdown","content":"# FASTElement\n\nThe `FASTElement` is our extension of the `HTMLElement`. As such it leverages the lifecycles but also requires additional setup before before the class `constructor` or the `connectedCallback` method is executed which are explained in the [overview](./overview.md). This document explains specifically what `FASTElement` leverages inside the `HTMLElement`s lifecycle hooks.\n\nFor an explanation into `HTMLElement` lifecycle hooks refer to the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks).\n\nBecause `FASTElement` extends `HTMLElement`, it is a browser `Window` runtime\nAPI. It is not intended to execute in workers, server-side JavaScript runtimes,\nor other non-window hosts where custom element lifecycle callbacks and animation\nframe scheduling are unavailable.\n\n## A Custom Element is Detected by the Browser\n\nBecause the `FASTElement` is an extension of the `HTMLElement`, it makes use of the same lifecycle hooks and extends them with `$fastController`. It also initializes using another class `ElementController`, the methods this are called during the custom elements native `constructor`, `connectedCallback`, `disconnectedCallback`, and `attributeChangedCallback` lifecycle hooks.\n\n### 🔄 **Lifecycle**: Initialization\n\n```mermaid\nflowchart TD\n    A[A <code>FASTElement</code> web component is added to the <code>DOM</code>] --> B\n    B[<code>FASTElement</code> initializes the <code>ElementController.forCustomElement</code> passing the Custom Element instance] --> C\n    B --> F[Observables applied to the <code>FASTElement</code> are updated on the FAST global without values]\n    C{Is an <code>ElementController</code> available?}\n    C --> |yes|E\n    C --> |no|D\n    D[Initialize a new <code>ElementController</code> referred to as setting an element controller strategy]\n    D --> F\n    E[<code>ElementController</code> captures the Custom Element instance and the definition and attaches them to the <code>$fastController</code> which is then attached to the instance]\n```\n\n### 🔄 **Lifecycle**: Component is connected\n\n```mermaid\nflowchart TD\n    A[browser <code>HTMLElement</code>'s <code>connectedCallback</code> is called] --> B\n    B[<code>this.$fastController.connect</code> in FASTElement is called] --> C\n    B --> D\n    B --> E\n    B --> F\n    C[bind observables by capturing public own Custom Element properties and setting those values through the matching accessors]\n    D[connect behaviors by call the <code>connectedCallback</code> on all behaviors]\n    E[render template, execute an <code>ElementViewTemplate</code>'s render method]\n    F[add styles either as an appended <code>StyleElement</code> node or an <code>adoptedStylesheet</code> which may include and attach behaviors]\n```\n\n#### Render Template\n\nThe rendering of the template on the `ElementController` is by the `renderTemplate` method which is called during the `ElementController.connect` method which is triggered by `HTMLElement`s `connectedCallback` lifecycle.\n\nThe `renderTemplate` identifies the Custom Element, and the shadow root associated with the Custom Element. This then places a rendering of the template (an `ElementView`) onto the internal `view` of the controller. When creating the `ElementView`/`HTMLView` using the `ViewTemplate.render`, the `Compiler.compile()` method identifies a `DocumentFragment` either by using an existing `<template>` tag, or creating one to wrap the contents of the shadow root. A new `CompilationContext` is created and the `compileAttributes` function is called, this results in the replacement of the placeholder attributes initally set-up during the pre-render step with their values if a value has been assigned. The factories with the associated nodes identified are then passed to the context. The view then binds all behaviors to the source element. The `CompilationContext.createView` is executed with the `DocumentFragment` as the root, and returns an `HTMLView`. This `HTMLView` includes an `appendTo` method to attach the fragment to the host element, which it then does. It should be noted that the compiled HTML is a `string`, which when set on the `DocumentFragment` as `innerHTML`, this allows the browser to dictate the creation of HTML nodes.\n\n### 🔄 **Lifecycle**: Component is disconnected\n\nWhen a component is disconnected, a cleanup step is created to remove associated behaviors.\n\n### 🔄 **Lifecycle**: Attribute has been changed\n\nAttributes have an `AttributeDefinition` which allows for converters, attachment of the `<attributName>Changed` aspect of the `@attr` decorator among other capabilities.\n\n```mermaid\nflowchart TD\n    A[The browser <code>HTMLElement</code>'s <code>attributeChangedCallback</code> is called] --> B\n    B[<code>this.$fastController.onAttributeChangedCallback</code> in <code>FASTElement</code> is called] --> C\n    C[calls the attribute definitions <code>onAttributeChangedCallback</code> method with the updated value] --> D\n    D[An <code>Updates.enqueue</code> is called which places the update in the task queue which is then executed, these are performed async unless otherwise specified]\n```\n\nThese changes are observed and similar to the way `Observables` work, they utilize an `Accessor` pattern which has a `getValue` and `setValue` in which DOM updates are applied.\n\nObservable backing slots such as `_foo` are FAST-owned internal state. The\ncontroller's connection-time observable binding only replays public own\nproperties that shadow prototype accessors; it does not normalize backing slots\ninto public property assignments. This keeps attribute converter output in its\nalready-converted model form while preserving pre-upgrade public property\nassignments and opt-in extension behavior.","isInternal":false,"tokens":1260,"sizeBytes":5807},{"name":"html-tagged-template-literal.md","path":"packages/fast-element/docs/architecture/html-tagged-template-literal.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/architecture/html-tagged-template-literal.md","title":"Architecture Skill","category":"anthropic-skill","format":"markdown","content":"# `html` tagged template literal\n\nThe `html` export from `@microsoft/fast-element` is used to create the template logic for the custom element.\n\n## Pre-processing the `html` tagged template literal contents\n\nBefore the template can be used it goes through a step to convert it into a `ViewTemplate` which it does via the `ViewTemplate.create()` method. This is then used during the `compose` step, before `FASTElement` is instantiated.\n\nDuring the static `ViewTemplate.create()` method (called by the `html` tag), the following happens for each string:\n- Factories with unique IDs are created for each tag template literal argument (or `TemplateValue`) which matches with the corresponding string\n- A binding is created from the `TemplateValue`\n\nThe `Compiler.compile()` method is called lazily the first time the template is rendered (via `ViewTemplate.compile()`, which is triggered by `ViewTemplate.create()` instance method or `ViewTemplate.render()`).\n\nA resulting string using a `createHTML()` function is produced using the `HTMLDirective`s executed for each factory. The behavior is augmented by the previous string from the `html` tag template which determines the aspect if one exists, these aspects are the `@`, `:`, or other binding aspect attached to attributes.\n\nThe `createHTML()` function utilizes a `Markup` attribute which is assigned to a factory's unique ID. The strings are concatenated and passed to a new `ViewTemplate` with all the factories (empty until one is assigned) that act as a dictionary with the unique IDs as the key to look up each factory once it has been created. The string this creates is injected into a `<template>` as `innerHTML`, which allows the browser to create the nodes and placeholder factory IDs, with the only `DOM` node that is explicitly created being the wrapping `<template>` element.\n\n## Directives\n\nThe `HTMLBindingDirective` applies bindings to items identified as various `TemplateValue`s within the `html` tagged template. The `createHTML` step uses the factory associated with the binding to create strings in the markup using the factory's ID.\n\n```mermaid\nflowchart TD\n    A[A <code>new HTMLBindingDirective</code> is created with a data binding which has a policy, options, <code>createObserver</code>, and an evaluate method assigned to the passed arrow function such as <pre>x => x.foo</pre>]\n    B[<code>oneTime</code> binding passes the corresponding tag template argument, an arrow function]\n    C[<code>oneWay</code> binding passes a copy of the corresponding tag template argument, an arrow function]\n    D[An already specified binding such as a <code>repeat</code> or <code>when</code> directive is passed]\n    A --> B\n    A --> C\n    A --> D\n    E[When a <code>createObserver</code> is called, an <code>Observable.binding</code> is created passing the arrow function to be evaluated and the subscriber to be notified]\n    C --> E\n    F[When a <code>createObserver</code> is called, the instance of the one time binding is returned which includes a bind method returning the arrow function executed against the controller source and context]\n    B --> F\n```\n","isInternal":false,"tokens":688,"sizeBytes":3130},{"name":"intro.md","path":"packages/fast-element/docs/architecture/intro.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/architecture/intro.md","title":"Architecture Skill","category":"anthropic-skill","format":"markdown","content":"# Introduction\n\nThis document (and the linked documents) explains how the exports and side effects of `@microsoft/fast-element` are used to create custom elements.\n\n`@microsoft/fast-element` is designed to run in a client-side browser `Window`\nruntime. Its element lifecycle, rendering, and update queue assume browser DOM,\nCustom Elements, Shadow DOM, and `requestAnimationFrame` are available. Workers,\nserver-side JavaScript runtimes, and other non-window hosts are not supported\ntargets for the FAST Element client runtime.\n\n## Glossary\n\n- [Overview](./overview.md): How the `@microsoft/fast-element` should be used by a developer and what code is executed during the first render.\n- [`FASTElement`](./fastelement.md): How the `FASTElement` is architected.\n- [`html` tagged template literal](./html-tagged-template-literal.md): How the `html` tagged template literal takes and converts the contents into a `ViewTemplate`.\n- [`Updates` queue](./updates.md): How updates to attributes and observables are processed.","isInternal":false,"tokens":221,"sizeBytes":1017},{"name":"overview.md","path":"packages/fast-element/docs/architecture/overview.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/architecture/overview.md","title":"Architecture Skill","category":"anthropic-skill","format":"markdown","content":"# General FAST usage\n\n`FASTElement` is an extension of `HTMLElement` which makes use of Custom Element APIs native to the browser. It also supplies the following methods:\n\n- The `define` method combines the Custom Element name, template, style, and other options into a `FASTElementDefinition`, then uses the native Custom Element [`define()`](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define) to register the Custom Element with a Custom Element Registry.\n- The `from` method allows the use of Customized Built-in elements, which extend from native elements such as `HTMLButtonElement`.\n\n### Creating a Custom Element from FASTElement\n\nA basic developer flow for defining a custom element looks like this:\n\n```mermaid\nflowchart TD\n    A[Create a <code>FASTElement</code> web component by extending the <code>FASTElement</code> class] --> F\n    F[Prepare the definition with template and styles] --> G[Define the component in the browser with <code>define()</code>]\n```\n\nLet's take a look at the definition step to see what the FAST architecture is doing at this stage.\n\n### Defining a Custom Element\n\nThe subclass `define()` method creates a new `FASTElementDefinition`, which includes all metadata needed for the element (such as templates, attributes, and styles), and registers it with the configured Custom Element Registry. The resulting object can be retrieved via `ElementController.definition`.\n\n## A Custom Element in JavaScript is sent to the Browser\n\nLet's step back from defining the Custom Element and consider what is happening when we import from the `@microsoft/fast-element` package.\n\nThe FAST Element client runtime is expected to run in the browser `Window`.\nCustom element definition, connection, rendering, and update scheduling all rely\non browser APIs such as the Custom Element Registry, DOM, Shadow DOM, and\n`requestAnimationFrame`.\n\nFirst, a global `FAST` property will be created if one does not already exist, typically in browser on the `window`.\n\nAdditionally, when Custom Elements are included in a script a few things might happen even before a Custom Element gets detected by the browser. First, there are initial side effects caused by the use of decorators. These include the `attr` decorator from `@microsoft/fast-element` and the `observable` decorator from `@microsoft/fast-element`.\n\nHere is a basic flow of what code is executed and when during initial load of a script that contains a FAST defined Custom Element:\n\n```mermaid\nflowchart TD\n    A@{ shape: circle, label: \"The browser loads the JavaScript file containing FAST and FAST Custom Element definitions\" }\n    B@{ shape: rect, label: \"The FAST global is added to the window\" }\n    A --> B\n    C@{ shape: rect, label: \"A Custom Element executes the <code>compose</code> step\"}\n    B --> C\n    D@{ shape: procs, label: \"<ul style='text-align: left'><li>Any defined observable decorators are added to the FAST global</li><li>An attribute decorator locates the associated Custom Elements constructor which it uses to push itself to the Custom Elements attribute collection</li></ul>\"}\n    C --> D\n    F@{ shape: rect, label: \"An HTML tagged template literal is executed for the FAST Custom Element and applied to the definition\" }\n    D --> F\n    G@{ shape: rect, label: \"The <code>define</code> step is hit and the <code>customElement</code> is registered with the Custom Element Registry\" }\n    F --> G\n    H@{ shape: rect, label: \"A Custom Element is detected on the page and the browser initializes it\" }\n    I@{ shape: dbl-circ, label: \"The lifecycle steps for <code>FASTElement</code> are executed\" }\n    G --> H\n    H --> I\n```\n","isInternal":false,"tokens":819,"sizeBytes":3659},{"name":"updates.md","path":"packages/fast-element/docs/architecture/updates.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/architecture/updates.md","title":"Architecture Skill","category":"anthropic-skill","format":"markdown","content":"# `Updates`\n\nThe `Updates` API batches FAST Element DOM work in the client-side browser\n`Window` runtime. Queued work includes updates to attributes, observables, and\nobserved arrays. The async queue is aligned to `requestAnimationFrame`, which is\nexpected to be available in the supported runtime.\n\nFAST Element is not intended to run its client runtime in workers, server-side\nJavaScript runtimes, or other non-window hosts. Code that needs server rendering\nshould generate HTML for the browser, then let the browser window run FAST\nElement, connect custom elements, and process queued updates.\n\n## Attributes\n\nAn attribute change may be queued when the value of the attribute is updated. This change is triggered by `HTMLElement` lifecycle hook `attributeChangedCallback`. The `Updates` queue is used to try to reflect the attribute with the updated value onto the element using `DOM` APIs.\n\n## Observables\n\nThe `Reflect` API is used to override `defineProperty` in order to observe a property on an Custom Element, this overrides the getter and setter, which allows subscribers to be notified of changes. Any changes which `set` the value are passed to the `Updates` queue.","isInternal":false,"tokens":242,"sizeBytes":1177},{"name":"api-report.api.md","path":"packages/fast-element/docs/arrays/api-report.api.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/arrays/api-report.api.md","title":"Arrays Skill","category":"anthropic-skill","format":"markdown","content":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport interface ArrayObserver extends SubscriberSet {\n    addSort(sort: Sort): void;\n    addSplice(splice: Splice): void;\n    flush(): void;\n    readonly lengthObserver: LengthObserver;\n    reset(oldCollection: any[] | undefined): void;\n    readonly sortObserver: SortObserver;\n    strategy: SpliceStrategy | null;\n}\n\n// @public\nexport const ArrayObserver: Readonly<{\n    readonly sorted: 0;\n    readonly enable: () => void;\n}>;\n\n// @public\nexport interface LengthObserver extends Subscriber {\n    length: number;\n}\n\n// @public\nexport function lengthOf<T>(array: readonly T[]): number;\n\n// @public\nexport interface Notifier {\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber, propertyToWatch?: any): void;\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: any): void;\n}\n\n// @public\nexport class Sort {\n    constructor(sorted?: number[] | undefined);\n    // (undocumented)\n    sorted?: number[] | undefined;\n}\n\n// @public\nexport function sortedCount<T>(array: readonly T[]): number;\n\n// @public\nexport interface SortObserver extends Subscriber {\n    sorted: number;\n}\n\n// @public\nexport class Splice {\n    constructor(index: number, removed: any[], addedCount: number);\n    // (undocumented)\n    addedCount: number;\n    adjustTo(array: any[]): this;\n    // (undocumented)\n    index: number;\n    // (undocumented)\n    removed: any[];\n    reset?: boolean;\n}\n\n// @public\nexport interface SpliceStrategy {\n    normalize(previous: unknown[] | undefined, current: unknown[], changes: Splice[] | undefined): readonly Splice[];\n    pop(array: any[], observer: ArrayObserver, pop: typeof Array.prototype.pop, args: any[]): any;\n    push(array: any[], observer: ArrayObserver, push: typeof Array.prototype.push, args: any[]): any;\n    reverse(array: any[], observer: ArrayObserver, reverse: typeof Array.prototype.reverse, args: any[]): any;\n    shift(array: any[], observer: ArrayObserver, shift: typeof Array.prototype.shift, args: any[]): any;\n    sort(array: any[], observer: ArrayObserver, sort: typeof Array.prototype.sort, args: any[]): any[];\n    splice(array: any[], observer: ArrayObserver, splice: typeof Array.prototype.splice, args: any[]): any;\n    readonly support: SpliceStrategySupport;\n    unshift(array: any[], observer: ArrayObserver, unshift: typeof Array.prototype.unshift, args: any[]): any[];\n}\n\n// @public\nexport const SpliceStrategy: Readonly<{\n    readonly reset: Splice[];\n    readonly setDefaultStrategy: (strategy: SpliceStrategy) => void;\n}>;\n\n// @public\nexport const SpliceStrategySupport: Readonly<{\n    readonly reset: 1;\n    readonly splice: 2;\n    readonly optimized: 3;\n}>;\n\n// @public\nexport type SpliceStrategySupport = (typeof SpliceStrategySupport)[keyof typeof SpliceStrategySupport];\n\n// @public\nexport interface Subscriber {\n    handleChange(subject: any, args: any): void;\n}\n\n// @public\nexport class SubscriberSet implements Notifier {\n    constructor(subject: any, initialSubscriber?: Subscriber);\n    has(subscriber: Subscriber): boolean;\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber): void;\n    unsubscribe(subscriber: Subscriber): void;\n}\n\n// (No @packageDocumentation comment for this package)\n\n```\n","isInternal":false,"tokens":785,"sizeBytes":3408},{"name":"api-report.api.md","path":"packages/fast-element/docs/context/api-report.api.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/context/api-report.api.md","title":"Context Skill","category":"anthropic-skill","format":"markdown","content":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport type Context<T> = {\n    readonly name: string;\n    readonly initialValue?: T;\n};\n\n// @public\nexport const Context: Readonly<{\n    eventType: \"context-request\";\n    for<T = unknown>(name: string): FASTContext<T>;\n    create<T = unknown>(name: string, initialValue?: T): FASTContext<T>;\n    setDefaultRequestStrategy(strategy: FASTContextRequestStrategy): void;\n    get<T extends UnknownContext>(target: EventTarget, context: T): ContextType<T>;\n    request<T extends UnknownContext>(target: EventTarget, context: T, callback: ContextCallback<ContextType<T>>, multiple?: boolean): void;\n    dispatch<T extends UnknownContext>(target: EventTarget, context: T, callback: ContextCallback<ContextType<T>>, multiple?: boolean): void;\n    provide<T extends UnknownContext>(target: EventTarget, context: T, value: ContextType<T>): void;\n    handle<T extends UnknownContext>(target: EventTarget, callback: (event: ContextEvent<T>) => void, context?: T): void;\n    defineProperty<T extends UnknownContext>(target: Constructable<EventTarget> | EventTarget, propertyName: string, context: T): void;\n}>;\n\n// @public\nexport type ContextCallback<ValueType> = (value: ValueType, dispose?: () => void) => void;\n\n// Warning: (ae-forgotten-export) The symbol \"ParameterDecorator_2\" needs to be exported by the entry point context.d.ts\n//\n// @public\nexport type ContextDecorator<T = any> = Readonly<Context<T>> & PropertyDecorator & ParameterDecorator_2;\n\n// @public\nexport class ContextEvent<T extends UnknownContext> extends Event {\n    constructor(context: T, callback: ContextCallback<ContextType<T>>, multiple?: boolean | undefined);\n    // (undocumented)\n    readonly callback: ContextCallback<ContextType<T>>;\n    // (undocumented)\n    readonly context: T;\n    // (undocumented)\n    readonly multiple?: boolean | undefined;\n}\n\n// @public\nexport type ContextType<T extends UnknownContext> = T extends Context<infer Y> ? Y : never;\n\n// @public\nexport type FASTContext<T> = ContextDecorator<T> & {\n    get(target: EventTarget): T;\n    provide(target: EventTarget, value: T): void;\n    request(target: EventTarget, callback: ContextCallback<T>, multiple?: boolean): void;\n    handle(target: EventTarget, callback: (event: ContextEvent<FASTContext<T>>) => void): void;\n};\n\n// @public\nexport type FASTContextRequestStrategy = <T extends UnknownContext>(target: EventTarget, context: T, callback: ContextCallback<ContextType<T>>, multiple: any) => void;\n\n// @public\nexport type UnknownContext = Context<unknown>;\n\n// Warnings were encountered during analysis:\n//\n// dist/dts/context.d.ts:127:5 - (ae-forgotten-export) The symbol \"Constructable\" needs to be exported by the entry point context.d.ts\n\n// (No @packageDocumentation comment for this package)\n\n```\n","isInternal":false,"tokens":682,"sizeBytes":2912},{"name":"api-report.api.md","path":"packages/fast-element/docs/declarative/api-report.api.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/declarative/api-report.api.md","title":"Declarative Skill","category":"anthropic-skill","format":"markdown","content":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport interface AccessCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"access\";\n}\n\n// @public\nexport interface Accessor {\n    getValue(source: any): any;\n    name: string;\n    setValue(source: any, value: any): void;\n}\n\n// @public\nexport type AttributeConfiguration = {\n    property: string;\n    attribute?: string;\n    mode?: AttributeMode;\n    converter?: ValueConverter;\n};\n\n// @public\nexport const AttributeConfiguration: Readonly<{\n    locate: (target: {}) => AttributeConfiguration[];\n}>;\n\n// @public\nexport class AttributeDefinition implements Accessor {\n    constructor(Owner: Function, name: string, attribute?: string, mode?: AttributeMode, converter?: ValueConverter);\n    readonly attribute: string;\n    // @internal\n    static collect(Owner: Function, ...attributeLists: (ReadonlyArray<string | AttributeConfiguration> | undefined)[]): ReadonlyArray<AttributeDefinition>;\n    readonly converter?: ValueConverter;\n    getValue(source: HTMLElement): any;\n    readonly mode: AttributeMode;\n    readonly name: string;\n    // @internal (undocumented)\n    onAttributeChangedCallback(element: HTMLElement, value: any): void;\n    readonly Owner: Function;\n    setValue(source: HTMLElement, newValue: any): void;\n}\n\n// @public\nexport type AttributeMode = \"reflect\" | \"boolean\" | \"fromView\";\n\n// @public\nexport type CachedPath = DefaultCachedPath | RepeatCachedPath | AccessCachedPath | EventCachedPath;\n\n// @public\nexport interface CachedPathCommon {\n    // (undocumented)\n    currentContext: string | null;\n    // (undocumented)\n    parentContext: string | null;\n    // (undocumented)\n    path: string;\n}\n\n// @public\nexport type CachedPathMap = Map<string, Map<string, JSONSchema>>;\n\n// @public\nexport interface CaptureType<TSource = any, TParent = any> {\n}\n\n// @public\nexport interface ChildrenMap {\n    // (undocumented)\n    attributeName: string;\n    // (undocumented)\n    customElementName: string;\n}\n\n// @public\nexport type ComposableStyles = string | ElementStyles | CSSStyleSheet;\n\n// @public\nexport type Constructable<T = {}> = {\n    new (...args: any[]): T;\n};\n\n// @public\nexport type ConstructibleStyleStrategy = {\n    new (styles: (string | CSSStyleSheet)[]): StyleStrategy;\n};\n\n// @public\nexport function declarativeTemplate<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(): FASTElementTemplateResolver<TType>;\n\n// @public\nexport interface DefaultCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"default\";\n}\n\n// @public\nexport const DOMAspect: Readonly<{\n    readonly none: 0;\n    readonly attribute: 1;\n    readonly booleanAttribute: 2;\n    readonly property: 3;\n    readonly content: 4;\n    readonly tokenList: 5;\n    readonly event: 6;\n}>;\n\n// @public\nexport type DOMAspect = (typeof DOMAspect)[Exclude<keyof typeof DOMAspect, \"none\">];\n\n// @public\nexport type DOMAspectGuards = {\n    [DOMAspect.attribute]?: DOMSinkGuards;\n    [DOMAspect.booleanAttribute]?: DOMSinkGuards;\n    [DOMAspect.property]?: DOMSinkGuards;\n    [DOMAspect.content]?: DOMSinkGuards;\n    [DOMAspect.tokenList]?: DOMSinkGuards;\n    [DOMAspect.event]?: DOMSinkGuards;\n};\n\n// @public\nexport type DOMElementGuards = Record<string, DOMAspectGuards>;\n\n// @public\nexport type DOMGuards = {\n    elements: DOMElementGuards;\n    aspects: DOMAspectGuards;\n};\n\n// @public\nexport interface DOMPolicy {\n    createHTML(value: string): string;\n    protect(tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink): DOMSink;\n}\n\n// @public\nexport const DOMPolicy: Readonly<{\n    create(options?: DOMPolicyOptions): Readonly<DOMPolicy>;\n}>;\n\n// @public\nexport type DOMPolicyOptions = {\n    trustedType?: TrustedTypesPolicy;\n    guards?: Partial<DOMGuards>;\n};\n\n// @public\nexport type DOMSink = (target: Node, aspectName: string, value: any, ...args: any[]) => void;\n\n// @public\nexport type DOMSinkGuards = Record<string, (tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink) => DOMSink>;\n\n// @public\nexport class ElementStyles {\n    constructor(styles: ReadonlyArray<ComposableStyles>);\n    // @internal (undocumented)\n    addStylesTo(target: StyleTarget): void;\n    // @internal (undocumented)\n    isAttachedTo(target: StyleTarget): boolean;\n    static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;\n    // @internal (undocumented)\n    removeStylesFrom(target: StyleTarget): void;\n    static setDefaultStrategy(Strategy: ConstructibleStyleStrategy): void;\n    get strategy(): StyleStrategy;\n    // (undocumented)\n    readonly styles: ReadonlyArray<ComposableStyles>;\n    static readonly supportsAdoptedStyleSheets: boolean;\n    withStrategy(Strategy: ConstructibleStyleStrategy): this;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"View\" needs to be exported by the entry point index.d.ts\n//\n// @public\nexport interface ElementView<TSource = any, TParent = any> extends View<TSource, TParent> {\n    appendTo(node: Node): void;\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): any;\n    }): void;\n    // Warning: (ae-forgotten-export) The symbol \"SourceLifetime\" needs to be exported by the entry point index.d.ts\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface ElementViewTemplate<TSource = any, TParent = any> {\n    create(hostBindingTarget: Element): ElementView<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): ElementView<TSource, TParent>;\n}\n\n// @public\nexport interface EventCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"event\";\n}\n\n// @public\nexport class FASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributeLookup: Record<string, AttributeDefinition>;\n    readonly attributes: ReadonlyArray<AttributeDefinition>;\n    static compose<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition<TType>): Promise<FASTElementDefinition<TType>>;\n    define(registry?: CustomElementRegistry, extensions?: FASTElementExtension[]): this;\n    readonly elementOptions: ElementDefinitionOptions;\n    static readonly getByType: (key: Function) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    static readonly getForInstance: (object: any) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    get isDefined(): boolean;\n    readonly name: string;\n    readonly propertyLookup: Record<string, AttributeDefinition>;\n    // @internal\n    static registerBaseType(type: Function): void;\n    readonly registry: CustomElementRegistry;\n    schema?: Schema;\n    shadowOptions?: ShadowRootOptions;\n    readonly styles?: ElementStyles;\n    template?: ElementViewTemplate<InstanceType<TType>>;\n    readonly type: TType;\n}\n\n// @public\nexport type FASTElementExtension = (definition: FASTElementDefinition) => void;\n\n// @public\nexport type FASTElementTemplateResolver<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> = (definition: FASTElementDefinition<TType>) => ElementViewTemplate<InstanceType<TType>> | Promise<ElementViewTemplate<InstanceType<TType>>>;\n\n// @public\nexport interface HTMLTemplateCompilationResult<TSource = any, TParent = any> {\n    createView(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    // Warning: (ae-forgotten-export) The symbol \"CompiledViewBehaviorFactory\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    readonly factories: CompiledViewBehaviorFactory[];\n}\n\n// Warning: (ae-forgotten-export) The symbol \"DefaultExecutionContext\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"SyntheticView\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"ExecutionContext\" needs to be exported by the entry point index.d.ts\n//\n// @public\nexport class HTMLView<TSource = any, TParent = any> extends DefaultExecutionContext<TParent> implements ElementView<TSource, TParent>, SyntheticView<TSource, TParent>, ExecutionContext<TParent> {\n    constructor(fragment: DocumentFragment, factories: ReadonlyArray<CompiledViewBehaviorFactory>, targets: ViewBehaviorTargets);\n    appendTo(node: Node): void;\n    bind(source: TSource, context?: ExecutionContext<TParent>): void;\n    context: ExecutionContext<TParent>;\n    dispose(): void;\n    static disposeContiguousBatch(views: SyntheticView[]): void;\n    firstChild: Node;\n    insertBefore(node: Node): void;\n    isBound: boolean;\n    isHydrated: Promise<boolean>;\n    isPrerendered: Promise<boolean>;\n    lastChild: Node;\n    // (undocumented)\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): void;\n    }): void;\n    remove(): void;\n    // @internal\n    _skipAttrUpdates: boolean;\n    source: TSource | null;\n    readonly sourceLifetime: SourceLifetime;\n    // Warning: (ae-forgotten-export) The symbol \"ViewBehaviorTargets\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    readonly targets: ViewBehaviorTargets;\n    unbind(): void;\n}\n\n// @public\nexport interface JSONSchema extends JSONSchemaCommon {\n    // (undocumented)\n    $defs?: Record<string, JSONSchemaDefinition>;\n    // (undocumented)\n    $id: string;\n    // (undocumented)\n    $schema: string;\n}\n\n// @public\nexport interface JSONSchemaCommon {\n    $observe?: boolean;\n    // (undocumented)\n    $ref?: string;\n    // (undocumented)\n    anyOf?: Array<any>;\n    // (undocumented)\n    items?: any;\n    // (undocumented)\n    properties?: any;\n    // (undocumented)\n    type?: string;\n}\n\n// @public\nexport interface JSONSchemaDefinition extends JSONSchemaCommon {\n    // (undocumented)\n    $fast_context: string;\n    // (undocumented)\n    $fast_parent_contexts: Array<string>;\n}\n\n// @public\nexport interface PartialFASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributes?: (AttributeConfiguration | string)[];\n    readonly elementOptions?: ElementDefinitionOptions;\n    readonly name: string;\n    readonly registry?: CustomElementRegistry;\n    readonly schema?: Schema;\n    readonly shadowOptions?: Partial<ShadowRootOptions> | null;\n    readonly styles?: ComposableStyles | ComposableStyles[];\n    readonly template?: ElementViewTemplate<InstanceType<TType>> | FASTElementTemplateResolver<TType>;\n}\n\n// @public\nexport interface RegisterPathConfig {\n    // (undocumented)\n    childrenMap: ChildrenMap | null;\n    // (undocumented)\n    pathConfig: CachedPath;\n    // (undocumented)\n    rootPropertyName: string;\n}\n\n// @public\nexport interface RepeatCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"repeat\";\n}\n\n// @public\nexport interface ResolvedStringsAndValues {\n    // (undocumented)\n    strings: Array<string>;\n    // (undocumented)\n    values: Array<any>;\n}\n\n// @public\nexport class Schema {\n    constructor(name: string);\n    addPath(config: RegisterPathConfig): void;\n    getRootProperties(): IterableIterator<string>;\n    getSchema(rootPropertyName: string): JSONSchema | null;\n}\n\n// @public\nexport const schemaRegistry: CachedPathMap;\n\n// @public\nexport interface ShadowRootOptions extends ShadowRootInit {\n    // @beta\n    registry?: CustomElementRegistry;\n}\n\n// @public\nexport interface StyleStrategy {\n    addStylesTo(target: StyleTarget): void;\n    removeStylesFrom(target: StyleTarget): void;\n}\n\n// @public\nexport interface StyleTarget extends Pick<Node, \"getRootNode\"> {\n    adoptedStyleSheets?: CSSStyleSheet[];\n    append(styles: HTMLStyleElement): void;\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\n    removeChild(styles: HTMLStyleElement): void;\n}\n\n// @public\nexport interface SyntheticViewTemplate<TSource = any, TParent = any> {\n    create(): SyntheticView<TSource, TParent>;\n    inline(): CaptureType<TSource, TParent>;\n}\n\n// @public\nexport class TemplateParser {\n    createTemplate(strings: Array<string>, values: Array<any>): ViewTemplate<any, any>;\n    parse(innerHTML: string, schema: Schema): ResolvedStringsAndValues;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"Expression\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"Binding\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"HTMLDirective\" needs to be exported by the entry point index.d.ts\n//\n// @public\nexport type TemplateValue<TSource, TParent = any> = Expression<TSource, any, TParent> | Binding<TSource, any, TParent> | HTMLDirective | CaptureType<TSource, TParent>;\n\n// @public\nexport type TrustedTypesPolicy = {\n    createHTML(html: string): string;\n};\n\n// @public\nexport interface ValueConverter {\n    fromView(value: any): any;\n    toView(value: any): any;\n}\n\n// @public\nexport interface ViewBehavior<TSource = any, TParent = any> {\n    bind(controller: ViewController<TSource, TParent>): void;\n}\n\n// @public\nexport interface ViewBehaviorFactory {\n    createBehavior(): ViewBehavior;\n    id?: string;\n    policy?: DOMPolicy;\n    targetNodeId?: string;\n    targetTagName?: string | null;\n}\n\n// @public\nexport class ViewTemplate<TSource = any, TParent = any> implements ElementViewTemplate<TSource, TParent>, SyntheticViewTemplate<TSource, TParent> {\n    constructor(html: string | HTMLTemplateElement, factories?: Record<string, ViewBehaviorFactory>, policy?: DOMPolicy | undefined);\n    // @internal (undocumented)\n    compile(): HTMLTemplateCompilationResult<TSource, TParent>;\n    create(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    static create<TSource = any, TParent = any>(strings: string[], values: TemplateValue<TSource, TParent>[], policy?: DOMPolicy): ViewTemplate<TSource, TParent>;\n    readonly factories: Record<string, ViewBehaviorFactory>;\n    readonly html: string | HTMLTemplateElement;\n    inline(): CaptureType<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    withPolicy(policy: DOMPolicy): this;\n}\n\n// Warnings were encountered during analysis:\n//\n// dist/dts/templating/view.d.ts:45:9 - (ae-forgotten-export) The symbol \"ViewController\" needs to be exported by the entry point index.d.ts\n\n// (No @packageDocumentation comment for this package)\n\n```\n","isInternal":false,"tokens":3338,"sizeBytes":14531},{"name":"design.md","path":"packages/fast-element/docs/declarative/design.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/declarative/design.md","title":"Declarative Skill","category":"anthropic-skill","format":"markdown","content":"# Declarative HTML Design\n\nThis document is intended for contributors who want to understand the internal\narchitecture of the declarative runtime and schema-driven map extensions in\n`@microsoft/fast-element`. It covers the feature's purpose, core concepts, data\nflow, and its integration with the rest of `@microsoft/fast-element`.\n\n## Table of Contents\n\n1. [Overview](#overview)\n2. [Goals](#goals)\n3. [Core Concepts](#core-concepts)\n4. [Package Structure](#package-structure)\n5. [Exports and Public API](#exports-and-public-api)\n6. [Template Syntax](#template-syntax)\n7. [Data Flow](#data-flow)\n8. [Template Parsing Pipeline](#template-parsing-pipeline)\n9. [Schema and Observer Map](#schema-and-observer-map)\n10. [Lifecycle](#lifecycle)\n11. [Integration with fast-element](#integration-with-fast-element)\n12. [Hydration Model](#hydration-model)\n13. [Testing Architecture](#testing-architecture)\n14. [Further Reading](#further-reading)\n\n---\n\n## Overview\n\n`@microsoft/fast-element` lets you write FAST Web Component\ntemplates as plain HTML rather than JavaScript `html` tagged template literals.\nThe browser-side JS bundle defines FAST's internal native `<f-template>`\npublisher on demand. It parses declarative template markup at runtime and\nreturns a `ViewTemplate` to the waiting FAST element definition through the\nregistry-aware declarative template bridge.\n\n```html\n<!-- Declarative template — stack-agnostic, no JS needed to render -->\n<my-component greeting=\"Hello\">\n    <template shadowrootmode=\"open\">\n        <!--fe:b-->Hello<!--fe:/b-->\n    </template>\n</my-component>\n\n<!-- Template definition — parsed once by the browser bundle -->\n<f-template name=\"my-component\">\n    <template>{{greeting}}</template>\n</f-template>\n```\n\n---\n\n## Goals\n\n| Goal | Description |\n|---|---|\n| **Server-agnostic rendering** | Templates are plain HTML strings with no dependency on Node.js or any specific SSR framework. |\n| **Progressive enhancement** | Components can be server-rendered and then hydrated client-side without a full re-render. |\n| **FAST parity** | The declarative syntax maps 1-to-1 to FAST Element directive helpers (`repeat`, `when`, `slotted`, `children`, `ref`) exported from `@microsoft/fast-element`. |\n| **Minimal authoring overhead** | Component authors write HTML, not tagged template strings, while retaining full reactive capabilities. |\n\n---\n\n## Core Concepts\n\n### `<f-template>` — the internal template publisher\n\n`<f-template>` is an internal custom element implemented as a lightweight native\n`HTMLElement`. It is defined automatically by `declarativeTemplate()` in the same\n`CustomElementRegistry` as the FAST element definition. Consumers should not\nimport, subclass, or define the implementation directly.\n\nWhen connected to the DOM it:\n\n1. Registers itself with the declarative template bridge using its registry and\n   `name` attribute.\n2. Publishes a template when a matching FAST element definition requests one.\n3. Delegates parsing of the inner `<template>` tag to `TemplateParser`, which\n   converts declarative bindings into FAST `ViewTemplate` strings and values.\n4. Runs definition-scoped schema transforms, such as `attributeMap()` and\n   `observerMap()`, before returning the concrete `ViewTemplate`.\n\nWhen multiple connected `<f-template>` publishers share the same `name`, the\nbridge resolves pending definitions from the first connected publisher and keeps\nthe resolved template stable. Later duplicate publishers do not reassign the\ndefinition template.\n\n### `TemplateParser` — declarative HTML parser\n\nA standalone class that converts declarative HTML template markup into the\n`strings` and `values` arrays that `ViewTemplate.create()` consumes. It is used\nby the internal `<f-template>` publisher but can also be used independently for\nprogrammatic template compilation. The parsing pipeline is fully synchronous —\nno promises are allocated during template resolution. A `StringsAccumulator`\ntracks the running concatenation of preceding HTML, eliminating repeated O(N)\n`join(\"\")` calls at each binding site. `createTemplate()` lazily installs the\ndeclarative runtime's debug messages; hydration support is installed only by\n`enableHydration()`.\n\n### `Schema` — JSON schema builder\n\nBuilt during declarative template parsing, one `Schema` instance per\n`<f-template>`. Non-declarative callers can also create and attach a `Schema`\nmanually. It records every binding path discovered in the template or supplied\nby code and constructs a JSON Schema-compatible data structure. This schema:\n\n- Describes the shape of each root property referenced in the template.\n- Tracks repeat context chains (parent/child array relationships).\n- Uses an instance-level `schemaMap` for its own property schemas.\n- Registers itself in the module-level `schemaRegistry` (keyed by custom element name) for cross-element `$ref` resolution.\n\n`FASTElementDefinition.schema` is optional. `declarativeTemplate()` assigns it\nautomatically after parsing; manual schema users can pass `schema` in the\ndefinition object.\n\n### `ObserverMap` — automatic observable setup\n\nAn optional layer that uses the `Schema` to automatically:\n\n- Call `Observable.defineProperty()` for every root property on the element prototype.\n- Install property-change handlers that wrap newly assigned objects/arrays in `Proxy` instances.\n- Propagate deep property mutations back through FAST's observable system so bindings re-render.\n\nEnabled via the `observerMap()` definition extension exported from\n`@microsoft/fast-element/observer-map.js`. Calling `observerMap()` without\narguments observes all root properties discovered in the template or supplied\nschema.\n\n#### Path-level observation control\n\nThe `ObserverMapConfig` interface accepts an optional `schema` for\nnon-declarative/manual schema use and an optional `properties` key that maps\nroot property names to a recursive path tree controlling observation\ngranularity:\n\n```typescript\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [\n        observerMap({\n            properties: {\n                user: {\n                    name: true,          // user.name — observed\n                    details: {\n                        age: true,       // user.details.age — observed\n                        history: false,  // user.details.history — NOT observed\n                    },\n                },\n                // root properties not listed here are skipped\n            },\n        }),\n    ],\n);\n```\n\nEach path entry can be:\n- **`true`** — observe this path and all descendants (unless overridden deeper).\n- **`false`** — skip this path and all descendants (unless overridden deeper).\n- **`ObserverMapPathNode`** — an object with an optional `$observe` boolean and child property overrides, allowing alternating opt-in/opt-out to arbitrary depth.\n\nWhen `properties` is omitted, all root properties are observed. When\n`properties` is present but empty (`{ properties: {} }`), no root properties\nare observed.\n\nObserver-map-managed array updates replace the array reference when `deepMerge`\nreceives a new array. This avoids mutating an existing observed array while it\nmay be notifying subscribers and lets repeat bindings observe the new array\nreference. Replaced arrays are wrapped with the schema for the assigned\nproperty, and array observer subscriptions are installed once per array so\nreprocessing does not duplicate accessors or notification work.\n\nFor non-declarative elements, pass a schema directly to `observerMap()`:\n\n```typescript\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-element\");\nschema.addPath({\n    rootPropertyName: \"user\",\n    pathConfig: {\n        type: \"default\",\n        parentContext: null,\n        currentContext: null,\n        path: \"user.name\",\n    },\n    childrenMap: null,\n});\n\nMyElement.define({ name: \"my-element\" }, [observerMap({ schema })]);\n```\n\nThe resolution algorithm walks the schema and configuration tree in parallel:\n1. If `properties` is present and a root property is not listed, it is skipped.\n2. `true`/`false` booleans apply to the entire subtree.\n3. `$observe` on a node object controls the current level; children inherit when unspecified.\n4. Paths in the config but not in the schema are silently ignored (forward-compatible).\n\n### `AttributeMap` — automatic `@attr` definitions\n\nAn optional layer that uses the `Schema` to automatically register `@attr`-style reactive properties for every **leaf binding** in the template — i.e. simple expressions like `{{foo}}` or `id=\"{{foo-bar}}\"` that have no nested properties, no explicit type, and no child element references.\n\n- By default (`attribute-name-strategy: \"camelCase\"`), the binding key is treated as a camelCase property name and the HTML attribute name is derived by converting it to kebab-case (e.g. `{{fooBar}}` → property `fooBar`, attribute `foo-bar`). This matches the build-time `--attribute-name-strategy` option in `@microsoft/fast-build`.\n- When `attribute-name-strategy` is `\"none\"`, the **attribute name** and **property name** are both the binding key exactly as written in the template (e.g. `{{foo-bar}}` → attribute `foo-bar`, property `foo-bar`). No normalization is applied.\n- Because HTML attributes are case-insensitive, binding keys should use lowercase names (optionally dash-separated) when using the `\"none\"` strategy.\n- Properties already decorated with `@attr` or `@observable` are left untouched.\n- `FASTElementDefinition.attributeLookup` is keyed by the HTML attribute name, and `propertyLookup` is keyed by the JS property name so `attributeChangedCallback` correctly delegates to the new `AttributeDefinition`.\n\nEnabled via the `attributeMap()` definition extension exported from\n`@microsoft/fast-element/attribute-map.js`. Calling `attributeMap()` without\narguments uses the default `\"camelCase\"` strategy. To preserve binding keys\nexactly as written, pass `attributeMap({ \"attribute-name-strategy\": \"none\" })`.\nOutside declarative templates, `attributeMap()` uses the optional `schema` on the\nFAST element definition.\n\n### Syntax constants (`syntax.ts`)\n\nAll delimiters used by the parser are defined in a single `Syntax` interface and exported as named constants from `syntax.ts`. This makes the syntax pluggable and easy to audit.\n\n| Constant | Value | Use |\n|---|---|---|\n| `openExpression` / `closeExpression` | `{{` / `}}` | Default (SSR-compatible) binding |\n| `unescapedOpenExpression` / `unescapedCloseExpression` | `{{{` / `}}}` | Raw HTML binding |\n| `clientSideOpenExpression` / `clientSideCloseExpression` | `{` / `}` | Client-only (event / attribute directive) binding |\n| `repeatDirectiveOpen` / `repeatDirectiveClose` | `<f-repeat` / `</f-repeat>` | Repeat directive |\n| `whenDirectiveOpen` / `whenDirectiveClose` | `<f-when` / `</f-when>` | When directive |\n| `attributeDirectivePrefix` | `f-` | Attribute directive prefix |\n| `eventArgAccessor` | `$e` | DOM event argument |\n| `executionContextAccessor` | `$c` | Execution context argument |\n\n---\n\n## Package Structure\n\n```\npackages/fast-element/\n├── src/\n│   ├── components/\n│   │   ├── schema.ts          # Shared Schema class + schemaRegistry\n│   │   └── definition-schema-transforms.ts # Definition-scoped schema transform storage\n│   ├── declarative/\n│       ├── index.ts           # Public declarative entrypoint implementation\n│       ├── interfaces.ts      # Message enum (error codes)\n│       ├── debug.ts           # Human-readable declarative debug messages\n│       ├── template.ts        # declarativeTemplate(), internal <f-template> publisher, lifecycle orchestration\n│       ├── template-bridge.ts # Registry/name bridge between definitions and publishers\n│       ├── template-parser.ts # TemplateParser — converts declarative HTML to ViewTemplate strings/values\n│       ├── observer-map.ts    # observerMap() implementation\n│       ├── attribute-map.ts   # attributeMap() implementation\n│       ├── observer-map-utilities.ts # Shared observer-map helpers\n│       ├── utilities.ts       # Declarative parsing helpers\n│       └── syntax.ts          # Syntax delimiter constants\n│   └── hydration/\n│       ├── markers.ts         # Default 3.x marker reader and marker strategy contract\n│       └── markers-v2.ts      # Opt-in 2.x indexed marker reader\n├── scripts/\n│   └── declarative/           # Fixture build + webui integration scripts\n└── test/\n    └── declarative/fixtures/  # One directory per feature, each with spec + index.html + main.ts\n```\n\n### Module dependency direction\n\nThe default `declarativeTemplate()` path avoids importing optional map\nimplementations. Map helpers attach schema transforms to the definition only\nwhen the consumer passes them as define extensions.\n\n```\ndeclarative/template.ts ──imports──▶ components/definition-schema-transforms.ts (schema transform reads)\ndeclarative/template.ts ──imports──▶ components/schema.ts (Schema)\ndeclarative/attribute-map.ts ──imports──▶ components/definition-schema-transforms.ts (register attribute-map transform)\ndeclarative/observer-map.ts ──imports──▶ components/definition-schema-transforms.ts (register observer-map transform)\ndeclarative/observer-map.ts ──imports──▶ components/schema.ts (Schema types)\ndeclarative/attribute-map.ts ──imports──▶ components/schema.ts (Schema types)\ndeclarative/utilities.ts ──imports──▶ components/schema.ts (schemaRegistry for cross-element $ref resolution)\n```\n\nSchema transforms run in deterministic order. `attributeMap()` runs before\n`observerMap()`, so generated attributes are available to observer mapping.\n\n---\n\n## Exports and Public API\n\n```typescript\nimport {\n    declarativeTemplate,\n    TemplateParser,\n    type ResolvedStringsAndValues,\n} from \"@microsoft/fast-element/declarative.js\";\nimport {\n    Schema,\n    schemaRegistry,\n    type CachedPathMap,\n    type JSONSchema,\n} from \"@microsoft/fast-element/schema.js\";\nimport { type FASTElementExtension } from \"@microsoft/fast-element\";\nimport {\n    attributeMap,\n    type AttributeMapConfig,\n} from \"@microsoft/fast-element/attribute-map.js\";\nimport {\n    observerMap,\n    type ObserverMapConfig,\n    type ObserverMapPathEntry,\n    type ObserverMapPathNode,\n} from \"@microsoft/fast-element/observer-map.js\";\n```\n\nDeclarative template helpers, map helpers, and their configuration types are\navailable from focused path exports.\n\nPrimary declarative exports intended for application code:\n\n| Export | Purpose |\n|---|---|\n| `declarativeTemplate()` | `@microsoft/fast-element/declarative.js` template resolver for subclass `define()` calls; auto-defines the internal `<f-template>` publisher and waits for the matching template. |\n| `TemplateParser` | `@microsoft/fast-element/declarative.js` standalone parser that converts declarative HTML into `ViewTemplate` strings/values. Can be used independently of `<f-template>` for programmatic template compilation. |\n| `Schema` | `@microsoft/fast-element/schema.js` JSON schema builder that records binding paths discovered during template parsing. Each instance owns its own schema map and registers itself in the `schemaRegistry` for cross-element `$ref` resolution. |\n| `schemaRegistry` | `@microsoft/fast-element/schema.js` module-level `Map<string, Map<string, JSONSchema>>` that indexes schemas by custom element name. Used for cross-element lookups (e.g. nested component `$ref` resolution). |\n\nHydration marker selection is available from\n`@microsoft/fast-element/hydration.js`. FAST Element 3.x data-free markers are\nthe default; `enableHydration({ markers: markers_v2 })` opts into the FAST Element 2.x\nindexed marker reader for staged server/client migrations.\n\nPrimary map extension exports:\n\n| Export | Import path | Purpose |\n|---|---|---|\n| `attributeMap()` | `@microsoft/fast-element/attribute-map.js` | Define extension that registers `@attr`-style properties for leaf bindings discovered during parsing or supplied by `definition.schema`. |\n| `observerMap()` | `@microsoft/fast-element/observer-map.js` | Define extension that defines observable root properties and proxy-based deep change tracking from `config.schema`, `definition.schema`, or a declarative template schema. |\n\nThe implementation element class (`<f-template>`), `TemplateElement.config()`,\n`TemplateElement.options()`, `ElementOptions*`, and\n`HydrationLifecycleCallbacks` are not exported from the public declarative\nentrypoint. Use `declarativeTemplate()`, `attributeMap()`, `observerMap()`, and\n`enableHydration()` instead. The `AttributeMap` and `ObserverMap` implementation\nclasses are available for advanced scenarios, but application code should\nnormally use the extension factories.\n\nAdditionally, `@microsoft/fast-element` exports these types:\n\n| Type | Source Module | Purpose |\n|---|---|---|\n| `FASTElementExtension` | `fast-definitions.ts` | Definition extension callback signature used by `attributeMap()` and `observerMap()`. |\n| `JSONSchema` | `components/schema.ts` | JSON Schema interface used by `Schema` for property structure. |\n| `CachedPathMap` | `components/schema.ts` | `Map<string, Map<string, JSONSchema>>` — the shape of the schema registry. |\n\nThe map configuration types are exported from the same map-specific paths:\n\n| Type | Import path | Purpose |\n|---|---|---|\n| `ObserverMapConfig` | `@microsoft/fast-element/observer-map.js` | Configuration object for `observerMap()`; accepts optional `schema` and `properties` keys. |\n| `ObserverMapPathEntry` | `@microsoft/fast-element/observer-map.js` | `boolean \\| ObserverMapPathNode` — a node in the observation path tree. |\n| `ObserverMapPathNode` | `@microsoft/fast-element/observer-map.js` | Object node with optional `$observe` and child property overrides. |\n| `AttributeMapConfig` | `@microsoft/fast-element/attribute-map.js` | Configuration object for `attributeMap()`; accepts `attribute-name-strategy`. |\n\n---\n\n## Template Syntax\n\nThe declarative syntax is a superset of HTML with three binding delimiters:\n\n| Syntax | Example | Behaviour |\n|---|---|---|\n| `{{expr}}` | `{{greeting}}` | SSR-compatible content / attribute binding |\n| `{{{expr}}}` | `{{{rawHtml}}}` | Unescaped HTML (wraps in `<div :innerHTML>`) |\n| `{expr}` | `@click=\"{handleClick($e)}\"` | Client-only binding (events, attribute directives) |\n\n### Directives\n\nBindings and FAST directive markup inside HTML comments are unsupported. The\nstring-based parsers do not reliably exclude comment contents, so commenting out\nbound markup can still affect binding discovery and hydration. See the\n[HTML comment restrictions](./syntax.md#html-comments).\n\n| Directive | Example |\n|---|---|\n| `<f-when value=\"{{expr}}\">` | Conditional rendering |\n| `<f-repeat value=\"{{item in list}}\">` | List rendering |\n| `f-slotted=\"{prop}\"` | Slotted nodes attribute directive |\n| `f-children=\"{prop}\"` | Children attribute directive |\n| `f-ref=\"{prop}\"` | Element ref attribute directive |\n\nFor full syntax reference see [syntax.md](./syntax.md).\n\n---\n\n## Data Flow\n\nThe high-level data flow from authoring to interactive component:\n\n```mermaid\nflowchart TD\n    A[\"Author writes declarative HTML\nusing f-template with binding expressions\"] --> B[\"Server renders hydratable HTML\nwith fe:b comments and data-fe attributes\"]\n    B --> C[Browser loads JS bundle]\n    C --> D[\"MyElement.define called\nwith template: declarativeTemplate()\"]\n    D --> E[\"declarativeTemplate() defines internal f-template\nin the target registry\"]\n    E --> F[\"f-template connects to DOM\n→ registers publisher with bridge\"]\n    F --> G[\"definition requests template\nvia registry + name bridge\"]\n    G --> H[transformInnerHTML normalises HTML entities]\n    H --> I[\"TemplateParser parses bindings/directives\nbuilds Schema, strings, values\"]\n    I --> J[\"Run definition schema transforms\nattributeMap before observerMap\"]\n    J --> K[\"ViewTemplate.create(strings, values)\nreturned to definition\"]\n    K --> L[\"FASTElementDefinition.define\nregisters element with platform\"]\n    L --> M{\"enableHydration() called?\"}\n    M -- yes --> N[\"ElementController hydrates existing DOM\nvia template.hydrate()\"]\n    M -- no --> O[\"ElementController client-side renders\nexisting DSD is not reused\"]\n    N --> P[Interactive component]\n    O --> P\n```\n\n---\n\n## Template Parsing Pipeline\n\nThe internal `<f-template>` publisher orchestrates the pipeline by creating a\n`TemplateParser` instance and delegating all parsing logic to it. The recursive\nparsing context is encapsulated in a `TemplateResolutionContext` object internal\nto the parser, keeping method signatures lean.\n\n### Architecture\n\nThe parsing pipeline is split across two classes plus definition-scoped\ntransforms:\n\n- **Internal `<f-template>` publisher** (`template.ts`) — Custom element\n  lifecycle, registry/name bridge registration, template publication, and\n  schema-transform execution. It is a native `HTMLElement`, not a `FASTElement`.\n- **`TemplateParser`** (`template-parser.ts`) — Synchronous template parser:\n  converts declarative HTML into `strings`/`values` arrays for\n  `ViewTemplate.create()`. Uses a `StringsAccumulator` to track the running\n  previous-string in O(1) per binding site instead of O(N) `join(\"\")` calls.\n  Independently testable without DOM.\n- **Schema transforms** (`definition-options.ts`) — Extension-provided callbacks run\n  after parsing and before `ViewTemplate.create()`. `attributeMap()` runs before\n  `observerMap()`.\n\n```mermaid\nsequenceDiagram\n    participant DOM\n    participant FTE as internal f-template\n    participant TP as TemplateParser\n    participant U as utilities.ts\n    participant S as Schema\n    participant Transforms as schema transforms\n\n    DOM->>FTE: connectedCallback()\n    FTE->>FTE: register publisher with bridge\n    FTE->>FTE: publishTemplate(definition)\n    FTE->>S: new Schema(name)\n    FTE->>U: transformInnerHTML(this.innerHTML)\n    FTE->>TP: parser.parse(innerHTML, schema)\n    loop getNextBehavior(innerHTML)\n        TP->>U: getNextBehavior()\n        U-->>TP: DataBindingBehaviorConfig | TemplateDirectiveBehaviorConfig\n        alt content binding\n            TP->>TP: resolveContentBinding()\n            TP->>TP: resolveAccessBinding()\n            TP->>U: bindingResolver()\n            U->>S: schema.addPath()\n            U-->>TP: (x,c) => value function\n        else attribute binding\n            TP->>TP: resolveAttributeBinding()\n            alt event (@)\n                TP->>TP: resolveEventBinding()\n            else boolean (?)\n                TP->>U: getBooleanBinding() or resolveAccessBinding()\n            else default\n                TP->>TP: resolveAccessBinding()\n            end\n        else attributeDirective (slotted / children / ref)\n            TP->>TP: resolveAttributeDirectiveBinding()\n        else templateDirective (when / repeat)\n            TP->>TP: resolveTemplateDirective()\n            note over TP: recurses into resolveStringsAndValues\n        end\n    end\n    TP-->>FTE: { strings, values }\n    FTE->>Transforms: attributeMap(), then observerMap()\n    FTE->>TP: parser.createTemplate(strings, values)\n    FTE-->>DOM: return ViewTemplate to definition resolver\n```\n\n### TemplateParser method decomposition\n\n| Method | Visibility | Role |\n|---|---|---|\n| `parse()` | public | Entry point: parses declarative HTML into `{ strings, values }`. |\n| `createTemplate()` | public | Creates a `ViewTemplate` from resolved strings and values, lazily installing declarative debug messages. |\n| `resolveStringsAndValues()` | private | Creates `strings`/`values` arrays and delegates to `resolveInnerHTML()`. |\n| `resolveInnerHTML()` | private | Recursive HTML parser that dispatches to data binding or template directive handlers. |\n| `resolveDataBinding()` | private | Thin dispatcher that routes to `resolveContentBinding()`, `resolveAttributeBinding()`, or `resolveAttributeDirectiveBinding()`. |\n| `resolveContentBinding()` | private | Handles `{{expression}}` in text content. |\n| `resolveAttributeBinding()` | private | Handles `{{expression}}` in HTML attributes; dispatches to `resolveEventBinding()` or `resolveAccessBinding()` based on aspect. |\n| `resolveAttributeDirectiveBinding()` | private | Handles `f-children`, `f-slotted`, `f-ref` directives. |\n| `resolveAccessBinding()` | private | Shared helper for access-type bindings (content, boolean-attribute fallback, default attribute). |\n| `resolveEventBinding()` | private | Handles event bindings (`@event`), including arg parsing and owner resolution. |\n| `resolveTemplateDirective()` | private | Handles `<f-when>` and `<f-repeat>` directives. |\n| `resolveAttributeDirective()` | private | Creates FAST `children()`, `slotted()`, or `ref()` directives. |\n\n### TemplateResolutionContext\n\nThe `TemplateResolutionContext` interface (internal to `TemplateParser`) groups the stable fields that flow through the recursive parsing pipeline:\n\n```typescript\ninterface TemplateResolutionContext {\n    parentContext: string | null;  // Current repeat item alias (e.g. \"item\")\n    level: number;          // Nesting depth for repeat directives\n    schema: Schema;         // JSON schema builder for property tracking\n}\n```\n\n`rootPropertyName` is intentionally kept separate because it is selectively mutated per branch and must not leak across sibling binding resolutions.\n\n### Key parsing functions (utilities.ts)\n\n| Function | Role |\n|---|---|\n| `getNextBehavior(innerHTML)` | Top-level scanner: returns the next `DataBindingBehaviorConfig` or `TemplateDirectiveBehaviorConfig`, or `null` when done. |\n| `getNextDataBindingBehavior(innerHTML)` | Identifies whether the next binding is `{{}}`, `{{{}}}`, or `{}` and classifies it as content/attribute/attributeDirective. |\n| `getNextDirectiveBehavior(innerHTML)` | Finds the next `<f-when>` or `<f-repeat>` and its matching close tag. |\n| `bindingResolver(...)` | Builds a `(x, c) => value` closure for a given path; also calls `schema.addPath()`. |\n| `pathResolver(path, contextPath, level, schema)` | Returns a closure that traverses an object using dot-notation, handling repeat context levels. |\n| `getBooleanBinding(...)` | Returns a `(x, c) => boolean` closure for `<f-when>` expressions. |\n| `assignObservables(schema, rootSchema, data, target, rootProperty)` | Wraps objects/arrays in `Proxy` for deep observation. |\n| `deepMerge(target, source)` | Merges source into an existing proxy, preserving proxy identity and triggering observable notifications. |\n| `transformInnerHTML(html)` | Normalises HTML-encoded operator characters (`&gt;`, `&lt;`, etc.) used in `<f-when>` expressions. |\n| `escapeBracesInCodeElements(html)` | Replaces `{` / `}` characters inside every `<code>` element with `&#123;` / `&#125;` so binding-like syntax in code samples renders literally rather than being interpreted as FAST bindings. Client-side half of a two-stage escape — the brace escape mirrors the server-side pass in `microsoft-fast-build` (necessary client-side because `&#123;` / `&#125;` decode back to literal `{` / `}` in the DOM and `.innerHTML` does not re-encode them). The angle-bracket escape for FAST directive tags (`<f-when>`, `</f-when>`, `<f-repeat>`, `</f-repeat>`) inside `<code>` runs only on the server because the DOM serializer re-encodes `<` / `>` in text content automatically. Real HTML elements (`<button>`) and custom elements inside `<code>` keep their angle brackets and continue to render as live DOM elements. Modeled on Microsoft WebUI's `webui-press` markdown renderer. |\n\n### Binding classification\n\n```\ninnerHTML token\n  ├── {{{ ... }}}  → unescaped content binding  (innerHTML div)\n  ├── {{ ... }}    → default binding\n  │     ├── attr=\"{{expr}}\"    → attribute binding   (aspect: null / \":\" / \"?\")\n  │     └── {{expr}} in text  → content binding\n  └── { ... }      → client-side binding\n        ├── @event=\"{handler(...)}\"  → event binding (aspect \"@\")\n        └── f-dir=\"{prop}\"           → attribute directive binding\n```\n\n---\n\n## Schema and Observer Map\n\nThe `Schema` class accumulates all binding paths discovered during parsing into an instance-level JSON Schema map (`schemaMap`) indexed by `rootPropertyName → JSONSchema`. Each `Schema` instance also registers itself in the module-level `schemaRegistry` (keyed by custom element name) for cross-element `$ref` resolution.\n\n```mermaid\nflowchart LR\n    A[\"Template binding\\nuser.details.age\"] --> B[bindingResolver]\n    B --> C[schema.addPath\\ntype:'access'\\npath:'user.details.age'\\nrootProperty:'user']\n    C --> D[\"schema.schemaMap\\n{'user' => JSONSchema}\"]\n    C --> D2[\"schemaRegistry\\n{'my-el' => schemaMap}\"]\n    D --> E[ObserverMap.defineProperties]\n    E --> E1[\"applyConfigToSchema\\nstamps $observe: false on excluded schema nodes\"]\n    E1 --> F[Observable.defineProperty on prototype\\nfor 'user']\n    E1 --> G[install instanceResolverChanged handler]\n    G --> H[\"when user= is set:\\nassignObservables checks schema.$observe\\n→ Proxy wraps observed paths only\\ndeep mutations → Observable.notify\"]\n```\n\nFor a deep dive into the schema structure, context tracking, and proxy system\nsee\n[schema-observer-map.md](./schema-observer-map.md).\n\n### `$observe` flag on schema nodes\n\nWhen an `ObserverMapConfig` with a `properties` key is provided, `ObserverMap.defineProperties()` calls `applyConfigToSchema()` to stamp `$observe: false` on excluded schema nodes **before** the proxy system runs. This is a one-time pre-processing pass that walks the config and schema trees in parallel:\n\n- `false` in the config → `$observe: false` is stamped recursively on the node and all its descendants.\n- `$observe: false` on a config node → the schema node is stamped, and unlisted children inherit the stamp.\n- `true` in the config → no stamp needed (observed is the default).\n- Config paths not in the schema are silently ignored.\n\n**Convention: stamp-only-when-excluding.** The `$observe` flag is only ever set to `false` — it is never explicitly set to `true`. Absence of `$observe` (i.e. `undefined`) means the node is observed. This means:\n\n- When Observer Map is enabled without a `properties` tree, `applyConfigToSchema`\n  is never called and no schema nodes are mutated — zero overhead for the\n  common case.\n- The proxy system uses `isSchemaExcluded(schema)` (checks `$observe === false` with no observed descendants) as the single predicate for all skip/suppress decisions.\n- Schema nodes without `$observe` are always treated as observed.\n\n### AttributeMap and leaf bindings\n\nWhen `attributeMap()` is enabled with a declarative template, it registers a\ndefinition schema transform. With a manually supplied definition schema, it runs\nimmediately. The extension constructs an `AttributeMap` implementation and calls\n`defineProperties()`. It iterates `Schema.getRootProperties()` and skips any\nproperty whose schema entry contains `properties`, `type`, or `anyOf` — keeping\nonly plain leaf bindings. For each leaf:\n\n1. The schema key is used as the **JS property name**.\n2. The **HTML attribute name** depends on the `attribute-name-strategy`:\n   - `\"camelCase\"` (default): the attribute name is derived by converting the camelCase property name to kebab-case (e.g. `fooBar` → `foo-bar`).\n   - `\"none\"`: the attribute name equals the property name (e.g. `foo-bar` → `foo-bar`).\n3. A new `AttributeDefinition` is registered via `Observable.defineProperty`.\n4. `FASTElementDefinition.attributeLookup` is keyed by the HTML attribute name and `propertyLookup` is keyed by the JS property name so `attributeChangedCallback` can route attribute changes to the correct property.\n\nWhen using the `\"none\"` strategy, property names may contain dashes and must be\naccessed via bracket notation (e.g. `element[\"foo-bar\"]`). When using\n`\"camelCase\"`, property names are standard JS identifiers (e.g.\n`element.fooBar`).\n\nSchema transforms run in deterministic order. When both extensions are supplied,\nattribute mapping runs before observer mapping.\n\n---\n\n## Lifecycle\n\n```mermaid\nsequenceDiagram\n    participant App as Application JS\n    participant FER as FASTElementDefinition\n    participant FTE as internal f-template\n    participant EC as ElementController\n    participant Hydration as enableHydration().whenHydrated()\n\n    App->>Hydration: const hydration = enableHydration() [optional]\n    App->>FER: MyElement.define({name:'my-el', template: declarativeTemplate()}, [attributeMap(), observerMap()])\n    note over FER: definition composed; resolver waits for template\n\n    DOM->>FTE: f-template connected to DOM\n    FTE->>FTE: bridge matches registry + name\n    FTE->>FTE: parse template → schema → transforms → ViewTemplate\n    FTE->>FER: return viewTemplate to resolver\n    FER->>FER: customElements.define('my-el', MyElement)\n\n    DOM->>EC: element instance connects with existing shadow root\n    EC->>EC: isPrerendered = true (existing shadow root detected)\n    alt enableHydration() was called\n        EC->>EC: template.hydrate() — maps existing DOM to binding targets\n        EC->>Hydration: resolve active batch when all pending elements finish\n    else hydration not enabled\n        EC->>EC: client-side render; isHydrated = false\n    end\n```\n\n### Promise readiness reference\n\n| Promise | Import path | Resolves when |\n|---|---|---|\n| `enableHydration().whenHydrated(\"my-element\")` | `@microsoft/fast-element/hydration.js` | Hydration work for that tag name completes. |\n| `enableHydration().whenHydrated()` | `@microsoft/fast-element/hydration.js` | The active hydration batch completes. |\n\nBy default, hydration no-ops for later prerendered batches after the initial\nbatch completes. Set\n`enableHydration({ stopHydration: StopHydration.never })` when Declarative Shadow\nDOM may be streamed into the page after the initial hydration batch. In that\nmode, `enableHydration().whenHydrated()` intentionally remains pending because\nthere is no global completion point.\n\nFor usage examples see\n[lifecycle.md](./lifecycle.md).\n\n---\n\n## Integration with fast-element\n\nThe declarative runtime is a thin orchestration layer on top of\n`@microsoft/fast-element`. It does not re-implement any reactive primitives; it\nconverts declarative HTML syntax into the same data structures that `html`\ntagged templates produce.\n\n| fast-element primitive | How the declarative runtime uses it |\n|---|---|\n| `FASTElement` | Base class for user components; the internal `<f-template>` publisher is a native `HTMLElement` |\n| `FASTElementDefinition.register()` / template resolvers | Deferred element registration — element waits for its template |\n| `FASTElementDefinition.schema` | Optional schema used by schema-driven extensions; assigned automatically by `declarativeTemplate()` and available for manual schemas |\n| `FASTElementExtension` | Extension callback mechanism used by `attributeMap()` and `observerMap()` to attach schema transforms before template resolution or consume manually supplied schemas |\n| `ViewTemplate.create(strings, values)` | Compiles the resolved strings/values arrays into a `ViewTemplate` |\n| `ElementController` | Automatically detects prerendered content (`isPrerendered`) and hydrates server-rendered DOM using `fe-b` comment/dataset markers via `template.hydrate()` |\n| `Observable.defineProperty()` | Defines observable root properties on element prototypes (ObserverMap) |\n| `Observable.getNotifier()` | Triggers change notifications from proxy handlers |\n| `when(expr, template)` | FAST directive used for `<f-when>` |\n| `repeat(expr, template)` | FAST directive used for `<f-repeat>` |\n| `slotted(options)` | FAST directive used for `f-slotted` |\n| `children(prop)` | FAST directive used for `f-children` |\n| `ref(prop)` | FAST directive used for `f-ref` |\n\n### Deferred template attachment via define\n\nStandard subclass `define()` calls return a `Promise` that resolves immediately when a concrete template is provided at definition time. When `template: declarativeTemplate()` is used, the `Promise` resolves after the matching `<f-template>` supplies a concrete template through the bridge. This unified API replaces the previous `defineAsync()` / `composeAsync()` methods.\n\n---\n\n## Hydration Model\n\nWhen declarative templates are used, the server must render:\n\n1. The custom element tag with its attributes and initial state.\n2. A `<template shadowrootmode=\"open\">` containing pre-rendered HTML annotated with FAST's hydration markers.\n3. An `<f-template>` element somewhere in the page that carries the template definition.\n\nWith `declarativeTemplate()`, connection gating happens before platform registration: the resolver waits for the matching `<f-template>` and keeps the definition concrete before elements can connect. Hydration can therefore start immediately when `ElementController.connect()` runs. The `defer-hydration` and `needs-hydration` attributes are no longer needed in server-rendered markup.\n\n### Hydration marker formats\n\n`enableHydration()` uses the FAST Element 3.x data-free marker reader by\ndefault. The marker strategy is shared by target discovery and nested repeat\nhydration so a view uses one consistent format throughout its hydration walk.\nThe optional `markers_v2` strategy contains the legacy indexed-marker parsing logic and\nis selected with `enableHydration({ markers: markers_v2 })`.\n\n**Content bindings** use HTML comments (data-free, matched by string equality):\n\n```\n<!--fe:b-->\n<!--fe:/b-->\n```\n\n**Attribute bindings** use a single `data-fe` dataset attribute with binding count:\n\n```html\n<el data-fe=\"3\">\n```\n\n**Repeat directives** wrap each item in comment pairs:\n```\n<!--fe:r-->\n...item DOM...\n<!--fe:/r-->\n```\n\nFor detailed examples see\n[rendering.md](./rendering.md).\n\n---\n\n## Testing Architecture\n\nEach feature is verified by a **Playwright** integration test against a live\nVite dev server. The `test/declarative/fixtures/` directory contains one\nsubdirectory per feature:\n\n```\ntest/declarative/fixtures/<feature>/\n├── <feature>.spec.ts        # Playwright test\n├── entry.html               # Entry template with root custom elements\n├── fast-build.config.json   # Build configuration for @microsoft/fast-build\n├── index.html               # Pre-rendered page (GENERATED by scripts/declarative/build-fixtures.js — do not edit)\n├── main.ts                  # Component definitions, declarativeTemplate(), extensions, and enableHydration() setup\n├── state.json               # Initial state for server-side rendering\n└── templates.html           # Declarative <f-template> definitions\n```\n\nFixtures are auto-discovered by scanning for directories that contain `entry.html`, `templates.html`, `state.json`, and `fast-build.config.json`. Both the build script and the Vite config pick up new fixtures automatically — no registration step is needed.\n\nFor fixtures that use SSR-style pre-rendered HTML,\n`scripts/declarative/build-fixtures.js` invokes `@microsoft/fast-build` with\n`--config` pointing to each fixture's `fast-build.config.json` to generate\n`index.html` from the configured source files.\n\n### WebUI Integration Tests\n\nA separate integration test suite validates that `@microsoft/webui` can build and render the same fixture templates that `@microsoft/fast-build` processes. This is split into two steps:\n\n1. **Build** (`npm run build:fixtures:webui`) — runs\n   `scripts/declarative/build-fixtures-with-webui.js`, which extracts\n   `<f-template>` elements, converts each component template with\n   `fast convert --syntax=webui-prerelease`, builds each fixture with\n   `webui build --plugin=fast`, renders the protocol with `state.json`, and\n   writes the output alongside `main.ts` and assets to\n   `temp/integrations/webui/fixtures/`.\n2. **Test** (`npm run test:webui-integration`) — builds the fixtures, then runs\n   the same Playwright specs against the webui-rendered output served by a Vite\n   dev server on port 5174 (configured in\n   `playwright.declarative.webui.config.ts`).\n\nFixtures that intentionally contain invalid FAST declarative templates are skipped in\nthe WebUI build because `fast convert` validates and rejects them before WebUI\nrenders. Run locally with `npm run test:webui-integration` or via the\n`ci-webui-integration.yml` GitHub Action on PRs and pushes to `main`.\n\n#### Skipped tests\n\nSome tests are conditionally skipped when running under the webui integration\nconfig. The `playwright.declarative.webui.config.ts` file sets\n`process.env.FAST_WEBUI_INTEGRATION = \"true\"`, and individual tests check this\nvariable with `test.skip()` to opt out of cases that exercise known differences\nbetween `fast-build` and `webui` rendering:\n\n- **`errors.spec.ts` — \"throws an error when no template element is present\"**: webui does not render `<f-template>` elements that lack a `<template>` child, so the expected error is never thrown.\n\n### Hydration readiness\n\nFixtures that exercise prerendered output wait for hydration to complete before\nrunning assertions. Each `main.ts` calls `enableHydration()` and then awaits\nthe returned controller's `whenHydrated()` promise to set a global flag, and each spec file calls\n`page.waitForFunction()` after `page.goto()` to block until the flag is set.\nSee [test/declarative/fixtures/README.md](../../test/declarative/fixtures/README.md)\nfor the implementation pattern.\n\nSee\n[test/declarative/fixtures/WRITING_FIXTURES.md](../../test/declarative/fixtures/WRITING_FIXTURES.md)\nfor the complete fixture authoring guide,\n[test/declarative/fixtures/README.md](../../test/declarative/fixtures/README.md)\nfor a quick reference, and\n[test/declarative/fixtures/extensions/observer-map-deep-merge/README.md](../../test/declarative/fixtures/extensions/observer-map-deep-merge/README.md)\nfor an example of a complex multi-feature fixture.\n\n---\n\n## Further Reading\n\n| Document | Topic |\n|---|---|\n| [syntax.md](./syntax.md) | Installation, syntax reference, hydration promises, usage examples |\n| [rendering.md](./rendering.md) | Hydratable HTML format: comment markers, dataset attributes, directive markers |\n| [lifecycle.md](./lifecycle.md) | Phase-by-phase rendering lifecycle, hydration readiness, performance notes |\n| [schema-observer-map.md](./schema-observer-map.md) | Deep dive into Schema JSON structure, ObserverMap proxy system, debugging |\n| [test/declarative/fixtures/README.md](../../test/declarative/fixtures/README.md) | Quick reference for fixture structure |\n| [test/declarative/fixtures/WRITING_FIXTURES.md](../../test/declarative/fixtures/WRITING_FIXTURES.md) | Complete guide to writing new Playwright fixture tests |\n| [test/declarative/fixtures/extensions/observer-map-deep-merge/README.md](../../test/declarative/fixtures/extensions/observer-map-deep-merge/README.md) | Complex deep-merge fixture: observable arrays, nested repeats, conditionals |\n","isInternal":false,"tokens":9594,"sizeBytes":43171},{"name":"lifecycle.md","path":"packages/fast-element/docs/declarative/lifecycle.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/declarative/lifecycle.md","title":"Declarative Skill","category":"anthropic-skill","format":"markdown","content":"# Rendering Lifecycle\n\nThis document describes the declarative rendering lifecycle inside\n`@microsoft/fast-element`.\n\n## Overview\n\nThe FAST Element rendering lifecycle involves a coordinated process between the\ncore runtime and its declarative entrypoint:\n\n- **`@microsoft/fast-element`**: Provides the core `FASTElement` base class and\n  element definition system.\n- **`@microsoft/fast-element/declarative.js`**: Provides the `f-template`\n  custom element that processes HTML templates and attaches them to FAST\n  elements as a `ViewTemplate` in lieu of an `html` template created during\n  a subclass `define()` call. The preferred path uses `declarativeTemplate()` so\n  the subclass `define()` call waits for the matching declarative template and keeps\n  the definition concrete before registration completes.\n\n## Lifecycle Phases\n\nGiven a DOM which includes an `f-template` and a component:\n\n```html\n<my-component text=\"Hello World\">\n    <template shadowrootmode=\"open\">\n        <h1><!--fe:b-->Hello World<!--fe:/b--></h1>\n    </template>\n</my-component>\n\n<f-template name=\"my-component\">\n    <template>\n        <h1>{{text}}</h1>\n    </template>\n</f-template>\n```\n\nThe following phases will then be kicked off once the JavaScript is parsed.\n\n### Phase 1: Definition Resolution\n\nCustom elements begin their lifecycle by composing a definition that points at\n`declarativeTemplate()`. The resolver waits for a matching declarative template\nand returns a concrete `ViewTemplate` before the platform registration step.\n\n```typescript\n// Custom element class definition\nclass MyComponent extends FASTElement {\n    @attr text: string = \"\";\n}\n\n// Register with the declarative template bridge\nMyComponent.define({\n    name: \"my-component\",\n    template: declarativeTemplate(),\n});\n```\n\nKey characteristics of this phase:\n- The element definition stays unresolved until a matching declarative template is available\n- The resolved template is concrete before platform registration completes\n\n### Phase 2: Declarative Template Bridge\n\n`declarativeTemplate()` from `@microsoft/fast-element/declarative.js`\nautomatically ensures that `f-template` is defined in the same registry as the\nFAST element being composed.\n\n### Phase 3: Template Processing and Attachment\n\nWhen an `f-template` element is connected to the DOM, it initiates the template attachment process.\n\nThe lifecycle flow during this phase:\n\n1. **Template Discovery**: The resolver waits for a matching\n   `<f-template name=\"...\">` in the same registry as the element definition.\n2. **Template Element Connection**: The matching `f-template` element's\n   `connectedCallback()` registers it with the declarative template bridge.\n3. **Template Processing**: The bridge reads and transforms the markup, builds\n   the schema, applies `observerMap()` / `attributeMap()` behavior, and resolves\n   data bindings, directives, and other template features into the `ViewTemplate`\n   model which is also used by the `@microsoft/fast-element` `html` tag template.\n4. **Template Attachment**: The concrete `ViewTemplate` is returned to\n   the subclass `define()` call, which assigns it to the definition before platform\n   registration completes.\n\n### Phase 4: Composition Completion\n\nOnce the template is attached to the partial definition, the element completes its composition:\n\n1. **`compose()` Execution**: The element definition internally completes its composition process\n2. **Platform Registration**: The completed element definition is fully registered with the platform's custom element registry\n\n### Phase 5: Element Instantiation and Hydration\n\nWhen custom elements are instantiated in the DOM, the following occurs:\n\n1. **Element Creation**: The platform creates instances of the custom element\n2. **Prerendered Content Detection**: `ElementController` detects the existing shadow root from SSR — `isPrerendered` resolves `true`\n3. **Hydration Check**: If `enableHydration()` was called and the template is hydratable, the element hydrates — `isHydrated` resolves `true`. Otherwise it falls back to client-side rendering.\n4. **Concrete Template Ready**: Because `declarativeTemplate()` resolved during\n   definition, `connect()` starts with the final template already attached.\n5. **Hydration**: `ElementController` uses `template.hydrate()` to create a\n   `HydrationView` that maps existing DOM nodes to binding targets using `fe:b`\n   / `fe:/b` markers\n\nThe DOM after hydration should look like this:\n\n```html\n<my-component text=\"Hello World\">\n    <template shadowrootmode=\"open\">\n        <h1><!---->Hello World<!----></h1>\n    </template>\n</my-component>\n```\n\n## Key Integration Points\n\n### Fast Element Registry\n\nThe `fastElementRegistry` serves as the central coordination point between the\ntwo packages and is available to consumers from\n`@microsoft/fast-element/registry.js`:\n\n- Stores partial element definitions created by `define()`\n- Provides lookup mechanism via `register()` for template attachment\n- Resolves `fastElementRegistry.whenRegistered(tagName)` when a matching\n  definition is registered\n- Maintains the registry of all FAST element definitions\n\n### Observable Pattern\n\nBoth packages use the Observable pattern for coordination:\n\n- Element definition template assignment notifies observers that are waiting for a concrete template\n- Template attachment triggers observable notifications to complete the lifecycle\n\n## Error Handling\n\nThe lifecycle includes error handling for missing components:\n\n- Template elements throw errors if no corresponding element definition is found\n- Element definitions can exist without templates (partial state)\n\n## Performance Considerations\n\nThe asynchronous nature of the lifecycle provides several performance benefits:\n\n- **Progressive Enhancement**: Elements can be registered before templates are loaded\n- **Code Splitting**: Templates can be loaded separately from element definitions  \n- **Reduced Blocking**: Template processing doesn't block element registration\n- **Hydration Optimization**: Server-side rendered content can be hydrated efficiently\n\nThis coordinated lifecycle enables powerful scenarios like server-side rendering, progressive enhancement, and dynamic template loading while maintaining the reactive capabilities of FAST Element.\n\n## Hydration promise APIs\n\nFAST Element exposes promises for hydration readiness points that are useful to\napplication code.\n\nHydration must be explicitly opted into by calling `enableHydration()`. Await\nthe returned controller's `whenHydrated()` promise when code needs to run after\nthe active hydration batch completes. Pass a tag name to `whenHydrated(tagName)`\nwhen code needs to wait for a specific FAST element.\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nconst hydration = enableHydration();\nawait hydration.whenHydrated(\"my-component\");\nawait hydration.whenHydrated();\n```\n\nBy default, hydration no-ops for later prerendered batches after the initial\nbatch completes. Set `stopHydration: StopHydration.never` in\n`enableHydration()` when streaming Declarative Shadow DOM should continue\nhydrating after the initial batch. In that mode, `hydration.whenHydrated()`\nintentionally remains pending because hydration has no global completion point.\n","isInternal":false,"tokens":1481,"sizeBytes":7267},{"name":"rendering.md","path":"packages/fast-element/docs/declarative/rendering.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/declarative/rendering.md","title":"Declarative Skill","category":"anthropic-skill","format":"markdown","content":"# Non-browser HTML rendering\n\n1. [Initial State](#initial-state)\n2. [Hydrating Comments and Datasets](#hydration-comments-and-datasets)\n\nThis document details information on rendering hydratable content and includes some pointers on how Dependency Injection can be used to create services that hydrate a custom elements state. Non-browser rendering in this context means producing HTML that a browser can parse and hydrate later; it does not mean running the FAST Element client runtime in a worker, server-side JavaScript runtime, or other non-window host.\n\n## Initial State\n\nTo create initial state this should be added somewhere accessible by your service, in this example a `<script>` tag can be used to provide a global initial state.\n\nExample:\n```html\n<script>\n    window.__INITIAL_STATE__ = {\n        text: \"Hello world\"\n    }\n</script>\n```\n\nAdd a Dependency Injection service in your bundle to access properties in your state.\n\nSimple example (`initial-state.ts`):\n```typescript\nimport { DI } from \"@microsoft/fast-element/di.js\";\n\ninterface InitialState {\n    text: string;\n}\n\nexport interface IInitialStateService {\n  init(): InitialState;\n}\n\nexport class InitialStateService implements IInitialStateService {\n    private initialState: any;\n\n    constructor() {\n        this.initialState = window.__INITIAL_STATE__;\n    }\n\n    public init(...keys: Array<string>): InitialState {\n        const config: any = {};\n\n        for (let key of keys) {\n            config[key] = this.initialState[key];\n        }\n\n        return config;\n    }\n}\n\nexport const initialStateFactory = DI.createContext<IInitialStateService>(\n  'i-initial-state-service',\n  (x) => x.singleton(InitialStateService)\n);\n```\n\nInclude the DI service to your component.\n\nExample:\n```typescript\nimport { attr, FASTElement, Observable } from \"@microsoft/fast-element\";\nimport {\n    initialStateFactory,\n    InitialStateService,\n    type IInitialStateService,\n} from \"./initial-state.js\";\nimport { inject } from \"@microsoft/fast-element/di.js\";\n\nexport class MyComponent extends FASTElement {\n    @inject(initialStateFactory) initialStateService!: InitialStateService;\n\n    @attr\n    text: string = \"\";\n\n    service!: IInitialStateService;\n\n    connectedCallback() {\n        super.connectedCallback();\n\n        this.loadItemFromInitialState();\n    }\n\n    loadItemFromInitialState(): void {\n        const initialState = this.initialStateService.init([\"text\"]);\n\n        this.text = initialState.text;\n    }\n}\n\nMyComponent.define({\n    name: \"my-component\",\n    template: declarativeTemplate(),\n});\n```\n\nWhen the element connects, `ElementController` automatically detects the\nexisting shadow root from SSR and sets `isPrerendered = true`.\n`declarativeTemplate()` keeps the definition template concrete before\nregistration completes, so the element can hydrate the prerendered shadow root\nimmediately. The `defer-hydration` and `needs-hydration` attributes are no\nlonger needed.\n\n## Hydration Comments and Datasets\n\nWhen hydrating the HTML, FAST uses `ElementController` which detects an\nexisting shadow root (from SSR or declarative shadow DOM) and sets\n`isPrerendered = true`. It then uses `template.hydrate()` to create a\n`HydrationView` that maps existing DOM nodes to binding targets using hydration\n\"markers\" such as comments and dataset attributes. By default the declarative\nruntime in `@microsoft/fast-element` assumes component hydration will occur, so\nrendering hydratable markup is required.\n\n### Bindings\n\n#### Content Bindings\n\nContent binding markers are represented using HTML comments. These comments are used to indicate where dynamic content exists in the template. Markers carry no embedded data — they are fixed strings matched by string equality (not regex).\n\n* Start binding: `<!--fe:b-->`\n* End binding: `<!--fe:/b-->`\n\nBinding pairs are matched using balanced depth counting: each start marker increments a depth counter and each end marker decrements it. When the counter returns to zero the pair is complete.\n\n##### Content Binding Marker Examples\n\n**Note**\nExamples shown below mostly skip the wrapping custom element and the internal template element with `shadowrootmode=\"open\"`.\n\nTypically along with the content from the examples below, the rendering should include:\n\n```html\n<my-component>\n    <template shadowrootmode=\"open\" shadowroot=\"open\">\n        <!-- hydratable content -->\n    </template>\n</my-component>\n```\n\n**Simple content example**\n\nContent bindings such as:\n```html\n<h1>{{text}}</h1>\n```\n\nWhen combined with state such as:\n```json\n{\n    \"text\": \"Hello world\"\n}\n```\n\nShould result in:\n```html\n<h1><!--fe:b-->Hello world<!--fe:/b--></h1>\n```\n\n#### Attribute Bindings\n\nAttribute bindings are tracked using a single dataset attribute: `data-fe=\"N\"` where `N` is the number of attribute bindings on the element.\n\n##### Examples\n\n###### Single attribute example\n\nAttribute binding such as:\n```html\n<h1 greeting=\"{{greeting}}\"></h1>\n```\n\nWhen combined with state such as:\n```json\n{\n    \"greeting\": \"Hello\"\n}\n```\n\nShould result in:\n\n```html\n<h1 data-fe=\"1\" greeting=\"Hello\"></h1>\n```\n\n###### Multiple attribute bindings\n\nWhen multiple attribute bindings exist on the same element:\n```html\n<h1 greeting=\"{{greeting}}\" subtitle=\"{{subtitle}}\" punctuation=\"{{punctuation}}\"></h1>\n```\n\nWhen combined with state such as:\n```json\n{\n    \"greeting\": \"Hello\",\n    \"subtitle\": \"world\",\n    \"punctuation\": \"!\"\n}\n```\n\nShould result in:\n\n```html\n<h1 data-fe=\"3\" greeting=\"Hello\" subtitle=\"world\" punctuation=\"!\"></h1>\n```\n\n**Mixed attribute and content example**\n\nMultiple attributes and content bindings such as:\n```html\n<div show=\"{{show}}\" appearance=\"{{appearance}}\" punctuation=\"{{punctuation}}\">\n    <h1>{{text}}</h1>\n    <span>{{subtitle}}</span>\n    <span>{{punctuation}}</span>\n</div>\n```\n\nShould result in:\n```html\n<div data-fe=\"3\" show appearance=\"large\" punctuation=\"!\">\n    <h1><!--fe:b-->Hello<!--fe:/b--></h1>\n    <span><!--fe:b-->world<!--fe:/b--></span>\n    <span><!--fe:b-->!<!--fe:/b--></span>\n</div>\n```\n\n### Directives\n\nDirectives are treated differently from bindings as they include a template. This means that in addition to the binding used to determine the logic for the directive FAST also requires a separate marker for the directive itself to demarkate the beginning and end of the template.\n\n#### Repeat\n\nExample repeat binding:\n```html\n<f-repeat value=\"{{item in list}}\">\n    <span>{{item}}</span>\n</f-repeat>\n```\n\nCombined with state:\n```json\n[\n    \"Bob\",\n    \"Alice\",\n    \"Sue\"\n]\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<!--fe:r-->\n<span>\n    <!--fe:b-->Bob<!--fe:/b-->\n</span>\n<!--fe:/r-->\n<!--fe:r-->\n<span>\n    <!--fe:b-->Alice<!--fe:/b-->\n</span>\n<!--fe:/r-->\n<!--fe:r-->\n<span>\n    <!--fe:b-->Sue<!--fe:/b-->\n</span>\n<!--fe:/r-->\n<!--fe:/b-->\n```\n\nNote that the repeat markers are data-free — they carry no index or ID. Pairing uses balanced depth counting. Additionally, a binding wraps the repeat markers; even if the array is empty, this binding must be rendered.\n\nExample result of an empty array:\n```html\n<!--fe:b-->\n<!--fe:/b-->\n```\n\n#### When\n\nThe when directive is either present in the DOM or not, and therefore does not need an extra marker for the template.\n\nExample when binding:\n```html\n<f-when value=\"{{show}}\">\n    <span>{{text}}</span>\n</f-when>\n```\n\nCombined with state:\n```json\n{\n    \"show\": true,\n    \"text\": \"Hello world\"\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<span>\n    <!--fe:b-->Hello world<!--fe:/b-->\n</span>\n<!--fe:/b-->\n```\n\nIf the when is evaluated to `falsy` then we can safely leave the binding markers only.\n\nExample state:\n```json\n{\n    \"show\": false,\n    \"text\": \"Hello world\"\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<!--fe:/b-->\n```\n\n### Host attributes from `<f-template>`\n\nBuild-time renderers (e.g. `@microsoft/fast-build`) forward attributes declared on the inner `<template>` element of an `<f-template>` onto the rendered host element opening tag.\n\nExample template:\n```html\n<f-template name=\"my-button\">\n    <template tabindex=\"0\" ?disabled=\"{{isDisabled}}\">\n        <button><slot></slot></button>\n    </template>\n</f-template>\n```\n\nCombined with author HTML `<my-button></my-button>` and state:\n```json\n{\n    \"isDisabled\": true\n}\n```\n\nShould result in:\n```html\n<my-button tabindex=\"0\" disabled defer-hydration needs-hydration>\n    <template shadowrootmode=\"open\" shadowroot=\"open\">\n        <button><slot></slot></button>\n    </template>\n</my-button>\n```\n\nRules:\n- Client-only attributes (`@event`, `:prop`, `f-ref`, `f-slotted`, `f-children`) are skipped — they have no meaning on a server-rendered host element.\n- Author attributes on the host element always win on conflicts (case-insensitive name match; the dedupe key for `?name=\"{{expr}}\"` is the bare `name`).\n- Static `name=\"value\"` is forwarded verbatim (HTML-escaped); static boolean `name` is emitted bare.\n- `name=\"{{expr}}\"` is resolved against the element's initial child state; primitives are emitted as `name=\"value\"`, `Array` / `Object` / `Null` and missing values are stripped.\n- `?name=\"{{expr}}\"` is evaluated as a boolean against the same state; the bare `name` (without `?`) is emitted when truthy and skipped when falsy.\n\n### Client Side Bindings\n\nClient side bindings are bindings which the client needs, but they are not necessary as part of an initial render. These must still be accounted for when creating hydration comments however, as the template needs to know which elements to attach these bindings to. There are two types of client side bindings, events and attribute directives. These do not require state as they are bound to class methods or properties.\n\n#### Event Bindings\n\nEvent bindings such as `@keydown` and `@click` can be represented with hydration comments.\n\nExample event binding:\n```html\n<button @click=\"{handleClick($e)}\">Button</button>\n```\n\nShould result in:\n```html\n<button data-fe=\"1\">Button</button>\n```\n\n#### Attribute Directives\n\nAttribute directives such as `f-slotted` and `f-ref` can be represented with hydration comments.\n\nExample `f-ref` binding:\n```html\n<button f-ref=\"{button}\">Button</button>\n```\n\nShould result in:\n```html\n<button data-fe=\"1\">Button</button>\n```\n\n#### More Examples\n\n##### Nested Whens\n\nExample when binding:\n```html\n<f-when value=\"{{show}}\">\n    <span>{{text}}</span>\n    <f-when value=\"{{showInternal}}\">\n        <span>{{internalText}}</span>\n    </f-when>\n</f-when>\n```\n\nCombined with state:\n```json\n{\n    \"show\": true,\n    \"text\": \"Hello world\",\n    \"showInternal\": true,\n    \"internalText\": \"Hello pluto\"\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<span>\n    <!--fe:b-->Hello world<!--fe:/b-->\n</span>\n    <!--fe:b-->\n    <span>\n        <!--fe:b-->Hello pluto<!--fe:/b-->\n    </span>\n    <!--fe:/b-->\n<!--fe:/b-->\n```\n\n##### Nested Repeats\n\nExample when binding:\n```html\n<f-repeat value=\"{{item in items}}\">\n    <div>\n        <span>{{item.name}}</span>\n        <f-when value=\"{{!!item.nested}}\">\n            <ul>\n                <f-repeat value=\"{{person in item.nested}}\">\n                    <li>{{person.name}}</li>\n                </f-repeat>\n            </ul>\n        </f-when>\n    </div>\n</f-repeat>\n```\n\nCombined with state:\n```json\n{\n    \"items\": [\n        {\n            \"name\": \"Bob\"\n        },\n        {\n            \"name\": \"Alice\"\n        },\n        {\n            \"name\": \"Sue\",\n            \"nested\": [\n                {\n                    \"name\": \"Amy\"\n                },\n                {\n                    \"name\": \"Clarice\"\n                },\n                {\n                    \"name\": \"Lawrence\"\n                }\n            ]\n        }\n    ]\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n    <!--fe:r-->\n    <div>\n        <span><!--fe:b-->Bob<!--fe:/b--></span>\n        <!--fe:b--><!--fe:/b-->\n    </div>\n    <!--fe:/r--><!--fe:r-->\n    <div>\n        <span><!--fe:b-->Alice<!--fe:/b--></span>\n        <!--fe:b--><!--fe:/b-->\n    </div>\n    <!--fe:/r--><!--fe:r-->\n    <div>\n        <span><!--fe:b-->Sue<!--fe:/b--></span>\n        <!--fe:b-->\n            <ul>\n                <!--fe:b-->\n                <!--fe:r-->\n                <li>\n                    <!--fe:b-->Amy<!--fe:/b-->\n                </li>\n                <!--fe:/r-->\n                <!--fe:r-->\n                <li>\n                    <!--fe:b-->Clarice<!--fe:/b-->\n                </li>\n                <!--fe:/r-->\n                <!--fe:r-->\n                <li>\n                    <!--fe:b-->Lawrence<!--fe:/b-->\n                </li>\n                <!--fe:/r-->\n                <!--fe:/b-->\n            </ul>\n        <!--fe:/b-->\n    </div>\n    <!--fe:/r-->\n<!--fe:/b-->\n```\n\n##### Nested components with `<slot>`\n\nThis example shows the wrapping custom element tag as well as the template component with `shadowrootmode=\"open\"` for the sake of illustrating an example that would exist in the DOM.\n\nExample template of component \"nested-component\":\n```html\n<f-when value=\"{{showButton}}\">\n    <my-button appearance=\"{{appearance}}\">{{text}}</my-button>\n</f-when>\n```\n\nExample template of component \"my-button\":\n```html\n<button class=\"{{appearance}}\">\n    <slot></slot>\n</button>\n```\n\nCombined with state:\n```json\n{\n    \"showButton\": true,\n    \"text\": \"Hello world\",\n    \"appearance\": \"fancy\"\n}\n```\n\nShould result in:\n```html\n<nested-components>\n    <template shadowrootmode=\"open\" shadowroot=\"open\">\n        <!--fe:b-->\n        <my-button data-fe=\"1\" appearance=\"fancy\">\n            <template shadowrootmode=\"open\" shadowroot=\"open\">\n                <button class=\"default\" data-fe=\"1\">\n                    <slot></slot>\n                </button>\n            </template>\n            <!--fe:b-->Hello world<!--fe:/b-->\n        </my-button>\n        <!--fe:/b-->\n    </template>\n</nested-components>\n```\n\n## Rendering Lifecycle\n\nFor information about the declarative rendering lifecycle inside\n`@microsoft/fast-element`, see\n[lifecycle.md](./lifecycle.md).\n","isInternal":false,"tokens":3301,"sizeBytes":13885},{"name":"schema-observer-map.md","path":"packages/fast-element/docs/declarative/schema-observer-map.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/declarative/schema-observer-map.md","title":"Declarative Skill","category":"anthropic-skill","format":"markdown","content":"# Schema and Observer Map Architecture\n\nThis document provides a technical explainer for how the `Schema` and\n`ObserverMap` classes work together to describe data objects and automatically\nobserve them in FAST elements. Declarative `<f-template>` markup creates schemas\nautomatically, but the schema and observer map implementation are factored so\nthey can also be used without declarative templating.\n\n## Table of Contents\n\n1. [Overview](#overview)\n2. [The Schema Class](#the-schema-class)\n3. [The Observer Map Class](#the-observer-map-class)\n4. [Integration with f-template](#integration-with-f-template)\n5. [Initial Path Processing Flow](#initial-path-processing-flow)\n6. [Dynamic Path Processing Updates](#dynamic-path-processing-updates)\n7. [Observable Proxy System](#observable-proxy-system)\n8. [Examples](#examples)\n9. [Technical Details](#technical-details)\n\n## Overview\n\nThe Schema and Observer Map architecture enables automatic observation of complex nested data objects in FAST HTML templates. This system solves the problem of manually tracking all the binding paths used in declarative HTML templates, automatically creating observables for nested properties that are referenced in the template bindings.\n\n**Important**: This system is designed specifically for observable data objects (objects, arrays, and primitives). It explicitly does not handle binding paths that are assumed to be functions, methods, or other non-data constructs like event handlers.\n\n### Key Components\n\n- **Schema Class**: Generates JSON schemas that describe the structure and binding paths of data objects based on template analysis or manually registered paths\n- **Observer Map Class**: Uses the schema information to automatically define observable properties and create proxies for nested object observation\n- **f-template Integration**: Template processing automatically populates schemas and configures observer maps during template compilation\n- **Map helpers**: `@microsoft/fast-element` exposes the map helpers independently from declarative templating\n\n### Supported Data Types\n\nThe system automatically handles:\n- **Objects**: Nested object structures with observable properties\n- **Arrays**: Arrays with observable mutations and nested object elements  \n- **Primitives**: String, number, boolean values as object properties\n\n### Explicitly Not Handled\n\nThe system does not process:\n- **Function bindings**: Event handlers and method calls like `@click=\"{handleClick()}\"`\n- **Context paths**: Bindings using the `$c` prefix (e.g., `$c.parent.showNames`) resolve directly from the `ExecutionContext` and are not part of the data model\n- **Computed expressions**: Complex expressions that evaluate to non-data values\n- **Non-observable constructs**: Any binding assumed to reference functions or non-data objects\n\n## The Schema Class\n\nThe `Schema` class is responsible for building JSON Schema definitions that map the structure of data objects used in template bindings. It analyzes binding paths from template processing and constructs schemas that describe:\n\n- Root properties and their nested structures\n- Array contexts for repeat operations\n- Object property relationships\n- Cross-references to child components\n\n**Important**: Each schema created corresponds to a property that will belong to the custom element's class. The schema describes the expected structure and relationships of data that will be assigned to that property, enabling automatic observation of nested objects and arrays within that property's data structure.\n\n### Core Methods\n\n#### Constructor\n```typescript\nconstructor(name: string)\n```\nCreates a new schema instance for a specific custom element name and initializes an instance-level `schemaMap`. The instance also registers itself in the module-level `schemaRegistry` for cross-element `$ref` resolution. `FASTElementDefinition.schema` is optional; declarative templates assign it after parsing, while manual schema users can pass one in the element definition or directly to `observerMap({ schema })`.\n\n#### addPath\n```typescript\npublic addPath(config: RegisterPathConfig)\n```\nRegisters a binding path discovered during template processing. The configuration includes:\n- `pathConfig`: Describes the path type (`access`, `default`, `repeat`, `event`)\n- `rootPropertyName`: The root property this path belongs to\n- `childrenMap`: Information about child components referenced in this path\n\n**Note**: Only `access`, `default`, and `repeat` path types result in schema entries. Event paths are identified but not processed since they represent function calls rather than observable data.\n\n#### getSchema\n```typescript\npublic getSchema(rootPropertyName: string): JSONSchema | null\n```\nRetrieves the JSON schema for a specific root property.\n\n### Path Types\n\nThe schema handles different types of binding paths:\n\n- **`access`/`default`**: Direct property access like `{{user.name}}`\n- **`repeat`**: Array iteration contexts like `{{item}}` within `<f-repeat>`\n- **`event`**: Event handler bindings like `@click=\"{handleClick()}\"` - **Note: These are explicitly not processed by the schema system as they are assumed to be functions rather than observable data objects**\n\n### Schema Structure\n\nGenerated schemas follow JSON Schema format with FAST-specific extensions:\n\n```typescript\n{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://fast.design/schemas/my-element/users.json\",\n  \"type\": \"array\",\n  \"$ref\": \"#/$defs/user\",\n  \"$defs\": {\n    \"user\": {\n      \"$fast_context\": \"users\",\n      \"$fast_parent_contexts\": [null],\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {},\n        \"details\": {\n          \"type\": \"object\", \n          \"properties\": {\n            \"age\": {}\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n**Note on Property Types**: Properties accessed through binding paths (like `name` and `age` above) are defined with empty objects `{}` rather than specific JSON Schema types. This is because it's not possible to determine the exact primitive type (string, number, boolean, etc.) from the path syntax alone. The system focuses on structural relationships rather than specific data types for leaf properties.\n\n## The Observer Map Class\n\nThe `ObserverMap` class uses schema information to automatically configure observable properties on custom element prototypes. It creates the infrastructure needed to observe nested object changes without manual setup.\n\n### Constructor\n```typescript\nconstructor(classPrototype: any, schema: Schema, config?: ObserverMapConfig)\n```\nCreates an observer map instance that will configure the provided class prototype using the schema information.\n\n### defineProperties\n```typescript\npublic defineProperties(): void\n```\nThe main method that:\n1. Iterates through all root properties defined in the schema (each schema instance contains multiple root property schemas)\n2. Defines observable properties using FAST Element's `Observable.defineProperty` (an alternative to the `@observable` decorator syntax used in custom element classes)\n3. Sets up property change handlers that create proxies for nested objects\n\n### Property Change Handling\n\nWhen a root property transitions from `undefined` to a defined value, the observer map:\n1. Analyzes the schema to understand the expected object structure\n2. Creates proxies using the `assignObservables` utility function\n3. Establishes deep observation of nested properties based on the schema of that root property\n\n## Integration with f-template and manual schemas\n\nThe Schema and Observer Map classes integrate seamlessly with the f-template system, but they are not tied to it:\n\n### Template Processing Flow\n\n1. **Template Parsing**: When an `f-template` element is processed, it creates a `Schema` instance\n2. **Binding Discovery**: As template bindings are processed, paths are registered with `schema.addPath()`\n3. **Observer Map Creation**: If enabled, an `ObserverMap` is instantiated with the populated schema\n4. **Property Definition**: The observer map defines observable properties on the custom element prototype\n\n### Configuration\n\nObserver Map functionality is enabled through the `observerMap()` definition\nextension exported from `@microsoft/fast-element/observer-map.js`:\n\n```typescript\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nMyElement.define(\n  {\n    name: \"my-custom-element\",\n    template: declarativeTemplate(),\n  },\n  [observerMap()]\n);\n```\n\nWhen the `properties` key is omitted, all root properties discovered in the\ntemplate are observed. Add a `properties` object to opt into selective\nobservation behavior.\n\nFor non-declarative/manual schema use, pass the schema in the observer map\nconfiguration:\n\n```typescript\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-custom-element\");\nschema.addPath({\n  rootPropertyName: \"user\",\n  pathConfig: {\n    type: \"default\",\n    parentContext: null,\n    currentContext: null,\n    path: \"user.name\",\n  },\n  childrenMap: null,\n});\n\nMyElement.define(\n  {\n    name: \"my-custom-element\",\n  },\n  [observerMap({ schema })]\n);\n```\n\nYou can also attach a manual schema to the FAST element definition. This is the\npath used automatically by `declarativeTemplate()` after it parses a template:\n\n```typescript\nMyElement.define(\n  {\n    name: \"my-custom-element\",\n    schema,\n  },\n  [observerMap()]\n);\n```\n\n## Initial Path Processing Flow\n\nHere's how binding paths flow through the system during initial template processing:\n\n1. **Template Binding**: `{{user.details.personal.name}}`\n2. **Path Analysis**: Utilities identify root property (`user`) and nested path (`details.personal.name`)\n3. **Type Check**: Confirms this is a data binding (not an event handler like `@click=\"{handleClick()}\"`)\n4. **Schema Registration**: \n   ```typescript\n   schema.addPath({\n     pathConfig: {\n       type: \"access\",\n       currentContext: null,\n       parentContext: null,\n       path: \"user.details.personal.name\"\n     },\n     rootPropertyName: \"user\",\n     childrenMap: null\n   });\n   ```\n5. **Schema Building**: Creates nested object structure in JSON schema\n6. **Observable Definition**: Observer map makes `user` property observable\n7. **Proxy Creation**: When `user` is assigned, proxies are created for deep observation\n\n### Event Handler and Context Path Exclusion\n\nEvent handlers are identified but explicitly excluded from schema processing:\n- **Template Binding**: `@click=\"{handleClick()}\"`\n- **Path Analysis**: Utilities identify this as an event handler\n- **Type Check**: Confirms this is type `\"event\"`\n- **Schema Registration**: **Skipped** - Event handlers are not added to schemas since they represent function calls\n\nContext paths (`$c` prefix) are also excluded from schema processing:\n- **Template Binding**: `{{$c.parent.showNames}}` or `@click=\"{$c.parent.handleClick($c.event)}\"`\n- **Path Analysis**: Utilities detect the `$c.` prefix\n- **Schema Registration**: **Skipped** - These paths resolve from the `ExecutionContext`, not from observable data properties\n\n## Dynamic Path Processing Updates\n\nAfter initial schema creation and observer map setup, the system continues to dynamically update observation as data structures evolve:\n\n### Runtime Object Assignment\n\nWhen nested objects or array items become defined after initial setup:\n\n1. **Property Assignment**: A previously undefined nested property gets assigned a value\n   ```typescript\n   // Initially: user.details was undefined\n   user.details = { age: 30, location: { city: \"Seattle\" } };\n   ```\n\n2. **Schema Consultation**: The system consults the existing schema for this root property to understand expected nested structure\n\n3. **Proxy Creation**: New proxies are automatically created for the newly assigned nested objects based on the schema definition\n\n4. **Deep Observation Extension**: Observation is extended to all nested properties defined in the schema\n\n### Array Item Addition\n\nWhen new items are added to observed arrays:\n\n1. **Array Mutation**: Items are added via push, splice, or direct assignment\n   ```typescript\n   users.push({ name: \"John\", details: { age: 25 } });\n   ```\n\n2. **Array Observer Trigger**: The array proxy detects the mutation and triggers observation setup\n\n3. **Item Processing**: Each new array item is processed according to the array's context schema definition\n\n4. **Nested Object Proxying**: New nested objects within array items are automatically proxied based on the schema structure\n\n## Observable Proxy System\n\nThe proxy system in `utilities.ts` provides the deep observation capabilities:\n\n### assignObservables Function\n\n```typescript\nexport function assignObservables(\n    schema: JSONSchema | JSONSchemaDefinition,\n    rootSchema: JSONSchema,\n    data: any,\n    target: any,\n    rootProperty: string\n): typeof Proxy\n```\n\nThis function:\n- Analyzes the data type (object, array, primitive)\n- Creates proxies for objects and arrays\n- Establishes property observation for nested structures\n- Handles array mutations and object property changes\n\n### Proxy Behavior\n\nProxied objects:\n- Trigger Observable notifications when properties change\n- Automatically proxy newly assigned nested objects\n- Track array mutations and splice operations\n- Maintain references to root properties for change notifications\n\n## Examples\n\n### Basic Object Observation\n\n**Template:**\n```html\n<f-template name=\"user-profile\">\n  <template>\n    <div>{{user.name}} - {{user.details.age}} years old</div>\n    <div>Location: {{user.details.location.city}}</div>\n  </template>\n</f-template>\n```\n\n**Generated Schema Structure:**\n```typescript\n// Root property: \"user\"\n{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://fast.design/schemas/user-profile/user.json\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": {},\n    \"details\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"age\": {},\n        \"location\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"city\": {}\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n### Array with Repeat Context\n\n**Template:**\n```html\n<f-template name=\"user-list\">\n  <template>\n    <f-repeat value=\"{{user in users}}\">\n      <div>{{user.name}} has {{user.posts.length}} posts</div>\n    </f-repeat>\n  </template>\n</f-template>\n```\n\n**Generated Schema Structure:**\n```typescript\n// Root property: \"users\"\n{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://fast.design/schemas/user-list/users.json\",\n  \"type\": \"array\",\n  \"$ref\": \"#/$defs/user\",\n  \"$defs\": {\n    \"user\": {\n      \"$fast_context\": \"users\",\n      \"$fast_parent_contexts\": [null],\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {},\n        \"posts\": {\n          \"type\": \"array\"\n        }\n      }\n    }\n  }\n}\n```\n\n### Nested Repeat Contexts\n\n**Template:**\n```html\n<f-template name=\"complex-data\">\n  <template>\n    <f-repeat value=\"{{user in users}}\">\n      <div>{{user.name}}</div>\n      <f-repeat value=\"{{post in user.posts}}\">\n        <div>{{post.title}} - {{post.metadata.views}} views</div>\n      </f-repeat>\n    </f-repeat>\n  </template>\n</f-template>\n```\n\nThis creates nested context definitions where the `post` context understands its relationship to the parent `user` context.\n\n## Technical Details\n\n### Schema Registry\n\nThe `Schema` module exports a module-level `schemaRegistry`:\n```typescript\nexport const schemaRegistry: CachedPathMap = new Map();\n```\n\nEach `Schema` instance owns an instance-level `schemaMap: Map<string, JSONSchema>` and registers itself in `schemaRegistry` on construction.\n\nThe registry structure is: `Map<customElementName, Map<rootPropertyName, JSONSchema>>`\n\n**Rationale for Module-level Registry**: The registry allows cross-element `$ref` resolution for nested components inside f-templates. When an object or array is passed to another custom element within an f-template, that nested component needs to observe the entire root property's structure based on the binding paths within that nested component. The registry allows all components to access and contribute to the same schema definitions, ensuring consistent observation behavior across component boundaries.\n\n### Context Tracking\n\nThe schema system tracks binding contexts using special metadata:\n- `$fast_context`: The array property name that created this context\n- `$fast_parent_contexts`: Chain of parent contexts leading to the root\n\n### Performance Considerations\n\n- **Lazy Proxy Creation**: Proxies are only created when objects are assigned to observable properties\n- **Weak Map Caching**: The system uses WeakMaps to avoid memory leaks when tracking proxied objects\n- **Schema Reuse**: Schemas are generated once per custom element and reused across instances\n\n### Memory Management\n\n- **WeakMap Usage**: `objectTargetsMap` and `observedArraysMap` use WeakMaps to automatically clean up references\n- **Proxy Identification**: Proxies are marked with `$isProxy` to prevent double-proxying\n- **Reference Tracking**: Target elements and root properties are tracked for proper change notification\n\n## Debugging and Troubleshooting\n\n### Schema Inspection\n\nYou can inspect generated schemas using the module-level `schemaRegistry` import:\n\n```typescript\nimport { schemaRegistry } from \"@microsoft/fast-element\";\n\n// Get all schemas for an element:\nconst elementSchemas = schemaRegistry.get('my-element');\nconst userSchema = elementSchemas?.get('users');\nconsole.log(JSON.stringify(userSchema, null, 2));\n```\n\n### Observer Map Status\n\n`observerMap()` is applied as a definition extension before the element is\nregistered. There is no public `TemplateElement.options()` state to inspect.\nTo verify that observer mapping ran, inspect the generated schema and the\nobservable accessors on the element prototype:\n\n```typescript\nimport { Observable, schemaRegistry } from \"@microsoft/fast-element\";\n\nconst schemas = schemaRegistry.get(\"my-element\");\nconst accessors = Observable.getAccessors(MyElement.prototype).map(a => a.name);\nconsole.log(schemas, accessors);\n```\n\n### Proxy Detection\n\nObjects processed by the system will have a `$isProxy` property:\n```typescript\nconsole.log('Is proxied:', myObject.$isProxy === true);\n```\n","isInternal":false,"tokens":3841,"sizeBytes":18394},{"name":"syntax.md","path":"packages/fast-element/docs/declarative/syntax.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/declarative/syntax.md","title":"Declarative Skill","category":"anthropic-skill","format":"markdown","content":"# FAST Element Declarative HTML\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-element.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-element)\n\nThe declarative entrypoint in `@microsoft/fast-element` interprets FAST\ndeclarative HTML syntax as a template for a FAST web component.\n\nThis document focuses on declarative-runtime implementation details:\ntemplate structure, prerendered markup requirements, hydration promise APIs,\nbinding configuration, syntax, and integration testing.\n\nFor package installation, using `declarativeTemplate()`, extension setup, and\nthe package-level hydration overview, see the\n[FAST Element README](../../README.md#declarative-html) and\n[Prerendered Content Optimization](../../README.md#prerendered-content-optimization).\nFor user-facing guides covering f-template syntax, element definition, and\nserver-side rendering, see the\n[Declarative HTML docs](https://fast.design/docs/3.x/declarative-templates/overview/).\n\n## Template Structure\n\nAfter importing the declarative APIs as shown in the README, templates are\nassociated with an element through\n`<f-template name=\"[custom-element-name]\"><template>...</template></f-template>`.\nThe host custom element should be defined with\n`template: declarativeTemplate()`. This automatically defines `<f-template>` in\nthe relevant registry and waits for the matching declarative template when it is\nalready present or inserted later.\n\nThe `@microsoft/fast-element` entrypoint itself remains\nside-effect free at import time. Declarative APIs lazily install declarative\ndebug messages when they create templates. Hydratable `ViewTemplate` support is\ninstalled only when `enableHydration()` is called from\n`@microsoft/fast-element/hydration.js`.\n\n`observerMap()` and `attributeMap()` are available from\n`@microsoft/fast-element/observer-map.js` and\n`@microsoft/fast-element/attribute-map.js`, including when using the maps\nwithout declarative templates.\n\nExample:\n```html\n<my-custom-element greeting=\"Hello world\">\n    <template shadowrootmode=\"open\">\n        Hello world\n    </template>\n</my-custom-element>\n<f-template name=\"my-custom-element\">\n    <template>{{greeting}}</template>\n</f-template>\n```\n\nThe legacy `defer-hydration` and `needs-hydration` attributes are no longer\nrequired.\n\n## HTML Comments\n\nBindings and FAST directive markup inside HTML comments are unsupported. This\nincludes double-brace and triple-brace bindings, client-only bindings, and\ncommented-out elements containing bindings or directives.\n\nThe declarative parsers scan template strings and do not reliably exclude\ncomments. A comment such as `<!-- {{greeting}} -->` can still contribute a binding,\nleading to unexpected evaluation, rendering errors, or hydration mismatches.\nRemove unused bound markup rather than commenting it out, and keep explanatory\ncomments free of binding syntax and FAST directive tags.\n\n## Non-browser HTML Rendering\n\nOne of the benefits of FAST declarative HTML templates is that the server can\nbe stack agnostic because JavaScript does not need to be interpreted to emit\nthe initial HTML. This does not mean the FAST Element client runtime runs on the\nserver: custom element definition, hydration, client rendering, and reactive\nupdates still run in the browser `Window`. The declarative runtime expects\nhydratable comment markers and datasets when prerendered content is generated.\nFor the required marker format and initial-state application details, see\n[rendering.md](./rendering.md).\n\n## Hydration promise APIs\n\nFAST Element's declarative APIs expose hydration readiness promises that are\nuseful to application code.\n\nHydration is opt-in. Call `enableHydration()` before FAST elements connect when\nyou want prerendered Declarative Shadow DOM to be reused, then await\nthe returned controller's `whenHydrated()` promise when code needs to run after\nthe active hydration batch:\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nconst hydration = enableHydration();\nawait hydration.whenHydrated();\n```\n\nThe hydration hook no-ops for new prerendered elements after the initial\nhydration batch completes by default. Streaming scenarios that append hydratable\nDeclarative Shadow DOM later can keep the hook active:\n\n```typescript\nimport { enableHydration, StopHydration } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({\n    stopHydration: StopHydration.never,\n});\n```\n\nWhen `StopHydration.never` is used, `enableHydration().whenHydrated()`\nintentionally remains pending because hydration has no global completion point.\n\nFAST Element 3.x data-free hydration markers are selected by default. Existing\nserver output that uses FAST Element 2.x indexed markers can be hydrated by\nselecting the v2 marker reader:\n\n```typescript\nimport { enableHydration, markers_v2 } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ markers: markers_v2 });\n```\n\nSet `\"markers_v2\": true` in the matching `@microsoft/fast-build`\nconfiguration so the generated HTML uses the same marker format.\n\n## `observerMap`\n\nWhen the `observerMap()` extension is applied to an element definition,\nit automatically sets up deep reactive observation for root properties\ndiscovered in the template. Declarative templates assign `definition.schema`\nduring template resolution, so `observerMap()` has schema data automatically.\nFor non-declarative/manual schemas, import from\n`@microsoft/fast-element/observer-map.js` and pass `observerMap({ schema })`.\n\n```typescript\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n```\n\nFor finer control, pass a configuration object with a `properties` key that maps root property names to a recursive path tree:\n\n```typescript\nUserProfile.define(\n    {\n        name: \"user-profile\",\n        template: declarativeTemplate(),\n    },\n    [\n        observerMap({\n            properties: {\n                user: {\n                    name: true,          // user.name — observed\n                    details: {\n                        age: true,       // user.details.age — observed\n                        history: false,  // user.details.history — NOT observed\n                    },\n                },\n                // root properties not listed here are skipped\n            },\n        }),\n    ],\n);\n```\n\nEach path entry can be:\n- **`true`** — observe this path and all descendants.\n- **`false`** — skip this path and all descendants.\n- **An object** with an optional `$observe` boolean and child property overrides.\n\nUse `$observe: false` on a node to skip it by default, then re-include specific children:\n\n```typescript\nobserverMap({\n    properties: {\n        analytics: {\n            charts: {\n                $observe: false,       // charts NOT observed by default\n                activeChart: true,     // ...except activeChart IS observed\n            },\n        },\n    },\n});\n```\n\nWhen `properties` is omitted, all root properties are observed. When\n`properties` is present but empty (`{ properties: {} }`), no root properties\nare observed.\n\nWhen observer-map data is updated with `deepMerge`, array properties are replaced\nrather than updated in place. This avoids synchronous reentrant array work and\nallows repeat bindings to observe the new array reference. Replacement arrays\nare processed through observerMap so nested item properties and subsequent array\nmutations remain observable.\n\nManual schema example:\n\n```typescript\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-element\");\nschema.addPath({\n    rootPropertyName: \"user\",\n    pathConfig: {\n        type: \"default\",\n        parentContext: null,\n        currentContext: null,\n        path: \"user.name\",\n    },\n    childrenMap: null,\n});\n\nMyElement.define({ name: \"my-element\" }, [observerMap({ schema })]);\n```\n\n## `attributeMap`\n\nWhen the `attributeMap()` extension is applied to an element definition,\nit automatically creates reactive `@attr` properties for every **leaf binding**\nin the template — simple expressions like `{{foo}}` or `id=\"{{fooBar}}\"` that\nhave no nested properties. Declarative templates provide the schema\nautomatically. For non-declarative/manual schemas, place the optional `schema`\non the FAST element definition and import `attributeMap()` from\n`@microsoft/fast-element`.\n\n```typescript\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\n```\n\nBy default, the binding key is treated as a camelCase property name and the HTML\nattribute name is derived by converting it to kebab-case. Properties already\ndecorated with `@attr` or `@observable` on the class are left untouched.\n\n```typescript\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [attributeMap()],\n);\n```\n\nWith the template:\n\n```html\n<f-template name=\"my-element\">\n    <template>\n        <p>{{greeting}}</p>\n        <p>{{firstName}}</p>\n    </template>\n</f-template>\n```\n\nThis registers `greeting` (attribute `greeting`, property `greeting`) and\n`firstName` (attribute `first-name`, property `firstName`) as `@attr`\nproperties on the element prototype, enabling `setAttribute(\"first-name\",\n\"Jane\")` to trigger a template re-render automatically.\n\n### `attribute-name-strategy`\n\nThe `attribute-name-strategy` configuration option controls how template binding\nkeys map to HTML attribute names. This matches the build-time\n`--attribute-name-strategy` option in `@microsoft/fast-build`.\n\n| Strategy | Behaviour | Example |\n|---|---|---|\n| `\"camelCase\"` (default) | Binding key is the camelCase property; attribute name is derived as kebab-case | `{{fooBar}}` → property `fooBar`, attribute `foo-bar` |\n| `\"none\"` | Binding key used as-is for both property and attribute | `{{foo-bar}}` → property `foo-bar`, attribute `foo-bar` |\n\n```typescript\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [\n        attributeMap({\n            \"attribute-name-strategy\": \"none\",\n        }),\n    ],\n);\n```\n\nWhen using the `\"none\"` strategy, property names may contain dashes and must be\naccessed via bracket notation (e.g. `element[\"foo-bar\"]`).\n\n## Syntax\n\nAll bindings use a handlebars-like syntax.\n\nSome bindings are only relevant to the browser, such as for click handlers or other pieces of dynamic interaction. As such, their bindings use single curly braces `{}`, this is to prevent an intial SSR (Server Side Rendering) or other build time rendering technologies from needing to interpret them.\n\nIf a binding is relevant to both client and the back end rendering engine, it will use `{{}}` or `{{{}}}` depending on what type of data injection is being done.\n\nBrowser-only bindings:\n- Event bindings\n- Attribute directives\n\n### Content binding\n\n```html\n{{text}}\n```\n\n### Event binding\n\nEvent bindings must include the `()` as well as being preceeded by `@` in keeping with the `@microsoft/fast-element` tagged template syntax.\n\n```html\n<button @click=\"{handleClick()}\"></button>\n```\n\nYou can pass the DOM event object, the execution context, or both as arguments. Any other argument is treated as a binding expression and resolved against the current data source.\n\n**`$e` — DOM event object (preferred):**\n```html\n<button @click=\"{handleClick($e)}\"></button>\n```\n\n**`$c` — execution context:**\n```html\n<button @click=\"{handleClick($c)}\"></button>\n```\n\n**`$c.somePath` — a property of the execution context (e.g. `$c.parent`, `$c.event`):**\n```html\n<button @click=\"{handleClick($c.parent)}\"></button>\n```\n\n**Multiple arguments:**\n```html\n<button @click=\"{handleClick($e, $c)}\"></button>\n```\n\n**Arbitrary binding expressions** — any token that is not `$e` or `$c` is resolved as a binding path on the data source:\n```html\n<button @click=\"{handleClick(user.id)}\"></button>\n```\n\nUse `$e` for the DOM event object.\n\n### Directives\n\nDirectives are assumed to be either an attribute directive or a directive that also serves a template. Both are prepended by `f-`. The logic of these directives and what their use cases are is explained in the [FAST html documentation](https://fast.design/docs/getting-started/html-directives).\n\nAttribute directives are part of [client side binding](#syntax) and therefore use the `{}` syntax.\n\nAttribute directives include:\n- **slotted**\n\n    Example:\n    ```html\n    <slot f-slotted=\"{slottedNodes}\"></slot>\n    <slot f-slotted=\"{slottedNodes filter elements()}\"></slot>\n    <slot f-slotted=\"{slottedNodes filter elements(div, p)}\"></slot>\n    ```\n\n- **children**\n\n    Example:\n    ```html\n    <ul f-children=\"{listItems}\"><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    <ul f-children=\"{listItems filter elements()}\"><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    <ul f-children=\"{listItems filter elements(li)}\"><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    ```\n\n- **ref**\n\n    Example:\n    ```html\n    <video f-ref=\"{video}\"></video>\n    ```\n\nTemplate directives include:\n- **when**\n\n    Example:\n    ```html\n    <f-when value=\"{{show}}\">Hello world</f-when>\n    <f-when value=\"{{!show}}\">Goodbye world</f-when>\n    ```\n\nThe following operators can also be used:\n- `==`\n- `!=`\n- `>=`\n- `>`\n- `<=`\n- `<`\n- `||`\n- `&&`\n\nWhere the right operand can be either a reference to a value (string e.g. `{{foo == 'bar'}}`, boolean e.g. `{{foo == true}}`, number e.g. `{{foo == 3}}`) or another binding value.\n\n- **repeat**\n\n    Example:\n    ```html\n    <ul><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    ```\n\n    Bindings inside `<f-repeat>` without a context prefix resolve to the custom element. For example, `{{title}}` below resolves to the host element's `title` property:\n\n    ```html\n    <ul><f-repeat value=\"{{item in list}}\"><li>{{item}} - {{title}}</li></f-repeat></ul>\n    ```\n\n### Execution Context Access\n\nIn imperative fast-element templates, every binding expression receives both the data source and the execution context: `${(x, c) => c.parent.handleClick(c.event)}`. Declarative `<f-template>` expressions can access the same execution context using the `$c` prefix.\n\nThis is particularly useful inside `<f-repeat>`, where `$c.parent` refers to the parent view-model (typically the host element) and `$c.event` provides the DOM event.\n\nEvent handler with context access:\n\n```html\n<f-repeat value=\"{{item in items}}\">\n    <button @click=\"{$c.parent.handleItemClick($c.event)}\">{{item.name}}</button>\n</f-repeat>\n```\n\nConditional rendering using a host property inside a repeat:\n\n```html\n<f-repeat value=\"{{item in items}}\">\n    <f-when value=\"{{$c.parent.showNames}}\">\n        <span>{{item.name}}</span>\n    </f-when>\n</f-repeat>\n```\n\n### Unescaped HTML\n\nYou can add unescaped HTML using triple braces, this will create an additional `div` element as the HTML needs an element to bind to. Where possible it is advisable to not use unescaped HTML and instead use other binding techniques.\n\nExample:\n```html\n{{{html}}}\n```\n\n### Code samples inside `<code>`\n\nAny text or attribute value inside a `<code>` element has its `{` and `}` characters automatically replaced with the HTML numeric character references `&#123;` and `&#125;` before template parsing. As a result, binding delimiters (`{{...}}`, `{{{...}}}`, `{...}`) inside `<code>` are rendered as literal text rather than being interpreted as FAST bindings — making `<code>` blocks safe for embedding code samples that contain binding-like syntax. No marker attribute is needed.\n\nIn addition, the build-time renderer (`@microsoft/fast-build`) entity-escapes the `<` and `>` of every **FAST directive tag** (`<f-when>`, `</f-when>`, `<f-repeat>`, `</f-repeat>`) it finds inside `<code>`, so authors can write the directive literally without manually entity-encoding the angle brackets. Tag-name matching is case-insensitive. Non-directive elements inside `<code>` — real HTML elements such as `<button>` and custom elements such as `<my-widget>` — keep their angle brackets and continue to render as live DOM elements; only brace-binding syntax in their attribute values is neutralised.\n\nThe brace escape is applied symmetrically by both the server-side renderer and the client-side `<f-template>` parser, so binding positions stay in sync between SSR and hydration. The directive-tag angle escape only needs to run on the server: the DOM serializer re-encodes `<`/`>` in text content, so the client-side parser never sees a raw `<f-when>` inside `<code>` regardless of what the page source contained. This behaviour mirrors how Microsoft WebUI's `webui-press` markdown renderer transparently escapes the same characters inside code spans and code fences.\n\nExample:\n```html\n<f-template name=\"docs-page\">\n    <template>\n        <h1>{{title}}</h1>\n        <pre><code>span {{greeting}} /span</code></pre>\n        <pre><code><f-when value=\"{{flag}}\">wrapped</f-when></code></pre>\n        <pre><code>Try: <button class=\"demo\">click</button></code></pre>\n    </template>\n</f-template>\n```\n\nThe `<h1>` binds to `title`, the first `<code>` displays the literal text `span {{greeting}} /span`, the second displays the literal text `<f-when value=\"{{flag}}\">wrapped</f-when>`, and the third renders a live `<button>` element alongside the surrounding sample text.\n\n## Writing Components\n\nWhen writing components with the intention of using the declarative HTML syntax, it is imperative that components are written with styling and rendering of the component to be less reliant on any JavaScript state management. An example of this is relying on `elementInterals` state to style a component.\n\n## WebUI Integration Testing\n\nThe fixture tests in `test/declarative/fixtures/` are also validated against\n[`@microsoft/webui`](https://github.com/microsoft/webui) to ensure\ncross-renderer compatibility. The build step renders each fixture's templates\nwith `webui build --plugin=fast`, then the existing Playwright specs run\nagainst the webui-rendered output.\n\n```shell\n# Build fixtures with webui and run Playwright tests\nnpm run test:webui-integration -w @microsoft/fast-element\n\n# Or run the steps separately\nnpm run build:fixtures:webui -w @microsoft/fast-element\nnpm exec -w @microsoft/fast-element -- playwright test --config=playwright.declarative.webui.config.ts\n```\n\nThis is also run automatically in CI via the `ci-webui-integration.yml` GitHub Action on pull requests and pushes to `main`.\n\nSome tests are conditionally skipped during webui integration runs due to known\nrendering differences between `fast-build` and `webui`. The\n`playwright.declarative.webui.config.ts` file sets\n`FAST_WEBUI_INTEGRATION=true`, and affected tests use `test.skip()` with a\ndescriptive reason. See the WebUI Integration Tests section in\n[design.md](./design.md) for the full list.\n","isInternal":false,"tokens":4324,"sizeBytes":19009},{"name":"api-report.api.md","path":"packages/fast-element/docs/di/api-report.api.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/di/api-report.api.md","title":"Di Skill","category":"anthropic-skill","format":"markdown","content":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport const all: (key: any, searchAncestors?: boolean) => ReturnType<typeof DI.inject>;\n\n// @public\nexport type AsyncRegistrationLocator = (key: Key) => Promise<Registration | null>;\n\n// @public\nexport interface Container extends ServiceLocator {\n    createChild(config?: Partial<Omit<ContainerConfiguration, \"parentLocator\">>): Container;\n    getFactory<T extends Constructable>(key: T): Factory<T>;\n    getResolver<K extends Key, T = K>(key: K | Key, autoRegister?: boolean): Resolver<T> | null;\n    register(...params: any[]): Container;\n    // Warning: (ae-forgotten-export) The symbol \"Constructable\" needs to be exported by the entry point di.d.ts\n    registerFactory<T extends Constructable>(key: T, factory: Factory<T>): void;\n    registerResolver<K extends Key, T = K>(key: K, resolver: Resolver<T>): Resolver<T>;\n    registerTransformer<K extends Key, T = K>(key: K, transformer: Transformer_2<T>): boolean;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"ContextDecorator\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport const Container: ContextDecorator<Container>;\n\n// @public\nexport interface ContainerConfiguration {\n    asyncRegistrationLocator: AsyncRegistrationLocator;\n    defaultResolver(key: Key, handler: Container): Resolver;\n    parentLocator: ParentLocator;\n    responsibleForOwnerRequests: boolean;\n}\n\n// @public\nexport const ContainerConfiguration: Readonly<{\n    default: Readonly<ContainerConfiguration>;\n}>;\n\n// Warning: (ae-internal-missing-underscore) The name \"ContainerImpl\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport class ContainerImpl implements DOMContainer {\n    constructor(owner: any, config: ContainerConfiguration);\n    // (undocumented)\n    protected config: ContainerConfiguration;\n    // (undocumented)\n    createChild(config?: Partial<Omit<ContainerConfiguration, \"parentLocator\">>): Container;\n    // (undocumented)\n    get depth(): number;\n    // (undocumented)\n    get<K extends Key>(key: K): Resolved<K>;\n    // (undocumented)\n    getAll<K extends Key>(key: K, searchAncestors?: boolean): readonly Resolved<K>[];\n    // (undocumented)\n    getAsync<K extends Key>(key: K): Promise<Resolved<K>>;\n    // (undocumented)\n    getFactory<K extends Constructable>(Type: K): Factory<K>;\n    // (undocumented)\n    getResolver<K extends Key, T = K>(key: K | Key, autoRegister?: boolean): Resolver<T> | null;\n    // (undocumented)\n    handleContextRequests(enable: boolean): void;\n    // (undocumented)\n    has<K extends Key>(key: K, searchAncestors?: boolean): boolean;\n    // (undocumented)\n    protected owner: any;\n    // (undocumented)\n    get parent(): ContainerImpl | null;\n    // (undocumented)\n    register(...params: any[]): Container;\n    // (undocumented)\n    registerFactory<K extends Constructable>(key: K, factory: Factory<K>): void;\n    // (undocumented)\n    registerResolver<K extends Key, T = K>(key: K, resolver: Resolver<T>): Resolver<T>;\n    // (undocumented)\n    registerTransformer<K extends Key, T = K>(key: K, transformer: Transformer_2<T>): boolean;\n    // (undocumented)\n    get responsibleForOwnerRequests(): boolean;\n}\n\n// @public\nexport const DefaultResolver: Readonly<{\n    none(key: Key): Resolver;\n    singleton(key: Key): Resolver;\n    transient(key: Key): Resolver;\n}>;\n\n// @public\nexport const DI: Readonly<{\n    installAsContextRequestStrategy(fallback?: () => DOMContainer): void;\n    createContainer(config?: Partial<ContainerConfiguration>): Container;\n    findResponsibleContainer(target: EventTarget, fallback?: () => DOMContainer): DOMContainer;\n    findParentContainer(target: EventTarget, fallback?: () => DOMContainer): DOMContainer;\n    getOrCreateDOMContainer(target?: EventTarget, config?: Partial<Omit<ContainerConfiguration, \"parentLocator\">>): DOMContainer;\n    getDependencies(Type: Constructable | Injectable): Key[];\n    defineProperty(target: {}, propertyName: string, key: Key, respectConnection?: boolean): void;\n    createContext: typeof createContext;\n    inject(...dependencies: Key[]): (target: any, key?: string | number, descriptor?: PropertyDescriptor | number) => void;\n    transient<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;\n    singleton<T extends Constructable>(target: T & Partial<RegisterSelf<T>>, options?: SingletonOptions): T & RegisterSelf<T>;\n}>;\n\n// @public\nexport interface DOMContainer extends Container {\n    // @beta\n    handleContextRequests(enable: boolean): void;\n}\n\n// @public\nexport const DOMContainer: ContextDecorator<DOMContainer>;\n\n// @public\nexport interface Factory<T extends Constructable = any> {\n    construct(container: Container, dynamicDependencies?: Key[]): Resolved<T>;\n    constructAsync(container: Container, dynamicDependencies?: Key[]): Promise<Resolved<T>>;\n    registerTransformer(transformer: Transformer_2<T>): void;\n    readonly Type: T;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"FactoryImpl\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport class FactoryImpl<T extends Constructable = any> implements Factory<T> {\n    constructor(Type: T, dependencies: Key[]);\n    // (undocumented)\n    construct(container: Container, dynamicDependencies?: Key[]): Resolved<T>;\n    // (undocumented)\n    constructAsync(container: Container, dynamicDependencies?: Key[]): Promise<Resolved<T>>;\n    // (undocumented)\n    registerTransformer(transformer: (instance: any) => any): void;\n    // (undocumented)\n    Type: T;\n}\n\n// @public\nexport function ignore(target: Injectable, property?: string | number, descriptor?: PropertyDescriptor | number): void;\n\n// @public\nexport const inject: (...dependencies: Key[]) => (target: any, key?: string | number, descriptor?: PropertyDescriptor | number) => void;\n\n// @public\nexport type Injectable<T = {}> = Constructable<T> & {\n    inject?: Key[];\n};\n\n// @public\nexport interface InterfaceConfiguration {\n    friendlyName?: string;\n    respectConnection?: boolean;\n}\n\n// @public\nexport type Key = PropertyKey | object | ContextDecorator | Constructable | Resolver;\n\n// @public\nexport const lazy: (key: any) => any;\n\n// @public\nexport const newInstanceForScope: (key: any) => any;\n\n// @public\nexport const newInstanceOf: (key: any) => any;\n\n// @public\nexport const optional: (key: any) => any;\n\n// @public\nexport type ParentLocator = (owner: any) => Container | null;\n\n// @public\nexport type RegisterSelf<T extends Constructable> = {\n    register(container: Container): Resolver<InstanceType<T>>;\n    registerInRequestor: boolean;\n};\n\n// @public\nexport interface Registration<K = any> {\n    register(container: Container): Resolver<K>;\n}\n\n// @public\nexport const Registration: Readonly<{\n    instance<T>(key: Key, value: T): Registration<T>;\n    singleton<T extends Constructable>(key: Key, value: T): Registration<InstanceType<T>>;\n    transient<T extends Constructable>(key: Key, value: T): Registration<InstanceType<T>>;\n    callback<T>(key: Key, callback: ResolveCallback<T>): Registration<Resolved<T>>;\n    cachedCallback<T>(key: Key, callback: ResolveCallback<T>): Registration<Resolved<T>>;\n    aliasTo<T>(originalKey: T, aliasKey: Key): Registration<Resolved<T>>;\n}>;\n\n// @public\nexport interface Registry {\n    register(container: Container, ...params: unknown[]): void | Resolver;\n}\n\n// @public\nexport type ResolveCallback<T = any> = (handler: Container, requestor: Container, resolver: Resolver<T>) => T;\n\n// Warning: (ae-forgotten-export) The symbol \"ResolverLike\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport type Resolved<K> = K extends ContextDecorator<infer T> ? T : K extends Constructable ? InstanceType<K> : K extends ResolverLike<any, infer T1> ? T1 extends Constructable ? InstanceType<T1> : T1 : K;\n\n// @public\nexport interface Resolver<K = any> extends ResolverLike<Container, K> {\n}\n\n// @public\nexport class ResolverBuilder<K> {\n    constructor(container: Container, key: Key);\n    aliasTo(destinationKey: Key): Resolver<K>;\n    cachedCallback(value: ResolveCallback<K>): Resolver<K>;\n    callback(value: ResolveCallback<K>): Resolver<K>;\n    instance(value: K): Resolver<K>;\n    singleton(value: Constructable): Resolver<K>;\n    transient(value: Constructable): Resolver<K>;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"ResolverImpl\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport class ResolverImpl implements Resolver, Registration {\n    // (undocumented)\n    get $isResolver(): true;\n    constructor(key: Key, strategy: ResolverStrategy, state: any);\n    // (undocumented)\n    getFactory(container: Container): Factory | null;\n    // (undocumented)\n    key: Key;\n    // (undocumented)\n    register(container: Container): Resolver;\n    // (undocumented)\n    resolve(handler: Container, requestor: Container): any;\n    // (undocumented)\n    resolveAsync(handler: Container, requestor: Container): Promise<any>;\n    // (undocumented)\n    state: any;\n    // (undocumented)\n    strategy: ResolverStrategy;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"ResolverStrategy\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport const enum ResolverStrategy {\n    // (undocumented)\n    alias = 5,\n    // (undocumented)\n    array = 4,\n    // (undocumented)\n    callback = 3,\n    // (undocumented)\n    instance = 0,\n    // (undocumented)\n    singleton = 1,\n    // (undocumented)\n    transient = 2\n}\n\n// @public\nexport interface ServiceLocator {\n    get<K extends Key>(key: K): Resolved<K>;\n    get<K extends Key>(key: Key): Resolved<K>;\n    get<K extends Key>(key: K | Key): Resolved<K>;\n    getAll<K extends Key>(key: K, searchAncestors?: boolean): readonly Resolved<K>[];\n    getAll<K extends Key>(key: Key, searchAncestors?: boolean): readonly Resolved<K>[];\n    getAll<K extends Key>(key: K | Key, searchAncestors?: boolean): readonly Resolved<K>[];\n    getAsync<K extends Key>(key: K): Promise<Resolved<K>>;\n    getAsync<K extends Key>(key: Key): Promise<Resolved<K>>;\n    getAsync<K extends Key>(key: K | Key): Promise<Resolved<K>>;\n    has<K extends Key>(key: K | Key, searchAncestors: boolean): boolean;\n}\n\n// @public\nexport const ServiceLocator: ContextDecorator<ServiceLocator>;\n\n// Warning: (ae-forgotten-export) The symbol \"singletonDecorator\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport function singleton<T extends Constructable>(): typeof singletonDecorator;\n\n// @public (undocumented)\nexport function singleton<T extends Constructable>(options?: SingletonOptions): typeof singletonDecorator;\n\n// @public\nexport function singleton<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;\n\n// @public\ntype Transformer_2<K> = (instance: Resolved<K>) => Resolved<K>;\nexport { Transformer_2 as Transformer }\n\n// Warning: (ae-forgotten-export) The symbol \"transientDecorator\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport function transient<T extends Constructable>(): typeof transientDecorator;\n\n// @public\nexport function transient<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;\n\n// Warning: (ae-internal-missing-underscore) The name \"validateKey\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport function validateKey(key: any): void;\n\n// Warnings were encountered during analysis:\n//\n// dist/dts/di/di.d.ts:479:5 - (ae-forgotten-export) The symbol \"createContext\" needs to be exported by the entry point di.d.ts\n// dist/dts/di/di.d.ts:540:5 - (ae-forgotten-export) The symbol \"SingletonOptions\" needs to be exported by the entry point di.d.ts\n\n// (No @packageDocumentation comment for this package)\n\n```\n","isInternal":false,"tokens":2835,"sizeBytes":12088},{"name":"fast-element-2.md","path":"packages/fast-element/docs/migration/fast-element-2.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/migration/fast-element-2.md","title":"Migration Skill","category":"anthropic-skill","format":"markdown","content":"# Changes in FASTElement 2.0\n\n## Breaking Changes\n\n* `HTMLDirective` - The `targetIndex: number` property has been replaced by a `targetId: string` property. The `createBehavior` method no longer takes a target `Node` but instead takes a `BehaviorTargets` instance. The actual target can be looked up on the `BehaviorTargets` instance by indexing with the `targetId` property.\n* `compileTemplate()` - Internals have been significantly changed. The implementation no longer uses a TreeWalker. The return type has change to an `HTMLTemplateCompilationResult` with different properties.\n* `View` and `HTMLView` - Type parameters added to enable strongly typed views based on their data source. The constructor of `HTMLView` has a new signature based on changes to the compiler's output. Internals have been cleaned up and no longer rely on the Range type.\n* `ElementViewTemplate`, `SyntheticViewTemplate`, and `ViewTemplate` - Added type parameters throughout. Logic to instantiate and apply behaviors moved out of the template and into the view where it can be lazily executed. Removed the ability of the `render` method to take a string id of the node to render to. You must provide a node.\n* `DOM` - Tree Walker methods are no longer used and are thus removed. The API for removing child nodes has been removed as well since it was only used in one place and could be inlined. The helper `createCustomAttributePlaceholder()` no longer requires an attribute name. It will be uniquely generated internally.\n* `class` - Bindings to `class` are now more nuanced. Binding directly to `class` will simply set the `className` property. If you need to bind to `class` knowing that manual JS will also manipulate the `classList` in addition to the binding, then you should now bind to `:classList` instead. This allows for performance optimizations in the simple, most common case.\n* `Behavior` and `ViewBehavior` - `Behavior` now requires an `ExecutionContext` for `unbind`. Behaviors can be used for elements or views. `ViewBehavior` has been introduced for use exclusively with views, and provides some optimization opportunities.\n* `RefBehavior` has been replaced with `RefDirective`. The directive also implements `ViewBehavior` allowing a single directive instance to be shared across all template instances that use the ref.\n* Removed `SlottedBehavior` and `ChildrenBehavior` have been replaced with `SlottedDirective` and `ChildrenDirective`. These directives allow a single directive instance to be shared across all template instances that use the ref.\n* Removed `AttachedBehaviorHTMLDirective` and `AttachedBehaviorType` since they are no longer used in the new directive/behavior architecture for ref, slotted, and children.\n* Renamed `Notifier#source` to `Notifier#subject` to align with other observable terminology and prevent name clashes with `BindingObserver` properties.","isInternal":false,"tokens":608,"sizeBytes":2880},{"name":"fast-element-3.md","path":"packages/fast-element/docs/migration/fast-element-3.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/migration/fast-element-3.md","title":"Migration Skill","category":"anthropic-skill","format":"markdown","content":"# Migrating from previous versions\n\n## FASTGlobal version tracking (v2 → v3)\n\n### Removed API\n\n| Removed | Replacement |\n|---|---|\n| `FAST.versions` | No replacement. Multiple FAST versions on the same page are unsupported in v3. |\n\n### Removed configuration\n\n| Removed | Replacement |\n|---|---|\n| `fast-kernel=\"share\"` / `fast-kernel=\"share-v2\"` / `fast-kernel=\"isolate\"` | No replacement. FAST now uses a single shared kernel contract, and multiple FAST versions on the same page are unsupported. |\n\n### Migration steps\n\n1. Remove any runtime checks that read `FAST.versions`.\n2. Fix duplicate FAST installs in your bundler or dependency graph instead of relying on version tracking at runtime.\n3. Remove any `fast-kernel` script attributes. They no longer affect FAST initialization.\n\n## Native globals and scheduler requirements (v2 → v3)\n\n### Changed behavior\n\n- **Browser `Window` runtime required**: `@microsoft/fast-element` is a\n  client-side browser runtime. It expects browser DOM, Custom Elements, Shadow\n  DOM, and scheduling APIs such as `requestAnimationFrame`.\n- **Native `globalThis` required**: `@microsoft/fast-element` no longer installs\n  a `globalThis` polyfill as a side effect.\n- **No idle-callback polyfill**: FAST Element v3 no longer installs or depends\n  on a `requestIdleCallback` / `cancelIdleCallback` fallback. The async\n  `Updates` queue schedules work with `globalThis.requestAnimationFrame`.\n\n### Migration steps\n\n1. Verify that the browsers you support provide native `globalThis` and\n   `requestAnimationFrame`.\n2. If you still target an older browser without `globalThis`, load that polyfill\n   before importing `@microsoft/fast-element`.\n3. Do not import or run the FAST Element client runtime in workers,\n   server-side JavaScript runtimes, or other non-window hosts. SSR tools may\n   emit HTML, but hydration and client rendering run in the browser `Window`.\n4. You do not need to polyfill `requestIdleCallback` or `cancelIdleCallback`\n   for FAST Element itself. Only provide them if your application or another\n   dependency calls those APIs directly.\n\n## Declarative HTML moved into fast-element (v3)\n\nDeclarative HTML APIs now ship from focused `@microsoft/fast-element` package\npath exports instead of the removed `@microsoft/fast-html` package.\n\n### Import changes\n\n| Before | After |\n|---|---|\n| `@microsoft/fast-html` | `@microsoft/fast-element/declarative.js` |\n| `@microsoft/fast-html/utilities.js` | `@microsoft/fast-element/declarative-utilities.js` |\n\nCore FAST Element helpers are available from the root package export:\n\n| API | Import path |\n|---|---|\n| `Updates` | `@microsoft/fast-element` |\n| `Observable`, `observable` | `@microsoft/fast-element` |\n| `attr`, `AttributeDefinition`, converters, `ValueConverter` | `@microsoft/fast-element` |\n| `Binding`, `oneWay`, `oneTime`, `listener` | `@microsoft/fast-element` |\n| `DOM`, `DOMAspect`, `DOMPolicy` | `@microsoft/fast-element` |\n| `Schema`, `schemaRegistry`, schema types | `@microsoft/fast-element` |\n| `css` | `@microsoft/fast-element` |\n| `html`, `ViewTemplate`, `HTMLView` | `@microsoft/fast-element` |\n| `Compiler`, `HTMLDirective`, `htmlDirective`, templating/view types | `@microsoft/fast-element` |\n| `render`, `RenderBehavior`, `RenderDirective` | `@microsoft/fast-element` |\n| `enableHydration`, `deferHydrationAttribute`, `HydrationTracker`, hydration types | `@microsoft/fast-element/hydration.js` |\n| `ArrayObserver` | `@microsoft/fast-element` |\n| `volatile` | `@microsoft/fast-element` |\n| `children` | `@microsoft/fast-element` |\n| `elements`, `NodeObservationDirective` | `@microsoft/fast-element` |\n| `ref` | `@microsoft/fast-element` |\n| `slotted` | `@microsoft/fast-element` |\n| `when` | `@microsoft/fast-element` |\n| `repeat` | `@microsoft/fast-element` |\n\n### Migration steps\n\n1. Update declarative runtime imports to\n   `@microsoft/fast-element/declarative.js`.\n2. Update declarative utility imports such as `deepMerge` to\n   `@microsoft/fast-element/declarative-utilities.js`.\n3. Keep importing FAST Element APIs such as `FASTElement`, `FAST`,\n   `ElementController`, definition/controller types, `attr`, `Schema`, and\n   `observable` from `@microsoft/fast-element`.\n4. Call `enableHydration()` from `@microsoft/fast-element/hydration.js` when\n   prerendered content should be hydrated.\n\n## `deepMerge` array replacement\n\nWhen an array's contents change, `deepMerge` replaces the owning property's\narray rather than mutating the existing array in place. This affects both\n`observerMap()`-managed data and direct consumers of the exported helper.\nPreviously captured array references retain the old data; mutating them no\nlonger updates the owning object. Deeply equal arrays are left unchanged.\n\nRe-read the array from its owner after merging:\n\n```ts\nimport { deepMerge } from \"@microsoft/fast-element/declarative-utilities.js\";\n\nconst user = { orders: [{ id: 101 }] };\nconst oldOrders = user.orders;\n\ndeepMerge(user, { orders: [{ id: 103 }] });\n\n// oldOrders still contains order 101 and is disconnected from user.orders.\nuser.orders.push({ id: 104 });\n```\n\nFor `observerMap()`-managed properties, the owning property's notification\ncauses `f-repeat` bindings to observe the replacement array automatically.\nDirect `deepMerge` consumers must still arrange their own change notifications;\nthe helper does not make plain objects observable.\n\n## Optional helper and removed path exports (v2 → v3)\n\nFAST Element v3 adds focused flat path exports for optional helpers and removes\nolder nested or unused package exports. Root imports for core FAST Element APIs\nremain supported, but code that imports helper APIs from older nested paths must\nmove to the flat path exports.\n\n### Import changes\n\n| Before | After |\n|---|---|\n| `@microsoft/fast-element/binding/two-way.js` | `@microsoft/fast-element/two-way.js` |\n| `@microsoft/fast-element/binding/signal.js` | `@microsoft/fast-element/signal.js` |\n| Deep directive imports | `@microsoft/fast-element/children.js`, `@microsoft/fast-element/repeat.js`, `@microsoft/fast-element/when.js`, `@microsoft/fast-element/ref.js`, `@microsoft/fast-element/slotted.js`, or `@microsoft/fast-element/node-observation.js` |\n| Declarative map helpers from old declarative surfaces | `@microsoft/fast-element/attribute-map.js` and `@microsoft/fast-element/observer-map.js` |\n\n### Removed package exports\n\n| Removed | Replacement |\n|---|---|\n| `@microsoft/fast-element/install-element-hydration.js` | No side-effect import. Call `enableHydration()` from `@microsoft/fast-element/hydration.js` when SSR content should hydrate. |\n| `@microsoft/fast-element/install-hydratable-view-templates.js` | No side-effect import. `enableHydration()` installs hydratable template support. |\n| `@microsoft/fast-element/element-hydration.js` | `@microsoft/fast-element/hydration.js` for public hydration APIs. |\n| `@microsoft/fast-element/metadata.js` | No supported public replacement. |\n| `@microsoft/fast-element/testing.js` | No supported public replacement. |\n| `@microsoft/fast-element/pending-task.js` | No supported public replacement. |\n\n### Migration steps\n\n1. Replace older nested helper imports with the flat path exports shown above.\n2. Remove hydration side-effect imports and call `enableHydration()` before FAST\n   elements connect when SSR content should hydrate.\n3. Remove imports from deleted package exports. If your app depended on one of\n   those internals, move that usage into app-owned code or a supported public\n   API.\n\n## `attribute-name-strategy` default changed (v2 → v3)\n\nThe declarative attribute map default changed from `\"none\"` to `\"camelCase\"`.\nWith the default strategy, a binding key such as `{{firstName}}` maps to the\n`firstName` property and the `first-name` HTML attribute. In v2-style\ndeclarative templates that relied on literal attribute names, this can change\nwhich property receives data.\n\n### Migration steps\n\n1. Audit declarative templates for binding keys that contain hyphens or that\n   intentionally matched attribute names exactly.\n2. If you want the v2 behavior, configure the client definition extension with\n   `attributeMap({ \"attribute-name-strategy\": \"none\" })`.\n3. If server-rendered HTML is generated with `@microsoft/fast-build`, pass\n   `--attribute-name-strategy=none` so server and client mapping agree.\n\n## `TemplateOptions` removal (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `TemplateOptions` | No replacement |\n| `PartialFASTElementDefinition.templateOptions` | No replacement |\n| `FASTElementDefinition.templateOptions` | No replacement |\n\n### Changed behavior\n\n- Subclass `define()` calls no longer use `templateOptions` to delay platform\n  definition or connection.\n- Elements can still be defined before a template is attached; a later\n  `FASTElementDefinition.template` update notifies connected elements so they\n  can render or hydrate with the new template.\n\n### Migration steps\n\n1. Remove `templateOptions` from element definitions.\n2. Continue calling `define({ name })` when a definition needs to exist before\n   its template is attached.\n3. If a template is supplied later, assign `FASTElementDefinition.template` (or\n   use the declarative runtime that does so for you).\n\n## `FASTElementDefinition.isRegistered` removal (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `FASTElementDefinition.isRegistered` | `fastElementRegistry.whenRegistered(tagName)`, `fastElementRegistry.getByType(type)`, or `fastElementRegistry.getForInstance(instance)` |\n\n### Migration steps\n\n1. Import `fastElementRegistry` from `@microsoft/fast-element/registry.js`.\n2. Use `fastElementRegistry.whenRegistered(tagName)` when code needs to wait for\n   a definition by tag name.\n3. Use `fastElementRegistry.getByType(type)` or\n   `fastElementRegistry.getForInstance(instance)` when code already has a\n   constructor or element instance.\n\n## Declarative TemplateElement API removal (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `TemplateElement` public export | `declarativeTemplate()` on each FAST element definition |\n| `TemplateElement.define({ name: \"f-template\" })` | No manual definition; `declarativeTemplate()` defines FAST's internal `<f-template>` publisher in the target registry |\n| `TemplateElement.config(callbacks)` / `HydrationLifecycleCallbacks` | `enableHydration().whenHydrated(tagName)` for tag-specific hydration waits and `enableHydration().whenHydrated()` for the active hydration batch |\n| `TemplateElement.options(...)`, `ElementOptions`, `ElementOptionsDictionary` | Define extensions: `attributeMap(...)` and `observerMap(...)` passed as the second argument to `define()` |\n| `AttributeMap` / `ObserverMap` exports from the old declarative public surface | `attributeMap()` / `observerMap()` extension helpers and their config types |\n\n### Migration steps\n\n1. Replace manual `<f-template>` registration with `template: declarativeTemplate()`:\n\n   ```typescript\n   // Before\n   import { TemplateElement } from \"@microsoft/fast-element\";\n   TemplateElement.define({ name: \"f-template\" });\n\n   MyElement.define({ name: \"my-element\" });\n\n   // After\n   import { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n\n   MyElement.define({\n       name: \"my-element\",\n       template: declarativeTemplate(),\n   });\n   ```\n\n2. Replace `TemplateElement.options()` with definition extensions:\n\n   ```typescript\n   import { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\n   import { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n   import { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\n   MyElement.define(\n       {\n           name: \"my-element\",\n           template: declarativeTemplate(),\n       },\n       [attributeMap(), observerMap()],\n   );\n   ```\n\n   `attributeMap()` is imported from\n   `@microsoft/fast-element/attribute-map.js` and `observerMap()` from\n   `@microsoft/fast-element/observer-map.js` for declarative templates,\n   manually supplied schemas, or both. `FASTElementDefinition.schema` is optional;\n   `declarativeTemplate()` assigns it automatically, and `observerMap()` can\n   take a manual schema with `observerMap({ schema })`.\n\n3. Replace `TemplateElement.config()` with `enableHydration().whenHydrated(tagName)`\n   for tag-specific hydration waits and `enableHydration().whenHydrated()` for the\n   active hydration batch.\n   Hydration is not installed by `declarative.js`; call `enableHydration()`\n   before elements connect when SSR content should hydrate.\n\n## Debug entrypoint explicit enablement (v3)\n\n### Import changes\n\n| Before | After |\n|---|---|\n| `import \"@microsoft/fast-element\";` | `import { enableDebug } from \"@microsoft/fast-element/debug.js\"; enableDebug();` |\n\n### Migration steps\n\n1. Replace setup-only `debug.js` imports with an explicit `enableDebug()` call.\n2. Keep using the root package `development` export or debug rollup bundle when\n   you want debug behavior enabled automatically.\n\n## Declarative event handler `e` removal (v3)\n\n### Removed behavior\n\n| Removed | Replacement |\n|---|---|\n| Bare `e` event arguments in declarative event handlers | `$e` |\n| `TemplateParser.hasDeprecatedEventSyntax` | No replacement |\n\nOnly `$e` and `$c` are reserved event handler arguments in declarative\ntemplates. Bare `e` now resolves like any other binding path on the current\ndata source.\n\n### Migration steps\n\n1. Replace declarative event bindings such as\n   `@click=\"{handleClick(e)}\"` with `@click=\"{handleClick($e)}\"`.\n2. Remove any `TemplateParser.hasDeprecatedEventSyntax` checks or warnings from\n   custom tooling.\n\n## Prerendered Content Optimization (v2 → v3)\n\n### Removed and moved APIs\n\n| 2.x API | 3.x guidance |\n|---|---|\n| `HydratableElementController` | `ElementController` (prerendered path built in) |\n| `HydrationControllerCallbacks` | Call `enableHydration()` and await the returned controller's `whenHydrated()` promise |\n| `needsHydrationAttribute` | No replacement. Existing shadow root detection sets `ElementController.isPrerendered`. |\n| Root `deferHydrationAttribute` export | Import `deferHydrationAttribute` from `@microsoft/fast-element/hydration.js` only if you still need the legacy attribute string. New server-rendered markup should omit `defer-hydration`. |\n\n### Removed side-effect imports\n\n| Import | Replacement |\n|---|---|\n| `@microsoft/fast-element/install-hydration.js` | No replacement needed — prerendered path is built into `ElementController` |\n| `@microsoft/fast-element/install-hydratable-view-templates.js` | No replacement needed — `enableHydration()` installs hydratable template support |\n\nUse `enableHydration()` from `@microsoft/fast-element/hydration.js` when SSR\ncontent should hydrate. The declarative entrypoint no longer installs hydration\nautomatically.\n\n### Changed behavior\n\n- **`attributeChangedCallback` during upgrade**: When `isPrerendered` is true and the element has not yet connected, attribute change callbacks are suppressed. After connection, all attribute changes are processed normally.\n- **Declarative template resolution**: `declarativeTemplate()` waits for the\n  matching `<f-template>` before `define()` completes, so connected elements\n  hydrate with a concrete template. No `defer-hydration` attribute is needed.\n- **Binding evaluation with existing shadow root**: When an existing shadow root is detected, `attribute` and `booleanAttribute` bindings skip their initial DOM update. All other binding types (event, content, property, tokenList) run normally.\n\n### New APIs\n\n- **`ElementController.isPrerendered`** (`Promise<boolean>`): Resolves to `true` when the element had a declarative shadow root at connect time, or `false` when the component was client-side rendered.\n- **`ElementController.isHydrated`** (`Promise<boolean>`): Resolves to `true` only when hydration ran successfully.\n- **`ViewController.isPrerendered`** (`Promise<boolean> | undefined`): Available to custom directives. Resolves to `true` when the view's content was prerendered, `false` otherwise.\n- **`ViewController.isHydrated`** (`Promise<boolean> | undefined`): Available to custom directives. Resolves to `true` only when hydration ran successfully.\n\n### Migration steps\n\n1. Remove `HydratableElementController.install()` calls.\n2. Remove `import \"@microsoft/fast-element/install-hydration.js\"` side-effect imports.\n3. Replace `element.$fastController instanceof HydratableElementController` checks with `await element.$fastController.isPrerendered`.\n4. Remove `defer-hydration` and `needs-hydration` attributes from server-rendered markup.\n\n## Hydration Marker Format (v3)\n\n### Changed format\n\nThe hydration markers embedded in SSR output have been simplified from verbose, index-embedded comment markers to compact, data-free sequential markers.\n\n#### Comment markers\n\n| Marker type | Old format | New format |\n|---|---|---|\n| Content binding start | `<!-- fe-b$$start$$<index>$$<scopeId>$$fe-b -->` | `<!--fe:b-->` |\n| Content binding end | `<!-- fe-b$$end$$<index>$$<scopeId>$$fe-b -->` | `<!--fe:/b-->` |\n| Repeat item start | `<!-- fe-repeat$$start$$<itemIndex>$$fe-repeat -->` | `<!--fe:r-->` |\n| Repeat item end | `<!-- fe-repeat$$end$$<itemIndex>$$fe-repeat -->` | `<!--fe:/r-->` |\n| Element boundary start | `<!-- fe-eb$$start$$<elementId>$$fe-eb -->` | `<!--fe:e-->` |\n| Element boundary end | `<!-- fe-eb$$end$$<elementId>$$fe-eb -->` | `<!--fe:/e-->` |\n\n#### Attribute binding markers\n\n| Old format | New format |\n|---|---|\n| `data-fe-b=\"0 1 2\"` (space-separated indices) | `data-fe=\"N\"` (binding count) |\n| `data-fe-b-0` (enumerated, one per factory) | `data-fe=\"N\"` |\n| `data-fe-c-0-3` (compact, start index + count) | `data-fe=\"N\"` |\n\n### Removed APIs\n\n| Export | Replacement |\n|---|---|\n| `HydrationMarkup.contentBindingStartMarker(index, scopeId)` | `HydrationMarkup.contentBindingStartMarker()` |\n| `HydrationMarkup.contentBindingEndMarker(index, scopeId)` | `HydrationMarkup.contentBindingEndMarker()` |\n| `HydrationMarkup.isContentBindingStartMarker(data)` | `HydrationMarkup.isContentBindingStartMarker(data)` (unchanged signature, new implementation) |\n| `HydrationMarkup.isContentBindingEndMarker(data)` | `HydrationMarkup.isContentBindingEndMarker(data)` (unchanged signature, new implementation) |\n| `HydrationMarkup.parseAttributeBinding(element)` | `HydrationMarkup.parseAttributeBindingCount(element)` |\n| `HydrationMarkup.parseRepeatStartMarker(data)` | `HydrationMarkup.isRepeatViewStartMarker(data)` |\n| `HydrationMarkup.parseRepeatEndMarker(data)` | `HydrationMarkup.isRepeatViewEndMarker(data)` |\n| `HydrationMarkup.parseElementBoundaryStartMarker(content)` | `HydrationMarkup.isElementBoundaryStartMarker(node)` |\n| `HydrationMarkup.parseElementBoundaryEndMarker(content)` | `HydrationMarkup.isElementBoundaryEndMarker(node)` |\n\n### Impact\n\nThis is a **breaking change** for SSR output format. Any system that produces or parses hydration markers must be updated to use the new format. The `@microsoft/fast-build` Rust crate and WASM binary have been updated accordingly.\n\n- Marker parsing uses string equality checks (`data === \"fe:b\"`) instead of regex\n- Start/end pairing uses balanced depth counting instead of embedded IDs\n- The hydration walker uses a sequential factory pointer instead of index-based lookup\n- SSR and client versions must match — mixing old SSR output with new client code (or vice versa) will fail\n\n## Async define/compose/register API (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `FASTElement.defineAsync()` | Subclass `define()` calls |\n| `FASTElement.compose()` and subclass `compose()` calls | Subclass `define()` calls |\n| `FASTElementDefinition.composeAsync()` | Subclass `define()` calls |\n| `FASTElementDefinition.registerAsync()` | `FASTElementDefinition.register()` (same `Promise<Function>` return type) |\n\n### Changed behavior\n\n- Subclass **`define()`** calls return `Promise<TType>` only for code that\n  explicitly needs to observe registration completion. When\n  `template: declarativeTemplate()` is used, that Promise resolves after the\n  matching `<f-template>` supplies the concrete template.\n- Subclass compose helpers are no longer part of the public authoring surface; use subclass `define()` for registration.\n- **`@customElement` decorator** calls `define()` internally but does not return the Promise (fire-and-forget). For complete definitions with a template, the element is registered via a microtask.\n\n### Migration steps\n\n1. Replace `defineAsync()` calls with `define()`:\n\n   ```typescript\n    // Before\n    MyElement.defineAsync({\n        name: \"my-element\",\n        templateOptions: \"defer-and-hydrate\",\n    });\n\n    // After\n    MyElement.define({\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    });\n   ```\n\n2. Replace subclass `compose()` calls that immediately register an element with\n   `define()`:\n\n   ```typescript\n    // Before\n    MyElement.compose({\n        name: \"my-element\",\n        template,\n        styles,\n    }).define();\n\n    // After\n    MyElement.define({\n        name: \"my-element\",\n        template,\n        styles,\n    });\n   ```\n\n3. Replace `FASTElementDefinition.composeAsync()` calls that register an element\n   with subclass `define()`:\n\n   ```typescript\n   // Before\n   (await FASTElementDefinition.composeAsync(MyElement, {\n       name: \"my-element\",\n       template,\n       styles,\n   })).define();\n\n   // After\n   MyElement.define({\n       name: \"my-element\",\n       template,\n       styles,\n   });\n   ```\n\n4. Replace `registerAsync()` calls with `register()`:\n\n   ```typescript\n   // Before\n   const el = await FASTElementDefinition.registerAsync(name);\n\n   // After\n   const el = await FASTElementDefinition.register(name);\n   ```\n\n5. Replace `FASTElementDefinition.compose()` calls that chain `.define()` with\n   subclass `define()`:\n\n   ```typescript\n    // Before\n    FASTElementDefinition.compose(MyElement, options).define();\n\n    // After\n    MyElement.define(options);\n   ```\n\n## Dynamic stylesheet behaviors (v3)\n\n### Removed API\n\n| Removed | Replacement |\n|---|---|\n| `ElementStyles.withBehaviors()` | Move the runtime condition into the element and call `this.$fastController.addStyles()` / `this.$fastController.removeStyles()` directly. |\n| `ElementStyles.behaviors` | Move any runtime behavior out of the stylesheet and into the element or controller lifecycle. |\n| CSS bindings in `css` (for example ``css`color: ${x => x.color}```) | Move the dynamic value into the element and update classes, attributes, or inline styles from element code. |\n| `CSSDirective.createCSS(add)` | Update directives to implement `createCSS()` and return only static CSS content. |\n\n### Changed behavior\n\n- `css` and `css.partial()` no longer compose `HostBehavior`s.\n- `css` no longer accepts function or `Binding` interpolations.\n- `ElementStyles` is now a fully static style container.\n\n### Migration steps\n\n1. Keep the conditional `ElementStyles` in a separate `css` value.\n2. Move the external listener or condition (for example `matchMedia()` or an app event subscription) into the element lifecycle.\n3. Call `this.$fastController.addStyles(styles)` when the condition is active and `this.$fastController.removeStyles(styles)` when it is inactive or during cleanup.\n4. If you previously interpolated bindings or behavior-producing directives into `css`, replace them with element state and standard DOM or controller updates.\n\n## `booleanConverter` aligned with native HTML boolean attribute semantics (v2 → v3)\n\n### Changed behavior\n\n`@attr({ mode: \"boolean\" })` and `booleanConverter` now match how the platform treats native boolean attributes (e.g., `disabled`, `required`):\n\n- **Attribute → property** is presence-based: `setAttribute(name, anyString)` (including the empty string) sets the property to `true`; only `removeAttribute(name)` makes it `false`.\n- **Property → attribute** uses `Boolean()` coercion: any JavaScript truthy value adds the attribute (with value `\"\"`); any falsy value removes it.\n\nThe headline v2 → v3 difference is that `setAttribute(name, \"false\")` now resolves to property `true`, matching `<input disabled=\"false\">` still being disabled.\n\n`booleanConverter` shape:\n\n```ts\ntoView(value: any) {\n    return value ? \"\" : null;\n}\n\nfromView(value: any) {\n    return !!value;\n}\n```\n\n`booleanConverter` v2 → v3 result differences:\n\n| Call | v2 result | v3 result |\n|---|---|---|\n| `fromView(\"false\")` | `false` | `true` |\n| `fromView(\"\")` | `true` | `false` |\n| `fromView(NaN)` | `true` | `false` |\n| `toView(true)` (or any truthy) | `\"true\"` | `\"\"` |\n| `toView(false)` (or any falsy) | `\"false\"` | `null` |\n\n> **Note**: For `mode: \"boolean\"`, FAST writes attributes via `DOM.setBooleanAttribute` (presence-based) and reads them as `value !== null`, so the `mode: \"boolean\"` reflection path does **not** route through `booleanConverter.toView()` or `booleanConverter.fromView()`. The converter methods still apply to property assignment (`el.bool = X` runs `fromView(X)`), explicit calls (`booleanConverter.fromView(x)`), and `booleanConverter` paired with `mode: \"reflect\"` (which calls `toView`).\n\n### Migration steps\n\n1. Audit `boolean`-mode attributes for the literal string `\"false\"` in templates or SSR HTML — the resulting property will be `true`, not `false`. To express the falsy state, omit the attribute entirely (or call `element.removeAttribute(name)`). Setting `element.bool = false` continues to remove the reflected attribute.\n2. Audit code that calls `booleanConverter.toView()` directly or pairs `booleanConverter` with `mode: \"reflect\"`. The output strings are no longer `\"true\"` / `\"false\"`.\n3. If you need a tri-state attribute (`true` / `false` / unset) that preserves an explicit `\"false\"` string value, use `nullableBooleanConverter` with `mode: \"reflect\"` instead of `mode: \"boolean\"`.\n","isInternal":false,"tokens":6087,"sizeBytes":25868},{"name":"fast-html.md","path":"packages/fast-element/docs/migration/fast-html.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/migration/fast-html.md","title":"Migration Skill","category":"anthropic-skill","format":"markdown","content":"# Migrating from previous versions\n\n## Hydration Marker Format (v1-alpha → v1)\n\nThe SSR output format for hydration markers has been simplified. If you have any tooling that inspects or generates hydration markers, update it to use the new format.\n\n| Old marker | New marker |\n|---|---|\n| `<!-- fe-b$$start$$...$$fe-b -->` | `<!--fe:b-->` |\n| `<!-- fe-b$$end$$...$$fe-b -->` | `<!--fe:/b-->` |\n| `<!-- fe-repeat$$start$$...$$fe-repeat -->` | `<!--fe:r-->` |\n| `<!-- fe-repeat$$end$$...$$fe-repeat -->` | `<!--fe:/r-->` |\n| `data-fe-b=\"0 1 2\"` / `data-fe-b-0` / `data-fe-c-0-3` | `data-fe=\"N\"` |\n\nThe `@microsoft/fast-build` WASM binary emits the new markers automatically. Rebuild all fixtures and SSR output after upgrading.\n\nSee the [`@microsoft/fast-element` migration guide](./fast-element-3.md#hydration-marker-format-v3) for full details on API changes.\n\n## Prerendered Content Optimization (v1-alpha → v1)\n\n### Removed exports\n\n| Export | Replacement |\n|---|---|\n| `RenderableFASTElement` | Extend `FASTElement` |\n\n### Removed concepts\n\n| Concept | Replacement |\n|---|---|\n| `prepare()` lifecycle hook | Set state in `connectedCallback`; the reactive system updates the DOM |\n| `defer-hydration` attribute in rendered markup | Template-pending guard in `ElementController.connect()` |\n| `needs-hydration` attribute in rendered markup | `hasExistingShadowRoot` detection in `ElementController` |\n| `waitForAncestorHydration()` | Not needed — prerendered content is correct regardless of connection order |\n\n### Migration steps\n\n1. Replace `RenderableFASTElement(MyComponent).defineAsync({...})` with\n   `MyComponent.define({...})` and use `declarativeTemplate()` for declarative\n   templates. If code explicitly observes the Promise returned by `define()`,\n   it resolves after the matching `<f-template>` supplies the concrete template.\n\n   ```typescript\n   // Before\n   import { RenderableFASTElement } from \"@microsoft/fast-html\";\n   RenderableFASTElement(MyComponent).defineAsync({\n       name: \"my-component\",\n       templateOptions: \"defer-and-hydrate\",\n   });\n\n   // After\n   MyComponent.define({\n       name: \"my-component\",\n       template: declarativeTemplate(),\n   });\n   ```\n\n2. Remove `prepare()` methods. Move any initialization logic to `connectedCallback`:\n\n   ```typescript\n   // Before\n   class MyComponent extends FASTElement {\n       async prepare() {\n           this.data = await fetchData();\n       }\n   }\n\n   // After\n   class MyComponent extends FASTElement {\n       connectedCallback() {\n           super.connectedCallback();\n           this.loadData();\n       }\n       async loadData() {\n           this.data = await fetchData();\n       }\n   }\n   ```\n\n3. Remove `defer-hydration` and `needs-hydration` attributes from server-rendered markup:\n\n   ```html\n   <!-- Before -->\n   <my-component defer-hydration needs-hydration text=\"Hello\">\n       <template shadowrootmode=\"open\">...</template>\n   </my-component>\n\n   <!-- After -->\n   <my-component text=\"Hello\">\n       <template shadowrootmode=\"open\">...</template>\n   </my-component>\n   ```\n\n4. Await `$fastController.isPrerendered` to detect prerendered components:\n\n   ```typescript\n   connectedCallback() {\n       super.connectedCallback();\n       this.$fastController.isPrerendered.then(prerendered => {\n           if (!prerendered) {\n               this.fetchData();\n           }\n       });\n   }\n   ```\n\n## Modularize Schema, ObserverMap, and AttributeMap\n\n### Import changes\n\nConfiguration types have moved from `template.ts` to their owning modules. If you import types directly from internal paths, update your imports:\n\n| Before | After |\n|---|---|\n| `import type { ObserverMapConfig } from \"./template.js\"` | `import type { ObserverMapConfig } from \"./observer-map.js\"` |\n| `import type { AttributeMapConfig } from \"./template.js\"` | `import type { AttributeMapConfig } from \"./attribute-map.js\"` |\n\nPublic declarative imports now come from\n`@microsoft/fast-element/declarative.js` rather than\n`@microsoft/fast-html`, and declarative utilities come from\n`@microsoft/fast-element/declarative-utilities.js`. Map extensions come from\n`@microsoft/fast-element/attribute-map.js` and\n`@microsoft/fast-element/observer-map.js`.\n\n### Schema changes\n\n`Schema.jsonSchemaMap` (static property) has been replaced by:\n- An instance-level `schemaMap` on each `Schema` instance (private)\n- A module-level `schemaRegistry` export for cross-element lookups\n\n| Before | After |\n|---|---|\n| `Schema.jsonSchemaMap.get('my-element')` | `import { schemaRegistry } from \"@microsoft/fast-element\"; schemaRegistry.get('my-element')` |\n\n### Public exports\n\nThe public entrypoint exports the functional declarative API:\n\n| Export | Purpose |\n|---|---|\n| `declarativeTemplate()` | Resolves `<f-template>` markup for a FAST element definition |\n| `attributeMap()` | Definition extension for automatic `@attr` property registration |\n| `observerMap()` | Definition extension for automatic deep observation |\n| `Schema` | JSON schema builder class |\n| `schemaRegistry` | Module-level registry for cross-element schema lookups |\n| `JSONSchema` | JSON Schema type interface |\n| `CachedPathMap` | Schema registry map type |\n\n## Simplified ObserverMap and AttributeMap defaults\n\nThe explicit `ObserverMapOption.all` and `AttributeMapOption.all` constants have\nbeen removed. Calling `observerMap()` with no arguments observes every\ndiscovered root property, and calling `attributeMap()` with no arguments maps\nevery discovered leaf binding.\n\n| Before | After |\n|---|---|\n| `observerMap(ObserverMapOption.all)` | `observerMap()` |\n| `attributeMap(AttributeMapOption.all)` | `attributeMap()` |\n\n## Attribute name strategy default changed\n\nThe default `attribute-name-strategy` for declarative attribute mapping is now\n`\"camelCase\"` instead of `\"none\"`. A binding key such as `{{firstName}}` maps to\nthe `firstName` property and the `first-name` HTML attribute by default. If your\ntemplates depended on literal attribute names, opt back in to the old behavior:\n\n```ts\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\n\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [attributeMap({ \"attribute-name-strategy\": \"none\" })],\n);\n```\n\nWhen using `@microsoft/fast-build`, keep the server and client settings aligned:\n\n```bash\nfast build --attribute-name-strategy=none\n```\n\n## Declarative TemplateElement API removal\n\nThe public declarative API is now the functional API. The `<f-template>`\nimplementation is internal and is defined automatically by `declarativeTemplate()`.\n\n| Removed | Replacement |\n|---|---|\n| `TemplateElement` public export | `declarativeTemplate()` on each FAST element definition |\n| `TemplateElement.define({ name: \"f-template\" })` | No manual definition; `declarativeTemplate()` defines the internal publisher in the target registry |\n| `TemplateElement.config(callbacks)` / `HydrationLifecycleCallbacks` | `enableHydration().whenHydrated(tagName)` for tag-specific hydration waits and `enableHydration().whenHydrated()` for the active hydration batch |\n| `TemplateElement.options({ \"my-el\": { attributeMap, observerMap } })` | Define extensions: `MyElement.define(definition, [attributeMap(...), observerMap(...)])` |\n| `ElementOptions` / `ElementOptionsDictionary` | No replacement |\n| `AttributeMap` / `ObserverMap` class exports from the old declarative public surface | `attributeMap()` / `observerMap()` extension helpers and their config types |\n\nHydration is also no longer installed by `@microsoft/fast-element`.\nCall `enableHydration()` from `@microsoft/fast-element/hydration.js` before FAST\nelements connect when prerendered Declarative Shadow DOM should be reused.\n\n## Schema-driven maps and optional definition schema\n\n`attributeMap()` and `observerMap()` are now schema-driven extensions that are\nfactored away from declarative templating. Import them from\n`@microsoft/fast-element` for declarative or non-declarative use:\n\n```ts\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n```\n\n`FASTElementDefinition.schema` is optional. `declarativeTemplate()` assigns it\nautomatically when it parses `<f-template>` markup. Manual schema users can pass\na schema in the element definition, and `observerMap()` can also take a schema\ndirectly in configuration:\n\n```ts\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-element\");\nschema.addPath({\n    rootPropertyName: \"user\",\n    pathConfig: {\n        type: \"default\",\n        parentContext: null,\n        currentContext: null,\n        path: \"user.name\",\n    },\n    childrenMap: null,\n});\n\nMyElement.define({ name: \"my-element\" }, [observerMap({ schema })]);\n```\n","isInternal":false,"tokens":2073,"sizeBytes":8922},{"name":"api-report.api.md","path":"packages/fast-element/docs/styles/api-report.api.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/styles/api-report.api.md","title":"Styles Skill","category":"anthropic-skill","format":"markdown","content":"## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport type ComposableStyles = string | ElementStyles | CSSStyleSheet;\n\n// @public\nexport type Constructable<T = {}> = {\n    new (...args: any[]): T;\n};\n\n// @public\nexport type ConstructibleStyleStrategy = {\n    new (styles: (string | CSSStyleSheet)[]): StyleStrategy;\n};\n\n// @public\nexport interface CSSDirective {\n    createCSS(): ComposableStyles;\n}\n\n// @public\nexport const CSSDirective: Readonly<{\n    getForInstance: (object: any) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    getByType: (key: Function) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    define<TType extends Constructable<CSSDirective>>(type: any): TType;\n}>;\n\n// @public\nexport function cssDirective(): (type: Constructable<CSSDirective>) => void;\n\n// @public\nexport interface CSSDirectiveDefinition<TType extends Constructable<CSSDirective> = Constructable<CSSDirective>> {\n    readonly type: TType;\n}\n\n// @public\nexport class ElementStyles {\n    constructor(styles: ReadonlyArray<ComposableStyles>);\n    // @internal (undocumented)\n    addStylesTo(target: StyleTarget): void;\n    // @internal (undocumented)\n    isAttachedTo(target: StyleTarget): boolean;\n    static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;\n    // @internal (undocumented)\n    removeStylesFrom(target: StyleTarget): void;\n    static setDefaultStrategy(Strategy: ConstructibleStyleStrategy): void;\n    get strategy(): StyleStrategy;\n    // (undocumented)\n    readonly styles: ReadonlyArray<ComposableStyles>;\n    static readonly supportsAdoptedStyleSheets: boolean;\n    withStrategy(Strategy: ConstructibleStyleStrategy): this;\n}\n\n// @public\nexport interface ExecutionContext<TParent = any> {\n    readonly event: Event;\n    eventDetail<TDetail>(): TDetail;\n    eventTarget<TTarget extends EventTarget>(): TTarget;\n    index: number;\n    readonly isEven: boolean;\n    readonly isFirst: boolean;\n    readonly isInMiddle: boolean;\n    readonly isLast: boolean;\n    readonly isOdd: boolean;\n    length: number;\n    parent: TParent;\n    parentContext: ExecutionContext<TParent>;\n}\n\n// @public\nexport const ExecutionContext: Readonly<{\n    default: ExecutionContext;\n    getEvent(): Event | null;\n    setEvent(event: Event | null): void;\n}>;\n\n// @public\nexport interface ExpressionController<TSource = any, TParent = any> {\n    readonly context: ExecutionContext<TParent>;\n    readonly isBound: boolean;\n    onUnbind(behavior: {\n        unbind(controller: ExpressionController<TSource, TParent>): any;\n    }): void;\n    readonly source: TSource;\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface HostBehavior<TSource = any> {\n    addedCallback?(controller: HostController<TSource>): void;\n    connectedCallback?(controller: HostController<TSource>): void;\n    disconnectedCallback?(controller: HostController<TSource>): void;\n    removedCallback?(controller: HostController<TSource>): void;\n}\n\n// @public\nexport interface HostController<TSource = any> extends ExpressionController<TSource> {\n    addBehavior(behavior: HostBehavior<TSource>): void;\n    addStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    readonly isConnected: boolean;\n    mainStyles: ElementStyles | null;\n    removeBehavior(behavior: HostBehavior<TSource>, force?: boolean): void;\n    removeStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n}\n\n// @public\nexport const SourceLifetime: Readonly<{\n    readonly unknown: undefined;\n    readonly coupled: 1;\n}>;\n\n// @public\nexport type SourceLifetime = (typeof SourceLifetime)[keyof typeof SourceLifetime];\n\n// @public\nexport interface StyleStrategy {\n    addStylesTo(target: StyleTarget): void;\n    removeStylesFrom(target: StyleTarget): void;\n}\n\n// @public\nexport interface StyleTarget extends Pick<Node, \"getRootNode\"> {\n    adoptedStyleSheets?: CSSStyleSheet[];\n    append(styles: HTMLStyleElement): void;\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\n    removeChild(styles: HTMLStyleElement): void;\n}\n\n// (No @packageDocumentation comment for this package)\n\n```\n","isInternal":false,"tokens":954,"sizeBytes":4309},{"name":"template-bindings.md","path":"packages/fast-element/docs/template-bindings.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/docs/template-bindings.md","title":"Docs Skill","category":"anthropic-skill","format":"markdown","content":"# FAST Element Template Bindings Architecture\n\nThis document explains how the FAST Element `html` tagged template system stores bindings, applies them to DOM elements, triggers updates on data changes, and handles HTML-specific behaviors like event listeners.\n\n## Overview\n\nThe template binding pipeline has five major stages:\n\n1. **Template Authoring** – The `html` tagged template collects binding expressions and builds placeholder-marked HTML.\n2. **Compilation** – The compiler parses the placeholder HTML into a `DocumentFragment`, walks the DOM tree, and records where each binding targets.\n3. **View Creation** – The compiled result clones the fragment and creates a *targets* object that maps each binding to its DOM node.\n4. **Binding (first render)** – Each factory creates a behavior that attaches to its target node: adding event listeners, setting attributes, or observing expressions.\n5. **Reactive Updates** – When observed data changes, one-way binding observers notify their directive, which re-evaluates the expression and pushes the new value to the DOM through a \"sink\" function.\n\n---\n\n## Mermaid Diagrams\n\n### 1. Template Creation & Storage\n\nThis diagram shows how the `html` tagged template literal processes interpolated values and stores them as factories keyed by unique IDs.\n\n```mermaid\nflowchart TD\n    A[\"html`&lt;div class='${expr}'&gt;${text}&lt;/div&gt;`\"] --> B[\"ViewTemplate.create(strings, values)\"]\n    B --> C{\"For each interpolated value\"}\n    C -->|Function| D[\"Wrap in oneWay() → HTMLBindingDirective\"]\n    C -->|Binding instance| E[\"Wrap in HTMLBindingDirective\"]\n    C -->|HTMLDirective| F[\"Use directly\"]\n    C -->|Static value| G[\"Wrap in oneTime() → HTMLBindingDirective\"]\n    D --> H[\"directive.createHTML(add)\"]\n    E --> H\n    F --> H\n    G --> H\n    H --> I[\"add(factory) assigns unique ID\"]\n    I --> J[\"factories Record&lt;string, ViewBehaviorFactory&gt;\"]\n    I --> K[\"Returns placeholder marker in HTML string\"]\n    K --> L[\"Aspect Detection via lastAttributeNameRegex\"]\n    L -->|In attribute context| M[\"HTMLDirective.assignAspect(directive, attrName)\"]\n    L -->|In text content| N[\"aspectType = DOMAspect.content\"]\n    M --> O{\"Attribute prefix\"}\n    O -->|No prefix| P[\"DOMAspect.attribute\"]\n    O -->|: prefix| Q[\"DOMAspect.property\"]\n    O -->|? prefix| R[\"DOMAspect.booleanAttribute\"]\n    O -->|\"@\" prefix| S[\"DOMAspect.event\"]\n    O -->|:classList| T[\"DOMAspect.tokenList\"]\n    J --> U[\"new ViewTemplate(html, factories)\"]\n```\n\n### 2. Compilation – Walking the DOM & Storing Target Locations\n\nThe compiler transforms the placeholder-laden HTML into a `DocumentFragment` and builds a prototype with lazy property descriptors that navigate to target nodes by child index.\n\n```mermaid\nflowchart TD\n    A[\"ViewTemplate.compile()\"] --> B[\"Compiler.compile(html, factories, policy)\"]\n    B --> C[\"Create HTMLTemplateElement\"]\n    C --> D[\"template.innerHTML = policy.createHTML(html)\"]\n    D --> E[\"document.adoptNode(template.content) → fragment\"]\n    E --> F[\"new CompilationContext(fragment, factories, policy)\"]\n    F --> G[\"compileAttributes(context, template, 'h') — host bindings\"]\n    G --> H[\"compileChildren(context, fragment, 'r') — root\"]\n\n    H --> I{\"For each child node\"}\n    I -->|Element node type=1| J[\"compileAttributes: parse each attribute value\"]\n    J --> K{\"Parser.parse finds placeholders?\"}\n    K -->|Yes| L[\"Remove attribute from DOM\"]\n    L --> M[\"context.addFactory(factory, parentId, nodeId, index, tagName)\"]\n    I -->|Element node| N[\"compileChildren recursively\"]\n    I -->|Text node type=3| O[\"compileContent: Parser.parse text\"]\n    O --> P{\"Placeholders found?\"}\n    P -->|Yes| Q[\"Split text node, insert new text nodes\"]\n    Q --> R[\"context.addFactory for each directive part\"]\n    I -->|Comment node type=8| S[\"Parser.parse comment data\"]\n    S --> T[\"context.addFactory for structural directives\"]\n\n    M --> U[\"addTargetDescriptor(parentId, nodeId, childIndex)\"]\n    U --> V[\"Lazy getter: this[parentId].childNodes[childIndex]\"]\n    V --> W[\"Stored in descriptors → prototype via Object.create\"]\n\n    subgraph \"Target Node ID Scheme\"\n        X[\"Root: 'r'\"]\n        Y[\"Host: 'h'\"]\n        Z[\"Children: 'r.0', 'r.1', 'r.0.2'\"]\n        AA[\"Encodes DOM tree path via dot-separated child indices\"]\n    end\n\n    W --> AB[\"context.freeze() → compilation result\"]\n```\n\n### 3. View Creation – Cloning the Fragment & Resolving Targets\n\n```mermaid\nflowchart TD\n    A[\"compilationResult.createView(hostBindingTarget?)\"] --> B[\"fragment.cloneNode(true) → new DocumentFragment\"]\n    B --> C[\"targets = Object.create(proto)\"]\n    C --> D[\"targets.r = fragment (root)\"]\n    D --> E[\"targets.h = hostBindingTarget (host element)\"]\n    E --> F{\"For each registered nodeId\"}\n    F --> G[\"Access targets[nodeId] — triggers lazy getter chain\"]\n    G --> H[\"Getter resolves: this[parentId].childNodes[childIndex]\"]\n    H --> I[\"Caches result in targets._nodeId field\"]\n    I --> J[\"new HTMLView(fragment, factories, targets)\"]\n\n    subgraph \"HTMLView Structure\"\n        K[\"fragment: DocumentFragment with cloned DOM\"]\n        L[\"factories: CompiledViewBehaviorFactory[]\"]\n        M[\"targets: ViewBehaviorTargets {nodeId → Node}\"]\n        N[\"firstChild / lastChild: boundary nodes\"]\n        O[\"source: null (until bound)\"]\n        P[\"behaviors: null (created on first bind)\"]\n    end\n    J --> K\n    J --> L\n    J --> M\n```\n\n### 4. Binding – Attaching Behaviors to DOM Nodes\n\n```mermaid\nflowchart TD\n    A[\"view.bind(source)\"] --> B{\"First bind?\"}\n    B -->|Yes| C[\"Set view.source = source\"]\n    C --> D[\"Create behaviors array\"]\n    D --> E{\"For each factory\"}\n    E --> F[\"factory.createBehavior()\"]\n    F --> G[\"Select sink from sinkLookup based on aspectType\"]\n    G --> H[\"Wrap sink through policy.protect()\"]\n    H --> I[\"behavior.bind(controller/view)\"]\n\n    B -->|Subsequent| J[\"Unbind previous, set new source\"]\n    J --> K[\"Re-bind existing behaviors\"]\n\n    I --> L{\"aspectType?\"}\n\n    L -->|DOMAspect.event| M[\"Store controller ref on target node\"]\n    M --> N[\"target.addEventListener(targetAspect, directive, options)\"]\n    N --> O[\"directive IS the EventListener via handleEvent()\"]\n\n    L -->|DOMAspect.content| P[\"Register unbind handler\"]\n    P --> Q[\"Create observer via dataBinding.createObserver()\"]\n\n    L -->|attribute / property / etc.| Q\n\n    Q --> R[\"observer.bind(controller) → evaluates expression\"]\n    R --> S[\"updateTarget(target, aspect, value, controller)\"]\n\n    subgraph \"Sink Functions (sinkLookup)\"\n        S1[\"attribute → DOM.setAttribute(target, name, value)\"]\n        S2[\"booleanAttribute → DOM.setBooleanAttribute(target, name, value)\"]\n        S3[\"property → target[name] = value\"]\n        S4[\"content → updateContent() — manages text or composed views\"]\n        S5[\"tokenList → updateTokenList() — classList with versioning\"]\n        S6[\"event → no-op (handled via addEventListener)\"]\n    end\n```\n\n### 5. Reactive Update Cycle – Change Detection & DOM Updates\n\n```mermaid\nsequenceDiagram\n    participant Source as Data Source\n    participant Observable as Observable System\n    participant Observer as ExpressionObserver (OneWayBinding)\n    participant Directive as HTMLBindingDirective\n    participant Sink as UpdateTarget (sink fn)\n    participant DOM as Target DOM Node\n\n    Note over Source,DOM: Initial Bind\n    Directive->>Observer: dataBinding.createObserver(directive, directive)\n    Observer->>Source: Evaluate expression (tracks property access)\n    Source-->>Observer: Return value + record dependencies\n    Directive->>Sink: updateTarget(target, aspect, value, controller)\n    Sink->>DOM: Apply value (setAttribute, textContent, etc.)\n\n    Note over Source,DOM: Data Change\n    Source->>Observable: Property setter triggered\n    Observable->>Observer: Notify subscriber of change\n    Observer->>Directive: handleChange(binding, observer)\n    Directive->>Observer: observer.bind(controller) — re-evaluate\n    Observer->>Source: Re-evaluate expression\n    Source-->>Observer: Return new value\n    Directive->>Sink: updateTarget(target, aspect, newValue, controller)\n    Sink->>DOM: Update DOM with new value\n```\n\n### 6. Event Handling – Click Events and Other DOM Events\n\n```mermaid\nsequenceDiagram\n    participant User as User Interaction\n    participant DOM as Target DOM Element\n    participant Directive as HTMLBindingDirective (EventListener)\n    participant Context as ExecutionContext\n    participant Binding as dataBinding.evaluate()\n    participant Source as Component Source\n\n    Note over DOM: During bind: target.addEventListener(\"click\", directive)\n    Note over DOM: directive stores controller ref on target[data]\n\n    User->>DOM: Click event fires\n    DOM->>Directive: handleEvent(event)\n    Directive->>DOM: Read controller from event.currentTarget[data]\n    Directive->>Directive: Check controller.isBound\n    Directive->>Context: ExecutionContext.setEvent(event)\n    Directive->>Binding: evaluate(controller.source, controller.context)\n    Binding->>Source: Execute handler: (s, c) => s.handleClick(c.event)\n    Source-->>Binding: Return result\n    Binding-->>Directive: Return result\n    alt result !== true\n        Directive->>DOM: event.preventDefault()\n    end\n    Directive->>Context: ExecutionContext.setEvent(null)\n```\n\n### 7. Content Binding – Template Composition\n\nWhen a binding expression returns a `ContentTemplate` (e.g., another `ViewTemplate`), the content update sink composes a child view into the DOM.\n\n```mermaid\nflowchart TD\n    A[\"updateContent(target, aspect, value, controller)\"] --> B{\"value is null/undefined?\"}\n    B -->|Yes| C[\"Treat as empty string\"]\n    B -->|No| D{\"value.create exists? (ContentTemplate)\"}\n\n    D -->|Yes — Template| E[\"Clear target.textContent\"]\n    E --> F{\"Existing view on target.$fastView?\"}\n    F -->|No| G[\"view = value.create()\"]\n    F -->|Yes, same template| H[\"Reuse existing view\"]\n    F -->|Yes, different template| I[\"Remove old view, create new\"]\n    G --> J[\"view.bind(source, context)\"]\n    I --> J\n    J --> K[\"view.insertBefore(target)\"]\n    K --> L[\"Cache: target.$fastView = view, target.$fastTemplate = value\"]\n\n    D -->|No — Primitive| M{\"Existing composed view?\"}\n    M -->|Yes| N[\"view.remove(), view.unbind()\"]\n    N --> O[\"target.textContent = value\"]\n    M -->|No| O\n```\n\n---\n\n## Key Data Structures\n\n| Structure | Location | Purpose |\n|---|---|---|\n| `ViewTemplate` | template.ts | Holds raw HTML + factories record. Entry point for compilation. |\n| `factories: Record<string, ViewBehaviorFactory>` | template.ts | Maps unique IDs to binding factories (directives). |\n| `CompilationContext` | compiler.ts | Accumulates factories and builds the target prototype during compilation. |\n| `targets: ViewBehaviorTargets` | view.ts / html-directive.ts | Maps node IDs (e.g., `\"r.0.2\"`) to actual DOM nodes in a cloned fragment. |\n| `HTMLView` | view.ts | The live view instance: holds the fragment, factories, targets, behaviors, and source. |\n| `HTMLBindingDirective` | html-binding-directive.ts | The core binding: acts as factory, behavior, and event listener. |\n| `sinkLookup` | html-binding-directive.ts | Maps `DOMAspect` types to DOM update functions. |\n| `Binding` (abstract) | binding/binding.ts | Wraps an expression with policy, volatility, and observer creation. |\n| `ExpressionObserver` | observation/observable.ts | Tracks dependencies during expression evaluation and notifies on change. |\n\n## Binding Type Summary\n\n| Markup Syntax | Aspect Type | Sink Function | Example |\n|---|---|---|---|\n| `attr=\"${x => x.val}\"` | `attribute` | `DOM.setAttribute` | `class=\"${x => x.cls}\"` |\n| `?attr=\"${x => x.val}\"` | `booleanAttribute` | `DOM.setBooleanAttribute` | `?disabled=\"${x => x.off}\"` |\n| `:prop=\"${x => x.val}\"` | `property` | `target[prop] = value` | `:value=\"${x => x.name}\"` |\n| `:classList=\"${x => x.val}\"` | `tokenList` | `updateTokenList` | `:classList=\"${x => x.classes}\"` |\n| `@event=\"${x => x.handler}\"` | `event` | addEventListener | `@click=\"${(x,c) => x.onClick(c.event)}\"` |\n| `${x => x.val}` (in text) | `content` | `updateContent` | `<p>${x => x.msg}</p>` |\n\n---\n\n## Hydration: Attaching Bindings to Server-Rendered DOM\n\nWhen a page is server-side rendered (SSR) with Declarative Shadow DOM, the HTML arrives in the browser fully formed. Instead of creating new DOM nodes, FAST's hydration system **reuses the existing DOM** and attaches reactive bindings to it. This section explains how hydration markers in the SSR output guide the client-side binding process.\n\n### Enabling Hydration\n\nHydration is an opt-in feature. Calling `enableHydration()` patches\n`ViewTemplate.prototype` with:\n1. A `Hydratable` symbol — marks the template as hydration-capable (checked via `isHydratable()`).\n2. A `hydrate(firstChild, lastChild, hostBindingTarget?)` method — creates a `HydrationView` instead of an `HTMLView`.\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration();\n```\n\n### Hydration Marker Format\n\nThe SSR renderer embeds comment nodes and data attributes into the HTML to mark where bindings should attach. These markers encode the **factory index** (position in the compiled factories array) so the client can map each marker back to its corresponding `ViewBehaviorFactory`.\n\n#### Attribute Binding Markers\n\nElements with attribute/property/event bindings receive a `data-fe` attribute with the binding count:\n\n```html\n<!-- SSR output for: <div class=\"${x => x.cls}\" :value=\"${x => x.val}\"> -->\n<div data-fe=\"2\">server-rendered content</div>\n```\n\nThe attribute marker format is:\n\n| Attribute | Example | Description |\n|---|---|---|\n| `data-fe` | `data-fe=\"3\"` | Binding count — the number of attribute bindings on the element |\n\n#### Content Binding Markers\n\nText/template content bindings are wrapped in paired data-free comment nodes (matched by string equality, paired by balanced depth counting):\n\n```html\n<!--fe:b-->\nHello, World!\n<!--fe:/b-->\n```\n\n#### Repeat Directive Markers\n\nEach repeated item is bracketed by data-free repeat markers:\n\n```html\n<!--fe:r-->\n<li>First item</li>\n<!--fe:/r-->\n<!--fe:r-->\n<li>Second item</li>\n<!--fe:/r-->\n```\n\n#### Element Boundary Markers\n\nNested custom elements that also need hydration are demarcated so the parent's walker can skip over them:\n\n```html\n<!--fe:e-->\n<child-element>\n  <template shadowrootmode=\"open\">...child shadow DOM...</template>\n</child-element>\n<!--fe:/e-->\n```\n\n### Hydration Binding Flow\n\n`hydration/traversal.ts` owns pointer navigation and its live Range fallback.\n`hydration/target-builder.ts` consumes that traversal to map factories, keeping\ndirect native marker reads inline. `HydrationView` uses the same range utility\nwhen producing diagnostic fragments, without coupling it to target discovery.\n\n`enableHydration()` replaces the small core `components/element-registration.ts`\nstrategy with `hydration/attribute-observation.ts`. Client-only `FASTElement`\nbundles do not include observation tracking. Immediately before FAST's platform\nregistration, tracking records only a boolean proving that `data-fe` is\nunobserved, after extensions and asynchronous template resolution. The proof is\navailable during synchronous upgrades and restored if registration fails.\nEarlier untracked registrations remain conservative; calling `enableHydration()`\nagain does not reset existing proof. Hydration never reconstructs the platform\nsnapshot by rereading `constructor.observedAttributes`.\n\nFor a known unobserved `data-fe` attribute and native attribute methods, removal\ncannot invoke an attribute-change callback, so pointers remain active.\nRegistration/lifecycle accessors, custom attribute iterators, unknown registry\nwrappers, customized built-ins, and overridden attribute methods remain\nconservative. Legacy/custom marker cleanup still captures live boundaries from\nthe outset. Marker removal is not deferred and callback order is unchanged.\n\n```mermaid\nflowchart TD\n    A[\"Server renders HTML with Declarative Shadow DOM\"] --> B[\"Browser parses HTML, creates DOM + shadow roots\"]\n    B --> C[\"Custom element connects, HydratableElementController activates\"]\n    C --> D{\"Has 'defer-hydration' attribute?\"}\n    D -->|Yes| E[\"Wait until attribute is removed\"]\n    D -->|No| F[\"template.hydrate(firstChild, lastChild, hostBindingTarget)\"]\n    E -->|Attribute removed| F\n    F --> G[\"new HydrationView(firstChild, lastChild, sourceTemplate)\"]\n    G --> H[\"HydrationView.bind(source)\"]\n    H --> I[\"Stage: unhydrated → hydrating\"]\n    I --> J[\"buildViewBindingTargets(firstChild, lastChild, factories)\"]\n\n    J --> K[\"Pointer DFS for ordered sibling endpoints; live Range fallback otherwise or before mutating cleanup\"]\n    K --> L{\"Walk each node\"}\n\n    L -->|Element node| M[\"Parse data-fe attribute\"]\n    M --> N[\"Consume N sequential factories directly via targetFactory(); generic resolution for legacy markers\"]\n    N --> O[\"Remove data-fe marker attribute\"]\n\n    L -->|Comment: content marker| P[\"Match fe:b start marker by string equality\"]\n    P --> Q[\"Walk siblings to find matching fe:/b end marker\\nusing balanced depth counting\"]\n    Q --> R{\"Content between markers?\"}\n    R -->|Single text node| S[\"Target factory to text node directly\"]\n    R -->|Multiple nodes / template| T[\"Store boundaries in ViewBehaviorBoundaries\"]\n    T --> U[\"Insert dummy text node as target for future string updates\"]\n    R -->|Empty null/false binding| U\n    L -->|Comment: element boundary| V[\"Clear fe:e start marker data\\nSkip to matching fe:/e end marker\\nusing balanced depth counting\\nClear fe:/e end marker data\\nThrow if end marker not found\"]\n    L -->|Other| W[\"Continue walking\"]\n    J --> X[\"Return { targets, boundaries }\"]\n    X --> Y[\"Create behaviors from factories\"]\n    Y --> Z[\"behavior.bind(hydrationView)\"]\n    Z --> AA[\"Stage: hydrating → hydrated\"]\n\n    subgraph \"Host Binding Offset\"\n        BB[\"Host bindings (targetNodeId='h') are at the start of the factories array\"]\n        CC[\"getHydrationIndexOffset() counts host bindings to skip\"]\n        DD[\"SSR markers use indices relative to non-host factories\"]\n    end\n```\n\n### HydrationView vs HTMLView\n\n```mermaid\nflowchart LR\n    subgraph \"HTMLView (client-rendered)\"\n        A1[\"Compiler produces DocumentFragment\"] --> A2[\"fragment.cloneNode(true)\"]\n        A2 --> A3[\"Resolve targets via prototype getter chain\"]\n        A3 --> A4[\"Create behaviors & bind\"]\n    end\n\n    subgraph \"HydrationView (server-rendered)\"\n        B1[\"DOM already exists in shadow root\"] --> B2[\"Bounded pointer DFS scans markers; live Range fallback when needed\"]\n        B2 --> B3[\"buildViewBindingTargets maps markers → nodes\"]\n        B3 --> B4[\"Create behaviors & bind to existing nodes\"]\n        B4 --> B5[\"Marker comments cleared (data set to empty string)\"]\n    end\n```\n\n| Aspect | HTMLView | HydrationView |\n|---|---|---|\n| **DOM source** | Clones compiled DocumentFragment | Reuses server-rendered DOM in place |\n| **Target resolution** | Prototype getters via childNodes indices | Pointer DFS + sequential markers; live Range / generic-strategy fallback |\n| **Node creation** | Creates all DOM nodes from scratch | No node creation (reuses existing) |\n| **Fragment** | Holds cloned fragment, moved into host | No fragment initially (created only on remove) |\n| **Lifecycle** | Ready immediately after creation | Transitions through unhydrated → hydrating → hydrated |\n| **Validation** | Compilation guarantees structure | Must validate markers match factories (throws HydrationBindingError) |\n| **Boundaries** | Not needed (compiler tracks structure) | `bindingViewBoundaries` stores first/last node pairs for structural directives |\n\n### Content Binding Hydration\n\nWhen `HTMLBindingDirective.bind()` runs during hydration and the binding returns a `ContentTemplate`, the `updateContent` sink checks for pre-rendered boundaries:\n\n```mermaid\nsequenceDiagram\n    participant Directive as HTMLBindingDirective\n    participant Controller as HydrationView (controller)\n    participant Sink as updateContent()\n    participant Template as ContentTemplate\n\n    Directive->>Controller: bind(controller)\n    Note over Directive: aspectType = DOMAspect.content\n    Directive->>Sink: updateTarget(target, aspect, value, controller)\n    Sink->>Sink: value is ContentTemplate?\n\n    alt Hydrating & boundaries exist\n        Sink->>Controller: Check bindingViewBoundaries[targetNodeId]\n        Controller-->>Sink: { first: Node, last: Node }\n        Sink->>Template: value.hydrate(first, last)\n        Template-->>Sink: HydrationView (reuses existing nodes)\n        Sink->>Sink: view.bind(source, context) — attaches to pre-rendered DOM\n    else Already hydrated or no boundaries\n        Sink->>Template: value.create()\n        Template-->>Sink: HTMLView (creates new nodes)\n        Sink->>Sink: view.bind + view.insertBefore\n    end\n```\n\n### Repeat Directive Hydration\n\nThe repeat directive scans **forward** from its own content boundary to its\nlocation, pairing top-level ranges with a stack. This avoids reverse collection\nand rescanning prefixes belonging to earlier adjacent repeats. Nested markers\nremain untouched until child views hydrate. Both unmatched starts and unmatched\nends throw before repeat markers are cleared.\n\nThe read-only `collectHydrationRepeatRanges()` helper in\n`hydration/repeat-ranges.ts` owns this discovery and validation. `RepeatBehavior`\nsupplies its own binding boundaries, then clears top-level markers and hydrates,\ncreates, or removes views. The discovery helper does not alter marker data or\nbind views.\n\n```mermaid\nflowchart TD\n    A[\"RepeatBehavior.bind(controller)\"] --> B{\"isHydratable(template) && hydrating?\"}\n    B -->|Yes| C[\"hydrateViews(template)\"]\n    B -->|No| D[\"refreshAllViews() — normal client path\"]\n\n    C --> E[\"Allocate views array sized to items.length\"]\n    E --> F[\"Scan bindingViewBoundaries[targetNodeId].first through location\"]\n    F --> G{\"Repeat marker?\"}\n    G -->|Start| H[\"Push start marker\"]\n    G -->|End| I[\"Pop start; throw if absent\"]\n    I --> J{\"Stack empty?\"}\n    J -->|Yes| K[\"Append top-level range in item order\"]\n    J -->|No| F\n    H --> F\n    K --> F\n    G -->|Other node| F\n    F -->|Reached location| L[\"Throw if stack nonempty; otherwise clear top-level markers\"]\n    L --> M[\"Hydrate overlapping SSR/client ranges in order\"]\n    M --> N[\"Create missing client views and remove excess server ranges\"]\n\n    subgraph \"Result\"\n        S[\"Each array item mapped to a HydrationView\"]\n        T[\"Views reuse server-rendered DOM between markers\"]\n        U[\"Markers cleared to empty strings (invisible in DOM)\"]\n    end\n```\n\n### Hydration CPU regression coverage\n\n`src/hydration/hydration-performance.pw.spec.ts` instruments Range/TreeWalker\ncreation and native factory-index array allocation across 500 sibling-bounded\nviews. Those counters must all be zero on the ordinary native path. It also\nasserts exact linear repeat predicate visits (four starts and two ends per\nfour-comment nested item), scope isolation from earlier siblings, nested marker\npreservation, malformed-marker diagnostics, installed `markers_v2`, empty items,\nand missing/excess reconciliation. Existing target-builder tests compare live\nendpoint mutations with the legacy Range walker. The declarative repeat fixture\nchecks SSR node identity, three nested repeat levels, an empty inner list, and an\nadjacent repeat before exercising reactive updates. The co-located\n`src/hydration/repeat-ranges.pw.spec.ts` also verifies that successful discovery\nleaves native and legacy marker data unchanged and excludes adjacent ranges.\n\n`src/hydration/native-marker-cleanup.pw.spec.ts` exercises a 1,000-record,\nthree-repeat-level workload with 20 adjacent prefix items: 4,021 FAST elements,\n4,020 native attribute markers, and 8,041 hydrated views. Range/TreeWalker setup,\n`comparePoint`, and `intersectsNode` counts are all zero; all 7,020 SSR descendant\nelements retain their identity. Mutation fixtures require the fallback and\nverify immediate insertion/removal, endpoint moves, unstable observation\nmetadata, method accessors, customized built-ins, and legacy/custom strategies.\nRegistration-order cases cover disabled tracking, enabling after registration,\nrepeated enablement after observation changes, and platform registration deferred\nuntil after asynchronous template resolution.\nThe declarative repeat fixture includes bound FAST child elements, checks zero\nlive traversal setup, and exercises reactive updates after hydration.\n\nRun focused correctness coverage from the monorepo root:\n\n```sh\nnpm exec -w @microsoft/fast-element -- playwright test src/hydration/target-builder.pw.spec.ts src/hydration/hydration-performance.pw.spec.ts src/hydration/native-marker-cleanup.pw.spec.ts src/hydration/repeat-ranges.pw.spec.ts src/templating/repeat.pw.spec.ts --project=chromium\n```\n\nCPU timings live separately in `src/hydration/hydration-benchmark.pw.spec.ts`\nand are opt-in rather than flaky wall-clock CI gates:\n\n```sh\nFAST_HYDRATION_BENCHMARK=1 npm exec -w @microsoft/fast-element -- playwright test src/hydration/hydration-benchmark.pw.spec.ts --project=chromium --retries=0\n```\n\nThe workloads measure 4,000 marker-free sibling views, 4,000 native\nattribute/content marker groups, 4,000 nested repeat ranges with stubbed child\nhydration, 20 adjacent repeats with 200 flat item ranges each, and a combined\n1,000-record page with three repeat levels, 4,000 minimal native custom elements,\nand 8,001 hydrated views. Setup, custom-element registration, and template\nconstruction are outside the timed interval; repeat workloads include bind and unbind. Each\nworkload has one warm-up and ten recorded samples, each in a fresh document so\nlive Ranges from earlier samples cannot amplify later DOM mutation costs.\nCompare the same test on the base and changed revisions on the same browser and\nmachine. To attribute improvements, also compare traversal-only, native-only,\nand repeat-only source variants in an isolated worktree, reversing variant order\nfor a second pass. The combined workload includes conservative live-Range\nfallbacks for custom-element attribute cleanup, not just ordinary element views.\nThese microbenchmarks time template hydration, not the issue's application\nregistration or hydration-completion tracking, and should not be presented as\nthat application's hydration timings.\n\nThe separate native FAST workload times bind/unbind for the 4,021-element /\n8,041-view case above. Setup and registration are excluded, identity and marker\nremoval are verified after every sample, and the same fresh-document sampling\nrules apply. Use this workload to compare the known-unobserved cleanup path;\nthe original combined workload intentionally registers ordinary custom elements\noutside FAST and therefore retains its conservative fallback.\n\n### Hydration Stage Lifecycle\n\n```mermaid\nstateDiagram-v2\n    [*] --> unhydrated: HydrationView created\n\n    unhydrated --> hydrating: bind() called\n    note right of hydrating\n        buildViewBindingTargets() scans DOM\n        Markers parsed, targets resolved\n        Behaviors created and bound\n        Attribute bindings skip DOM update\n        (server already set correct values)\n    end note\n\n    hydrating --> hydrated: All behaviors bound\n    note right of hydrated\n        Subsequent bind() calls\n        behave like normal HTMLView rebind\n        (re-evaluate expressions, update DOM)\n    end note\n\n    hydrated --> hydrated: rebind with new source\n```\n\nDuring the `hydrating` stage, attribute and boolean-attribute bindings **skip their initial DOM update** (the server already rendered the correct value). This avoids unnecessary DOM writes during hydration:\n\n```typescript\n// In HTMLBindingDirective.bind(), during hydration:\nif (isHydrating && (this.aspectType === DOMAspect.attribute ||\n                    this.aspectType === DOMAspect.booleanAttribute)) {\n    observer.bind(controller);  // Set up observation only\n    break;                      // Skip updateTarget — server value is current\n}\n```\n\n### Error Handling\n\nWhen the server-rendered DOM doesn't match the client template, hydration throws descriptive errors:\n\n| Error | Cause | Contains |\n|---|---|---|\n| `HydrationTargetElementError` | `data-fe` specifies a binding count that cannot be satisfied, more content binding markers exist than factories, or an element boundary end marker is missing | Factories array, target node; with `hydrationDebugger()` installed: structured `expected` (string or `HydrationMismatchExpectation`) describing what the walk wanted next, and `received` (`HydrationMismatchActual`) containing an HTML snippet of the offending DOM |\n| `HydrationBindingError` | A factory's `targetNodeId` has no matching entry in targets after the SSR DOM walk completes | Factory, cloned fragment, template string; with `hydrationDebugger()` installed: structured `expected` (`HydrationMismatchExpectation` with `tagName` and human-readable `aspect`) and `received` (`HydrationMismatchActual` with an HTML snippet of the SSR view range) |\n| `HydrationRepeatError` | A repeat view slot is unexpectedly `null` / `undefined` during rebind or unbind (internal invariant violation). SSR/client item-count mismatches are no longer surfaced as errors — they are reconciled silently by `RepeatBehavior.hydrateViews()` (missing client views are created, extra SSR ranges are removed) | Hydration stage, items length, view states |\n| `FAST.error(1210)` | `data-fe` attribute contains a non-numeric or non-positive value | Attribute value |\n\nThese errors typically indicate a mismatch between the server-rendered HTML and the client-side template definition.\n\nBy default, both errors emit a minimal one-line message that points at the opt-in `hydrationDebugger()`. Install the debugger from `@microsoft/fast-element/hydration.js` and pass it to `enableHydration` to swap in the rich format:\n\n```ts\nimport { enableHydration, hydrationDebugger } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ debugger: hydrationDebugger() });\n```\n\nWith the debugger installed, both errors format their message as:\n\n```\nHydration mismatch in <host-element>.\n  Expected: <tag> with <aspect> binding   (or a structural description)\n  Received: <SSR HTML snippet>\n```\n\nand expose the same information programmatically through the `expected` and `received` fields so tooling can read the structured description without parsing the message string. Keeping the debugger out of the import graph saves ~0.5 KB on the production hydration bundle.\n","isInternal":false,"tokens":6992,"sizeBytes":30612},{"name":"api-report.api.md","path":"packages/fast-router/docs/api-report.api.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-router/docs/api-report.api.md","title":"Docs Skill","category":"anthropic-skill","format":"markdown","content":"## API Report File for \"@microsoft/fast-router\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\nimport { AddViewBehaviorFactory } from '@microsoft/fast-element';\nimport { ComposableStyles } from '@microsoft/fast-element';\nimport { Constructable } from '@microsoft/fast-element';\nimport { ExecutionContext } from '@microsoft/fast-element';\nimport { FASTElement } from '@microsoft/fast-element';\nimport { ViewBehavior } from '@microsoft/fast-element';\nimport { ViewBehaviorFactory } from '@microsoft/fast-element';\nimport { ViewController } from '@microsoft/fast-element';\nimport { ViewTemplate } from '@microsoft/fast-element';\n\n// Warning: (ae-internal-missing-underscore) The name \"childRouteParameter\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport const childRouteParameter = \"fast-child-route\";\n\n// @beta (undocumented)\nexport type CommandFallbackRouteDefinition<TSettings = any> = HasCommand & SupportsSettings<TSettings> & HasTitle;\n\n// @beta (undocumented)\nexport type CommandRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings> & HasCommand & HasTitle;\n\n// @beta (undocumented)\nexport class ConfigurableRoute implements Route {\n    constructor(path: string, name: string, caseSensitive: boolean);\n    // (undocumented)\n    readonly caseSensitive: boolean;\n    // (undocumented)\n    readonly name: string;\n    // (undocumented)\n    readonly path: string;\n}\n\n// @beta (undocumented)\nexport type ContributorOptions = {\n    lifecycle?: boolean;\n    parameters?: boolean;\n};\n\n// @beta (undocumented)\nexport class DefaultLinkHandler implements LinkHandler {\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n}\n\n// @beta (undocumented)\nexport class DefaultNavigationProcess<TSettings> {\n    // Warning: (ae-forgotten-export) The symbol \"NavigationPhaseImpl\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    commit(phase: NavigationPhaseImpl): void;\n    // (undocumented)\n    run(router: Router, message: NavigationMessage): Promise<void>;\n}\n\n// @beta (undocumented)\nexport class DefaultNavigationQueue implements NavigationQueue, NavigationHandler {\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n    // (undocumented)\n    enqueue(msg: NavigationMessage): void;\n    // (undocumented)\n    handleEvent(event: PopStateEvent): void;\n    // (undocumented)\n    receive(): Promise<NavigationMessage>;\n}\n\n// @beta (undocumented)\nexport class DefaultRouter implements Router {\n    constructor(host: HTMLElement);\n    // (undocumented)\n    addContributor(contributor: NavigationContributor): void;\n    // (undocumented)\n    beginRender(route: RecognizedRoute, command: RenderCommand): Promise<{\n        commit: () => Promise<void>;\n        rollback: () => Promise<void>;\n    }>;\n    // (undocumented)\n    get config(): RouterConfiguration | null;\n    set config(value: RouterConfiguration | null);\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n    // (undocumented)\n    readonly host: HTMLElement;\n    // (undocumented)\n    get level(): number;\n    // (undocumented)\n    get parent(): Router<any> | null;\n    // (undocumented)\n    removeContributor(contributor: NavigationContributor): void;\n    // (undocumented)\n    route: RecognizedRoute | null;\n    // (undocumented)\n    shouldRender(route: RecognizedRoute): boolean;\n}\n\n// @beta (undocumented)\nexport class DefaultRouteRecognizer<TSettings> implements RouteRecognizer<TSettings> {\n    // (undocumented)\n    add(routeOrRoutes: Route | readonly Route[], settings?: TSettings): void;\n    generateFromName(name: string, params: object): string | null;\n    generateFromPath(path: string, params: object): string | null;\n    // (undocumented)\n    recognize(path: string, converters?: Readonly<Record<string, RouteParameterConverter>>): Promise<RecognizedRoute<TSettings> | null>;\n}\n\n// @beta (undocumented)\nexport type DefinitionCallback = () => Promise<FallbackRouteDefinition> | FallbackRouteDefinition;\n\n// @beta (undocumented)\nexport type ElementFallbackRouteDefinition<TSettings = any> = LayoutAndTransitionRouteDefinition & HasElement & SupportsSettings<TSettings> & HasTitle;\n\n// @beta (undocumented)\nexport type ElementRouteDefinition<TSettings = any> = NavigableRouteDefinition<TSettings> & HasElement;\n\n// @beta (undocumented)\nexport class Endpoint<TSettings = any> {\n    constructor(route: ConfigurableRoute, paramNames: readonly string[], paramTypes: readonly string[], settings: TSettings | null);\n    // (undocumented)\n    readonly paramNames: readonly string[];\n    // (undocumented)\n    readonly paramTypes: readonly string[];\n    // (undocumented)\n    get path(): string;\n    // (undocumented)\n    readonly route: ConfigurableRoute;\n    // (undocumented)\n    readonly settings: TSettings | null;\n}\n\n// @beta (undocumented)\nexport type FallbackRouteDefinition<TSettings = any> = ElementFallbackRouteDefinition<TSettings> | TemplateFallbackRouteDefinition<TSettings> | Pick<RedirectRouteDefinition<TSettings>, \"redirect\"> | CommandFallbackRouteDefinition<TSettings>;\n\n// @beta (undocumented)\nexport type FASTElementConstructor = new () => FASTElement;\n\n// @beta (undocumented)\nexport class FASTElementLayout implements Layout {\n    constructor(template?: ViewTemplate | null, styles?: ComposableStyles | ComposableStyles[] | undefined, runBeforeCommit?: boolean);\n    // (undocumented)\n    afterCommit(routerElement: HTMLElement): Promise<void>;\n    // (undocumented)\n    beforeCommit(routerElement: HTMLElement): Promise<void>;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"FASTRouter_base\" needs to be exported by the entry point index.d.ts\n//\n// @beta (undocumented)\nexport class FASTRouter extends FASTRouter_base {\n}\n\n// @beta (undocumented)\nexport type HasCommand = {\n    command: NavigationCommand;\n};\n\n// @beta (undocumented)\nexport type HasElement = {\n    element: string | FASTElementConstructor | HTMLElement | (() => Promise<string | FASTElementConstructor | HTMLElement>);\n};\n\n// @beta (undocumented)\nexport type HasTemplate = {\n    template: ViewTemplate | (() => Promise<ViewTemplate>);\n};\n\n// @beta (undocumented)\nexport type HasTitle = {\n    title?: string;\n};\n\n// @beta (undocumented)\nexport type IgnorableRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings>;\n\n// @beta (undocumented)\nexport class Ignore implements NavigationCommand {\n    // (undocumented)\n    createContributor(): Promise<{\n        navigate(phase: NavigationPhase): Promise<void>;\n    }>;\n}\n\n// @beta (undocumented)\nexport function isFASTElementHost(host: HTMLElement): host is HTMLElement & FASTElement;\n\n// @beta (undocumented)\nexport function isNavigationPhaseContributor<T extends NavigationPhaseName>(object: any, phase: T): object is Record<T, NavigationPhaseHook>;\n\n// @beta (undocumented)\nexport interface Layout {\n    // (undocumented)\n    afterCommit(routerElement: HTMLElement): Promise<void>;\n    // (undocumented)\n    beforeCommit(routerElement: HTMLElement): Promise<void>;\n}\n\n// @beta (undocumented)\nexport const Layout: Readonly<{\n    default: Readonly<Layout>;\n}>;\n\n// @beta (undocumented)\nexport type LayoutAndTransitionRouteDefinition = {\n    layout?: Layout | ViewTemplate;\n    transition?: Transition;\n};\n\n// @beta (undocumented)\nexport interface LinkHandler {\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n}\n\n// @beta (undocumented)\nexport type MappableRouteDefinition<TSettings = any> = RenderableRouteDefinition<TSettings> | RedirectRouteDefinition<TSettings> | CommandRouteDefinition<TSettings> | ParentRouteDefinition<TSettings>;\n\n// @beta (undocumented)\nexport type NavigableRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings> & LayoutAndTransitionRouteDefinition & HasTitle & {\n    childRouters?: boolean;\n};\n\n// @beta (undocumented)\nexport interface NavigationCommand {\n    // (undocumented)\n    createContributor(router: Router, route: RecognizedRoute): Promise<NavigationContributor>;\n}\n\n// @beta (undocumented)\nexport interface NavigationCommitPhase<TSettings = any> extends Omit<NavigationPhase<TSettings>, \"cancel\" | \"canceled\" | \"onCancel\"> {\n    // (undocumented)\n    setTitle(title: string): void;\n}\n\n// @beta (undocumented)\nexport type NavigationCommitPhaseHook<TSettings = any> = (phase: NavigationCommitPhase<TSettings>) => Promise<any> | any;\n\n// @beta (undocumented)\nexport type NavigationContributor<TSettings = any> = Partial<Record<Exclude<NavigationPhaseName, \"commit\">, NavigationPhaseHook<TSettings>>> & {\n    commit?: NavigationCommitPhaseHook<TSettings>;\n};\n\n// Warning: (ae-forgotten-export) The symbol \"NavigationContributorDirective\" needs to be exported by the entry point index.d.ts\n//\n// @beta (undocumented)\nexport function navigationContributor(options?: ContributorOptions): NavigationContributorDirective;\n\n// @beta (undocumented)\nexport interface NavigationHandler {\n    // (undocumented)\n    enqueue(msg: NavigationMessage): void;\n}\n\n// @beta (undocumented)\nexport const NavigationHandler: Readonly<{\n    register(handler: NavigationHandler): void;\n    unregister(handler: NavigationHandler): void;\n}>;\n\n// @beta (undocumented)\nexport class NavigationMessage {\n    constructor(path: string);\n    // (undocumented)\n    path: string;\n}\n\n// @beta (undocumented)\nexport interface NavigationPhase<TSettings = any> {\n    // (undocumented)\n    cancel(callback?: NavigationPhaseFollowupAction): void;\n    // (undocumented)\n    readonly canceled: boolean;\n    // (undocumented)\n    evaluateContributor(contributor: any, route?: RecognizedRoute<TSettings>, router?: Router<TSettings>): Promise<void>;\n    // (undocumented)\n    readonly name: NavigationPhaseName;\n    // (undocumented)\n    onCancel(callback: NavigationPhaseFollowupAction): void;\n    // (undocumented)\n    onCommit(callback: NavigationPhaseFollowupAction): void;\n    // (undocumented)\n    readonly route: RecognizedRoute<TSettings>;\n    // (undocumented)\n    readonly router: Router<TSettings>;\n}\n\n// @beta (undocumented)\nexport type NavigationPhaseFollowupAction = () => Promise<any> | any;\n\n// @beta (undocumented)\nexport type NavigationPhaseHook<TSettings = any> = (phase: NavigationPhase<TSettings>) => Promise<any> | any;\n\n// @beta (undocumented)\nexport type NavigationPhaseName = \"navigate\" | \"leave\" | \"construct\" | \"enter\" | \"commit\";\n\n// @beta (undocumented)\nexport interface NavigationProcess {\n    // (undocumented)\n    run(router: Router, message: NavigationMessage): Promise<void>;\n}\n\n// @beta (undocumented)\nexport interface NavigationQueue {\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n    // (undocumented)\n    receive(): Promise<NavigationMessage>;\n}\n\n// @beta (undocumented)\nexport type ParameterConverter = RouteParameterConverter | RouteParameterConverterObject | Constructable<RouteParameterConverterObject>;\n\n// @beta (undocumented)\nexport type ParentRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings> & LayoutAndTransitionRouteDefinition & {\n    children: MappableRouteDefinition<TSettings>[];\n};\n\n// @beta (undocumented)\nexport type PathedRouteDefinition<TSettings = any> = SupportsSettings<TSettings> & Route;\n\n// @beta (undocumented)\nexport const QueryString: Readonly<{\n    readonly current: string;\n    build(params: Record<string, string>, traditional?: boolean): string;\n    separate(path: string): Readonly<{\n        path: string;\n        queryString: string;\n    }>;\n    parse(queryString: string): Readonly<Record<string, string>>;\n}>;\n\n// @beta (undocumented)\nexport class RecognizedRoute<TSettings = any> {\n    constructor(endpoint: Endpoint<TSettings>, params: Readonly<Record<string, string | undefined>>, typedParams: Readonly<Record<string, any>>, queryParams: Readonly<Record<string, string>>);\n    // (undocumented)\n    readonly allParams: Readonly<Record<string, string | undefined>>;\n    // (undocumented)\n    readonly allTypedParams: Readonly<Record<string, any>>;\n    // (undocumented)\n    readonly endpoint: Endpoint<TSettings>;\n    // (undocumented)\n    readonly params: Readonly<Record<string, string | undefined>>;\n    // (undocumented)\n    readonly queryParams: Readonly<Record<string, string>>;\n    // (undocumented)\n    get settings(): TSettings | null;\n    // (undocumented)\n    readonly typedParams: Readonly<Record<string, any>>;\n}\n\n// @beta (undocumented)\nexport class Redirect implements NavigationCommand {\n    constructor(redirect: string);\n    // (undocumented)\n    createContributor(): Promise<{\n        navigate(phase: NavigationPhase): Promise<void>;\n    }>;\n}\n\n// @beta (undocumented)\nexport type RedirectRouteDefinition<TSettings = any> = PathedRouteDefinition<TSettings> & {\n    redirect: string;\n};\n\n// @beta (undocumented)\nexport class Render implements RenderCommand {\n    constructor(owner: RouterConfiguration, createView: () => Promise<RouteView>);\n    // Warning: (ae-forgotten-export) The symbol \"RenderContributor\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    createContributor(router: Router, route: RecognizedRoute): Promise<RenderContributor>;\n    // (undocumented)\n    createView: () => Promise<RouteView>;\n    // (undocumented)\n    static fromDefinition(owner: RouterConfiguration, definition: ElementRouteDefinition | TemplateRouteDefinition | ElementFallbackRouteDefinition | TemplateFallbackRouteDefinition): Render;\n    // (undocumented)\n    get layout(): Layout;\n    set layout(value: Layout);\n    // (undocumented)\n    title: string;\n    // (undocumented)\n    get transition(): Transition;\n    set transition(value: Transition);\n}\n\n// @beta (undocumented)\nexport type RenderableRouteDefinition<TSettings = any> = ElementRouteDefinition<TSettings> | TemplateRouteDefinition<TSettings>;\n\n// @beta (undocumented)\nexport interface RenderCommand extends NavigationCommand {\n    // (undocumented)\n    createView(): Promise<RouteView>;\n    // (undocumented)\n    layout: Layout;\n    // (undocumented)\n    transition: Transition;\n}\n\n// @beta (undocumented)\nexport interface RenderOperation {\n    // (undocumented)\n    commit(): Promise<void>;\n    // (undocumented)\n    rollback(): Promise<void>;\n}\n\n// @beta (undocumented)\nexport interface Route {\n    // (undocumented)\n    readonly caseSensitive?: boolean;\n    // (undocumented)\n    readonly name?: string;\n    // (undocumented)\n    readonly path: string;\n}\n\n// @beta (undocumented)\nexport const Route: Readonly<{\n    path: Readonly<{\n        readonly current: string;\n        generateRoute(relativeTo: HTMLElement | Router, path: string, params?: Object): Promise<string | null>;\n        push(path: string, trigger?: boolean): void;\n        replace(path: string, trigger?: boolean): void;\n        trigger(path: string): void;\n    }>;\n    name: Readonly<{\n        generateRoute(relativeTo: HTMLElement | Router, name: string, params?: Object): Promise<string | null>;\n        push(relativeTo: HTMLElement | Router, name: string, params?: Object, trigger?: boolean): Promise<void>;\n        replace(relativeTo: HTMLElement | Router, name: string, params?: Object, trigger?: boolean): Promise<void>;\n        trigger(relativeTo: HTMLElement | Router, name: string, params?: Object): Promise<void>;\n    }>;\n}>;\n\n// @beta (undocumented)\nexport class RouteCollection<TSettings = any> {\n    constructor(owner: RouterConfiguration);\n    // (undocumented)\n    converter(name: string, converter: ParameterConverter): void;\n    // (undocumented)\n    fallback(definitionOrCallback: FallbackRouteDefinition<TSettings> | DefinitionCallback): void;\n    generateFromName(name: string, params: object): string | null;\n    generateFromPath(path: string, params: object): string | null;\n    // (undocumented)\n    ignore(definitionOrString: IgnorableRouteDefinition<TSettings> | string): void;\n    // (undocumented)\n    map(...routes: MappableRouteDefinition<TSettings>[]): void;\n    // (undocumented)\n    recognize(path: string): Promise<RouteMatch<TSettings> | null>;\n}\n\n// @beta (undocumented)\nexport type RouteMatch<TSettings = any> = {\n    route: RecognizedRoute<TSettings>;\n    command: NavigationCommand;\n};\n\n// @beta (undocumented)\nexport type RouteParameterConverter = (name: string, value: string | undefined, context: RouteParameterConverterContext) => any | Promise<any>;\n\n// @beta (undocumented)\nexport interface RouteParameterConverterContext<TSettings = any> {\n    // (undocumented)\n    readonly endpoint: Endpoint<TSettings>;\n    // (undocumented)\n    readonly params: Readonly<Record<string, string | undefined>>;\n    // (undocumented)\n    readonly queryParams: Record<string, string>;\n    // (undocumented)\n    readonly typedParams: Record<string, any>;\n}\n\n// @beta (undocumented)\nexport type RouteParameterConverterObject = {\n    convert: RouteParameterConverter;\n};\n\n// @beta (undocumented)\nexport interface Router<TSettings = any> {\n    // (undocumented)\n    addContributor(contributor: NavigationContributor): void;\n    // (undocumented)\n    beginRender(route: RecognizedRoute<TSettings>, command: RenderCommand): Promise<RenderOperation>;\n    // (undocumented)\n    config: RouterConfiguration | null;\n    // (undocumented)\n    connect(): void;\n    // (undocumented)\n    disconnect(): void;\n    // (undocumented)\n    readonly level: number;\n    // (undocumented)\n    readonly parent: Router | null;\n    // (undocumented)\n    removeContributor(contributor: NavigationContributor): void;\n    // (undocumented)\n    readonly route: RecognizedRoute | null;\n    // (undocumented)\n    shouldRender(route: RecognizedRoute<TSettings>): boolean;\n}\n\n// @beta (undocumented)\nexport const Router: Readonly<{\n    getOrCreateFor(element: HTMLElement): Router<any>;\n    find(element: HTMLElement): Router | null;\n    from<TBase extends typeof HTMLElement>(BaseType: TBase): {\n        new (): InstanceType<TBase> & RouterElement;\n    };\n}>;\n\n// @beta (undocumented)\nexport abstract class RouterConfiguration<TSettings = any> {\n    // (undocumented)\n    protected cached(ElementType: new () => HTMLElement): () => Promise<HTMLElement>;\n    // (undocumented)\n    protected abstract configure(): Promise<void> | void;\n    // (undocumented)\n    construct<T>(Type: Constructable<T>): T;\n    // (undocumented)\n    readonly contributors: NavigationContributor<TSettings>[];\n    // Warning: (ae-forgotten-export) The symbol \"RoutingEventSink\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    createEventSink(): RoutingEventSink;\n    // (undocumented)\n    createLinkHandler(): LinkHandler;\n    // (undocumented)\n    createNavigationProcess(): NavigationProcess;\n    // (undocumented)\n    createNavigationQueue(): NavigationQueue;\n    // (undocumented)\n    createRouteRecognizer(): RouteRecognizer<TSettings>;\n    // Warning: (ae-forgotten-export) The symbol \"TitleBuilder\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    createTitleBuilder(): TitleBuilder;\n    // (undocumented)\n    defaultLayout: Layout;\n    // (undocumented)\n    defaultTransition: Readonly<Transition>;\n    // (undocumented)\n    findContributors<T extends NavigationPhaseName>(phase: T): Record<T, NavigationPhaseHook<TSettings>>[];\n    generateRouteFromName(name: string, params: object): Promise<string | null>;\n    generateRouteFromPath(path: string, params: object): Promise<string | null>;\n    // (undocumented)\n    parent: RouterConfiguration<TSettings> | null;\n    // (undocumented)\n    recognizeRoute(path: string): Promise<RouteMatch<TSettings> | null>;\n    // (undocumented)\n    readonly routes: RouteCollection<TSettings>;\n    // (undocumented)\n    title: string;\n}\n\n// @beta (undocumented)\nexport interface RouteRecognizer<TSettings> {\n    // (undocumented)\n    add(routeOrRoutes: Route | readonly Route[], settings?: TSettings): void;\n    // (undocumented)\n    generateFromName(name: string, params: object): string | null;\n    // (undocumented)\n    generateFromPath(path: string, params: object): string | null;\n    // (undocumented)\n    recognize(path: string, converters?: Readonly<Record<string, RouteParameterConverter>>): Promise<RecognizedRoute<TSettings> | null>;\n}\n\n// @beta (undocumented)\nexport interface RouterElement extends HTMLElement {\n    // Warning: (ae-forgotten-export) The symbol \"routerProperty\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    readonly [routerProperty]: Router;\n    // (undocumented)\n    config: RouterConfiguration | null;\n    // (undocumented)\n    connectedCallback(): void;\n    // (undocumented)\n    disconnectedCallback(): void;\n}\n\n// @beta (undocumented)\nexport type RouterExecutionContext = ExecutionContext & {\n    router?: Router;\n};\n\n// @beta (undocumented)\nexport interface RouteView {\n    // (undocumented)\n    appendTo(host: HTMLElement): void;\n    // (undocumented)\n    bind(allTypedParams: Readonly<Record<string, any>>): void;\n    // (undocumented)\n    context: RouterExecutionContext;\n    // (undocumented)\n    dispose(): void;\n}\n\n// @beta (undocumented)\nexport type SupportsSettings<TSettings = any> = {\n    settings?: TSettings;\n};\n\n// @beta (undocumented)\nexport type TemplateFallbackRouteDefinition<TSettings = any> = LayoutAndTransitionRouteDefinition & HasTemplate & SupportsSettings<TSettings> & HasTitle;\n\n// @beta (undocumented)\nexport type TemplateRouteDefinition<TSettings = any> = NavigableRouteDefinition<TSettings> & HasTemplate;\n\n// @beta (undocumented)\nexport interface Transition {\n    // (undocumented)\n    begin(host: HTMLElement, prev: RouteView | null, next: RouteView): Promise<void>;\n    // (undocumented)\n    commit(host: HTMLElement, prev: RouteView | null, next: RouteView): Promise<void>;\n    // (undocumented)\n    rollback(host: HTMLElement, prev: RouteView | null, next: RouteView): Promise<void>;\n}\n\n// @beta (undocumented)\nexport const Transition: Readonly<{\n    default: Readonly<Transition>;\n}>;\n\n// (No @packageDocumentation comment for this package)\n\n```\n","isInternal":false,"tokens":4924,"sizeBytes":22085},{"name":"component-explorer.md","path":"sites/website/src/docs/1.x/tools/component-explorer.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/sites/website/src/docs/1.x/tools/component-explorer.md","title":"Tools Skill","category":"anthropic-skill","format":"markdown","content":"---\nid: component-explorer\ntitle: Component Explorer\neleventyNavigation:\n  key: component-explorer1x\n  parent: tools1x\n  title: Component Explorer\nnavigationOptions:\n  activeKey: component-explorer1x\ndescription: Launch our Component Explorer to experience our FAST Components and development tools.\nkeywords:\n  - component explorer\nlayout: 1x\n---\n\nLaunch our [Component Explorer](https://explore.fast.design) to experience our [FAST Components](https://www.npmjs.com/package/@microsoft/fast-components) and development tools.","frontmatter":{"id":"component-explorer","title":"Component Explorer","eleventyNavigation":{"key":"component-explorer1x","parent":"tools1x","title":"Component Explorer"},"navigationOptions":{"activeKey":"component-explorer1x"},"description":"Launch our Component Explorer to experience our FAST Components and development tools.","keywords":["component explorer"],"layout":"1x"},"isInternal":false,"tokens":119,"sizeBytes":526},{"name":"hot-module-reload.md","path":"sites/website/src/docs/1.x/tools/hot-module-reload.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/sites/website/src/docs/1.x/tools/hot-module-reload.md","title":"Tools Skill","category":"anthropic-skill","format":"markdown","content":"---\nid: hot-module-reload\ntitle: Hot Module Reload\neleventyNavigation:\n  key: hot-module-reload1x\n  parent: tools1x\n  title: Hot Module Reload\nnavigationOptions:\n  activeKey: hot-module-reload1x\ndescription: Hot Module Replacement (HMR) allows your web components to be updated as you develop, without needing a full refresh of the browser.\nkeywords:\n  - hot module reload\nlayout: 1x\n---\n\nHot Module Replacement (HMR) allows your web components to be updated as you develop, without needing a full refresh of the browser. The [Open Web Components](https://open-wc.org/) project maintains a number of tools and libraries for working with Web Components, including a plugin for enabling HMR with FAST Web Components.\n\nTo learn more about HMR for Web Components and to see how to setup HMR in your own FAST projects, [please see the Open Web Components HMR documentation](https://open-wc.org/docs/development/hot-module-replacement/).\n\n:::note\nHMR is limited in what it can update for a given component. So, full-page refreshes are still needed in certain cases. Changes to constructor logic or adding new `@attr` properties are notable examples of HMR's update limitations. However, template and style changes should be handled automatically without needing a full refresh.\n:::","frontmatter":{"id":"hot-module-reload","title":"Hot Module Reload","eleventyNavigation":{"key":"hot-module-reload1x","parent":"tools1x","title":"Hot Module Reload"},"navigationOptions":{"activeKey":"hot-module-reload1x"},"description":"Hot Module Replacement (HMR) allows your web components to be updated as you develop, without needing a full refresh of the browser.","keywords":["hot module reload"],"layout":"1x"},"isInternal":false,"tokens":288,"sizeBytes":1275},{"name":"vscode.md","path":"sites/website/src/docs/1.x/tools/vscode.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/sites/website/src/docs/1.x/tools/vscode.md","title":"Tools Skill","category":"anthropic-skill","format":"markdown","content":"---\nid: vscode\ntitle: Visual Studio Code\neleventyNavigation:\n  key: vscode1x\n  parent: tools1x\n  title: Visual Studio Code\nnavigationOptions:\n  activeKey: vscode1x\ndescription: You can use any code editor you like when working with FAST. One of our favorites is Visual Studio Code.\nkeywords:\n  - visual studio code\nlayout: 1x\n---\n\nYou can use any code editor you like when working with FAST. One of our favorites is [Visual Studio Code](https://code.visualstudio.com/). VS Code has great support for API autocomplete for TypeScript and JavaScript APIs, as well as a rich ecosystem of plugins.\n\nWhen working with VS Code, we recommend using these plugins:\n\n* [FAST Snippets](https://marketplace.visualstudio.com/items?itemName=kingoftac.fast-snippets) to get commonly used conventions when creating `FAST Components`.\n* [literally-html](https://marketplace.visualstudio.com/items?itemName=webreflection.literally-html) to get syntax highlighting and documentation in your `html` blocks.\n* [es6-string-css](https://marketplace.visualstudio.com/items?itemName=bashmish.es6-string-css) to get syntax highlighting in your `css` blocks.","frontmatter":{"id":"vscode","title":"Visual Studio Code","eleventyNavigation":{"key":"vscode1x","parent":"tools1x","title":"Visual Studio Code"},"navigationOptions":{"activeKey":"vscode1x"},"description":"You can use any code editor you like when working with FAST. One of our favorites is Visual Studio Code.","keywords":["visual studio code"],"layout":"1x"},"isInternal":false,"tokens":262,"sizeBytes":1130},{"name":"README.md","path":"packages/fast-build/README.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-build/README.md","title":"fast-build Documentation","category":"plugin-manifest","format":"markdown","content":"# FAST Build\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-build.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-build)\n\nThe `fast-build` package renders the declarative HTML template syntax of [`@microsoft/fast-element`](https://www.npmjs.com/package/@microsoft/fast-element), primarily for use in testing environments. It is powered by a WebAssembly core with zero runtime npm dependencies.\n\n> **Note:** For production server-side rendering, we recommend using the [`@microsoft/webui`](https://github.com/microsoft/webui) project instead.\n\n## Installation\n\n### From NPM\n\nTo install the latest `@microsoft/fast-build` package using `npm`:\n\n```shell\nnpm install --save @microsoft/fast-build\n```\n\nWithin your JavaScript or TypeScript code, you can then import library APIs like this:\n\n```ts\nimport { render } from '@microsoft/fast-build';\n```\n\n## CLI usage\n\nOnce installed, the `fast` binary is available. Use the `build` subcommand to render an HTML template with an optional JSON state file, or `convert` to convert a FAST declarative HTML template to another supported syntax:\n\n```shell\nfast build [options]\nfast convert [options]\n```\n\n### Build options\n\n| Option | Default | Description |\n|---|---|---|\n| `--entry=\"<path>\"` | `index.html` | Entry HTML template to render |\n| `--state=\"<path>\"` | `{}` when omitted | JSON file containing the template state. If omitted, no state file is loaded and rendering uses an empty state object. If `--state` is provided, the file must exist. |\n| `--output=\"<path>\"` | `output.html` | Where to write the rendered HTML |\n| `--templates=\"<glob>\"` | _(none)_ | Glob pattern(s) for custom element template HTML files. Separate multiple patterns with commas. A warning is printed if not provided in non-streaming mode or if no files match a pattern. |\n| `--attribute-name-strategy=\"<strategy>\"` | `camelCase` | Strategy for mapping HTML attribute names to state property names on custom elements. `\"camelCase\"` converts dashes to camelCase (e.g. `foo-bar` → `fooBar`). `\"none\"` preserves dashes (e.g. `foo-bar` → `foo-bar`). See [Attribute name strategy](#attribute-name-strategy). |\n| `--markers_v2[=true/false]` | `false` | Emit FAST Element 2.x indexed hydration markers instead of the default FAST Element 3.x data-free markers. |\n| `--config=\"<path>\"` | `fast-build.config.json` | Path to a JSON configuration file. If omitted, `fast-build.config.json` in the current directory is used when present. CLI arguments take precedence over config values. See [Configuration file](#configuration-file). |\n| `--stream[=true/false]` | `false` | Write rendered HTML chunks directly to stdout instead of writing `--output`. Valueless `--stream` is treated as `true`. |\n\n### Example\n\nGiven an `index.html`:\n\n```html\n<html>\n  <body>\n    <h1>{{title}}</h1>\n    <p>{{description}}</p>\n  </body>\n</html>\n```\n\nAnd a `state.json`:\n\n```json\n{\n  \"title\": \"Hello FAST\",\n  \"description\": \"Server-side rendered with WebAssembly.\"\n}\n```\n\nRun:\n\n```shell\nfast build --entry=index.html --state=state.json --output=output.html\n```\n\nProduces `output.html`:\n\n```html\n<html>\n  <body>\n    <h1>Hello FAST</h1>\n    <p>Server-side rendered with WebAssembly.</p>\n  </body>\n</html>\n```\n\n### Streaming output\n\nPass `--stream`, `--stream=true`, or `--stream=false`, or set\n`\"stream\": true` in `fast-build.config.json`, to control stdout streaming. When\nstreaming is enabled, the CLI writes raw rendered HTML chunks to stdout, does\nnot write the `--output` file, and does not print the normal `Built: ...`\nmessage.\n\n```shell\nfast build --entry=index.html --state=state.json --stream\n```\n\nStreaming is simulated by the WebAssembly renderer: chunks are prepared in\nmemory, returned to JavaScript as a JSON array, parsed by the CLI, and then\nwritten to stdout. `--stream` uses the same entry renderer with its stream flag\nenabled and passes an empty templates map when no `--templates` glob is\nprovided. Chunk boundaries are safe for HTML parsing:\n\n- Attribute bindings stay within complete opening tag chunks.\n- Custom element opening chunks include the complete Declarative Shadow DOM\n  template.\n- Streamed output uses the same renderer preprocessing and custom-element host\n  attribute propagation as normal output.\n- Empty chunks are omitted.\n- Concatenating all chunks matches the normal non-streamed render.\n\n### Performance benchmarks for contributors\n\nThe renderer discovers tags and bindings in a forward scan, eliminating repeated\nremaining-suffix searches for adjacent custom elements and plain tags. Existing\nWASM exports, rendered bytes, default markers, and `markers_v2` remain compatible.\nRendering is still synchronous, and `--stream` still buffers all chunks in WASM.\n\nFrom a FAST repository checkout, not an installed npm package:\n\n```shell\nnpm run build -w @microsoft/fast-build\nnpm run bench:render -w @microsoft/fast-build -- --case=url_sink_siblings --output=/tmp/fast-render.json\nnpm run bench:render -w @microsoft/fast-build -- --case=url_sink_siblings --check-scaling\n```\n\nThe runner benchmarks the actual packaged WASM in fresh child processes in both\nmarker modes, recording timing, CPU, output hashes, throughput, and peak RSS.\nUse `--case`, `--counts`, `--samples`, or `--compare=<baseline.json>` to narrow\nor compare a run. Output files are never overwritten. Normal tests verify the\nsame fixtures against pre-optimization hashes without flaky timing thresholds.\nSee the [benchmark guide](../../crates/microsoft-fast-build/benchmark-baselines/README.md)\nfor native Criterion benchmarks, fixture sizes, methodology, and limitations.\n\nThe guide includes post-scanner repeat/state-heavy and many-definition profiles.\nStart expensive repeat cases with `--counts=250,1000 --warmup-count=250`;\nstate-overlay controls and separate native phases help identify the next\noptimization without running an unbounded matrix. Native CPU samples are not\nWASM allocation measurements, and no production rendering behavior is changed.\n\nThe guide also includes an opt-in native allocation baseline and a fresh-process\nmatrix command: `node crates/microsoft-fast-build/benches/profile-allocations.mjs\n--output=/tmp/fast-allocations.json` from the repository root. Its counters are\ndevelopment-only Rust tooling, not part of the npm CLI or WASM; native peak\nnewly-live heap is not process RSS.\n\n### Missing or omitted state\n\nState is optional. When `--state` is omitted and no `state` path is provided by config, `fast build` does not look for `state.json`; rendering uses an empty object (`{}`). An explicit `--state` path, or a `state` path from config, must exist or the command exits with an error.\n\n> **Breaking change:** Earlier versions implicitly loaded `state.json` from the current working directory when `--state` was omitted. To use a state file, pass `--state=state.json` or set `\"state\": \"state.json\"` in `fast-build.config.json`.\n\nWhen a binding value is not present in state:\n\n- Content bindings render nothing, including unresolved dot paths: `<p>{{foo.bar}}</p>` becomes `<p></p>`.\n- Attribute bindings omit the entire attribute, including unresolved dot paths: `<div class=\"{{foo.bar}}\"></div>` becomes `<div></div>`.\n- `<f-repeat>` treats a missing list binding, including unresolved dot paths, as an empty array and renders zero iterations. If the binding is present but is not an array, rendering still errors.\n\nExplicit `null` also omits an attribute, even in an interpolated attribute\nvalue. Empty strings remain present. Known HTML boolean attributes bound to\nJSON booleans use presence/absence; ordinary attributes (including ARIA)\nretain textual booleans. Use `?name` for browser-side truthy/falsy bindings.\nAuthor bindings resolving to absence still override template-host defaults.\nThese intentional output changes are described in the\n[plugin migration guide](./docs/migration/plugin-integrations.md).\n\n### APIs for build-time plugins\n\nImport the actual exported WASM subpath; do not slice rendered host HTML:\n\n```js\nimport {\n    parse_f_templates,\n    render_shadow_root,\n} from \"@microsoft/fast-build/wasm/microsoft_fast_build.js\";\n\nconst definitions = JSON.parse(parse_f_templates(templateHtml));\nconst templates = Object.fromEntries(\n    definitions.filter(definition => definition.name !== null)\n        .map(definition => [definition.name, definition]),\n);\nconst shadowRootHtml = render_shadow_root(\n    \"my-card\", JSON.stringify(templates), JSON.stringify(componentState),\n);\n```\n\nThe result is the complete DSD `<template>` fragment, with hydration markers\nand nested components, but no host, host defaults, or light DOM. Pass resolved\ncomponent state; the API does not derive it from caller-owned host attributes.\nIt accepts the existing attribute-name strategy and v2 marker options.\n\nParsed records add `formatVersion: 1` and `bindings` without changing the array\nshape. Binding records expose `name` (null for compound expressions),\n`expression`, syntax `kind`, lexical `paths`, and outer-to-inner repeat\n`scope` frames. `type` is null except for repeat collections (`\"array\"`);\n`optional` is null because required state declarations are not inferable.\n`$index` paths refer to the active repeat frame, not a root state key.\nClient expressions are described lexically, not fully JavaScript-type-checked.\nCode samples are excluded; metadata is not full syntax or state validation.\nGenerated WASM declarations expose these JSON interfaces.\n\n#### Authored binding source spans\n\nEach binding occurrence includes `span: { start, end }`. Both positions contain\n`offset`, `line`, and `column`, relative to the **complete HTML string passed to\n`parse_f_templates`**, not the extracted or trimmed template body. Duplicate\nexpressions have separate spans, including occurrences in host attributes,\ninterpolated attribute values, and nested directives.\n\n- `offset` is a zero-based UTF-16 code-unit offset, compatible with JavaScript\n  string slicing. It is not a UTF-8 byte offset.\n- `line` and `column` are one-based. Columns count UTF-16 code units, not visual\n  width or Unicode code points; a tab counts as one and a non-BMP character\n  counts as two.\n- Ranges are half-open: `start` is inclusive and `end` is exclusive. They cover\n  the trimmed expression, excluding braces and surrounding whitespace.\n- CRLF counts as one line break but two offset units. Lone CR and LF each count\n  as one line break. Input line endings are not normalized.\n- Repeat bindings locate the iterable expression, not the alias or `in` keyword,\n  matching their existing `expression` field. Nested `scope` frames are unchanged.\n\n```js\nconst [definition] = JSON.parse(parse_f_templates(templateHtml));\nfor (const binding of definition.bindings) {\n    const { start, end } = binding.span;\n    const authoredExpression = templateHtml.slice(start.offset, end.offset);\n    console.log(`${start.line}:${start.column}`, authoredExpression);\n}\n```\n\nPositions refer to the original, entity-encoded attribute text. No entity decoding\nis introduced. Code samples remain excluded without shifting subsequent spans.\nCallers associate the input with its file name and must regenerate metadata after\nediting that input. Bindings and directives inside HTML comments remain unsupported.\n\nRender exports reject unsupported/malformed explicit versions before rendering.\nLegacy unversioned maps and string definitions remain supported. The CLI keeps\nversion/binding fields when assembling a map; persisted metadata should do the\nsame instead of discarding them.\n\n#### Structured errors\n\nFailing render, conversion, composition, and metadata-validation APIs throw actual\nJavaScript `Error` objects, retaining the existing human-readable `message`.\nBoth WASM modules export this TypeScript interface (not a runtime constructor):\n\n```ts\ninterface FastBuildError extends Error {\n    code: string;\n    line?: number;\n    column?: number;\n    length?: number;\n    templateName?: string;\n}\n```\n\nUse `code`, such as `unclosed-binding`, `repeat-not-array`, or `missing-template`,\ninstead of parsing messages. The complete code lists are documented with the\n[renderer errors](../../crates/microsoft-fast-build/README.md#error-handling)\nand [converter errors](../../crates/microsoft-fast-convert/README.md#error-codes).\n\nLocations use one-based lines and UTF-16 columns, with a UTF-16 highlight `length`.\nTabs count as one unit, non-BMP characters as two; CRLF is one line break and lone\nCR/LF are also line breaks. A highlight covers the offending opening tag or\nbinding including its delimiters; an unclosed binding highlights its opening\ndelimiters. Unlike successful binding metadata, these are error-token ranges,\nnot trimmed expression ranges.\n\nEntry-render and conversion coordinates refer to the original HTML argument,\neven after code-sample escaping, inner-template extraction, or publisher-attribute\nrewriting. Light DOM remains in its caller's source. Errors in separately supplied\ncustom-element definitions include `templateName` and use coordinates within that\ndefinition's supplied `content`, not the entry HTML or the full file it was\nextracted from. Maintain a name-to-source mapping when presenting these locations.\nFor a missing inner template, the highlight identifies its containing\n`<f-template>`; duplicate-wrapper errors identify the second wrapper.\n\nCoordinates are absent when there is no meaningful HTML position: invalid state\nJSON, malformed metadata/options, missing template definitions or outer wrappers,\nfilesystem errors, and unsafe separately supplied CSS. A known `templateName`\ncan still be present without coordinates. `parse_f_templates` remains permissive:\nit does not gain strict syntax validation or new failures.\n\nFor a direct `render(html, stateJson)` call, an integration can report:\n\n```js\ntry {\n    render(html, stateJson);\n} catch (error) {\n    if (!(error instanceof Error)) throw error;\n    const location = error.line === undefined\n        ? inputPath\n        : `${inputPath}:${error.line}:${error.column}`;\n    console.error(`${location} [${error.code}]: ${error.message}`);\n}\n```\n\nSee the [migration guide](./docs/migration/plugin-integrations.md#structured-errors)\nwhen updating consumers that previously caught strings.\n\n### Custom element templates\n\nPass a glob pattern (or comma-separated list of patterns) to `--templates` to expand custom elements into [Declarative Shadow DOM](https://developer.chrome.com/docs/css-ui/declarative-shadow-dom):\n\n```shell\nfast build \\\n  --templates=\"./components/**/*.html\" \\\n  --entry=index.html \\\n  --state=state.json \\\n  --output=output.html\n```\n\nEach matched `.html` file is scanned for `<f-template>` elements. The `name` attribute of each `<f-template>` determines the custom element name. A single file may contain multiple templates.\n\nTemplate files must use the following format:\n\n```html\n<f-template name=\"my-button\">\n    <template>\n        <button>{{label}}</button>\n    </template>\n</f-template>\n```\n\nIf an `<f-template>` element has no `name` attribute, a warning is printed and it is ignored. Exact file paths (no wildcards) are also accepted as patterns, making it possible to register a single template file. The parser follows browser tag boundaries for the `<f-template>` and inner `<template>` wrappers, including ASCII whitespace before `>` in opening and closing tags.\n\nAny `shadowroot*` attributes on `<f-template>` are forwarded to the rendered Declarative Shadow DOM `<template>`. The CLI normalizes `shadowrootmode` and legacy `shadowroot` for compatibility: when neither has a non-empty value, it emits `shadowrootmode=\"open\" shadowroot=\"open\"`; when exactly one has a non-empty value, that value is mirrored to the other; when both have explicit non-empty values, both are preserved as authored, even if they conflict.\n\n### Attribute name strategy\n\nThe `--attribute-name-strategy` option controls how HTML attribute names on custom elements are mapped to state property names in their shadow templates.\n\n| Strategy | Behaviour | Template binding |\n|---|---|---|\n| `camelCase` (default) | Dashed attribute names converted to camelCase | `foo-bar` → `{{fooBar}}` |\n| `none` | Attribute names lowercased as-is, dashes preserved | `foo-bar` → `{{foo-bar}}` |\n\nThe `camelCase` strategy only affects \"plain\" custom element attributes. It does **not** change:\n- `data-*` attributes (always use `dataset.*` grouping)\n- `aria-*` attributes (always use ARIA reflection lookup)\n- HTML global attributes with known property names (e.g. `tabindex` → `tabIndex`)\n\n```shell\nfast build \\\n  --templates=\"./components/**/*.html\" \\\n  --attribute-name-strategy=camelCase \\\n  --entry=index.html \\\n  --state=state.json \\\n  --output=output.html\n```\n\n### Configuration file\n\nInstead of passing every option on the command line, you can place a `fast-build.config.json` file alongside your project files:\n\n```json\n{\n    \"entry\": \"index.html\",\n    \"state\": \"state.json\",\n    \"output\": \"output.html\",\n    \"templates\": \"./components/**/*.html\",\n    \"markers_v2\": true\n}\n```\n\nThe CLI automatically loads `fast-build.config.json` from the current directory when it exists. To use a different file, pass `--config`:\n\n```shell\nfast build --config=configs/my-build.json\n```\n\n**Precedence:** CLI arguments always override config file values. For example, `--output=other.html` will override the `output` value in the config file.\n\n**Path resolution:** File paths in the config file (`entry`, `state`, `output`, `templates`) are resolved relative to the config file's directory, not the current working directory. This ensures the config works correctly regardless of where the CLI is invoked.\n\nAll keys are optional. Only the following keys are allowed: `entry`, `state`, `output`, `templates`, `attribute-name-strategy`, `markers_v2`, and `stream`. Unknown keys produce an error. Values must be strings except `markers_v2` and `stream`, which must be JSON booleans (`true` or `false`). If `state` is omitted, rendering uses `{}`; if `state` is present, the referenced file must exist. CLI arguments always override config values, including `--stream=false` overriding `\"stream\": true`.\n\n## Convert\n\n`fast convert` converts FAST declarative template files using the converter WASM module in `wasm/convert/`. Supported syntax names, output extensions, and default output suffixes are read from the converter WASM metadata so the Rust converter remains the source of truth for syntax targets.\n\n```shell\nfast convert --syntax=webui-prerelease --templates=example.html\nfast convert --syntax=fast-v3-ts --templates=example.html --output=../*.template.ts\nfast convert --syntax=fast-v3-ts --templates=\"src/**/*.html\" --output=generated/*.template.ts\nfast convert --syntax=fast-v3-ts --templates=example.html \\\n    --type-source=MyElement --type-source-import=./my-element.js\n```\n\n### Convert options\n\n| Option | Default | Description |\n|---|---|---|\n| `--syntax=\"<syntax>\"` | _(required)_ | Target syntax: `webui-prerelease`, `webui-framework-prerelease`, or `fast-v3-ts` |\n| `--templates=\"<glob>\"` | _(required)_ | Comma-separated glob pattern(s) matching `.html` templates to convert. An exact single file path is also accepted. Loads the converter WASM module once for the whole batch. |\n| `--output=\"<path>\"` | Next to source | Output file path. `webui-prerelease` defaults to `*.webui.html`; `webui-framework-prerelease` defaults to `*.webui-framework.html`; `fast-v3-ts` defaults to `*.template.ts`. Any `*` in the output path is replaced with the input basename without extension. Every file matched by `--templates` is written under `--output`'s directory (or next to its source if `--output` is omitted). |\n| `--overwrite` | `false` | Allow replacing an existing output file. CLI presence always means `true`. |\n| `--typed[=true/false]` | `false` | Only for `fast-v3-ts`. Add an explicit `ElementViewTemplate<TSource>` export annotation and type-only import. Explicit false overrides configured true. |\n| `--type-source=\"<Name>\"` | _(none)_ | Only valid with `--syntax=fast-v3-ts`. Emits `export const template = html<Name>\\`…\\`;` instead of the untyped `html` call. Must be a dotted TypeScript identifier (e.g. `MyElement` or `Namespace.MyElement`). |\n| `--type-source-import=\"<module>\"` | _(none)_ | Requires `--type-source`. Also emits `import type { <Name> } from \"<module>\";` alongside the helper imports. |\n| `--config=\"<path>\"` | `fast-convert.config.json` | Path to a JSON configuration file. If omitted, `fast-convert.config.json` in the current directory is used when present. CLI arguments take precedence over config values. |\n\nOnly matched `.html` files are converted; non-`.html` files and directories are never matched. The output extension must match the selected syntax: `.html` for `webui-prerelease`/`webui-framework-prerelease` and `.ts` for `fast-v3-ts`. The output parent directory is created automatically if it doesn't exist (`mkdir -p` semantics), and an existing output file is rejected unless `--overwrite` or `\"overwrite\": true` is used. When a `--templates` pattern matches zero files, a warning is printed but the command does not fail unless every pattern matches zero files.\n\n`webui-framework-prerelease` converts FAST's declarative syntax into the Microsoft WebUI Framework's own declarative runtime syntax (`webui-prerelease` remains unchanged — it emits HTML for WebUI's separate FAST parser plugin instead). When `webui-framework-prerelease` strips an unsupported `f-slotted`/`f-children` directive, the CLI prints `Warning: <message>` to stderr for each stripped directive without failing the command.\n\n`--type-source` exists so templates that combine more than one differently-named\n`ref`/`children`/`slotted` directive (which otherwise fail to type-check once a\nreal `TSource` is supplied, because `html<TSource, TParent>` infers a single\n`TSource` for the whole tagged template) can be generated already type-checked\nagainst a concrete element type. See\n[`microsoft-fast-convert` DESIGN.md](../../crates/microsoft-fast-convert/DESIGN.md#explicit-tsource-generic).\n\n### Convert configuration file\n\n`fast-convert.config.json` follows the same precedence and path-resolution rules as `fast-build.config.json`: CLI arguments override config values, and `templates`/`output` paths from config are resolved relative to the config file directory.\n\n```json\n{\n    \"syntax\": \"fast-v3-ts\",\n    \"templates\": \"src/**/*.html\",\n    \"output\": \"generated/*.template.ts\",\n    \"overwrite\": false,\n    \"type-source\": \"MyElement\",\n    \"type-source-import\": \"./my-element.js\"\n}\n```\n\nOnly `syntax`, `templates`, `output`, `overwrite`, `type-source`,\n`type-source-import`, and `typed` are allowed. Values must be strings except\n`overwrite` and `typed`, which must be JSON booleans.\n\nFor declaration-emitting consumers, use `--typed --type-source=MyElement`.\nThe converter WASM's `convert_template_with_options` accepts an appended\noptional `typed` boolean. `convert_stylesheet(css, \"fast-v3-ts\", \"styles\",\ntrue)` emits an `ElementStyles` annotation. Existing calls remain untyped;\ntyped exports are tested with TypeScript `isolatedDeclarations`.\n\n### Running converter fixtures locally\n\nBuild the package WASM, then run the fixture validation:\n\n```shell\nnpm run build -w @microsoft/fast-build\nnpm run test:fixtures:convert -w @microsoft/fast-build\n```\n\nThe fixture tests run `fast convert` from fixture directories that contain\n`fast-convert.config.json`, so they verify the same default config discovery used\nby `fast build`. Generated fixture output is written under\n`packages/fast-build/test/.fixture-output/` and removed by the tests.\n`test/fixtures/convert/type-source.test.js` additionally type-checks\n`--type-source` output with the TypeScript compiler API against a companion\nelement type, using a separate `test/.fixture-output-type-source/` directory.\n\n## Template syntax\n\nBindings and FAST directive markup inside HTML comments are unsupported.\nCommenting out bound markup does not reliably disable its bindings and can cause\nrendering errors or client hydration mismatches. Remove unused bound markup\ninstead, and keep explanatory comments free of binding syntax and FAST directive\ntags.\n\nTemplate syntax follows the FAST declarative HTML format. See the\n[`@microsoft/fast-element` declarative documentation](../fast-element/docs/declarative/syntax.md)\nfor full documentation on bindings, conditionals, repeats, and directives.\n","isInternal":false,"tokens":5509,"sizeBytes":24476},{"name":"README.md","path":"packages/fast-element/README.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-element/README.md","title":"fast-element Documentation","category":"plugin-manifest","format":"markdown","content":"# FAST Element\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-element.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-element)\n\nThe `fast-element` library is a lightweight means to easily build performant, memory-efficient, standards-compliant Web Components. FAST Elements work in every major browser and can be used in combination with any front-end framework or even without a framework.\n\n## Installation\n\n### From NPM\n\nTo install the latest `fast-element` library using `npm`:\n\n```shell\nnpm install --save @microsoft/fast-element\n```\n\nWithin your JavaScript or TypeScript code, you can then import library APIs like this:\n\n```ts\nimport { FASTElement } from '@microsoft/fast-element';\n```\n\n### From CDN\n\nA pre-bundled script that contains all APIs needed to build web components with FAST Element is available on CDN. You can use this script by adding [`type=\"module\"`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) to the script element and then importing from the CDN.\n\n```html\n<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <script type=\"module\">\n          import { FASTElement } from \"https://cdn.jsdelivr.net/npm/@microsoft/fast-element/dist/fast-element.min.js\";\n\n          // your code here\n        </script>\n    </head>\n    <!-- ... -->\n</html>\n```\n\nThe markup above always references the latest release. When deploying to production, you will want to ship with a specific version. Here's an example of the markup for that:\n\n```html\n<script type=\"module\" src=\"https://cdn.jsdelivr.net/npm/@microsoft/fast-element@1.6.2/dist/fast-element.min.js\"></script>\n```\n\n:::note\nFor simplicity, examples throughout the documentation will assume the library has been installed from NPM, but you can always replace the import location with the CDN URL.\n:::\n\n:::tip\nLooking for a quick guide on building components?  Check out [our Cheat Sheet](../resources/cheat-sheet.md#building-components).\n:::\n\n## Browser Requirements\n\nFAST Element v3 assumes a client-side browser `Window` runtime with native\n`globalThis`, Custom Elements, DOM, Shadow DOM, and `requestAnimationFrame`.\nThe `FAST` object is now a module-scoped export (not on `globalThis`). If you\nneed to support an older browser without `globalThis`, load that polyfill before\nimporting `@microsoft/fast-element`.\n\nThe FAST Element client runtime is not intended to execute in workers,\nserver-side JavaScript runtimes, or other non-window hosts. Use server-side\nrendering tools to produce HTML for the browser, and run FAST Element in the\nclient window where custom elements connect, render, update, and hydrate.\n\n## Debug entrypoint\n\nThe declarative attribute fixture covers server-side omission of null/missing\nattributes and subsequent hydration updates. Explicit empty strings remain\npresent, and omitted attributes retain binding slots. See the\n[server-rendering guide](https://www.fast.design/docs/3.x/declarative-templates/server-rendering/)\nfor the rendering contract.\n\n`@microsoft/fast-element/debug.js` exports `enableDebug()` instead of configuring\nFAST at import time. The development root export and debug rollup bundle still\nenable debug behavior automatically.\n\n```ts\nimport { enableDebug } from \"@microsoft/fast-element/debug.js\";\n\nenableDebug();\n```\n\n## Server-rendered hydration\n\nCall `enableHydration()` from `@microsoft/fast-element/hydration.js` before\ncomponents connect to reuse their server-rendered DOM. Ordered sibling-bounded\nviews use pointer traversal and consume native markers without factory-index\narrays; unusual boundaries and potentially mutating cleanup retain the live\nRange fallback. Nested and adjacent repeats pair only their own server ranges,\npreserving SSR nodes while reconciling missing or excess items.\n\nCall `enableHydration()` before components are registered with the platform to\nalso enable pointer-only native marker cleanup for FAST components that do not\nobserve `data-fe`. Observation tracking is opt-in and excluded from client-only\n`FASTElement` bundles. Earlier registrations still hydrate correctly through\nthe conservative fallback, as do unknown registration, observed markers,\ncustomized built-ins, and overridden attribute methods. Cleanup remains\nsynchronous.\n\nExisting FAST 3 marker output and opt-in `markers_v2` remain supported without\napplication changes. See the [server-rendering guide](https://www.fast.design/docs/3.x/declarative-templates/server-rendering/)\nand [contributor performance workloads](./docs/template-bindings.md#hydration-cpu-regression-coverage).\nContributor-facing internals separate DOM traversal, binding target mapping,\nand repeat-range discovery; the opt-in benchmark spec is independent of the\ndeterministic correctness and allocation regression spec.\n\n## Export Sizes\n\nBundle sizes for each tree-shakeable export are tracked in [`SIZES.md`](./SIZES.md) and regenerated on every build. See the [Export Sizes](https://www.fast.design/docs/3.x/resources/export-sizes/) documentation page for the latest numbers.\n\n## Root Imports and Path Exports\n\nThe root `@microsoft/fast-element` entrypoint exports the FAST Element\nimplementation APIs, including the element base class, kernel, controller,\ndefinition APIs, template APIs, binding helpers, directives, styles, and schema\nhelpers. The FAST element registry is also available from\n`@microsoft/fast-element/registry.js` for focused definition lookups and\n`fastElementRegistry.whenRegistered(tagName)` registration promises.\nDeclarative, hydration, context, and dependency injection APIs are available\nfrom their focused path exports.\n\nFocused package path exports remain available for consumers that want to import\na narrower entrypoint directly. The website's\n[Path Exports](https://www.fast.design/docs/3.x/advanced/path-exports/) page is\ngenerated from `package.json` and lists each supported path.\n\n## Dynamic Style Application\n\nImport `css`, `CSSTemplateTag`, `CSSValue`, and style APIs such as\n`ElementStyles`, `CSSDirective`, `cssDirective`, `ComposableStyles`,\n`HostBehavior`, `HostController`, `StyleStrategy`, and `StyleTarget` from\n`@microsoft/fast-element`:\n\n```ts\nimport { ElementStyles, css } from \"@microsoft/fast-element\";\n```\n\nWhen runtime state or external signals need to add or remove styles, create the\n`ElementStyles` with `css` and toggle it through\n`this.$fastController.addStyles()` / `this.$fastController.removeStyles()` from\nthe element lifecycle or change handlers.\n\n`css` templates remain static style definitions. Runtime CSS bindings and\nbehavior-producing CSS directives are no longer supported; keep the condition on\nthe element and toggle a separate `ElementStyles` instance through the\ncontroller when styles need to change.\n\n## Declarative HTML\n\nBindings and FAST directive markup inside HTML comments are unsupported in\ndeclarative templates. Commenting out bound markup does not reliably disable its\nbindings; remove unused markup instead. See the\n[template syntax restrictions](./docs/declarative/syntax.md#html-comments).\n\nFAST Element publishes its declarative HTML runtime from\n`@microsoft/fast-element/declarative.js`. This entrypoint exports the\nfunctional APIs for declarative templates: `declarativeTemplate()`,\n`TemplateParser`, and related configuration types. `attributeMap()` and\n`observerMap()` are available from their own focused path exports. The\ndeclarative runtime is pure at import time; declarative APIs lazily install only\ndeclarative debug messages. Hydration is separate and remains opt-in through\n`enableHydration()` from `@microsoft/fast-element/hydration.js`.\n\n```ts\nimport { FASTElement } from \"@microsoft/fast-element\";\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n\nclass MyElement extends FASTElement {}\n\nMyElement.define({\n    name: \"my-element\",\n    template: declarativeTemplate(),\n});\n```\n\n`declarativeTemplate()` automatically defines FAST's internal native\n`<f-template>` publisher in the relevant registry, resolves the matching\n`<f-template name=\"my-element\">`, and keeps the definition template concrete\nbefore `define()` resolves. If multiple matching `<f-template>` elements are\nconnected, the first connected element supplies the template and later duplicates\ndo not reassign it. Consumers should not import or define the `<f-template>`\nimplementation directly.\n\nDeclarative schema behavior is enabled with define extensions:\n\n```ts\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [attributeMap(), observerMap()],\n);\n```\n\n`attributeMap()` creates `@attr`-style accessors for leaf bindings, and\n`observerMap()` creates deep observable accessors for discovered root\nproperties. Declarative templates assign `definition.schema` during template\nresolution so these extensions always have schema data when used with\n`declarativeTemplate()`. For non-declarative/manual schema use, import `Schema`\nfrom `@microsoft/fast-element` and pass it on the element definition;\n`observerMap()` can also receive\n`observerMap({ schema })` directly. When both extensions are present, attribute\nmapping runs before observer mapping.\n\nDeclarative utilities such as `deepMerge` are available from\n`@microsoft/fast-element/declarative-utilities.js`. See\n[`docs/declarative/syntax.md`](./docs/declarative/syntax.md) for declarative implementation\ndetails and the\n[Declarative HTML docs](https://fast.design/docs/3.x/declarative-templates/overview/)\nfor guides on writing f-templates, defining declarative elements, and\nserver-side rendering. Declarative event bindings use `$e` for the DOM event\nobject and `$c` for the execution context.\n\n## Prerendered Content Optimization\n\nHydration of prerendered content is **opt-in**. Call `enableHydration()` from `@microsoft/fast-element/hydration.js` before any FAST elements connect to activate the hydration path:\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nconst hydration = enableHydration();\n\nawait hydration.whenHydrated();\nconsole.log(\"hydration complete\");\n```\n\nBy default, hydration handles the initial prerendered batch and then no-ops\nafter the active hydration batch completes. If your app streams Declarative\nShadow DOM after the initial batch, keep the hydration hook active. In this\nmode, `enableHydration().whenHydrated()` intentionally remains pending because\nhydration never reaches a global completion point.\n\n```typescript\nimport { enableHydration, StopHydration } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({\n    stopHydration: StopHydration.never,\n});\n```\n\nFAST Element 3.x data-free hydration markers are the only format recognized\nby default. Server output that still emits the legacy FAST Element 2.x\nindexed markers will fail to hydrate unless you opt into that reader on its\ndedicated export path — an interoperability enhancement for backend systems\nthat have not yet adopted the data-free format:\n\n```typescript\nimport { enableHydration, markers_v2 } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ markers: markers_v2 });\n```\n\nBecause `markers_v2` is only referenced when explicitly imported, its legacy\nparsing logic is tree-shaken out of the bundle for consumers who don't use it.\n\nWhen using `@microsoft/fast-build`, set `\"markers_v2\": true` in\n`fast-build.config.json` so the renderer and client use the same format.\n\nWhen hydration is enabled and a FAST element connects with an existing shadow root (from server-side rendering or declarative shadow DOM), `ElementController` detects this and hydrates instead of re-rendering. Two properties on the controller let you inspect the result:\n\n- **`isPrerendered: Promise<boolean>`** — resolves `true` when the element had a declarative shadow root (DSD) at connect time, regardless of whether hydration ran.\n- **`isHydrated: Promise<boolean>`** — resolves `true` only when hydration actually ran successfully.\n\nThis enables several optimizations:\n\n- **Hydration instead of re-render**: The template uses `hydrate()` to map existing DOM nodes to binding targets rather than cloning new DOM.\n- **Declarative template resolution**: `declarativeTemplate()` waits for the\n  matching `<f-template>` before `define()` completes, so connected elements\n  hydrate with a concrete template.\n- **Attribute skip**: `onAttributeChangedCallback()` skips processing during initial upgrade when the element is prerendered, since server-rendered attribute values are already correct.\n- **Binding skip**: `HTMLBindingDirective.bind()` skips `updateTarget` for `attribute` and `booleanAttribute` aspect types when the view is prerendered.\n\n### Hydration Mismatch Diagnostics\n\nIf a prerendered DOM diverges from the client template in a way FAST cannot\nreconcile (the `render()` empty-boundary and `repeat()` count-mismatch cases\nrecover silently), `HydrationBindingError` or `HydrationTargetElementError` is\nthrown. By default the message is a single line pointing at the opt-in\n`hydrationDebugger()`. Install the debugger to get a rich\n\"Expected … / Received …\" report with the SSR HTML snippet and structured\n`expected` / `received` fields on the thrown error:\n\n```typescript\nimport { enableHydration, hydrationDebugger } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ debugger: hydrationDebugger() });\n```\n\nThe debugger module is tree-shaken out of production hydration bundles when\nnot imported, so the rich diagnostic helpers only land in builds that opt in.\n\nComponent authors can await both promises to distinguish prerendered content from successful hydration:\n\n```typescript\nconst controller = this.$fastController;\nconst prerendered = await controller.isPrerendered;\nconst hydrated = await controller.isHydrated;\n\nif (prerendered && !hydrated) {\n    // Had DSD but hydration wasn't enabled — client-side rendered\n}\n```\n\nCustom directives can also await `controller.isPrerendered` and `controller.isHydrated` (both `Promise<boolean>` on the `ViewController` interface) to determine how the view's content was rendered.\n\n## Define Extensions\n\nThe static `define()` method on a `FASTElement` subclass accepts an optional second argument — an array of extension callbacks that are invoked with the resolved element definition before the element is registered with the platform. This enables a plugin pattern where reusable behaviors can hook into element registration.\n\n```typescript\nimport { FASTElement, type FASTElementExtension } from \"@microsoft/fast-element\";\n\nfunction logger(): FASTElementExtension {\n    return definition => {\n        console.log(`Defining element: ${definition.name}`);\n    };\n}\n\nclass MyComponent extends FASTElement {\n    // component code\n}\n\nMyComponent.define({ name: \"my-component\", template, styles }, [logger()]);\n```\nEach extension receives the full `FASTElementDefinition`, which includes the resolved element name, type, template, styles, and attribute metadata. Extensions run before `customElements.define()`, so any setup they perform is available when existing DOM elements are upgraded.\n","isInternal":false,"tokens":3275,"sizeBytes":15369},{"name":"README.md","path":"packages/fast-router/README.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-router/README.md","title":"fast-router Documentation","category":"plugin-manifest","format":"markdown","content":"# FAST Router\n\nThe `@microsoft/fast-router` package contains a history-based navigation and routing solution designed around Web Components. By using `fast-router`, you can create multi-page and full application experiences. The router works with any Web Components, but has special support for Web Components built on FAST.\n\n## Installation\n\n### From NPM\n\nTo install the `fast-router` library using `npm`:\n\n```shell\nnpm install --save @microsoft/fast-router\n```\n\nWithin your JavaScript or TypeScript code, you can then import library APIs like this:\n\n```ts\nimport { FASTRouter } from '@microsoft/fast-router';\n```\n\nLooking for a setup that integrates with a particular front-end framework or bundler? Check out [our integration docs](https://fast.design/docs/integrations/introduction).\n\n## Configuration at a Glance\n\nThe router is currently in `alpha` while we address a few bugs, finish up some final polish, and write the full documentation. Below is a quick sample of how to configure the router, to help get you going while we complete the full documentation.\n\n#### A Sample Route Configuration\n\n```ts\nimport { RouterConfiguration, Route } from '@microsoft/fast-router';\nimport { HomeScreen } from './home';\nimport { AccountLogin } from './account/login';\nimport { AccountSignup } from './account/signup';\nimport { ConfirmEmail } from './account/confirm-email';\nimport { Session } from './account/session';\nimport { AccountSettings } from './account/settings';\nimport { StoreArea } from './store/store-area';\nimport { NotFound } from './not-found';\nimport { pageLayout } from './layouts/page-layout';\nimport { anonymousLayout } from './layouts/anonymous-layout';\n\ntype RouteSettings = {\n  public?: boolean\n};\n\nexport class AppRouterConfiguration extends RouterConfiguration<RouteSettings> {\n  public configure() {\n    this.title = 'My App';\n    this.defaultLayout = pageLayout;\n    this.routes.map(\n      { path: '', redirect: 'home' },\n      { path: 'home', title: 'Home', element: HomeScreen },\n      { \n        path: 'account', \n        layout: anonymousLayout, \n        title: 'Account',\n        settings: { public: true }, \n        children: [\n          { path: \"login\", title: 'Login', element: AccountLogin, name: 'login' },\n          { path: 'signup' title: 'Signup', element: AccountSignup },\n          { path: 'confirm/{confirmation:Confirmation}', title: 'Confirm', element: ConfirmEmail },\n          { path: 'settings', title: 'Settings', element: AccountSettings, layout: pageLayout, settings: { public: false } },\n        ] \n      },\n      { path: 'store', title: 'Store', element: StoreArea, childRouters: true },\n      { path: 'not-found', title: 'Not Found', element: NotFound }\n    );\n\n    this.routes.fallback(\n      () => Session.isLoggedIn\n        ? { redirect: 'not-found' }\n        : { redirect: 'login' }\n    );\n\n    this.routes.converter(\"Confirmation\", async (confirmationId) => {\n      // ...fetch confirmation from web service...\n      return confirmation;\n    });\n\n    this.contributors.push({\n      navigate(phase) {\n        const settings = phase.route.settings;\n  \n        if (settings && settings.public) {\n          return;\n        }\n  \n        if (Session.loggedIn) {\n          return;\n        }\n  \n        phase.cancel(() => {\n          Session.returnUrl = Route.path.current;\n          Route.name.replace(phase.router, 'login');\n        });\n      }\n    });\n  }\n}\n```\n\n#### Using the Configuration with a Router\n\n```ts\nimport { FASTElement, customElement } from '@microsoft/fast-element/fast-element.js';\nimport { css } from '@microsoft/fast-element/css.js';\nimport { html } from '@microsoft/fast-element/html.js';\nimport { FASTRouter } from '@microsoft/fast-router';\nimport { AppRouterConfiguration } from './routes';\n\nFASTRouter;\n\nconst template = html<MainApplication>`\n    <fast-router :config=${x => x.routerConfiguration}></fast-router>\n`;\n\nconst styles = css`\n  :host {\n    contain: content;\n  }\n\n  :host, fast-router {  \n    display: block;\n    width: 100%;\n    height: 100%;\n  }\n`;\n\n@customElement({\n  name: 'main-application',\n  template,\n  styles\n})\nexport class MainApplication extends FASTElement {\n  routerConfiguration = new AppRouterConfiguration();\n}\n```\n","isInternal":false,"tokens":934,"sizeBytes":4214},{"name":"README.md","path":"packages/fast-test-harness/README.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/fast-test-harness/README.md","title":"fast-test-harness Documentation","category":"plugin-manifest","format":"markdown","content":"# FAST Test Harness\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\nThe `fast-test-harness` package is a Playwright testing harness for FAST Element web components with CSR and SSR support.\n\n## Requirements\n\n- Node.js 22.18 or later\n- Playwright 1.56 or later\n\n## Installation\n\nTo install `fast-test-harness` using `npm`:\n\n```shell\nnpm install --save-dev @microsoft/fast-test-harness\n```\n\n## Test directory setup\n\nThe harness serves a Vite dev server from a `test/` directory in your project. CSR and SSR modes use different entry points from the same directory.\n\n```\ntest/\n├── index.html              # CSR: loads main.ts\n├── ssr.html                # SSR: template with comment placeholders\n├── vite.config.ts          # Vite config (shared by both modes)\n└── src/\n    ├── main.ts             # CSR: registers components, applies theme\n    ├── entry-client.ts     # SSR: registers components for hydration\n    └── entry-server.ts     # SSR: exports render() for fixture generation\n```\n\n## Writing tests\n\nImport `test` and `expect` from the harness. Configure the component tag name with `test.use()`, then call `fastPage.setTemplate()` in each test to render it.\n\n```ts\nimport { expect, test } from \"@microsoft/fast-test-harness\";\n\ntest.describe(\"Button\", () => {\n    test.use({ tagName: \"my-button\", innerHTML: \"Click me\" });\n\n    test(\"should render\", async ({ fastPage }) => {\n        await fastPage.setTemplate();\n        await expect(fastPage.element).toBeVisible();\n    });\n\n    test(\"should accept attributes\", async ({ fastPage }) => {\n        await fastPage.setTemplate({\n            attributes: { appearance: \"primary\", disabled: true },\n        });\n        await expect(fastPage.element).toHaveAttribute(\"appearance\", \"primary\");\n    });\n\n    test(\"should work inside a form\", async ({ fastPage }) => {\n        await fastPage.setTemplate(`\n            <form>\n                <my-button type=\"submit\">Submit</my-button>\n            </form>\n        `);\n        await expect(fastPage.element).toBeVisible();\n    });\n});\n```\n\nUse `updateTemplate()` to modify attributes or innerHTML after the initial render without navigating away from the page:\n\n```ts\nawait fastPage.setTemplate();\nawait fastPage.updateTemplate(fastPage.element, { attributes: { disabled: true } });\n```\n\nThe `toHaveCustomState` assertion checks `ElementInternals` custom states:\n\n```ts\nawait expect(element).toHaveCustomState(\"checked\");\n```\n\n## Fixture options\n\n| Option | Type | Default | Description |\n| -------- | ------ | --------- | ------------- |\n| `base` | `string` | `\"/\"` | Base path for the test page and SSR endpoint |\n| `tagName` | `string` | `\"\"` | Custom element tag name |\n| `innerHTML` | `string` | `\"\"` | Default inner HTML |\n| `waitFor` | `string[]` | `[]` | Additional elements to wait for before testing |\n| `ssr` | `boolean` | `false` | Use SSR mode (or set `PLAYWRIGHT_TEST_SSR=true`) |\n\n### CSR files\n\n**`index.html`** loads a script that registers your components:\n\n```html\n<!doctype html>\n<html lang=\"en\">\n    <head><meta charset=\"UTF-8\" /></head>\n    <body>\n        <script type=\"module\" src=\"/src/main.ts\"></script>\n    </body>\n</html>\n```\n\n**`main.ts`** registers components and applies global config. The body starts empty; `setTemplate()` injects HTML per test.\n\n```ts\nimport \"./define-all.js\";\nimport { setTheme } from \"./theme.js\";\nsetTheme(lightTheme);\n```\n\n### SSR files\n\n**`ssr.html`** contains comment placeholders the server fills in per request:\n\n```html\n<!doctype html>\n<html lang=\"en\">\n    <head>\n        <title><!--fixturetitle--></title>\n        <!--stylespreload-->\n    </head>\n    <body>\n        <!--fixture-->\n        <!--templates-->\n        <script type=\"module\" src=\"/src/entry-client.ts\"></script>\n    </body>\n</html>\n```\n\n**`entry-client.ts`** imports the harness SSR entry (which enables hydration) and registers components. Component definition modules should use `template: declarativeTemplate()`; this automatically defines FAST's internal `<f-template>` publisher.\n\n```ts\nimport \"@microsoft/fast-test-harness/ssr/entry-client.js\";\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n\nimport { MyButton, definition } from \"../../src/button/index.js\";\n\nMyButton.define({\n    name: definition.name,\n    template: declarativeTemplate(),\n});\n```\n\n**`entry-server.ts`** exports a `render()` function that the server calls for each `setTemplate()` request. It returns three strings that get injected into `ssr.html`:\n\n```ts\nexport function render(queryObj: Record<string, string>): {\n    template: string;    // <f-template> HTML → <!--templates-->\n    fixture: string;     // rendered element HTML → <!--fixture-->\n    preloadLinks: string; // <link> tags → <!--stylespreload-->\n};\n```\n\nUse `createSSRRenderer` from the harness to build the `render()` function. It scans for component build artifacts (f-templates, stylesheets) and uses the `@microsoft/fast-build` WASM renderer to produce declarative shadow DOM on each request.\n\n**Multi-component package** (all components in one package):\n\n```ts\nimport { createSSRRenderer } from \"@microsoft/fast-test-harness/ssr/render.js\";\n\nconst { render } = createSSRRenderer({\n    packageName: \"@my-scope/web-components\",\n    tagPrefix: \"my\",\n});\n\nexport { render };\n```\n\n**Per-component packages** (each component is a separate npm package):\n\n```ts\nimport { createSSRRenderer } from \"@microsoft/fast-test-harness/ssr/render.js\";\n\nconst { render } = createSSRRenderer({\n    tagPrefix: \"my\",\n    components: [\n        { name: \"button\", packageName: \"@my-scope/button\" },\n        { name: \"checkbox\", packageName: \"@my-scope/checkbox\" },\n    ],\n});\n\nexport { render };\n```\n\n## Server\n\nThe package includes a Node.js HTTP server with Vite middleware that handles both CSR page serving and SSR fixture generation. Run it directly or let Playwright manage it via `webServer`:\n\n```ts\n// playwright.config.ts\nexport default defineConfig({\n    webServer: {\n        command: \"fast-test-harness\",\n        port: 3278,\n        reuseExistingServer: true,\n    },\n});\n```\n\nFor custom setup, import `startServer`:\n\n```ts\nimport { startServer } from \"@microsoft/fast-test-harness/server.mjs\";\nawait startServer(process.cwd(), \"./test\", \"./test/vite.config.ts\", {\n    port: 4000,\n    debug: true,\n});\n```\n\nOne server can host several test directories at separate paths. Set the matching\n`base` fixture option for each test group.\n\n```ts\nawait startServer(process.cwd(), process.cwd(), \"./vite.config.ts\", {\n    routes: [\n        { base: \"/button/\", root: \"./packages/button/test\" },\n        { base: \"/dialog/\", root: \"./packages/dialog/test\" },\n    ],\n});\n\ntest.use({ base: \"/button/\", tagName: \"my-button\" });\n```\n\n| Parameter | Default | Description |\n| --------- | ------- | ----------- |\n| `cwd` | `process.cwd()` | Static file serving root |\n| `root` | `<cwd>/test` | Vite root (contains `index.html`, `ssr.html`) |\n| `configFile` | Vite auto-discovery | Vite config path |\n| `options.port` | `3278` | Server port |\n| `options.base` | `/` | Base URL path |\n| `options.debug` | `false` | Write SSR fixtures to `temp/` for inspection |\n| `options.routes` | Single route from `root` and `base` | Test roots keyed by URL base path |\n\n### CLI flags\n\n```\nfast-test-harness [command] [options]\n\nCommands:\n  serve                    Start the test harness dev server (default)\n  generate-templates       Generate <f-template> HTML files from compiled templates\n  generate-stylesheets     Generate CSS files from compiled ElementStyles\n  generate-webui-templates Generate WebUI-compatible DSD templates\n\nServe options:\n  -p, --port <number>    Server port (default: 3278)\n  -b, --base <path>      Base URL path (default: /)\n  -r, --root <path>      Vite root directory (default: <cwd>/test)\n  -c, --config <path>    Vite config file path (default: Vite auto-discovery)\n  -d, --debug            Write SSR fixtures to temp/ for inspection\n  -v, --version          Show version number\n  -h, --help             Show help message\n```\n\nCLI flags take precedence over environment variables.\n\n`generate-templates` preserves browser-valid `<template>` wrappers and strips\nstatic wrappers even when the opening or closing tag includes ASCII whitespace\nbefore `>`.\n\n| Environment variable | Default | Description |\n| -------------------- | ------- | ----------- |\n| `PORT` | `3278` | Server port (overridden by `--port`) |\n| `BASE` | `/` | Base URL path (overridden by `--base`) |\n| `FAST_DEBUG` | — | Set `\"true\"` to enable debug mode (overridden by `--debug`) |\n| `PLAYWRIGHT_TEST_SSR` | — | Set `\"true\"` for SSR mode |\n\n## SSR renderer\n\n**`createSSRRenderer(options)`** scans for component build artifacts and returns a `{ render }` object compatible with the server's `entry-server.ts` contract. It uses the `@microsoft/fast-build` WASM module to parse f-templates and render them into declarative shadow DOM, including wrapper tags whose opening or closing `>` is preceded by ASCII whitespace.\n\n| Option | Type | Description |\n| -------- | ------ | ------------- |\n| `tagPrefix` | `string` | Tag name prefix for custom elements (e.g., `\"fluent\"`, `\"contoso\"`) |\n| `packageName` | `string?` | Monolithic package name — scans subdirectories for component artifacts. Mutually exclusive with `components`. |\n| `components` | `ComponentRegistration[]?` | Explicit list of per-component packages. Mutually exclusive with `packageName`. |\n| `distDir` | `string?` | Artifact directory relative to the package root (default: `\"dist/esm\"`). Only used with `packageName`. |\n| `themeStylesheet` | `string?` | URL or package specifier for a global theme stylesheet. |\n\n## Exports\n\n| Specifier | Contents |\n| ----------- | ---------- |\n| `@microsoft/fast-test-harness` | `test`, `expect`, `CSRFixture`, `SSRFixture`, `toHaveCustomState`, `installDomShim`, `createSSRRenderer` |\n| `@microsoft/fast-test-harness/build/*.js` | `installDomShim`, `generateStylesheets`, `generateFTemplates`, `generateWebuiTemplates`, `definitionAsyncResolver`, `shadowOptionsToAttributes`, `ShadowOptionsResolver` |\n| `@microsoft/fast-test-harness/fixtures/*.js` | `CSRFixture`, `SSRFixture`, `toHaveCustomState`, extended `test` and `expect` |\n| `@microsoft/fast-test-harness/ssr/render.js` | `createSSRRenderer`, `renderTemplate`, `buildEntryHtml`, `buildState` |\n| `@microsoft/fast-test-harness/ssr/entry-client.js` | Enables FAST Element hydration for SSR pages |\n| `@microsoft/fast-test-harness/server.mjs` | `startServer` |\n| `@microsoft/fast-test-harness/playwright.config.mjs` | Shared Playwright configuration |\n| `@microsoft/fast-test-harness/vite.config.mjs` | Shared Vite configuration |\n| `@microsoft/fast-test-harness/public/*` | Static assets (base CSS) |\n","isInternal":false,"tokens":2631,"sizeBytes":10821},{"name":"README.md","path":"packages/README.md","rawUrl":"https://raw.githubusercontent.com/microsoft/fast/HEAD/packages/README.md","title":"packages Documentation","category":"plugin-manifest","format":"markdown","content":"# FAST Packages\n\nOur web component packages.\n\n## `@microsoft/fast-element`\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-element.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-element)\n\nThe `@microsoft/fast-element` library is a lightweight means to easily build performant, memory-efficient, standards-compliant Web Components. FAST Elements work in every major browser and can be used in combination with any front-end framework or even without a framework. To get up and running with `@microsoft/fast-element` see [the Getting Started guide](https://fast.design/docs/getting-started/quick-start).\n\n## `@microsoft/fast-router`\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-foundation.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-router)\n\nThe `@microsoft/fast-router` package contains a history-based navigation and routing solution designed around Web Components. By using `fast-router`, you can create multi-page and full application experiences. The router works with any Web Components, but has special support for Web Components built on FAST.","isInternal":false,"tokens":308,"sizeBytes":1307},{"name":".cursorrules","path":".cursorrules (fastapi-production-architecture-cursorrules-prompt-file.mdc)","rawUrl":"https://raw.githubusercontent.com/PatrickJS/awesome-cursorrules/main/rules/fastapi-production-architecture-cursorrules-prompt-file.mdc","title":"Awesome Cursorrules: fastapi production architecture","category":"cursor-rule","format":"markdown","content":"---\ndescription: \"Cursor rules for FastAPI services with router/service/repository boundaries, typed provider adapters, bulkhead isolation, idempotency, and domain exceptions.\"\nglobs: **/*\nalwaysApply: false\n---\n# FastAPI Production Architecture Rules\n# Principles for production-ready FastAPI services.\n\n## LAYER ARCHITECTURE (Principles A1-A8)\n\nThis codebase follows strict 4-layer architecture: Router → Service → Repository → ORM/HTTP/Storage.\nImports flow downward only. Each layer has hard boundaries you must NOT cross.\n\n### Router rules (app/routers/**)\n- Handlers are THIN: ≤10 lines of executable code per handler\n- Allowed imports: fastapi, app.schemas.*, app.core.deps, app.services.*\n- FORBIDDEN imports: sqlalchemy, httpx, boto3, app.models.*, app.repositories.*\n- Every endpoint declares response_model= for OpenAPI fidelity\n- Every protected/business endpoint requires user_id: str = Depends(get_current_user_id)\n- Public endpoints (health checks, webhooks, callbacks) are exempt from auth\n- Business logic lives in services. Routers parse input, call one service method, return response.\n\nGOOD:\n@router.post(\"/wallet/charge\", response_model=WalletResponse, status_code=201)\nasync def charge(\n    req: ChargeRequest,\n    user_id: str = Depends(get_current_user_id),\n    svc: WalletUserService = Depends(get_wallet_service),\n) -> WalletResponse:\n    wallet = await svc.charge(\n        user_id=user_id,\n        amount=req.amount,\n        idempotency_key=req.idempotency_key,\n    )\n    return WalletResponse.from_domain(wallet)\n\nBAD (business logic + SQL in router):\n@router.post(\"/wallet/charge\")\nasync def charge(req: ChargeRequest, db: Session = Depends(get_db)):\n    wallet = db.query(Wallet).filter(Wallet.user_id == user_id).with_for_update().one()\n    ...\n\n### Service rules (app/services/**)\n- FORBIDDEN imports: sqlalchemy, httpx, boto3, redis, FastAPI Request/Response/HTTPException\n- Constructor injects Protocol-typed dependencies, not concrete classes\n- Raise domain exceptions (InsufficientFundsError), not HTTPException\n\nGOOD:\nfrom app.repositories.protocols import WalletRepoProtocol\nclass WalletUserService:\n    def __init__(self, repo: WalletRepoProtocol):  # Protocol, not SQLAlchemy Session\n        self._repo = repo\n\nBAD:\nfrom sqlalchemy.orm import Session\nclass WalletUserService:\n    def __init__(self, db: Session): ...  # Wrong — service depends on infrastructure\n\n### Repository rules (app/repositories/**)\n- ONLY layer allowed to import sqlalchemy\n- Implements Protocol from app/repositories/protocols.py\n- Returns domain objects, not ORM models\n- Every query scoped by user_id (multi-tenancy)\n\n### Provider rules (app/providers/**)\n- ONLY layer allowed to import httpx directly\n- Returns GenerateResult | ProviderError — NEVER raw dict\n- Uses per-provider httpx.AsyncClient (bulkhead pattern)\n\n## FILE SIZE RULES (Principle A1)\n\n| LOC      | State  | Action                                      |\n|----------|--------|---------------------------------------------|\n| 0–399    | Green  | None.                                       |\n| 400–599  | Yellow | Plan split. Add TODO(decompose) header.     |\n| 600+     | Red    | BLOCK merge. Decompose first.               |\n\nConvert file to package when ANY is true:\n- Crosses 400 LOC and next change pushes past 500\n- Contains 2+ disjoint sub-domains (image vs video, user vs admin)\n- Mixes HTTP handlers with worker handlers\n- Has 2+ callers each importing only one symbol\n\nSafe split pattern (atomic PR):\n1. Create <file>/__init__.py (empty for now)\n2. Move pieces to sub-files (a.py, b.py, c.py)\n3. Re-export old public names from __init__.py\n4. Run tests — must pass without changes\n5. Follow-up PR to migrate callers off legacy alias\n\n__init__.py pattern:\nfrom .user import WalletUserService\nfrom .admin import WalletAdminService\nWalletService = WalletUserService  # backwards-compat alias\n__all__ = [\"WalletUserService\", \"WalletAdminService\", \"WalletService\"]\n\n## EXTERNAL INTEGRATION RULES (Principles B1-B10)\n\n### Rule 1: Anti-Corruption Layer (ACL)\nProviders return GenerateResult | ProviderError, never dict.\n\nfrom dataclasses import dataclass\nfrom decimal import Decimal\n\n@dataclass(frozen=True)\nclass GenerateResult:\n    url: str\n    cost_usd: Decimal\n    latency_ms: int\n    provider_request_id: str\n\nclass ProviderError(Exception):\n    def __init__(self, message: str, *, retryable: bool, code: str | None = None):\n        super().__init__(message); self.retryable = retryable; self.code = code\n\nclass ProviderTimeout(ProviderError):\n    def __init__(self, message: str): super().__init__(message, retryable=True, code=\"timeout\")\n\n### Rule 2: Per-Provider Bulkhead\nEach external provider has its OWN httpx.AsyncClient with its OWN Limits. NEVER share.\n\nGOOD:\nFAL_HTTP = httpx.AsyncClient(\n    base_url=settings.FAL_BASE_URL,\n    timeout=httpx.Timeout(connect=5.0, read=60.0, write=10.0, pool=5.0),\n    limits=httpx.Limits(max_connections=20, max_keepalive_connections=10),\n)\nOPENAI_HTTP = httpx.AsyncClient(\n    base_url=\"https://api.openai.com/v1\",\n    limits=httpx.Limits(max_connections=50, max_keepalive_connections=20),\n)\n\nBAD:\nHTTP = httpx.AsyncClient()  # shared across all providers — no bulkhead isolation\n\n# Shutdown cleanup — close all provider clients in FastAPI lifespan\nfrom contextlib import asynccontextmanager\n\n@asynccontextmanager\nasync def lifespan(app):\n    yield  # app startup\n    await FAL_HTTP.aclose()\n    await OPENAI_HTTP.aclose()\n\napp = FastAPI(lifespan=lifespan)\n# Or on_event(\"shutdown\"):\n# @app.on_event(\"shutdown\")\n# async def close_http_clients() -> None:\n#     await FAL_HTTP.aclose()\n#     await OPENAI_HTTP.aclose()\n\n### Rule 3: Idempotency Keys\nEvery side-effect operation accepts an idempotency_key: UUID. Look up before retrying.\n\n### Rule 4: Structured Logging with contextvars\nUse ContextVar to thread provider, user_id, request_id through async call stacks.\n\nimport contextvars\n\nprovider_var   = contextvars.ContextVar[str | None](\"provider\", default=None)\nuser_id_var    = contextvars.ContextVar[str | None](\"user_id\", default=None)\nrequest_id_var = contextvars.ContextVar[str | None](\"request_id\", default=None)\n\n# Read in logs: provider_var.get(), user_id_var.get(), request_id_var.get()\n# JSON formatter picks these up automatically via extra={} or ContextVar.get()\n\n### Rule 5: Single-Writer Principle (Principle B10)\nFor safety-critical state: exactly ONE service-layer module does the writing.\nOnly the designated writer service for a domain may call repo.hold().\nRouters and providers must NOT call repo.hold() directly.\nAdmin services implemented in the service layer may call repo.hold() only\nif they are the designated writer for that domain.\nEnforce via: code-review grep check (`grep -r \"repo\\.hold(\" --include=\"*.py\"`)\nand unit tests that assert call-origin of repo.hold().\n\n## ANTI-PATTERNS — REJECT ON SIGHT\n\n1. def some_method(self, db: Session, ...) → use Protocol-typed repo\n2. from app.models.user import User inside a service → return domain types from repo\n3. httpx.AsyncClient() instantiated inside a function → use shared per-provider client\n4. raise HTTPException(...) inside a service → raise domain exception\n5. db.query(...) inside a router → move to service then repo\n6. async def call(self, req) -> dict: return resp.json() → ACL violation\n7. HTTP = httpx.AsyncClient() shared → bulkhead violation\n8. result[\"vendor_field\"][\"nested\"] in service code → ACL violation\n9. logger.info(f\"{user_id} did X\") → use structured logging with extra={}\n10. Side-effect operation without idempotency_key → double-charge risk\n\n## DEPENDENCY INJECTION\n\nUse FastAPI Depends() + factory functions in app/core/deps.py.\nDo NOT install dependency-injector, punq, or any DI container.\n\ndef get_wallet_service(db: Session = Depends(get_db)) -> WalletUserService:\n    return WalletUserService(repo=SQLAlchemyWalletRepo(db))\n\n## DOMAIN EXCEPTIONS PATTERN\n\nServices raise domain errors. Routers map to HTTP.\n\n# services/wallet/exceptions.py\nclass InsufficientFundsError(Exception): ...\nclass WalletNotFoundError(Exception): ...\n\n# routers/wallet.py\ntry:\n    wallet = await svc.charge(...)\nexcept InsufficientFundsError:\n    raise HTTPException(402, detail=\"insufficient funds\")\n","tokens":1935,"sizeBytes":8269}],"systemPromptSnippet":"<yakaai_skills repo=\"microsoft/fast\">\n<!-- File: .github/copilot-instructions.md (Tokens: ~2004 | Category: copilot-instructions) -->\n---\nname: FAST Instructions\ndescription: This file describes the general instructions for working with the FAST monorepo, including repository structure, code style, tooling, and contribution guidelines.\napplyTo: '**/*'\n---\n\n# Instructions for FAST\n\n## General\n\n- **Explicit instruction only**: Do not take any action unless explicitly instructed. Wait for clear direction before making changes, running commands, or modifying files.\n\n## Repository Overview\n\nFAST (`@microsoft/fast`) is a Microsoft open-source monorepo for building W3C-standards-compliant Web Components. The core package is `@microsoft/fast-element` — a lightweight, performant Web Component authoring library with a declarative HTML entrypoint. Additional packages provide routing plus declarative build and test tooling.\n\n## Packages\n\nEach package includes a DESIGN.md file, read that to gain a general understanding of the code for that package.\n\n| Package | Status | Purpose |\n|---|---|---|\n| `@microsoft/fast-element` | Stable (v2) | Core Web Component library, including declarative HTML via `@microsoft/fast-element/declarative.js` |\n| `@microsoft/fast-router` | Alpha | Web Component router |\n| `@microsoft/fast-build` | Prerelease | Declarative HTML server side renderer |\n| `@microsoft/fast-test-harness` | Prerelease | Testing utilities for FASTElement components |\n\n### Sites\n\n| Package | Status | Purpose |\n|---|---|---|\n| `sites/website` | Private (not published as a package) | Documentation website source |\n| `sites/benchmarks` | Private (not published as a package) | Benchmarking site |\n\n### Example projects\n\n- `examples/design-system/` — Shared semantic design tokens (`@microsoft/fast-examples-design-system`) consumed by all example apps.\n- `examples/csr/todo-app/` — A simple To-Do app demonstrating FAST usage patterns and using the shared `@microsoft/fast-examples-design-system` tokens.\n- `examples/csr/todo-mobx-app/` — A To-Do app demonstrating how to integrate MobX state with `@microsoft/fast-element` using a single `autorun` per component (no custom bridge code).\n- `examples/ssr/chat-app/` — A declarative FAST chat demo that pre-renders with `@microsoft/fast-build` and streams canned assistant replies into the transcript. Dark theme.\n- `examples/ssr/webui-todo-app/` — A To-Do app demonstrating FAST declarative HTML with `@microsoft/webui` prerendering and `@microsoft/fast-element/declarative.js` hydration. Light theme.\n\n## Skills\n\nThese contain domain-specific guidance. Read when performing related tasks:\n\n- [TypeScript](./skills/typescript/SKILL.md) — compiler constraints, import/export conventions, decorator usage, testing patterns.\n- [Rust](./skills/rust/SKILL.md) — general guidance on performing updates between the crate and package.\n- [Shipping](./skills/shipping/SKILL.md) — pull request format, change file generation, documentation updates.\n- [Pull Request](./skills/fast-pull-request/SKILL.md) — generate a pull request description from the branch diff.\n- [Bug Report](./skills/fast-bug-report/SKILL.md) — generate a bug report issue from conversation context.\n- [Feature Request](./skills/fast-feature-request/SKILL.md) — generate a feature request issue from conversation context.\n- [Testing](./skills/testing/SKILL.md) — running tests locally and in CI, writing Playwright fixture tests.\n- [Documentation](./skills/documentation/SKILL.md) — adding documentation in code, markdown files in each package/crate, and the website.\n\n## Commands\n\nRun all commands from the monorepo root. Use workspace flags to target a single package.\n\n| Task | Command |\n|---|---|\n| Install | `npm ci` |\n| Build all | `npm run build` |\n| Build one package | `npm run build -w @microsoft/fast-element` |\n| Test all | `npm run test` |\n| Test one package | `npm run test -w @microsoft/fast-element` |\n| Test Chromium only | `npm run test:chromium` |\n| Build/test changed only | `lage build --since origin/main` |\n| Test changed only | `lage test:node test:chromium --since origin/main` |\n| Lint | `npm run lint` |\n| Lint fix | `npm run lint:fix` |\n| Format check | `npm run format:check` |\n| Format fix | `npm run format` |\n| Check (lint + format + imports) | `npm run biome:check` |\n| Check fix | `npm run biome:fix` |\n| CI check (read-only) | `npm run biome:ci` |\n| Generate change file | `npm run change` |\n| Check change files | `npm run checkchange` |\n| API docs | `npm run doc -w @microsoft/fast-element` |\n\nBuild and test commands use [Lage](https://microsoft.github.io/lage/) for dependency-aware task execution. Lage respects the package dependency graph and can run incrementally with `--since <ref>` to only build/test changed packages and their dependents. The CI pipelines use `--since` for pull requests to skip unchanged packages.\n\nAll `lint`, `biome:check`, `biome:fix`, and `biome:ci` commands use `biome-changed`, which runs biome only on files with uncommitted git changes. The `format:check` and `format` commands use biome's own `--changed` flag to compare against the default branch.\n\n## Project Structure\n\n```\npackages/<package>/\n  src/                    # Source code\n    index.ts              # Main barrel (re-exports)\n    <feature>/            # Feature directories\n      <feature>.ts        # Implementation\n      <feature>.pw.spec.ts # Co-located Playwright test\n  test/                   # Test harness (Vite dev server, fixtures)\n  dist/                   # Build output (ESM + declarations)\n  docs/                   # API reports (api-extractor)\n  DESIGN.md               # Code documentation for the package or crate\n  README.md               # README for published package use\n```\n\n- Source files use **kebab-case**: `element-controller.ts`, `update-queue.ts`.\n- Playwright test files use `*.pw.spec.ts` suffix, co-located next to the source they test.\n- Node test files use `*.spec.ts` suffix.\n\n## Code Style\n\n### Formatting & Linting (Biome)\n\n- 90-character print width, 4-space indent, double quotes, trailing commas.\n- Single-arg arrow functions omit parens: `x => x + 1`.\n- Import ordering enforced via `organizeImports`.\n- No `I` prefix on interfaces.\n- `any` is permitted (`noExplicitAny: off`).\n- Config: [`biome.jsonc`](../biome.jsonc).\n\n### Naming Conventions\n\n| Element | Convention | Examples |\n|---|---|---|\n| Classes | PascalCase | `ElementController`, `FASTElementDefinition` |\n| Interfaces/Types | PascalCase, no `I` prefix | `Accessor`, `Disposable`, `Expression` |\n| Methods/functions | camelCase | `getValue()`, `handleChange()` |\n| Constants | PascalCase frozen objects or camelCase | `SourceLifetime`, `emptyArray` |\n| Private fields | `_` prefix | `_template`, `_shadowRootOptions` |\n| Files | kebab-case | `element-controller.ts`, `observer-map.ts` |\n| Change callbacks | `${prop}Changed` | `childChanged()`, `templateChanged()` |\n\n### TypeScript\n\nKey constraints (details in [TypeScript skill](./skills/typescript/SKILL.md)):\n\n- ESM only (`\"type\": \"module\"`) — imports use `.js` extensions.\n- `import type { ... }` required for type-only imports (`verbatimModuleSyntax`).\n- Named exports only — no default exports.\n- Legacy decorators enabled (`experimentalDecorators: true`).\n- `strictNullChecks` and `noImplicitAny` enabled.\n\n## Tooling\n\n| Tool | Purpose |\n|---|---|\n| npm workspaces | Package management |\n| Lage | Task runner — dependency-aware builds and incremental testing |\n| TypeScript | Compilation |\n| Rollup | Bundling (`fast-element` only) |\n| Playwright | Testing |\n| Vite | Test dev server |\n| api-extractor | API documentation + `.d.ts` rollup |\n| beachball | Change files, versioning, publishing |\n| Biome | Formatting + Linting |\n| lefthook | Pre-commit hooks (runs `biome:check` and `checkchange` on staged files) |\n| Rust | Rendering Declarative templates (`fast-build` package and `microsoft-fast-build` crate only) |\n\n## Acceptance Checklist\n\nBefore finishing any change, run these commands from the monorepo root and confirm they pass:\n\n- [ ] `npm run build` — all packages build successfully\n- [ ] `npm run test` — all tests pass\n- [ ] `npm run biome:check` — Biome linting and formatting pass\n- [ ] `npm run checkchange` — beachball change files exist for any `packages/*` changes\n\nRead the [shipping skill](./skills/shipping/SKILL.md) and ensure you have updated everything outlined in that file.\n\n<!-- File: .github/skills/documentation/SKILL.md (Tokens: ~240 | Category: anthropic-skill) -->\n---\nname: documentation\ndescription: Add documentation for contributors and developers.\n---\n\nDocumentation exists in 3 forms, code comments, design/architectural documentation that is made up of markdown files describing code flow and core concepts (such as DESIGN.md), and the documentation website.\n\nDesign/architectural documentation such as DESIGN.md should always be kept up-to-date.\n\nThe website captures the documentation primarily for the `@microsoft/fast-element` package. Other packages are treated as tangential, so testing packages or other utilities should have their own sections.\n\nThe website has been written in 11ty and primarily consists of markdown files. When making changes, ensure that the website has been scanned on whichever latest major version is available. These are organized by folder, so if 1.x/2.x/3.x folders are available, you will update the documentation in the 3.x folder.\n\nIf you are making a breaking change, ensure the migration document has been updated.\n\nAll markdown documentation aside from the package/crate level DESIGN.md files are in that package/crates docs folder.\n\nAny documentation created for the website should be written with the developer implementing the package in mind, it is not intended for other audiences.\n\n<!-- File: .github/skills/fast-bug-report/SKILL.md (Tokens: ~389 | Category: anthropic-skill) -->\n---\nname: fast-bug-report\ndescription: Generate a bug report issue for the FAST repository using the provided template.\n---\nThis prompt only applies to generating Bug Report issues for the FAST repository.\n\nDo not create or modify any existing Github issues. This skill is only for\ngenerating the markdown content for a new issue based on the provided template.\n\nBased on the conversation context, generate a bug report as a markdown code\nblock using the template located at\n[../../ISSUE_TEMPLATE/bug-report.md](../../ISSUE_TEMPLATE/bug-report.md).\n\nThe summary should clearly state what the bug is and which part of the system\nis affected.\n\nRepro or Code Sample should provide clear, minimal steps to reproduce the issue.\nInclude a code snippet, repository link, or gist if possible.\n\nExpected Behavior should describe what the correct behavior should be.\n\nCurrent Behavior should explain what actually happens instead. Include the full\nerror message and stack trace if applicable. Mention screenshots if they would\nhelp illustrate the problem.\n\nPossible Solution is optional. Include it only if there is a concrete idea about\nthe cause or fix. Mention if the reporter is willing to contribute a fix.\n\nContext should explain how the bug affects the user and what they are trying to\naccomplish. This helps prioritize and design the right solution.\n\nYour Environment should capture relevant details: OS, device, browser, and\npackage version.\n\nSearch for existing open or closed issues that overlap with this bug report.\nIf duplicates or related issues exist, mention them in the Context section.\n\nSuggest a concise issue title in the format `fix: [what is the issue?] in [where is the issue?]`.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nAny comments in the template can be removed since they're only meant to provide\nguidance on how to fill out the template, and are not intended to be part of the\nfinal issue body.\n\n<!-- File: .github/skills/fast-feature-request/SKILL.md (Tokens: ~374 | Category: anthropic-skill) -->\n---\nname: fast-feature-request\ndescription: Generate a feature request issue for the FAST repository using the provided template.\n---\nThis prompt only applies to generating Feature Request issues for the FAST repository.\n\nDo not create or modify any existing Github issues. This skill is only for\ngenerating the markdown content for a new issue based on the provided template.\n\nBased on the conversation context, generate a feature request as a markdown code\nblock using the template located at\n[../../ISSUE_TEMPLATE/feature-request.md](../../ISSUE_TEMPLATE/feature-request.md).\n\nThe summary should clearly state what the feature is and why it matters, focusing\non user value rather than implementation details.\n\nExpected Behavior should describe how the feature would work from an end-user or\ndeveloper perspective. Be specific about the desired outcome.\n\nCurrent Behavior should explain the gap — what exists today and how the absence of\nthis feature affects users. If there is a workaround, mention it briefly.\n\nPossible Solution is optional. Include it only if there is a concrete implementation\nidea worth capturing. Prefer high-level direction over prescriptive code.\n\nContext should explain the motivation — what the user is trying to accomplish\nand why this feature would help. Mention alternatives that were considered, if any.\n\nExamples is optional. Include it when code snippets, screenshots, or usage\nscenarios would clarify the request.\n\nSearch for existing open or closed issues that overlap with this feature request.\nIf duplicates or related issues exist, mention them in the Context section.\n\nSuggest a concise issue title in the format `feat: add [what] to/in [where]`.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nAny comments in the template can be removed since they're only meant to provide\nguidance on how to fill out the template, and are not intended to be part of the\nfinal issue body.\n\n<!-- File: .github/skills/fast-pull-request/SKILL.md (Tokens: ~596 | Category: anthropic-skill) -->\n---\nname: fast-pull-request\ndescription: Generate a pull request description for the FAST repository using the provided template.\n---\nThis skill only applies to generating Pull Request descriptions for the FAST repository.\n\nDo not create or modify any existing Github pull requests. This skill is only for\ngenerating the markdown content for a pull request description based on the provided template.\n\nBased on the conversation context, generate a pull request description as a markdown code\nblock using the template located at\n[../../pull_request_template.md](../../pull_request_template.md).\n\nUse the Pull Request Template to generate a markdown code block for the most\nrelevant work on this git branch, compared to `main`.\n\nThe Description should be either a summary description of the content of the branch,\nor a list of the most relevant changes made in the branch. The goal is to address\nthe purpose of the pull request in a concise manner, rather than detailing every change. \"Why\"\nand \"what\" over \"how\".\n\nDetermine if any current github issues are being addressed by this work, and\nlist them in the Issues section with links. If none are found, remove the Issues section.\n\nThe reviewer notes section is optional. Include it only if there are specific\nareas where you would like feedback or attention from the reviewer.\n\nThe Test Plan section should outline any issues that need to be verified before merging,\nor steps to reproduce the behavior locally. Even a brief note is helpful, such as \"All existing tests pass\".\n\nThe checklist section should be completed to indicate the status of various\naspects of the pull request.\n\nIf there are change files that have been added to the PR, check the box labeled \"I have included a change request file using `$ npm run change`\".\n\nIf any new tests have been added, check the box labeled \"I have added tests for my changes.\"\n\nCheck the terminal output for evidence of passing tests, and check the box labeled \"I have tested my changes.\" if tests have been run and are passing. If not, leave the box unchecked.\n\nIf any doc blocks have been added or modified, or if any documentation files have been added or modified, check the box labeled \"I have updated the project documentation to reflect my changes.\" This also applies to any changes made to api-report files.\n\nThe final checkbox must be checked by the pull request author. It should never be checked when generating this PR description.\n\nThe Next Steps section is optional. Include it only if there are specific follow-up tasks\nor work items that should be addressed after merging this PR, such as updating documentation, adding new tests, or performing code cleanup. If any existing issues are being addressed by the next steps, reference them here.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nAny comments in the template can be removed since they're only meant to provide\nguidance on how to fill out the template, and are not intended to be part of the\nfinal PR description.\n\n<!-- File: .github/skills/rust/SKILL.md (Tokens: ~145 | Category: anthropic-skill) -->\n---\ndescription: Use this guide when working on Rust changes in the FAST monorepo.\nname: rust\n---\n\n# Working with the Rust crate and the Rust NodeJS CLI\n\nThe primary location for the Rust logic should exist within a crate. If the logic is made accessible in the NodeJS environment via wrapping the crate and using a wasm bindgen, as much as possible any logic that exists in Rust should not be duplicated in JavaScript/TypeScript.\n\n## Breaking changes\n\nUnderstand [semver](https://semver.org/) and check the crate and package version. If the version is currently in a prerelease state, update the APIs with breaking changes as necessary and ensure that any generated pull request descriptions capture this.\n\n<!-- File: .github/skills/shipping/SKILL.md (Tokens: ~2065 | Category: anthropic-skill) -->\n---\ndescription: Use this skill when contributing changes to the FAST monorepo — creating pull requests, generating change files, writing PR descriptions, and keeping documentation up to date.\nname: shipping\n---\n\n# Shipping Patterns for FAST\n\nUse this guide when shipping changes in the FAST monorepo — writing PR descriptions, generating change files, and keeping documentation up to date.\n\n# Guardrails\n\nDo NOT perform any of the following actions autonomously. These require explicit human action:\n\n- **Do not merge or close pull requests** — no `gh pr merge`, `gh pr close`, or equivalent.\n- **Do not publish packages** — no `npm publish`, `beachball publish`, or release operations.\n- **Do not modify branch protection or repository settings**.\n\n## Key references\n\nRead these documents for additional context when needed:\n\n- [`.github/pull_request_template.md`](../../pull_request_template.md) — PR description template (source of truth for PR structure).\n- [`CONTRIBUTING.md`](../../../CONTRIBUTING.md) — Full contributor guide (machine setup, branching, governance).\n- [`BRANCH_GUIDE.md`](../../../BRANCH_GUIDE.md) — Branch management conventions.\n- [`beachball.config.js`](../../../beachball.config.js) — Beachball configuration (ignored patterns, publish settings).\n- [`CODE_OF_CONDUCT.md`](../../../CODE_OF_CONDUCT.md) — Community standards.\n\n### Package/Crate references\n\nRead these documents, they are located at the root of the specific package or crate, e.g. `packages/<package>/<file>.md` and relate to the package/crates they are located in. When making changes in the package/crate afterwards update these files if necessary.\n\n- `DESIGN.md` - Explains the code patterns.\n- `README.md` - Explains how a developer/agent would use this package/crate.\n\n# Commit and PR title conventions\n\nUse [conventional commit](https://www.conventionalcommits.org/) format for PR titles and merge commit messages:\n\n```\n<type>: <short summary>\n```\n\nCommon types: `feat`, `fix`, `chore`, `docs`, `refactor`, `test`, `perf`.\n\nExamples:\n- `feat: add shadow DOM support to declarative templates`\n- `fix: resolve memory leak in template binding`\n- `chore: update dev dependencies`\n\n# Pull requests\n\nUse the repository's PR template at [`.github/pull_request_template.md`](../../pull_request_template.md) as the basis for all pull request descriptions.\n\nProvide the markdown code block only, without any additional commentary or explanation.\n\nThe comments in the template can be removed since they're only meant to provide guidance on how to fill out the template, and are not intended to be part of the final PR description.\n\nFill out each section as detailed below.\n\n## Description\n\nThe Description should be either a summary description of the content of the branch,\nor a list of the most relevant changes made in the branch. The goal is to address\nthe purpose of the pull request in a concise manner, rather than detailing every change. \"Why\"\nand \"what\" over \"how\".\n\n## Issues\n\nDetermine if any current github issues are being addressed by this work, and\nlist them in the Issues section with links. If none are found, remove the Issues section.\n\n## Reviewer Notes\n\nThe reviewer notes section is optional. Include it only if there are specific\nareas where you would like feedback or attention from the reviewer.\n\n## Test Plan\n\nThe Test Plan section should outline any issues that need to be verified before merging,\nor steps to reproduce the behavior locally. Even a brief note is helpful, such as \"All existing tests pass\".\n\n## Checklist\n\nThe checklist section should be completed to indicate the status of various\naspects of the pull request.\n\nIf there are change files that have been added to the PR, check the box labeled \"I have included a change request file using `$ npm run change`\".\n\nIf any new tests have been added, check the box labeled \"I have added tests for my changes.\"\n\nCheck the terminal output for evidence of passing tests, and check the box labeled \"I have tested my changes.\" if tests have been run and are passing. If not, leave the box unchecked.\n\nIf any doc blocks have been added or modified, or if any documentation files have been added or modified, check the box labeled \"I have updated the project documentation to reflect my changes.\" This also applies to any changes made to api-report files.\n\nThe final checkbox must be checked by the pull request author. It should never be checked when generating this PR description.\n\n## Next Steps\n\nThe Next Steps section is optional. Include it only if there are specific follow-up tasks\nor work items that should be addressed after merging this PR, such as updating documentation, adding new tests, or performing code cleanup. If any existing issues are being addressed by the next steps, reference them here.\n\n# Acceptance checklist\n\nBefore making a change, if the change is addressing a bug make sure you write a test first and ensure that it is failing:\n\n```bash\nnpm run build            # all packages build successfully\nnpm run test             # test fails\n```\n\nBefore finishing any change, run these commands from the monorepo root and confirm they pass:\n\n```bash\nnpm run build            # all packages build successfully\nnpm run test             # all tests pass\nnpm run format:check     # Prettier formatting is correct\nnpm run checkchange      # Beachball change files exist for packages/* changes\n```\n\n# Change files\n\nAfter completing a change to any package under `packages/`, generate a Beachball change file:\n\n```bash\n# This should be run from the monorepo root\nnpm run change\n```\n\nThis walks through the steps to create a change description file that is required for versioning and publishing. The CI gate `npm run checkchange` will fail if a change file is missing for a modified package.\n\n## Change comments\n\nWrite the `comment` field as release-note text, not as a commit message. Use a\nconcise sentence that starts with a capital letter and ends with a period. Do not\nprefix comments with conventional commit types such as `fix:`, `feat:`, or\n`chore:`.\n\nBeachball uses change-file comments to generate package changelogs and release\nnotes. Sentence-style comments read cleanly in those user-facing outputs, while\ncommit-style prefixes duplicate the separate change type metadata and add noise.\n\n## Change types\n\nWhen prompted, select the appropriate change type:\n\n| Type | When to use |\n|---|---|\n| `major` | Breaking changes to public API |\n| `minor` | New features, non-breaking additions |\n| `patch` | Bug fixes, minor corrections |\n| `none` | Changes that don't affect the published package (tests, docs, tooling) |\n\n## When change files are NOT required\n\nThe Beachball config ([`beachball.config.js`](../../../beachball.config.js)) ignores these paths — changes limited to them do not need change files:\n\n- `.github/` — CI configs, templates, skills\n- Test files (`src/e2e/`, `src/tests/`, `src/fixtures/`)\n- `package-lock.json`\n- `.vscode/`, `.prettierrc`\n\nAdditionally, [`build/scripts/checkchange.mjs`](../../../build/scripts/checkchange.mjs) (which wraps `beachball check` for the `checkchange` npm script) skips the check entirely on **manual version bump** branches authored by a repo admin. Specifically, both of the following must be true for the current run:\n\n1. Branch name matches `^publish_\\d+$` (beachball's documented publish-branch convention).\n2. The actor (`$GITHUB_ACTOR` in CI; locally, the user from `gh api user`) has the `admin` role on `microsoft/fast`, verified via the GitHub REST API.\n\nIf either condition fails, the change-file requirement applies as before. See [`CONTRIBUTING.md` > Manual version bumps](../../../CONTRIBUTING.md#manual-version-bumps) for the full rationale and reviewer expectations.\n\n## Cross-branch targeting\n\nWhen working across feature branches, target the branch explicitly:\n\n```bash\nnpm run change -- --branch origin/{branch-name}\n```\n\n## Multiple unrelated changes\n\nIf addressing multiple unrelated issues, prefer separate pull requests.\n\n# Breaking changes\n\nWhen introducing breaking changes:\n\n1. Select `major` as the change type when running `npm run change`.\n2. Document the migration strategy in `packages/<package>/docs/migration/<migration-name>.md`.\n\nFormat for a migration document:\n\n```md\n# Migrating from previous versions\n\n## v1 to v2\n\n- Export `Foo` has been renamed to `Bar`.\n- `Bat` has been updated to use the new API [`BatConfig`](link/to/api).\n```\n\nIf the breaking change is significant or requires multiple PRs, open a [discussion](https://github.com/microsoft/fast/discussions) first.\n\n# Documentation\n\nAfter any changes ensure that the documentation is up to date, this includes the files DESIGN.md and README.md files for any packages/crates that have been modified. If your changes update or add to the public API, update the sites/website/src/docs/ files. Only update the latest version, these are denoted by major versions in their folder names inside the docs folder, 1.x, 2.x, etc., find the latest version of the docs and modify them if necessary.\n\nWhen adding or modifying exported APIs, run the website prebuild script to regenerate API documentation from the api-extractor output:\n\n```bash\nnpm run prebuild -w sites/website\n```\n\nThis runs [`sites/website/scripts/generate-docs.cjs`](../../../sites/website/scripts/generate-docs.cjs), which copies API documentation from each package's extracted API reports into the website source. Run this after building packages to ensure generated documentation stays in sync with the codebase.\n\n<!-- File: .github/skills/testing/SKILL.md (Tokens: ~1403 | Category: anthropic-skill) -->\n---\nname: testing\ndescription: Use this skill when running or writing tests in the FAST monorepo — local test execution, CI workflows, Playwright fixtures, and WebUI integration testing.\n---\n\n# Testing Patterns for FAST\n\nUse this guide when running or writing tests in the FAST monorepo. FAST uses [Playwright](https://playwright.dev/) for integration testing with a [Vite](https://vitejs.dev/) dev server.\n\n## Running tests\n\n### Locally\n\n#### First-time setup\n\nAfter cloning and installing dependencies (`npm ci`), install Playwright browsers:\n\n```bash\nnpx playwright install --with-deps\n```\n\n#### Commands\n\nAll commands are run from the **monorepo root**. Use `-w` to target a specific package.\n\n| Task | Command |\n|---|---|\n| Run all tests (all browsers) | `npm run test` |\n| Run all tests (Chromium only) | `npm run test:chromium` |\n| Test a single package (all browsers) | `npm run test -w @microsoft/fast-element` |\n| Test a single package (Chromium only) | `npm run test:chromium -w @microsoft/fast-element` |\n| Test changed packages only | `npx lage test:node test:chromium --since origin/main` |\n\n#### Interactive / debug workflows\n\nFor FAST declarative tests in `@microsoft/fast-element`, these additional scripts are available:\n\n| Task | Command |\n|---|---|\n| Playwright UI mode | `npm run test:ui:declarative -w @microsoft/fast-element` |\n| Start declarative source server | `npm run test-server:declarative -w @microsoft/fast-element` |\n| Rebuild fixtures | `npm run build:fixtures -w @microsoft/fast-element` |\n| Build fixtures with webui | `npm run build:fixtures:webui -w @microsoft/fast-element` |\n| Run webui integration tests | `npm run test:webui-integration -w @microsoft/fast-element` |\n\n**Playwright UI mode** (`test:ui`) starts a visual test runner where you can select and debug individual tests, view traces, and inspect DOM snapshots.\n\n**Declarative browser workflows** resolve `@microsoft/fast-element` package imports directly to `src` and let Vite transpile TypeScript on demand. Vite does not type-check these modules; the package build remains responsible for type checking, while `test:exports` imports every emitted package export.\n\n### Through GitHub Actions\n\nThe repository uses several CI workflows to validate changes.\n\n#### PR validation (ci-validate-pr.yml)\n\nRuns on every pull request targeting `main`, `releases/*`, or `features/*` branches. Tests run on **Ubuntu with Chromium only** for fast feedback.\n\nKey steps:\n- Checks for change files (`npm run checkchange`)\n- Biome lint/format check\n- Builds affected packages (incremental with `--since`)\n- Runs `test:node` and `test:chromium` for affected packages\n\n#### Cross-platform validation (ci-validate-platforms.yml)\n\nRuns on pushes to `main`, PRs targeting `main`, and on a weekly schedule. Tests run on **Ubuntu, Windows, and macOS** with **Chromium, Firefox, and Safari**.\n\nThis ensures cross-platform and cross-browser compatibility.\n\n#### WebUI integration testing (ci-webui-integration.yml)\n\nA dedicated workflow for validating FAST's integration with `@microsoft/webui`. This workflow runs on:\n\n- **Manual dispatch** (`workflow_dispatch`)\n- **Pushes to `webui/*` branches**\n\n> **Note:** This workflow does _not_ run on regular pull requests. It is scoped to `webui/*` branches to test integration changes in isolation before they land on `main`.\n\nThe workflow builds all packages, installs Playwright Chromium, and runs:\n\n```bash\nnpm run test:webui-integration -w @microsoft/fast-element\n```\n\nThis builds each fixture with `webui build --plugin=fast`, renders the protocol with the fixture's `state.json`, and runs the same Playwright specs against the webui-rendered output.\n\nTo trigger WebUI integration tests for your changes:\n\n1. Create a branch with the `webui/` prefix (e.g., `webui/my-integration-change`).\n2. Push the branch — the workflow runs automatically.\n3. Alternatively, trigger the workflow manually from the Actions tab using `workflow_dispatch`.\n\n#### Azure Pipelines (azure-pipelines-ci.yml)\n\nThe repository also has an Azure DevOps pipeline that runs on PRs to `main`. This pipeline runs in a 1ES-managed environment and includes SDL compliance checks in addition to building and testing.\n\n## Writing tests\n\nFAST tests are [Playwright](https://playwright.dev/) integration tests that run against fixture pages served by Vite.\n\n### Test file conventions\n\n- Test files use the `*.spec.ts` suffix (specifically `*.pw.spec.ts` for package `src/` tests).\n- Tests for developer-authored declarative markup and directives live in the matching\n  `test/declarative/fixtures/<category>/<feature>/<feature>.spec.ts` fixture.\n- Tests for implementation APIs and lifecycle behavior are co-located with their source as\n  `src/<feature>/<feature>.pw.spec.ts`.\n\n### Writing declarative fixture tests\n\nFixture tests in `@microsoft/fast-element/test/declarative/fixtures` are the primary way to verify declarative template features. Each fixture is a self-contained test case with its own HTML, state, templates, and component definitions.\n\nWhen changing declarative syntax, directive parsing, template generation, hydration behavior, or other user-authored template behavior, add or update a declarative fixture and exercise it in browser. Source-level parser tests may supplement narrow parsing edge cases, but they should not be the only coverage for syntax that users write in `entry.html` or `templates.html`. Use the local README files under `packages/fast-element/test/declarative/fixtures/` and each fixture category to choose the right fixture type and follow category-specific examples.\n\nFor a complete guide on creating fixtures — including how to write `entry.html`, `state.json`, `templates.html`, `main.ts`, and spec files — see:\n\n📄 **[Writing Fixtures](../../../packages/fast-element/test/declarative/fixtures/WRITING_FIXTURES.md)**\n\n### Quick example\n\n```typescript\nimport { expect, test } from \"@playwright/test\";\n\ntest.describe(\"my-feature\", async () => {\n    test(\"renders correctly\", async ({ page }) => {\n        await page.goto(\"/fixtures/bindings/my-feature/\");\n\n        const element = page.locator(\"my-element\");\n        await expect(element).toHaveText(\"Hello\");\n    });\n});\n```\n\n<!-- File: .github/skills/typescript/SKILL.md (Tokens: ~1806 | Category: anthropic-skill) -->\n---\ndescription: Use this guide when working on TypeScript changes in the FAST monorepo — authoring Web Components, writing templates and styles, working with the observable/reactive system, and testing.\nname: typescript\n---\n\n# TypeScript Patterns for FAST\n\n## Modules\n\n`fast-element` enables `verbatimModuleSyntax`, so type-only imports must use `import type`\nor the inline `type` qualifier:\n\n```ts\nimport type { Notifier, Subscriber } from \"./notifier.js\";\nimport { type Constructable, isFunction } from \"../interfaces.js\";\n```\n\nSub-entry-points expose focused APIs through the `exports` map:\n\n```ts\nimport { twoWay } from \"@microsoft/fast-element/two-way.js\";\nimport { reactive } from \"@microsoft/fast-element/state.js\";\n```\n\nThe barrel `index.ts` explicitly lists every re-export grouped by subsystem — no\n`export *` statements.\n\nAside from the `index.ts` or `index.*.ts` files there should be no barrel exports.\n\n## Side Effects\n\nDo not add side effectful code and do not add `sideEffects` to `package.json` files.\nAPIs added should import named exports.\n\n## Browser APIs\n\n### Do not use\n\nOur stance as a framework library is that certain browser APIs are best avoided by\nthe framework. We may facilitate the use of them through our provided APIs.\n\nList of APIs to avoid implementing in FAST packages:\n- `requestIdleCallback`\n- `setTimeout`\n- `setInterval`\n\n### Avoid\n\nSome browser APIs can be used but should be avoided as a developer may encounter\nedge cases with task queuing or other logic their app is executing.\n\nList of APIs to avoid in FAST packages:\n- `requestAnimationFrame`\n- `queueMicrotask`\n\n## Custom elements\n\nElements extend `FASTElement`. Do **not** use the `@customElement` decorator.\n\nUse `define()` for registration. `define()` returns a `Promise` that resolves\nimmediately when a template is provided:\n\nExample define.ts (side-effect import):\n```ts\nexport class MyElement extends FASTElement {\n    @observable items: string[] = [];\n}\n\nawait MyElement.define({\n    name: \"my-element\",\n    template,\n    styles,\n});\n```\n\n## Templates\n\nTemplates use the `html` tagged template literal typed to the element class:\n\n```ts\nimport { html } from \"@microsoft/fast-element/html.js\";\nimport { repeat } from \"@microsoft/fast-element/repeat.js\";\nimport { when } from \"@microsoft/fast-element/when.js\";\nimport type { MyElement } from \"./my-element.js\";\n\nexport const template = html<MyElement>`\n    <h1>${x => x.title}</h1>\n    ${when(x => x.showList, html<MyElement>`\n        <ul>\n            ${repeat(\n                x => x.items,\n                html<string>`<li>${x => x}</li>`\n            )}\n        </ul>\n    `)}\n`;\n```\n\n### Binding syntax\n\n| Prefix | Purpose | Example |\n|---|---|---|\n| `${x => ...}` | Content or attribute | `${x => x.name}` |\n| `@event` | Event listener | `@click=${x => x.handleClick()}` |\n| `@event` | Event with context | `@click=${(x, c) => c.parent.remove(x)}` |\n| `:prop` | DOM property | `:value=${twoWay(x => x.description)}` |\n| `?attr` | Boolean attribute | `?disabled=${x => !x.isValid}` |\n\nTwo-way bindings require a sub-entry-point import:\n\n```ts\nimport { twoWay } from \"@microsoft/fast-element/two-way.js\";\n```\n\n### Partial HTML\n\nUse `html.partial()` to inject pre-built HTML strings into a template without creating\na full `ViewTemplate`:\n\n```ts\nhtml<MyElement>`\n    <div>${html.partial(\"<span>static markup</span>\")}</div>\n`;\n```\n\n## Styles\n\nStyles use the `css` tagged template literal. They attach through the element definition's\n`styles` property:\n\n```ts\nimport { css } from \"@microsoft/fast-element/css.js\";\n\nexport const styles = css`\n    :host {\n        display: block;\n        padding: 16px;\n    }\n`;\n```\n\nFor declarative HTML definitions, styles live in a separate `.styles.css` file linked from\nboth the initial shadow root template and the `<f-template>`:\n\n```html\n<f-template name=\"my-element\">\n    <template>\n        <link rel=\"stylesheet\" href=\"./my-element.styles.css\">\n    </template>\n</f-template>\n```\n\n`css.partial()` works the same way as `html.partial()` — injecting raw CSS strings.\n\n## Reactivity\n\n`@attr` maps HTML attributes to properties. `@observable` creates reactive properties\ntracked by templates. `@volatile` marks getters whose dependencies change between calls:\n\n```ts\nimport { FASTElement } from \"@microsoft/fast-element/fast-element.js\";\nimport { attr, nullableNumberConverter } from \"@microsoft/fast-element/attr.js\";\nimport { Observable, observable } from \"@microsoft/fast-element/observable.js\";\nimport { volatile } from \"@microsoft/fast-element/volatile.js\";\n\nclass MyElement extends FASTElement {\n    @attr label?: string;\n    @attr({ mode: \"boolean\" }) active?: boolean;\n    @attr({ converter: nullableNumberConverter }) count?: number;\n\n    @observable private _items: string[] = [];\n\n    // Convention: ${propertyName}Changed\n    labelChanged(prev: string | undefined, next: string | undefined) {}\n\n    @volatile\n    get sortedItems(): readonly string[] {\n        return [...this._items].sort();\n    }\n}\n```\n\nNotify the system after in-place mutations that it cannot detect automatically:\n\n```ts\nthis._items.splice(index, 1);\nObservable.notify(this, \"_items\");\n```\n\nMake plain objects observable via the state sub-entry-point:\n\n```ts\nimport { reactive } from \"@microsoft/fast-element/state.js\";\nconst todo = reactive({ description: \"Buy milk\", done: false });\n```\n\n## Testing\n\nTests use Playwright Test (`*.pw.spec.ts`) and combine two patterns within the same file.\n\n### Direct-import tests\n\nFor logic that does not need browser APIs — the test callback takes no parameters:\n\n```ts\nimport { expect, test } from \"@playwright/test\";\nimport { Observable } from \"./observable.js\";\n\ntest.describe(\"Observable\", () => {\n    test(\"can get a notifier\", () => {\n        const notifier = Observable.getNotifier(new Model());\n        expect(notifier).toBeInstanceOf(PropertyChangeNotifier);\n    });\n});\n```\n\n### Browser-evaluated tests\n\nFor tests requiring DOM APIs, navigate to the Vite dev server and import via\n`\"/main.js\"`. The `@ts-expect-error` comment is required because TypeScript cannot\nresolve the URL-based import:\n\n```ts\ntest(\"renders element\", async ({ page }) => {\n    await page.goto(\"/\");\n\n    const result = await page.evaluate(async () => {\n        // @ts-expect-error: Client module.\n        const { FASTElement, html, uniqueElementName } = await import(\"/main.js\");\n        // ... test logic ...\n        return someSerializableValue;\n    });\n\n    expect(result).toBe(expected);\n});\n```\n\nOnly serializable values can cross the `page.evaluate` boundary — run `expect()`\nassertions outside it on the returned data.\n\nThe test harness at `packages/<package>/test/main.ts` re-exports source modules for\nbrowser tests. When adding new package exports, add them there too.\n\n## TypeScript idioms\n\n### Const-type merging for enumerations\n\nFrozen const objects paired with a type extracted from their values replace TypeScript\n`enum`:\n\n```ts\nexport const SourceLifetime = {\n    default: undefined,\n    couple: 1,\n} as const;\n\nexport type SourceLifetime =\n    (typeof SourceLifetime)[keyof typeof SourceLifetime];\n```\n\n### Interface-const merging\n\n`FASTElement` is both an interface (instance shape) and a const (constructor). Static\nmethods use `typeof` to carry overloaded signatures:\n\n```ts\nexport const FASTElement: {\n    new (): FASTElement;\n    define: typeof define;\n} = Object.assign(createFASTElement(HTMLElement), { define });\n```\n\n### Tagged template intersection types\n\n`html` and `css` are typed as intersections of a tagged template function and a\n`.partial()` method:\n\n```ts\ntype HTMLTemplateTag = (<TSource, TParent>(\n    strings: TemplateStringsArray,\n    ...values: TemplateValue<TSource, TParent>[]\n) => ViewTemplate<TSource, TParent>) & {\n    partial(html: string): InlineTemplateDirective;\n};\n```\n\n<!-- File: packages/fast-build/docs/migration/plugin-integrations.md (Tokens: ~1088 | Category: anthropic-skill) -->\n# Migrating plugin integration pipelines\n\n## Structured errors\n\nWASM failures now throw JavaScript `Error` objects rather than strings. Read\n`error.message` for the previous human-readable text; `String(error)` now has the\nstandard `Error: ` prefix. Replace message matching with stable `error.code`\nchecks. Both WASM declaration modules export a `FastBuildError` interface extending\n`Error`; it is a type only, not an exported constructor.\n\nOptional `line`/`column` are one-based UTF-16 coordinates, and `length` is a UTF-16\nerror-token highlight length. CRLF is one break; lone CR/LF also break lines.\nEntry and conversion coordinates refer to the complete supplied HTML. A named\ncustom-element render failure instead refers to its separately supplied `content`.\nUse `templateName` to select that source, rather than attaching its coordinates\nto the entry or to a full file from which `content` was extracted. Older metadata\ndoes not carry enough provenance to reconstruct those full-file positions.\nDo not fabricate HTML locations when these fields are absent (JSON/options,\nmissing sources, filesystem errors, or separate CSS).\n\nNative Rust `RenderError` and `ConvertError` expose `code()`, `location()` returning\nan optional `ErrorLocation`, `template_name()`, and `kind()`. Source-annotated\nvalidation errors may use the new `Located` variant; match `error.kind()` to\ninspect the underlying variant. Context fields now use boxed `ErrorContext`\ninstead of `String`; use `context.to_string()` to read the unchanged snippet and\n`String::into()` when constructing a context without source provenance.\nUpdate exhaustive enum matches for `Located`. These are intentional pre-1.0\nnative API changes. Successful rendering/conversion, warnings, missing-state\nbehavior, and permissive `parse_f_templates` parsing are unchanged.\n\n## Attribute output changes\n\nMissing and explicit `null` bindings now omit the entire attribute, including\nmixed literal/binding values. To intentionally keep `href=\"\"`, provide `\"\"`\ninstead of null. JSON booleans on known HTML boolean attributes use presence:\nfalse omits `disabled`, true emits it. ARIA/ordinary attribute booleans remain\ntextual. Use FAST's `?name` syntax for matching client-side truthy/falsy behavior.\nAuthor bindings resolving to absence suppress matching template-host defaults.\nRemove wrapper regular expressions that strip empty values: they would erase\nintentional empty strings. Hydration slot counts remain unchanged.\n\n## Typed converter output\n\nThe default output remains unchanged. Opt into `typed: true` (or `--typed`)\nfor explicit `ElementViewTemplate<TSource>` / `ElementStyles` annotations and\ntype-only imports, then remove wrapper string replacements. Supply\n`type_source`/`--type-source` when strict source-property checking is required.\nRust `ConvertOptions` struct literals must include the new `typed` field or\nuse `..ConvertOptions::default()`.\nThe pre-1.0 native error enums also gain integration-related variants; update\nexhaustive `RenderError` / `ConvertError` matches accordingly.\n\n## Caller-owned host markup\n\nReplace throwaway-host rendering and substring extraction with\n`render_shadow_root` (WASM) or `render_shadow_root_*_with_locator` (Rust).\nPass resolved component state and insert the returned complete DSD `<template>`\ninto the host you own. The fragment does not include host/default attributes\nor light-DOM children.\n\n## Persisted template metadata\n\n`parse_f_templates` keeps its JSON array shape and existing fields, adding\nper-record `formatVersion: 1` and `bindings`. Preserve these fields when\npersisting or constructing a keyed map. Unsupported/malformed explicit versions\nnow fail before rendering. Unversioned legacy maps remain supported, but cannot\nreceive stale-version protection. Regenerate metadata on format changes rather\nthan rewriting a version number onto incompatible data.\n\nBindings describe names, expression kinds, paths, and repeat scopes. Unknown\ntypes and state optionality are explicitly null, not inferred declarations.\nRepeat collections alone have a known array requirement. Complex/client\nreferences are lexical descriptions; metadata is not a full state schema or\nsyntax-validation certificate. Use application declarations for definitive\ntype/requiredness checks.\n\nEach newly parsed binding now includes an authored `span` with half-open `start`\nand `end` positions in the complete input string. Offsets are zero-based UTF-16;\nlines and UTF-16 columns are one-based. Use the original input, not the returned\ntrimmed `content`, when slicing or attaching diagnostics. The range covers the\ntrimmed expression without braces; repeat bindings locate only the iterable.\nCRLF counts as one line break and two offset units; lone CR and LF each count\nas a line break. Raw attribute entities are not decoded.\n\nFormat version 1 is unchanged, and renderers still accept older records without\nspans. Regenerate persisted metadata to obtain authored locations; preserve spans\nwhen mapping or serializing records. Native `BindingMetadata` struct literals\nmust now supply the public `span: SourceSpan` field; prefer `parse_f_templates`\nto constructing descriptive metadata manually. Generated WASM declarations expose\n`TemplateSourceSpan` and `TemplateSourcePosition`.\n\n<!-- File: packages/fast-element/docs/ACKNOWLEDGEMENTS.md (Tokens: ~423 | Category: anthropic-skill) -->\n# Acknowledgements\n\nThere are many great open source projects that have inspired us and enabled us to build FAST. Below are a few that stand out.\n\n* [.NET](https://dotnet.microsoft.com/) - Many thanks to the .NET team for sharing their policies and practices upon which our issue management and release planning docs and practices were based.\n* [asap](https://github.com/kriskowal/asap) - An awesome, time-tested async task queue implementation that heavily inspired our DOM update system.\n* [Aurelia 1 and Aurelia 2](https://aurelia.io/) - Various details of Aurelia 2's decorator and metadata model inspired us in the design of `fast-element`. Additionally, Aurelia 1's mechanisms for array observation, binding, and template compilation also guided us in our work.\n* [faastjs](https://github.com/faastjs) - A project with a similar name but a very different purpose. Their API documentation approach leveraging [api-extractor](https://api-extractor.com/) was a huge help to us.\n* [Knockout](https://knockoutjs.com/) - One of the first JavaScript libraries (if not the first) to implement an observer system. The original techniques for observables and computed observables have influenced many libraries over the years. Re-interpreting these ideas in terms of modern JavaScript and DOM has helped us to build a powerful and robust system.\n* [lit-html](https://lit-html.polymer-project.org/) - One of the first libraries to leverage standard JavaScript tagged template literals for HTML templates. We were inspired by this technique and wanted to explore whether it could be combined with our idea of arrow function binding expressions.\n* [Polymer](https://www.polymer-project.org/) - One of the first libraries (if not the first) to embrace Web Components.\n* [Vue](https://vuejs.org/) - We liked the terseness of the `:` and `@` syntax in templates, so we adapted it along with some modifications in our templates.\n\n<!-- File: packages/fast-element/docs/api-report.api.md (Tokens: ~9696 | Category: anthropic-skill) -->\n## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport interface AccessCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"access\";\n}\n\n// @public\nexport interface Accessor {\n    getValue(source: any): any;\n    name: string;\n    setValue(source: any, value: any): void;\n}\n\n// @public\nexport type AddViewBehaviorFactory = (factory: ViewBehaviorFactory) => string;\n\n// @public\nexport interface ArrayObserver extends SubscriberSet {\n    addSort(sort: Sort): void;\n    addSplice(splice: Splice): void;\n    flush(): void;\n    readonly lengthObserver: LengthObserver;\n    reset(oldCollection: any[] | undefined): void;\n    readonly sortObserver: SortObserver;\n    strategy: SpliceStrategy | null;\n}\n\n// @public\nexport const ArrayObserver: Readonly<{\n    readonly sorted: 0;\n    readonly enable: () => void;\n}>;\n\n// @public\nexport interface Aspected {\n    aspectType: DOMAspect;\n    dataBinding?: Binding;\n    sourceAspect: string;\n    targetAspect: string;\n}\n\n// @public\nexport function attr(config?: DecoratorAttributeConfiguration): (target: {}, property: string) => void;\n\n// @public\nexport function attr(target: {}, prop: string): void;\n\n// @public\nexport type AttributeConfiguration = {\n    property: string;\n    attribute?: string;\n    mode?: AttributeMode;\n    converter?: ValueConverter;\n};\n\n// @public\nexport const AttributeConfiguration: Readonly<{\n    locate: (target: {}) => AttributeConfiguration[];\n}>;\n\n// @public\nexport class AttributeDefinition implements Accessor {\n    constructor(Owner: Function, name: string, attribute?: string, mode?: AttributeMode, converter?: ValueConverter);\n    readonly attribute: string;\n    // @internal\n    static collect(Owner: Function, ...attributeLists: (ReadonlyArray<string | AttributeConfiguration> | undefined)[]): ReadonlyArray<AttributeDefinition>;\n    readonly converter?: ValueConverter;\n    getValue(source: HTMLElement): any;\n    readonly mode: AttributeMode;\n    readonly name: string;\n    // @internal (undocumented)\n    onAttributeChangedCallback(element: HTMLElement, value: any): void;\n    readonly Owner: Function;\n    setValue(source: HTMLElement, newValue: any): void;\n}\n\n// @public\nexport type AttributeMode = \"reflect\" | \"boolean\" | \"fromView\";\n\n// @public\nexport abstract class Binding<TSource = any, TReturn = any, TParent = any> {\n    constructor(evaluate: Expression<TSource, TReturn, TParent>, policy?: DOMPolicy, isVolatile?: boolean);\n    abstract createObserver(subscriber: Subscriber, directive: BindingDirective): ExpressionObserver<TSource, TReturn, TParent>;\n    evaluate: Expression<TSource, TReturn, TParent>;\n    isVolatile: boolean;\n    options?: any;\n    policy?: DOMPolicy;\n}\n\n// @public\nexport interface BindingDirective {\n    readonly aspectType?: DOMAspect;\n    readonly dataBinding: Binding;\n    readonly targetAspect?: string;\n}\n\n// @public\nexport const booleanConverter: ValueConverter;\n\n// @public\nexport type CachedPath = DefaultCachedPath | RepeatCachedPath | AccessCachedPath | EventCachedPath;\n\n// @public\nexport interface CachedPathCommon {\n    // (undocumented)\n    currentContext: string | null;\n    // (undocumented)\n    parentContext: string | null;\n    // (undocumented)\n    path: string;\n}\n\n// @public\nexport type CachedPathMap = Map<string, Map<string, JSONSchema>>;\n\n// @public\nexport type Callable = typeof Function.prototype.call | {\n    call(): void;\n};\n\n// @public\nexport interface CaptureType<TSource = any, TParent = any> {\n}\n\n// @public\nexport interface ChildListDirectiveOptions<T = any> extends NodeBehaviorOptions<T>, Omit<MutationObserverInit, \"subtree\" | \"childList\"> {\n}\n\n// @public\nexport function children<TSource = any, TParent = any>(propertyOrOptions: (keyof TSource & string) | ChildrenDirectiveOptions<keyof TSource & string>): CaptureType<TSource, TParent>;\n\n// @public\nexport class ChildrenDirective extends NodeObservationDirective<ChildrenDirectiveOptions> {\n    constructor(options: ChildrenDirectiveOptions);\n    disconnect(target: any): void;\n    getNodes(target: Element): Node[];\n    observe(target: any): void;\n}\n\n// @public\nexport type ChildrenDirectiveOptions<T = any> = ChildListDirectiveOptions<T> | SubtreeDirectiveOptions<T>;\n\n// @public\nexport interface ChildrenMap {\n    // (undocumented)\n    attributeName: string;\n    // (undocumented)\n    customElementName: string;\n}\n\n// @public\nexport type Class<T, C = {}> = C & Constructable<T> & {\n    readonly prototype: T;\n};\n\n// @public\nexport type CompilationStrategy = (\nhtml: string | HTMLTemplateElement,\nfactories: Record<string, ViewBehaviorFactory>,\npolicy: DOMPolicy) => HTMLTemplateCompilationResult;\n\n// @public\nexport type CompiledViewBehaviorFactory = Required<ViewBehaviorFactory>;\n\n// @public\nexport const Compiler: {\n    compile<TSource = any, TParent = any>(html: string | HTMLTemplateElement, factories: Record<string, ViewBehaviorFactory>, policy?: DOMPolicy): HTMLTemplateCompilationResult<TSource, TParent>;\n    setDefaultStrategy(strategy: CompilationStrategy): void;\n    aggregate(parts: (string | ViewBehaviorFactory)[], policy?: DOMPolicy): ViewBehaviorFactory;\n};\n\n// @public\nexport type ComposableStyles = string | ElementStyles | CSSStyleSheet;\n\n// @public\nexport function composedContains(reference: HTMLElement, test: HTMLElement): boolean;\n\n// @public\nexport function composedParent<T extends HTMLElement>(element: T): HTMLElement | null;\n\n// @beta\nexport type ComputedBuilder = {\n    on: {\n        setup(callback: ComputedSetupCallback): void;\n    };\n};\n\n// @beta\nexport type ComputedInitializer<T> = (builder: ComputedBuilder) => () => T;\n\n// @beta\nexport type ComputedSetupCallback = () => (() => void) | void;\n\n// @beta\nexport type ComputedState<T> = ReadonlyState<T> & Disposable & {\n    subscribe(subscriber: Subscriber): void;\n    unsubscribe(subscriber: Subscriber): void;\n};\n\n// @beta\nexport function computedState<T>(initialize: ComputedInitializer<T>, name?: string): ComputedState<T>;\n\n// @public\nexport type Constructable<T = {}> = {\n    new (...args: any[]): T;\n};\n\n// @public\nexport type ConstructibleStyleStrategy = {\n    new (styles: (string | CSSStyleSheet)[]): StyleStrategy;\n};\n\n// @public\nexport interface ContentTemplate {\n    create(): ContentView;\n}\n\n// @public\nexport interface ContentView {\n    bind(source: any, context?: ExecutionContext): void;\n    // (undocumented)\n    readonly context: ExecutionContext;\n    insertBefore(node: Node): void;\n    remove(): void;\n    unbind(): void;\n}\n\n// @public\nexport const css: CSSTemplateTag;\n\n// @public\nexport interface CSSDirective {\n    createCSS(): ComposableStyles;\n}\n\n// @public\nexport const CSSDirective: Readonly<{\n    getForInstance: (object: any) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    getByType: (key: Function) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    define<TType extends Constructable<CSSDirective>>(type: any): TType;\n}>;\n\n// @public\nexport function cssDirective(): (type: Constructable<CSSDirective>) => void;\n\n// @public\nexport interface CSSDirectiveDefinition<TType extends Constructable<CSSDirective> = Constructable<CSSDirective>> {\n    readonly type: TType;\n}\n\n// @public\nexport type CSSTemplateTag = ((strings: TemplateStringsArray, ...values: CSSValue[]) => ElementStyles) & {\n    partial(strings: TemplateStringsArray, ...values: CSSValue[]): CSSDirective;\n};\n\n// @public\nexport type CSSValue = ComposableStyles | CSSDirective;\n\n// @public\nexport function customElement(nameOrDef: string | PartialFASTElementDefinition): (type: Constructable<HTMLElement>) => void;\n\n// @public\nexport type DecoratorAttributeConfiguration = Omit<AttributeConfiguration, \"property\">;\n\n// @public\nexport interface DefaultCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"default\";\n}\n\n// @public\nexport class DefaultExecutionContext<TParent> implements ExecutionContext<TParent> {\n    get event(): Event;\n    eventDetail<TDetail>(): TDetail;\n    eventTarget<TTarget extends EventTarget>(): TTarget;\n    index: number;\n    get isEven(): boolean;\n    get isFirst(): boolean;\n    get isInMiddle(): boolean;\n    get isLast(): boolean;\n    get isOdd(): boolean;\n    length: number;\n    readonly parent: TParent;\n    readonly parentContext: ExecutionContext<TParent>;\n}\n\n// @public\nexport interface Disposable {\n    dispose(): void;\n}\n\n// @public\nexport const DOM: Readonly<{\n    readonly policy: DOMPolicy;\n    setPolicy(value: DOMPolicy): void;\n    setAttribute(element: HTMLElement, attributeName: string, value: any): void;\n    setBooleanAttribute(element: HTMLElement, attributeName: string, value: boolean): void;\n}>;\n\n// @public\nexport const DOMAspect: Readonly<{\n    readonly none: 0;\n    readonly attribute: 1;\n    readonly booleanAttribute: 2;\n    readonly property: 3;\n    readonly content: 4;\n    readonly tokenList: 5;\n    readonly event: 6;\n}>;\n\n// @public\nexport type DOMAspect = (typeof DOMAspect)[Exclude<keyof typeof DOMAspect, \"none\">];\n\n// @public\nexport type DOMAspectGuards = {\n    [DOMAspect.attribute]?: DOMSinkGuards;\n    [DOMAspect.booleanAttribute]?: DOMSinkGuards;\n    [DOMAspect.property]?: DOMSinkGuards;\n    [DOMAspect.content]?: DOMSinkGuards;\n    [DOMAspect.tokenList]?: DOMSinkGuards;\n    [DOMAspect.event]?: DOMSinkGuards;\n};\n\n// @public\nexport type DOMElementGuards = Record<string, DOMAspectGuards>;\n\n// @public\nexport type DOMGuards = {\n    elements: DOMElementGuards;\n    aspects: DOMAspectGuards;\n};\n\n// @public\nexport interface DOMPolicy {\n    createHTML(value: string): string;\n    protect(tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink): DOMSink;\n}\n\n// @public\nexport const DOMPolicy: Readonly<{\n    create(options?: DOMPolicyOptions): Readonly<DOMPolicy>;\n}>;\n\n// @public\nexport type DOMPolicyOptions = {\n    trustedType?: TrustedTypesPolicy;\n    guards?: Partial<DOMGuards>;\n};\n\n// @public\nexport type DOMSink = (target: Node, aspectName: string, value: any, ...args: any[]) => void;\n\n// @public\nexport type DOMSinkGuards = Record<string, (tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink) => DOMSink>;\n\n// @public\nexport class ElementController<TElement extends HTMLElement = HTMLElement> implements Notifier, HostController<TElement> {\n    // @internal\n    constructor(element: TElement, definition: FASTElementDefinition);\n    addBehavior(behavior: HostBehavior<TElement>): void;\n    addStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    protected behaviors: Map<HostBehavior<TElement>, number> | null;\n    protected bindObservables(): void;\n    protected captureBoundObservables(): void;\n    connect(): void;\n    protected connectBehaviors(): void;\n    get context(): ExecutionContext;\n    readonly definition: FASTElementDefinition;\n    disconnect(): void;\n    protected disconnectBehaviors(): void;\n    emit(type: string, detail?: any, options?: Omit<CustomEventInit, \"detail\">): void | boolean;\n    static forCustomElement(element: HTMLElement, override?: boolean): ElementController;\n    protected hasExistingShadowRoot: boolean;\n    // @internal\n    static installHydrationHook(hook: (controller: ElementController, template: ElementViewTemplate, element: HTMLElement, host: Node) => boolean): void;\n    get isBound(): boolean;\n    get isConnected(): boolean;\n    readonly isHydrated: Promise<boolean>;\n    readonly isPrerendered: Promise<boolean>;\n    get mainStyles(): ElementStyles | null;\n    set mainStyles(value: ElementStyles | null);\n    protected needsInitialization: boolean;\n    notify(args: any): void;\n    protected observeLateAttributes(): void;\n    onAttributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;\n    onUnbind(behavior: {\n        unbind(controller: ExpressionController<TElement>): any;\n    }): void;\n    removeBehavior(behavior: HostBehavior<TElement>, force?: boolean): void;\n    removeStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    protected renderTemplate(template: ElementViewTemplate | null | undefined): void;\n    static setStrategy(strategy: ElementControllerStrategy): void;\n    get shadowOptions(): ShadowRootOptions | undefined;\n    set shadowOptions(value: ShadowRootOptions | undefined);\n    readonly source: TElement;\n    get sourceLifetime(): SourceLifetime | undefined;\n    protected stage: Stages;\n    get subject(): TElement;\n    subscribe(subscriber: Subscriber, propertyToWatch?: any): void;\n    protected syncLateAttributes(): void;\n    get template(): ElementViewTemplate<TElement> | null;\n    set template(value: ElementViewTemplate<TElement> | null);\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: any): void;\n    readonly view: ElementView<TElement> | null;\n}\n\n// @public\nexport interface ElementControllerStrategy {\n    // (undocumented)\n    new (element: HTMLElement, definition: FASTElementDefinition): ElementController;\n}\n\n// @public\nexport const elements: (selector?: string) => ElementsFilter;\n\n// @public\nexport type ElementsFilter = (value: Node, index?: number, array?: Node[]) => boolean;\n\n// @public\nexport class ElementStyles {\n    constructor(styles: ReadonlyArray<ComposableStyles>);\n    // @internal (undocumented)\n    addStylesTo(target: StyleTarget): void;\n    // @internal (undocumented)\n    isAttachedTo(target: StyleTarget): boolean;\n    static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;\n    // @internal (undocumented)\n    removeStylesFrom(target: StyleTarget): void;\n    static setDefaultStrategy(Strategy: ConstructibleStyleStrategy): void;\n    get strategy(): StyleStrategy;\n    // (undocumented)\n    readonly styles: ReadonlyArray<ComposableStyles>;\n    static readonly supportsAdoptedStyleSheets: boolean;\n    withStrategy(Strategy: ConstructibleStyleStrategy): this;\n}\n\n// @public\nexport interface ElementView<TSource = any, TParent = any> extends View<TSource, TParent> {\n    appendTo(node: Node): void;\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): any;\n    }): void;\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface ElementViewTemplate<TSource = any, TParent = any> {\n    create(hostBindingTarget: Element): ElementView<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): ElementView<TSource, TParent>;\n}\n\n// @public\nexport const emptyArray: readonly never[];\n\n// @public\nexport function enableDebug(): void;\n\n// @public\nexport interface EventCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"event\";\n}\n\n// @public\nexport interface ExecutionContext<TParent = any> {\n    readonly event: Event;\n    eventDetail<TDetail>(): TDetail;\n    eventTarget<TTarget extends EventTarget>(): TTarget;\n    index: number;\n    readonly isEven: boolean;\n    readonly isFirst: boolean;\n    readonly isInMiddle: boolean;\n    readonly isLast: boolean;\n    readonly isOdd: boolean;\n    length: number;\n    parent: TParent;\n    parentContext: ExecutionContext<TParent>;\n}\n\n// @public\nexport const ExecutionContext: Readonly<{\n    default: ExecutionContext;\n    getEvent(): Event | null;\n    setEvent(event: Event | null): void;\n}>;\n\n// @public\nexport type Expression<TSource = any, TReturn = any, TParent = any> = (source: TSource, context: ExecutionContext<TParent>) => TReturn;\n\n// @public\nexport interface ExpressionController<TSource = any, TParent = any> {\n    readonly context: ExecutionContext<TParent>;\n    readonly isBound: boolean;\n    onUnbind(behavior: {\n        unbind(controller: ExpressionController<TSource, TParent>): any;\n    }): void;\n    readonly source: TSource;\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface ExpressionNotifier<TSource = any, TReturn = any, TParent = any> extends Notifier, ExpressionObserver<TSource, TReturn, TParent>, Disposable {\n    observe(source: TSource, context?: ExecutionContext): TReturn;\n    records(): IterableIterator<ObservationRecord>;\n    setMode(isAsync: boolean): void;\n}\n\n// @public\nexport interface ExpressionObserver<TSource = any, TReturn = any, TParent = any> {\n    bind(controller: ExpressionController<TSource, TParent>): TReturn;\n}\n\n// @public\nexport const FAST: {\n    warn(_code: number, _values?: Record<string, any>): void;\n    error(code: number, _values?: Record<string, any>): Error;\n    addMessages(messages: Record<number, string>): void;\n};\n\n// @public\nexport interface FASTElement extends HTMLElement {\n    $emit(type: string, detail?: any, options?: Omit<CustomEventInit, \"detail\">): boolean | void;\n    readonly $fastController: ElementController;\n    attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;\n    connectedCallback(): void;\n    disconnectedCallback(): void;\n}\n\n// @public\nexport const FASTElement: FASTElementConstructor;\n\n// @public\nexport interface FASTElementConstructor {\n    new (): FASTElement;\n    define<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(this: TType, nameOrDef: string | PartialFASTElementDefinition<TType>, extensions?: FASTElementExtension[]): Promise<TType>;\n    define<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition<TType>, extensions?: FASTElementExtension[]): Promise<TType>;\n    from<TBase extends typeof HTMLElement>(BaseType: TBase): {\n        new (): InstanceType<TBase> & FASTElement;\n    };\n}\n\n// @public\nexport class FASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributeLookup: Record<string, AttributeDefinition>;\n    readonly attributes: ReadonlyArray<AttributeDefinition>;\n    static compose<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition<TType>): Promise<FASTElementDefinition<TType>>;\n    define(registry?: CustomElementRegistry, extensions?: FASTElementExtension[]): this;\n    readonly elementOptions: ElementDefinitionOptions;\n    static readonly getByType: (key: Function) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    static readonly getForInstance: (object: any) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    get isDefined(): boolean;\n    readonly name: string;\n    readonly propertyLookup: Record<string, AttributeDefinition>;\n    // @internal\n    static registerBaseType(type: Function): void;\n    readonly registry: CustomElementRegistry;\n    schema?: Schema;\n    shadowOptions?: ShadowRootOptions;\n    readonly styles?: ElementStyles;\n    template?: ElementViewTemplate<InstanceType<TType>>;\n    readonly type: TType;\n}\n\n// @public\nexport type FASTElementExtension = (definition: FASTElementDefinition) => void;\n\n// @public\nexport interface FASTElementRegistry extends TypeRegistry<FASTElementDefinition> {\n    whenRegistered(name: string, registry?: CustomElementRegistry): Promise<FASTElementDefinition>;\n}\n\n// @public\nexport const fastElementRegistry: FASTElementRegistry;\n\n// @public\nexport type FASTElementTemplateResolver<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> = (definition: FASTElementDefinition<TType>) => ElementViewTemplate<InstanceType<TType>> | Promise<ElementViewTemplate<InstanceType<TType>>>;\n\n// @public\nexport interface HostBehavior<TSource = any> {\n    addedCallback?(controller: HostController<TSource>): void;\n    connectedCallback?(controller: HostController<TSource>): void;\n    disconnectedCallback?(controller: HostController<TSource>): void;\n    removedCallback?(controller: HostController<TSource>): void;\n}\n\n// @public\nexport interface HostController<TSource = any> extends ExpressionController<TSource> {\n    addBehavior(behavior: HostBehavior<TSource>): void;\n    addStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    readonly isConnected: boolean;\n    mainStyles: ElementStyles | null;\n    removeBehavior(behavior: HostBehavior<TSource>, force?: boolean): void;\n    removeStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n}\n\n// @public\nexport const html: HTMLTemplateTag;\n\n// @public\nexport class HTMLBindingDirective implements HTMLDirective, ViewBehaviorFactory, ViewBehavior, Aspected, BindingDirective {\n    constructor(dataBinding: Binding);\n    aspectType: DOMAspect;\n    // @internal\n    bind(controller: ViewController): void;\n    createBehavior(): ViewBehavior;\n    createHTML(add: AddViewBehaviorFactory): string;\n    dataBinding: Binding;\n    // @internal\n    handleChange(binding: Expression, observer: ExpressionObserver): void;\n    // @internal\n    handleEvent(event: Event): void;\n    id: string;\n    policy: DOMPolicy;\n    sourceAspect: string;\n    targetAspect: string;\n    targetNodeId: string;\n    targetTagName: string | null;\n    // @internal (undocumented)\n    unbind(controller: ViewController): void;\n}\n\n// @public\nexport interface HTMLDirective {\n    createHTML(add: AddViewBehaviorFactory): string;\n}\n\n// @public\nexport const HTMLDirective: Readonly<{\n    getForInstance: (object: any) => HTMLDirectiveDefinition<Constructable<HTMLDirective>> | undefined;\n    getByType: (key: Function) => HTMLDirectiveDefinition<Constructable<HTMLDirective>> | undefined;\n    define<TType extends Constructable<HTMLDirective>>(type: TType, options?: PartialHTMLDirectiveDefinition): TType;\n    assignAspect(directive: Aspected, value?: string): void;\n}>;\n\n// @public\nexport function htmlDirective(options?: PartialHTMLDirectiveDefinition): (type: Constructable<HTMLDirective>) => void;\n\n// @public\nexport interface HTMLDirectiveDefinition<TType extends Constructable<HTMLDirective> = Constructable<HTMLDirective>> extends Required<PartialHTMLDirectiveDefinition> {\n    readonly type: TType;\n}\n\n// @public\nexport interface HTMLTemplateCompilationResult<TSource = any, TParent = any> {\n    createView(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    // (undocumented)\n    readonly factories: CompiledViewBehaviorFactory[];\n}\n\n// @public\nexport type HTMLTemplateTag = (<TSource = any, TParent = any>(strings: TemplateStringsArray, ...values: TemplateValue<TSource, TParent>[]) => ViewTemplate<TSource, TParent>) & {\n    partial(html: string): InlineTemplateDirective;\n};\n\n// @public\nexport class HTMLView<TSource = any, TParent = any> extends DefaultExecutionContext<TParent> implements ElementView<TSource, TParent>, SyntheticView<TSource, TParent>, ExecutionContext<TParent> {\n    constructor(fragment: DocumentFragment, factories: ReadonlyArray<CompiledViewBehaviorFactory>, targets: ViewBehaviorTargets);\n    appendTo(node: Node): void;\n    bind(source: TSource, context?: ExecutionContext<TParent>): void;\n    context: ExecutionContext<TParent>;\n    dispose(): void;\n    static disposeContiguousBatch(views: SyntheticView[]): void;\n    firstChild: Node;\n    insertBefore(node: Node): void;\n    isBound: boolean;\n    isHydrated: Promise<boolean>;\n    isPrerendered: Promise<boolean>;\n    lastChild: Node;\n    // (undocumented)\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): void;\n    }): void;\n    remove(): void;\n    // @internal\n    _skipAttrUpdates: boolean;\n    source: TSource | null;\n    readonly sourceLifetime: SourceLifetime;\n    // (undocumented)\n    readonly targets: ViewBehaviorTargets;\n    unbind(): void;\n}\n\n// @public\nexport class InlineTemplateDirective implements HTMLDirective {\n    constructor(html: string, factories?: Record<string, ViewBehaviorFactory>);\n    createHTML(add: AddViewBehaviorFactory): string;\n    static readonly empty: InlineTemplateDirective;\n}\n\n// @public\nexport interface JSONSchema extends JSONSchemaCommon {\n    // (undocumented)\n    $defs?: Record<string, JSONSchemaDefinition>;\n    // (undocumented)\n    $id: string;\n    // (undocumented)\n    $schema: string;\n}\n\n// @public\nexport interface JSONSchemaCommon {\n    $observe?: boolean;\n    // (undocumented)\n    $ref?: string;\n    // (undocumented)\n    anyOf?: Array<any>;\n    // (undocumented)\n    items?: any;\n    // (undocumented)\n    properties?: any;\n    // (undocumented)\n    type?: string;\n}\n\n// @public\nexport interface JSONSchemaDefinition extends JSONSchemaCommon {\n    // (undocumented)\n    $fast_context: string;\n    // (undocumented)\n    $fast_parent_contexts: Array<string>;\n}\n\n// @public\nexport interface LengthObserver extends Subscriber {\n    length: number;\n}\n\n// @public\nexport function lengthOf<T>(array: readonly T[]): number;\n\n// @public\nexport function listener<T = any>(expression: Expression<T>, options?: AddEventListenerOptions): Binding<T>;\n\n// @public\nexport const Markup: Readonly<{\n    interpolation: (id: string) => string;\n    attribute: (id: string) => string;\n    comment: (id: string) => string;\n}>;\n\n// @public\nexport interface NodeBehaviorOptions<T = any> {\n    filter?: ElementsFilter;\n    property: T;\n}\n\n// @public\nexport abstract class NodeObservationDirective<T extends NodeBehaviorOptions> extends StatelessAttachedAttributeDirective<T> {\n    bind(controller: ViewController): void;\n    protected computeNodes(target: any): Node[];\n    protected abstract disconnect(target: any): void;\n    protected abstract getNodes(target: any): Node[];\n    protected getSource(target: Node): any;\n    get id(): string;\n    set id(value: string);\n    protected abstract observe(target: any): void;\n    targetNodeId: string;\n    unbind(controller: ViewController): void;\n    protected updateTarget(source: any, value: ReadonlyArray<any>): void;\n}\n\n// @public\nexport function normalizeBinding<TSource = any, TReturn = any, TParent = any>(value: Expression<TSource, TReturn, TParent> | Binding<TSource, TReturn, TParent> | {}): Binding<TSource, TReturn, TParent>;\n\n// @public\nexport interface Notifier {\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber, propertyToWatch?: any): void;\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: any): void;\n}\n\n// @public\nexport const nullableBooleanConverter: ValueConverter;\n\n// @public\nexport const nullableNumberConverter: ValueConverter;\n\n// @public\nexport const Observable: Readonly<{\n    setArrayObserverFactory(factory: (collection: any[]) => Notifier): void;\n    getNotifier: <T extends Notifier = Notifier>(source: any) => T;\n    track(source: unknown, propertyName: string): void;\n    trackVolatile(): void;\n    notify(source: unknown, args: any): void;\n    defineProperty(target: {}, nameOrAccessor: string | Accessor): void;\n    getAccessors: (target: {}) => Accessor[];\n    binding<TSource = any, TReturn = any>(expression: Expression<TSource, TReturn>, initialSubscriber?: Subscriber, isVolatileBinding?: boolean): ExpressionNotifier<TSource, TReturn>;\n    isVolatileBinding<TSource = any, TReturn = any>(expression: Expression<TSource, TReturn>): boolean;\n}>;\n\n// @public\nexport function observable(target: {}, nameOrAccessor: string | Accessor): void;\n\n// @public\nexport interface ObservationRecord {\n    propertyName: string;\n    propertySource: any;\n}\n\n// @public\nexport function oneTime<T = any>(expression: Expression<T>, policy?: DOMPolicy): Binding<T>;\n\n// @public\nexport function oneWay<T = any>(expression: Expression<T>, policy?: DOMPolicy, isVolatile?: boolean): Binding<T>;\n\n// @beta\nexport type OwnedState<T> = ReadonlyOwnedState<T> & {\n    set(owner: any, value: T): void;\n    asReadonly(): ReadonlyOwnedState<T>;\n};\n\n// @beta\nexport function ownedState<T>(value: T | (() => T), options?: string | StateOptions): OwnedState<T>;\n\n// @public\nexport const Parser: Readonly<{\n    parse(value: string, factories: Record<string, ViewBehaviorFactory>): (string | ViewBehaviorFactory)[] | null;\n}>;\n\n// @public\nexport interface PartialFASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributes?: (AttributeConfiguration | string)[];\n    readonly elementOptions?: ElementDefinitionOptions;\n    readonly name: string;\n    readonly registry?: CustomElementRegistry;\n    readonly schema?: Schema;\n    readonly shadowOptions?: Partial<ShadowRootOptions> | null;\n    readonly styles?: ComposableStyles | ComposableStyles[];\n    readonly template?: ElementViewTemplate<InstanceType<TType>> | FASTElementTemplateResolver<TType>;\n}\n\n// @public\nexport interface PartialHTMLDirectiveDefinition {\n    aspected?: boolean;\n}\n\n// @public\nexport class PropertyChangeNotifier implements Notifier {\n    constructor(subject: any);\n    notify(propertyName: string): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber, propertyToWatch?: string): void;\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: string): void;\n}\n\n// @beta\nexport function reactive<T>(object: T, deep?: boolean): T;\n\n// @beta\nexport type ReadonlyOwnedState<T> = {\n    (owner: any): T;\n};\n\n// @beta\nexport type ReadonlyState<T> = {\n    (): T;\n    readonly current: T;\n};\n\n// @public\nexport const ref: <TSource = any, TParent = any>(propertyName: keyof TSource & string) => CaptureType<TSource, TParent>;\n\n// @public\nexport class RefDirective extends StatelessAttachedAttributeDirective<string> {\n    bind(controller: ViewController): void;\n    targetNodeId: string;\n}\n\n// @public\nexport interface RegisterPathConfig {\n    // (undocumented)\n    childrenMap: ChildrenMap | null;\n    // (undocumented)\n    pathConfig: CachedPath;\n    // (undocumented)\n    rootPropertyName: string;\n}\n\n// @public\nexport function render<TSource = any, TItem = any, TParent = any>(value?: Expression<TSource, TItem> | Binding<TSource, TItem> | {}, template?: ContentTemplate | string | Expression<TSource, ContentTemplate | string | Node, TParent> | Binding<TSource, ContentTemplate | string | Node, TParent>): CaptureType<TSource, TParent>;\n\n// @public\nexport class RenderBehavior<TSource = any> implements ViewBehavior, Subscriber {\n    constructor(directive: RenderDirective);\n    bind(controller: ViewController): void;\n    // @internal\n    handleChange(source: any, observer: ExpressionObserver): void;\n    unbind(controller: ViewController): void;\n}\n\n// @public\nexport class RenderDirective<TSource = any> implements HTMLDirective, ViewBehaviorFactory, BindingDirective {\n    constructor(dataBinding: Binding<TSource>, templateBinding: Binding<TSource, ContentTemplate>, templateBindingDependsOnData: boolean);\n    createBehavior(): RenderBehavior<TSource>;\n    createHTML(add: AddViewBehaviorFactory): string;\n    // (undocumented)\n    readonly dataBinding: Binding<TSource>;\n    targetNodeId: string;\n    // (undocumented)\n    readonly templateBinding: Binding<TSource, ContentTemplate>;\n    // (undocumented)\n    readonly templateBindingDependsOnData: boolean;\n}\n\n// @public\nexport function repeat<TSource = any, TArray extends ReadonlyArray<any> = ReadonlyArray<any>, TParent = any>(items: Expression<TSource, TArray, TParent> | Binding<TSource, TArray, TParent> | ReadonlyArray<any>, template: Expression<TSource, ViewTemplate<any, TSource>> | Binding<TSource, ViewTemplate<any, TSource>> | ViewTemplate<any, TSource>, options?: RepeatOptions): CaptureType<TSource, TParent>;\n\n// @public\nexport class RepeatBehavior<TSource = any> implements ViewBehavior, Subscriber {\n    constructor(directive: RepeatDirective);\n    bind(controller: ViewController): void;\n    handleChange(source: any, args: Splice[] | Sort[] | ExpressionObserver): void;\n    unbind(): void;\n    // @internal (undocumented)\n    views: SyntheticView[];\n}\n\n// @public\nexport interface RepeatCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"repeat\";\n}\n\n// @public\nexport class RepeatDirective<TSource = any> implements HTMLDirective, ViewBehaviorFactory, BindingDirective {\n    constructor(dataBinding: Binding<TSource>, templateBinding: Binding<TSource, SyntheticViewTemplate>, options: RepeatOptions);\n    createBehavior(): RepeatBehavior<TSource>;\n    createHTML(add: AddViewBehaviorFactory): string;\n    // (undocumented)\n    readonly dataBinding: Binding<TSource>;\n    // (undocumented)\n    readonly options: RepeatOptions;\n    targetNodeId: string;\n    // (undocumented)\n    readonly templateBinding: Binding<TSource, SyntheticViewTemplate>;\n}\n\n// @public\nexport interface RepeatOptions {\n    positioning?: boolean;\n    recycle?: boolean;\n}\n\n// @public\nexport class Schema {\n    constructor(name: string);\n    addPath(config: RegisterPathConfig): void;\n    getRootProperties(): IterableIterator<string>;\n    getSchema(rootPropertyName: string): JSONSchema | null;\n}\n\n// @public\nexport const schemaRegistry: CachedPathMap;\n\n// @public\nexport interface ShadowRootOptions extends ShadowRootInit {\n    // @beta\n    registry?: CustomElementRegistry;\n}\n\n// @public\nexport const Signal: Readonly<{\n    subscribe(signal: string, subscriber: Subscriber): void;\n    unsubscribe(signal: string, subscriber: Subscriber): void;\n    send(signal: string): void;\n}>;\n\n// @public\nexport function signal<T = any>(expression: Expression<T>, options: string | Expression<T>, policy?: DOMPolicy): Binding<T>;\n\n// @public\nexport function slotted<TSource = any, TParent = any>(propertyOrOptions: (keyof TSource & string) | SlottedDirectiveOptions<keyof TSource & string>): CaptureType<TSource, TParent>;\n\n// @public\nexport class SlottedDirective extends NodeObservationDirective<SlottedDirectiveOptions> {\n    disconnect(target: EventSource): void;\n    getNodes(target: HTMLSlotElement): Node[];\n    // @internal (undocumented)\n    handleEvent(event: Event): void;\n    observe(target: EventSource): void;\n}\n\n// @public\nexport interface SlottedDirectiveOptions<T = any> extends NodeBehaviorOptions<T>, AssignedNodesOptions {\n}\n\n// @public\nexport class Sort {\n    constructor(sorted?: number[] | undefined);\n    // (undocumented)\n    sorted?: number[] | undefined;\n}\n\n// @public\nexport function sortedCount<T>(array: readonly T[]): number;\n\n// @public\nexport interface SortObserver extends Subscriber {\n    sorted: number;\n}\n\n// @public\nexport const SourceLifetime: Readonly<{\n    readonly unknown: undefined;\n    readonly coupled: 1;\n}>;\n\n// @public\nexport type SourceLifetime = (typeof SourceLifetime)[keyof typeof SourceLifetime];\n\n// @public\nexport class Splice {\n    constructor(index: number, removed: any[], addedCount: number);\n    // (undocumented)\n    addedCount: number;\n    adjustTo(array: any[]): this;\n    // (undocumented)\n    index: number;\n    // (undocumented)\n    removed: any[];\n    reset?: boolean;\n}\n\n// @public\nexport interface SpliceStrategy {\n    normalize(previous: unknown[] | undefined, current: unknown[], changes: Splice[] | undefined): readonly Splice[];\n    pop(array: any[], observer: ArrayObserver, pop: typeof Array.prototype.pop, args: any[]): any;\n    push(array: any[], observer: ArrayObserver, push: typeof Array.prototype.push, args: any[]): any;\n    reverse(array: any[], observer: ArrayObserver, reverse: typeof Array.prototype.reverse, args: any[]): any;\n    shift(array: any[], observer: ArrayObserver, shift: typeof Array.prototype.shift, args: any[]): any;\n    sort(array: any[], observer: ArrayObserver, sort: typeof Array.prototype.sort, args: any[]): any[];\n    splice(array: any[], observer: ArrayObserver, splice: typeof Array.prototype.splice, args: any[]): any;\n    readonly support: SpliceStrategySupport;\n    unshift(array: any[], observer: ArrayObserver, unshift: typeof Array.prototype.unshift, args: any[]): any[];\n}\n\n// @public\nexport const SpliceStrategy: Readonly<{\n    readonly reset: Splice[];\n    readonly setDefaultStrategy: (strategy: SpliceStrategy) => void;\n}>;\n\n// @public\nexport const SpliceStrategySupport: Readonly<{\n    readonly reset: 1;\n    readonly splice: 2;\n    readonly optimized: 3;\n}>;\n\n// @public\nexport type SpliceStrategySupport = (typeof SpliceStrategySupport)[keyof typeof SpliceStrategySupport];\n\n// @public\nexport const enum Stages {\n    connected = 1,\n    connecting = 0,\n    disconnected = 3,\n    disconnecting = 2\n}\n\n// @beta\nexport type State<T> = ReadonlyState<T> & {\n    current: T;\n    set(value: T): void;\n    asReadonly(): ReadonlyState<T>;\n};\n\n// @beta\nexport function state<T>(value: T, options?: string | StateOptions): State<T>;\n\n// @public\nexport abstract class StatelessAttachedAttributeDirective<TOptions> implements HTMLDirective, ViewBehaviorFactory, ViewBehavior {\n    constructor(options: TOptions);\n    abstract bind(controller: ViewController): void;\n    createBehavior(): ViewBehavior;\n    createHTML(add: AddViewBehaviorFactory): string;\n    // (undocumented)\n    protected options: TOptions;\n}\n\n// @beta\nexport type StateOptions = {\n    deep?: boolean;\n    name?: string;\n};\n\n// @public\nexport interface StyleStrategy {\n    addStylesTo(target: StyleTarget): void;\n    removeStylesFrom(target: StyleTarget): void;\n}\n\n// @public\nexport interface StyleTarget extends Pick<Node, \"getRootNode\"> {\n    adoptedStyleSheets?: CSSStyleSheet[];\n    append(styles: HTMLStyleElement): void;\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\n    removeChild(styles: HTMLStyleElement): void;\n}\n\n// @public\nexport interface Subscriber {\n    handleChange(subject: any, args: any): void;\n}\n\n// @public\nexport class SubscriberSet implements Notifier {\n    constructor(subject: any, initialSubscriber?: Subscriber);\n    has(subscriber: Subscriber): boolean;\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber): void;\n    unsubscribe(subscriber: Subscriber): void;\n}\n\n// @public\nexport interface SubtreeDirectiveOptions<T = any> extends NodeBehaviorOptions<T>, Omit<MutationObserverInit, \"subtree\" | \"childList\"> {\n    selector: string;\n    subtree: boolean;\n}\n\n// @public\nexport interface SyntheticView<TSource = any, TParent = any> extends View<TSource, TParent> {\n    readonly firstChild: Node;\n    insertBefore(node: Node): void;\n    readonly lastChild: Node;\n    remove(): void;\n}\n\n// @public\nexport interface SyntheticViewTemplate<TSource = any, TParent = any> {\n    create(): SyntheticView<TSource, TParent>;\n    inline(): CaptureType<TSource, TParent>;\n}\n\n// @public\nexport type TemplateValue<TSource, TParent = any> = Expression<TSource, any, TParent> | Binding<TSource, any, TParent> | HTMLDirective | CaptureType<TSource, TParent>;\n\n// @public\nexport type TrustedTypesPolicy = {\n    createHTML(html: string): string;\n};\n\n// @public\nexport function twoWay<T = any>(expression: Expression<T>, optionsOrChangeEvent?: TwoWayBindingOptions | string, policy?: DOMPolicy, isBindingVolatile?: boolean): Binding<T>;\n\n// @public\nexport type TwoWayBindingOptions = {\n    changeEvent?: string;\n    fromView?: (value: any) => any;\n};\n\n// @public\nexport interface TwoWaySettings {\n    determineChangeEvent(bindingSource: BindingDirective, target: HTMLElement): string;\n}\n\n// @public\nexport const TwoWaySettings: Readonly<{\n    configure(settings: TwoWaySettings): void;\n}>;\n\n// @public\nexport interface TypeDefinition {\n    type: Function;\n}\n\n// @public\nexport interface TypeRegistry<TDefinition extends TypeDefinition> {\n    getByType(key: Function): TDefinition | undefined;\n    getForInstance(object: any): TDefinition | undefined;\n    register(definition: TDefinition): boolean;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"UnobservableMutationObserver\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal\nexport class UnobservableMutationObserver extends MutationObserver {\n    constructor(callback: MutationCallback);\n    // (undocumented)\n    observe(target: Node, options?: MutationObserverInit | undefined): void;\n    // (undocumented)\n    unobserve(target: Node): void;\n}\n\n// @public\nexport interface UpdateQueue {\n    enqueue(callable: Callable): void;\n    next(): Promise<void>;\n    process(): void;\n    setMode(isAsync: boolean): void;\n}\n\n// @public\nexport const Updates: UpdateQueue;\n\n// @public\nexport interface ValueConverter {\n    fromView(value: any): any;\n    toView(value: any): any;\n}\n\n// @public\nexport interface View<TSource = any, TParent = any> extends Disposable {\n    bind(source: TSource, context?: ExecutionContext<TParent>): void;\n    readonly context: ExecutionContext<TParent>;\n    readonly isBound: boolean;\n    readonly source: TSource | null;\n    unbind(): void;\n}\n\n// @public\nexport interface ViewBehavior<TSource = any, TParent = any> {\n    bind(controller: ViewController<TSource, TParent>): void;\n}\n\n// @public\nexport interface ViewBehaviorFactory {\n    createBehavior(): ViewBehavior;\n    id?: string;\n    policy?: DOMPolicy;\n    targetNodeId?: string;\n    targetTagName?: string | null;\n}\n\n// @public\nexport interface ViewBehaviorOrchestrator<TSource = any, TParent = any> extends ViewController<TSource, TParent>, HostBehavior<TSource> {\n    addBehavior(behavior: ViewBehavior): void;\n    addBehaviorFactory(factory: ViewBehaviorFactory, target: Node): void;\n    // (undocumented)\n    addTarget(nodeId: string, target: Node): void;\n}\n\n// @public\nexport const ViewBehaviorOrchestrator: Readonly<{\n    create<TSource = any, TParent = any>(source: TSource): ViewBehaviorOrchestrator<TSource, TParent>;\n}>;\n\n// @public\nexport type ViewBehaviorTargets = {\n    [id: string]: Node;\n};\n\n// @public\nexport interface ViewController<TSource = any, TParent = any> extends ExpressionController<TSource, TParent> {\n    readonly isHydrated?: Promise<boolean>;\n    readonly isPrerendered?: Promise<boolean>;\n    // @internal\n    readonly _skipAttrUpdates?: boolean;\n    readonly targets: ViewBehaviorTargets;\n}\n\n// @public\nexport class ViewTemplate<TSource = any, TParent = any> implements ElementViewTemplate<TSource, TParent>, SyntheticViewTemplate<TSource, TParent> {\n    constructor(html: string | HTMLTemplateElement, factories?: Record<string, ViewBehaviorFactory>, policy?: DOMPolicy | undefined);\n    // @internal (undocumented)\n    compile(): HTMLTemplateCompilationResult<TSource, TParent>;\n    create(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    static create<TSource = any, TParent = any>(strings: string[], values: TemplateValue<TSource, TParent>[], policy?: DOMPolicy): ViewTemplate<TSource, TParent>;\n    readonly factories: Record<string, ViewBehaviorFactory>;\n    readonly html: string | HTMLTemplateElement;\n    inline(): CaptureType<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    withPolicy(policy: DOMPolicy): this;\n}\n\n// @public\nexport function volatile(target: {}, name: string | Accessor, descriptor: PropertyDescriptor): PropertyDescriptor;\n\n// @beta\nexport function watch(object: any, subscriber: Subscriber | ((subject: any, args: any) => void)): Disposable;\n\n// @public\nexport function when<TSource = any, TReturn = any, TParent = any>(condition: Expression<TSource, TReturn, TParent> | boolean, templateOrTemplateBinding: SyntheticViewTemplate<TSource, TParent> | Expression<TSource, SyntheticViewTemplate<TSource, TParent>, TParent>, elseTemplateOrTemplateBinding?: SyntheticViewTemplate<TSource, TParent> | Expression<TSource, SyntheticViewTemplate<TSource, TParent>, TParent>): CaptureType<TSource, TParent>;\n\n```\n\n<!-- File: packages/fast-element/docs/architecture/fastelement.md (Tokens: ~1260 | Category: anthropic-skill) -->\n# FASTElement\n\nThe `FASTElement` is our extension of the `HTMLElement`. As such it leverages the lifecycles but also requires additional setup before before the class `constructor` or the `connectedCallback` method is executed which are explained in the [overview](./overview.md). This document explains specifically what `FASTElement` leverages inside the `HTMLElement`s lifecycle hooks.\n\nFor an explanation into `HTMLElement` lifecycle hooks refer to the [MDN documentation](https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#custom_element_lifecycle_callbacks).\n\nBecause `FASTElement` extends `HTMLElement`, it is a browser `Window` runtime\nAPI. It is not intended to execute in workers, server-side JavaScript runtimes,\nor other non-window hosts where custom element lifecycle callbacks and animation\nframe scheduling are unavailable.\n\n## A Custom Element is Detected by the Browser\n\nBecause the `FASTElement` is an extension of the `HTMLElement`, it makes use of the same lifecycle hooks and extends them with `$fastController`. It also initializes using another class `ElementController`, the methods this are called during the custom elements native `constructor`, `connectedCallback`, `disconnectedCallback`, and `attributeChangedCallback` lifecycle hooks.\n\n### 🔄 **Lifecycle**: Initialization\n\n```mermaid\nflowchart TD\n    A[A <code>FASTElement</code> web component is added to the <code>DOM</code>] --> B\n    B[<code>FASTElement</code> initializes the <code>ElementController.forCustomElement</code> passing the Custom Element instance] --> C\n    B --> F[Observables applied to the <code>FASTElement</code> are updated on the FAST global without values]\n    C{Is an <code>ElementController</code> available?}\n    C --> |yes|E\n    C --> |no|D\n    D[Initialize a new <code>ElementController</code> referred to as setting an element controller strategy]\n    D --> F\n    E[<code>ElementController</code> captures the Custom Element instance and the definition and attaches them to the <code>$fastController</code> which is then attached to the instance]\n```\n\n### 🔄 **Lifecycle**: Component is connected\n\n```mermaid\nflowchart TD\n    A[browser <code>HTMLElement</code>'s <code>connectedCallback</code> is called] --> B\n    B[<code>this.$fastController.connect</code> in FASTElement is called] --> C\n    B --> D\n    B --> E\n    B --> F\n    C[bind observables by capturing public own Custom Element properties and setting those values through the matching accessors]\n    D[connect behaviors by call the <code>connectedCallback</code> on all behaviors]\n    E[render template, execute an <code>ElementViewTemplate</code>'s render method]\n    F[add styles either as an appended <code>StyleElement</code> node or an <code>adoptedStylesheet</code> which may include and attach behaviors]\n```\n\n#### Render Template\n\nThe rendering of the template on the `ElementController` is by the `renderTemplate` method which is called during the `ElementController.connect` method which is triggered by `HTMLElement`s `connectedCallback` lifecycle.\n\nThe `renderTemplate` identifies the Custom Element, and the shadow root associated with the Custom Element. This then places a rendering of the template (an `ElementView`) onto the internal `view` of the controller. When creating the `ElementView`/`HTMLView` using the `ViewTemplate.render`, the `Compiler.compile()` method identifies a `DocumentFragment` either by using an existing `<template>` tag, or creating one to wrap the contents of the shadow root. A new `CompilationContext` is created and the `compileAttributes` function is called, this results in the replacement of the placeholder attributes initally set-up during the pre-render step with their values if a value has been assigned. The factories with the associated nodes identified are then passed to the context. The view then binds all behaviors to the source element. The `CompilationContext.createView` is executed with the `DocumentFragment` as the root, and returns an `HTMLView`. This `HTMLView` includes an `appendTo` method to attach the fragment to the host element, which it then does. It should be noted that the compiled HTML is a `string`, which when set on the `DocumentFragment` as `innerHTML`, this allows the browser to dictate the creation of HTML nodes.\n\n### 🔄 **Lifecycle**: Component is disconnected\n\nWhen a component is disconnected, a cleanup step is created to remove associated behaviors.\n\n### 🔄 **Lifecycle**: Attribute has been changed\n\nAttributes have an `AttributeDefinition` which allows for converters, attachment of the `<attributName>Changed` aspect of the `@attr` decorator among other capabilities.\n\n```mermaid\nflowchart TD\n    A[The browser <code>HTMLElement</code>'s <code>attributeChangedCallback</code> is called] --> B\n    B[<code>this.$fastController.onAttributeChangedCallback</code> in <code>FASTElement</code> is called] --> C\n    C[calls the attribute definitions <code>onAttributeChangedCallback</code> method with the updated value] --> D\n    D[An <code>Updates.enqueue</code> is called which places the update in the task queue which is then executed, these are performed async unless otherwise specified]\n```\n\nThese changes are observed and similar to the way `Observables` work, they utilize an `Accessor` pattern which has a `getValue` and `setValue` in which DOM updates are applied.\n\nObservable backing slots such as `_foo` are FAST-owned internal state. The\ncontroller's connection-time observable binding only replays public own\nproperties that shadow prototype accessors; it does not normalize backing slots\ninto public property assignments. This keeps attribute converter output in its\nalready-converted model form while preserving pre-upgrade public property\nassignments and opt-in extension behavior.\n\n<!-- File: packages/fast-element/docs/architecture/html-tagged-template-literal.md (Tokens: ~688 | Category: anthropic-skill) -->\n# `html` tagged template literal\n\nThe `html` export from `@microsoft/fast-element` is used to create the template logic for the custom element.\n\n## Pre-processing the `html` tagged template literal contents\n\nBefore the template can be used it goes through a step to convert it into a `ViewTemplate` which it does via the `ViewTemplate.create()` method. This is then used during the `compose` step, before `FASTElement` is instantiated.\n\nDuring the static `ViewTemplate.create()` method (called by the `html` tag), the following happens for each string:\n- Factories with unique IDs are created for each tag template literal argument (or `TemplateValue`) which matches with the corresponding string\n- A binding is created from the `TemplateValue`\n\nThe `Compiler.compile()` method is called lazily the first time the template is rendered (via `ViewTemplate.compile()`, which is triggered by `ViewTemplate.create()` instance method or `ViewTemplate.render()`).\n\nA resulting string using a `createHTML()` function is produced using the `HTMLDirective`s executed for each factory. The behavior is augmented by the previous string from the `html` tag template which determines the aspect if one exists, these aspects are the `@`, `:`, or other binding aspect attached to attributes.\n\nThe `createHTML()` function utilizes a `Markup` attribute which is assigned to a factory's unique ID. The strings are concatenated and passed to a new `ViewTemplate` with all the factories (empty until one is assigned) that act as a dictionary with the unique IDs as the key to look up each factory once it has been created. The string this creates is injected into a `<template>` as `innerHTML`, which allows the browser to create the nodes and placeholder factory IDs, with the only `DOM` node that is explicitly created being the wrapping `<template>` element.\n\n## Directives\n\nThe `HTMLBindingDirective` applies bindings to items identified as various `TemplateValue`s within the `html` tagged template. The `createHTML` step uses the factory associated with the binding to create strings in the markup using the factory's ID.\n\n```mermaid\nflowchart TD\n    A[A <code>new HTMLBindingDirective</code> is created with a data binding which has a policy, options, <code>createObserver</code>, and an evaluate method assigned to the passed arrow function such as <pre>x => x.foo</pre>]\n    B[<code>oneTime</code> binding passes the corresponding tag template argument, an arrow function]\n    C[<code>oneWay</code> binding passes a copy of the corresponding tag template argument, an arrow function]\n    D[An already specified binding such as a <code>repeat</code> or <code>when</code> directive is passed]\n    A --> B\n    A --> C\n    A --> D\n    E[When a <code>createObserver</code> is called, an <code>Observable.binding</code> is created passing the arrow function to be evaluated and the subscriber to be notified]\n    C --> E\n    F[When a <code>createObserver</code> is called, the instance of the one time binding is returned which includes a bind method returning the arrow function executed against the controller source and context]\n    B --> F\n```\n\n<!-- File: packages/fast-element/docs/architecture/intro.md (Tokens: ~221 | Category: anthropic-skill) -->\n# Introduction\n\nThis document (and the linked documents) explains how the exports and side effects of `@microsoft/fast-element` are used to create custom elements.\n\n`@microsoft/fast-element` is designed to run in a client-side browser `Window`\nruntime. Its element lifecycle, rendering, and update queue assume browser DOM,\nCustom Elements, Shadow DOM, and `requestAnimationFrame` are available. Workers,\nserver-side JavaScript runtimes, and other non-window hosts are not supported\ntargets for the FAST Element client runtime.\n\n## Glossary\n\n- [Overview](./overview.md): How the `@microsoft/fast-element` should be used by a developer and what code is executed during the first render.\n- [`FASTElement`](./fastelement.md): How the `FASTElement` is architected.\n- [`html` tagged template literal](./html-tagged-template-literal.md): How the `html` tagged template literal takes and converts the contents into a `ViewTemplate`.\n- [`Updates` queue](./updates.md): How updates to attributes and observables are processed.\n\n<!-- File: packages/fast-element/docs/architecture/overview.md (Tokens: ~819 | Category: anthropic-skill) -->\n# General FAST usage\n\n`FASTElement` is an extension of `HTMLElement` which makes use of Custom Element APIs native to the browser. It also supplies the following methods:\n\n- The `define` method combines the Custom Element name, template, style, and other options into a `FASTElementDefinition`, then uses the native Custom Element [`define()`](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define) to register the Custom Element with a Custom Element Registry.\n- The `from` method allows the use of Customized Built-in elements, which extend from native elements such as `HTMLButtonElement`.\n\n### Creating a Custom Element from FASTElement\n\nA basic developer flow for defining a custom element looks like this:\n\n```mermaid\nflowchart TD\n    A[Create a <code>FASTElement</code> web component by extending the <code>FASTElement</code> class] --> F\n    F[Prepare the definition with template and styles] --> G[Define the component in the browser with <code>define()</code>]\n```\n\nLet's take a look at the definition step to see what the FAST architecture is doing at this stage.\n\n### Defining a Custom Element\n\nThe subclass `define()` method creates a new `FASTElementDefinition`, which includes all metadata needed for the element (such as templates, attributes, and styles), and registers it with the configured Custom Element Registry. The resulting object can be retrieved via `ElementController.definition`.\n\n## A Custom Element in JavaScript is sent to the Browser\n\nLet's step back from defining the Custom Element and consider what is happening when we import from the `@microsoft/fast-element` package.\n\nThe FAST Element client runtime is expected to run in the browser `Window`.\nCustom element definition, connection, rendering, and update scheduling all rely\non browser APIs such as the Custom Element Registry, DOM, Shadow DOM, and\n`requestAnimationFrame`.\n\nFirst, a global `FAST` property will be created if one does not already exist, typically in browser on the `window`.\n\nAdditionally, when Custom Elements are included in a script a few things might happen even before a Custom Element gets detected by the browser. First, there are initial side effects caused by the use of decorators. These include the `attr` decorator from `@microsoft/fast-element` and the `observable` decorator from `@microsoft/fast-element`.\n\nHere is a basic flow of what code is executed and when during initial load of a script that contains a FAST defined Custom Element:\n\n```mermaid\nflowchart TD\n    A@{ shape: circle, label: \"The browser loads the JavaScript file containing FAST and FAST Custom Element definitions\" }\n    B@{ shape: rect, label: \"The FAST global is added to the window\" }\n    A --> B\n    C@{ shape: rect, label: \"A Custom Element executes the <code>compose</code> step\"}\n    B --> C\n    D@{ shape: procs, label: \"<ul style='text-align: left'><li>Any defined observable decorators are added to the FAST global</li><li>An attribute decorator locates the associated Custom Elements constructor which it uses to push itself to the Custom Elements attribute collection</li></ul>\"}\n    C --> D\n    F@{ shape: rect, label: \"An HTML tagged template literal is executed for the FAST Custom Element and applied to the definition\" }\n    D --> F\n    G@{ shape: rect, label: \"The <code>define</code> step is hit and the <code>customElement</code> is registered with the Custom Element Registry\" }\n    F --> G\n    H@{ shape: rect, label: \"A Custom Element is detected on the page and the browser initializes it\" }\n    I@{ shape: dbl-circ, label: \"The lifecycle steps for <code>FASTElement</code> are executed\" }\n    G --> H\n    H --> I\n```\n\n<!-- File: packages/fast-element/docs/architecture/updates.md (Tokens: ~242 | Category: anthropic-skill) -->\n# `Updates`\n\nThe `Updates` API batches FAST Element DOM work in the client-side browser\n`Window` runtime. Queued work includes updates to attributes, observables, and\nobserved arrays. The async queue is aligned to `requestAnimationFrame`, which is\nexpected to be available in the supported runtime.\n\nFAST Element is not intended to run its client runtime in workers, server-side\nJavaScript runtimes, or other non-window hosts. Code that needs server rendering\nshould generate HTML for the browser, then let the browser window run FAST\nElement, connect custom elements, and process queued updates.\n\n## Attributes\n\nAn attribute change may be queued when the value of the attribute is updated. This change is triggered by `HTMLElement` lifecycle hook `attributeChangedCallback`. The `Updates` queue is used to try to reflect the attribute with the updated value onto the element using `DOM` APIs.\n\n## Observables\n\nThe `Reflect` API is used to override `defineProperty` in order to observe a property on an Custom Element, this overrides the getter and setter, which allows subscribers to be notified of changes. Any changes which `set` the value are passed to the `Updates` queue.\n\n<!-- File: packages/fast-element/docs/arrays/api-report.api.md (Tokens: ~785 | Category: anthropic-skill) -->\n## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport interface ArrayObserver extends SubscriberSet {\n    addSort(sort: Sort): void;\n    addSplice(splice: Splice): void;\n    flush(): void;\n    readonly lengthObserver: LengthObserver;\n    reset(oldCollection: any[] | undefined): void;\n    readonly sortObserver: SortObserver;\n    strategy: SpliceStrategy | null;\n}\n\n// @public\nexport const ArrayObserver: Readonly<{\n    readonly sorted: 0;\n    readonly enable: () => void;\n}>;\n\n// @public\nexport interface LengthObserver extends Subscriber {\n    length: number;\n}\n\n// @public\nexport function lengthOf<T>(array: readonly T[]): number;\n\n// @public\nexport interface Notifier {\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber, propertyToWatch?: any): void;\n    unsubscribe(subscriber: Subscriber, propertyToUnwatch?: any): void;\n}\n\n// @public\nexport class Sort {\n    constructor(sorted?: number[] | undefined);\n    // (undocumented)\n    sorted?: number[] | undefined;\n}\n\n// @public\nexport function sortedCount<T>(array: readonly T[]): number;\n\n// @public\nexport interface SortObserver extends Subscriber {\n    sorted: number;\n}\n\n// @public\nexport class Splice {\n    constructor(index: number, removed: any[], addedCount: number);\n    // (undocumented)\n    addedCount: number;\n    adjustTo(array: any[]): this;\n    // (undocumented)\n    index: number;\n    // (undocumented)\n    removed: any[];\n    reset?: boolean;\n}\n\n// @public\nexport interface SpliceStrategy {\n    normalize(previous: unknown[] | undefined, current: unknown[], changes: Splice[] | undefined): readonly Splice[];\n    pop(array: any[], observer: ArrayObserver, pop: typeof Array.prototype.pop, args: any[]): any;\n    push(array: any[], observer: ArrayObserver, push: typeof Array.prototype.push, args: any[]): any;\n    reverse(array: any[], observer: ArrayObserver, reverse: typeof Array.prototype.reverse, args: any[]): any;\n    shift(array: any[], observer: ArrayObserver, shift: typeof Array.prototype.shift, args: any[]): any;\n    sort(array: any[], observer: ArrayObserver, sort: typeof Array.prototype.sort, args: any[]): any[];\n    splice(array: any[], observer: ArrayObserver, splice: typeof Array.prototype.splice, args: any[]): any;\n    readonly support: SpliceStrategySupport;\n    unshift(array: any[], observer: ArrayObserver, unshift: typeof Array.prototype.unshift, args: any[]): any[];\n}\n\n// @public\nexport const SpliceStrategy: Readonly<{\n    readonly reset: Splice[];\n    readonly setDefaultStrategy: (strategy: SpliceStrategy) => void;\n}>;\n\n// @public\nexport const SpliceStrategySupport: Readonly<{\n    readonly reset: 1;\n    readonly splice: 2;\n    readonly optimized: 3;\n}>;\n\n// @public\nexport type SpliceStrategySupport = (typeof SpliceStrategySupport)[keyof typeof SpliceStrategySupport];\n\n// @public\nexport interface Subscriber {\n    handleChange(subject: any, args: any): void;\n}\n\n// @public\nexport class SubscriberSet implements Notifier {\n    constructor(subject: any, initialSubscriber?: Subscriber);\n    has(subscriber: Subscriber): boolean;\n    notify(args: any): void;\n    readonly subject: any;\n    subscribe(subscriber: Subscriber): void;\n    unsubscribe(subscriber: Subscriber): void;\n}\n\n// (No @packageDocumentation comment for this package)\n\n```\n\n<!-- File: packages/fast-element/docs/context/api-report.api.md (Tokens: ~682 | Category: anthropic-skill) -->\n## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport type Context<T> = {\n    readonly name: string;\n    readonly initialValue?: T;\n};\n\n// @public\nexport const Context: Readonly<{\n    eventType: \"context-request\";\n    for<T = unknown>(name: string): FASTContext<T>;\n    create<T = unknown>(name: string, initialValue?: T): FASTContext<T>;\n    setDefaultRequestStrategy(strategy: FASTContextRequestStrategy): void;\n    get<T extends UnknownContext>(target: EventTarget, context: T): ContextType<T>;\n    request<T extends UnknownContext>(target: EventTarget, context: T, callback: ContextCallback<ContextType<T>>, multiple?: boolean): void;\n    dispatch<T extends UnknownContext>(target: EventTarget, context: T, callback: ContextCallback<ContextType<T>>, multiple?: boolean): void;\n    provide<T extends UnknownContext>(target: EventTarget, context: T, value: ContextType<T>): void;\n    handle<T extends UnknownContext>(target: EventTarget, callback: (event: ContextEvent<T>) => void, context?: T): void;\n    defineProperty<T extends UnknownContext>(target: Constructable<EventTarget> | EventTarget, propertyName: string, context: T): void;\n}>;\n\n// @public\nexport type ContextCallback<ValueType> = (value: ValueType, dispose?: () => void) => void;\n\n// Warning: (ae-forgotten-export) The symbol \"ParameterDecorator_2\" needs to be exported by the entry point context.d.ts\n//\n// @public\nexport type ContextDecorator<T = any> = Readonly<Context<T>> & PropertyDecorator & ParameterDecorator_2;\n\n// @public\nexport class ContextEvent<T extends UnknownContext> extends Event {\n    constructor(context: T, callback: ContextCallback<ContextType<T>>, multiple?: boolean | undefined);\n    // (undocumented)\n    readonly callback: ContextCallback<ContextType<T>>;\n    // (undocumented)\n    readonly context: T;\n    // (undocumented)\n    readonly multiple?: boolean | undefined;\n}\n\n// @public\nexport type ContextType<T extends UnknownContext> = T extends Context<infer Y> ? Y : never;\n\n// @public\nexport type FASTContext<T> = ContextDecorator<T> & {\n    get(target: EventTarget): T;\n    provide(target: EventTarget, value: T): void;\n    request(target: EventTarget, callback: ContextCallback<T>, multiple?: boolean): void;\n    handle(target: EventTarget, callback: (event: ContextEvent<FASTContext<T>>) => void): void;\n};\n\n// @public\nexport type FASTContextRequestStrategy = <T extends UnknownContext>(target: EventTarget, context: T, callback: ContextCallback<ContextType<T>>, multiple: any) => void;\n\n// @public\nexport type UnknownContext = Context<unknown>;\n\n// Warnings were encountered during analysis:\n//\n// dist/dts/context.d.ts:127:5 - (ae-forgotten-export) The symbol \"Constructable\" needs to be exported by the entry point context.d.ts\n\n// (No @packageDocumentation comment for this package)\n\n```\n\n<!-- File: packages/fast-element/docs/declarative/api-report.api.md (Tokens: ~3338 | Category: anthropic-skill) -->\n## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport interface AccessCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"access\";\n}\n\n// @public\nexport interface Accessor {\n    getValue(source: any): any;\n    name: string;\n    setValue(source: any, value: any): void;\n}\n\n// @public\nexport type AttributeConfiguration = {\n    property: string;\n    attribute?: string;\n    mode?: AttributeMode;\n    converter?: ValueConverter;\n};\n\n// @public\nexport const AttributeConfiguration: Readonly<{\n    locate: (target: {}) => AttributeConfiguration[];\n}>;\n\n// @public\nexport class AttributeDefinition implements Accessor {\n    constructor(Owner: Function, name: string, attribute?: string, mode?: AttributeMode, converter?: ValueConverter);\n    readonly attribute: string;\n    // @internal\n    static collect(Owner: Function, ...attributeLists: (ReadonlyArray<string | AttributeConfiguration> | undefined)[]): ReadonlyArray<AttributeDefinition>;\n    readonly converter?: ValueConverter;\n    getValue(source: HTMLElement): any;\n    readonly mode: AttributeMode;\n    readonly name: string;\n    // @internal (undocumented)\n    onAttributeChangedCallback(element: HTMLElement, value: any): void;\n    readonly Owner: Function;\n    setValue(source: HTMLElement, newValue: any): void;\n}\n\n// @public\nexport type AttributeMode = \"reflect\" | \"boolean\" | \"fromView\";\n\n// @public\nexport type CachedPath = DefaultCachedPath | RepeatCachedPath | AccessCachedPath | EventCachedPath;\n\n// @public\nexport interface CachedPathCommon {\n    // (undocumented)\n    currentContext: string | null;\n    // (undocumented)\n    parentContext: string | null;\n    // (undocumented)\n    path: string;\n}\n\n// @public\nexport type CachedPathMap = Map<string, Map<string, JSONSchema>>;\n\n// @public\nexport interface CaptureType<TSource = any, TParent = any> {\n}\n\n// @public\nexport interface ChildrenMap {\n    // (undocumented)\n    attributeName: string;\n    // (undocumented)\n    customElementName: string;\n}\n\n// @public\nexport type ComposableStyles = string | ElementStyles | CSSStyleSheet;\n\n// @public\nexport type Constructable<T = {}> = {\n    new (...args: any[]): T;\n};\n\n// @public\nexport type ConstructibleStyleStrategy = {\n    new (styles: (string | CSSStyleSheet)[]): StyleStrategy;\n};\n\n// @public\nexport function declarativeTemplate<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(): FASTElementTemplateResolver<TType>;\n\n// @public\nexport interface DefaultCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"default\";\n}\n\n// @public\nexport const DOMAspect: Readonly<{\n    readonly none: 0;\n    readonly attribute: 1;\n    readonly booleanAttribute: 2;\n    readonly property: 3;\n    readonly content: 4;\n    readonly tokenList: 5;\n    readonly event: 6;\n}>;\n\n// @public\nexport type DOMAspect = (typeof DOMAspect)[Exclude<keyof typeof DOMAspect, \"none\">];\n\n// @public\nexport type DOMAspectGuards = {\n    [DOMAspect.attribute]?: DOMSinkGuards;\n    [DOMAspect.booleanAttribute]?: DOMSinkGuards;\n    [DOMAspect.property]?: DOMSinkGuards;\n    [DOMAspect.content]?: DOMSinkGuards;\n    [DOMAspect.tokenList]?: DOMSinkGuards;\n    [DOMAspect.event]?: DOMSinkGuards;\n};\n\n// @public\nexport type DOMElementGuards = Record<string, DOMAspectGuards>;\n\n// @public\nexport type DOMGuards = {\n    elements: DOMElementGuards;\n    aspects: DOMAspectGuards;\n};\n\n// @public\nexport interface DOMPolicy {\n    createHTML(value: string): string;\n    protect(tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink): DOMSink;\n}\n\n// @public\nexport const DOMPolicy: Readonly<{\n    create(options?: DOMPolicyOptions): Readonly<DOMPolicy>;\n}>;\n\n// @public\nexport type DOMPolicyOptions = {\n    trustedType?: TrustedTypesPolicy;\n    guards?: Partial<DOMGuards>;\n};\n\n// @public\nexport type DOMSink = (target: Node, aspectName: string, value: any, ...args: any[]) => void;\n\n// @public\nexport type DOMSinkGuards = Record<string, (tagName: string | null, aspect: DOMAspect, aspectName: string, sink: DOMSink) => DOMSink>;\n\n// @public\nexport class ElementStyles {\n    constructor(styles: ReadonlyArray<ComposableStyles>);\n    // @internal (undocumented)\n    addStylesTo(target: StyleTarget): void;\n    // @internal (undocumented)\n    isAttachedTo(target: StyleTarget): boolean;\n    static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;\n    // @internal (undocumented)\n    removeStylesFrom(target: StyleTarget): void;\n    static setDefaultStrategy(Strategy: ConstructibleStyleStrategy): void;\n    get strategy(): StyleStrategy;\n    // (undocumented)\n    readonly styles: ReadonlyArray<ComposableStyles>;\n    static readonly supportsAdoptedStyleSheets: boolean;\n    withStrategy(Strategy: ConstructibleStyleStrategy): this;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"View\" needs to be exported by the entry point index.d.ts\n//\n// @public\nexport interface ElementView<TSource = any, TParent = any> extends View<TSource, TParent> {\n    appendTo(node: Node): void;\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): any;\n    }): void;\n    // Warning: (ae-forgotten-export) The symbol \"SourceLifetime\" needs to be exported by the entry point index.d.ts\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface ElementViewTemplate<TSource = any, TParent = any> {\n    create(hostBindingTarget: Element): ElementView<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): ElementView<TSource, TParent>;\n}\n\n// @public\nexport interface EventCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"event\";\n}\n\n// @public\nexport class FASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributeLookup: Record<string, AttributeDefinition>;\n    readonly attributes: ReadonlyArray<AttributeDefinition>;\n    static compose<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>>(type: TType, nameOrDef?: string | PartialFASTElementDefinition<TType>): Promise<FASTElementDefinition<TType>>;\n    define(registry?: CustomElementRegistry, extensions?: FASTElementExtension[]): this;\n    readonly elementOptions: ElementDefinitionOptions;\n    static readonly getByType: (key: Function) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    static readonly getForInstance: (object: any) => FASTElementDefinition<Constructable<HTMLElement>> | undefined;\n    get isDefined(): boolean;\n    readonly name: string;\n    readonly propertyLookup: Record<string, AttributeDefinition>;\n    // @internal\n    static registerBaseType(type: Function): void;\n    readonly registry: CustomElementRegistry;\n    schema?: Schema;\n    shadowOptions?: ShadowRootOptions;\n    readonly styles?: ElementStyles;\n    template?: ElementViewTemplate<InstanceType<TType>>;\n    readonly type: TType;\n}\n\n// @public\nexport type FASTElementExtension = (definition: FASTElementDefinition) => void;\n\n// @public\nexport type FASTElementTemplateResolver<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> = (definition: FASTElementDefinition<TType>) => ElementViewTemplate<InstanceType<TType>> | Promise<ElementViewTemplate<InstanceType<TType>>>;\n\n// @public\nexport interface HTMLTemplateCompilationResult<TSource = any, TParent = any> {\n    createView(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    // Warning: (ae-forgotten-export) The symbol \"CompiledViewBehaviorFactory\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    readonly factories: CompiledViewBehaviorFactory[];\n}\n\n// Warning: (ae-forgotten-export) The symbol \"DefaultExecutionContext\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"SyntheticView\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"ExecutionContext\" needs to be exported by the entry point index.d.ts\n//\n// @public\nexport class HTMLView<TSource = any, TParent = any> extends DefaultExecutionContext<TParent> implements ElementView<TSource, TParent>, SyntheticView<TSource, TParent>, ExecutionContext<TParent> {\n    constructor(fragment: DocumentFragment, factories: ReadonlyArray<CompiledViewBehaviorFactory>, targets: ViewBehaviorTargets);\n    appendTo(node: Node): void;\n    bind(source: TSource, context?: ExecutionContext<TParent>): void;\n    context: ExecutionContext<TParent>;\n    dispose(): void;\n    static disposeContiguousBatch(views: SyntheticView[]): void;\n    firstChild: Node;\n    insertBefore(node: Node): void;\n    isBound: boolean;\n    isHydrated: Promise<boolean>;\n    isPrerendered: Promise<boolean>;\n    lastChild: Node;\n    // (undocumented)\n    onUnbind(behavior: {\n        unbind(controller: ViewController<TSource, TParent>): void;\n    }): void;\n    remove(): void;\n    // @internal\n    _skipAttrUpdates: boolean;\n    source: TSource | null;\n    readonly sourceLifetime: SourceLifetime;\n    // Warning: (ae-forgotten-export) The symbol \"ViewBehaviorTargets\" needs to be exported by the entry point index.d.ts\n    //\n    // (undocumented)\n    readonly targets: ViewBehaviorTargets;\n    unbind(): void;\n}\n\n// @public\nexport interface JSONSchema extends JSONSchemaCommon {\n    // (undocumented)\n    $defs?: Record<string, JSONSchemaDefinition>;\n    // (undocumented)\n    $id: string;\n    // (undocumented)\n    $schema: string;\n}\n\n// @public\nexport interface JSONSchemaCommon {\n    $observe?: boolean;\n    // (undocumented)\n    $ref?: string;\n    // (undocumented)\n    anyOf?: Array<any>;\n    // (undocumented)\n    items?: any;\n    // (undocumented)\n    properties?: any;\n    // (undocumented)\n    type?: string;\n}\n\n// @public\nexport interface JSONSchemaDefinition extends JSONSchemaCommon {\n    // (undocumented)\n    $fast_context: string;\n    // (undocumented)\n    $fast_parent_contexts: Array<string>;\n}\n\n// @public\nexport interface PartialFASTElementDefinition<TType extends Constructable<HTMLElement> = Constructable<HTMLElement>> {\n    readonly attributes?: (AttributeConfiguration | string)[];\n    readonly elementOptions?: ElementDefinitionOptions;\n    readonly name: string;\n    readonly registry?: CustomElementRegistry;\n    readonly schema?: Schema;\n    readonly shadowOptions?: Partial<ShadowRootOptions> | null;\n    readonly styles?: ComposableStyles | ComposableStyles[];\n    readonly template?: ElementViewTemplate<InstanceType<TType>> | FASTElementTemplateResolver<TType>;\n}\n\n// @public\nexport interface RegisterPathConfig {\n    // (undocumented)\n    childrenMap: ChildrenMap | null;\n    // (undocumented)\n    pathConfig: CachedPath;\n    // (undocumented)\n    rootPropertyName: string;\n}\n\n// @public\nexport interface RepeatCachedPath extends CachedPathCommon {\n    // (undocumented)\n    type: \"repeat\";\n}\n\n// @public\nexport interface ResolvedStringsAndValues {\n    // (undocumented)\n    strings: Array<string>;\n    // (undocumented)\n    values: Array<any>;\n}\n\n// @public\nexport class Schema {\n    constructor(name: string);\n    addPath(config: RegisterPathConfig): void;\n    getRootProperties(): IterableIterator<string>;\n    getSchema(rootPropertyName: string): JSONSchema | null;\n}\n\n// @public\nexport const schemaRegistry: CachedPathMap;\n\n// @public\nexport interface ShadowRootOptions extends ShadowRootInit {\n    // @beta\n    registry?: CustomElementRegistry;\n}\n\n// @public\nexport interface StyleStrategy {\n    addStylesTo(target: StyleTarget): void;\n    removeStylesFrom(target: StyleTarget): void;\n}\n\n// @public\nexport interface StyleTarget extends Pick<Node, \"getRootNode\"> {\n    adoptedStyleSheets?: CSSStyleSheet[];\n    append(styles: HTMLStyleElement): void;\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\n    removeChild(styles: HTMLStyleElement): void;\n}\n\n// @public\nexport interface SyntheticViewTemplate<TSource = any, TParent = any> {\n    create(): SyntheticView<TSource, TParent>;\n    inline(): CaptureType<TSource, TParent>;\n}\n\n// @public\nexport class TemplateParser {\n    createTemplate(strings: Array<string>, values: Array<any>): ViewTemplate<any, any>;\n    parse(innerHTML: string, schema: Schema): ResolvedStringsAndValues;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"Expression\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"Binding\" needs to be exported by the entry point index.d.ts\n// Warning: (ae-forgotten-export) The symbol \"HTMLDirective\" needs to be exported by the entry point index.d.ts\n//\n// @public\nexport type TemplateValue<TSource, TParent = any> = Expression<TSource, any, TParent> | Binding<TSource, any, TParent> | HTMLDirective | CaptureType<TSource, TParent>;\n\n// @public\nexport type TrustedTypesPolicy = {\n    createHTML(html: string): string;\n};\n\n// @public\nexport interface ValueConverter {\n    fromView(value: any): any;\n    toView(value: any): any;\n}\n\n// @public\nexport interface ViewBehavior<TSource = any, TParent = any> {\n    bind(controller: ViewController<TSource, TParent>): void;\n}\n\n// @public\nexport interface ViewBehaviorFactory {\n    createBehavior(): ViewBehavior;\n    id?: string;\n    policy?: DOMPolicy;\n    targetNodeId?: string;\n    targetTagName?: string | null;\n}\n\n// @public\nexport class ViewTemplate<TSource = any, TParent = any> implements ElementViewTemplate<TSource, TParent>, SyntheticViewTemplate<TSource, TParent> {\n    constructor(html: string | HTMLTemplateElement, factories?: Record<string, ViewBehaviorFactory>, policy?: DOMPolicy | undefined);\n    // @internal (undocumented)\n    compile(): HTMLTemplateCompilationResult<TSource, TParent>;\n    create(hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    static create<TSource = any, TParent = any>(strings: string[], values: TemplateValue<TSource, TParent>[], policy?: DOMPolicy): ViewTemplate<TSource, TParent>;\n    readonly factories: Record<string, ViewBehaviorFactory>;\n    readonly html: string | HTMLTemplateElement;\n    inline(): CaptureType<TSource, TParent>;\n    render(source: TSource, host: Node, hostBindingTarget?: Element): HTMLView<TSource, TParent>;\n    withPolicy(policy: DOMPolicy): this;\n}\n\n// Warnings were encountered during analysis:\n//\n// dist/dts/templating/view.d.ts:45:9 - (ae-forgotten-export) The symbol \"ViewController\" needs to be exported by the entry point index.d.ts\n\n// (No @packageDocumentation comment for this package)\n\n```\n\n<!-- File: packages/fast-element/docs/declarative/design.md (Tokens: ~9594 | Category: anthropic-skill) -->\n# Declarative HTML Design\n\nThis document is intended for contributors who want to understand the internal\narchitecture of the declarative runtime and schema-driven map extensions in\n`@microsoft/fast-element`. It covers the feature's purpose, core concepts, data\nflow, and its integration with the rest of `@microsoft/fast-element`.\n\n## Table of Contents\n\n1. [Overview](#overview)\n2. [Goals](#goals)\n3. [Core Concepts](#core-concepts)\n4. [Package Structure](#package-structure)\n5. [Exports and Public API](#exports-and-public-api)\n6. [Template Syntax](#template-syntax)\n7. [Data Flow](#data-flow)\n8. [Template Parsing Pipeline](#template-parsing-pipeline)\n9. [Schema and Observer Map](#schema-and-observer-map)\n10. [Lifecycle](#lifecycle)\n11. [Integration with fast-element](#integration-with-fast-element)\n12. [Hydration Model](#hydration-model)\n13. [Testing Architecture](#testing-architecture)\n14. [Further Reading](#further-reading)\n\n---\n\n## Overview\n\n`@microsoft/fast-element` lets you write FAST Web Component\ntemplates as plain HTML rather than JavaScript `html` tagged template literals.\nThe browser-side JS bundle defines FAST's internal native `<f-template>`\npublisher on demand. It parses declarative template markup at runtime and\nreturns a `ViewTemplate` to the waiting FAST element definition through the\nregistry-aware declarative template bridge.\n\n```html\n<!-- Declarative template — stack-agnostic, no JS needed to render -->\n<my-component greeting=\"Hello\">\n    <template shadowrootmode=\"open\">\n        <!--fe:b-->Hello<!--fe:/b-->\n    </template>\n</my-component>\n\n<!-- Template definition — parsed once by the browser bundle -->\n<f-template name=\"my-component\">\n    <template>{{greeting}}</template>\n</f-template>\n```\n\n---\n\n## Goals\n\n| Goal | Description |\n|---|---|\n| **Server-agnostic rendering** | Templates are plain HTML strings with no dependency on Node.js or any specific SSR framework. |\n| **Progressive enhancement** | Components can be server-rendered and then hydrated client-side without a full re-render. |\n| **FAST parity** | The declarative syntax maps 1-to-1 to FAST Element directive helpers (`repeat`, `when`, `slotted`, `children`, `ref`) exported from `@microsoft/fast-element`. |\n| **Minimal authoring overhead** | Component authors write HTML, not tagged template strings, while retaining full reactive capabilities. |\n\n---\n\n## Core Concepts\n\n### `<f-template>` — the internal template publisher\n\n`<f-template>` is an internal custom element implemented as a lightweight native\n`HTMLElement`. It is defined automatically by `declarativeTemplate()` in the same\n`CustomElementRegistry` as the FAST element definition. Consumers should not\nimport, subclass, or define the implementation directly.\n\nWhen connected to the DOM it:\n\n1. Registers itself with the declarative template bridge using its registry and\n   `name` attribute.\n2. Publishes a template when a matching FAST element definition requests one.\n3. Delegates parsing of the inner `<template>` tag to `TemplateParser`, which\n   converts declarative bindings into FAST `ViewTemplate` strings and values.\n4. Runs definition-scoped schema transforms, such as `attributeMap()` and\n   `observerMap()`, before returning the concrete `ViewTemplate`.\n\nWhen multiple connected `<f-template>` publishers share the same `name`, the\nbridge resolves pending definitions from the first connected publisher and keeps\nthe resolved template stable. Later duplicate publishers do not reassign the\ndefinition template.\n\n### `TemplateParser` — declarative HTML parser\n\nA standalone class that converts declarative HTML template markup into the\n`strings` and `values` arrays that `ViewTemplate.create()` consumes. It is used\nby the internal `<f-template>` publisher but can also be used independently for\nprogrammatic template compilation. The parsing pipeline is fully synchronous —\nno promises are allocated during template resolution. A `StringsAccumulator`\ntracks the running concatenation of preceding HTML, eliminating repeated O(N)\n`join(\"\")` calls at each binding site. `createTemplate()` lazily installs the\ndeclarative runtime's debug messages; hydration support is installed only by\n`enableHydration()`.\n\n### `Schema` — JSON schema builder\n\nBuilt during declarative template parsing, one `Schema` instance per\n`<f-template>`. Non-declarative callers can also create and attach a `Schema`\nmanually. It records every binding path discovered in the template or supplied\nby code and constructs a JSON Schema-compatible data structure. This schema:\n\n- Describes the shape of each root property referenced in the template.\n- Tracks repeat context chains (parent/child array relationships).\n- Uses an instance-level `schemaMap` for its own property schemas.\n- Registers itself in the module-level `schemaRegistry` (keyed by custom element name) for cross-element `$ref` resolution.\n\n`FASTElementDefinition.schema` is optional. `declarativeTemplate()` assigns it\nautomatically after parsing; manual schema users can pass `schema` in the\ndefinition object.\n\n### `ObserverMap` — automatic observable setup\n\nAn optional layer that uses the `Schema` to automatically:\n\n- Call `Observable.defineProperty()` for every root property on the element prototype.\n- Install property-change handlers that wrap newly assigned objects/arrays in `Proxy` instances.\n- Propagate deep property mutations back through FAST's observable system so bindings re-render.\n\nEnabled via the `observerMap()` definition extension exported from\n`@microsoft/fast-element/observer-map.js`. Calling `observerMap()` without\narguments observes all root properties discovered in the template or supplied\nschema.\n\n#### Path-level observation control\n\nThe `ObserverMapConfig` interface accepts an optional `schema` for\nnon-declarative/manual schema use and an optional `properties` key that maps\nroot property names to a recursive path tree controlling observation\ngranularity:\n\n```typescript\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [\n        observerMap({\n            properties: {\n                user: {\n                    name: true,          // user.name — observed\n                    details: {\n                        age: true,       // user.details.age — observed\n                        history: false,  // user.details.history — NOT observed\n                    },\n                },\n                // root properties not listed here are skipped\n            },\n        }),\n    ],\n);\n```\n\nEach path entry can be:\n- **`true`** — observe this path and all descendants (unless overridden deeper).\n- **`false`** — skip this path and all descendants (unless overridden deeper).\n- **`ObserverMapPathNode`** — an object with an optional `$observe` boolean and child property overrides, allowing alternating opt-in/opt-out to arbitrary depth.\n\nWhen `properties` is omitted, all root properties are observed. When\n`properties` is present but empty (`{ properties: {} }`), no root properties\nare observed.\n\nObserver-map-managed array updates replace the array reference when `deepMerge`\nreceives a new array. This avoids mutating an existing observed array while it\nmay be notifying subscribers and lets repeat bindings observe the new array\nreference. Replaced arrays are wrapped with the schema for the assigned\nproperty, and array observer subscriptions are installed once per array so\nreprocessing does not duplicate accessors or notification work.\n\nFor non-declarative elements, pass a schema directly to `observerMap()`:\n\n```typescript\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-element\");\nschema.addPath({\n    rootPropertyName: \"user\",\n    pathConfig: {\n        type: \"default\",\n        parentContext: null,\n        currentContext: null,\n        path: \"user.name\",\n    },\n    childrenMap: null,\n});\n\nMyElement.define({ name: \"my-element\" }, [observerMap({ schema })]);\n```\n\nThe resolution algorithm walks the schema and configuration tree in parallel:\n1. If `properties` is present and a root property is not listed, it is skipped.\n2. `true`/`false` booleans apply to the entire subtree.\n3. `$observe` on a node object controls the current level; children inherit when unspecified.\n4. Paths in the config but not in the schema are silently ignored (forward-compatible).\n\n### `AttributeMap` — automatic `@attr` definitions\n\nAn optional layer that uses the `Schema` to automatically register `@attr`-style reactive properties for every **leaf binding** in the template — i.e. simple expressions like `{{foo}}` or `id=\"{{foo-bar}}\"` that have no nested properties, no explicit type, and no child element references.\n\n- By default (`attribute-name-strategy: \"camelCase\"`), the binding key is treated as a camelCase property name and the HTML attribute name is derived by converting it to kebab-case (e.g. `{{fooBar}}` → property `fooBar`, attribute `foo-bar`). This matches the build-time `--attribute-name-strategy` option in `@microsoft/fast-build`.\n- When `attribute-name-strategy` is `\"none\"`, the **attribute name** and **property name** are both the binding key exactly as written in the template (e.g. `{{foo-bar}}` → attribute `foo-bar`, property `foo-bar`). No normalization is applied.\n- Because HTML attributes are case-insensitive, binding keys should use lowercase names (optionally dash-separated) when using the `\"none\"` strategy.\n- Properties already decorated with `@attr` or `@observable` are left untouched.\n- `FASTElementDefinition.attributeLookup` is keyed by the HTML attribute name, and `propertyLookup` is keyed by the JS property name so `attributeChangedCallback` correctly delegates to the new `AttributeDefinition`.\n\nEnabled via the `attributeMap()` definition extension exported from\n`@microsoft/fast-element/attribute-map.js`. Calling `attributeMap()` without\narguments uses the default `\"camelCase\"` strategy. To preserve binding keys\nexactly as written, pass `attributeMap({ \"attribute-name-strategy\": \"none\" })`.\nOutside declarative templates, `attributeMap()` uses the optional `schema` on the\nFAST element definition.\n\n### Syntax constants (`syntax.ts`)\n\nAll delimiters used by the parser are defined in a single `Syntax` interface and exported as named constants from `syntax.ts`. This makes the syntax pluggable and easy to audit.\n\n| Constant | Value | Use |\n|---|---|---|\n| `openExpression` / `closeExpression` | `{{` / `}}` | Default (SSR-compatible) binding |\n| `unescapedOpenExpression` / `unescapedCloseExpression` | `{{{` / `}}}` | Raw HTML binding |\n| `clientSideOpenExpression` / `clientSideCloseExpression` | `{` / `}` | Client-only (event / attribute directive) binding |\n| `repeatDirectiveOpen` / `repeatDirectiveClose` | `<f-repeat` / `</f-repeat>` | Repeat directive |\n| `whenDirectiveOpen` / `whenDirectiveClose` | `<f-when` / `</f-when>` | When directive |\n| `attributeDirectivePrefix` | `f-` | Attribute directive prefix |\n| `eventArgAccessor` | `$e` | DOM event argument |\n| `executionContextAccessor` | `$c` | Execution context argument |\n\n---\n\n## Package Structure\n\n```\npackages/fast-element/\n├── src/\n│   ├── components/\n│   │   ├── schema.ts          # Shared Schema class + schemaRegistry\n│   │   └── definition-schema-transforms.ts # Definition-scoped schema transform storage\n│   ├── declarative/\n│       ├── index.ts           # Public declarative entrypoint implementation\n│       ├── interfaces.ts      # Message enum (error codes)\n│       ├── debug.ts           # Human-readable declarative debug messages\n│       ├── template.ts        # declarativeTemplate(), internal <f-template> publisher, lifecycle orchestration\n│       ├── template-bridge.ts # Registry/name bridge between definitions and publishers\n│       ├── template-parser.ts # TemplateParser — converts declarative HTML to ViewTemplate strings/values\n│       ├── observer-map.ts    # observerMap() implementation\n│       ├── attribute-map.ts   # attributeMap() implementation\n│       ├── observer-map-utilities.ts # Shared observer-map helpers\n│       ├── utilities.ts       # Declarative parsing helpers\n│       └── syntax.ts          # Syntax delimiter constants\n│   └── hydration/\n│       ├── markers.ts         # Default 3.x marker reader and marker strategy contract\n│       └── markers-v2.ts      # Opt-in 2.x indexed marker reader\n├── scripts/\n│   └── declarative/           # Fixture build + webui integration scripts\n└── test/\n    └── declarative/fixtures/  # One directory per feature, each with spec + index.html + main.ts\n```\n\n### Module dependency direction\n\nThe default `declarativeTemplate()` path avoids importing optional map\nimplementations. Map helpers attach schema transforms to the definition only\nwhen the consumer passes them as define extensions.\n\n```\ndeclarative/template.ts ──imports──▶ components/definition-schema-transforms.ts (schema transform reads)\ndeclarative/template.ts ──imports──▶ components/schema.ts (Schema)\ndeclarative/attribute-map.ts ──imports──▶ components/definition-schema-transforms.ts (register attribute-map transform)\ndeclarative/observer-map.ts ──imports──▶ components/definition-schema-transforms.ts (register observer-map transform)\ndeclarative/observer-map.ts ──imports──▶ components/schema.ts (Schema types)\ndeclarative/attribute-map.ts ──imports──▶ components/schema.ts (Schema types)\ndeclarative/utilities.ts ──imports──▶ components/schema.ts (schemaRegistry for cross-element $ref resolution)\n```\n\nSchema transforms run in deterministic order. `attributeMap()` runs before\n`observerMap()`, so generated attributes are available to observer mapping.\n\n---\n\n## Exports and Public API\n\n```typescript\nimport {\n    declarativeTemplate,\n    TemplateParser,\n    type ResolvedStringsAndValues,\n} from \"@microsoft/fast-element/declarative.js\";\nimport {\n    Schema,\n    schemaRegistry,\n    type CachedPathMap,\n    type JSONSchema,\n} from \"@microsoft/fast-element/schema.js\";\nimport { type FASTElementExtension } from \"@microsoft/fast-element\";\nimport {\n    attributeMap,\n    type AttributeMapConfig,\n} from \"@microsoft/fast-element/attribute-map.js\";\nimport {\n    observerMap,\n    type ObserverMapConfig,\n    type ObserverMapPathEntry,\n    type ObserverMapPathNode,\n} from \"@microsoft/fast-element/observer-map.js\";\n```\n\nDeclarative template helpers, map helpers, and their configuration types are\navailable from focused path exports.\n\nPrimary declarative exports intended for application code:\n\n| Export | Purpose |\n|---|---|\n| `declarativeTemplate()` | `@microsoft/fast-element/declarative.js` template resolver for subclass `define()` calls; auto-defines the internal `<f-template>` publisher and waits for the matching template. |\n| `TemplateParser` | `@microsoft/fast-element/declarative.js` standalone parser that converts declarative HTML into `ViewTemplate` strings/values. Can be used independently of `<f-template>` for programmatic template compilation. |\n| `Schema` | `@microsoft/fast-element/schema.js` JSON schema builder that records binding paths discovered during template parsing. Each instance owns its own schema map and registers itself in the `schemaRegistry` for cross-element `$ref` resolution. |\n| `schemaRegistry` | `@microsoft/fast-element/schema.js` module-level `Map<string, Map<string, JSONSchema>>` that indexes schemas by custom element name. Used for cross-element lookups (e.g. nested component `$ref` resolution). |\n\nHydration marker selection is available from\n`@microsoft/fast-element/hydration.js`. FAST Element 3.x data-free markers are\nthe default; `enableHydration({ markers: markers_v2 })` opts into the FAST Element 2.x\nindexed marker reader for staged server/client migrations.\n\nPrimary map extension exports:\n\n| Export | Import path | Purpose |\n|---|---|---|\n| `attributeMap()` | `@microsoft/fast-element/attribute-map.js` | Define extension that registers `@attr`-style properties for leaf bindings discovered during parsing or supplied by `definition.schema`. |\n| `observerMap()` | `@microsoft/fast-element/observer-map.js` | Define extension that defines observable root properties and proxy-based deep change tracking from `config.schema`, `definition.schema`, or a declarative template schema. |\n\nThe implementation element class (`<f-template>`), `TemplateElement.config()`,\n`TemplateElement.options()`, `ElementOptions*`, and\n`HydrationLifecycleCallbacks` are not exported from the public declarative\nentrypoint. Use `declarativeTemplate()`, `attributeMap()`, `observerMap()`, and\n`enableHydration()` instead. The `AttributeMap` and `ObserverMap` implementation\nclasses are available for advanced scenarios, but application code should\nnormally use the extension factories.\n\nAdditionally, `@microsoft/fast-element` exports these types:\n\n| Type | Source Module | Purpose |\n|---|---|---|\n| `FASTElementExtension` | `fast-definitions.ts` | Definition extension callback signature used by `attributeMap()` and `observerMap()`. |\n| `JSONSchema` | `components/schema.ts` | JSON Schema interface used by `Schema` for property structure. |\n| `CachedPathMap` | `components/schema.ts` | `Map<string, Map<string, JSONSchema>>` — the shape of the schema registry. |\n\nThe map configuration types are exported from the same map-specific paths:\n\n| Type | Import path | Purpose |\n|---|---|---|\n| `ObserverMapConfig` | `@microsoft/fast-element/observer-map.js` | Configuration object for `observerMap()`; accepts optional `schema` and `properties` keys. |\n| `ObserverMapPathEntry` | `@microsoft/fast-element/observer-map.js` | `boolean \\| ObserverMapPathNode` — a node in the observation path tree. |\n| `ObserverMapPathNode` | `@microsoft/fast-element/observer-map.js` | Object node with optional `$observe` and child property overrides. |\n| `AttributeMapConfig` | `@microsoft/fast-element/attribute-map.js` | Configuration object for `attributeMap()`; accepts `attribute-name-strategy`. |\n\n---\n\n## Template Syntax\n\nThe declarative syntax is a superset of HTML with three binding delimiters:\n\n| Syntax | Example | Behaviour |\n|---|---|---|\n| `{{expr}}` | `{{greeting}}` | SSR-compatible content / attribute binding |\n| `{{{expr}}}` | `{{{rawHtml}}}` | Unescaped HTML (wraps in `<div :innerHTML>`) |\n| `{expr}` | `@click=\"{handleClick($e)}\"` | Client-only binding (events, attribute directives) |\n\n### Directives\n\nBindings and FAST directive markup inside HTML comments are unsupported. The\nstring-based parsers do not reliably exclude comment contents, so commenting out\nbound markup can still affect binding discovery and hydration. See the\n[HTML comment restrictions](./syntax.md#html-comments).\n\n| Directive | Example |\n|---|---|\n| `<f-when value=\"{{expr}}\">` | Conditional rendering |\n| `<f-repeat value=\"{{item in list}}\">` | List rendering |\n| `f-slotted=\"{prop}\"` | Slotted nodes attribute directive |\n| `f-children=\"{prop}\"` | Children attribute directive |\n| `f-ref=\"{prop}\"` | Element ref attribute directive |\n\nFor full syntax reference see [syntax.md](./syntax.md).\n\n---\n\n## Data Flow\n\nThe high-level data flow from authoring to interactive component:\n\n```mermaid\nflowchart TD\n    A[\"Author writes declarative HTML\nusing f-template with binding expressions\"] --> B[\"Server renders hydratable HTML\nwith fe:b comments and data-fe attributes\"]\n    B --> C[Browser loads JS bundle]\n    C --> D[\"MyElement.define called\nwith template: declarativeTemplate()\"]\n    D --> E[\"declarativeTemplate() defines internal f-template\nin the target registry\"]\n    E --> F[\"f-template connects to DOM\n→ registers publisher with bridge\"]\n    F --> G[\"definition requests template\nvia registry + name bridge\"]\n    G --> H[transformInnerHTML normalises HTML entities]\n    H --> I[\"TemplateParser parses bindings/directives\nbuilds Schema, strings, values\"]\n    I --> J[\"Run definition schema transforms\nattributeMap before observerMap\"]\n    J --> K[\"ViewTemplate.create(strings, values)\nreturned to definition\"]\n    K --> L[\"FASTElementDefinition.define\nregisters element with platform\"]\n    L --> M{\"enableHydration() called?\"}\n    M -- yes --> N[\"ElementController hydrates existing DOM\nvia template.hydrate()\"]\n    M -- no --> O[\"ElementController client-side renders\nexisting DSD is not reused\"]\n    N --> P[Interactive component]\n    O --> P\n```\n\n---\n\n## Template Parsing Pipeline\n\nThe internal `<f-template>` publisher orchestrates the pipeline by creating a\n`TemplateParser` instance and delegating all parsing logic to it. The recursive\nparsing context is encapsulated in a `TemplateResolutionContext` object internal\nto the parser, keeping method signatures lean.\n\n### Architecture\n\nThe parsing pipeline is split across two classes plus definition-scoped\ntransforms:\n\n- **Internal `<f-template>` publisher** (`template.ts`) — Custom element\n  lifecycle, registry/name bridge registration, template publication, and\n  schema-transform execution. It is a native `HTMLElement`, not a `FASTElement`.\n- **`TemplateParser`** (`template-parser.ts`) — Synchronous template parser:\n  converts declarative HTML into `strings`/`values` arrays for\n  `ViewTemplate.create()`. Uses a `StringsAccumulator` to track the running\n  previous-string in O(1) per binding site instead of O(N) `join(\"\")` calls.\n  Independently testable without DOM.\n- **Schema transforms** (`definition-options.ts`) — Extension-provided callbacks run\n  after parsing and before `ViewTemplate.create()`. `attributeMap()` runs before\n  `observerMap()`.\n\n```mermaid\nsequenceDiagram\n    participant DOM\n    participant FTE as internal f-template\n    participant TP as TemplateParser\n    participant U as utilities.ts\n    participant S as Schema\n    participant Transforms as schema transforms\n\n    DOM->>FTE: connectedCallback()\n    FTE->>FTE: register publisher with bridge\n    FTE->>FTE: publishTemplate(definition)\n    FTE->>S: new Schema(name)\n    FTE->>U: transformInnerHTML(this.innerHTML)\n    FTE->>TP: parser.parse(innerHTML, schema)\n    loop getNextBehavior(innerHTML)\n        TP->>U: getNextBehavior()\n        U-->>TP: DataBindingBehaviorConfig | TemplateDirectiveBehaviorConfig\n        alt content binding\n            TP->>TP: resolveContentBinding()\n            TP->>TP: resolveAccessBinding()\n            TP->>U: bindingResolver()\n            U->>S: schema.addPath()\n            U-->>TP: (x,c) => value function\n        else attribute binding\n            TP->>TP: resolveAttributeBinding()\n            alt event (@)\n                TP->>TP: resolveEventBinding()\n            else boolean (?)\n                TP->>U: getBooleanBinding() or resolveAccessBinding()\n            else default\n                TP->>TP: resolveAccessBinding()\n            end\n        else attributeDirective (slotted / children / ref)\n            TP->>TP: resolveAttributeDirectiveBinding()\n        else templateDirective (when / repeat)\n            TP->>TP: resolveTemplateDirective()\n            note over TP: recurses into resolveStringsAndValues\n        end\n    end\n    TP-->>FTE: { strings, values }\n    FTE->>Transforms: attributeMap(), then observerMap()\n    FTE->>TP: parser.createTemplate(strings, values)\n    FTE-->>DOM: return ViewTemplate to definition resolver\n```\n\n### TemplateParser method decomposition\n\n| Method | Visibility | Role |\n|---|---|---|\n| `parse()` | public | Entry point: parses declarative HTML into `{ strings, values }`. |\n| `createTemplate()` | public | Creates a `ViewTemplate` from resolved strings and values, lazily installing declarative debug messages. |\n| `resolveStringsAndValues()` | private | Creates `strings`/`values` arrays and delegates to `resolveInnerHTML()`. |\n| `resolveInnerHTML()` | private | Recursive HTML parser that dispatches to data binding or template directive handlers. |\n| `resolveDataBinding()` | private | Thin dispatcher that routes to `resolveContentBinding()`, `resolveAttributeBinding()`, or `resolveAttributeDirectiveBinding()`. |\n| `resolveContentBinding()` | private | Handles `{{expression}}` in text content. |\n| `resolveAttributeBinding()` | private | Handles `{{expression}}` in HTML attributes; dispatches to `resolveEventBinding()` or `resolveAccessBinding()` based on aspect. |\n| `resolveAttributeDirectiveBinding()` | private | Handles `f-children`, `f-slotted`, `f-ref` directives. |\n| `resolveAccessBinding()` | private | Shared helper for access-type bindings (content, boolean-attribute fallback, default attribute). |\n| `resolveEventBinding()` | private | Handles event bindings (`@event`), including arg parsing and owner resolution. |\n| `resolveTemplateDirective()` | private | Handles `<f-when>` and `<f-repeat>` directives. |\n| `resolveAttributeDirective()` | private | Creates FAST `children()`, `slotted()`, or `ref()` directives. |\n\n### TemplateResolutionContext\n\nThe `TemplateResolutionContext` interface (internal to `TemplateParser`) groups the stable fields that flow through the recursive parsing pipeline:\n\n```typescript\ninterface TemplateResolutionContext {\n    parentContext: string | null;  // Current repeat item alias (e.g. \"item\")\n    level: number;          // Nesting depth for repeat directives\n    schema: Schema;         // JSON schema builder for property tracking\n}\n```\n\n`rootPropertyName` is intentionally kept separate because it is selectively mutated per branch and must not leak across sibling binding resolutions.\n\n### Key parsing functions (utilities.ts)\n\n| Function | Role |\n|---|---|\n| `getNextBehavior(innerHTML)` | Top-level scanner: returns the next `DataBindingBehaviorConfig` or `TemplateDirectiveBehaviorConfig`, or `null` when done. |\n| `getNextDataBindingBehavior(innerHTML)` | Identifies whether the next binding is `{{}}`, `{{{}}}`, or `{}` and classifies it as content/attribute/attributeDirective. |\n| `getNextDirectiveBehavior(innerHTML)` | Finds the next `<f-when>` or `<f-repeat>` and its matching close tag. |\n| `bindingResolver(...)` | Builds a `(x, c) => value` closure for a given path; also calls `schema.addPath()`. |\n| `pathResolver(path, contextPath, level, schema)` | Returns a closure that traverses an object using dot-notation, handling repeat context levels. |\n| `getBooleanBinding(...)` | Returns a `(x, c) => boolean` closure for `<f-when>` expressions. |\n| `assignObservables(schema, rootSchema, data, target, rootProperty)` | Wraps objects/arrays in `Proxy` for deep observation. |\n| `deepMerge(target, source)` | Merges source into an existing proxy, preserving proxy identity and triggering observable notifications. |\n| `transformInnerHTML(html)` | Normalises HTML-encoded operator characters (`&gt;`, `&lt;`, etc.) used in `<f-when>` expressions. |\n| `escapeBracesInCodeElements(html)` | Replaces `{` / `}` characters inside every `<code>` element with `&#123;` / `&#125;` so binding-like syntax in code samples renders literally rather than being interpreted as FAST bindings. Client-side half of a two-stage escape — the brace escape mirrors the server-side pass in `microsoft-fast-build` (necessary client-side because `&#123;` / `&#125;` decode back to literal `{` / `}` in the DOM and `.innerHTML` does not re-encode them). The angle-bracket escape for FAST directive tags (`<f-when>`, `</f-when>`, `<f-repeat>`, `</f-repeat>`) inside `<code>` runs only on the server because the DOM serializer re-encodes `<` / `>` in text content automatically. Real HTML elements (`<button>`) and custom elements inside `<code>` keep their angle brackets and continue to render as live DOM elements. Modeled on Microsoft WebUI's `webui-press` markdown renderer. |\n\n### Binding classification\n\n```\ninnerHTML token\n  ├── {{{ ... }}}  → unescaped content binding  (innerHTML div)\n  ├── {{ ... }}    → default binding\n  │     ├── attr=\"{{expr}}\"    → attribute binding   (aspect: null / \":\" / \"?\")\n  │     └── {{expr}} in text  → content binding\n  └── { ... }      → client-side binding\n        ├── @event=\"{handler(...)}\"  → event binding (aspect \"@\")\n        └── f-dir=\"{prop}\"           → attribute directive binding\n```\n\n---\n\n## Schema and Observer Map\n\nThe `Schema` class accumulates all binding paths discovered during parsing into an instance-level JSON Schema map (`schemaMap`) indexed by `rootPropertyName → JSONSchema`. Each `Schema` instance also registers itself in the module-level `schemaRegistry` (keyed by custom element name) for cross-element `$ref` resolution.\n\n```mermaid\nflowchart LR\n    A[\"Template binding\\nuser.details.age\"] --> B[bindingResolver]\n    B --> C[schema.addPath\\ntype:'access'\\npath:'user.details.age'\\nrootProperty:'user']\n    C --> D[\"schema.schemaMap\\n{'user' => JSONSchema}\"]\n    C --> D2[\"schemaRegistry\\n{'my-el' => schemaMap}\"]\n    D --> E[ObserverMap.defineProperties]\n    E --> E1[\"applyConfigToSchema\\nstamps $observe: false on excluded schema nodes\"]\n    E1 --> F[Observable.defineProperty on prototype\\nfor 'user']\n    E1 --> G[install instanceResolverChanged handler]\n    G --> H[\"when user= is set:\\nassignObservables checks schema.$observe\\n→ Proxy wraps observed paths only\\ndeep mutations → Observable.notify\"]\n```\n\nFor a deep dive into the schema structure, context tracking, and proxy system\nsee\n[schema-observer-map.md](./schema-observer-map.md).\n\n### `$observe` flag on schema nodes\n\nWhen an `ObserverMapConfig` with a `properties` key is provided, `ObserverMap.defineProperties()` calls `applyConfigToSchema()` to stamp `$observe: false` on excluded schema nodes **before** the proxy system runs. This is a one-time pre-processing pass that walks the config and schema trees in parallel:\n\n- `false` in the config → `$observe: false` is stamped recursively on the node and all its descendants.\n- `$observe: false` on a config node → the schema node is stamped, and unlisted children inherit the stamp.\n- `true` in the config → no stamp needed (observed is the default).\n- Config paths not in the schema are silently ignored.\n\n**Convention: stamp-only-when-excluding.** The `$observe` flag is only ever set to `false` — it is never explicitly set to `true`. Absence of `$observe` (i.e. `undefined`) means the node is observed. This means:\n\n- When Observer Map is enabled without a `properties` tree, `applyConfigToSchema`\n  is never called and no schema nodes are mutated — zero overhead for the\n  common case.\n- The proxy system uses `isSchemaExcluded(schema)` (checks `$observe === false` with no observed descendants) as the single predicate for all skip/suppress decisions.\n- Schema nodes without `$observe` are always treated as observed.\n\n### AttributeMap and leaf bindings\n\nWhen `attributeMap()` is enabled with a declarative template, it registers a\ndefinition schema transform. With a manually supplied definition schema, it runs\nimmediately. The extension constructs an `AttributeMap` implementation and calls\n`defineProperties()`. It iterates `Schema.getRootProperties()` and skips any\nproperty whose schema entry contains `properties`, `type`, or `anyOf` — keeping\nonly plain leaf bindings. For each leaf:\n\n1. The schema key is used as the **JS property name**.\n2. The **HTML attribute name** depends on the `attribute-name-strategy`:\n   - `\"camelCase\"` (default): the attribute name is derived by converting the camelCase property name to kebab-case (e.g. `fooBar` → `foo-bar`).\n   - `\"none\"`: the attribute name equals the property name (e.g. `foo-bar` → `foo-bar`).\n3. A new `AttributeDefinition` is registered via `Observable.defineProperty`.\n4. `FASTElementDefinition.attributeLookup` is keyed by the HTML attribute name and `propertyLookup` is keyed by the JS property name so `attributeChangedCallback` can route attribute changes to the correct property.\n\nWhen using the `\"none\"` strategy, property names may contain dashes and must be\naccessed via bracket notation (e.g. `element[\"foo-bar\"]`). When using\n`\"camelCase\"`, property names are standard JS identifiers (e.g.\n`element.fooBar`).\n\nSchema transforms run in deterministic order. When both extensions are supplied,\nattribute mapping runs before observer mapping.\n\n---\n\n## Lifecycle\n\n```mermaid\nsequenceDiagram\n    participant App as Application JS\n    participant FER as FASTElementDefinition\n    participant FTE as internal f-template\n    participant EC as ElementController\n    participant Hydration as enableHydration().whenHydrated()\n\n    App->>Hydration: const hydration = enableHydration() [optional]\n    App->>FER: MyElement.define({name:'my-el', template: declarativeTemplate()}, [attributeMap(), observerMap()])\n    note over FER: definition composed; resolver waits for template\n\n    DOM->>FTE: f-template connected to DOM\n    FTE->>FTE: bridge matches registry + name\n    FTE->>FTE: parse template → schema → transforms → ViewTemplate\n    FTE->>FER: return viewTemplate to resolver\n    FER->>FER: customElements.define('my-el', MyElement)\n\n    DOM->>EC: element instance connects with existing shadow root\n    EC->>EC: isPrerendered = true (existing shadow root detected)\n    alt enableHydration() was called\n        EC->>EC: template.hydrate() — maps existing DOM to binding targets\n        EC->>Hydration: resolve active batch when all pending elements finish\n    else hydration not enabled\n        EC->>EC: client-side render; isHydrated = false\n    end\n```\n\n### Promise readiness reference\n\n| Promise | Import path | Resolves when |\n|---|---|---|\n| `enableHydration().whenHydrated(\"my-element\")` | `@microsoft/fast-element/hydration.js` | Hydration work for that tag name completes. |\n| `enableHydration().whenHydrated()` | `@microsoft/fast-element/hydration.js` | The active hydration batch completes. |\n\nBy default, hydration no-ops for later prerendered batches after the initial\nbatch completes. Set\n`enableHydration({ stopHydration: StopHydration.never })` when Declarative Shadow\nDOM may be streamed into the page after the initial hydration batch. In that\nmode, `enableHydration().whenHydrated()` intentionally remains pending because\nthere is no global completion point.\n\nFor usage examples see\n[lifecycle.md](./lifecycle.md).\n\n---\n\n## Integration with fast-element\n\nThe declarative runtime is a thin orchestration layer on top of\n`@microsoft/fast-element`. It does not re-implement any reactive primitives; it\nconverts declarative HTML syntax into the same data structures that `html`\ntagged templates produce.\n\n| fast-element primitive | How the declarative runtime uses it |\n|---|---|\n| `FASTElement` | Base class for user components; the internal `<f-template>` publisher is a native `HTMLElement` |\n| `FASTElementDefinition.register()` / template resolvers | Deferred element registration — element waits for its template |\n| `FASTElementDefinition.schema` | Optional schema used by schema-driven extensions; assigned automatically by `declarativeTemplate()` and available for manual schemas |\n| `FASTElementExtension` | Extension callback mechanism used by `attributeMap()` and `observerMap()` to attach schema transforms before template resolution or consume manually supplied schemas |\n| `ViewTemplate.create(strings, values)` | Compiles the resolved strings/values arrays into a `ViewTemplate` |\n| `ElementController` | Automatically detects prerendered content (`isPrerendered`) and hydrates server-rendered DOM using `fe-b` comment/dataset markers via `template.hydrate()` |\n| `Observable.defineProperty()` | Defines observable root properties on element prototypes (ObserverMap) |\n| `Observable.getNotifier()` | Triggers change notifications from proxy handlers |\n| `when(expr, template)` | FAST directive used for `<f-when>` |\n| `repeat(expr, template)` | FAST directive used for `<f-repeat>` |\n| `slotted(options)` | FAST directive used for `f-slotted` |\n| `children(prop)` | FAST directive used for `f-children` |\n| `ref(prop)` | FAST directive used for `f-ref` |\n\n### Deferred template attachment via define\n\nStandard subclass `define()` calls return a `Promise` that resolves immediately when a concrete template is provided at definition time. When `template: declarativeTemplate()` is used, the `Promise` resolves after the matching `<f-template>` supplies a concrete template through the bridge. This unified API replaces the previous `defineAsync()` / `composeAsync()` methods.\n\n---\n\n## Hydration Model\n\nWhen declarative templates are used, the server must render:\n\n1. The custom element tag with its attributes and initial state.\n2. A `<template shadowrootmode=\"open\">` containing pre-rendered HTML annotated with FAST's hydration markers.\n3. An `<f-template>` element somewhere in the page that carries the template definition.\n\nWith `declarativeTemplate()`, connection gating happens before platform registration: the resolver waits for the matching `<f-template>` and keeps the definition concrete before elements can connect. Hydration can therefore start immediately when `ElementController.connect()` runs. The `defer-hydration` and `needs-hydration` attributes are no longer needed in server-rendered markup.\n\n### Hydration marker formats\n\n`enableHydration()` uses the FAST Element 3.x data-free marker reader by\ndefault. The marker strategy is shared by target discovery and nested repeat\nhydration so a view uses one consistent format throughout its hydration walk.\nThe optional `markers_v2` strategy contains the legacy indexed-marker parsing logic and\nis selected with `enableHydration({ markers: markers_v2 })`.\n\n**Content bindings** use HTML comments (data-free, matched by string equality):\n\n```\n<!--fe:b-->\n<!--fe:/b-->\n```\n\n**Attribute bindings** use a single `data-fe` dataset attribute with binding count:\n\n```html\n<el data-fe=\"3\">\n```\n\n**Repeat directives** wrap each item in comment pairs:\n```\n<!--fe:r-->\n...item DOM...\n<!--fe:/r-->\n```\n\nFor detailed examples see\n[rendering.md](./rendering.md).\n\n---\n\n## Testing Architecture\n\nEach feature is verified by a **Playwright** integration test against a live\nVite dev server. The `test/declarative/fixtures/` directory contains one\nsubdirectory per feature:\n\n```\ntest/declarative/fixtures/<feature>/\n├── <feature>.spec.ts        # Playwright test\n├── entry.html               # Entry template with root custom elements\n├── fast-build.config.json   # Build configuration for @microsoft/fast-build\n├── index.html               # Pre-rendered page (GENERATED by scripts/declarative/build-fixtures.js — do not edit)\n├── main.ts                  # Component definitions, declarativeTemplate(), extensions, and enableHydration() setup\n├── state.json               # Initial state for server-side rendering\n└── templates.html           # Declarative <f-template> definitions\n```\n\nFixtures are auto-discovered by scanning for directories that contain `entry.html`, `templates.html`, `state.json`, and `fast-build.config.json`. Both the build script and the Vite config pick up new fixtures automatically — no registration step is needed.\n\nFor fixtures that use SSR-style pre-rendered HTML,\n`scripts/declarative/build-fixtures.js` invokes `@microsoft/fast-build` with\n`--config` pointing to each fixture's `fast-build.config.json` to generate\n`index.html` from the configured source files.\n\n### WebUI Integration Tests\n\nA separate integration test suite validates that `@microsoft/webui` can build and render the same fixture templates that `@microsoft/fast-build` processes. This is split into two steps:\n\n1. **Build** (`npm run build:fixtures:webui`) — runs\n   `scripts/declarative/build-fixtures-with-webui.js`, which extracts\n   `<f-template>` elements, converts each component template with\n   `fast convert --syntax=webui-prerelease`, builds each fixture with\n   `webui build --plugin=fast`, renders the protocol with `state.json`, and\n   writes the output alongside `main.ts` and assets to\n   `temp/integrations/webui/fixtures/`.\n2. **Test** (`npm run test:webui-integration`) — builds the fixtures, then runs\n   the same Playwright specs against the webui-rendered output served by a Vite\n   dev server on port 5174 (configured in\n   `playwright.declarative.webui.config.ts`).\n\nFixtures that intentionally contain invalid FAST declarative templates are skipped in\nthe WebUI build because `fast convert` validates and rejects them before WebUI\nrenders. Run locally with `npm run test:webui-integration` or via the\n`ci-webui-integration.yml` GitHub Action on PRs and pushes to `main`.\n\n#### Skipped tests\n\nSome tests are conditionally skipped when running under the webui integration\nconfig. The `playwright.declarative.webui.config.ts` file sets\n`process.env.FAST_WEBUI_INTEGRATION = \"true\"`, and individual tests check this\nvariable with `test.skip()` to opt out of cases that exercise known differences\nbetween `fast-build` and `webui` rendering:\n\n- **`errors.spec.ts` — \"throws an error when no template element is present\"**: webui does not render `<f-template>` elements that lack a `<template>` child, so the expected error is never thrown.\n\n### Hydration readiness\n\nFixtures that exercise prerendered output wait for hydration to complete before\nrunning assertions. Each `main.ts` calls `enableHydration()` and then awaits\nthe returned controller's `whenHydrated()` promise to set a global flag, and each spec file calls\n`page.waitForFunction()` after `page.goto()` to block until the flag is set.\nSee [test/declarative/fixtures/README.md](../../test/declarative/fixtures/README.md)\nfor the implementation pattern.\n\nSee\n[test/declarative/fixtures/WRITING_FIXTURES.md](../../test/declarative/fixtures/WRITING_FIXTURES.md)\nfor the complete fixture authoring guide,\n[test/declarative/fixtures/README.md](../../test/declarative/fixtures/README.md)\nfor a quick reference, and\n[test/declarative/fixtures/extensions/observer-map-deep-merge/README.md](../../test/declarative/fixtures/extensions/observer-map-deep-merge/README.md)\nfor an example of a complex multi-feature fixture.\n\n---\n\n## Further Reading\n\n| Document | Topic |\n|---|---|\n| [syntax.md](./syntax.md) | Installation, syntax reference, hydration promises, usage examples |\n| [rendering.md](./rendering.md) | Hydratable HTML format: comment markers, dataset attributes, directive markers |\n| [lifecycle.md](./lifecycle.md) | Phase-by-phase rendering lifecycle, hydration readiness, performance notes |\n| [schema-observer-map.md](./schema-observer-map.md) | Deep dive into Schema JSON structure, ObserverMap proxy system, debugging |\n| [test/declarative/fixtures/README.md](../../test/declarative/fixtures/README.md) | Quick reference for fixture structure |\n| [test/declarative/fixtures/WRITING_FIXTURES.md](../../test/declarative/fixtures/WRITING_FIXTURES.md) | Complete guide to writing new Playwright fixture tests |\n| [test/declarative/fixtures/extensions/observer-map-deep-merge/README.md](../../test/declarative/fixtures/extensions/observer-map-deep-merge/README.md) | Complex deep-merge fixture: observable arrays, nested repeats, conditionals |\n\n<!-- File: packages/fast-element/docs/declarative/lifecycle.md (Tokens: ~1481 | Category: anthropic-skill) -->\n# Rendering Lifecycle\n\nThis document describes the declarative rendering lifecycle inside\n`@microsoft/fast-element`.\n\n## Overview\n\nThe FAST Element rendering lifecycle involves a coordinated process between the\ncore runtime and its declarative entrypoint:\n\n- **`@microsoft/fast-element`**: Provides the core `FASTElement` base class and\n  element definition system.\n- **`@microsoft/fast-element/declarative.js`**: Provides the `f-template`\n  custom element that processes HTML templates and attaches them to FAST\n  elements as a `ViewTemplate` in lieu of an `html` template created during\n  a subclass `define()` call. The preferred path uses `declarativeTemplate()` so\n  the subclass `define()` call waits for the matching declarative template and keeps\n  the definition concrete before registration completes.\n\n## Lifecycle Phases\n\nGiven a DOM which includes an `f-template` and a component:\n\n```html\n<my-component text=\"Hello World\">\n    <template shadowrootmode=\"open\">\n        <h1><!--fe:b-->Hello World<!--fe:/b--></h1>\n    </template>\n</my-component>\n\n<f-template name=\"my-component\">\n    <template>\n        <h1>{{text}}</h1>\n    </template>\n</f-template>\n```\n\nThe following phases will then be kicked off once the JavaScript is parsed.\n\n### Phase 1: Definition Resolution\n\nCustom elements begin their lifecycle by composing a definition that points at\n`declarativeTemplate()`. The resolver waits for a matching declarative template\nand returns a concrete `ViewTemplate` before the platform registration step.\n\n```typescript\n// Custom element class definition\nclass MyComponent extends FASTElement {\n    @attr text: string = \"\";\n}\n\n// Register with the declarative template bridge\nMyComponent.define({\n    name: \"my-component\",\n    template: declarativeTemplate(),\n});\n```\n\nKey characteristics of this phase:\n- The element definition stays unresolved until a matching declarative template is available\n- The resolved template is concrete before platform registration completes\n\n### Phase 2: Declarative Template Bridge\n\n`declarativeTemplate()` from `@microsoft/fast-element/declarative.js`\nautomatically ensures that `f-template` is defined in the same registry as the\nFAST element being composed.\n\n### Phase 3: Template Processing and Attachment\n\nWhen an `f-template` element is connected to the DOM, it initiates the template attachment process.\n\nThe lifecycle flow during this phase:\n\n1. **Template Discovery**: The resolver waits for a matching\n   `<f-template name=\"...\">` in the same registry as the element definition.\n2. **Template Element Connection**: The matching `f-template` element's\n   `connectedCallback()` registers it with the declarative template bridge.\n3. **Template Processing**: The bridge reads and transforms the markup, builds\n   the schema, applies `observerMap()` / `attributeMap()` behavior, and resolves\n   data bindings, directives, and other template features into the `ViewTemplate`\n   model which is also used by the `@microsoft/fast-element` `html` tag template.\n4. **Template Attachment**: The concrete `ViewTemplate` is returned to\n   the subclass `define()` call, which assigns it to the definition before platform\n   registration completes.\n\n### Phase 4: Composition Completion\n\nOnce the template is attached to the partial definition, the element completes its composition:\n\n1. **`compose()` Execution**: The element definition internally completes its composition process\n2. **Platform Registration**: The completed element definition is fully registered with the platform's custom element registry\n\n### Phase 5: Element Instantiation and Hydration\n\nWhen custom elements are instantiated in the DOM, the following occurs:\n\n1. **Element Creation**: The platform creates instances of the custom element\n2. **Prerendered Content Detection**: `ElementController` detects the existing shadow root from SSR — `isPrerendered` resolves `true`\n3. **Hydration Check**: If `enableHydration()` was called and the template is hydratable, the element hydrates — `isHydrated` resolves `true`. Otherwise it falls back to client-side rendering.\n4. **Concrete Template Ready**: Because `declarativeTemplate()` resolved during\n   definition, `connect()` starts with the final template already attached.\n5. **Hydration**: `ElementController` uses `template.hydrate()` to create a\n   `HydrationView` that maps existing DOM nodes to binding targets using `fe:b`\n   / `fe:/b` markers\n\nThe DOM after hydration should look like this:\n\n```html\n<my-component text=\"Hello World\">\n    <template shadowrootmode=\"open\">\n        <h1><!---->Hello World<!----></h1>\n    </template>\n</my-component>\n```\n\n## Key Integration Points\n\n### Fast Element Registry\n\nThe `fastElementRegistry` serves as the central coordination point between the\ntwo packages and is available to consumers from\n`@microsoft/fast-element/registry.js`:\n\n- Stores partial element definitions created by `define()`\n- Provides lookup mechanism via `register()` for template attachment\n- Resolves `fastElementRegistry.whenRegistered(tagName)` when a matching\n  definition is registered\n- Maintains the registry of all FAST element definitions\n\n### Observable Pattern\n\nBoth packages use the Observable pattern for coordination:\n\n- Element definition template assignment notifies observers that are waiting for a concrete template\n- Template attachment triggers observable notifications to complete the lifecycle\n\n## Error Handling\n\nThe lifecycle includes error handling for missing components:\n\n- Template elements throw errors if no corresponding element definition is found\n- Element definitions can exist without templates (partial state)\n\n## Performance Considerations\n\nThe asynchronous nature of the lifecycle provides several performance benefits:\n\n- **Progressive Enhancement**: Elements can be registered before templates are loaded\n- **Code Splitting**: Templates can be loaded separately from element definitions  \n- **Reduced Blocking**: Template processing doesn't block element registration\n- **Hydration Optimization**: Server-side rendered content can be hydrated efficiently\n\nThis coordinated lifecycle enables powerful scenarios like server-side rendering, progressive enhancement, and dynamic template loading while maintaining the reactive capabilities of FAST Element.\n\n## Hydration promise APIs\n\nFAST Element exposes promises for hydration readiness points that are useful to\napplication code.\n\nHydration must be explicitly opted into by calling `enableHydration()`. Await\nthe returned controller's `whenHydrated()` promise when code needs to run after\nthe active hydration batch completes. Pass a tag name to `whenHydrated(tagName)`\nwhen code needs to wait for a specific FAST element.\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nconst hydration = enableHydration();\nawait hydration.whenHydrated(\"my-component\");\nawait hydration.whenHydrated();\n```\n\nBy default, hydration no-ops for later prerendered batches after the initial\nbatch completes. Set `stopHydration: StopHydration.never` in\n`enableHydration()` when streaming Declarative Shadow DOM should continue\nhydrating after the initial batch. In that mode, `hydration.whenHydrated()`\nintentionally remains pending because hydration has no global completion point.\n\n<!-- File: packages/fast-element/docs/declarative/rendering.md (Tokens: ~3301 | Category: anthropic-skill) -->\n# Non-browser HTML rendering\n\n1. [Initial State](#initial-state)\n2. [Hydrating Comments and Datasets](#hydration-comments-and-datasets)\n\nThis document details information on rendering hydratable content and includes some pointers on how Dependency Injection can be used to create services that hydrate a custom elements state. Non-browser rendering in this context means producing HTML that a browser can parse and hydrate later; it does not mean running the FAST Element client runtime in a worker, server-side JavaScript runtime, or other non-window host.\n\n## Initial State\n\nTo create initial state this should be added somewhere accessible by your service, in this example a `<script>` tag can be used to provide a global initial state.\n\nExample:\n```html\n<script>\n    window.__INITIAL_STATE__ = {\n        text: \"Hello world\"\n    }\n</script>\n```\n\nAdd a Dependency Injection service in your bundle to access properties in your state.\n\nSimple example (`initial-state.ts`):\n```typescript\nimport { DI } from \"@microsoft/fast-element/di.js\";\n\ninterface InitialState {\n    text: string;\n}\n\nexport interface IInitialStateService {\n  init(): InitialState;\n}\n\nexport class InitialStateService implements IInitialStateService {\n    private initialState: any;\n\n    constructor() {\n        this.initialState = window.__INITIAL_STATE__;\n    }\n\n    public init(...keys: Array<string>): InitialState {\n        const config: any = {};\n\n        for (let key of keys) {\n            config[key] = this.initialState[key];\n        }\n\n        return config;\n    }\n}\n\nexport const initialStateFactory = DI.createContext<IInitialStateService>(\n  'i-initial-state-service',\n  (x) => x.singleton(InitialStateService)\n);\n```\n\nInclude the DI service to your component.\n\nExample:\n```typescript\nimport { attr, FASTElement, Observable } from \"@microsoft/fast-element\";\nimport {\n    initialStateFactory,\n    InitialStateService,\n    type IInitialStateService,\n} from \"./initial-state.js\";\nimport { inject } from \"@microsoft/fast-element/di.js\";\n\nexport class MyComponent extends FASTElement {\n    @inject(initialStateFactory) initialStateService!: InitialStateService;\n\n    @attr\n    text: string = \"\";\n\n    service!: IInitialStateService;\n\n    connectedCallback() {\n        super.connectedCallback();\n\n        this.loadItemFromInitialState();\n    }\n\n    loadItemFromInitialState(): void {\n        const initialState = this.initialStateService.init([\"text\"]);\n\n        this.text = initialState.text;\n    }\n}\n\nMyComponent.define({\n    name: \"my-component\",\n    template: declarativeTemplate(),\n});\n```\n\nWhen the element connects, `ElementController` automatically detects the\nexisting shadow root from SSR and sets `isPrerendered = true`.\n`declarativeTemplate()` keeps the definition template concrete before\nregistration completes, so the element can hydrate the prerendered shadow root\nimmediately. The `defer-hydration` and `needs-hydration` attributes are no\nlonger needed.\n\n## Hydration Comments and Datasets\n\nWhen hydrating the HTML, FAST uses `ElementController` which detects an\nexisting shadow root (from SSR or declarative shadow DOM) and sets\n`isPrerendered = true`. It then uses `template.hydrate()` to create a\n`HydrationView` that maps existing DOM nodes to binding targets using hydration\n\"markers\" such as comments and dataset attributes. By default the declarative\nruntime in `@microsoft/fast-element` assumes component hydration will occur, so\nrendering hydratable markup is required.\n\n### Bindings\n\n#### Content Bindings\n\nContent binding markers are represented using HTML comments. These comments are used to indicate where dynamic content exists in the template. Markers carry no embedded data — they are fixed strings matched by string equality (not regex).\n\n* Start binding: `<!--fe:b-->`\n* End binding: `<!--fe:/b-->`\n\nBinding pairs are matched using balanced depth counting: each start marker increments a depth counter and each end marker decrements it. When the counter returns to zero the pair is complete.\n\n##### Content Binding Marker Examples\n\n**Note**\nExamples shown below mostly skip the wrapping custom element and the internal template element with `shadowrootmode=\"open\"`.\n\nTypically along with the content from the examples below, the rendering should include:\n\n```html\n<my-component>\n    <template shadowrootmode=\"open\" shadowroot=\"open\">\n        <!-- hydratable content -->\n    </template>\n</my-component>\n```\n\n**Simple content example**\n\nContent bindings such as:\n```html\n<h1>{{text}}</h1>\n```\n\nWhen combined with state such as:\n```json\n{\n    \"text\": \"Hello world\"\n}\n```\n\nShould result in:\n```html\n<h1><!--fe:b-->Hello world<!--fe:/b--></h1>\n```\n\n#### Attribute Bindings\n\nAttribute bindings are tracked using a single dataset attribute: `data-fe=\"N\"` where `N` is the number of attribute bindings on the element.\n\n##### Examples\n\n###### Single attribute example\n\nAttribute binding such as:\n```html\n<h1 greeting=\"{{greeting}}\"></h1>\n```\n\nWhen combined with state such as:\n```json\n{\n    \"greeting\": \"Hello\"\n}\n```\n\nShould result in:\n\n```html\n<h1 data-fe=\"1\" greeting=\"Hello\"></h1>\n```\n\n###### Multiple attribute bindings\n\nWhen multiple attribute bindings exist on the same element:\n```html\n<h1 greeting=\"{{greeting}}\" subtitle=\"{{subtitle}}\" punctuation=\"{{punctuation}}\"></h1>\n```\n\nWhen combined with state such as:\n```json\n{\n    \"greeting\": \"Hello\",\n    \"subtitle\": \"world\",\n    \"punctuation\": \"!\"\n}\n```\n\nShould result in:\n\n```html\n<h1 data-fe=\"3\" greeting=\"Hello\" subtitle=\"world\" punctuation=\"!\"></h1>\n```\n\n**Mixed attribute and content example**\n\nMultiple attributes and content bindings such as:\n```html\n<div show=\"{{show}}\" appearance=\"{{appearance}}\" punctuation=\"{{punctuation}}\">\n    <h1>{{text}}</h1>\n    <span>{{subtitle}}</span>\n    <span>{{punctuation}}</span>\n</div>\n```\n\nShould result in:\n```html\n<div data-fe=\"3\" show appearance=\"large\" punctuation=\"!\">\n    <h1><!--fe:b-->Hello<!--fe:/b--></h1>\n    <span><!--fe:b-->world<!--fe:/b--></span>\n    <span><!--fe:b-->!<!--fe:/b--></span>\n</div>\n```\n\n### Directives\n\nDirectives are treated differently from bindings as they include a template. This means that in addition to the binding used to determine the logic for the directive FAST also requires a separate marker for the directive itself to demarkate the beginning and end of the template.\n\n#### Repeat\n\nExample repeat binding:\n```html\n<f-repeat value=\"{{item in list}}\">\n    <span>{{item}}</span>\n</f-repeat>\n```\n\nCombined with state:\n```json\n[\n    \"Bob\",\n    \"Alice\",\n    \"Sue\"\n]\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<!--fe:r-->\n<span>\n    <!--fe:b-->Bob<!--fe:/b-->\n</span>\n<!--fe:/r-->\n<!--fe:r-->\n<span>\n    <!--fe:b-->Alice<!--fe:/b-->\n</span>\n<!--fe:/r-->\n<!--fe:r-->\n<span>\n    <!--fe:b-->Sue<!--fe:/b-->\n</span>\n<!--fe:/r-->\n<!--fe:/b-->\n```\n\nNote that the repeat markers are data-free — they carry no index or ID. Pairing uses balanced depth counting. Additionally, a binding wraps the repeat markers; even if the array is empty, this binding must be rendered.\n\nExample result of an empty array:\n```html\n<!--fe:b-->\n<!--fe:/b-->\n```\n\n#### When\n\nThe when directive is either present in the DOM or not, and therefore does not need an extra marker for the template.\n\nExample when binding:\n```html\n<f-when value=\"{{show}}\">\n    <span>{{text}}</span>\n</f-when>\n```\n\nCombined with state:\n```json\n{\n    \"show\": true,\n    \"text\": \"Hello world\"\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<span>\n    <!--fe:b-->Hello world<!--fe:/b-->\n</span>\n<!--fe:/b-->\n```\n\nIf the when is evaluated to `falsy` then we can safely leave the binding markers only.\n\nExample state:\n```json\n{\n    \"show\": false,\n    \"text\": \"Hello world\"\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<!--fe:/b-->\n```\n\n### Host attributes from `<f-template>`\n\nBuild-time renderers (e.g. `@microsoft/fast-build`) forward attributes declared on the inner `<template>` element of an `<f-template>` onto the rendered host element opening tag.\n\nExample template:\n```html\n<f-template name=\"my-button\">\n    <template tabindex=\"0\" ?disabled=\"{{isDisabled}}\">\n        <button><slot></slot></button>\n    </template>\n</f-template>\n```\n\nCombined with author HTML `<my-button></my-button>` and state:\n```json\n{\n    \"isDisabled\": true\n}\n```\n\nShould result in:\n```html\n<my-button tabindex=\"0\" disabled defer-hydration needs-hydration>\n    <template shadowrootmode=\"open\" shadowroot=\"open\">\n        <button><slot></slot></button>\n    </template>\n</my-button>\n```\n\nRules:\n- Client-only attributes (`@event`, `:prop`, `f-ref`, `f-slotted`, `f-children`) are skipped — they have no meaning on a server-rendered host element.\n- Author attributes on the host element always win on conflicts (case-insensitive name match; the dedupe key for `?name=\"{{expr}}\"` is the bare `name`).\n- Static `name=\"value\"` is forwarded verbatim (HTML-escaped); static boolean `name` is emitted bare.\n- `name=\"{{expr}}\"` is resolved against the element's initial child state; primitives are emitted as `name=\"value\"`, `Array` / `Object` / `Null` and missing values are stripped.\n- `?name=\"{{expr}}\"` is evaluated as a boolean against the same state; the bare `name` (without `?`) is emitted when truthy and skipped when falsy.\n\n### Client Side Bindings\n\nClient side bindings are bindings which the client needs, but they are not necessary as part of an initial render. These must still be accounted for when creating hydration comments however, as the template needs to know which elements to attach these bindings to. There are two types of client side bindings, events and attribute directives. These do not require state as they are bound to class methods or properties.\n\n#### Event Bindings\n\nEvent bindings such as `@keydown` and `@click` can be represented with hydration comments.\n\nExample event binding:\n```html\n<button @click=\"{handleClick($e)}\">Button</button>\n```\n\nShould result in:\n```html\n<button data-fe=\"1\">Button</button>\n```\n\n#### Attribute Directives\n\nAttribute directives such as `f-slotted` and `f-ref` can be represented with hydration comments.\n\nExample `f-ref` binding:\n```html\n<button f-ref=\"{button}\">Button</button>\n```\n\nShould result in:\n```html\n<button data-fe=\"1\">Button</button>\n```\n\n#### More Examples\n\n##### Nested Whens\n\nExample when binding:\n```html\n<f-when value=\"{{show}}\">\n    <span>{{text}}</span>\n    <f-when value=\"{{showInternal}}\">\n        <span>{{internalText}}</span>\n    </f-when>\n</f-when>\n```\n\nCombined with state:\n```json\n{\n    \"show\": true,\n    \"text\": \"Hello world\",\n    \"showInternal\": true,\n    \"internalText\": \"Hello pluto\"\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n<span>\n    <!--fe:b-->Hello world<!--fe:/b-->\n</span>\n    <!--fe:b-->\n    <span>\n        <!--fe:b-->Hello pluto<!--fe:/b-->\n    </span>\n    <!--fe:/b-->\n<!--fe:/b-->\n```\n\n##### Nested Repeats\n\nExample when binding:\n```html\n<f-repeat value=\"{{item in items}}\">\n    <div>\n        <span>{{item.name}}</span>\n        <f-when value=\"{{!!item.nested}}\">\n            <ul>\n                <f-repeat value=\"{{person in item.nested}}\">\n                    <li>{{person.name}}</li>\n                </f-repeat>\n            </ul>\n        </f-when>\n    </div>\n</f-repeat>\n```\n\nCombined with state:\n```json\n{\n    \"items\": [\n        {\n            \"name\": \"Bob\"\n        },\n        {\n            \"name\": \"Alice\"\n        },\n        {\n            \"name\": \"Sue\",\n            \"nested\": [\n                {\n                    \"name\": \"Amy\"\n                },\n                {\n                    \"name\": \"Clarice\"\n                },\n                {\n                    \"name\": \"Lawrence\"\n                }\n            ]\n        }\n    ]\n}\n```\n\nShould result in:\n```html\n<!--fe:b-->\n    <!--fe:r-->\n    <div>\n        <span><!--fe:b-->Bob<!--fe:/b--></span>\n        <!--fe:b--><!--fe:/b-->\n    </div>\n    <!--fe:/r--><!--fe:r-->\n    <div>\n        <span><!--fe:b-->Alice<!--fe:/b--></span>\n        <!--fe:b--><!--fe:/b-->\n    </div>\n    <!--fe:/r--><!--fe:r-->\n    <div>\n        <span><!--fe:b-->Sue<!--fe:/b--></span>\n        <!--fe:b-->\n            <ul>\n                <!--fe:b-->\n                <!--fe:r-->\n                <li>\n                    <!--fe:b-->Amy<!--fe:/b-->\n                </li>\n                <!--fe:/r-->\n                <!--fe:r-->\n                <li>\n                    <!--fe:b-->Clarice<!--fe:/b-->\n                </li>\n                <!--fe:/r-->\n                <!--fe:r-->\n                <li>\n                    <!--fe:b-->Lawrence<!--fe:/b-->\n                </li>\n                <!--fe:/r-->\n                <!--fe:/b-->\n            </ul>\n        <!--fe:/b-->\n    </div>\n    <!--fe:/r-->\n<!--fe:/b-->\n```\n\n##### Nested components with `<slot>`\n\nThis example shows the wrapping custom element tag as well as the template component with `shadowrootmode=\"open\"` for the sake of illustrating an example that would exist in the DOM.\n\nExample template of component \"nested-component\":\n```html\n<f-when value=\"{{showButton}}\">\n    <my-button appearance=\"{{appearance}}\">{{text}}</my-button>\n</f-when>\n```\n\nExample template of component \"my-button\":\n```html\n<button class=\"{{appearance}}\">\n    <slot></slot>\n</button>\n```\n\nCombined with state:\n```json\n{\n    \"showButton\": true,\n    \"text\": \"Hello world\",\n    \"appearance\": \"fancy\"\n}\n```\n\nShould result in:\n```html\n<nested-components>\n    <template shadowrootmode=\"open\" shadowroot=\"open\">\n        <!--fe:b-->\n        <my-button data-fe=\"1\" appearance=\"fancy\">\n            <template shadowrootmode=\"open\" shadowroot=\"open\">\n                <button class=\"default\" data-fe=\"1\">\n                    <slot></slot>\n                </button>\n            </template>\n            <!--fe:b-->Hello world<!--fe:/b-->\n        </my-button>\n        <!--fe:/b-->\n    </template>\n</nested-components>\n```\n\n## Rendering Lifecycle\n\nFor information about the declarative rendering lifecycle inside\n`@microsoft/fast-element`, see\n[lifecycle.md](./lifecycle.md).\n\n<!-- File: packages/fast-element/docs/declarative/schema-observer-map.md (Tokens: ~3841 | Category: anthropic-skill) -->\n# Schema and Observer Map Architecture\n\nThis document provides a technical explainer for how the `Schema` and\n`ObserverMap` classes work together to describe data objects and automatically\nobserve them in FAST elements. Declarative `<f-template>` markup creates schemas\nautomatically, but the schema and observer map implementation are factored so\nthey can also be used without declarative templating.\n\n## Table of Contents\n\n1. [Overview](#overview)\n2. [The Schema Class](#the-schema-class)\n3. [The Observer Map Class](#the-observer-map-class)\n4. [Integration with f-template](#integration-with-f-template)\n5. [Initial Path Processing Flow](#initial-path-processing-flow)\n6. [Dynamic Path Processing Updates](#dynamic-path-processing-updates)\n7. [Observable Proxy System](#observable-proxy-system)\n8. [Examples](#examples)\n9. [Technical Details](#technical-details)\n\n## Overview\n\nThe Schema and Observer Map architecture enables automatic observation of complex nested data objects in FAST HTML templates. This system solves the problem of manually tracking all the binding paths used in declarative HTML templates, automatically creating observables for nested properties that are referenced in the template bindings.\n\n**Important**: This system is designed specifically for observable data objects (objects, arrays, and primitives). It explicitly does not handle binding paths that are assumed to be functions, methods, or other non-data constructs like event handlers.\n\n### Key Components\n\n- **Schema Class**: Generates JSON schemas that describe the structure and binding paths of data objects based on template analysis or manually registered paths\n- **Observer Map Class**: Uses the schema information to automatically define observable properties and create proxies for nested object observation\n- **f-template Integration**: Template processing automatically populates schemas and configures observer maps during template compilation\n- **Map helpers**: `@microsoft/fast-element` exposes the map helpers independently from declarative templating\n\n### Supported Data Types\n\nThe system automatically handles:\n- **Objects**: Nested object structures with observable properties\n- **Arrays**: Arrays with observable mutations and nested object elements  \n- **Primitives**: String, number, boolean values as object properties\n\n### Explicitly Not Handled\n\nThe system does not process:\n- **Function bindings**: Event handlers and method calls like `@click=\"{handleClick()}\"`\n- **Context paths**: Bindings using the `$c` prefix (e.g., `$c.parent.showNames`) resolve directly from the `ExecutionContext` and are not part of the data model\n- **Computed expressions**: Complex expressions that evaluate to non-data values\n- **Non-observable constructs**: Any binding assumed to reference functions or non-data objects\n\n## The Schema Class\n\nThe `Schema` class is responsible for building JSON Schema definitions that map the structure of data objects used in template bindings. It analyzes binding paths from template processing and constructs schemas that describe:\n\n- Root properties and their nested structures\n- Array contexts for repeat operations\n- Object property relationships\n- Cross-references to child components\n\n**Important**: Each schema created corresponds to a property that will belong to the custom element's class. The schema describes the expected structure and relationships of data that will be assigned to that property, enabling automatic observation of nested objects and arrays within that property's data structure.\n\n### Core Methods\n\n#### Constructor\n```typescript\nconstructor(name: string)\n```\nCreates a new schema instance for a specific custom element name and initializes an instance-level `schemaMap`. The instance also registers itself in the module-level `schemaRegistry` for cross-element `$ref` resolution. `FASTElementDefinition.schema` is optional; declarative templates assign it after parsing, while manual schema users can pass one in the element definition or directly to `observerMap({ schema })`.\n\n#### addPath\n```typescript\npublic addPath(config: RegisterPathConfig)\n```\nRegisters a binding path discovered during template processing. The configuration includes:\n- `pathConfig`: Describes the path type (`access`, `default`, `repeat`, `event`)\n- `rootPropertyName`: The root property this path belongs to\n- `childrenMap`: Information about child components referenced in this path\n\n**Note**: Only `access`, `default`, and `repeat` path types result in schema entries. Event paths are identified but not processed since they represent function calls rather than observable data.\n\n#### getSchema\n```typescript\npublic getSchema(rootPropertyName: string): JSONSchema | null\n```\nRetrieves the JSON schema for a specific root property.\n\n### Path Types\n\nThe schema handles different types of binding paths:\n\n- **`access`/`default`**: Direct property access like `{{user.name}}`\n- **`repeat`**: Array iteration contexts like `{{item}}` within `<f-repeat>`\n- **`event`**: Event handler bindings like `@click=\"{handleClick()}\"` - **Note: These are explicitly not processed by the schema system as they are assumed to be functions rather than observable data objects**\n\n### Schema Structure\n\nGenerated schemas follow JSON Schema format with FAST-specific extensions:\n\n```typescript\n{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://fast.design/schemas/my-element/users.json\",\n  \"type\": \"array\",\n  \"$ref\": \"#/$defs/user\",\n  \"$defs\": {\n    \"user\": {\n      \"$fast_context\": \"users\",\n      \"$fast_parent_contexts\": [null],\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {},\n        \"details\": {\n          \"type\": \"object\", \n          \"properties\": {\n            \"age\": {}\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n**Note on Property Types**: Properties accessed through binding paths (like `name` and `age` above) are defined with empty objects `{}` rather than specific JSON Schema types. This is because it's not possible to determine the exact primitive type (string, number, boolean, etc.) from the path syntax alone. The system focuses on structural relationships rather than specific data types for leaf properties.\n\n## The Observer Map Class\n\nThe `ObserverMap` class uses schema information to automatically configure observable properties on custom element prototypes. It creates the infrastructure needed to observe nested object changes without manual setup.\n\n### Constructor\n```typescript\nconstructor(classPrototype: any, schema: Schema, config?: ObserverMapConfig)\n```\nCreates an observer map instance that will configure the provided class prototype using the schema information.\n\n### defineProperties\n```typescript\npublic defineProperties(): void\n```\nThe main method that:\n1. Iterates through all root properties defined in the schema (each schema instance contains multiple root property schemas)\n2. Defines observable properties using FAST Element's `Observable.defineProperty` (an alternative to the `@observable` decorator syntax used in custom element classes)\n3. Sets up property change handlers that create proxies for nested objects\n\n### Property Change Handling\n\nWhen a root property transitions from `undefined` to a defined value, the observer map:\n1. Analyzes the schema to understand the expected object structure\n2. Creates proxies using the `assignObservables` utility function\n3. Establishes deep observation of nested properties based on the schema of that root property\n\n## Integration with f-template and manual schemas\n\nThe Schema and Observer Map classes integrate seamlessly with the f-template system, but they are not tied to it:\n\n### Template Processing Flow\n\n1. **Template Parsing**: When an `f-template` element is processed, it creates a `Schema` instance\n2. **Binding Discovery**: As template bindings are processed, paths are registered with `schema.addPath()`\n3. **Observer Map Creation**: If enabled, an `ObserverMap` is instantiated with the populated schema\n4. **Property Definition**: The observer map defines observable properties on the custom element prototype\n\n### Configuration\n\nObserver Map functionality is enabled through the `observerMap()` definition\nextension exported from `@microsoft/fast-element/observer-map.js`:\n\n```typescript\nimport { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nMyElement.define(\n  {\n    name: \"my-custom-element\",\n    template: declarativeTemplate(),\n  },\n  [observerMap()]\n);\n```\n\nWhen the `properties` key is omitted, all root properties discovered in the\ntemplate are observed. Add a `properties` object to opt into selective\nobservation behavior.\n\nFor non-declarative/manual schema use, pass the schema in the observer map\nconfiguration:\n\n```typescript\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-custom-element\");\nschema.addPath({\n  rootPropertyName: \"user\",\n  pathConfig: {\n    type: \"default\",\n    parentContext: null,\n    currentContext: null,\n    path: \"user.name\",\n  },\n  childrenMap: null,\n});\n\nMyElement.define(\n  {\n    name: \"my-custom-element\",\n  },\n  [observerMap({ schema })]\n);\n```\n\nYou can also attach a manual schema to the FAST element definition. This is the\npath used automatically by `declarativeTemplate()` after it parses a template:\n\n```typescript\nMyElement.define(\n  {\n    name: \"my-custom-element\",\n    schema,\n  },\n  [observerMap()]\n);\n```\n\n## Initial Path Processing Flow\n\nHere's how binding paths flow through the system during initial template processing:\n\n1. **Template Binding**: `{{user.details.personal.name}}`\n2. **Path Analysis**: Utilities identify root property (`user`) and nested path (`details.personal.name`)\n3. **Type Check**: Confirms this is a data binding (not an event handler like `@click=\"{handleClick()}\"`)\n4. **Schema Registration**: \n   ```typescript\n   schema.addPath({\n     pathConfig: {\n       type: \"access\",\n       currentContext: null,\n       parentContext: null,\n       path: \"user.details.personal.name\"\n     },\n     rootPropertyName: \"user\",\n     childrenMap: null\n   });\n   ```\n5. **Schema Building**: Creates nested object structure in JSON schema\n6. **Observable Definition**: Observer map makes `user` property observable\n7. **Proxy Creation**: When `user` is assigned, proxies are created for deep observation\n\n### Event Handler and Context Path Exclusion\n\nEvent handlers are identified but explicitly excluded from schema processing:\n- **Template Binding**: `@click=\"{handleClick()}\"`\n- **Path Analysis**: Utilities identify this as an event handler\n- **Type Check**: Confirms this is type `\"event\"`\n- **Schema Registration**: **Skipped** - Event handlers are not added to schemas since they represent function calls\n\nContext paths (`$c` prefix) are also excluded from schema processing:\n- **Template Binding**: `{{$c.parent.showNames}}` or `@click=\"{$c.parent.handleClick($c.event)}\"`\n- **Path Analysis**: Utilities detect the `$c.` prefix\n- **Schema Registration**: **Skipped** - These paths resolve from the `ExecutionContext`, not from observable data properties\n\n## Dynamic Path Processing Updates\n\nAfter initial schema creation and observer map setup, the system continues to dynamically update observation as data structures evolve:\n\n### Runtime Object Assignment\n\nWhen nested objects or array items become defined after initial setup:\n\n1. **Property Assignment**: A previously undefined nested property gets assigned a value\n   ```typescript\n   // Initially: user.details was undefined\n   user.details = { age: 30, location: { city: \"Seattle\" } };\n   ```\n\n2. **Schema Consultation**: The system consults the existing schema for this root property to understand expected nested structure\n\n3. **Proxy Creation**: New proxies are automatically created for the newly assigned nested objects based on the schema definition\n\n4. **Deep Observation Extension**: Observation is extended to all nested properties defined in the schema\n\n### Array Item Addition\n\nWhen new items are added to observed arrays:\n\n1. **Array Mutation**: Items are added via push, splice, or direct assignment\n   ```typescript\n   users.push({ name: \"John\", details: { age: 25 } });\n   ```\n\n2. **Array Observer Trigger**: The array proxy detects the mutation and triggers observation setup\n\n3. **Item Processing**: Each new array item is processed according to the array's context schema definition\n\n4. **Nested Object Proxying**: New nested objects within array items are automatically proxied based on the schema structure\n\n## Observable Proxy System\n\nThe proxy system in `utilities.ts` provides the deep observation capabilities:\n\n### assignObservables Function\n\n```typescript\nexport function assignObservables(\n    schema: JSONSchema | JSONSchemaDefinition,\n    rootSchema: JSONSchema,\n    data: any,\n    target: any,\n    rootProperty: string\n): typeof Proxy\n```\n\nThis function:\n- Analyzes the data type (object, array, primitive)\n- Creates proxies for objects and arrays\n- Establishes property observation for nested structures\n- Handles array mutations and object property changes\n\n### Proxy Behavior\n\nProxied objects:\n- Trigger Observable notifications when properties change\n- Automatically proxy newly assigned nested objects\n- Track array mutations and splice operations\n- Maintain references to root properties for change notifications\n\n## Examples\n\n### Basic Object Observation\n\n**Template:**\n```html\n<f-template name=\"user-profile\">\n  <template>\n    <div>{{user.name}} - {{user.details.age}} years old</div>\n    <div>Location: {{user.details.location.city}}</div>\n  </template>\n</f-template>\n```\n\n**Generated Schema Structure:**\n```typescript\n// Root property: \"user\"\n{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://fast.design/schemas/user-profile/user.json\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"name\": {},\n    \"details\": {\n      \"type\": \"object\",\n      \"properties\": {\n        \"age\": {},\n        \"location\": {\n          \"type\": \"object\",\n          \"properties\": {\n            \"city\": {}\n          }\n        }\n      }\n    }\n  }\n}\n```\n\n### Array with Repeat Context\n\n**Template:**\n```html\n<f-template name=\"user-list\">\n  <template>\n    <f-repeat value=\"{{user in users}}\">\n      <div>{{user.name}} has {{user.posts.length}} posts</div>\n    </f-repeat>\n  </template>\n</f-template>\n```\n\n**Generated Schema Structure:**\n```typescript\n// Root property: \"users\"\n{\n  \"$schema\": \"https://json-schema.org/draft/2019-09/schema\",\n  \"$id\": \"https://fast.design/schemas/user-list/users.json\",\n  \"type\": \"array\",\n  \"$ref\": \"#/$defs/user\",\n  \"$defs\": {\n    \"user\": {\n      \"$fast_context\": \"users\",\n      \"$fast_parent_contexts\": [null],\n      \"type\": \"object\",\n      \"properties\": {\n        \"name\": {},\n        \"posts\": {\n          \"type\": \"array\"\n        }\n      }\n    }\n  }\n}\n```\n\n### Nested Repeat Contexts\n\n**Template:**\n```html\n<f-template name=\"complex-data\">\n  <template>\n    <f-repeat value=\"{{user in users}}\">\n      <div>{{user.name}}</div>\n      <f-repeat value=\"{{post in user.posts}}\">\n        <div>{{post.title}} - {{post.metadata.views}} views</div>\n      </f-repeat>\n    </f-repeat>\n  </template>\n</f-template>\n```\n\nThis creates nested context definitions where the `post` context understands its relationship to the parent `user` context.\n\n## Technical Details\n\n### Schema Registry\n\nThe `Schema` module exports a module-level `schemaRegistry`:\n```typescript\nexport const schemaRegistry: CachedPathMap = new Map();\n```\n\nEach `Schema` instance owns an instance-level `schemaMap: Map<string, JSONSchema>` and registers itself in `schemaRegistry` on construction.\n\nThe registry structure is: `Map<customElementName, Map<rootPropertyName, JSONSchema>>`\n\n**Rationale for Module-level Registry**: The registry allows cross-element `$ref` resolution for nested components inside f-templates. When an object or array is passed to another custom element within an f-template, that nested component needs to observe the entire root property's structure based on the binding paths within that nested component. The registry allows all components to access and contribute to the same schema definitions, ensuring consistent observation behavior across component boundaries.\n\n### Context Tracking\n\nThe schema system tracks binding contexts using special metadata:\n- `$fast_context`: The array property name that created this context\n- `$fast_parent_contexts`: Chain of parent contexts leading to the root\n\n### Performance Considerations\n\n- **Lazy Proxy Creation**: Proxies are only created when objects are assigned to observable properties\n- **Weak Map Caching**: The system uses WeakMaps to avoid memory leaks when tracking proxied objects\n- **Schema Reuse**: Schemas are generated once per custom element and reused across instances\n\n### Memory Management\n\n- **WeakMap Usage**: `objectTargetsMap` and `observedArraysMap` use WeakMaps to automatically clean up references\n- **Proxy Identification**: Proxies are marked with `$isProxy` to prevent double-proxying\n- **Reference Tracking**: Target elements and root properties are tracked for proper change notification\n\n## Debugging and Troubleshooting\n\n### Schema Inspection\n\nYou can inspect generated schemas using the module-level `schemaRegistry` import:\n\n```typescript\nimport { schemaRegistry } from \"@microsoft/fast-element\";\n\n// Get all schemas for an element:\nconst elementSchemas = schemaRegistry.get('my-element');\nconst userSchema = elementSchemas?.get('users');\nconsole.log(JSON.stringify(userSchema, null, 2));\n```\n\n### Observer Map Status\n\n`observerMap()` is applied as a definition extension before the element is\nregistered. There is no public `TemplateElement.options()` state to inspect.\nTo verify that observer mapping ran, inspect the generated schema and the\nobservable accessors on the element prototype:\n\n```typescript\nimport { Observable, schemaRegistry } from \"@microsoft/fast-element\";\n\nconst schemas = schemaRegistry.get(\"my-element\");\nconst accessors = Observable.getAccessors(MyElement.prototype).map(a => a.name);\nconsole.log(schemas, accessors);\n```\n\n### Proxy Detection\n\nObjects processed by the system will have a `$isProxy` property:\n```typescript\nconsole.log('Is proxied:', myObject.$isProxy === true);\n```\n\n<!-- File: packages/fast-element/docs/declarative/syntax.md (Tokens: ~4324 | Category: anthropic-skill) -->\n# FAST Element Declarative HTML\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![npm version](https://badge.fury.io/js/%40microsoft%2Ffast-element.svg)](https://badge.fury.io/js/%40microsoft%2Ffast-element)\n\nThe declarative entrypoint in `@microsoft/fast-element` interprets FAST\ndeclarative HTML syntax as a template for a FAST web component.\n\nThis document focuses on declarative-runtime implementation details:\ntemplate structure, prerendered markup requirements, hydration promise APIs,\nbinding configuration, syntax, and integration testing.\n\nFor package installation, using `declarativeTemplate()`, extension setup, and\nthe package-level hydration overview, see the\n[FAST Element README](../../README.md#declarative-html) and\n[Prerendered Content Optimization](../../README.md#prerendered-content-optimization).\nFor user-facing guides covering f-template syntax, element definition, and\nserver-side rendering, see the\n[Declarative HTML docs](https://fast.design/docs/3.x/declarative-templates/overview/).\n\n## Template Structure\n\nAfter importing the declarative APIs as shown in the README, templates are\nassociated with an element through\n`<f-template name=\"[custom-element-name]\"><template>...</template></f-template>`.\nThe host custom element should be defined with\n`template: declarativeTemplate()`. This automatically defines `<f-template>` in\nthe relevant registry and waits for the matching declarative template when it is\nalready present or inserted later.\n\nThe `@microsoft/fast-element` entrypoint itself remains\nside-effect free at import time. Declarative APIs lazily install declarative\ndebug messages when they create templates. Hydratable `ViewTemplate` support is\ninstalled only when `enableHydration()` is called from\n`@microsoft/fast-element/hydration.js`.\n\n`observerMap()` and `attributeMap()` are available from\n`@microsoft/fast-element/observer-map.js` and\n`@microsoft/fast-element/attribute-map.js`, including when using the maps\nwithout declarative templates.\n\nExample:\n```html\n<my-custom-element greeting=\"Hello world\">\n    <template shadowrootmode=\"open\">\n        Hello world\n    </template>\n</my-custom-element>\n<f-template name=\"my-custom-element\">\n    <template>{{greeting}}</template>\n</f-template>\n```\n\nThe legacy `defer-hydration` and `needs-hydration` attributes are no longer\nrequired.\n\n## HTML Comments\n\nBindings and FAST directive markup inside HTML comments are unsupported. This\nincludes double-brace and triple-brace bindings, client-only bindings, and\ncommented-out elements containing bindings or directives.\n\nThe declarative parsers scan template strings and do not reliably exclude\ncomments. A comment such as `<!-- {{greeting}} -->` can still contribute a binding,\nleading to unexpected evaluation, rendering errors, or hydration mismatches.\nRemove unused bound markup rather than commenting it out, and keep explanatory\ncomments free of binding syntax and FAST directive tags.\n\n## Non-browser HTML Rendering\n\nOne of the benefits of FAST declarative HTML templates is that the server can\nbe stack agnostic because JavaScript does not need to be interpreted to emit\nthe initial HTML. This does not mean the FAST Element client runtime runs on the\nserver: custom element definition, hydration, client rendering, and reactive\nupdates still run in the browser `Window`. The declarative runtime expects\nhydratable comment markers and datasets when prerendered content is generated.\nFor the required marker format and initial-state application details, see\n[rendering.md](./rendering.md).\n\n## Hydration promise APIs\n\nFAST Element's declarative APIs expose hydration readiness promises that are\nuseful to application code.\n\nHydration is opt-in. Call `enableHydration()` before FAST elements connect when\nyou want prerendered Declarative Shadow DOM to be reused, then await\nthe returned controller's `whenHydrated()` promise when code needs to run after\nthe active hydration batch:\n\n```typescript\nimport { enableHydration } from \"@microsoft/fast-element/hydration.js\";\n\nconst hydration = enableHydration();\nawait hydration.whenHydrated();\n```\n\nThe hydration hook no-ops for new prerendered elements after the initial\nhydration batch completes by default. Streaming scenarios that append hydratable\nDeclarative Shadow DOM later can keep the hook active:\n\n```typescript\nimport { enableHydration, StopHydration } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({\n    stopHydration: StopHydration.never,\n});\n```\n\nWhen `StopHydration.never` is used, `enableHydration().whenHydrated()`\nintentionally remains pending because hydration has no global completion point.\n\nFAST Element 3.x data-free hydration markers are selected by default. Existing\nserver output that uses FAST Element 2.x indexed markers can be hydrated by\nselecting the v2 marker reader:\n\n```typescript\nimport { enableHydration, markers_v2 } from \"@microsoft/fast-element/hydration.js\";\n\nenableHydration({ markers: markers_v2 });\n```\n\nSet `\"markers_v2\": true` in the matching `@microsoft/fast-build`\nconfiguration so the generated HTML uses the same marker format.\n\n## `observerMap`\n\nWhen the `observerMap()` extension is applied to an element definition,\nit automatically sets up deep reactive observation for root properties\ndiscovered in the template. Declarative templates assign `definition.schema`\nduring template resolution, so `observerMap()` has schema data automatically.\nFor non-declarative/manual schemas, import from\n`@microsoft/fast-element/observer-map.js` and pass `observerMap({ schema })`.\n\n```typescript\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n```\n\nFor finer control, pass a configuration object with a `properties` key that maps root property names to a recursive path tree:\n\n```typescript\nUserProfile.define(\n    {\n        name: \"user-profile\",\n        template: declarativeTemplate(),\n    },\n    [\n        observerMap({\n            properties: {\n                user: {\n                    name: true,          // user.name — observed\n                    details: {\n                        age: true,       // user.details.age — observed\n                        history: false,  // user.details.history — NOT observed\n                    },\n                },\n                // root properties not listed here are skipped\n            },\n        }),\n    ],\n);\n```\n\nEach path entry can be:\n- **`true`** — observe this path and all descendants.\n- **`false`** — skip this path and all descendants.\n- **An object** with an optional `$observe` boolean and child property overrides.\n\nUse `$observe: false` on a node to skip it by default, then re-include specific children:\n\n```typescript\nobserverMap({\n    properties: {\n        analytics: {\n            charts: {\n                $observe: false,       // charts NOT observed by default\n                activeChart: true,     // ...except activeChart IS observed\n            },\n        },\n    },\n});\n```\n\nWhen `properties` is omitted, all root properties are observed. When\n`properties` is present but empty (`{ properties: {} }`), no root properties\nare observed.\n\nWhen observer-map data is updated with `deepMerge`, array properties are replaced\nrather than updated in place. This avoids synchronous reentrant array work and\nallows repeat bindings to observe the new array reference. Replacement arrays\nare processed through observerMap so nested item properties and subsequent array\nmutations remain observable.\n\nManual schema example:\n\n```typescript\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-element\");\nschema.addPath({\n    rootPropertyName: \"user\",\n    pathConfig: {\n        type: \"default\",\n        parentContext: null,\n        currentContext: null,\n        path: \"user.name\",\n    },\n    childrenMap: null,\n});\n\nMyElement.define({ name: \"my-element\" }, [observerMap({ schema })]);\n```\n\n## `attributeMap`\n\nWhen the `attributeMap()` extension is applied to an element definition,\nit automatically creates reactive `@attr` properties for every **leaf binding**\nin the template — simple expressions like `{{foo}}` or `id=\"{{fooBar}}\"` that\nhave no nested properties. Declarative templates provide the schema\nautomatically. For non-declarative/manual schemas, place the optional `schema`\non the FAST element definition and import `attributeMap()` from\n`@microsoft/fast-element`.\n\n```typescript\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\n```\n\nBy default, the binding key is treated as a camelCase property name and the HTML\nattribute name is derived by converting it to kebab-case. Properties already\ndecorated with `@attr` or `@observable` on the class are left untouched.\n\n```typescript\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [attributeMap()],\n);\n```\n\nWith the template:\n\n```html\n<f-template name=\"my-element\">\n    <template>\n        <p>{{greeting}}</p>\n        <p>{{firstName}}</p>\n    </template>\n</f-template>\n```\n\nThis registers `greeting` (attribute `greeting`, property `greeting`) and\n`firstName` (attribute `first-name`, property `firstName`) as `@attr`\nproperties on the element prototype, enabling `setAttribute(\"first-name\",\n\"Jane\")` to trigger a template re-render automatically.\n\n### `attribute-name-strategy`\n\nThe `attribute-name-strategy` configuration option controls how template binding\nkeys map to HTML attribute names. This matches the build-time\n`--attribute-name-strategy` option in `@microsoft/fast-build`.\n\n| Strategy | Behaviour | Example |\n|---|---|---|\n| `\"camelCase\"` (default) | Binding key is the camelCase property; attribute name is derived as kebab-case | `{{fooBar}}` → property `fooBar`, attribute `foo-bar` |\n| `\"none\"` | Binding key used as-is for both property and attribute | `{{foo-bar}}` → property `foo-bar`, attribute `foo-bar` |\n\n```typescript\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [\n        attributeMap({\n            \"attribute-name-strategy\": \"none\",\n        }),\n    ],\n);\n```\n\nWhen using the `\"none\"` strategy, property names may contain dashes and must be\naccessed via bracket notation (e.g. `element[\"foo-bar\"]`).\n\n## Syntax\n\nAll bindings use a handlebars-like syntax.\n\nSome bindings are only relevant to the browser, such as for click handlers or other pieces of dynamic interaction. As such, their bindings use single curly braces `{}`, this is to prevent an intial SSR (Server Side Rendering) or other build time rendering technologies from needing to interpret them.\n\nIf a binding is relevant to both client and the back end rendering engine, it will use `{{}}` or `{{{}}}` depending on what type of data injection is being done.\n\nBrowser-only bindings:\n- Event bindings\n- Attribute directives\n\n### Content binding\n\n```html\n{{text}}\n```\n\n### Event binding\n\nEvent bindings must include the `()` as well as being preceeded by `@` in keeping with the `@microsoft/fast-element` tagged template syntax.\n\n```html\n<button @click=\"{handleClick()}\"></button>\n```\n\nYou can pass the DOM event object, the execution context, or both as arguments. Any other argument is treated as a binding expression and resolved against the current data source.\n\n**`$e` — DOM event object (preferred):**\n```html\n<button @click=\"{handleClick($e)}\"></button>\n```\n\n**`$c` — execution context:**\n```html\n<button @click=\"{handleClick($c)}\"></button>\n```\n\n**`$c.somePath` — a property of the execution context (e.g. `$c.parent`, `$c.event`):**\n```html\n<button @click=\"{handleClick($c.parent)}\"></button>\n```\n\n**Multiple arguments:**\n```html\n<button @click=\"{handleClick($e, $c)}\"></button>\n```\n\n**Arbitrary binding expressions** — any token that is not `$e` or `$c` is resolved as a binding path on the data source:\n```html\n<button @click=\"{handleClick(user.id)}\"></button>\n```\n\nUse `$e` for the DOM event object.\n\n### Directives\n\nDirectives are assumed to be either an attribute directive or a directive that also serves a template. Both are prepended by `f-`. The logic of these directives and what their use cases are is explained in the [FAST html documentation](https://fast.design/docs/getting-started/html-directives).\n\nAttribute directives are part of [client side binding](#syntax) and therefore use the `{}` syntax.\n\nAttribute directives include:\n- **slotted**\n\n    Example:\n    ```html\n    <slot f-slotted=\"{slottedNodes}\"></slot>\n    <slot f-slotted=\"{slottedNodes filter elements()}\"></slot>\n    <slot f-slotted=\"{slottedNodes filter elements(div, p)}\"></slot>\n    ```\n\n- **children**\n\n    Example:\n    ```html\n    <ul f-children=\"{listItems}\"><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    <ul f-children=\"{listItems filter elements()}\"><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    <ul f-children=\"{listItems filter elements(li)}\"><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    ```\n\n- **ref**\n\n    Example:\n    ```html\n    <video f-ref=\"{video}\"></video>\n    ```\n\nTemplate directives include:\n- **when**\n\n    Example:\n    ```html\n    <f-when value=\"{{show}}\">Hello world</f-when>\n    <f-when value=\"{{!show}}\">Goodbye world</f-when>\n    ```\n\nThe following operators can also be used:\n- `==`\n- `!=`\n- `>=`\n- `>`\n- `<=`\n- `<`\n- `||`\n- `&&`\n\nWhere the right operand can be either a reference to a value (string e.g. `{{foo == 'bar'}}`, boolean e.g. `{{foo == true}}`, number e.g. `{{foo == 3}}`) or another binding value.\n\n- **repeat**\n\n    Example:\n    ```html\n    <ul><f-repeat value=\"{{item in list}}\"><li>{{item}}</li></f-repeat></ul>\n    ```\n\n    Bindings inside `<f-repeat>` without a context prefix resolve to the custom element. For example, `{{title}}` below resolves to the host element's `title` property:\n\n    ```html\n    <ul><f-repeat value=\"{{item in list}}\"><li>{{item}} - {{title}}</li></f-repeat></ul>\n    ```\n\n### Execution Context Access\n\nIn imperative fast-element templates, every binding expression receives both the data source and the execution context: `${(x, c) => c.parent.handleClick(c.event)}`. Declarative `<f-template>` expressions can access the same execution context using the `$c` prefix.\n\nThis is particularly useful inside `<f-repeat>`, where `$c.parent` refers to the parent view-model (typically the host element) and `$c.event` provides the DOM event.\n\nEvent handler with context access:\n\n```html\n<f-repeat value=\"{{item in items}}\">\n    <button @click=\"{$c.parent.handleItemClick($c.event)}\">{{item.name}}</button>\n</f-repeat>\n```\n\nConditional rendering using a host property inside a repeat:\n\n```html\n<f-repeat value=\"{{item in items}}\">\n    <f-when value=\"{{$c.parent.showNames}}\">\n        <span>{{item.name}}</span>\n    </f-when>\n</f-repeat>\n```\n\n### Unescaped HTML\n\nYou can add unescaped HTML using triple braces, this will create an additional `div` element as the HTML needs an element to bind to. Where possible it is advisable to not use unescaped HTML and instead use other binding techniques.\n\nExample:\n```html\n{{{html}}}\n```\n\n### Code samples inside `<code>`\n\nAny text or attribute value inside a `<code>` element has its `{` and `}` characters automatically replaced with the HTML numeric character references `&#123;` and `&#125;` before template parsing. As a result, binding delimiters (`{{...}}`, `{{{...}}}`, `{...}`) inside `<code>` are rendered as literal text rather than being interpreted as FAST bindings — making `<code>` blocks safe for embedding code samples that contain binding-like syntax. No marker attribute is needed.\n\nIn addition, the build-time renderer (`@microsoft/fast-build`) entity-escapes the `<` and `>` of every **FAST directive tag** (`<f-when>`, `</f-when>`, `<f-repeat>`, `</f-repeat>`) it finds inside `<code>`, so authors can write the directive literally without manually entity-encoding the angle brackets. Tag-name matching is case-insensitive. Non-directive elements inside `<code>` — real HTML elements such as `<button>` and custom elements such as `<my-widget>` — keep their angle brackets and continue to render as live DOM elements; only brace-binding syntax in their attribute values is neutralised.\n\nThe brace escape is applied symmetrically by both the server-side renderer and the client-side `<f-template>` parser, so binding positions stay in sync between SSR and hydration. The directive-tag angle escape only needs to run on the server: the DOM serializer re-encodes `<`/`>` in text content, so the client-side parser never sees a raw `<f-when>` inside `<code>` regardless of what the page source contained. This behaviour mirrors how Microsoft WebUI's `webui-press` markdown renderer transparently escapes the same characters inside code spans and code fences.\n\nExample:\n```html\n<f-template name=\"docs-page\">\n    <template>\n        <h1>{{title}}</h1>\n        <pre><code>span {{greeting}} /span</code></pre>\n        <pre><code><f-when value=\"{{flag}}\">wrapped</f-when></code></pre>\n        <pre><code>Try: <button class=\"demo\">click</button></code></pre>\n    </template>\n</f-template>\n```\n\nThe `<h1>` binds to `title`, the first `<code>` displays the literal text `span {{greeting}} /span`, the second displays the literal text `<f-when value=\"{{flag}}\">wrapped</f-when>`, and the third renders a live `<button>` element alongside the surrounding sample text.\n\n## Writing Components\n\nWhen writing components with the intention of using the declarative HTML syntax, it is imperative that components are written with styling and rendering of the component to be less reliant on any JavaScript state management. An example of this is relying on `elementInterals` state to style a component.\n\n## WebUI Integration Testing\n\nThe fixture tests in `test/declarative/fixtures/` are also validated against\n[`@microsoft/webui`](https://github.com/microsoft/webui) to ensure\ncross-renderer compatibility. The build step renders each fixture's templates\nwith `webui build --plugin=fast`, then the existing Playwright specs run\nagainst the webui-rendered output.\n\n```shell\n# Build fixtures with webui and run Playwright tests\nnpm run test:webui-integration -w @microsoft/fast-element\n\n# Or run the steps separately\nnpm run build:fixtures:webui -w @microsoft/fast-element\nnpm exec -w @microsoft/fast-element -- playwright test --config=playwright.declarative.webui.config.ts\n```\n\nThis is also run automatically in CI via the `ci-webui-integration.yml` GitHub Action on pull requests and pushes to `main`.\n\nSome tests are conditionally skipped during webui integration runs due to known\nrendering differences between `fast-build` and `webui`. The\n`playwright.declarative.webui.config.ts` file sets\n`FAST_WEBUI_INTEGRATION=true`, and affected tests use `test.skip()` with a\ndescriptive reason. See the WebUI Integration Tests section in\n[design.md](./design.md) for the full list.\n\n<!-- File: packages/fast-element/docs/di/api-report.api.md (Tokens: ~2835 | Category: anthropic-skill) -->\n## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport const all: (key: any, searchAncestors?: boolean) => ReturnType<typeof DI.inject>;\n\n// @public\nexport type AsyncRegistrationLocator = (key: Key) => Promise<Registration | null>;\n\n// @public\nexport interface Container extends ServiceLocator {\n    createChild(config?: Partial<Omit<ContainerConfiguration, \"parentLocator\">>): Container;\n    getFactory<T extends Constructable>(key: T): Factory<T>;\n    getResolver<K extends Key, T = K>(key: K | Key, autoRegister?: boolean): Resolver<T> | null;\n    register(...params: any[]): Container;\n    // Warning: (ae-forgotten-export) The symbol \"Constructable\" needs to be exported by the entry point di.d.ts\n    registerFactory<T extends Constructable>(key: T, factory: Factory<T>): void;\n    registerResolver<K extends Key, T = K>(key: K, resolver: Resolver<T>): Resolver<T>;\n    registerTransformer<K extends Key, T = K>(key: K, transformer: Transformer_2<T>): boolean;\n}\n\n// Warning: (ae-forgotten-export) The symbol \"ContextDecorator\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport const Container: ContextDecorator<Container>;\n\n// @public\nexport interface ContainerConfiguration {\n    asyncRegistrationLocator: AsyncRegistrationLocator;\n    defaultResolver(key: Key, handler: Container): Resolver;\n    parentLocator: ParentLocator;\n    responsibleForOwnerRequests: boolean;\n}\n\n// @public\nexport const ContainerConfiguration: Readonly<{\n    default: Readonly<ContainerConfiguration>;\n}>;\n\n// Warning: (ae-internal-missing-underscore) The name \"ContainerImpl\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport class ContainerImpl implements DOMContainer {\n    constructor(owner: any, config: ContainerConfiguration);\n    // (undocumented)\n    protected config: ContainerConfiguration;\n    // (undocumented)\n    createChild(config?: Partial<Omit<ContainerConfiguration, \"parentLocator\">>): Container;\n    // (undocumented)\n    get depth(): number;\n    // (undocumented)\n    get<K extends Key>(key: K): Resolved<K>;\n    // (undocumented)\n    getAll<K extends Key>(key: K, searchAncestors?: boolean): readonly Resolved<K>[];\n    // (undocumented)\n    getAsync<K extends Key>(key: K): Promise<Resolved<K>>;\n    // (undocumented)\n    getFactory<K extends Constructable>(Type: K): Factory<K>;\n    // (undocumented)\n    getResolver<K extends Key, T = K>(key: K | Key, autoRegister?: boolean): Resolver<T> | null;\n    // (undocumented)\n    handleContextRequests(enable: boolean): void;\n    // (undocumented)\n    has<K extends Key>(key: K, searchAncestors?: boolean): boolean;\n    // (undocumented)\n    protected owner: any;\n    // (undocumented)\n    get parent(): ContainerImpl | null;\n    // (undocumented)\n    register(...params: any[]): Container;\n    // (undocumented)\n    registerFactory<K extends Constructable>(key: K, factory: Factory<K>): void;\n    // (undocumented)\n    registerResolver<K extends Key, T = K>(key: K, resolver: Resolver<T>): Resolver<T>;\n    // (undocumented)\n    registerTransformer<K extends Key, T = K>(key: K, transformer: Transformer_2<T>): boolean;\n    // (undocumented)\n    get responsibleForOwnerRequests(): boolean;\n}\n\n// @public\nexport const DefaultResolver: Readonly<{\n    none(key: Key): Resolver;\n    singleton(key: Key): Resolver;\n    transient(key: Key): Resolver;\n}>;\n\n// @public\nexport const DI: Readonly<{\n    installAsContextRequestStrategy(fallback?: () => DOMContainer): void;\n    createContainer(config?: Partial<ContainerConfiguration>): Container;\n    findResponsibleContainer(target: EventTarget, fallback?: () => DOMContainer): DOMContainer;\n    findParentContainer(target: EventTarget, fallback?: () => DOMContainer): DOMContainer;\n    getOrCreateDOMContainer(target?: EventTarget, config?: Partial<Omit<ContainerConfiguration, \"parentLocator\">>): DOMContainer;\n    getDependencies(Type: Constructable | Injectable): Key[];\n    defineProperty(target: {}, propertyName: string, key: Key, respectConnection?: boolean): void;\n    createContext: typeof createContext;\n    inject(...dependencies: Key[]): (target: any, key?: string | number, descriptor?: PropertyDescriptor | number) => void;\n    transient<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;\n    singleton<T extends Constructable>(target: T & Partial<RegisterSelf<T>>, options?: SingletonOptions): T & RegisterSelf<T>;\n}>;\n\n// @public\nexport interface DOMContainer extends Container {\n    // @beta\n    handleContextRequests(enable: boolean): void;\n}\n\n// @public\nexport const DOMContainer: ContextDecorator<DOMContainer>;\n\n// @public\nexport interface Factory<T extends Constructable = any> {\n    construct(container: Container, dynamicDependencies?: Key[]): Resolved<T>;\n    constructAsync(container: Container, dynamicDependencies?: Key[]): Promise<Resolved<T>>;\n    registerTransformer(transformer: Transformer_2<T>): void;\n    readonly Type: T;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"FactoryImpl\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport class FactoryImpl<T extends Constructable = any> implements Factory<T> {\n    constructor(Type: T, dependencies: Key[]);\n    // (undocumented)\n    construct(container: Container, dynamicDependencies?: Key[]): Resolved<T>;\n    // (undocumented)\n    constructAsync(container: Container, dynamicDependencies?: Key[]): Promise<Resolved<T>>;\n    // (undocumented)\n    registerTransformer(transformer: (instance: any) => any): void;\n    // (undocumented)\n    Type: T;\n}\n\n// @public\nexport function ignore(target: Injectable, property?: string | number, descriptor?: PropertyDescriptor | number): void;\n\n// @public\nexport const inject: (...dependencies: Key[]) => (target: any, key?: string | number, descriptor?: PropertyDescriptor | number) => void;\n\n// @public\nexport type Injectable<T = {}> = Constructable<T> & {\n    inject?: Key[];\n};\n\n// @public\nexport interface InterfaceConfiguration {\n    friendlyName?: string;\n    respectConnection?: boolean;\n}\n\n// @public\nexport type Key = PropertyKey | object | ContextDecorator | Constructable | Resolver;\n\n// @public\nexport const lazy: (key: any) => any;\n\n// @public\nexport const newInstanceForScope: (key: any) => any;\n\n// @public\nexport const newInstanceOf: (key: any) => any;\n\n// @public\nexport const optional: (key: any) => any;\n\n// @public\nexport type ParentLocator = (owner: any) => Container | null;\n\n// @public\nexport type RegisterSelf<T extends Constructable> = {\n    register(container: Container): Resolver<InstanceType<T>>;\n    registerInRequestor: boolean;\n};\n\n// @public\nexport interface Registration<K = any> {\n    register(container: Container): Resolver<K>;\n}\n\n// @public\nexport const Registration: Readonly<{\n    instance<T>(key: Key, value: T): Registration<T>;\n    singleton<T extends Constructable>(key: Key, value: T): Registration<InstanceType<T>>;\n    transient<T extends Constructable>(key: Key, value: T): Registration<InstanceType<T>>;\n    callback<T>(key: Key, callback: ResolveCallback<T>): Registration<Resolved<T>>;\n    cachedCallback<T>(key: Key, callback: ResolveCallback<T>): Registration<Resolved<T>>;\n    aliasTo<T>(originalKey: T, aliasKey: Key): Registration<Resolved<T>>;\n}>;\n\n// @public\nexport interface Registry {\n    register(container: Container, ...params: unknown[]): void | Resolver;\n}\n\n// @public\nexport type ResolveCallback<T = any> = (handler: Container, requestor: Container, resolver: Resolver<T>) => T;\n\n// Warning: (ae-forgotten-export) The symbol \"ResolverLike\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport type Resolved<K> = K extends ContextDecorator<infer T> ? T : K extends Constructable ? InstanceType<K> : K extends ResolverLike<any, infer T1> ? T1 extends Constructable ? InstanceType<T1> : T1 : K;\n\n// @public\nexport interface Resolver<K = any> extends ResolverLike<Container, K> {\n}\n\n// @public\nexport class ResolverBuilder<K> {\n    constructor(container: Container, key: Key);\n    aliasTo(destinationKey: Key): Resolver<K>;\n    cachedCallback(value: ResolveCallback<K>): Resolver<K>;\n    callback(value: ResolveCallback<K>): Resolver<K>;\n    instance(value: K): Resolver<K>;\n    singleton(value: Constructable): Resolver<K>;\n    transient(value: Constructable): Resolver<K>;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"ResolverImpl\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport class ResolverImpl implements Resolver, Registration {\n    // (undocumented)\n    get $isResolver(): true;\n    constructor(key: Key, strategy: ResolverStrategy, state: any);\n    // (undocumented)\n    getFactory(container: Container): Factory | null;\n    // (undocumented)\n    key: Key;\n    // (undocumented)\n    register(container: Container): Resolver;\n    // (undocumented)\n    resolve(handler: Container, requestor: Container): any;\n    // (undocumented)\n    resolveAsync(handler: Container, requestor: Container): Promise<any>;\n    // (undocumented)\n    state: any;\n    // (undocumented)\n    strategy: ResolverStrategy;\n}\n\n// Warning: (ae-internal-missing-underscore) The name \"ResolverStrategy\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport const enum ResolverStrategy {\n    // (undocumented)\n    alias = 5,\n    // (undocumented)\n    array = 4,\n    // (undocumented)\n    callback = 3,\n    // (undocumented)\n    instance = 0,\n    // (undocumented)\n    singleton = 1,\n    // (undocumented)\n    transient = 2\n}\n\n// @public\nexport interface ServiceLocator {\n    get<K extends Key>(key: K): Resolved<K>;\n    get<K extends Key>(key: Key): Resolved<K>;\n    get<K extends Key>(key: K | Key): Resolved<K>;\n    getAll<K extends Key>(key: K, searchAncestors?: boolean): readonly Resolved<K>[];\n    getAll<K extends Key>(key: Key, searchAncestors?: boolean): readonly Resolved<K>[];\n    getAll<K extends Key>(key: K | Key, searchAncestors?: boolean): readonly Resolved<K>[];\n    getAsync<K extends Key>(key: K): Promise<Resolved<K>>;\n    getAsync<K extends Key>(key: Key): Promise<Resolved<K>>;\n    getAsync<K extends Key>(key: K | Key): Promise<Resolved<K>>;\n    has<K extends Key>(key: K | Key, searchAncestors: boolean): boolean;\n}\n\n// @public\nexport const ServiceLocator: ContextDecorator<ServiceLocator>;\n\n// Warning: (ae-forgotten-export) The symbol \"singletonDecorator\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport function singleton<T extends Constructable>(): typeof singletonDecorator;\n\n// @public (undocumented)\nexport function singleton<T extends Constructable>(options?: SingletonOptions): typeof singletonDecorator;\n\n// @public\nexport function singleton<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;\n\n// @public\ntype Transformer_2<K> = (instance: Resolved<K>) => Resolved<K>;\nexport { Transformer_2 as Transformer }\n\n// Warning: (ae-forgotten-export) The symbol \"transientDecorator\" needs to be exported by the entry point di.d.ts\n//\n// @public\nexport function transient<T extends Constructable>(): typeof transientDecorator;\n\n// @public\nexport function transient<T extends Constructable>(target: T & Partial<RegisterSelf<T>>): T & RegisterSelf<T>;\n\n// Warning: (ae-internal-missing-underscore) The name \"validateKey\" should be prefixed with an underscore because the declaration is marked as @internal\n//\n// @internal (undocumented)\nexport function validateKey(key: any): void;\n\n// Warnings were encountered during analysis:\n//\n// dist/dts/di/di.d.ts:479:5 - (ae-forgotten-export) The symbol \"createContext\" needs to be exported by the entry point di.d.ts\n// dist/dts/di/di.d.ts:540:5 - (ae-forgotten-export) The symbol \"SingletonOptions\" needs to be exported by the entry point di.d.ts\n\n// (No @packageDocumentation comment for this package)\n\n```\n\n<!-- File: packages/fast-element/docs/migration/fast-element-2.md (Tokens: ~608 | Category: anthropic-skill) -->\n# Changes in FASTElement 2.0\n\n## Breaking Changes\n\n* `HTMLDirective` - The `targetIndex: number` property has been replaced by a `targetId: string` property. The `createBehavior` method no longer takes a target `Node` but instead takes a `BehaviorTargets` instance. The actual target can be looked up on the `BehaviorTargets` instance by indexing with the `targetId` property.\n* `compileTemplate()` - Internals have been significantly changed. The implementation no longer uses a TreeWalker. The return type has change to an `HTMLTemplateCompilationResult` with different properties.\n* `View` and `HTMLView` - Type parameters added to enable strongly typed views based on their data source. The constructor of `HTMLView` has a new signature based on changes to the compiler's output. Internals have been cleaned up and no longer rely on the Range type.\n* `ElementViewTemplate`, `SyntheticViewTemplate`, and `ViewTemplate` - Added type parameters throughout. Logic to instantiate and apply behaviors moved out of the template and into the view where it can be lazily executed. Removed the ability of the `render` method to take a string id of the node to render to. You must provide a node.\n* `DOM` - Tree Walker methods are no longer used and are thus removed. The API for removing child nodes has been removed as well since it was only used in one place and could be inlined. The helper `createCustomAttributePlaceholder()` no longer requires an attribute name. It will be uniquely generated internally.\n* `class` - Bindings to `class` are now more nuanced. Binding directly to `class` will simply set the `className` property. If you need to bind to `class` knowing that manual JS will also manipulate the `classList` in addition to the binding, then you should now bind to `:classList` instead. This allows for performance optimizations in the simple, most common case.\n* `Behavior` and `ViewBehavior` - `Behavior` now requires an `ExecutionContext` for `unbind`. Behaviors can be used for elements or views. `ViewBehavior` has been introduced for use exclusively with views, and provides some optimization opportunities.\n* `RefBehavior` has been replaced with `RefDirective`. The directive also implements `ViewBehavior` allowing a single directive instance to be shared across all template instances that use the ref.\n* Removed `SlottedBehavior` and `ChildrenBehavior` have been replaced with `SlottedDirective` and `ChildrenDirective`. These directives allow a single directive instance to be shared across all template instances that use the ref.\n* Removed `AttachedBehaviorHTMLDirective` and `AttachedBehaviorType` since they are no longer used in the new directive/behavior architecture for ref, slotted, and children.\n* Renamed `Notifier#source` to `Notifier#subject` to align with other observable terminology and prevent name clashes with `BindingObserver` properties.\n\n<!-- File: packages/fast-element/docs/migration/fast-element-3.md (Tokens: ~6087 | Category: anthropic-skill) -->\n# Migrating from previous versions\n\n## FASTGlobal version tracking (v2 → v3)\n\n### Removed API\n\n| Removed | Replacement |\n|---|---|\n| `FAST.versions` | No replacement. Multiple FAST versions on the same page are unsupported in v3. |\n\n### Removed configuration\n\n| Removed | Replacement |\n|---|---|\n| `fast-kernel=\"share\"` / `fast-kernel=\"share-v2\"` / `fast-kernel=\"isolate\"` | No replacement. FAST now uses a single shared kernel contract, and multiple FAST versions on the same page are unsupported. |\n\n### Migration steps\n\n1. Remove any runtime checks that read `FAST.versions`.\n2. Fix duplicate FAST installs in your bundler or dependency graph instead of relying on version tracking at runtime.\n3. Remove any `fast-kernel` script attributes. They no longer affect FAST initialization.\n\n## Native globals and scheduler requirements (v2 → v3)\n\n### Changed behavior\n\n- **Browser `Window` runtime required**: `@microsoft/fast-element` is a\n  client-side browser runtime. It expects browser DOM, Custom Elements, Shadow\n  DOM, and scheduling APIs such as `requestAnimationFrame`.\n- **Native `globalThis` required**: `@microsoft/fast-element` no longer installs\n  a `globalThis` polyfill as a side effect.\n- **No idle-callback polyfill**: FAST Element v3 no longer installs or depends\n  on a `requestIdleCallback` / `cancelIdleCallback` fallback. The async\n  `Updates` queue schedules work with `globalThis.requestAnimationFrame`.\n\n### Migration steps\n\n1. Verify that the browsers you support provide native `globalThis` and\n   `requestAnimationFrame`.\n2. If you still target an older browser without `globalThis`, load that polyfill\n   before importing `@microsoft/fast-element`.\n3. Do not import or run the FAST Element client runtime in workers,\n   server-side JavaScript runtimes, or other non-window hosts. SSR tools may\n   emit HTML, but hydration and client rendering run in the browser `Window`.\n4. You do not need to polyfill `requestIdleCallback` or `cancelIdleCallback`\n   for FAST Element itself. Only provide them if your application or another\n   dependency calls those APIs directly.\n\n## Declarative HTML moved into fast-element (v3)\n\nDeclarative HTML APIs now ship from focused `@microsoft/fast-element` package\npath exports instead of the removed `@microsoft/fast-html` package.\n\n### Import changes\n\n| Before | After |\n|---|---|\n| `@microsoft/fast-html` | `@microsoft/fast-element/declarative.js` |\n| `@microsoft/fast-html/utilities.js` | `@microsoft/fast-element/declarative-utilities.js` |\n\nCore FAST Element helpers are available from the root package export:\n\n| API | Import path |\n|---|---|\n| `Updates` | `@microsoft/fast-element` |\n| `Observable`, `observable` | `@microsoft/fast-element` |\n| `attr`, `AttributeDefinition`, converters, `ValueConverter` | `@microsoft/fast-element` |\n| `Binding`, `oneWay`, `oneTime`, `listener` | `@microsoft/fast-element` |\n| `DOM`, `DOMAspect`, `DOMPolicy` | `@microsoft/fast-element` |\n| `Schema`, `schemaRegistry`, schema types | `@microsoft/fast-element` |\n| `css` | `@microsoft/fast-element` |\n| `html`, `ViewTemplate`, `HTMLView` | `@microsoft/fast-element` |\n| `Compiler`, `HTMLDirective`, `htmlDirective`, templating/view types | `@microsoft/fast-element` |\n| `render`, `RenderBehavior`, `RenderDirective` | `@microsoft/fast-element` |\n| `enableHydration`, `deferHydrationAttribute`, `HydrationTracker`, hydration types | `@microsoft/fast-element/hydration.js` |\n| `ArrayObserver` | `@microsoft/fast-element` |\n| `volatile` | `@microsoft/fast-element` |\n| `children` | `@microsoft/fast-element` |\n| `elements`, `NodeObservationDirective` | `@microsoft/fast-element` |\n| `ref` | `@microsoft/fast-element` |\n| `slotted` | `@microsoft/fast-element` |\n| `when` | `@microsoft/fast-element` |\n| `repeat` | `@microsoft/fast-element` |\n\n### Migration steps\n\n1. Update declarative runtime imports to\n   `@microsoft/fast-element/declarative.js`.\n2. Update declarative utility imports such as `deepMerge` to\n   `@microsoft/fast-element/declarative-utilities.js`.\n3. Keep importing FAST Element APIs such as `FASTElement`, `FAST`,\n   `ElementController`, definition/controller types, `attr`, `Schema`, and\n   `observable` from `@microsoft/fast-element`.\n4. Call `enableHydration()` from `@microsoft/fast-element/hydration.js` when\n   prerendered content should be hydrated.\n\n## `deepMerge` array replacement\n\nWhen an array's contents change, `deepMerge` replaces the owning property's\narray rather than mutating the existing array in place. This affects both\n`observerMap()`-managed data and direct consumers of the exported helper.\nPreviously captured array references retain the old data; mutating them no\nlonger updates the owning object. Deeply equal arrays are left unchanged.\n\nRe-read the array from its owner after merging:\n\n```ts\nimport { deepMerge } from \"@microsoft/fast-element/declarative-utilities.js\";\n\nconst user = { orders: [{ id: 101 }] };\nconst oldOrders = user.orders;\n\ndeepMerge(user, { orders: [{ id: 103 }] });\n\n// oldOrders still contains order 101 and is disconnected from user.orders.\nuser.orders.push({ id: 104 });\n```\n\nFor `observerMap()`-managed properties, the owning property's notification\ncauses `f-repeat` bindings to observe the replacement array automatically.\nDirect `deepMerge` consumers must still arrange their own change notifications;\nthe helper does not make plain objects observable.\n\n## Optional helper and removed path exports (v2 → v3)\n\nFAST Element v3 adds focused flat path exports for optional helpers and removes\nolder nested or unused package exports. Root imports for core FAST Element APIs\nremain supported, but code that imports helper APIs from older nested paths must\nmove to the flat path exports.\n\n### Import changes\n\n| Before | After |\n|---|---|\n| `@microsoft/fast-element/binding/two-way.js` | `@microsoft/fast-element/two-way.js` |\n| `@microsoft/fast-element/binding/signal.js` | `@microsoft/fast-element/signal.js` |\n| Deep directive imports | `@microsoft/fast-element/children.js`, `@microsoft/fast-element/repeat.js`, `@microsoft/fast-element/when.js`, `@microsoft/fast-element/ref.js`, `@microsoft/fast-element/slotted.js`, or `@microsoft/fast-element/node-observation.js` |\n| Declarative map helpers from old declarative surfaces | `@microsoft/fast-element/attribute-map.js` and `@microsoft/fast-element/observer-map.js` |\n\n### Removed package exports\n\n| Removed | Replacement |\n|---|---|\n| `@microsoft/fast-element/install-element-hydration.js` | No side-effect import. Call `enableHydration()` from `@microsoft/fast-element/hydration.js` when SSR content should hydrate. |\n| `@microsoft/fast-element/install-hydratable-view-templates.js` | No side-effect import. `enableHydration()` installs hydratable template support. |\n| `@microsoft/fast-element/element-hydration.js` | `@microsoft/fast-element/hydration.js` for public hydration APIs. |\n| `@microsoft/fast-element/metadata.js` | No supported public replacement. |\n| `@microsoft/fast-element/testing.js` | No supported public replacement. |\n| `@microsoft/fast-element/pending-task.js` | No supported public replacement. |\n\n### Migration steps\n\n1. Replace older nested helper imports with the flat path exports shown above.\n2. Remove hydration side-effect imports and call `enableHydration()` before FAST\n   elements connect when SSR content should hydrate.\n3. Remove imports from deleted package exports. If your app depended on one of\n   those internals, move that usage into app-owned code or a supported public\n   API.\n\n## `attribute-name-strategy` default changed (v2 → v3)\n\nThe declarative attribute map default changed from `\"none\"` to `\"camelCase\"`.\nWith the default strategy, a binding key such as `{{firstName}}` maps to the\n`firstName` property and the `first-name` HTML attribute. In v2-style\ndeclarative templates that relied on literal attribute names, this can change\nwhich property receives data.\n\n### Migration steps\n\n1. Audit declarative templates for binding keys that contain hyphens or that\n   intentionally matched attribute names exactly.\n2. If you want the v2 behavior, configure the client definition extension with\n   `attributeMap({ \"attribute-name-strategy\": \"none\" })`.\n3. If server-rendered HTML is generated with `@microsoft/fast-build`, pass\n   `--attribute-name-strategy=none` so server and client mapping agree.\n\n## `TemplateOptions` removal (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `TemplateOptions` | No replacement |\n| `PartialFASTElementDefinition.templateOptions` | No replacement |\n| `FASTElementDefinition.templateOptions` | No replacement |\n\n### Changed behavior\n\n- Subclass `define()` calls no longer use `templateOptions` to delay platform\n  definition or connection.\n- Elements can still be defined before a template is attached; a later\n  `FASTElementDefinition.template` update notifies connected elements so they\n  can render or hydrate with the new template.\n\n### Migration steps\n\n1. Remove `templateOptions` from element definitions.\n2. Continue calling `define({ name })` when a definition needs to exist before\n   its template is attached.\n3. If a template is supplied later, assign `FASTElementDefinition.template` (or\n   use the declarative runtime that does so for you).\n\n## `FASTElementDefinition.isRegistered` removal (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `FASTElementDefinition.isRegistered` | `fastElementRegistry.whenRegistered(tagName)`, `fastElementRegistry.getByType(type)`, or `fastElementRegistry.getForInstance(instance)` |\n\n### Migration steps\n\n1. Import `fastElementRegistry` from `@microsoft/fast-element/registry.js`.\n2. Use `fastElementRegistry.whenRegistered(tagName)` when code needs to wait for\n   a definition by tag name.\n3. Use `fastElementRegistry.getByType(type)` or\n   `fastElementRegistry.getForInstance(instance)` when code already has a\n   constructor or element instance.\n\n## Declarative TemplateElement API removal (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `TemplateElement` public export | `declarativeTemplate()` on each FAST element definition |\n| `TemplateElement.define({ name: \"f-template\" })` | No manual definition; `declarativeTemplate()` defines FAST's internal `<f-template>` publisher in the target registry |\n| `TemplateElement.config(callbacks)` / `HydrationLifecycleCallbacks` | `enableHydration().whenHydrated(tagName)` for tag-specific hydration waits and `enableHydration().whenHydrated()` for the active hydration batch |\n| `TemplateElement.options(...)`, `ElementOptions`, `ElementOptionsDictionary` | Define extensions: `attributeMap(...)` and `observerMap(...)` passed as the second argument to `define()` |\n| `AttributeMap` / `ObserverMap` exports from the old declarative public surface | `attributeMap()` / `observerMap()` extension helpers and their config types |\n\n### Migration steps\n\n1. Replace manual `<f-template>` registration with `template: declarativeTemplate()`:\n\n   ```typescript\n   // Before\n   import { TemplateElement } from \"@microsoft/fast-element\";\n   TemplateElement.define({ name: \"f-template\" });\n\n   MyElement.define({ name: \"my-element\" });\n\n   // After\n   import { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n\n   MyElement.define({\n       name: \"my-element\",\n       template: declarativeTemplate(),\n   });\n   ```\n\n2. Replace `TemplateElement.options()` with definition extensions:\n\n   ```typescript\n   import { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\n   import { declarativeTemplate } from \"@microsoft/fast-element/declarative.js\";\n   import { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\n   MyElement.define(\n       {\n           name: \"my-element\",\n           template: declarativeTemplate(),\n       },\n       [attributeMap(), observerMap()],\n   );\n   ```\n\n   `attributeMap()` is imported from\n   `@microsoft/fast-element/attribute-map.js` and `observerMap()` from\n   `@microsoft/fast-element/observer-map.js` for declarative templates,\n   manually supplied schemas, or both. `FASTElementDefinition.schema` is optional;\n   `declarativeTemplate()` assigns it automatically, and `observerMap()` can\n   take a manual schema with `observerMap({ schema })`.\n\n3. Replace `TemplateElement.config()` with `enableHydration().whenHydrated(tagName)`\n   for tag-specific hydration waits and `enableHydration().whenHydrated()` for the\n   active hydration batch.\n   Hydration is not installed by `declarative.js`; call `enableHydration()`\n   before elements connect when SSR content should hydrate.\n\n## Debug entrypoint explicit enablement (v3)\n\n### Import changes\n\n| Before | After |\n|---|---|\n| `import \"@microsoft/fast-element\";` | `import { enableDebug } from \"@microsoft/fast-element/debug.js\"; enableDebug();` |\n\n### Migration steps\n\n1. Replace setup-only `debug.js` imports with an explicit `enableDebug()` call.\n2. Keep using the root package `development` export or debug rollup bundle when\n   you want debug behavior enabled automatically.\n\n## Declarative event handler `e` removal (v3)\n\n### Removed behavior\n\n| Removed | Replacement |\n|---|---|\n| Bare `e` event arguments in declarative event handlers | `$e` |\n| `TemplateParser.hasDeprecatedEventSyntax` | No replacement |\n\nOnly `$e` and `$c` are reserved event handler arguments in declarative\ntemplates. Bare `e` now resolves like any other binding path on the current\ndata source.\n\n### Migration steps\n\n1. Replace declarative event bindings such as\n   `@click=\"{handleClick(e)}\"` with `@click=\"{handleClick($e)}\"`.\n2. Remove any `TemplateParser.hasDeprecatedEventSyntax` checks or warnings from\n   custom tooling.\n\n## Prerendered Content Optimization (v2 → v3)\n\n### Removed and moved APIs\n\n| 2.x API | 3.x guidance |\n|---|---|\n| `HydratableElementController` | `ElementController` (prerendered path built in) |\n| `HydrationControllerCallbacks` | Call `enableHydration()` and await the returned controller's `whenHydrated()` promise |\n| `needsHydrationAttribute` | No replacement. Existing shadow root detection sets `ElementController.isPrerendered`. |\n| Root `deferHydrationAttribute` export | Import `deferHydrationAttribute` from `@microsoft/fast-element/hydration.js` only if you still need the legacy attribute string. New server-rendered markup should omit `defer-hydration`. |\n\n### Removed side-effect imports\n\n| Import | Replacement |\n|---|---|\n| `@microsoft/fast-element/install-hydration.js` | No replacement needed — prerendered path is built into `ElementController` |\n| `@microsoft/fast-element/install-hydratable-view-templates.js` | No replacement needed — `enableHydration()` installs hydratable template support |\n\nUse `enableHydration()` from `@microsoft/fast-element/hydration.js` when SSR\ncontent should hydrate. The declarative entrypoint no longer installs hydration\nautomatically.\n\n### Changed behavior\n\n- **`attributeChangedCallback` during upgrade**: When `isPrerendered` is true and the element has not yet connected, attribute change callbacks are suppressed. After connection, all attribute changes are processed normally.\n- **Declarative template resolution**: `declarativeTemplate()` waits for the\n  matching `<f-template>` before `define()` completes, so connected elements\n  hydrate with a concrete template. No `defer-hydration` attribute is needed.\n- **Binding evaluation with existing shadow root**: When an existing shadow root is detected, `attribute` and `booleanAttribute` bindings skip their initial DOM update. All other binding types (event, content, property, tokenList) run normally.\n\n### New APIs\n\n- **`ElementController.isPrerendered`** (`Promise<boolean>`): Resolves to `true` when the element had a declarative shadow root at connect time, or `false` when the component was client-side rendered.\n- **`ElementController.isHydrated`** (`Promise<boolean>`): Resolves to `true` only when hydration ran successfully.\n- **`ViewController.isPrerendered`** (`Promise<boolean> | undefined`): Available to custom directives. Resolves to `true` when the view's content was prerendered, `false` otherwise.\n- **`ViewController.isHydrated`** (`Promise<boolean> | undefined`): Available to custom directives. Resolves to `true` only when hydration ran successfully.\n\n### Migration steps\n\n1. Remove `HydratableElementController.install()` calls.\n2. Remove `import \"@microsoft/fast-element/install-hydration.js\"` side-effect imports.\n3. Replace `element.$fastController instanceof HydratableElementController` checks with `await element.$fastController.isPrerendered`.\n4. Remove `defer-hydration` and `needs-hydration` attributes from server-rendered markup.\n\n## Hydration Marker Format (v3)\n\n### Changed format\n\nThe hydration markers embedded in SSR output have been simplified from verbose, index-embedded comment markers to compact, data-free sequential markers.\n\n#### Comment markers\n\n| Marker type | Old format | New format |\n|---|---|---|\n| Content binding start | `<!-- fe-b$$start$$<index>$$<scopeId>$$fe-b -->` | `<!--fe:b-->` |\n| Content binding end | `<!-- fe-b$$end$$<index>$$<scopeId>$$fe-b -->` | `<!--fe:/b-->` |\n| Repeat item start | `<!-- fe-repeat$$start$$<itemIndex>$$fe-repeat -->` | `<!--fe:r-->` |\n| Repeat item end | `<!-- fe-repeat$$end$$<itemIndex>$$fe-repeat -->` | `<!--fe:/r-->` |\n| Element boundary start | `<!-- fe-eb$$start$$<elementId>$$fe-eb -->` | `<!--fe:e-->` |\n| Element boundary end | `<!-- fe-eb$$end$$<elementId>$$fe-eb -->` | `<!--fe:/e-->` |\n\n#### Attribute binding markers\n\n| Old format | New format |\n|---|---|\n| `data-fe-b=\"0 1 2\"` (space-separated indices) | `data-fe=\"N\"` (binding count) |\n| `data-fe-b-0` (enumerated, one per factory) | `data-fe=\"N\"` |\n| `data-fe-c-0-3` (compact, start index + count) | `data-fe=\"N\"` |\n\n### Removed APIs\n\n| Export | Replacement |\n|---|---|\n| `HydrationMarkup.contentBindingStartMarker(index, scopeId)` | `HydrationMarkup.contentBindingStartMarker()` |\n| `HydrationMarkup.contentBindingEndMarker(index, scopeId)` | `HydrationMarkup.contentBindingEndMarker()` |\n| `HydrationMarkup.isContentBindingStartMarker(data)` | `HydrationMarkup.isContentBindingStartMarker(data)` (unchanged signature, new implementation) |\n| `HydrationMarkup.isContentBindingEndMarker(data)` | `HydrationMarkup.isContentBindingEndMarker(data)` (unchanged signature, new implementation) |\n| `HydrationMarkup.parseAttributeBinding(element)` | `HydrationMarkup.parseAttributeBindingCount(element)` |\n| `HydrationMarkup.parseRepeatStartMarker(data)` | `HydrationMarkup.isRepeatViewStartMarker(data)` |\n| `HydrationMarkup.parseRepeatEndMarker(data)` | `HydrationMarkup.isRepeatViewEndMarker(data)` |\n| `HydrationMarkup.parseElementBoundaryStartMarker(content)` | `HydrationMarkup.isElementBoundaryStartMarker(node)` |\n| `HydrationMarkup.parseElementBoundaryEndMarker(content)` | `HydrationMarkup.isElementBoundaryEndMarker(node)` |\n\n### Impact\n\nThis is a **breaking change** for SSR output format. Any system that produces or parses hydration markers must be updated to use the new format. The `@microsoft/fast-build` Rust crate and WASM binary have been updated accordingly.\n\n- Marker parsing uses string equality checks (`data === \"fe:b\"`) instead of regex\n- Start/end pairing uses balanced depth counting instead of embedded IDs\n- The hydration walker uses a sequential factory pointer instead of index-based lookup\n- SSR and client versions must match — mixing old SSR output with new client code (or vice versa) will fail\n\n## Async define/compose/register API (v3)\n\n### Removed APIs\n\n| Removed | Replacement |\n|---|---|\n| `FASTElement.defineAsync()` | Subclass `define()` calls |\n| `FASTElement.compose()` and subclass `compose()` calls | Subclass `define()` calls |\n| `FASTElementDefinition.composeAsync()` | Subclass `define()` calls |\n| `FASTElementDefinition.registerAsync()` | `FASTElementDefinition.register()` (same `Promise<Function>` return type) |\n\n### Changed behavior\n\n- Subclass **`define()`** calls return `Promise<TType>` only for code that\n  explicitly needs to observe registration completion. When\n  `template: declarativeTemplate()` is used, that Promise resolves after the\n  matching `<f-template>` supplies the concrete template.\n- Subclass compose helpers are no longer part of the public authoring surface; use subclass `define()` for registration.\n- **`@customElement` decorator** calls `define()` internally but does not return the Promise (fire-and-forget). For complete definitions with a template, the element is registered via a microtask.\n\n### Migration steps\n\n1. Replace `defineAsync()` calls with `define()`:\n\n   ```typescript\n    // Before\n    MyElement.defineAsync({\n        name: \"my-element\",\n        templateOptions: \"defer-and-hydrate\",\n    });\n\n    // After\n    MyElement.define({\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    });\n   ```\n\n2. Replace subclass `compose()` calls that immediately register an element with\n   `define()`:\n\n   ```typescript\n    // Before\n    MyElement.compose({\n        name: \"my-element\",\n        template,\n        styles,\n    }).define();\n\n    // After\n    MyElement.define({\n        name: \"my-element\",\n        template,\n        styles,\n    });\n   ```\n\n3. Replace `FASTElementDefinition.composeAsync()` calls that register an element\n   with subclass `define()`:\n\n   ```typescript\n   // Before\n   (await FASTElementDefinition.composeAsync(MyElement, {\n       name: \"my-element\",\n       template,\n       styles,\n   })).define();\n\n   // After\n   MyElement.define({\n       name: \"my-element\",\n       template,\n       styles,\n   });\n   ```\n\n4. Replace `registerAsync()` calls with `register()`:\n\n   ```typescript\n   // Before\n   const el = await FASTElementDefinition.registerAsync(name);\n\n   // After\n   const el = await FASTElementDefinition.register(name);\n   ```\n\n5. Replace `FASTElementDefinition.compose()` calls that chain `.define()` with\n   subclass `define()`:\n\n   ```typescript\n    // Before\n    FASTElementDefinition.compose(MyElement, options).define();\n\n    // After\n    MyElement.define(options);\n   ```\n\n## Dynamic stylesheet behaviors (v3)\n\n### Removed API\n\n| Removed | Replacement |\n|---|---|\n| `ElementStyles.withBehaviors()` | Move the runtime condition into the element and call `this.$fastController.addStyles()` / `this.$fastController.removeStyles()` directly. |\n| `ElementStyles.behaviors` | Move any runtime behavior out of the stylesheet and into the element or controller lifecycle. |\n| CSS bindings in `css` (for example ``css`color: ${x => x.color}```) | Move the dynamic value into the element and update classes, attributes, or inline styles from element code. |\n| `CSSDirective.createCSS(add)` | Update directives to implement `createCSS()` and return only static CSS content. |\n\n### Changed behavior\n\n- `css` and `css.partial()` no longer compose `HostBehavior`s.\n- `css` no longer accepts function or `Binding` interpolations.\n- `ElementStyles` is now a fully static style container.\n\n### Migration steps\n\n1. Keep the conditional `ElementStyles` in a separate `css` value.\n2. Move the external listener or condition (for example `matchMedia()` or an app event subscription) into the element lifecycle.\n3. Call `this.$fastController.addStyles(styles)` when the condition is active and `this.$fastController.removeStyles(styles)` when it is inactive or during cleanup.\n4. If you previously interpolated bindings or behavior-producing directives into `css`, replace them with element state and standard DOM or controller updates.\n\n## `booleanConverter` aligned with native HTML boolean attribute semantics (v2 → v3)\n\n### Changed behavior\n\n`@attr({ mode: \"boolean\" })` and `booleanConverter` now match how the platform treats native boolean attributes (e.g., `disabled`, `required`):\n\n- **Attribute → property** is presence-based: `setAttribute(name, anyString)` (including the empty string) sets the property to `true`; only `removeAttribute(name)` makes it `false`.\n- **Property → attribute** uses `Boolean()` coercion: any JavaScript truthy value adds the attribute (with value `\"\"`); any falsy value removes it.\n\nThe headline v2 → v3 difference is that `setAttribute(name, \"false\")` now resolves to property `true`, matching `<input disabled=\"false\">` still being disabled.\n\n`booleanConverter` shape:\n\n```ts\ntoView(value: any) {\n    return value ? \"\" : null;\n}\n\nfromView(value: any) {\n    return !!value;\n}\n```\n\n`booleanConverter` v2 → v3 result differences:\n\n| Call | v2 result | v3 result |\n|---|---|---|\n| `fromView(\"false\")` | `false` | `true` |\n| `fromView(\"\")` | `true` | `false` |\n| `fromView(NaN)` | `true` | `false` |\n| `toView(true)` (or any truthy) | `\"true\"` | `\"\"` |\n| `toView(false)` (or any falsy) | `\"false\"` | `null` |\n\n> **Note**: For `mode: \"boolean\"`, FAST writes attributes via `DOM.setBooleanAttribute` (presence-based) and reads them as `value !== null`, so the `mode: \"boolean\"` reflection path does **not** route through `booleanConverter.toView()` or `booleanConverter.fromView()`. The converter methods still apply to property assignment (`el.bool = X` runs `fromView(X)`), explicit calls (`booleanConverter.fromView(x)`), and `booleanConverter` paired with `mode: \"reflect\"` (which calls `toView`).\n\n### Migration steps\n\n1. Audit `boolean`-mode attributes for the literal string `\"false\"` in templates or SSR HTML — the resulting property will be `true`, not `false`. To express the falsy state, omit the attribute entirely (or call `element.removeAttribute(name)`). Setting `element.bool = false` continues to remove the reflected attribute.\n2. Audit code that calls `booleanConverter.toView()` directly or pairs `booleanConverter` with `mode: \"reflect\"`. The output strings are no longer `\"true\"` / `\"false\"`.\n3. If you need a tri-state attribute (`true` / `false` / unset) that preserves an explicit `\"false\"` string value, use `nullableBooleanConverter` with `mode: \"reflect\"` instead of `mode: \"boolean\"`.\n\n<!-- File: packages/fast-element/docs/migration/fast-html.md (Tokens: ~2073 | Category: anthropic-skill) -->\n# Migrating from previous versions\n\n## Hydration Marker Format (v1-alpha → v1)\n\nThe SSR output format for hydration markers has been simplified. If you have any tooling that inspects or generates hydration markers, update it to use the new format.\n\n| Old marker | New marker |\n|---|---|\n| `<!-- fe-b$$start$$...$$fe-b -->` | `<!--fe:b-->` |\n| `<!-- fe-b$$end$$...$$fe-b -->` | `<!--fe:/b-->` |\n| `<!-- fe-repeat$$start$$...$$fe-repeat -->` | `<!--fe:r-->` |\n| `<!-- fe-repeat$$end$$...$$fe-repeat -->` | `<!--fe:/r-->` |\n| `data-fe-b=\"0 1 2\"` / `data-fe-b-0` / `data-fe-c-0-3` | `data-fe=\"N\"` |\n\nThe `@microsoft/fast-build` WASM binary emits the new markers automatically. Rebuild all fixtures and SSR output after upgrading.\n\nSee the [`@microsoft/fast-element` migration guide](./fast-element-3.md#hydration-marker-format-v3) for full details on API changes.\n\n## Prerendered Content Optimization (v1-alpha → v1)\n\n### Removed exports\n\n| Export | Replacement |\n|---|---|\n| `RenderableFASTElement` | Extend `FASTElement` |\n\n### Removed concepts\n\n| Concept | Replacement |\n|---|---|\n| `prepare()` lifecycle hook | Set state in `connectedCallback`; the reactive system updates the DOM |\n| `defer-hydration` attribute in rendered markup | Template-pending guard in `ElementController.connect()` |\n| `needs-hydration` attribute in rendered markup | `hasExistingShadowRoot` detection in `ElementController` |\n| `waitForAncestorHydration()` | Not needed — prerendered content is correct regardless of connection order |\n\n### Migration steps\n\n1. Replace `RenderableFASTElement(MyComponent).defineAsync({...})` with\n   `MyComponent.define({...})` and use `declarativeTemplate()` for declarative\n   templates. If code explicitly observes the Promise returned by `define()`,\n   it resolves after the matching `<f-template>` supplies the concrete template.\n\n   ```typescript\n   // Before\n   import { RenderableFASTElement } from \"@microsoft/fast-html\";\n   RenderableFASTElement(MyComponent).defineAsync({\n       name: \"my-component\",\n       templateOptions: \"defer-and-hydrate\",\n   });\n\n   // After\n   MyComponent.define({\n       name: \"my-component\",\n       template: declarativeTemplate(),\n   });\n   ```\n\n2. Remove `prepare()` methods. Move any initialization logic to `connectedCallback`:\n\n   ```typescript\n   // Before\n   class MyComponent extends FASTElement {\n       async prepare() {\n           this.data = await fetchData();\n       }\n   }\n\n   // After\n   class MyComponent extends FASTElement {\n       connectedCallback() {\n           super.connectedCallback();\n           this.loadData();\n       }\n       async loadData() {\n           this.data = await fetchData();\n       }\n   }\n   ```\n\n3. Remove `defer-hydration` and `needs-hydration` attributes from server-rendered markup:\n\n   ```html\n   <!-- Before -->\n   <my-component defer-hydration needs-hydration text=\"Hello\">\n       <template shadowrootmode=\"open\">...</template>\n   </my-component>\n\n   <!-- After -->\n   <my-component text=\"Hello\">\n       <template shadowrootmode=\"open\">...</template>\n   </my-component>\n   ```\n\n4. Await `$fastController.isPrerendered` to detect prerendered components:\n\n   ```typescript\n   connectedCallback() {\n       super.connectedCallback();\n       this.$fastController.isPrerendered.then(prerendered => {\n           if (!prerendered) {\n               this.fetchData();\n           }\n       });\n   }\n   ```\n\n## Modularize Schema, ObserverMap, and AttributeMap\n\n### Import changes\n\nConfiguration types have moved from `template.ts` to their owning modules. If you import types directly from internal paths, update your imports:\n\n| Before | After |\n|---|---|\n| `import type { ObserverMapConfig } from \"./template.js\"` | `import type { ObserverMapConfig } from \"./observer-map.js\"` |\n| `import type { AttributeMapConfig } from \"./template.js\"` | `import type { AttributeMapConfig } from \"./attribute-map.js\"` |\n\nPublic declarative imports now come from\n`@microsoft/fast-element/declarative.js` rather than\n`@microsoft/fast-html`, and declarative utilities come from\n`@microsoft/fast-element/declarative-utilities.js`. Map extensions come from\n`@microsoft/fast-element/attribute-map.js` and\n`@microsoft/fast-element/observer-map.js`.\n\n### Schema changes\n\n`Schema.jsonSchemaMap` (static property) has been replaced by:\n- An instance-level `schemaMap` on each `Schema` instance (private)\n- A module-level `schemaRegistry` export for cross-element lookups\n\n| Before | After |\n|---|---|\n| `Schema.jsonSchemaMap.get('my-element')` | `import { schemaRegistry } from \"@microsoft/fast-element\"; schemaRegistry.get('my-element')` |\n\n### Public exports\n\nThe public entrypoint exports the functional declarative API:\n\n| Export | Purpose |\n|---|---|\n| `declarativeTemplate()` | Resolves `<f-template>` markup for a FAST element definition |\n| `attributeMap()` | Definition extension for automatic `@attr` property registration |\n| `observerMap()` | Definition extension for automatic deep observation |\n| `Schema` | JSON schema builder class |\n| `schemaRegistry` | Module-level registry for cross-element schema lookups |\n| `JSONSchema` | JSON Schema type interface |\n| `CachedPathMap` | Schema registry map type |\n\n## Simplified ObserverMap and AttributeMap defaults\n\nThe explicit `ObserverMapOption.all` and `AttributeMapOption.all` constants have\nbeen removed. Calling `observerMap()` with no arguments observes every\ndiscovered root property, and calling `attributeMap()` with no arguments maps\nevery discovered leaf binding.\n\n| Before | After |\n|---|---|\n| `observerMap(ObserverMapOption.all)` | `observerMap()` |\n| `attributeMap(AttributeMapOption.all)` | `attributeMap()` |\n\n## Attribute name strategy default changed\n\nThe default `attribute-name-strategy` for declarative attribute mapping is now\n`\"camelCase\"` instead of `\"none\"`. A binding key such as `{{firstName}}` maps to\nthe `firstName` property and the `first-name` HTML attribute by default. If your\ntemplates depended on literal attribute names, opt back in to the old behavior:\n\n```ts\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\n\nMyElement.define(\n    {\n        name: \"my-element\",\n        template: declarativeTemplate(),\n    },\n    [attributeMap({ \"attribute-name-strategy\": \"none\" })],\n);\n```\n\nWhen using `@microsoft/fast-build`, keep the server and client settings aligned:\n\n```bash\nfast build --attribute-name-strategy=none\n```\n\n## Declarative TemplateElement API removal\n\nThe public declarative API is now the functional API. The `<f-template>`\nimplementation is internal and is defined automatically by `declarativeTemplate()`.\n\n| Removed | Replacement |\n|---|---|\n| `TemplateElement` public export | `declarativeTemplate()` on each FAST element definition |\n| `TemplateElement.define({ name: \"f-template\" })` | No manual definition; `declarativeTemplate()` defines the internal publisher in the target registry |\n| `TemplateElement.config(callbacks)` / `HydrationLifecycleCallbacks` | `enableHydration().whenHydrated(tagName)` for tag-specific hydration waits and `enableHydration().whenHydrated()` for the active hydration batch |\n| `TemplateElement.options({ \"my-el\": { attributeMap, observerMap } })` | Define extensions: `MyElement.define(definition, [attributeMap(...), observerMap(...)])` |\n| `ElementOptions` / `ElementOptionsDictionary` | No replacement |\n| `AttributeMap` / `ObserverMap` class exports from the old declarative public surface | `attributeMap()` / `observerMap()` extension helpers and their config types |\n\nHydration is also no longer installed by `@microsoft/fast-element`.\nCall `enableHydration()` from `@microsoft/fast-element/hydration.js` before FAST\nelements connect when prerendered Declarative Shadow DOM should be reused.\n\n## Schema-driven maps and optional definition schema\n\n`attributeMap()` and `observerMap()` are now schema-driven extensions that are\nfactored away from declarative templating. Import them from\n`@microsoft/fast-element` for declarative or non-declarative use:\n\n```ts\nimport { attributeMap } from \"@microsoft/fast-element/attribute-map.js\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n```\n\n`FASTElementDefinition.schema` is optional. `declarativeTemplate()` assigns it\nautomatically when it parses `<f-template>` markup. Manual schema users can pass\na schema in the element definition, and `observerMap()` can also take a schema\ndirectly in configuration:\n\n```ts\nimport { FASTElement, Schema } from \"@microsoft/fast-element\";\nimport { observerMap } from \"@microsoft/fast-element/observer-map.js\";\n\nclass MyElement extends FASTElement {}\n\nconst schema = new Schema(\"my-element\");\nschema.addPath({\n    rootPropertyName: \"user\",\n    pathConfig: {\n        type: \"default\",\n        parentContext: null,\n        currentContext: null,\n        path: \"user.name\",\n    },\n    childrenMap: null,\n});\n\nMyElement.define({ name: \"my-element\" }, [observerMap({ schema })]);\n```\n\n<!-- File: packages/fast-element/docs/styles/api-report.api.md (Tokens: ~954 | Category: anthropic-skill) -->\n## API Report File for \"@microsoft/fast-element\"\n\n> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).\n\n```ts\n\n// @public\nexport type ComposableStyles = string | ElementStyles | CSSStyleSheet;\n\n// @public\nexport type Constructable<T = {}> = {\n    new (...args: any[]): T;\n};\n\n// @public\nexport type ConstructibleStyleStrategy = {\n    new (styles: (string | CSSStyleSheet)[]): StyleStrategy;\n};\n\n// @public\nexport interface CSSDirective {\n    createCSS(): ComposableStyles;\n}\n\n// @public\nexport const CSSDirective: Readonly<{\n    getForInstance: (object: any) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    getByType: (key: Function) => CSSDirectiveDefinition<Constructable<CSSDirective>> | undefined;\n    define<TType extends Constructable<CSSDirective>>(type: any): TType;\n}>;\n\n// @public\nexport function cssDirective(): (type: Constructable<CSSDirective>) => void;\n\n// @public\nexport interface CSSDirectiveDefinition<TType extends Constructable<CSSDirective> = Constructable<CSSDirective>> {\n    readonly type: TType;\n}\n\n// @public\nexport class ElementStyles {\n    constructor(styles: ReadonlyArray<ComposableStyles>);\n    // @internal (undocumented)\n    addStylesTo(target: StyleTarget): void;\n    // @internal (undocumented)\n    isAttachedTo(target: StyleTarget): boolean;\n    static normalize(styles: ComposableStyles | ComposableStyles[] | undefined): ElementStyles | undefined;\n    // @internal (undocumented)\n    removeStylesFrom(target: StyleTarget): void;\n    static setDefaultStrategy(Strategy: ConstructibleStyleStrategy): void;\n    get strategy(): StyleStrategy;\n    // (undocumented)\n    readonly styles: ReadonlyArray<ComposableStyles>;\n    static readonly supportsAdoptedStyleSheets: boolean;\n    withStrategy(Strategy: ConstructibleStyleStrategy): this;\n}\n\n// @public\nexport interface ExecutionContext<TParent = any> {\n    readonly event: Event;\n    eventDetail<TDetail>(): TDetail;\n    eventTarget<TTarget extends EventTarget>(): TTarget;\n    index: number;\n    readonly isEven: boolean;\n    readonly isFirst: boolean;\n    readonly isInMiddle: boolean;\n    readonly isLast: boolean;\n    readonly isOdd: boolean;\n    length: number;\n    parent: TParent;\n    parentContext: ExecutionContext<TParent>;\n}\n\n// @public\nexport const ExecutionContext: Readonly<{\n    default: ExecutionContext;\n    getEvent(): Event | null;\n    setEvent(event: Event | null): void;\n}>;\n\n// @public\nexport interface ExpressionController<TSource = any, TParent = any> {\n    readonly context: ExecutionContext<TParent>;\n    readonly isBound: boolean;\n    onUnbind(behavior: {\n        unbind(controller: ExpressionController<TSource, TParent>): any;\n    }): void;\n    readonly source: TSource;\n    readonly sourceLifetime?: SourceLifetime;\n}\n\n// @public\nexport interface HostBehavior<TSource = any> {\n    addedCallback?(controller: HostController<TSource>): void;\n    connectedCallback?(controller: HostController<TSource>): void;\n    disconnectedCallback?(controller: HostController<TSource>): void;\n    removedCallback?(controller: HostController<TSource>): void;\n}\n\n// @public\nexport interface HostController<TSource = any> extends ExpressionController<TSource> {\n    addBehavior(behavior: HostBehavior<TSource>): void;\n    addStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n    readonly isConnected: boolean;\n    mainStyles: ElementStyles | null;\n    removeBehavior(behavior: HostBehavior<TSource>, force?: boolean): void;\n    removeStyles(styles: ElementStyles | HTMLStyleElement | null | undefined): void;\n}\n\n// @public\nexport const SourceLifetime: Readonly<{\n    readonly unknown: undefined;\n    readonly coupled: 1;\n}>;\n\n// @public\nexport type SourceLifetime = (typeof SourceLifetime)[keyof typeof SourceLifetime];\n\n// @public\nexport interface StyleStrategy {\n    addStylesTo(target: StyleTarget): void;\n    removeStylesFrom(target: StyleTarget): void;\n}\n\n// @public\nexport interface StyleTarget extends Pick<Node, \"getRootNode\"> {\n    adoptedStyleSheets?: CSSStyleSheet[];\n    append(styles: HTMLStyleElement): void;\n    querySelectorAll<E extends Element = Element>(selectors: string): NodeListOf<E>;\n    removeChild(styles: HTMLStyleElement): void;\n}\n\n// (No @packageDocumentation comment for this package)\n\n```\n\n<!-- ... +11 more modular skills available via /api/skills/microsoft/fast?path={path} -->\n</yakaai_skills>"}