[
  {
    "path": ".claude/commands/bump-version.md",
    "content": "---\ndescription: Upgrade the library version across all files that contain it\nargument-hint: \"<new-version>\"\n---\n\nBump the JetLime library version from its current value to `$ARGUMENTS` (e.g. `4.2.0`) across every file that embeds it.\n\n## Files to update\n\nUpdate **all** occurrences of the old version string with the new version `$ARGUMENTS` in:\n\n1. `jetlime/build.gradle.kts`\n   - `mavenPublishing.coordinates(...)` third argument\n   - `cocoapods { version = \"...\" }`\n\n2. `jetlime/jetlime.podspec`\n   - `spec.version = '...'`\n\n3. `scripts/add_git_tag.sh`\n   - `TAG=\"...\"`\n\n4. `README.md`\n   - The `implementation(\"io.github.pushpalroy:jetlime:...\")` snippet\n\n## Steps\n\n1. Read each file listed above and locate the current version string.\n2. Replace every occurrence of the current version with `$ARGUMENTS` using the Edit tool.\n3. After all edits, grep the repo for the old version to confirm no stray occurrences remain:\n   ```\n   grep -r \"<old-version>\" --include=\"*.kts\" --include=\"*.kt\" --include=\"*.sh\" --include=\"*.md\" --include=\"*.podspec\" .\n   ```\n   If any hits remain outside `build/`, `docs/`, or `.git/`, report them and ask whether to update them too.\n4. Print a summary table — one row per file — showing the old value replaced and the new value written.\n\n## Constraints\n\n- Do NOT commit or tag. The user will review the diff and commit manually (or run `/dokka` and publish first).\n- Do NOT modify `CHANGELOG`, `docs/`, or any generated output — those are updated separately.\n- If `$ARGUMENTS` is missing or doesn't look like a semver string (`X.Y.Z`), stop and ask the user to provide it.\n"
  },
  {
    "path": ".claude/commands/ci-local.md",
    "content": "---\ndescription: Run the full CI pipeline locally (spotless + all platform builds) to catch failures before pushing\nargument-hint: \"[fast|full]\"\n---\n\nMirror the GitHub Actions `build.yml` pipeline locally so the user can verify everything CI runs before pushing. CI matrix: `spotlessCheck`, `build_android.sh`, `build_web_js.sh`, `build_web_wasm.sh`, `build_macos.sh`, `build_ios.sh`.\n\n## Behavior\n\nRun these in sequence with fail-fast semantics. As soon as one step fails, stop and show the failing step's last ~30 lines of output — do NOT continue to later steps, because cascaded failures hide the real error.\n\n### `$1 == \"fast\"` (or when user wants a quick pre-push check)\nRun only the cheap/fast steps:\n1. `./gradlew spotlessCheck`\n2. `./scripts/build_android.sh`\n3. `./scripts/build_web_js.sh`\n\nSkip wasm, desktop, and iOS.\n\n### `$1 == \"full\"` or no argument (default — matches CI exactly)\nRun every CI step, in order:\n1. `./gradlew spotlessCheck`\n2. `./scripts/build_android.sh`\n3. `./scripts/build_web_js.sh`\n4. `./scripts/build_web_wasm.sh`\n5. `./scripts/build_macos.sh`\n6. `./scripts/build_ios.sh` — only on macOS; skip with a note on other OSes.\n\n## Handling the common failures\n\n- **`spotlessCheck` fails**: tell the user to run `/spotless apply` (or `./gradlew spotlessApply`), review the diff, and re-run. Do NOT auto-apply — they should see what changed.\n- **`kotlinStoreYarnLock` fails during a web build** (\"Lock file was changed...\"): run `./gradlew kotlinUpgradeYarnLock`, then tell the user to commit `kotlin-js-store/yarn.lock` (and `kotlin-js-store/wasm/yarn.lock` if it changed). Do NOT commit automatically.\n- **Gradle daemon / class-cast weirdness after a Kotlin or AGP bump**: suggest `./gradlew --stop` and a re-run.\n- **iOS build on non-macOS host**: skip with a clear message — CI runs this only on `macos-latest`.\n\n## Final report\n\nAfter all steps succeed, print a single-line summary naming each step that ran and passed. No celebratory wall of text.\n\nIf a step failed, the summary is: which step, which file/task, and the recommended next command — nothing more.\n"
  },
  {
    "path": ".claude/commands/dokka.md",
    "content": "---\ndescription: Generate API documentation using Dokka V2 and sync to docs folder\n---\n\nGenerate HTML API documentation for the JetLime library. This command runs the Dokka V2 generation task and synchronizes the output to the root `docs/` directory, which is served via GitHub Pages.\n\nBehavior:\n1. Run `./scripts/run_dokka.sh`. This script executes the `:jetlime:syncDokkaToDocs` Gradle task.\n2. The task generates HTML documentation using Dokka V2 from the source files.\n3. It incorporates additional documentation from `dokkaModule.md` and `dokkaPackage.md` if present.\n4. It clears the existing `docs/` directory and copies the new documentation there.\n\nNotes:\n- The output in `docs/` should be reviewed if significant API changes were made.\n- Dokka V2 is used, as configured in `jetlime/build.gradle.kts`.\n- The synchronization task ensures that the latest documentation is ready for deployment to GitHub Pages.\n- If the command fails, check the Gradle output for configuration or source errors.\n"
  },
  {
    "path": ".claude/commands/spotless.md",
    "content": "---\ndescription: Run Spotless formatting check and auto-fix any violations\nargument-hint: \"[check|apply]\"\n---\n\nRun Spotless on this project. CI runs `spotlessCheck`, so formatting violations block merges — the goal of this command is to keep the branch clean.\n\nBehavior based on `$1`:\n\n- **`check`** (or no argument): run `./gradlew spotlessCheck`. If it passes, report \"Spotless passes\" and stop. If it fails, show the violating files from the output — do NOT auto-apply.\n- **`apply`**: run `./gradlew spotlessApply`, then `./gradlew spotlessCheck` to confirm. If files were modified, list them with `git status --short` so the user can review and commit.\n\nNotes:\n- Spotless uses ktlint + `io.nlopez.compose.rules:ktlint` and a mandatory MIT license header from `spotless/copyright.kt`. Do not hand-edit formatting — let `spotlessApply` own it.\n- After `apply`, do not commit or push automatically. Show the diff summary and let the user decide.\n- If the Gradle build itself errors (not just formatting), surface the real error rather than retrying.\n"
  },
  {
    "path": ".claude/skills/compose-expert/SKILL.md",
    "content": "---\nname: compose-expert\ndescription: >\n  Compose and Compose Multiplatform expert skill for UI development across Android, Desktop,\n  iOS, and Web. Guides state management, view composition, animations, navigation, performance,\n  design-to-code workflows, and production crash patterns. Backed by actual source code analysis\n  from both androidx/androidx and JetBrains/compose-multiplatform-core.\n  Use this skill whenever the user mentions Compose, @Composable, remember, LaunchedEffect,\n  Scaffold, NavHost, MaterialTheme, LazyColumn, Modifier, recomposition, Style, styleable,\n  MutableStyleState, Compose Multiplatform, CMP, KMP, commonMain, expect, actual,\n  ComposeUIViewController, Window composable, UIKitView, ComposeViewport, Res.drawable,\n  Res.string, or any Compose API. Also trigger when the user says \"Android UI\", \"Kotlin UI\",\n  \"compose layout\", \"compose navigation\", \"compose animation\", \"material3\", \"compose styles\",\n  \"compose multiplatform\", \"desktop compose\", \"iOS compose\", \"compose web\", \"design to compose\",\n  \"build this UI\", \"implement this design\", \"Android TV\", \"Google TV\", \"tv-material\",\n  \"tv-foundation\", \"Carousel\", \"NavigationDrawer\", \"D-pad\", \"focus indication\",\n  \"10-foot UI\", \"living room\", \"tv compose\", \"review this PR\", \"review this code\",\n  \"check this diff\", or any GitHub PR URL (github.com/.*/pull/),\n  \"design system\", \"component library\", \"atomic\", \"reusable component\",\n  \"design tokens\", \"atoms\", \"molecules\", or asks about modern\n  Kotlin UI development patterns. Even casual mentions like \"my compose screen is slow\"\n  or \"how do I pass data between screens\" or \"how do I build a TV app\" should trigger this skill.\n  Also trigger on session_start to auto-detect Compose projects — see references/auto-init.md.\nversion: 2.1.2\n---\n\n> **Installation notice:** This skill is now distributed as a plugin.\n> If you copied files into `~/.claude/skills/` manually, you are on an\n> unmaintained install path and will not receive updates. Migrate via:\n>\n>     /plugin marketplace add aldefy/compose-skill\n>     /plugin install compose-expert\n>\n> See [MIGRATION.md](../docs/MIGRATION.md) for Codex and Copilot CLI instructions.\n> This banner will remain through v2.x and escalate in v3.0.\n\n# Compose Expert Skill\n\nNon-opinionated, practical guidance for writing correct, performant Compose code —\nacross Android, Desktop, iOS, and Web. Covers Jetpack Compose and Compose Multiplatform.\nBacked by analysis of actual source code from `androidx/androidx` and\n`JetBrains/compose-multiplatform-core`.\n\n## Review Mode\n\n**Activate when** the input contains a GitHub PR URL (`github.com/.+/pull/\\d+`) or\nexplicit review phrases: \"review this PR\", \"review this diff\", \"check this code\",\n\"what's wrong with this\".\n\nWhen Review Mode activates:\n1. Do **not** follow the generation workflow below\n2. Read `references/pr-review.md` and follow its workflow exclusively\n3. Output a structured local review report — do not post to GitHub\n\n## Workflow\n\nWhen helping with Compose code, follow this checklist:\n\n### 1. Understand the request\n- What Compose layer is involved? (Runtime, UI, Foundation, Material3, Navigation)\n- Is this a state problem, layout problem, performance problem, or architecture question?\n- Is this Android-only or Compose Multiplatform (CMP)?\n\n### 2. Analyze the design (if visual reference provided)\n- If the user shares a Figma frame, screenshot, or design spec, consult `references/design-to-compose.md`\n- Decompose the design into a composable tree using the 5-step methodology\n- Map design tokens to MaterialTheme, spacing to CompositionLocals\n- Identify animation needs and consult `references/animation.md` for recipes\n\n### 3. Consult the right reference\nRead the relevant reference file(s) from `references/` before answering:\n\n| Topic | Reference File |\n|-------|---------------|\n| `@State`, `remember`, `mutableStateOf`, state hoisting, `derivedStateOf`, `snapshotFlow` | `references/state-management.md` |\n| Structuring composables, slots, extraction, preview | `references/view-composition.md` — for design system structure, also see `references/atomic-design.md` |\n| Modifier ordering, custom modifiers, `Modifier.Node` | `references/modifiers.md` |\n| `LaunchedEffect`, `DisposableEffect`, `SideEffect`, `rememberCoroutineScope` | `references/side-effects.md` |\n| `CompositionLocal`, `LocalContext`, `LocalDensity`, custom locals | `references/composition-locals.md` |\n| `LazyColumn`, `LazyRow`, `LazyGrid`, `Pager`, keys, content types | `references/lists-scrolling.md` |\n| `NavHost`, type-safe routes, deep links, shared element transitions | `references/navigation.md` |\n| `animate*AsState`, `AnimatedVisibility`, `Crossfade`, transitions | `references/animation.md` — for M3 token selection, also see `references/material3-motion.md` |\n| `MaterialTheme`, `ColorScheme`, dynamic color, `Typography`, shapes | `references/theming-material3.md` — for motion, see `references/material3-motion.md`; for design tokens, see `references/atomic-design.md` |\n| Recomposition skipping, stability, baseline profiles, benchmarking | `references/performance.md` |\n| Semantics, content descriptions, traversal order, testing | `references/accessibility.md` |\n| Removed/replaced APIs, migration paths from older Compose versions | `references/deprecated-patterns.md` |\n| **Styles API** (experimental): `Style {}`, `MutableStyleState`, `Modifier.styleable()` | `references/styles-experimental.md` |\n| Figma/screenshot decomposition, design tokens, spacing, modifier ordering | `references/design-to-compose.md` |\n| Production crash patterns, defensive coding, state/performance rules | `references/production-crash-playbook.md` |\n| Compose Multiplatform, `expect`/`actual`, resources (`Res.*`), migration | `references/multiplatform.md` |\n| Desktop (Window, Tray, MenuBar), iOS (UIKitView), Web (ComposeViewport) | `references/platform-specifics.md` |\n| TV Compose: Surface, Carousel, NavigationDrawer, Cards, focus, D-pad | `references/tv-compose.md` |\n| M3 motion tokens, `MotionTokens`, `MotionScheme`, animation duration, easing | `references/material3-motion.md` |\n| PR URL, code review, \"review this PR\", \"what's wrong with this\" | `references/pr-review.md` |\n| Session start, project detection | `references/auto-init.md` |\n| Atomic design, design system, reusable component, component library, design tokens | `references/atomic-design.md` |\n\n### 4. Apply and verify\n- Write code that follows the patterns in the reference\n- Flag any anti-patterns you see in the user's existing code\n- Suggest the minimal correct solution — don't over-engineer\n\n### 4a. Component building mode\nWhen the request involves building a component (composable that renders UI):\n- Consult `references/atomic-design.md`\n- Classify the component level (atom, molecule, organism, template)\n- Apply the \"Ask\" prompt from Section 5 before scaffolding code\n- Ensure the component satisfies the atom contract (modifier, slots, tokens, defaults)\n\n### 5. Cite the source\nWhen referencing Compose internals, point to the exact source file:\n```\n// See: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt\n```\n\n## Key Principles\n\n1. **Compose thinks in three phases**: Composition → Layout → Drawing. State reads in each\n   phase only trigger work for that phase and later ones.\n\n2. **Recomposition is frequent and cheap** — but only if you help the compiler skip unchanged\n   scopes. Use stable types, avoid allocations in composable bodies.\n\n3. **Modifier order matters**. `Modifier.padding(16.dp).background(Color.Red)` is visually\n   different from `Modifier.background(Color.Red).padding(16.dp)`.\n\n4. **State should live as low as possible** and be hoisted only as high as needed. Don't put\n   everything in a ViewModel just because you can.\n\n5. **Side effects exist to bridge Compose's declarative world with imperative APIs**. Use the\n   right one for the job — misusing them causes bugs that are hard to trace.\n\n6. **Compose Multiplatform shares the runtime but not the platform**. UI code in\n   `commonMain` is portable. Platform-specific APIs (`LocalContext`, `BackHandler`,\n   `Window`) require `expect`/`actual` or conditional source sets.\n\n## Source Code Receipts\n\nBeyond the guidance docs, this skill bundles the **actual source code** from\n`androidx/androidx` (branch: `androidx-main`) and `JetBrains/compose-multiplatform-core`\n(branch: `jb-main`). When you need to verify how something works internally, or the\nuser asks \"show me the actual implementation\", read the raw source from\n`references/source-code/`:\n\n| Module | Source Reference | Key Files Inside |\n|--------|-----------------|------------------|\n| Runtime | `references/source-code/runtime-source.md` | Composer.kt, Recomposer.kt, State.kt, Effects.kt, CompositionLocal.kt, Remember.kt, SlotTable.kt, Snapshot.kt |\n| UI | `references/source-code/ui-source.md` | AndroidCompositionLocals.android.kt, Modifier.kt, Layout.kt, LayoutNode.kt, ModifierNodeElement.kt, DrawModifier.kt |\n| Foundation | `references/source-code/foundation-source.md` | LazyList.kt, LazyGrid.kt, BasicTextField.kt, Clickable.kt, Scrollable.kt, Pager.kt |\n| Material3 | `references/source-code/material3-source.md` | MaterialTheme.kt, ColorScheme.kt, Button.kt, Scaffold.kt, TextField.kt, NavigationBar.kt |\n| Navigation | `references/source-code/navigation-source.md` | NavHost.kt, ComposeNavigator.kt, NavGraphBuilder.kt, DialogNavigator.kt |\n| CMP | `references/source-code/cmp-source.md` | Window.kt, ComposeUIViewController.kt, UIKitView.kt, ComposeViewport.kt, ResourceReader.kt |\n\n### Two-layer approach\n1. **Start with guidance** — read the topic-specific reference (e.g., `references/state-management.md`)\n2. **Go deeper with source** — if the user wants receipts or you need to verify, read from `references/source-code/`\n\n### Source tree map\n```\nandroidx/androidx (branch: androidx-main)\n├── compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/\n├── compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/\n├── compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/\n├── compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/\n├── compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/\n├── compose/navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/\n├── tv/tv-material/src/main/java/androidx/tv/material3/\n└── tv/tv-foundation/src/main/java/androidx/tv/foundation/\n\ncompose-multiplatform-core (branch: jb-main)\n├── compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/\n├── compose/ui/ui/src/iosMain/kotlin/androidx/compose/ui/window/\n├── compose/ui/ui/src/webMain/kotlin/androidx/compose/ui/window/\n├── compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/\n└── compose/foundation/foundation/src/skikoMain/kotlin/androidx/compose/foundation/\n\ncompose-multiplatform (resources library)\n└── components/resources/library/src/commonMain/\n```\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/accessibility.md",
    "content": "# Accessibility Reference\n\n## Semantics — Exposing UI to Accessibility Services\n\nSemantics describe UI elements to screen readers, voice commands, and testing tools. Compose generates semantics automatically for built-in components, but custom views require manual annotation.\n\n```kotlin\n// Built-in components have semantics\nButton(onClick = { }) { Text(\"Click me\") }  // Auto-announces as button\n\n// Custom composables need explicit semantics\nBox(\n    modifier = Modifier.semantics {\n        role = Role.Button\n        onClick(label = \"Activate\") { true }\n    }\n) {\n    Text(\"Custom button\")\n}\n```\n\n**Source**: `androidx/compose/ui/semantics/`\n\n---\n\n## contentDescription — Labels for Accessibility\n\nEvery meaningful visual element needs a label for screen readers.\n\n### When to Set contentDescription\n\n**DO**: Images, icons, buttons without text, decorative with meaningful purpose\n\n```kotlin\n// Icon in a button: set contentDescription\nButton(onClick = { }) {\n    Icon(Icons.Default.Settings, contentDescription = \"App settings\")\n}\n\n// Text-only button: contentDescription auto-generated\nButton(onClick = { }) { Text(\"Save\") }\n\n// Standalone image: always set description\nImage(\n    painter = painterResource(R.drawable.product),\n    contentDescription = \"Product photo: wireless headphones\"\n)\n```\n\n### When to Set contentDescription = null\n\n**Purely decorative images** that convey no information:\n\n```kotlin\n// Decorative divider line\nDivider(modifier = Modifier.padding(vertical = 8.dp))\n\n// Purely decorative background\nBox(\n    modifier = Modifier\n        .background(Color.Gray)\n        .size(100.dp)\n) {\n    Image(\n        painter = painterResource(R.drawable.background_pattern),\n        contentDescription = null  // Purely decorative\n    )\n}\n\n// Icon next to label: skip icon description\nRow {\n    Icon(\n        painter = painterResource(R.drawable.verified),\n        contentDescription = null,  // Label below describes it\n        tint = Color.Green\n    )\n    Text(\"Verified\")\n}\n```\n\nOmitting `contentDescription` or using `null` tells the screen reader to skip the element.\n\n---\n\n## Modifier.semantics — Merging and Overriding\n\n### Default Merging\n\nBy default, child semantics merge with parents:\n\n```kotlin\n// Child text is included in parent semantics\nColumn(modifier = Modifier.semantics { heading() }) {\n    Text(\"Section Title\")  // Screen reader: \"Section Title, heading\"\n}\n```\n\n### Clearing and Setting Semantics\n\nUse `clearAndSetSemantics` to override all child semantics:\n\n```kotlin\n// Screen reader ignores children, announces custom label\nBox(\n    modifier = Modifier.clearAndSetSemantics {\n        contentDescription = \"Custom audio player with play/pause\"\n    }\n) {\n    Icon(Icons.Default.PlayArrow, contentDescription = null)\n    Text(\"00:30\")  // Not read\n    Icon(Icons.Default.VolumeUp, contentDescription = null)  // Not read\n}\n```\n\n### Merging Disabled\n\nPrevent children from merging:\n\n```kotlin\nBox(\n    modifier = Modifier.semantics(mergeDescendants = false) {\n        heading()\n    }\n) {\n    Text(\"Heading\")  // Announced separately, not merged\n}\n```\n\n---\n\n## Touch Target Sizing\n\nMinimum touch target is 48dp × 48dp per Material Design and WCAG guidelines.\n\n```kotlin\n// Small button without sufficient touch target\nButton(modifier = Modifier.size(32.dp)) { }  // TOO SMALL\n\n// Proper touch target\nButton(\n    modifier = Modifier.sizeIn(minWidth = 48.dp, minHeight = 48.dp)\n) { }\n\n// Alternative: add padding\nBox(\n    modifier = Modifier\n        .size(32.dp)\n        .sizeIn(minWidth = 48.dp, minHeight = 48.dp)\n) {\n    Icon(Icons.Default.Edit, contentDescription = \"Edit\")\n}\n\n// For clickable elements without Button\nBox(\n    modifier = Modifier\n        .clip(RoundedCornerShape(8.dp))\n        .clickable { /* ... */ }\n        .sizeIn(minWidth = 48.dp, minHeight = 48.dp),\n    contentAlignment = Alignment.Center\n) {\n    Icon(Icons.Default.Close, contentDescription = \"Close\")\n}\n```\n\n---\n\n## Headings — Screen Reader Navigation\n\nHeadings allow users to navigate by section. Set heading semantic:\n\n```kotlin\n// Level 1 heading\nText(\n    text = \"Products\",\n    modifier = Modifier.semantics { heading() },\n    style = MaterialTheme.typography.headlineLarge\n)\n\n// Subheading (no formal levels in Compose; use structure)\nText(\n    text = \"New Arrivals\",\n    modifier = Modifier.semantics { heading() },\n    style = MaterialTheme.typography.headlineMedium\n)\n```\n\nScreen readers announce \"heading\" and allow jumping between sections. Use headings to structure content logically, not for styling.\n\n---\n\n## Custom Actions\n\nAllow screen readers to trigger complex interactions:\n\n```kotlin\n@Composable\nfun SlideToUnlock() {\n    Box(\n        modifier = Modifier\n            .fillMaxWidth()\n            .height(64.dp)\n            .semantics {\n                customActions = listOf(\n                    CustomAccessibilityAction(label = \"Unlock\") {\n                        unlock()\n                        true\n                    },\n                    CustomAccessibilityAction(label = \"Emergency call\") {\n                        emergencyCall()\n                        true\n                    }\n                )\n            }\n            .background(MaterialTheme.colorScheme.primary)\n    ) {\n        Text(\"Slide to Unlock\", color = Color.White)\n    }\n}\n```\n\nCustom actions appear in the accessibility menu. Avoid for standard interactions (Button, Checkbox).\n\n---\n\n## Traversal Order\n\nControl screen reader navigation order explicitly when needed:\n\n```kotlin\n// Default: top-to-bottom, left-to-right\nRow {\n    Button(onClick = { }) { Text(\"First\") }\n    Button(onClick = { }) { Text(\"Second\") }\n}\n\n// Custom order (right-to-left)\nRow {\n    Button(\n        onClick = { },\n        modifier = Modifier.semantics { traversalIndex = 1f }\n    ) { Text(\"Read Second\") }\n    Button(\n        onClick = { },\n        modifier = Modifier.semantics { traversalIndex = 0f }\n    ) { Text(\"Read First\") }\n}\n\n// Group items as single traversal unit\nColumn(\n    modifier = Modifier.semantics(mergeDescendants = false) {\n        isTraversalGroup = true\n    }\n) {\n    Text(\"Label\")\n    Text(\"Value\")\n}\n```\n\nUse `traversalIndex` sparingly. Good structure is usually sufficient.\n\n---\n\n## State Descriptions\n\nInform users of component state (enabled/disabled, checked/unchecked):\n\n```kotlin\n@Composable\nfun AccessibleCheckbox(\n    checked: Boolean,\n    onCheckedChange: (Boolean) -> Unit,\n    label: String\n) {\n    Row(\n        modifier = Modifier\n            .clip(RoundedCornerShape(8.dp))\n            .clickable { onCheckedChange(!checked) }\n            .semantics {\n                this.contentDescription = label\n                this.stateDescription = if (checked) \"Checked\" else \"Unchecked\"\n                role = Role.Checkbox\n            }\n            .sizeIn(minWidth = 48.dp, minHeight = 48.dp)\n    ) {\n        Icon(\n            if (checked) Icons.Default.CheckBox else Icons.Default.CheckBoxOutlineBlank,\n            contentDescription = null,\n            tint = MaterialTheme.colorScheme.primary\n        )\n        Text(label, modifier = Modifier.padding(start = 12.dp))\n    }\n}\n```\n\nScreen reader announces: \"Label, Checkbox, Checked\" or \"Label, Checkbox, Unchecked\".\n\n---\n\n## Live Regions\n\nAnnounce dynamic content changes without requiring interaction:\n\n```kotlin\n@Composable\nfun LiveMessage(message: String, modifier: Modifier = Modifier) {\n    Text(\n        text = message,\n        modifier = modifier.semantics {\n            liveRegion = LiveRegionMode.Assertive  // Polite or Assertive\n        }\n    )\n}\n\n// Usage\nvar status by remember { mutableStateOf(\"Loading...\") }\n\nLaunchedEffect(Unit) {\n    delay(2000)\n    status = \"Done loading\"  // Screen reader announces immediately\n}\n\nLiveMessage(message = status)\n```\n\n**Assertive**: Interrupts current speech. Use for critical updates (error, alert).\n**Polite**: Queues after current speech. Use for status updates.\n\n---\n\n## Testing Semantics\n\nUse Compose Test APIs to verify accessibility:\n\n```kotlin\n@get:Rule\nval composeTestRule = createComposeRule()\n\n@Test\nfun testContentDescription() {\n    composeTestRule.setContent {\n        Icon(\n            Icons.Default.Settings,\n            contentDescription = \"App settings\"\n        )\n    }\n\n    composeTestRule\n        .onNodeWithContentDescription(\"App settings\")\n        .assertIsDisplayed()\n}\n\n@Test\nfun testHeading() {\n    composeTestRule.setContent {\n        Text(\"Main Title\", modifier = Modifier.semantics { heading() })\n    }\n\n    composeTestRule\n        .onNode(isHeading())\n        .assertIsDisplayed()\n        .assertTextEquals(\"Main Title\")\n}\n\n@Test\nfun testTouchTarget() {\n    composeTestRule.setContent {\n        Button(modifier = Modifier.size(32.dp)) { Text(\"Too small\") }\n    }\n\n    composeTestRule\n        .onNodeWithText(\"Too small\")\n        .assertHeightIsAtLeast(48.dp)  // Fails: 32.dp < 48.dp\n}\n\n@Test\nfun testCustomAction() {\n    composeTestRule.setContent {\n        Box(\n            modifier = Modifier.semantics {\n                customActions = listOf(\n                    CustomAccessibilityAction(\"Unlock\") { true }\n                )\n            }\n        )\n    }\n\n    composeTestRule\n        .onNode(hasCustomAccessibilityAction(\"Unlock\"))\n        .performCustomAccessibilityAction(\"Unlock\")\n}\n```\n\n---\n\n## Anti-Patterns\n\n### Decorative Images Without null contentDescription\n\n```kotlin\n// DON'T: Screen reader reads useless description\nImage(\n    painter = painterResource(R.drawable.separator_line),\n    contentDescription = \"Line\"  // No value\n)\n\n// DO\nImage(\n    painter = painterResource(R.drawable.separator_line),\n    contentDescription = null\n)\n```\n\n### Clickable Without Semantics\n\n```kotlin\n// DON'T: No semantic role or description\nBox(\n    modifier = Modifier\n        .clickable { deleteItem() }\n        .size(32.dp)\n) {\n    Icon(Icons.Default.Delete, contentDescription = null)\n}\n\n// DO\nBox(\n    modifier = Modifier\n        .clickable { deleteItem() }\n        .sizeIn(minWidth = 48.dp, minHeight = 48.dp)\n        .semantics {\n            role = Role.Button\n            contentDescription = \"Delete item\"\n        },\n    contentAlignment = Alignment.Center\n) {\n    Icon(Icons.Default.Delete, contentDescription = null)\n}\n```\n\n### Hardcoded Content Descriptions Without Context\n\n```kotlin\n// DON'T: Generic, doesn't describe purpose\nIcon(Icons.Default.Star, contentDescription = \"Icon\")\n\n// DO: Specific\nIcon(Icons.Default.Star, contentDescription = \"Add to favorites\")\n```\n\n### Missing Heading Structure\n\n```kotlin\n// DON'T: No navigation structure\nColumn {\n    Text(\"Section 1\")\n    Text(\"Section 2\")\n    Text(\"Section 3\")\n}\n\n// DO\nColumn {\n    Text(\"Section 1\", modifier = Modifier.semantics { heading() })\n    Text(\"Section 2\", modifier = Modifier.semantics { heading() })\n    Text(\"Section 3\", modifier = Modifier.semantics { heading() })\n}\n```\n\n---\n\n## Resources\n\n- **Compose Accessibility**: https://developer.android.com/develop/ui/compose/accessibility\n- **Material Design Accessibility**: https://m3.material.io/foundations/accessible-design\n- **WCAG 2.1**: https://www.w3.org/WAI/WCAG21/quickref/\n- **Testing A11y in Compose**: https://developer.android.com/develop/ui/compose/testing#a11y\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/animation.md",
    "content": "# Animation in Jetpack Compose\n\nReference: `androidx/compose/animation/animation/src/commonMain/kotlin/androidx/compose/animation/`\n\n## State-Based Animations\n\n### animate*AsState\n\nAnimate individual properties by targeting a value. The animation starts when the value changes.\n\n```kotlin\nval size by animateDpAsState(\n    targetValue = if (isExpanded) 200.dp else 100.dp,\n    animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy),\n    label = \"size\"\n)\n\nBox(modifier = Modifier.size(size))\n```\n\nCommon variants:\n\n```kotlin\nanimateColorAsState(targetValue = Color.Blue)\nanimateFloatAsState(targetValue = 1f)\nanimateIntAsState(targetValue = 100)\nanimateOffsetAsState(targetValue = Offset(10f, 20f))\n```\n\nEach automatically handles coroutines and recomposition. Use the `label` parameter for debugging.\n\n## AnimatedVisibility\n\nControls appear/disappear animations with enter and exit transitions.\n\n```kotlin\nvar visible by remember { mutableStateOf(true) }\n\nAnimatedVisibility(visible = visible) {\n    Text(\"Hello!\")\n}\n\n// Trigger\nButton(onClick = { visible = !visible }) { Text(\"Toggle\") }\n```\n\n### Enter/Exit Transitions\n\n```kotlin\nAnimatedVisibility(\n    visible = visible,\n    enter = slideInHorizontally(initialOffsetX = { -it }) + fadeIn(),\n    exit = slideOutHorizontally(targetOffsetX = { -it }) + fadeOut()\n) {\n    Text(\"Animated!\")\n}\n```\n\nBuilt-in transitions:\n- `slideInVertically`, `slideOutVertically`\n- `slideInHorizontally`, `slideOutHorizontally`\n- `expandVertically`, `shrinkVertically`\n- `expandHorizontally`, `shrinkHorizontally`\n- `fadeIn`, `fadeOut`\n- `scaleIn`, `scaleOut`\n- Combine with `+`: `slideInVertically() + fadeIn()`\n\n### Advanced: Custom animation specs\n\n```kotlin\nAnimatedVisibility(\n    visible = visible,\n    enter = slideInVertically(\n        initialOffsetY = { fullHeight -> fullHeight },\n        animationSpec = spring()\n    ),\n    exit = slideOutVertically(\n        targetOffsetY = { fullHeight -> fullHeight },\n        animationSpec = tween(durationMillis = 300)\n    )\n) {\n    Box(Modifier.fillMaxWidth().height(100.dp).background(Color.Blue))\n}\n```\n\n## AnimatedContent\n\nReplace content with smooth transitions.\n\n```kotlin\nvar count by remember { mutableStateOf(0) }\n\nAnimatedContent(targetState = count) { target ->\n    Text(text = \"Count: $target\")\n}\n\nButton(onClick = { count++ }) { Text(\"Increment\") }\n```\n\n### Custom transitionSpec\n\n```kotlin\nAnimatedContent(\n    targetState = count,\n    transitionSpec = {\n        slideInVertically(initialOffsetY = { it }) with slideOutVertically(targetOffsetY = { -it })\n    }\n) { target ->\n    Text(\"$target\")\n}\n```\n\nUse `with` to specify exit and enter together. This runs exits and entries simultaneously.\n\n### Sequencing transitions\n\n```kotlin\nAnimatedContent(\n    targetState = count,\n    transitionSpec = {\n        slideInVertically(initialOffsetY = { it }) with slideOutVertically(targetOffsetY = { -it }) using SizeTransform(clip = false)\n    }\n) { target ->\n    Text(\n        \"Count: $target\",\n        modifier = Modifier.fillMaxWidth()\n    )\n}\n```\n\n`SizeTransform` animates container size smoothly during content changes.\n\n## Crossfade\n\nSimple content swap with fade effect.\n\n```kotlin\nvar showFirst by remember { mutableStateOf(true) }\n\nCrossfade(targetState = showFirst) { state ->\n    if (state) {\n        Text(\"First\")\n    } else {\n        Text(\"Second\")\n    }\n}\n```\n\nLightweight alternative to `AnimatedContent` for simple visibility toggles.\n\n## updateTransition\n\nCoordinate multiple animated values with a single state.\n\n```kotlin\nvar expanded by remember { mutableStateOf(false) }\nval transition = updateTransition(targetState = expanded)\n\nval size by transition.animateDp { if (it) 200.dp else 100.dp }\nval color by transition.animateColor { if (it) Color.Blue else Color.Red }\n\nBox(\n    modifier = Modifier\n        .size(size)\n        .background(color)\n        .clickable { expanded = !expanded }\n)\n```\n\nAll animations run in sync, controlled by a single state change. Useful for complex components with multiple animated properties.\n\n## rememberInfiniteTransition\n\nCreate looping animations.\n\n```kotlin\nval infiniteTransition = rememberInfiniteTransition(label = \"infinite\")\n\nval alpha by infiniteTransition.animateFloat(\n    initialValue = 0f,\n    targetValue = 1f,\n    animationSpec = infiniteRepeatable(\n        animation = tween(1000),\n        repeatMode = RepeatMode.Reverse\n    ),\n    label = \"alpha\"\n)\n\nText(\"Pulsing\", modifier = Modifier.alpha(alpha))\n```\n\nRuns continuously until the composable is removed. Perfect for loading states, pulsing indicators.\n\n## Animatable\n\nImperative animation control in coroutines. Use for fine-grained control.\n\n```kotlin\nval animatable = remember { Animatable(0f) }\n\nLaunchedEffect(trigger) {\n    animatable.animateTo(\n        targetValue = 100f,\n        animationSpec = spring()\n    )\n}\n\nBox(Modifier.graphicsLayer(translationX = animatable.value))\n```\n\nUseful for responding to gestures or complex conditions:\n\n```kotlin\nval animatable = remember { Animatable(0f) }\n\nLaunchedEffect(Unit) {\n    animatable.animateTo(targetValue = 360f, animationSpec = tween(2000))\n}\n\nBox(\n    Modifier\n        .size(100.dp)\n        .background(Color.Blue)\n        .graphicsLayer(rotationZ = animatable.value)\n)\n```\n\n## Animation Specifications\n\n### spring — Realistic, physics-based\n\n```kotlin\nval size by animateDpAsState(\n    targetValue = 200.dp,\n    animationSpec = spring(dampingRatio = Spring.DampingRatioMediumBouncy, stiffness = Spring.StiffnessLow)\n)\n```\n\n- `dampingRatio`: `NoBouncy` (1f), `LowBouncy` (0.75f), `MediumBouncy` (0.5f), `HighBouncy` (0.2f)\n- `stiffness`: `Low`, `Medium`, `High`\n\nUse for interactive feedback, familiar to users.\n\n### tween — Time-based\n\n```kotlin\nval color by animateColorAsState(\n    targetValue = Color.Blue,\n    animationSpec = tween(durationMillis = 500, easing = EaseInOutCubic)\n)\n```\n\nEasing functions: `EaseInQuad`, `EaseOutQuad`, `EaseInOutQuad`, `LinearEasing`, `FastOutSlowInEasing`.\n\nPredictable timing, good for sequential animations.\n\n### keyframes — Frame-by-frame control\n\n```kotlin\nval position by animateFloatAsState(\n    targetValue = 100f,\n    animationSpec = keyframes {\n        0f at 0 using EaseInQuad\n        50f at 150 using EaseOutQuad\n        100f at 300\n    }\n)\n```\n\nDefine exact values at specific timestamps. Use for complex choreography.\n\n## Automatic Size Animation\n\n### animateContentSize\n\nSmoothly animate Box size when content changes.\n\n```kotlin\nvar expanded by remember { mutableStateOf(false) }\n\nBox(\n    modifier = Modifier\n        .animateContentSize()\n        .background(Color.Blue)\n        .clickable { expanded = !expanded }\n) {\n    Column {\n        Text(\"Header\")\n        if (expanded) {\n            Text(\"Expanded content...\")\n        }\n    }\n}\n```\n\nNo need for explicit `AnimatedVisibility` or layout transitions. Handles the container automatically.\n\n## Layout Animation in LazyLists\n\n### animateItem — Replaces animateItemPlacement\n\nAnimate item appearance, removal, and reordering.\n\n```kotlin\nLazyColumn {\n    items(items, key = { it.id }) { item ->\n        Box(\n            modifier = Modifier\n                .fillMaxWidth()\n                .animateItem()\n                .padding(8.dp)\n                .background(Color.Gray)\n        ) {\n            Text(item.name)\n        }\n    }\n}\n```\n\nAutomatically animates:\n- New items sliding in\n- Removed items sliding out\n- Reordered items moving to new positions\n\nCalled on items in Lazy layouts (LazyColumn, LazyRow, LazyVerticalGrid).\n\n## Shared Element Transitions\n\nAnimate elements seamlessly across screen boundaries using `SharedTransitionLayout` and Navigation Compose.\n\n### sharedElement() vs sharedBounds()\n\n| Aspect | `sharedElement()` | `sharedBounds()` |\n|---|---|---|\n| **Content** | Identical on both screens (same image, same icon) | Different content in source and target (e.g., card expands to detail) |\n| **Use case** | Hero image, avatar, thumbnail | Container transform, card-to-page |\n| **During transition** | Only the target composable is rendered | Both source and target are visible and crossfade |\n\n### Complete Working Example\n\n```kotlin\n@Composable\nfun App() {\n    SharedTransitionLayout {\n        NavHost(navController = navController, startDestination = \"list\") {\n            composable(\"list\") {\n                ListScreen(\n                    onItemClick = { id -> navController.navigate(\"detail/$id\") },\n                    sharedTransitionScope = this@SharedTransitionLayout,\n                    animatedVisibilityScope = this@composable\n                )\n            }\n            composable(\"detail/{id}\") { backStackEntry ->\n                val id = backStackEntry.arguments?.getString(\"id\") ?: return@composable\n                DetailScreen(\n                    itemId = id,\n                    sharedTransitionScope = this@SharedTransitionLayout,\n                    animatedVisibilityScope = this@composable\n                )\n            }\n        }\n    }\n}\n\n@Composable\nfun ListScreen(\n    onItemClick: (String) -> Unit,\n    sharedTransitionScope: SharedTransitionScope,\n    animatedVisibilityScope: AnimatedVisibilityScope\n) {\n    with(sharedTransitionScope) {\n        Row(\n            modifier = Modifier\n                .clickable { onItemClick(item.id) }\n                // sharedBounds wraps the entire card container (different content at source/target)\n                .sharedBounds(\n                    sharedContentState = rememberSharedContentState(key = \"card-${item.id}\"),\n                    animatedVisibilityScope = animatedVisibilityScope,\n                    boundsTransform = BoundsTransform { initialBounds, targetBounds ->\n                        keyframes {\n                            durationMillis = 500\n                            initialBounds at 0 using ArcMode.ArcBelow\n                            targetBounds at 500\n                        }\n                    }\n                )\n        ) {\n            Image(\n                painter = painterResource(item.imageRes),\n                contentDescription = null,\n                modifier = Modifier\n                    .size(80.dp)\n                    // sharedElement for the identical image across screens\n                    .sharedElement(\n                        state = rememberSharedContentState(key = \"image-${item.id}\"),\n                        animatedVisibilityScope = animatedVisibilityScope\n                    )\n            )\n            Text(\n                text = item.title,\n                modifier = Modifier\n                    .sharedElement(\n                        state = rememberSharedContentState(key = \"title-${item.id}\"),\n                        animatedVisibilityScope = animatedVisibilityScope\n                    )\n                    // Prevent text reflow during transition by snapping to final size\n                    .skipToLookaheadSize()\n            )\n        }\n    }\n}\n\n@Composable\nfun DetailScreen(\n    itemId: String,\n    sharedTransitionScope: SharedTransitionScope,\n    animatedVisibilityScope: AnimatedVisibilityScope\n) {\n    with(sharedTransitionScope) {\n        Column(\n            modifier = Modifier\n                .sharedBounds(\n                    sharedContentState = rememberSharedContentState(key = \"card-$itemId\"),\n                    animatedVisibilityScope = animatedVisibilityScope\n                )\n        ) {\n            Image(\n                painter = painterResource(item.imageRes),\n                contentDescription = null,\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .height(300.dp)\n                    .sharedElement(\n                        state = rememberSharedContentState(key = \"image-$itemId\"),\n                        animatedVisibilityScope = animatedVisibilityScope\n                    )\n            )\n            Text(\n                text = item.title,\n                style = MaterialTheme.typography.headlineMedium,\n                modifier = Modifier\n                    .sharedElement(\n                        state = rememberSharedContentState(key = \"title-$itemId\"),\n                        animatedVisibilityScope = animatedVisibilityScope\n                    )\n                    .skipToLookaheadSize()\n            )\n            // Non-shared content fades in\n            Text(\n                text = item.description,\n                modifier = Modifier.animateEnterExit(\n                    enter = fadeIn() + slideInVertically { it / 3 },\n                    exit = fadeOut()\n                )\n            )\n        }\n    }\n}\n```\n\n### BoundsTransform for Arc Motion\n\nControl the animation path between source and target bounds:\n\n```kotlin\nval arcBoundsTransform = BoundsTransform { initialBounds, targetBounds ->\n    keyframes {\n        durationMillis = 500\n        initialBounds at 0 using ArcMode.ArcBelow\n        targetBounds at 500\n    }\n}\n\n// Apply to sharedElement or sharedBounds\nModifier.sharedElement(\n    state = rememberSharedContentState(key = \"hero\"),\n    animatedVisibilityScope = animatedVisibilityScope,\n    boundsTransform = arcBoundsTransform\n)\n```\n\n### Overlay Rendering\n\nKeep shared elements above all other content during the transition:\n\n```kotlin\nModifier.sharedElement(\n    state = rememberSharedContentState(key = \"fab\"),\n    animatedVisibilityScope = animatedVisibilityScope,\n    renderInSharedTransitionScopeOverlay = true // Renders above navigation transitions\n)\n```\n\n### Preventing Text Reflow\n\nUse `skipToLookaheadSize()` so text composables snap to their final size immediately, avoiding awkward line-break changes mid-transition:\n\n```kotlin\nText(\n    text = item.title,\n    modifier = Modifier\n        .sharedElement(\n            state = rememberSharedContentState(key = \"title-${item.id}\"),\n            animatedVisibilityScope = animatedVisibilityScope\n        )\n        .skipToLookaheadSize() // Text uses target size immediately, no reflow\n)\n```\n\n## Performance: graphicsLayer for Transforms\n\nAnimate transforms using `graphicsLayer` instead of layout changes.\n\n```kotlin\n// ✅ Correct: Uses GPU-accelerated graphicsLayer\nval offset by animateFloatAsState(targetValue = 100f)\nBox(modifier = Modifier.graphicsLayer(translationX = offset))\n\n// ❌ Avoid: Causes recomposition and relayout\nval offset by animateFloatAsState(targetValue = 100f)\nBox(modifier = Modifier.offset(x = offset.dp))\n```\n\nUse `graphicsLayer` for:\n- Translation (`translationX`, `translationY`)\n- Rotation (`rotationX`, `rotationY`, `rotationZ`)\n- Scale (`scaleX`, `scaleY`)\n- Alpha (opacity)\n\n## Anti-Patterns\n\n### Don't: Animate visibility with if\n\n```kotlin\n// ❌ Anti-pattern\n@Composable\nfun MyScreen() {\n    if (visible) {\n        Text(\"Content\") // Jumps in/out without animation\n    }\n}\n\n// ✅ Correct\n@Composable\nfun MyScreen() {\n    AnimatedVisibility(visible = visible) {\n        Text(\"Content\")\n    }\n}\n```\n\n### Don't: Create Animatable in composition\n\n```kotlin\n// ❌ Anti-pattern\n@Composable\nfun MyScreen() {\n    val animatable = Animatable(0f) // Recreated every recomposition!\n\n    LaunchedEffect(Unit) {\n        animatable.animateTo(100f)\n    }\n}\n\n// ✅ Correct\n@Composable\nfun MyScreen() {\n    val animatable = remember { Animatable(0f) } // Preserved across recompositions\n\n    LaunchedEffect(Unit) {\n        animatable.animateTo(100f)\n    }\n}\n```\n\n### Don't: Animate in composition phase\n\n```kotlin\n// ❌ Anti-pattern\n@Composable\nfun MyScreen() {\n    var position by remember { mutableStateOf(0f) }\n    position = position + 10f // Infinite recomposition loop!\n}\n\n// ✅ Correct\n@Composable\nfun MyScreen() {\n    var position by remember { mutableStateOf(0f) }\n\n    LaunchedEffect(Unit) {\n        repeat(10) {\n            position += 10f\n            delay(16)\n        }\n    }\n}\n```\n\n### Don't: Forget label parameter\n\n```kotlin\n// ❌ Anti-pattern (harder to debug)\nval size by animateDpAsState(targetValue = 100.dp)\n\n// ✅ Correct\nval size by animateDpAsState(\n    targetValue = 100.dp,\n    label = \"box_size\"\n)\n```\n\nLabels help with debugging layout inspector and animation inspection tools.\n\n---\n\n## Animation Decision Tree\n\n### When to Use Which API\n\n| API | Use When |\n|---|---|\n| `animate*AsState` | Animating a single property (size, color, alpha) driven by state |\n| `AnimatedVisibility` | Showing or hiding a composable with enter/exit transitions |\n| `AnimatedContent` / `Crossfade` | Switching between different composables (content swap) |\n| `updateTransition` | Multiple properties that must animate in sync from the same state |\n| `Animatable` | Gesture-driven or imperative control (coroutine-based, supports `snapTo`, `animateDecay`) |\n| `rememberInfiniteTransition` | Infinite looping animations (pulsing, rotating, shimmer) |\n| `animateContentSize` | Smoothly animating a container's size when its content changes |\n| `animateItem` | List item appearance, disappearance, and reordering in Lazy layouts |\n\n### Which Phase Each Animation Affects\n\nCompose rendering has three phases: **Composition** (what to show), **Layout** (where to place), **Draw** (how to render). Animations should read state in the latest possible phase to minimize work.\n\n```kotlin\n// BEST: Draw phase only — no relayout, no recomposition\nval alpha by animateFloatAsState(targetValue = if (visible) 1f else 0f, label = \"alpha\")\nBox(\n    modifier = Modifier.graphicsLayer { this.alpha = alpha }\n)\n\n// GOOD: Layout phase only — relayout but no recomposition\nval offsetPx by animateIntAsState(targetValue = if (moved) 300 else 0, label = \"offset\")\nBox(\n    modifier = Modifier.offset { IntOffset(offsetPx, 0) }\n)\n\n// MODERATE: Composition + Layout — triggers recomposition on every frame\nval offsetDp by animateDpAsState(targetValue = if (moved) 100.dp else 0.dp, label = \"offset\")\nBox(\n    modifier = Modifier.offset(x = offsetDp)\n)\n```\n\n**Rule:** Defer state reads to the latest possible phase. Use lambda-based modifiers (`graphicsLayer { }`, `offset { }`) instead of parameter-based modifiers (`graphicsLayer(alpha = ...)`, `offset(x = ...)`).\n\n---\n\n## Design-to-Animation Translation\n\n### Figma Easing Curves to Compose\n\n| Figma Easing | Compose Equivalent |\n|---|---|\n| Linear | `LinearEasing` |\n| Ease In | `FastOutLinearInEasing` |\n| Ease Out | `LinearOutSlowInEasing` |\n| Ease In and Out | `FastOutSlowInEasing` |\n| Custom Bezier (x1, y1, x2, y2) | `CubicBezierEasing(x1, y1, x2, y2)` |\n\n### M3 Motion Duration Tokens\n\n| Token | Duration |\n|---|---|\n| Short1 | 50ms |\n| Short2 | 100ms |\n| Short3 | 150ms |\n| Short4 | 200ms |\n| Medium1 | 250ms |\n| Medium2 | 300ms |\n| Medium3 | 350ms |\n| Medium4 | 400ms |\n| Long1 | 450ms |\n| Long2 | 500ms |\n| Long3 | 550ms |\n| Long4 | 600ms |\n| ExtraLong1 | 700ms |\n| ExtraLong2 | 800ms |\n| ExtraLong3 | 900ms |\n| ExtraLong4 | 1000ms |\n\n### M3 Easing Tokens\n\n| Token | Compose Value |\n|---|---|\n| Emphasized | `CubicBezierEasing(0.2f, 0f, 0f, 1f)` |\n| EmphasizedDecelerate | `CubicBezierEasing(0.05f, 0.7f, 0.1f, 1f)` |\n| EmphasizedAccelerate | `CubicBezierEasing(0.3f, 0f, 0.8f, 0.15f)` |\n| Standard | `FastOutSlowInEasing` |\n| StandardDecelerate | `LinearOutSlowInEasing` |\n| StandardAccelerate | `FastOutLinearInEasing` |\n\n### Spring Parameter Intuition\n\n**Stiffness** (how fast the animation moves toward its target):\n\n| Value | Constant | Feel |\n|---|---|---|\n| ~26f | — | Slow, heavy, lethargic |\n| 200f | `Spring.StiffnessLow` | Gentle, relaxed |\n| 400f | `Spring.StiffnessMediumLow` | Casual, comfortable |\n| 1500f | `Spring.StiffnessMedium` | Responsive, default |\n| 10000f | `Spring.StiffnessHigh` | Snappy, immediate |\n\n**Damping Ratio** (how much bounce):\n\n| Value | Constant | Feel |\n|---|---|---|\n| 1.0f | `Spring.DampingRatioNoBouncy` | No overshoot, settles directly |\n| 0.75f | `Spring.DampingRatioLowBouncy` | Subtle bounce, professional |\n| 0.5f | `Spring.DampingRatioMediumBouncy` | Playful, noticeable bounce |\n| 0.2f | `Spring.DampingRatioHighBouncy` | Exaggerated, cartoonish bounce |\n\n### Figma Spring to Compose Conversion\n\n```kotlin\nfun figmaSpringToCompose(mass: Float, stiffness: Float, damping: Float): SpringSpec<Float> {\n    val dampingRatio = damping / (2f * sqrt(stiffness * mass))\n    return spring(dampingRatio = dampingRatio, stiffness = stiffness)\n}\n```\n\n### Production-Validated Spring Specs\n\n```kotlin\nval figmaMatchedSpring = spring<Float>(dampingRatio = 0.444f, stiffness = 26.5f)\nval responsiveSpring = spring<Float>(dampingRatio = 0.7f, stiffness = 800f)\nval snappySpring = spring<Float>(dampingRatio = 0.6f, stiffness = 1000f)\n```\n\n---\n\n## Gesture-Driven Animations\n\n### Swipe-to-Dismiss with Animatable\n\n```kotlin\nfun Modifier.swipeToDismiss(onDismiss: () -> Unit): Modifier = composed {\n    val offsetX = remember { Animatable(0f) }\n    val decay = rememberSplineBasedDecay<Float>()\n\n    pointerInput(Unit) {\n        coroutineScope {\n            while (true) {\n                val velocityTracker = VelocityTracker()\n                // Wait for touch down\n                val pointerId = awaitPointerEventScope {\n                    awaitFirstDown().id\n                }\n                // Cancel any ongoing animation\n                offsetX.stop()\n\n                awaitPointerEventScope {\n                    horizontalDrag(pointerId) { change ->\n                        val horizontalDragOffset = offsetX.value + change.positionChange().x\n                        launch { offsetX.snapTo(horizontalDragOffset) }\n                        velocityTracker.addPosition(change.uptimeMillis, change.position)\n                        change.consume()\n                    }\n                }\n\n                val velocity = velocityTracker.calculateVelocity().x\n                val targetOffsetX = decay.calculateTargetValue(offsetX.value, velocity)\n\n                offsetX.updateBounds(\n                    lowerBound = -size.width.toFloat(),\n                    upperBound = size.width.toFloat()\n                )\n\n                launch {\n                    if (abs(targetOffsetX) >= size.width * 0.5f) {\n                        // Fling far enough — dismiss\n                        offsetX.animateDecay(velocity, decay)\n                        onDismiss()\n                    } else {\n                        // Snap back\n                        offsetX.animateTo(\n                            targetValue = 0f,\n                            initialVelocity = velocity\n                        )\n                    }\n                }\n            }\n        }\n    }.offset { IntOffset(offsetX.value.roundToInt(), 0) }\n}\n```\n\n### AnchoredDraggable Snap Points\n\n```kotlin\nenum class DragValue { Start, Center, End }\n\n@Composable\nfun AnchoredDraggableExample() {\n    val density = LocalDensity.current\n    val anchors = with(density) {\n        DraggableAnchors {\n            DragValue.Start at -200.dp.toPx()\n            DragValue.Center at 0f\n            DragValue.End at 200.dp.toPx()\n        }\n    }\n\n    val state = remember {\n        AnchoredDraggableState(\n            initialValue = DragValue.Center,\n            anchors = anchors,\n            positionalThreshold = { totalDistance -> totalDistance * 0.5f },\n            velocityThreshold = { with(density) { 125.dp.toPx() } },\n            animationSpec = spring()\n        )\n    }\n\n    Box(\n        modifier = Modifier\n            .offset { IntOffset(state.requireOffset().roundToInt(), 0) }\n            .anchoredDraggable(state, Orientation.Horizontal)\n            .size(80.dp)\n            .background(Color.Blue, RoundedCornerShape(16.dp))\n    )\n}\n```\n\n### Transformable: Pinch, Zoom, Rotate\n\n```kotlin\n@Composable\nfun TransformableExample() {\n    var scale by remember { mutableFloatStateOf(1f) }\n    var rotation by remember { mutableFloatStateOf(0f) }\n    var offset by remember { mutableStateOf(Offset.Zero) }\n\n    val transformableState = rememberTransformableState { zoomChange, offsetChange, rotationChange ->\n        scale = (scale * zoomChange).coerceIn(0.5f, 5f)\n        rotation += rotationChange\n        offset += offsetChange\n    }\n\n    Box(\n        modifier = Modifier\n            .graphicsLayer {\n                scaleX = scale\n                scaleY = scale\n                rotationZ = rotation\n                translationX = offset.x\n                translationY = offset.y\n            }\n            .transformable(state = transformableState)\n            .size(200.dp)\n            .background(Color.Blue)\n    )\n}\n```\n\n---\n\n## Animation Recipes\n\n### Shimmer / Skeleton Loading\n\n```kotlin\nfun Modifier.shimmerEffect(): Modifier = composed {\n    val transition = rememberInfiniteTransition(label = \"shimmer\")\n    val translateAnim by transition.animateFloat(\n        initialValue = -1000f,\n        targetValue = 1000f,\n        animationSpec = infiniteRepeatable(\n            animation = tween(durationMillis = 1200, easing = LinearEasing),\n            repeatMode = RepeatMode.Restart\n        ),\n        label = \"shimmer_translate\"\n    )\n\n    val shimmerBrush = Brush.linearGradient(\n        colors = listOf(\n            Color.LightGray.copy(alpha = 0.6f),\n            Color.LightGray.copy(alpha = 0.2f),\n            Color.LightGray.copy(alpha = 0.6f)\n        ),\n        start = Offset(translateAnim, 0f),\n        end = Offset(translateAnim + 500f, 0f)\n    )\n\n    background(shimmerBrush)\n}\n\n@Composable\nfun SkeletonCard() {\n    Column(modifier = Modifier.padding(16.dp)) {\n        Box(\n            modifier = Modifier\n                .fillMaxWidth()\n                .height(200.dp)\n                .clip(RoundedCornerShape(12.dp))\n                .shimmerEffect()\n        )\n        Spacer(modifier = Modifier.height(8.dp))\n        Box(\n            modifier = Modifier\n                .fillMaxWidth(0.7f)\n                .height(20.dp)\n                .clip(RoundedCornerShape(4.dp))\n                .shimmerEffect()\n        )\n    }\n}\n\n@Composable\nfun ContentWithLoading(isLoading: Boolean, content: @Composable () -> Unit) {\n    Crossfade(targetState = isLoading, label = \"loading_crossfade\") { loading ->\n        if (loading) {\n            SkeletonCard()\n        } else {\n            content()\n        }\n    }\n}\n```\n\n### Staggered List Entrance\n\n```kotlin\n@Composable\nfun StaggeredListEntrance(items: List<String>) {\n    Column {\n        items.forEachIndexed { index, item ->\n            val animatable = remember { Animatable(0f) }\n            LaunchedEffect(Unit) {\n                delay(index * 100L)\n                animatable.animateTo(\n                    targetValue = 1f,\n                    animationSpec = spring(\n                        dampingRatio = Spring.DampingRatioLowBouncy,\n                        stiffness = Spring.StiffnessMediumLow\n                    )\n                )\n            }\n            Text(\n                text = item,\n                modifier = Modifier\n                    .graphicsLayer {\n                        alpha = animatable.value\n                        translationX = (1f - animatable.value) * 100f\n                    }\n                    .padding(8.dp)\n            )\n        }\n    }\n}\n```\n\n### Swipe-to-Dismiss (Material 3)\n\n```kotlin\n@Composable\nfun SwipeToDismissItem(\n    onDismiss: () -> Unit,\n    content: @Composable () -> Unit\n) {\n    val dismissState = rememberSwipeToDismissBoxState(\n        confirmValueChange = { value ->\n            if (value != SwipeToDismissBoxValue.Settled) {\n                onDismiss()\n                true\n            } else false\n        }\n    )\n\n    SwipeToDismissBox(\n        state = dismissState,\n        backgroundContent = {\n            val color by animateColorAsState(\n                targetValue = when (dismissState.targetValue) {\n                    SwipeToDismissBoxValue.StartToEnd -> Color.Green\n                    SwipeToDismissBoxValue.EndToStart -> Color.Red\n                    SwipeToDismissBoxValue.Settled -> Color.Transparent\n                },\n                label = \"dismiss_bg\"\n            )\n            Box(\n                modifier = Modifier\n                    .fillMaxSize()\n                    .background(color)\n                    .padding(horizontal = 20.dp),\n                contentAlignment = when (dismissState.targetValue) {\n                    SwipeToDismissBoxValue.StartToEnd -> Alignment.CenterStart\n                    else -> Alignment.CenterEnd\n                }\n            ) {\n                Icon(\n                    imageVector = when (dismissState.targetValue) {\n                        SwipeToDismissBoxValue.StartToEnd -> Icons.Default.Done\n                        else -> Icons.Default.Delete\n                    },\n                    contentDescription = null,\n                    tint = Color.White\n                )\n            }\n        }\n    ) {\n        content()\n    }\n}\n```\n\n### Expandable Card\n\n```kotlin\n@Composable\nfun ExpandableCard(title: String, description: String) {\n    var expanded by remember { mutableStateOf(false) }\n    val arrowRotation by animateFloatAsState(\n        targetValue = if (expanded) 180f else 0f,\n        label = \"arrow_rotation\"\n    )\n\n    Card(\n        modifier = Modifier\n            .fillMaxWidth()\n            .animateContentSize(animationSpec = spring(stiffness = Spring.StiffnessMediumLow))\n            .clickable { expanded = !expanded }\n    ) {\n        Column(modifier = Modifier.padding(16.dp)) {\n            Row(verticalAlignment = Alignment.CenterVertically) {\n                Text(text = title, style = MaterialTheme.typography.titleMedium, modifier = Modifier.weight(1f))\n                Icon(\n                    imageVector = Icons.Default.KeyboardArrowDown,\n                    contentDescription = if (expanded) \"Collapse\" else \"Expand\",\n                    modifier = Modifier.graphicsLayer { rotationZ = arrowRotation }\n                )\n            }\n            AnimatedVisibility(visible = expanded) {\n                Text(\n                    text = description,\n                    style = MaterialTheme.typography.bodyMedium,\n                    modifier = Modifier.padding(top = 8.dp)\n                )\n            }\n        }\n    }\n}\n```\n\n### Pull-to-Refresh Custom\n\n```kotlin\n@Composable\nfun CustomPullToRefresh(\n    isRefreshing: Boolean,\n    onRefresh: () -> Unit,\n    content: @Composable () -> Unit\n) {\n    PullToRefreshBox(\n        isRefreshing = isRefreshing,\n        onRefresh = onRefresh,\n        indicator = { state ->\n            val distanceFraction = state.distanceFraction.coerceIn(0f, 1f)\n            Box(\n                modifier = Modifier\n                    .fillMaxWidth()\n                    .padding(top = 16.dp),\n                contentAlignment = Alignment.TopCenter\n            ) {\n                Icon(\n                    imageVector = Icons.Default.Refresh,\n                    contentDescription = \"Refreshing\",\n                    modifier = Modifier\n                        .size(32.dp)\n                        .graphicsLayer {\n                            scaleX = distanceFraction\n                            scaleY = distanceFraction\n                            rotationZ = distanceFraction * 360f\n                        }\n                )\n            }\n        }\n    ) {\n        content()\n    }\n}\n```\n\n### FAB Morph\n\n**Pattern 1: ExtendedFloatingActionButton with scroll-driven expand/collapse**\n\n```kotlin\n@Composable\nfun CollapsibleFab(listState: LazyListState) {\n    val expandedFab by remember {\n        derivedStateOf { listState.firstVisibleItemIndex == 0 }\n    }\n\n    ExtendedFloatingActionButton(\n        onClick = { /* action */ },\n        expanded = expandedFab,\n        icon = { Icon(Icons.Default.Add, contentDescription = \"Add\") },\n        text = { Text(\"New Item\") }\n    )\n}\n```\n\n**Pattern 2: Exploding FAB with updateTransition**\n\n```kotlin\n@Composable\nfun ExplodingFab(isExpanded: Boolean, onClick: () -> Unit) {\n    val transition = updateTransition(targetState = isExpanded, label = \"fab_explode\")\n\n    val size by transition.animateDp(label = \"size\") { if (it) 200.dp else 56.dp }\n    val cornerRadius by transition.animateDp(label = \"corner\") { if (it) 16.dp else 28.dp }\n    val color by transition.animateColor(label = \"color\") {\n        if (it) MaterialTheme.colorScheme.secondaryContainer\n        else MaterialTheme.colorScheme.primaryContainer\n    }\n    val contentAlpha by transition.animateFloat(label = \"alpha\") { if (it) 1f else 0f }\n\n    Surface(\n        modifier = Modifier.size(size).clickable { onClick() },\n        shape = RoundedCornerShape(cornerRadius),\n        color = color\n    ) {\n        Box(contentAlignment = Alignment.Center) {\n            if (!isExpanded) {\n                Icon(Icons.Default.Add, contentDescription = \"Add\")\n            }\n            Column(\n                modifier = Modifier.graphicsLayer { alpha = contentAlpha },\n                horizontalAlignment = Alignment.CenterHorizontally\n            ) {\n                // Expanded content\n                Text(\"Option 1\")\n                Text(\"Option 2\")\n                Text(\"Option 3\")\n            }\n        }\n    }\n}\n```\n\n### Bottom Sheet Drag\n\n```kotlin\nenum class SheetValue { Hidden, Collapsed, Expanded }\n\n@Composable\nfun DraggableBottomSheet(content: @Composable () -> Unit) {\n    val density = LocalDensity.current\n    val anchors = with(density) {\n        DraggableAnchors {\n            SheetValue.Hidden at 0f\n            SheetValue.Collapsed at -200.dp.toPx()\n            SheetValue.Expanded at -600.dp.toPx()\n        }\n    }\n\n    val state = remember {\n        AnchoredDraggableState(\n            initialValue = SheetValue.Hidden,\n            anchors = anchors,\n            positionalThreshold = { totalDistance -> totalDistance * 0.5f },\n            velocityThreshold = { with(density) { 125.dp.toPx() } },\n            animationSpec = spring(stiffness = Spring.StiffnessMediumLow)\n        )\n    }\n\n    Box(modifier = Modifier.fillMaxSize()) {\n        content()\n\n        Surface(\n            modifier = Modifier\n                .fillMaxWidth()\n                .align(Alignment.BottomCenter)\n                .offset { IntOffset(0, (state.requireOffset()).roundToInt()) }\n                .anchoredDraggable(state, Orientation.Vertical),\n            shape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp),\n            shadowElevation = 8.dp\n        ) {\n            Column(modifier = Modifier.fillMaxWidth().height(600.dp).padding(16.dp)) {\n                // Drag handle\n                Box(\n                    modifier = Modifier\n                        .align(Alignment.CenterHorizontally)\n                        .width(40.dp)\n                        .height(4.dp)\n                        .background(Color.Gray, RoundedCornerShape(2.dp))\n                )\n                Spacer(modifier = Modifier.height(16.dp))\n                Text(\"Sheet Content\")\n            }\n        }\n    }\n}\n```\n\n### Parallax Scroll Header\n\n```kotlin\n@Composable\nfun ParallaxHeader(scrollState: ScrollState) {\n    val scrollOffset = scrollState.value.toFloat()\n\n    Box(\n        modifier = Modifier\n            .fillMaxWidth()\n            .height(300.dp)\n            .graphicsLayer {\n                translationY = scrollOffset * 0.6f // Parallax factor\n                scaleX = 1f + (scrollOffset * 0.001f).coerceAtLeast(0f)\n                scaleY = 1f + (scrollOffset * 0.001f).coerceAtLeast(0f)\n                alpha = (1f - (scrollOffset / 600f)).coerceIn(0f, 1f)\n            }\n    ) {\n        Image(\n            painter = painterResource(R.drawable.header),\n            contentDescription = null,\n            contentScale = ContentScale.Crop,\n            modifier = Modifier.fillMaxSize()\n        )\n    }\n}\n```\n\n### Animated Tab Switch\n\n```kotlin\n@Composable\nfun AnimatedTabContent(selectedTabIndex: Int) {\n    AnimatedContent(\n        targetState = selectedTabIndex,\n        transitionSpec = {\n            val direction = if (targetState > initialState) 1 else -1\n            slideInHorizontally(\n                initialOffsetX = { fullWidth -> direction * fullWidth },\n                animationSpec = tween(300)\n            ) + fadeIn(animationSpec = tween(300)) togetherWith\n            slideOutHorizontally(\n                targetOffsetX = { fullWidth -> -direction * fullWidth },\n                animationSpec = tween(300)\n            ) + fadeOut(animationSpec = tween(300)) using\n            SizeTransform(clip = false)\n        },\n        label = \"tab_content\"\n    ) { tabIndex ->\n        when (tabIndex) {\n            0 -> TabOneContent()\n            1 -> TabTwoContent()\n            2 -> TabThreeContent()\n        }\n    }\n}\n```\n\n---\n\n## Sequential/Parallel Animation Choreography\n\n### Sequential (Coroutine Chaining)\n\nEach `animateTo` suspends until complete, so chaining them creates sequential animation:\n\n```kotlin\nval alpha = remember { Animatable(0f) }\nval translateY = remember { Animatable(100f) }\nval scale = remember { Animatable(0.5f) }\n\nLaunchedEffect(Unit) {\n    alpha.animateTo(1f, animationSpec = tween(300))\n    translateY.animateTo(0f, animationSpec = spring())\n    scale.animateTo(1f, animationSpec = tween(200))\n}\n```\n\n### Parallel (Multiple launch blocks)\n\n```kotlin\nval alpha = remember { Animatable(0f) }\nval translateY = remember { Animatable(100f) }\n\nLaunchedEffect(Unit) {\n    coroutineScope {\n        launch { alpha.animateTo(1f, animationSpec = tween(300)) }\n        launch { translateY.animateTo(0f, animationSpec = spring()) }\n    }\n    // Code here runs after BOTH animations complete\n}\n```\n\n### Staggered Delays\n\n```kotlin\nval items = remember { List(5) { Animatable(0f) } }\n\nLaunchedEffect(Unit) {\n    items.forEachIndexed { index, animatable ->\n        launch {\n            delay(index * 80L)\n            animatable.animateTo(1f, animationSpec = spring())\n        }\n    }\n}\n```\n\n### Mixed Sequential + Parallel\n\n```kotlin\nLaunchedEffect(Unit) {\n    // Phase 1: Sequential — fade in first\n    alpha.animateTo(1f, animationSpec = tween(200))\n\n    // Phase 2: Parallel — move and scale at the same time\n    coroutineScope {\n        launch { translateY.animateTo(0f, animationSpec = spring()) }\n        launch { scale.animateTo(1f, animationSpec = spring()) }\n    }\n\n    // Phase 3: Sequential — final flourish after Phase 2 completes\n    rotation.animateTo(360f, animationSpec = tween(400))\n}\n```\n\n---\n\n## Predictive Back Gesture Animation (Android 14+)\n\n### NavHost Transitions\n\n```kotlin\nNavHost(\n    navController = navController,\n    startDestination = \"home\",\n    enterTransition = {\n        slideInHorizontally(initialOffsetX = { it }) + fadeIn(animationSpec = tween(300))\n    },\n    exitTransition = {\n        slideOutHorizontally(targetOffsetX = { -it / 3 }) + fadeOut(animationSpec = tween(300))\n    },\n    popEnterTransition = {\n        slideInHorizontally(initialOffsetX = { -it / 3 }) + fadeIn(animationSpec = tween(300))\n    },\n    popExitTransition = {\n        slideOutHorizontally(targetOffsetX = { it }) + fadeOut(animationSpec = tween(300))\n    }\n) {\n    composable(\"home\") { HomeScreen() }\n    composable(\"detail\") { DetailScreen() }\n}\n```\n\n### PredictiveBackHandler\n\n```kotlin\n@Composable\nfun PredictiveBackExample(onBack: () -> Unit) {\n    var boxScale by remember { mutableFloatStateOf(1f) }\n\n    PredictiveBackHandler(enabled = true) { progress: Flow<BackEventCompat> ->\n        try {\n            progress.collect { backEvent ->\n                boxScale = 1f - (0.3f * backEvent.progress)\n            }\n            onBack()\n        } catch (e: CancellationException) {\n            boxScale = 1f\n            throw e\n        }\n    }\n\n    Box(\n        modifier = Modifier\n            .fillMaxSize()\n            .graphicsLayer {\n                scaleX = boxScale\n                scaleY = boxScale\n            }\n    ) {\n        Text(\"Swipe back to see scale animation\")\n    }\n}\n```\n\n### M3 Automatic Predictive Back\n\nThese Material 3 components animate with predictive back gestures out of the box (no extra code needed):\n\n- `SearchBar` — collapses back on swipe\n- `ModalBottomSheet` — slides down with gesture progress\n- `ModalNavigationDrawer` — slides closed with gesture progress\n\n---\n\n## Additional Anti-Patterns\n\n### Don't: Read animated state in composition when draw-phase suffices\n\n```kotlin\n// BAD: Reads alpha during composition, triggers recomposition every frame\nval alpha by animateFloatAsState(targetValue = 0.5f, label = \"alpha\")\nBox(modifier = Modifier.alpha(alpha))\n\n// GOOD: Reads alpha during draw phase only, skips recomposition\nval alpha by animateFloatAsState(targetValue = 0.5f, label = \"alpha\")\nBox(modifier = Modifier.graphicsLayer { this.alpha = alpha })\n```\n\n### Don't: Use offset(x, y) for animated movement\n\n```kotlin\n// BAD: Parameter-based offset triggers recomposition + relayout\nval animatedDp by animateDpAsState(targetValue = 100.dp, label = \"x\")\nBox(modifier = Modifier.offset(x = animatedDp))\n\n// BETTER: Lambda offset — layout phase only, no recomposition\nval animatedPx by animateIntAsState(targetValue = 300, label = \"x\")\nBox(modifier = Modifier.offset { IntOffset(animatedPx, 0) })\n\n// BEST: graphicsLayer — draw phase only\nval animatedPx by animateFloatAsState(targetValue = 300f, label = \"x\")\nBox(modifier = Modifier.graphicsLayer { translationX = animatedPx })\n```\n\n### Don't: Use updateTransition for independent properties\n\n```kotlin\n// BAD: Properties don't need synchronization but are coupled\nval transition = updateTransition(targetState = state, label = \"t\")\nval alpha by transition.animateFloat(label = \"a\") { if (it) 1f else 0f }\nval size by transition.animateDp(label = \"s\") { if (it) 200.dp else 100.dp }\n\n// GOOD: Independent properties use separate animate*AsState\nval alpha by animateFloatAsState(targetValue = if (state) 1f else 0f, label = \"alpha\")\nval size by animateDpAsState(targetValue = if (state) 200.dp else 100.dp, label = \"size\")\n```\n\n### Don't: Hardcode arbitrary durations\n\n```kotlin\n// BAD: Arbitrary duration with no design rationale\nval anim by animateFloatAsState(\n    targetValue = 1f,\n    animationSpec = tween(durationMillis = 347),\n    label = \"anim\"\n)\n\n// GOOD: Use M3 motion tokens for consistency\nval anim by animateFloatAsState(\n    targetValue = 1f,\n    animationSpec = tween(durationMillis = MotionTokens.DurationMedium2.toInt()),\n    label = \"anim\"\n)\n\n// BETTER: Use spring() for interruptible, natural-feeling animations\nval anim by animateFloatAsState(\n    targetValue = 1f,\n    animationSpec = spring(stiffness = Spring.StiffnessMedium),\n    label = \"anim\"\n)\n```\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/atomic-design.md",
    "content": "# Atomic Design System Reference\n\nBuilding reusable, hierarchical component systems in Jetpack Compose and Compose Multiplatform.\nBased on Brad Frost's atomic design methodology, mapped to Compose primitives.\n\n---\n\n## 1. The 5-Level Hierarchy Mapped to Compose\n\n| Level | Compose Equivalent | Examples |\n|-------|-------------------|----------|\n| **Tokens** | `MaterialTheme.colorScheme.*`, `MaterialTheme.typography.*`, custom `CompositionLocal` tokens (spacing, elevation, brand colors) | `AppTheme.spacing.medium`, `AppTheme.colors.brandPrimary` |\n| **Atoms** | Single-purpose composables with one responsibility, slot API, modifier param. Either wrap M3 or build custom. | `AppButton`, `AppTextField`, `AppAvatar`, `AppIcon` |\n| **Molecules** | Composables that combine 2+ atoms into a functional unit | `SearchBar` (icon + text field), `MovieCard` (image + text), `UserListItem` |\n| **Organisms** | Screen sections combining molecules into a UI region | `MovieCatalogRow` (header + LazyRow of MovieCards), `NavigationDrawerWithContent` |\n| **Templates** | Screen layouts defining content areas without data — `Scaffold` + slot composition | `MainScreenTemplate(topBar, content, bottomBar)`, `DetailScreenTemplate(hero, body, actions)` |\n\n**Dependency rule:** each level depends only on levels below it. An organism should not use\nraw `Text()` — it should use an atom. A molecule should not hardcode colors — it should use\ntokens via `MaterialTheme` or custom `CompositionLocal`.\n\n```\nTemplate\n  └── Organism\n        └── Molecule\n              └── Atom\n                    └── Token (MaterialTheme / CompositionLocal)\n```\n\n---\n\n## 2. Token Layer\n\nTokens are the foundation. Every visual property (color, typography, spacing, shape, motion)\nshould come from a token — never hardcoded in a composable body.\n\n### M3 tokens (use directly)\n\nThese are already provided by `MaterialTheme`:\n\n- `MaterialTheme.colorScheme` — primary, secondary, surface, error, etc.\n- `MaterialTheme.typography` — displayLarge through labelSmall\n- `MaterialTheme.shapes` — extraSmall through extraLarge\n- `MaterialTheme.motionScheme` — `defaultSpatialSpec()`, `defaultEffectsSpec()`\n\n### App-level custom tokens\n\nCreate when M3 doesn't cover your need. Use `CompositionLocal` + a wrapper theme.\n\n**Spacing scale:**\n```kotlin\nobject AppSpacing {\n    val xxs = 2.dp\n    val xs = 4.dp\n    val sm = 8.dp\n    val md = 16.dp\n    val lg = 24.dp\n    val xl = 32.dp\n}\nval LocalAppSpacing = staticCompositionLocalOf { AppSpacing }\n```\n\n**Brand colors (beyond M3 colorScheme):**\n```kotlin\ndata class AppBrandColors(\n    val accent: Color,\n    val onAccent: Color,\n    val surface: Color,\n)\nval LocalAppBrandColors = staticCompositionLocalOf {\n    AppBrandColors(\n        accent = Color.Unspecified,\n        onAccent = Color.Unspecified,\n        surface = Color.Unspecified,\n    )\n}\n```\n\n**Access pattern — wrap in `AppTheme`:**\n```kotlin\n@Composable\nfun AppTheme(content: @Composable () -> Unit) {\n    CompositionLocalProvider(\n        LocalAppSpacing provides AppSpacing,\n        LocalAppBrandColors provides AppBrandColors(\n            accent = Color(0xFF1A73E8),\n            onAccent = Color.White,\n            surface = Color(0xFFF5F5F5),\n        )\n    ) {\n        MaterialTheme(\n            colorScheme = /* your color scheme */,\n            typography = /* your typography */,\n            shapes = /* your shapes */,\n        ) {\n            content()\n        }\n    }\n}\n\n// Usage anywhere in the tree:\nval spacing = LocalAppSpacing.current\nval brandColors = LocalAppBrandColors.current\n```\n\n**When to create a custom token vs. use M3 directly:**\n- M3 covers it → use `MaterialTheme.*` directly\n- App-specific concept (brand accent, spacing scale, elevation scale) → custom `CompositionLocal`\n- One-off value needed in a single component → not a token, just a local constant\n\n---\n\n## 3. Atom Patterns\n\nAtoms are the smallest reusable UI units. Every atom must satisfy the **atom contract**.\n\n### Atom Contract\n\nEvery atom (public composable that renders UI) must satisfy:\n\n1. **`modifier: Modifier = Modifier` parameter** — caller controls layout\n2. **Slot APIs for variable content** — `@Composable () -> Unit` or scoped like `@Composable RowScope.() -> Unit`\n3. **Token-based styling** — no hardcoded `Color(0xFF...)`, `14.sp`, `FontWeight.Bold`\n4. **Sensible defaults** — works without configuration\n5. **Preview composable** — `@Preview` function for visual verification\n\n### Two atom types\n\n**1. M3 wrapper atoms** — wrap an M3 component with brand defaults:\n\n```kotlin\n@Composable\nfun AppButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    content: @Composable RowScope.() -> Unit,\n) {\n    Button(\n        onClick = onClick,\n        modifier = modifier,\n        enabled = enabled,\n        colors = ButtonDefaults.buttonColors(\n            containerColor = LocalAppBrandColors.current.accent,\n            contentColor = LocalAppBrandColors.current.onAccent,\n        ),\n        content = content,\n    )\n}\n```\n\n**2. Custom atoms** — when no M3 equivalent exists:\n\n```kotlin\n@Composable\nfun AppAvatar(\n    imageUrl: String,\n    size: AvatarSize = AvatarSize.Medium,\n    modifier: Modifier = Modifier,\n    contentDescription: String? = null,\n) {\n    AsyncImage(\n        model = imageUrl,\n        contentDescription = contentDescription,\n        contentScale = ContentScale.Crop,\n        modifier = modifier\n            .size(size.dp)\n            .clip(CircleShape)\n    )\n}\n\nenum class AvatarSize(val dp: Dp) {\n    Small(24.dp), Medium(40.dp), Large(56.dp)\n}\n```\n\n### Naming rule\n\nName by what the component **IS**, not where it's used.\n\n| Bad | Good | Why |\n|-----|------|-----|\n| `ButtonWithBoldCTA` | `AppButton` | The boldness is a style variant, not a component |\n| `RedBorderCard` | `HighlightCard` or `AppCard` | Named by visual appearance, not function |\n| `HomeMovieCard` | `MovieCard` | Named by screen, not reusable |\n| `ButtonForSettings` | `AppButton` | Named by context, not function |\n\n---\n\n## 4. Molecule, Organism, and Template Patterns\n\n### Molecule — composes 2+ atoms\n\nA molecule combines atoms into a functional unit. It accepts data and callbacks, not ViewModels.\n\n```kotlin\n@Composable\nfun MovieCard(\n    movie: Movie,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n) {\n    AppCard(onClick = onClick, modifier = modifier) {\n        AppImage(url = movie.posterUrl, contentDescription = movie.title)\n        AppText(text = movie.title, style = MaterialTheme.typography.titleSmall)\n        AppText(text = movie.year.toString(), style = MaterialTheme.typography.bodySmall)\n    }\n}\n```\n\n### Organism — composes molecules into a UI region\n\nAn organism is a screen section. It still accepts data as parameters — never reads from a ViewModel directly.\n\n```kotlin\n@Composable\nfun MovieCatalogRow(\n    title: String,\n    movies: List<Movie>,\n    onMovieClick: (Movie) -> Unit,\n    modifier: Modifier = Modifier,\n) {\n    Column(modifier = modifier) {\n        AppText(text = title, style = MaterialTheme.typography.headlineSmall)\n        LazyRow(\n            horizontalArrangement = Arrangement.spacedBy(LocalAppSpacing.current.sm)\n        ) {\n            items(movies, key = { it.id }) { movie ->\n                MovieCard(movie = movie, onClick = { onMovieClick(movie) })\n            }\n        }\n    }\n}\n```\n\n### Template — defines screen layout via slot composition\n\nTemplates define where content goes, not what it is. They accept slot parameters, no data.\n\n```kotlin\n@Composable\nfun CatalogScreenTemplate(\n    topBar: @Composable () -> Unit,\n    hero: @Composable () -> Unit,\n    sections: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n) {\n    Scaffold(topBar = topBar, modifier = modifier) { padding ->\n        LazyColumn(contentPadding = padding) {\n            item { hero() }\n            item { sections() }\n        }\n    }\n}\n```\n\n### Level summary\n\n| Level | Accepts | Composes | ViewModel? |\n|-------|---------|----------|-----------|\n| Atom | Primitives, slots, modifier | M3 components or raw Compose | No |\n| Molecule | Data classes, callbacks, modifier | Atoms | No |\n| Organism | Data, callbacks, modifier | Molecules + atoms | No |\n| Template | Slots only, modifier | Scaffold + layout | No |\n| Screen | ViewModel | Template + organisms + molecules | Yes — this is the only level that touches ViewModel |\n\n---\n\n## 5. The \"Ask\" Prompt\n\nWhen the skill detects component-building intent (user asks to \"build a card\", \"create a button\",\n\"implement this component\"), **before scaffolding code**, ask:\n\n> \"This looks like a **[molecule/organism]**. Should I also scaffold the **[lower-level] atoms**\n> it needs, or does your codebase already have them?\"\n\nThe developer can answer:\n\n| Answer | Skill behavior |\n|--------|---------------|\n| \"Yes, scaffold everything\" | Create from token layer up — define spacing/color tokens, atoms, then the requested component |\n| \"Just build the card\" | Build the requested component using atomic principles (slots, modifier, tokens) but don't create lower-level atoms |\n| \"We already have AppButton, AppImage\" | Reuse those atoms, only build the new molecule/organism |\n\n**The skill always applies atomic principles regardless of the answer.** The question is only\nabout whether to scaffold lower levels. Every component gets:\n- `modifier: Modifier = Modifier`\n- Slot APIs where appropriate\n- Token-based styling (no hardcoded values)\n- Sensible defaults\n\n---\n\n## 6. Anti-Patterns\n\n| Anti-Pattern | Why It's Wrong | Fix |\n|-------------|---------------|-----|\n| `Color(0xFF1A73E8)` inside a composable body | Hardcoded color — not themeable, not dark-mode-safe | Use `MaterialTheme.colorScheme.*` or app brand token |\n| `fontSize = 14.sp`, `fontWeight = FontWeight.Bold` | Hardcoded typography breaks consistency | Use `MaterialTheme.typography.*` |\n| `Modifier.padding(16.dp)` without spacing token | Magic number spacing — inconsistent across app | Use `LocalAppSpacing.current.md` (or define a spacing scale) |\n| Composable named `ButtonForSettings` / `CardWithRedBorder` | Named by context, not by function — not reusable | Name by what it IS: `AppButton`, `HighlightCard` |\n| Public composable with no `modifier` parameter | Caller cannot control layout | Add `modifier: Modifier = Modifier`, pass to root element |\n| Composable rendering UI with no slot parameters | Content is hardcoded, not composable | Add slot APIs for variable content |\n| Raw `Text()` / `Button()` / `Icon()` in an organism | Skips atomic levels — loses theming and consistency | Use app-level atom wrappers |\n| Organism that directly reads ViewModel | Couples UI to data layer — not reusable, not previewable | Accept data and callbacks as parameters; let the screen call ViewModel |\n| Molecule with more than 3–4 responsibilities | Too much in one component — hard to reuse parts | Decompose into smaller molecules or extract atoms |\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/auto-init.md",
    "content": "# Auto-Init: Compose Project Detection\n\nActivate on `session_start`. Detect whether the current project uses Compose and\nsilently activate the skill with a brief announcement.\n\n---\n\n## Detection Gate\n\nRun in order. Stop on first match.\n\n### Step 1 — Gradle scan\n\nLook for `build.gradle.kts`, `build.gradle`, or `libs.versions.toml` in the working\ndirectory or one level up. Check file contents for any of:\n\n- `compose`\n- `androidx.compose`\n- `org.jetbrains.compose`\n- `compose-multiplatform`\n\n```bash\n# Check working directory and parent\nfor dir in . ..; do\n  for file in build.gradle.kts build.gradle libs.versions.toml; do\n    if [ -f \"$dir/$file\" ]; then\n      grep -qi \"compose\\|androidx\\.compose\\|org\\.jetbrains\\.compose\\|compose-multiplatform\" \"$dir/$file\" && echo \"DETECTED\" && break 2\n    fi\n  done\ndone\n```\n\n### Step 2 — Source scan fallback\n\nIf no Gradle file found or no Compose reference in Gradle, scan Kotlin source files.\n\n```bash\n# Find up to 10 .kt files (exclude build dirs), check for @Composable\nfind . -name \"*.kt\" -not -path \"*/build/*\" -print -quit 2>/dev/null | head -10 | \\\n  xargs grep -l \"@Composable\" 2>/dev/null | head -1\n```\n\nIf any file contains `@Composable`, detection succeeds.\n\n---\n\n## On Detection\n\nPrint one line:\n\n```\nCompose project detected — compose-expert skill active.\n```\n\nThen proceed normally — wait for the user's request and follow the standard workflow\nin `SKILL.md`.\n\n## On No Detection\n\nDo nothing. The skill remains available if the user explicitly triggers it via\nkeyword (e.g., mentions `@Composable`, `LazyColumn`, `NavHost`, etc.) later in\nthe session.\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/composition-locals.md",
    "content": "# CompositionLocals: Implicit Data Passing in Jetpack Compose\n\nCompositionLocals provide a way to pass data implicitly down the composition tree without threading it through every function parameter. They're analogous to SwiftUI's `@Environment`.\n\n## What Are CompositionLocals?\n\nA CompositionLocal is a slot in the composition that holds a value accessible to any descendant composable without explicit parameter passing. Values are provided using `CompositionLocalProvider` and accessed via `current`.\n\n```kotlin\nval localAppTheme = compositionLocalOf { \"Light\" }\n\n@Composable\nfun MyScreen() {\n  CompositionLocalProvider(localAppTheme provides \"Dark\") {\n    DescendantComposable() // Can access \"Dark\" via localAppTheme.current\n  }\n}\n\n@Composable\nfun DescendantComposable() {\n  Text(localAppTheme.current) // Reads \"Dark\"\n}\n```\n\n**Source:** `androidx/compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionLocal.kt`\n\n## compositionLocalOf vs staticCompositionLocalOf\n\nThe key difference is **when recomposition is triggered** when a value changes.\n\n### compositionLocalOf\nCauses recomposition of all descendants when the value changes. Use when children genuinely depend on the value.\n\n```kotlin\nval LocalUserPreferences = compositionLocalOf { UserPreferences() }\n```\n\n**Recomposition behavior:** All consumers recompose.\n\n### staticCompositionLocalOf\nNo recomposition of descendants; only the direct reader is affected. Use when you're **confident descendants don't depend on updates**, or updates are infrequent.\n\n```kotlin\nval LocalAppVersion = staticCompositionLocalOf { \"1.0.0\" }\n```\n\n**⚠️ Pitfall:** If a child reads `LocalAppVersion.current` and expects updates, you'll get stale data. Only use for truly static configuration.\n\n### compositionLocalWithComputedDefaultOf\nIntroduced for computed default values. The lambda is called each time the value is read when no provider is active.\n\n```kotlin\nval LocalResources = compositionLocalWithComputedDefaultOf { context.resources }\n```\n\nThis is more efficient than `compositionLocalOf { lazy { ... } }` because it avoids capturing state unnecessarily.\n\n## Built-In CompositionLocals\n\nThe Compose runtime and UI libraries provide standard locals:\n\n| Local | Type | Purpose |\n|-------|------|---------|\n| `LocalContext` | `Context` | Android Context (requires AndroidCompositionLocals) |\n| `LocalConfiguration` | `Configuration` | Screen size, orientation, density |\n| `LocalDensity` | `Density` | Pixel density for dp/px conversion |\n| `LocalLayoutDirection` | `LayoutDirection` | LTR/RTL directionality |\n| `LocalView` | `View` | Underlying Android View (if available) |\n| `LocalLifecycleOwner` | `LifecycleOwner` | Activity/Fragment lifecycle |\n| `LocalSavedStateRegistryOwner` | `SavedStateRegistryOwner` | For state persistence |\n\n**Source:** `androidx/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidCompositionLocals.android.kt`\n\n```kotlin\n@Composable\nfun MyComposable() {\n  val context = LocalContext.current\n  val density = LocalDensity.current\n  val config = LocalConfiguration.current\n\n  Text(\"Screen width: ${config.screenWidthDp}dp\")\n}\n```\n\n## Providing Values with CompositionLocalProvider\n\nProvide one or multiple local values:\n\n```kotlin\n// Single local\nCompositionLocalProvider(LocalUserPreferences provides user) {\n  Content()\n}\n\n// Multiple locals\nCompositionLocalProvider(\n  LocalUserPreferences provides user,\n  LocalTheme provides darkTheme,\n  LocalLanguage provides \"en\"\n) {\n  Content()\n}\n```\n\nValues are **scoped** to descendants only:\n\n```kotlin\nCompositionLocalProvider(LocalUserPreferences provides userA) {\n  ComponentA() // Sees userA\n  CompositionLocalProvider(LocalUserPreferences provides userB) {\n    ComponentB() // Sees userB (overrides)\n  }\n  ComponentC() // Sees userA (original)\n}\n```\n\n## Creating Custom CompositionLocals\n\nCreate locals at top level, outside composable functions:\n\n```kotlin\ndata class AppTheme(val isDark: Boolean, val colors: Colors)\n\nval LocalAppTheme = compositionLocalOf<AppTheme> {\n  error(\"AppTheme not provided\")\n}\n\n// For nullable defaults\nval LocalOptionalUser = compositionLocalOf<User?> { null }\n```\n\n**When to create a CompositionLocal:**\n- Value is needed by many descendants\n- Threading it as a parameter creates \"prop drilling\"\n- Value is configuration-like (theme, locale, permissions)\n\n**When NOT to use CompositionLocal:**\n- Only 1–2 levels of composables need it → use parameters\n- Value changes frequently and children need precise control → use State/ViewModel\n- It's a dependency that should be testable → prefer parameters or dependency injection\n\n## Testing with CompositionLocals\n\nProvide test doubles to avoid real implementations:\n\n```kotlin\n@Composable\nfun MyScreen() {\n  val user = LocalUserRepository.current\n  Text(user.name)\n}\n\n// In test\n@Test\nfun testMyScreen() {\n  composeRule.setContent {\n    CompositionLocalProvider(\n      LocalUserRepository provides FakeUserRepository(User(\"Test User\"))\n    ) {\n      MyScreen()\n    }\n  }\n  composeRule.onNodeWithText(\"Test User\").assertExists()\n}\n```\n\n## Anti-Patterns\n\n### ✗ Using CompositionLocal as Generic Dependency Injection\n```kotlin\n// Bad: obscures dependencies, hard to test\nval LocalEverything = compositionLocalOf { AppContainer() }\n\n@Composable\nfun MyScreen() {\n  val container = LocalEverything.current\n  val repo = container.userRepo\n  val cache = container.cache\n}\n```\n\n**Better:** Provide specific locals or pass dependencies as parameters.\n\n### ✗ Reading LocalContext Repeatedly\n```kotlin\n// Inefficient: reads on every recomposition\n@Composable\nfun MyComposable() {\n  val context = LocalContext.current // Reading repeatedly\n  // ...\n}\n```\n\n**Better:** Read once outside the lambda or cache in remember:\n\n```kotlin\n@Composable\nfun MyComposable() {\n  val context = LocalContext.current\n  val effect = remember(context) { /* use context */ }\n}\n```\n\n### ✗ Storing Mutable State in CompositionLocal\n```kotlin\n// Bad: state changes won't trigger recomposition properly\nval LocalCounter = compositionLocalOf { mutableStateOf(0) }\n```\n\n**Better:** Store the State in a parent composable and provide the value, not the State:\n\n```kotlin\nval LocalCount = compositionLocalOf { 0 }\n\n@Composable\nfun Parent() {\n  var count by remember { mutableStateOf(0) }\n  CompositionLocalProvider(LocalCount provides count) {\n    Child()\n  }\n}\n```\n\n## Key Takeaways\n\n1. Use `compositionLocalOf` for values that children read and depend on updates\n2. Use `staticCompositionLocalOf` only for truly static values\n3. Prefer parameters over CompositionLocals unless you have significant nesting\n4. Always provide a sensible error default or nullable type\n5. Test by providing fake implementations via `CompositionLocalProvider`\n6. CompositionLocals are not a replacement for proper architecture — use them for configuration and environment data, not general dependency injection\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/deprecated-patterns.md",
    "content": "# Deprecated Patterns & API Migrations in Jetpack Compose\n\nThis guide covers major API changes and deprecations in Compose's evolution. Each section shows the old pattern → new approach with migration notes.\n\n---\n\n## String-Based Routes → Type-Safe `@Serializable` Routes\n\n**Old (pre-2.8):**\n```kotlin\nNavHost(navController, startDestination = \"home\") {\n    composable(\"home\") { HomeScreen() }\n    composable(\"details/{id}\") { backStackEntry ->\n        DetailsScreen(id = backStackEntry.arguments?.getString(\"id\"))\n    }\n}\n```\n\n**New (Navigation 2.8+):**\n```kotlin\n@Serializable data class Home\n@Serializable data class Details(val id: String)\n\nNavHost(navController, startDestination = Home) {\n    composable<Home> { HomeScreen() }\n    composable<Details> { backStackEntry ->\n        val args: Details = backStackEntry.toRoute()\n        DetailsScreen(id = args.id)\n    }\n}\n```\n\n**Migration notes:** Type-safe routes eliminate string typos and runtime crashes. Requires `kotlinx-serialization` plugin and `navigation-compose:2.8.0+`. Encode complex objects using custom serializers.\n\n---\n\n## `accompanist-systemuicontroller` → `enableEdgeToEdge()`\n\n**Old:**\n```kotlin\nval systemUiController = rememberSystemUiController()\nsystemUiController.setSystemBarsColor(\n    color = Color.Transparent,\n    darkIcons = false\n)\n```\n\n**New (Compose 1.7+):**\n```kotlin\nenableEdgeToEdge()\n// In Activity.onCreate() before setContent {}\n```\n\n**Migration notes:** Built-in since Compose 1.7. Automatically handles status bar, navigation bar, and IME behind content. Remove `accompanist-systemuicontroller` dependency entirely.\n\n---\n\n## `accompanist-pager` → `HorizontalPager`/`VerticalPager`\n\n**Old:**\n```kotlin\nval pagerState = rememberPagerState()\nHorizontalPager(count = items.size, state = pagerState) { page ->\n    PageContent(items[page])\n}\n```\n\n**New (Foundation):**\n```kotlin\nval pagerState = rememberPagerState(pageCount = { items.size })\nHorizontalPager(state = pagerState) { page ->\n    PageContent(items[page])\n}\n```\n\n**Migration notes:** Native Pager in `foundation:1.6+` replaces accompanist. Removes external dependency. State initialization slightly different; pass lambda for dynamic page counts.\n\n---\n\n## `accompanist-swiperefresh` → `PullToRefreshBox`\n\n**Old:**\n```kotlin\nSwipeRefresh(state = rememberSwipeRefreshState(isRefreshing), onRefresh = { load() }) {\n    LazyColumn { items(data) { item -> ItemRow(item) } }\n}\n```\n\n**New (Material3):**\n```kotlin\nPullToRefreshBox(isRefreshing = isRefreshing, onRefresh = { load() }) {\n    LazyColumn { items(data) { item -> ItemRow(item) } }\n}\n```\n\n**Migration notes:** `PullToRefreshBox` in `material3:1.2+` is the official replacement. Cleaner API. Remove `accompanist-swiperefresh` dependency.\n\n---\n\n## `accompanist-flowlayout` → `FlowRow`/`FlowColumn`\n\n**Old:**\n```kotlin\nFlowRow(mainAxisSize = SizeMode.Expand) {\n    items.forEach { item -> Chip(text = item) }\n}\n```\n\n**New (Foundation):**\n```kotlin\nFlowRow(modifier = Modifier.fillMaxWidth()) {\n    items.forEach { item -> Chip(text = item) }\n}\n```\n\n**Migration notes:** FlowRow/FlowColumn in `foundation:1.6+`. API simplified; use standard modifiers instead of `SizeMode`. Better performance and less memory overhead.\n\n---\n\n## `LazyColumn { animateItemPlacement() }` → `LazyColumn { animateItem() }`\n\n**Old:**\n```kotlin\nLazyColumn {\n    items(items, key = { it.id }) { item ->\n        ItemRow(item.name, Modifier.animateItemPlacement())\n    }\n}\n```\n\n**New:**\n```kotlin\nLazyColumn {\n    items(items, key = { it.id }) { item ->\n        ItemRow(item.name, Modifier.animateItem())\n    }\n}\n```\n\n**Migration notes:** `animateItem()` is the modern API (Compose 1.7+). Returns animation state for finer control. `animateItemPlacement()` still works but is superseded.\n\n---\n\n## `Modifier.composed` Pattern → `Modifier.Node` API\n\n**Old:**\n```kotlin\nfun Modifier.myModifier(value: Int) = composed {\n    val state = remember { mutableStateOf(value) }\n    Modifier.fillMaxWidth().padding(8.dp)\n}\n```\n\n**New:**\n```kotlin\nfun Modifier.myModifier(value: Int) = this.then(\n    Modifier\n        .fillMaxWidth()\n        .padding(8.dp)\n)\n// Or for complex state:\nclass MyModifierNode(val value: Int) : ModifierNodeElement<MyNodeImpl>() {\n    override fun create() = MyNodeImpl(value)\n    override fun update(node: MyNodeImpl) { node.value = value }\n}\nprivate class MyNodeImpl(var value: Int) : Modifier.Node\n```\n\n**Migration notes:** `composed {}` incurs overhead; avoid if no `remember` calls needed. For stateful modifiers, prefer `ModifierNode` API (Compose 1.8+). Benchmark before migrating existing code.\n\n---\n\n## Primitive State Optimization: `mutableStateOf(0)` → `mutableIntStateOf(0)`\n\n**Old:**\n```kotlin\nvar count by remember { mutableStateOf(0) }\nvar temperature by remember { mutableStateOf(37.5f) }\n```\n\n**New:**\n```kotlin\nvar count by remember { mutableIntStateOf(0) }\nvar temperature by remember { mutableFloatStateOf(37.5f) }\n```\n\n**Migration notes:** Primitive-specific functions (`mutableIntStateOf`, `mutableFloatStateOf`, `mutableLongStateOf`) avoid boxing. Negligible performance impact in UI code but best practice since Compose 1.4+.\n\n---\n\n## `collectAsState()` → `collectAsStateWithLifecycle()`\n\n**Old:**\n```kotlin\nval state by viewModel.uiState.collectAsState()\n```\n\n**New:**\n```kotlin\nval state by viewModel.uiState.collectAsStateWithLifecycle()\n```\n\n**Migration notes:** `collectAsStateWithLifecycle()` (Compose 1.6+) respects lifecycle—automatically stops collecting when activity is paused. Prevents memory leaks and redundant work. Requires `androidx.lifecycle:lifecycle-runtime-compose`.\n\n---\n\n## `@ExperimentalMaterial3Api` Graduation\n\n**Old:**\n```kotlin\n@OptIn(ExperimentalMaterial3Api::class)\nfun MyScreen() {\n    DatePicker(state = rememberDatePickerState())\n}\n```\n\n**New (Compose 1.8+, Material3 1.3+):**\n```kotlin\nfun MyScreen() {\n    DatePicker(state = rememberDatePickerState())\n}\n```\n\n**Migration notes:** DatePicker, TimePicker, ExposedDropdownMenuBox, and SearchBar graduated to stable in Material3 1.3+. Remove `@OptIn` annotations. APIs are stable—safe for production use.\n\n---\n\n## `Scaffold` Padding Enforcement\n\n**Old (problematic):**\n```kotlin\nScaffold(topBar = { TopAppBar() }) {\n    LazyColumn { items(data) { item -> ItemRow(item) } }\n}\n```\n\n**New (required since 1.6+):**\n```kotlin\nScaffold(topBar = { TopAppBar() }) { innerPadding ->\n    LazyColumn(modifier = Modifier.padding(innerPadding)) {\n        items(data) { item -> ItemRow(item) }\n    }\n}\n```\n\n**Migration notes:** Must use `innerPadding` parameter since Compose 1.6. Ignoring it causes content overlap under system bars. The compiler enforces this now—old pattern won't compile.\n\n---\n\n## Material 2 → Material 3 Migration\n\n**Old (Material):**\n```kotlin\nButton(onClick = { }) { Text(\"Click\") }\nTextField(value = text, onValueChange = { text = it })\nSurface(color = MaterialTheme.colors.primary) { /* */ }\n```\n\n**New (Material3):**\n```kotlin\nButton(onClick = { }) { Text(\"Click\") }  // Same signature\nTextField(value = text, onValueChange = { text = it })  // Same signature\nSurface(color = MaterialTheme.colorScheme.primary) { /* */ }\n```\n\n**Migration notes:** Most Composables are API-compatible. Main changes: `colors` → `colorScheme`, new shape system, updated ripple defaults. Use Compose BOM to align Material3 versions.\n\n---\n\n## `WindowInsets` & Edge-to-Edge\n\n**Old:**\n```kotlin\nSurface(modifier = Modifier.systemBarsPadding()) { /* */ }\n```\n\n**New (API 35+ default edge-to-edge):**\n```kotlin\nSurface(modifier = Modifier.padding(WindowInsets.systemBars.asPaddingValues())) { /* */ }\n// Or use enableEdgeToEdge() in Activity—handles automatically\n```\n\n**Migration notes:** Edge-to-edge is default on Android 15+. System bar colors are managed by `enableEdgeToEdge()`. Use `WindowInsets.safeDrawing` for notch-aware layouts. Deprecate manual `systemBarsPadding()` calls.\n\n---\n\n## `ObservableState` Pattern Changes\n\n**Old:**\n```kotlin\n@Composable\nfun observe(state: ObservableState): State<T> = produceState(state.value) {\n    state.onChange { value = it }\n}\n```\n\n**New:**\n```kotlin\n@Composable\nfun <T> ObservableState<T>.asState(): State<T> = produceState(this.value) {\n    snapshotFlow { value }.collect { value = it }\n}\n```\n\n**Migration notes:** `snapshotFlow {}` is preferred over direct listeners (Compose 1.6+). Integrates better with Compose's snapshot system. Use `distinctUntilChanged()` to avoid redundant recompositions.\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/design-to-compose.md",
    "content": "# Design-to-Compose Translation Reference\n\nTranslating visual designs (Figma mockups, screenshots, wireframes) into production Compose code. This guide provides a systematic decomposition algorithm, property mapping tables, and patterns that produce clean, theme-aware, accessible composables on the first pass.\n\n---\n\n## 1. Composable Decomposition Algorithm\n\nA divide-and-conquer approach for breaking any visual design into composable functions. Work top-down, outside-in.\n\n### Step 1: Identify Root Layout Structure\n\nLook at the full screen first. What is the outermost structural pattern?\n\n| Visual Pattern | Compose Root |\n|---|---|\n| Top bar + content + bottom bar | `Scaffold` |\n| Scrollable vertical content | `Column` + `verticalScroll()` or `LazyColumn` |\n| Tabbed sections | `Scaffold` + `TabRow` + `HorizontalPager` |\n| Full-bleed background with overlays | `Box` |\n| Side drawer + content | `ModalNavigationDrawer` + `Scaffold` |\n| Bottom sheet over content | `ModalBottomSheet` or `Scaffold` + `BottomSheetScaffold` |\n\n### Step 2: Decompose into Visual Sections (Top-Down)\n\nScan the design from top to bottom. Draw horizontal lines between visually distinct sections. Each section becomes a composable or a block within the parent layout.\n\n```\n+---------------------------+\n|  Top App Bar              |  -> TopAppBar()\n+---------------------------+\n|  Hero Image               |  -> HeroSection()\n+---------------------------+\n|  Title + Subtitle         |  -> HeaderSection()\n+---------------------------+\n|  Horizontal card list     |  -> FeaturedCardsRow()\n+---------------------------+\n|  Vertical item list       |  -> ItemList()\n+---------------------------+\n|  Bottom navigation        |  -> NavigationBar()\n+---------------------------+\n```\n\n**Do:** Name sections by their purpose (`FeaturedCardsRow`), not their layout (`HorizontalScrollRow`).\n\n**Don't:** Create a composable for every Figma frame. Flatten where possible.\n\n### Step 3: For Each Section, Identify Layout Type\n\n```\nIs content stacked vertically?\n  └─ Yes → Column\n       └─ Is list dynamic/long? → LazyColumn\n\nIs content arranged horizontally?\n  └─ Yes → Row\n       └─ Does it scroll? → LazyRow\n       └─ Does it wrap to next line? → FlowRow\n\nIs content overlapping/layered?\n  └─ Yes → Box\n\nIs it a grid?\n  └─ Fixed columns → LazyVerticalGrid\n  └─ Fixed item size → LazyVerticalStaggeredGrid\n  └─ Wrapping chips/tags → FlowRow\n```\n\n**Decision tree for layout selection:**\n\n```\n                    ┌─ Overlapping layers? ──→ Box\n                    │\n  Visual section ───┼─ Single axis? ──→ Vertical? ──→ Column / LazyColumn\n                    │                  └─ Horizontal? ──→ Row / LazyRow\n                    │\n                    └─ Grid / wrap? ──→ Fixed columns? ──→ LazyVerticalGrid\n                                       └─ Flowing tags? ──→ FlowRow\n```\n\n### Step 4: Extract Visual Properties\n\nFor each element, read these from the design:\n\n- **Colors** — map to `MaterialTheme.colorScheme.*` tokens, not hex values\n- **Typography** — map to `MaterialTheme.typography.*` text styles\n- **Spacing** — padding and gaps in dp, map to theme spacing tokens\n- **Elevation** — shadow depth, map to `tonalElevation` or `shadowElevation`\n- **Corner radius** — map to `MaterialTheme.shapes.*`\n\n### Step 5: Identify Interactive Elements and Map to M3 Components\n\n| Visual Element | Compose M3 Component |\n|---|---|\n| Rounded rectangle with text + click | `Button` / `OutlinedButton` / `TextButton` |\n| Card with image, title, subtitle | `Card` / `ElevatedCard` / `OutlinedCard` |\n| Text input field | `TextField` / `OutlinedTextField` |\n| Toggle switch | `Switch` |\n| Checkbox | `Checkbox` / `TriStateCheckbox` |\n| Chips / tags | `FilterChip` / `AssistChip` / `InputChip` / `SuggestionChip` |\n| Floating action button | `FloatingActionButton` / `ExtendedFloatingActionButton` |\n| Bottom navigation | `NavigationBar` + `NavigationBarItem` |\n| Side navigation | `NavigationRail` / `NavigationDrawer` |\n| Top bar | `TopAppBar` / `CenterAlignedTopAppBar` |\n| Dialog / modal | `AlertDialog` / `BasicAlertDialog` |\n| Progress indicator | `CircularProgressIndicator` / `LinearProgressIndicator` |\n| Divider line | `HorizontalDivider` |\n| Image with rounded corners | `Image` + `Modifier.clip()` |\n| Dropdown menu | `ExposedDropdownMenuBox` |\n| Slider | `Slider` / `RangeSlider` |\n\n---\n\n## 2. Figma-to-Compose Property Mapping Tables\n\n### Layout Containers\n\n| Figma Concept | Compose Equivalent |\n|---|---|\n| Frame (no auto-layout) | `Box` |\n| Auto-layout Vertical | `Column` |\n| Auto-layout Horizontal | `Row` |\n| Auto-layout Wrap | `FlowRow` / `FlowColumn` |\n| Grid (fixed columns) | `LazyVerticalGrid(columns = GridCells.Fixed(n))` |\n| Absolute-positioned child | `Box` + `Modifier.offset(x, y)` or `Modifier.align()` |\n| Component with variants | Composable function with parameters |\n| Component instance | Function call site |\n| Section / Group (organizational) | No composable needed; flatten into parent |\n\n### Sizing Modes\n\n| Figma Sizing | Compose Modifier |\n|---|---|\n| Fixed width/height | `Modifier.size(w.dp, h.dp)` or `.width(w.dp).height(h.dp)` |\n| Hug contents | Default behavior (wrap content) -- no modifier needed |\n| Fill container (horizontal) | `Modifier.fillMaxWidth()` |\n| Fill container (vertical) | `Modifier.fillMaxHeight()` |\n| Fill container (both) | `Modifier.fillMaxSize()` |\n| Fill with min width | `Modifier.fillMaxWidth().widthIn(min = minW.dp)` |\n| Fill with max width | `Modifier.fillMaxWidth().widthIn(max = maxW.dp)` |\n| Fill with min/max height | `Modifier.fillMaxHeight().heightIn(min = ..., max = ...)` |\n| Aspect ratio constraint | `Modifier.aspectRatio(ratio)` |\n\n### Spacing Model\n\n**Key principle: the parent owns spacing.**\n\n| Figma Spacing | Compose Equivalent |\n|---|---|\n| Padding (all sides) | `Modifier.padding(all.dp)` on the container |\n| Padding (per side) | `Modifier.padding(start = ..., top = ..., end = ..., bottom = ...)` |\n| Gap between children (vertical auto-layout) | `Column(verticalArrangement = Arrangement.spacedBy(gap.dp))` |\n| Gap between children (horizontal auto-layout) | `Row(horizontalArrangement = Arrangement.spacedBy(gap.dp))` |\n| Space between (distribute) | `Arrangement.SpaceBetween` |\n| Space around | `Arrangement.SpaceAround` |\n\n**Do:** Use `start`/`end` instead of `left`/`right` for RTL language support.\n\n```kotlin\n// Correct: RTL-aware\nModifier.padding(start = 16.dp, end = 8.dp)\n\n// Wrong: breaks in RTL locales\nModifier.padding(left = 16.dp, right = 8.dp)  // Avoid\n```\n\n**Do:** Use `Arrangement.spacedBy()` for uniform gaps. Avoid inserting `Spacer` between every child.\n\n```kotlin\n// Do: clean and uniform\nColumn(verticalArrangement = Arrangement.spacedBy(12.dp)) {\n    Text(\"First\")\n    Text(\"Second\")\n    Text(\"Third\")\n}\n\n// Don't: manual spacers everywhere\nColumn {\n    Text(\"First\")\n    Spacer(Modifier.height(12.dp))\n    Text(\"Second\")\n    Spacer(Modifier.height(12.dp))\n    Text(\"Third\")\n}\n```\n\n### Shadow Mapping (Compose 1.9+)\n\nCompose Foundation 1.9 introduced `dropShadow()` and `innerShadow()` as modifier extensions, replacing the legacy `shadow()` modifier for fine-grained control.\n\n```kotlin\n// Drop shadow: place BEFORE background in the modifier chain\nBox(\n    Modifier\n        .dropShadow(\n            shape = RoundedCornerShape(12.dp),\n            color = Color.Black.copy(alpha = 0.15f),\n            blur = 8.dp,\n            offsetX = 0.dp,\n            offsetY = 4.dp,\n            spread = 0.dp\n        )\n        .background(Color.White, RoundedCornerShape(12.dp))\n        .padding(16.dp)\n)\n\n// Inner shadow: place AFTER background in the modifier chain\nBox(\n    Modifier\n        .background(Color.White, RoundedCornerShape(12.dp))\n        .innerShadow(\n            shape = RoundedCornerShape(12.dp),\n            color = Color.Black.copy(alpha = 0.1f),\n            blur = 4.dp,\n            offsetX = 0.dp,\n            offsetY = 2.dp,\n            spread = 0.dp\n        )\n        .padding(16.dp)\n)\n```\n\n**Figma shadow fields to Compose mapping:**\n\n| Figma Shadow Property | Compose Parameter |\n|---|---|\n| X offset | `offsetX` |\n| Y offset | `offsetY` |\n| Blur | `blur` |\n| Spread | `spread` |\n| Color + opacity | `color = Color(hex).copy(alpha = opacity)` |\n| Drop Shadow type | `Modifier.dropShadow()` |\n| Inner Shadow type | `Modifier.innerShadow()` |\n\n**Legacy approach** (pre-1.9, still valid for simple elevation shadows):\n\n```kotlin\n// Simple elevation shadow\nBox(\n    Modifier\n        .shadow(elevation = 4.dp, shape = RoundedCornerShape(12.dp))\n        .background(Color.White)\n)\n```\n\n### Gradient Mapping\n\n| Figma Gradient Type | Compose Brush |\n|---|---|\n| Linear gradient | `Brush.linearGradient(colors, start, end)` |\n| Radial gradient | `Brush.radialGradient(colors, center, radius)` |\n| Angular/sweep gradient | `Brush.sweepGradient(colors, center)` |\n\nFigma uses normalized coordinates (0.0 to 1.0). Convert to pixel `Offset` values:\n\n```kotlin\n// Figma linear gradient: start (0, 0) to end (1, 1), 45-degree diagonal\nBox(\n    Modifier\n        .fillMaxWidth()\n        .height(200.dp)\n        .background(\n            Brush.linearGradient(\n                colors = listOf(Color(0xFF6200EE), Color(0xFF03DAC6)),\n                start = Offset.Zero,\n                end = Offset.Infinite  // diagonal\n            )\n        )\n)\n\n// For precise Figma coordinates, use onSizeChanged or BoxWithConstraints:\nBoxWithConstraints(\n    Modifier.background(\n        Brush.linearGradient(\n            colors = listOf(Color(0xFF6200EE), Color(0xFF03DAC6)),\n            start = Offset(0f, 0f),\n            end = Offset(constraints.maxWidth.toFloat(), constraints.maxHeight.toFloat())\n        )\n    )\n) {\n    // content\n}\n\n// Radial gradient\nBox(\n    Modifier\n        .size(200.dp)\n        .background(\n            Brush.radialGradient(\n                colors = listOf(Color.White, Color.Blue),\n                center = Offset(100f, 100f),  // center of 200dp box (approx)\n                radius = 150f\n            )\n        )\n)\n```\n\n### Corner Radius\n\n| Figma Corner Radius | Compose Shape |\n|---|---|\n| All corners equal | `RoundedCornerShape(radius.dp)` |\n| Per-corner values | `RoundedCornerShape(topStart = ..., topEnd = ..., bottomEnd = ..., bottomStart = ...)` |\n| Fully rounded (pill) | `RoundedCornerShape(50)` or `CircleShape` |\n| No radius | `RectangleShape` |\n| Cut corners | `CutCornerShape(size.dp)` |\n\n### Borders\n\n```kotlin\n// Solid border\nModifier.border(width.dp, Color(0xFFCCCCCC), RoundedCornerShape(8.dp))\n\n// Gradient border\nModifier.border(\n    width = 2.dp,\n    brush = Brush.linearGradient(listOf(Color.Red, Color.Blue)),\n    shape = RoundedCornerShape(8.dp)\n)\n```\n\n### Opacity\n\n| Figma Property | Compose Equivalent |\n|---|---|\n| Layer opacity | `Modifier.alpha(0.5f)` |\n| Fill color opacity | `Color(0xFF000000).copy(alpha = 0.5f)` |\n| Blend mode | `Modifier.graphicsLayer { compositingStrategy = ... }` |\n\n### Image Fill Modes\n\n| Figma Image Mode | Compose ContentScale |\n|---|---|\n| Fill (cover, may crop) | `ContentScale.Crop` |\n| Fit (contain, no crop) | `ContentScale.Fit` |\n| Stretch (distort) | `ContentScale.FillBounds` |\n| Tile | Custom `DrawScope` tiling |\n| Fill width | `ContentScale.FillWidth` |\n| Fill height | `ContentScale.FillHeight` |\n\n```kotlin\nImage(\n    painter = painterResource(R.drawable.hero),\n    contentDescription = \"Hero image\",\n    contentScale = ContentScale.Crop,\n    modifier = Modifier\n        .fillMaxWidth()\n        .height(200.dp)\n        .clip(RoundedCornerShape(12.dp))\n)\n```\n\n---\n\n## 3. Design Token to MaterialTheme Mapping\n\n| Design System Token | MaterialTheme API |\n|---|---|\n| Color styles (Primary, Surface, Error...) | `MaterialTheme.colorScheme` |\n| Text styles (Heading, Body, Caption...) | `MaterialTheme.typography` |\n| Corner radius (Small, Medium, Large...) | `MaterialTheme.shapes` |\n| Spacing scale (4, 8, 16, 24...) | Custom `CompositionLocal` (see below) |\n| Elevation scale | Custom `CompositionLocal` (see below) |\n\n### Custom Spacing CompositionLocal\n\nMaterial 3 does not ship a spacing scale. Define one that mirrors your design system:\n\n```kotlin\n@Immutable\ndata class AppSpacing(\n    val xxs: Dp = 2.dp,\n    val xs: Dp = 4.dp,\n    val sm: Dp = 8.dp,\n    val md: Dp = 16.dp,\n    val lg: Dp = 24.dp,\n    val xl: Dp = 32.dp,\n    val xxl: Dp = 48.dp\n)\n\nval LocalAppSpacing = staticCompositionLocalOf { AppSpacing() }\n\n// Provide in your theme wrapper\n@Composable\nfun AppTheme(content: @Composable () -> Unit) {\n    val spacing = AppSpacing()\n    CompositionLocalProvider(LocalAppSpacing provides spacing) {\n        MaterialTheme(\n            colorScheme = lightColorScheme(),\n            typography = Typography(),\n            shapes = Shapes()\n        ) {\n            content()\n        }\n    }\n}\n\n// Usage at call site\n@Composable\nfun ProfileCard() {\n    val spacing = LocalAppSpacing.current\n    Card(\n        modifier = Modifier.padding(spacing.md)\n    ) {\n        Column(\n            modifier = Modifier.padding(spacing.md),\n            verticalArrangement = Arrangement.spacedBy(spacing.sm)\n        ) {\n            Text(\"Name\", style = MaterialTheme.typography.titleMedium)\n            Text(\"Bio\", style = MaterialTheme.typography.bodyMedium)\n        }\n    }\n}\n```\n\n### Custom Elevation CompositionLocal\n\n```kotlin\n@Immutable\ndata class AppElevation(\n    val none: Dp = 0.dp,\n    val xs: Dp = 1.dp,\n    val sm: Dp = 2.dp,\n    val md: Dp = 4.dp,\n    val lg: Dp = 8.dp,\n    val xl: Dp = 16.dp\n)\n\nval LocalAppElevation = staticCompositionLocalOf { AppElevation() }\n```\n\n### Mapping Figma Text Styles to Typography\n\n```kotlin\n// Figma design system:        Compose Typography:\n// Heading/H1  36sp Bold    → displaySmall or headlineLarge\n// Heading/H2  28sp Bold    → headlineMedium\n// Heading/H3  22sp SemiBold→ titleLarge\n// Body/Large  16sp Regular → bodyLarge\n// Body/Small  14sp Regular → bodyMedium\n// Caption     12sp Regular → bodySmall or labelMedium\n// Button      14sp Medium  → labelLarge\n\nval AppTypography = Typography(\n    headlineLarge = TextStyle(\n        fontFamily = yourFontFamily,\n        fontWeight = FontWeight.Bold,\n        fontSize = 36.sp,\n        lineHeight = 44.sp\n    ),\n    // ... map each Figma text style\n)\n```\n\n---\n\n## 4. Modifier Ordering Rules\n\n**Canonical principle:** outer to inner = layout/sizing first, then decoration, then interaction.\n\nModifiers are applied left-to-right in the chain. Each modifier wraps everything that follows it. Think of it as layers from outside in.\n\n### Correct Ordering Patterns\n\n```kotlin\n// Pattern 1: Card-like surface\nModifier\n    .fillMaxWidth()                              // 1. Layout sizing\n    .padding(horizontal = 16.dp, vertical = 8.dp) // 2. External margin (space from siblings)\n    .dropShadow(                                  // 3. Shadow (before background)\n        shape = RoundedCornerShape(12.dp),\n        color = Color.Black.copy(alpha = 0.1f),\n        blur = 8.dp, offsetY = 4.dp\n    )\n    .background(Color.White, RoundedCornerShape(12.dp)) // 4. Background fill\n    .clip(RoundedCornerShape(12.dp))              // 5. Clip content to shape\n    .clickable { }                                // 6. Interaction (inside clip for ripple bounds)\n    .padding(16.dp)                               // 7. Internal padding (content inset)\n\n// Pattern 2: Clickable with large touch target\nModifier\n    .fillMaxWidth()\n    .clickable { }           // Clickable AFTER padding = larger touch target\n    .padding(16.dp)          // Internal content padding\n\n// Pattern 3: Background extends to edges, padding inside\nModifier\n    .fillMaxWidth()\n    .background(MaterialTheme.colorScheme.surface)\n    .padding(16.dp)\n```\n\n### Common Mistakes\n\n```kotlin\n// Wrong: padding before fillMaxWidth clips the fill area\nModifier\n    .padding(16.dp)\n    .fillMaxWidth()  // Fills remaining width AFTER padding is applied\n\n// Correct: fillMaxWidth first, then pad inward\nModifier\n    .fillMaxWidth()\n    .padding(16.dp)\n\n// Wrong: clickable before padding = small touch target\nModifier\n    .clickable { }\n    .padding(16.dp)   // Padding is outside the clickable area\n\n// Correct: clickable after padding = padding area is clickable too\nModifier\n    .padding(16.dp)\n    .clickable { }    // Entire padded region responds to clicks\n\n// Wrong: shadow after background (invisible or clipped)\nModifier\n    .background(Color.White, RoundedCornerShape(12.dp))\n    .dropShadow(...)  // Shadow drawn inside the background layer\n\n// Correct: shadow before background\nModifier\n    .dropShadow(...)\n    .background(Color.White, RoundedCornerShape(12.dp))\n```\n\n---\n\n## 5. Semantic vs Literal Translation\n\nFigma designs express visual output. Compose code should express semantics. Always prefer Material 3 components over manually reconstructing their appearance with `Box` + modifiers.\n\n### Anti-pattern: Literal Translation\n\n```kotlin\n// Figma shows a card: rounded rect, shadow, image, title, subtitle\n// Literal translation -- DON'T\nBox(\n    Modifier\n        .shadow(4.dp, RoundedCornerShape(12.dp))\n        .background(Color.White, RoundedCornerShape(12.dp))\n        .clip(RoundedCornerShape(12.dp))\n) {\n    Column(Modifier.padding(16.dp)) {\n        Image(painter = painterResource(R.drawable.photo), contentDescription = null)\n        Text(\"Title\", fontSize = 18.sp, fontWeight = FontWeight.Bold, color = Color.Black)\n        Text(\"Subtitle\", fontSize = 14.sp, color = Color(0xFF666666))\n    }\n}\n```\n\n### Correct: Semantic Translation\n\n```kotlin\n// Semantic translation -- DO\nElevatedCard(\n    modifier = Modifier.fillMaxWidth(),\n    shape = MaterialTheme.shapes.medium\n) {\n    Column {\n        Image(\n            painter = painterResource(R.drawable.photo),\n            contentDescription = \"Photo description\",\n            contentScale = ContentScale.Crop,\n            modifier = Modifier\n                .fillMaxWidth()\n                .height(180.dp)\n        )\n        Column(Modifier.padding(16.dp)) {\n            Text(\"Title\", style = MaterialTheme.typography.titleMedium)\n            Text(\n                \"Subtitle\",\n                style = MaterialTheme.typography.bodyMedium,\n                color = MaterialTheme.colorScheme.onSurfaceVariant\n            )\n        }\n    }\n}\n```\n\n### Why This Matters\n\n| Concern | Literal Box+Modifiers | M3 Component |\n|---|---|---|\n| Dark theme | Breaks (hardcoded colors) | Automatic |\n| Elevation overlay | Missing | Built-in tonal elevation |\n| Ripple / feedback | Must add manually | Built-in |\n| Accessibility | Must add semantics manually | Roles + descriptions built-in |\n| Dynamic color (Material You) | Does not respond | Automatic |\n| State handling (disabled, focused) | Manual | Built-in styling per state |\n\n**Rule:** If a Material 3 component exists for the visual pattern, use it. Only build custom layouts for genuinely novel UI elements.\n\n### Quick Mapping: Visual Pattern to M3 Component\n\n| \"It looks like a...\" | Use |\n|---|---|\n| Rounded card with shadow | `ElevatedCard` |\n| Outlined card | `OutlinedCard` |\n| Pill-shaped button | `Button(shape = CircleShape)` |\n| Icon + label row | `ListItem` |\n| Search bar | `SearchBar` / `DockedSearchBar` |\n| Segmented control | `SegmentedButton` (M3 1.2+) |\n| Banner notification | `Snackbar` |\n| Full-width separator | `HorizontalDivider` |\n| Pull-to-refresh | `PullToRefreshBox` |\n\n---\n\n## 6. Anti-Patterns\n\n### Over-nesting Layouts\n\nFigma designs often have deep frame hierarchies for organizational reasons. Do not mirror this nesting in Compose -- flatten aggressively.\n\n```kotlin\n// Anti-pattern: mirroring Figma's 5-level nesting\nBox {\n    Column {\n        Row {\n            Box {\n                Column {\n                    Text(\"Title\")\n                    Text(\"Subtitle\")\n                }\n            }\n        }\n    }\n}\n\n// Correct: flatten to what layout actually requires\nColumn {\n    Text(\"Title\", style = MaterialTheme.typography.titleMedium)\n    Text(\"Subtitle\", style = MaterialTheme.typography.bodyMedium)\n}\n```\n\nDeep nesting increases measure/layout passes. Each layout node is a measure cost. Flatten to the minimum tree depth that achieves the visual result.\n\n### Hardcoded Values vs Theme Tokens\n\n```kotlin\n// Anti-pattern: hardcoded hex colors and font sizes\nText(\n    text = \"Hello\",\n    color = Color(0xFF1A1A1A),\n    fontSize = 16.sp,\n    fontWeight = FontWeight.Medium\n)\n\nBox(Modifier.background(Color(0xFFF5F5F5)))\n\n// Correct: theme tokens\nText(\n    text = \"Hello\",\n    style = MaterialTheme.typography.bodyLarge,\n    color = MaterialTheme.colorScheme.onSurface\n)\n\nBox(Modifier.background(MaterialTheme.colorScheme.surfaceVariant))\n```\n\nHardcoded values break dark theme, dynamic color, and design system updates. The only acceptable hardcoded color is inside your theme definition files.\n\n### Ignoring Accessibility\n\n```kotlin\n// Anti-pattern: no content description, tiny touch target\nIcon(\n    imageVector = Icons.Default.Favorite,\n    contentDescription = null,  // Screen readers skip this\n    modifier = Modifier\n        .size(20.dp)            // Below 48dp minimum touch target\n        .clickable { onFavorite() }\n)\n\n// Correct: accessible\nIconButton(onClick = onFavorite) {  // IconButton enforces 48dp minimum\n    Icon(\n        imageVector = Icons.Default.Favorite,\n        contentDescription = \"Add to favorites\"\n    )\n}\n```\n\n**Accessibility checklist for design translation:**\n\n- All interactive elements have minimum 48dp touch targets (use `IconButton`, `TextButton`, or `Modifier.sizeIn(minWidth = 48.dp, minHeight = 48.dp)`)\n- All images and icons have meaningful `contentDescription` (or `null` if purely decorative, paired with `Modifier.semantics { }` as needed)\n- Color contrast ratios meet WCAG AA (4.5:1 for text, 3:1 for large text)\n- Interactive states are visually distinguishable (not just color change)\n\n### Designing for One Screen Width Only\n\n```kotlin\n// Anti-pattern: fixed widths that break on tablets\nRow(Modifier.width(360.dp)) {\n    Column(Modifier.width(180.dp)) { /* left panel */ }\n    Column(Modifier.width(180.dp)) { /* right panel */ }\n}\n\n// Correct: responsive with WindowSizeClass\nval windowSizeClass = currentWindowAdaptiveInfo().windowSizeClass\n\nwhen (windowSizeClass.windowWidthSizeClass) {\n    WindowWidthSizeClass.COMPACT -> {\n        // Single column layout (phones)\n        Column { /* all content stacked */ }\n    }\n    WindowWidthSizeClass.MEDIUM -> {\n        // Two-pane list-detail (small tablets, foldables)\n        ListDetailPaneScaffold(/* ... */)\n    }\n    WindowWidthSizeClass.EXPANDED -> {\n        // Navigation rail + content (large tablets, desktop)\n        Row {\n            NavigationRail { /* ... */ }\n            Content(Modifier.weight(1f))\n        }\n    }\n}\n```\n\n**Do:** Use `fillMaxWidth()`, `weight()`, and `WindowSizeClass` for responsive layouts.\n\n**Don't:** Use fixed pixel/dp widths for containers that should adapt.\n\n### Forgetting Scroll Behavior\n\n```kotlin\n// Anti-pattern: content overflows without scrolling\nColumn(Modifier.fillMaxSize()) {\n    // 20 items that exceed screen height -- bottom items invisible\n    repeat(20) { Text(\"Item $it\") }\n}\n\n// Correct: add scrolling\nColumn(\n    Modifier\n        .fillMaxSize()\n        .verticalScroll(rememberScrollState())\n) {\n    repeat(20) { Text(\"Item $it\") }\n}\n\n// Or for dynamic lists:\nLazyColumn(Modifier.fillMaxSize()) {\n    items(20) { Text(\"Item $it\") }\n}\n```\n\n### Ignoring Content Padding from Scaffold\n\n```kotlin\n// Anti-pattern: ignoring innerPadding from Scaffold\nScaffold(topBar = { TopAppBar(title = { Text(\"App\") }) }) { innerPadding ->\n    // Content renders BEHIND the top bar\n    LazyColumn {\n        items(data) { Text(it) }\n    }\n}\n\n// Correct: apply innerPadding\nScaffold(topBar = { TopAppBar(title = { Text(\"App\") }) }) { innerPadding ->\n    LazyColumn(\n        modifier = Modifier.padding(innerPadding),  // or contentPadding = innerPadding\n    ) {\n        items(data) { Text(it) }\n    }\n}\n```\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/lists-scrolling.md",
    "content": "# Lists and Scrolling in Jetpack Compose\n\nEfficient list rendering and scrolling are core to responsive mobile UIs. Jetpack Compose provides lazy layouts that compose items on-demand, not all at once.\n\n## LazyColumn and LazyRow\n\nThese composables only compose visible items, making them efficient for large lists unlike `Column`/`Row` which compose all children upfront.\n\n### LazyColumn (Vertical Scrolling)\n```kotlin\nLazyColumn(modifier = Modifier.fillMaxSize()) {\n  item {\n    HeaderComposable()\n  }\n  items(itemList.size) { index ->\n    ListItemComposable(itemList[index])\n  }\n  item {\n    FooterComposable()\n  }\n}\n```\n\n### LazyRow (Horizontal Scrolling)\n```kotlin\nLazyRow(modifier = Modifier.fillMaxWidth()) {\n  items(imageList.size) { index ->\n    Image(\n      painter = painterResource(imageList[index]),\n      contentDescription = null,\n      modifier = Modifier.width(200.dp)\n    )\n  }\n}\n```\n\n**Key difference from Column/Row:** Items are composed lazily as they enter the viewport, reducing memory and CPU usage.\n\n**Source:** `androidx/compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/`\n\n## DSL Patterns: item, items, itemsIndexed\n\n### `item` — Single Composable\n```kotlin\nLazyColumn {\n  item {\n    HeaderComposable()\n  }\n}\n```\n\n### `items` — From a List or Count\n```kotlin\n// From a List\nval users = listOf(User(\"Alice\"), User(\"Bob\"))\nLazyColumn {\n  items(users) { user ->\n    UserCard(user)\n  }\n}\n\n// From a count\nLazyColumn {\n  items(100) { index ->\n    Text(\"Item $index\")\n  }\n}\n```\n\n### `itemsIndexed` — With Index\n```kotlin\nLazyColumn {\n  itemsIndexed(users) { index, user ->\n    Text(\"${index + 1}. ${user.name}\")\n  }\n}\n```\n\n## Keys: Critical for Correctness and Performance\n\nThe `key` parameter ensures Compose can correctly identify and reuse items even if the list is reordered.\n\n### ✓ Good: Stable Keys\n```kotlin\ndata class User(val id: Long, val name: String)\n\nLazyColumn {\n  items(users, key = { it.id }) { user ->\n    UserCard(user)\n  }\n}\n```\n\nWhen `users` list is reordered, Compose knows which item moved because the key (id) is stable.\n\n### ✗ Bad: Index as Key\n```kotlin\n// AVOID: If list is reordered, state gets mixed up\nLazyColumn {\n  items(users, key = { index }) { user -> // Wrong!\n    var selected by remember { mutableStateOf(false) }\n    UserCard(user, selected)\n  }\n}\n```\n\nIf you remove item at index 0, the item that was at index 1 moves to index 0 and incorrectly inherits the state.\n\n### ✗ Bad: No Key\n```kotlin\n// If list changes, item state/animations may misbehave\nLazyColumn {\n  items(users) { user ->\n    UserCard(user)\n  }\n}\n```\n\nWithout a key, Compose can't distinguish items reliably if the list changes.\n\n**Rule:** Always provide a stable, unique key when the list can change. Use IDs, not indices.\n\n## Content Types for Recycling Optimization\n\nUse `contentType` to enable layout reuse when rendering different item types:\n\n```kotlin\nsealed class ListItem\ndata class HeaderItem(val title: String) : ListItem()\ndata class UserItem(val user: User) : ListItem()\n\nLazyColumn {\n  items(\n    items = listItems,\n    key = { it.id },\n    contentType = { when (it) {\n      is HeaderItem -> \"header\"\n      is UserItem -> \"user\"\n    }}\n  ) { item ->\n    when (item) {\n      is HeaderItem -> HeaderComposable(item)\n      is UserItem -> UserCard(item)\n    }\n  }\n}\n```\n\nItems with the same `contentType` can reuse layout state, improving performance when types repeat.\n\n## LazyListState: Scroll Position and Animations\n\nManage scroll position programmatically:\n\n```kotlin\nval listState = rememberLazyListState()\n\nLazyColumn(state = listState) {\n  items(100) { index ->\n    Text(\"Item $index\")\n  }\n}\n\n// Scroll to item 50\nLaunchedEffect(Unit) {\n  listState.scrollToItem(50)\n}\n\n// Animate scroll\nLaunchedEffect(Unit) {\n  listState.animateScrollToItem(50)\n}\n\n// Read current scroll position\nval firstVisibleIndex = listState.firstVisibleItemIndex\nval firstVisibleOffset = listState.firstVisibleItemScrollOffset\n```\n\n**Use case:** Scroll to a newly added item, or scroll on user action.\n\n## LazyVerticalGrid and LazyHorizontalGrid\n\n### Fixed Columns\n```kotlin\nLazyVerticalGrid(columns = GridCells.Fixed(3)) {\n  items(itemList.size) { index ->\n    GridItemComposable(itemList[index])\n  }\n}\n```\n\n### Adaptive Columns (Responsive)\n```kotlin\n// Column width ~100dp, fills available space with as many columns as fit\nLazyVerticalGrid(columns = GridCells.Adaptive(100.dp)) {\n  items(itemList.size) { index ->\n    GridItemComposable(itemList[index])\n  }\n}\n```\n\nAdaptive is preferable for responsive layouts.\n\n## LazyVerticalStaggeredGrid\n\nFor Pinterest-style layouts with variable heights:\n\n```kotlin\nLazyVerticalStaggeredGrid(\n  columns = StaggeredGridCells.Fixed(2),\n  modifier = Modifier.fillMaxSize()\n) {\n  items(images.size) { index ->\n    AsyncImage(\n      model = images[index].url,\n      contentDescription = null,\n      modifier = Modifier.fillMaxWidth()\n    )\n  }\n}\n```\n\nItems flow into the column with the shortest current height, creating a natural staggered appearance.\n\n## HorizontalPager and VerticalPager\n\nPage-by-page horizontal or vertical swiping:\n\n```kotlin\nval pagerState = rememberPagerState(pageCount = { pages.size })\n\nHorizontalPager(state = pagerState) { page ->\n  PageComposable(pages[page])\n}\n\n// Programmatic scroll to page\nLaunchedEffect(Unit) {\n  pagerState.scrollToPage(2)\n}\n\n// Animate to page\nLaunchedEffect(Unit) {\n  pagerState.animateScrollToPage(2)\n}\n```\n\n## Sticky Headers in Lazy Lists\n\nHeaders that remain visible at the top while scrolling:\n\n```kotlin\nLazyColumn {\n  stickyHeader {\n    SectionHeaderComposable(\"Section A\")\n  }\n  items(itemsA) { item ->\n    ItemComposable(item)\n  }\n\n  stickyHeader {\n    SectionHeaderComposable(\"Section B\")\n  }\n  items(itemsB) { item ->\n    ItemComposable(item)\n  }\n}\n```\n\n## Nested Scrolling: Pitfalls\n\n### ✗ Avoid Scrollable Inside LazyColumn\n```kotlin\n// Bad: nested scroll behavior is unpredictable\nLazyColumn {\n  item {\n    LazyRow { // Nested lazy is OK, but...\n      items(innerList) { item ->\n        InnerItem(item)\n      }\n    }\n  }\n}\n```\n\nNested lazy composables are acceptable but require careful thought about scroll precedence.\n\n### ✗ Avoid verticalScroll Modifier Inside LazyColumn\n```kotlin\n// Bad: two scroll containers fight for input\nLazyColumn {\n  item {\n    Column(modifier = Modifier.verticalScroll(rememberScrollState())) {\n      Text(\"This is scrollable twice!\")\n    }\n  }\n}\n```\n\nDon't wrap lazy children in scrollable modifiers; use nested lazy composables if you need multiple scroll axes.\n\n### ✓ Use nestedScroll for Complex Scenarios\n```kotlin\nval scrollState = rememberScrollState()\nval nestedScrollConnection = remember {\n  object : NestedScrollConnection {\n    override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {\n      // Custom scroll handling\n      return Offset.Zero\n    }\n  }\n}\n\nLazyColumn(modifier = Modifier.nestedScroll(nestedScrollConnection)) {\n  items(100) { index ->\n    Text(\"Item $index\")\n  }\n}\n```\n\n## Performance: Scroll-Dependent UI\n\n### ✗ Bad: Heavy Computation in Item Lambda\n```kotlin\nLazyColumn {\n  items(users) { user ->\n    val processedData = expensiveComputation(user) // Runs every recomposition!\n    UserCard(user, processedData)\n  }\n}\n```\n\n### ✓ Good: Use derivedStateOf for Scroll-Dependent Logic\n```kotlin\nval listState = rememberLazyListState()\nval showScrollToTop = remember {\n  derivedStateOf { listState.firstVisibleItemIndex > 0 }\n}\n\nLazyColumn(state = listState) {\n  items(100) { index ->\n    Text(\"Item $index\")\n  }\n}\n\nif (showScrollToTop.value) {\n  Button(onClick = { /* scroll up */ }) { Text(\"Top\") }\n}\n```\n\n`derivedStateOf` derives a new value when scroll state changes without recomposing the entire list.\n\n## Anti-Patterns\n\n### ✗ Using LazyColumn for Small Fixed Lists\n```kotlin\n// Bad: overkill for 5 items\nLazyColumn {\n  items(5) { index ->\n    Text(\"Item $index\")\n  }\n}\n```\n\n**Better:** Use `Column` for small fixed lists.\n\n### ✗ No Keys + List Mutations\n```kotlin\nvar items by remember { mutableStateOf(initialList) }\nLazyColumn {\n  items(items) { item -> // No key!\n    ItemComposable(item, onDelete = {\n      items = items.filter { it.id != item.id }\n    })\n  }\n}\n```\n\nWithout keys, removing an item corrupts the state of remaining items.\n\n### ✗ Creating New Objects in Keys\n```kotlin\n// Bad: key creates new object each recomposition\nLazyColumn {\n  items(users, key = { User(it.id, it.name) }) { user ->\n    UserCard(user)\n  }\n}\n```\n\n**Better:** Use primitive stable identifiers.\n\n## Key Takeaways\n\n1. Always provide stable, unique keys when using `items` on mutable lists\n2. Use `contentType` for multi-type lists to enable layout reuse\n3. Prefer `GridCells.Adaptive` for responsive grid layouts\n4. Avoid nested scrollables; use `nestedScroll` for complex scroll behavior\n5. Use `derivedStateOf` to avoid recomposing the entire list for scroll-dependent logic\n6. `LazyColumn`/`LazyRow` are for large or unbounded lists; use `Column`/`Row` for small fixed lists\n7. Never use indices as keys; list mutations will corrupt item state\n\n### Production Crash Patterns\n\n#### indexOf() Inside items {} — O(n^2) and Crashes\n\n```kotlin\n// BAD: O(n^2) total, returns -1 on recreated objects → IndexOutOfBoundsException\nitems(list.size) { index ->\n    val item = list[index]\n    val position = list.indexOf(item) // -1 if object was recreated!\n}\n\n// GOOD: use items() with key for stable identity\nitems(list, key = { it.id }) { item ->\n    ItemRow(item)\n}\n```\n\nRoot cause: `indexOf()` uses `equals()`. If list items are recreated (new object instances without proper `equals()` implementation), `indexOf()` returns -1.\n\n#### Duplicate LazyColumn Keys\n\nBackend sends items without unique IDs, or WebSocket reconnects deliver duplicates → `IllegalArgumentException: Key X was already used`.\n\n```kotlin\n// BAD: backend IDs may not be unique\nitems(messages, key = { it.id }) { msg -> ... }\n\n// GOOD: add dedup index for safety\nitems(messages, key = { \"${it.id}_${it.dedupIndex}\" }) { msg -> ... }\n```\n\nThe `dedupIndex` pattern: Add a field to the data class that is excluded from `equals()`/`hashCode()` but included in the LazyColumn key:\n\n```kotlin\ndata class ChatMessage(\n    val id: String,\n    val text: String,\n    val timestamp: Long\n) {\n    // NOT in data class constructor — excluded from equals/hashCode\n    var dedupIndex: Int = 0\n}\n\n// When processing messages from backend:\nfun deduplicateKeys(messages: List<ChatMessage>): List<ChatMessage> {\n    val seen = mutableMapOf<String, Int>()\n    return messages.map { msg ->\n        val count = seen.getOrPut(msg.id) { 0 }\n        seen[msg.id] = count + 1\n        msg.also { it.dedupIndex = count }\n    }\n}\n```\n\n#### derivedStateOf Driving Collection Size → IOOB\n\n```kotlin\n// BAD: derived count can be stale when items{} reads\nval itemCount by remember { derivedStateOf { filterItems(allItems).size } }\nLazyColumn {\n    items(itemCount) { index ->\n        val item = filterItems(allItems)[index] // IOOB if allItems changed!\n    }\n}\n\n// GOOD: derive the full filtered list, not just the count\nval filteredItems by remember { derivedStateOf { filterItems(allItems) } }\nLazyColumn {\n    items(filteredItems, key = { it.id }) { item ->\n        ItemRow(item)\n    }\n}\n```\n\nRule: `derivedStateOf` for scroll direction, visibility, form validation — **never for item counts that drive LazyList rendering**.\n\n### LazyList Hardening\n\n#### Multi-Field Keys with Collision Prefixes\n\nWhen a LazyList mixes items from different data sources, IDs can collide:\n\n```kotlin\n// BAD: id=42 in both liveItems and archivedItems → crash\nLazyColumn {\n    items(liveItems, key = { it.id }) { ... }\n    items(archivedItems, key = { it.id }) { ... }\n}\n\n// GOOD: prefix keys by source\nLazyColumn {\n    items(liveItems, key = { \"live_${it.id}\" }) { ... }\n    items(archivedItems, key = { \"archived_${it.id}\" }) { ... }\n    items(pinnedItems, key = { \"pinned_${it.id}\" }) { ... }\n}\n```\n\n#### items() with key Preferred Over itemsIndexed()\n\n`items(list, key = { it.id })` gives each item a stable identity across recompositions. This enables:\n- Correct `animateItem()` animations\n- Efficient diffing (only changed items recompose)\n- Proper state preservation per item\n\nUse `itemsIndexed()` only when you genuinely need the index for display (e.g., numbered list).\n\n#### animateItem() Parameters\n\n```kotlin\nitems(items, key = { it.id }) { item ->\n    ItemRow(\n        item = item,\n        modifier = Modifier.animateItem(\n            fadeInSpec = tween(durationMillis = 250),\n            placementSpec = spring(\n                dampingRatio = Spring.DampingRatioLowBouncy,\n                stiffness = Spring.StiffnessMediumLow\n            ),\n            fadeOutSpec = tween(durationMillis = 150)\n        )\n    )\n}\n```\n\n#### ReportDrawnWhen for Startup Performance\n\nSignal to the system that the first meaningful content is visible:\n\n```kotlin\n@Composable\nfun ConversationListScreen(items: List<Conversation>) {\n    ReportDrawnWhen { items.isNotEmpty() }\n\n    LazyColumn {\n        items(items, key = { it.id }) { item ->\n            ConversationRow(item)\n        }\n    }\n}\n```\n\nThis improves Time To Initial Display (TTID) and Time To Full Display (TTFD) metrics in Android vitals.\n\n#### Device-Specific Pagination\n\nSome devices (notably Samsung) handle scroll events differently, requiring fewer scroll confirmations for lazy load triggers. When implementing infinite scroll, test on multiple OEMs and consider a configurable scroll threshold.\n\n```kotlin\nval shouldLoadMore by remember {\n    derivedStateOf {\n        val lastVisibleItem = listState.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: 0\n        val totalItems = listState.layoutInfo.totalItemsCount\n        lastVisibleItem >= totalItems - PREFETCH_THRESHOLD // e.g., 5\n    }\n}\n\nLaunchedEffect(shouldLoadMore) {\n    if (shouldLoadMore) { viewModel.loadNextPage() }\n}\n```\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/material3-motion.md",
    "content": "# Material 3 Motion\n\nSource: `compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/MotionTokens.kt`\nand `compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MotionScheme.kt`\nin `androidx/androidx` (branch: `androidx-main`)\n\nCMP compatibility: `MotionTokens`, `MotionScheme`, and all easing constants are in\n`androidx.compose.material3` — available on all CMP targets (Android, Desktop, iOS, Web)\nsince M3 1.2.0. No platform guards needed.\n\n---\n\n## 1. Two APIs, One System\n\nM3 provides two ways to apply motion:\n\n| API | When to Use |\n|-----|------------|\n| **`MotionScheme`** (preferred) | Inside components that should adapt to the app's motion scheme — the theme controls whether spring-based or tween-based specs are used |\n| **`MotionTokens` + `tween()`** | When you need explicit `tween()` / `keyframes {}` control and the component is not theme-motion-aware |\n\nUse `MotionScheme` for new components. Use `MotionTokens` when the caller explicitly provides `AnimationSpec` parameters or when working with `AnimatedVisibility`, `Crossfade`, or shared elements.\n\n---\n\n## 2. MotionScheme API (Preferred for Components)\n\n`MotionScheme` is part of `MaterialTheme` alongside `colorScheme`, `typography`, and `shapes`.\n\n```kotlin\n// Access via MaterialTheme\nval motionScheme = MaterialTheme.motionScheme\n\n// Two built-in schemes\nMaterialTheme(motionScheme = MotionScheme.standard())    // utilitarian UI\nMaterialTheme(motionScheme = MotionScheme.expressive())  // prominent UI (M3 recommended default)\n```\n\n### Spec Functions\n\n| Function | Use Case |\n|----------|---------|\n| `defaultSpatialSpec<T>()` | Layout changes, position/size transitions (spatial) |\n| `fastSpatialSpec<T>()` | Quick spatial transitions |\n| `slowSpatialSpec<T>()` | Deliberate spatial transitions |\n| `defaultEffectsSpec<T>()` | Opacity, color, non-spatial changes |\n| `fastEffectsSpec<T>()` | Quick opacity/color transitions |\n| `slowEffectsSpec<T>()` | Deliberate opacity/color transitions |\n\n```kotlin\n@Composable\nfun AnimatedCard(expanded: Boolean) {\n    val motionScheme = MaterialTheme.motionScheme\n\n    // Size change = spatial\n    val size by animateDpAsState(\n        targetValue = if (expanded) 200.dp else 100.dp,\n        animationSpec = motionScheme.defaultSpatialSpec(),\n        label = \"card-size\"\n    )\n\n    // Color change = effects\n    val color by animateColorAsState(\n        targetValue = if (expanded) MaterialTheme.colorScheme.primaryContainer\n                      else MaterialTheme.colorScheme.surface,\n        animationSpec = motionScheme.defaultEffectsSpec(),\n        label = \"card-color\"\n    )\n}\n```\n\n> **Key difference from `tween()`**: `MotionScheme` specs are spring-based by default in\n> `expressive()`. The actual spec type (spring vs. tween) is controlled by the theme, not\n> the component. This means motion adapts to the app's motion scheme without code changes.\n\n---\n\n## 3. Duration Tokens\n\nUse when explicit `tween()` control is needed. All values sourced from `MotionTokens.kt`\n(generated from Material Design spec v0_103). Durations are `Float` — use `.toInt()` for\n`tween(durationMillis = ...)`.\n\n| Token | Value (ms) | Use Case |\n|-------|-----------|---------|\n| `MotionTokens.DurationShort1` | 50ms | Micro interactions — ripple spread, checkbox tick |\n| `MotionTokens.DurationShort2` | 100ms | Small element appear/disappear |\n| `MotionTokens.DurationShort3` | 150ms | Icon transitions, selection indicators |\n| `MotionTokens.DurationShort4` | 200ms | Tooltip appear, chip selection |\n| `MotionTokens.DurationMedium1` | 250ms | FAB expand, card state change |\n| `MotionTokens.DurationMedium2` | 300ms | **Most common** — dialog, bottom sheet, nav drawer |\n| `MotionTokens.DurationMedium3` | 350ms | Expanded component transitions |\n| `MotionTokens.DurationMedium4` | 400ms | Page-level panel transitions |\n| `MotionTokens.DurationLong1` | 450ms | Complex layout changes |\n| `MotionTokens.DurationLong2` | 500ms | Shared element enter |\n| `MotionTokens.DurationLong3` | 550ms | Shared element — large content |\n| `MotionTokens.DurationLong4` | 600ms | Full container morphs |\n| `MotionTokens.DurationExtraLong1` | 700ms | Full-screen transitions only |\n| `MotionTokens.DurationExtraLong2` | 800ms | Full-screen transitions only |\n| `MotionTokens.DurationExtraLong3` | 900ms | Full-screen transitions only |\n| `MotionTokens.DurationExtraLong4` | 1000ms | Full-screen transitions only |\n\n---\n\n## 4. Easing Tokens\n\nAll values sourced from `MotionTokens.kt`. Access via `MotionTokens.Easing*CubicBezier`.\n\n| Token | CubicBezierEasing(x1, y1, x2, y2) | Direction | Use Case |\n|-------|------------------------------------|-----------|---------|\n| `MotionTokens.EasingEmphasizedDecelerateCubicBezier` | `(0.05f, 0.7f, 0.1f, 1.0f)` | Entering | Element arriving on screen — fast start, gentle settle |\n| `MotionTokens.EasingEmphasizedAccelerateCubicBezier` | `(0.3f, 0.0f, 0.8f, 0.15f)` | Exiting | Element leaving screen — slow start, fast exit |\n| `MotionTokens.EasingEmphasizedCubicBezier` | `(0.2f, 0.0f, 0.0f, 1.0f)` | Both | Default for most M3 component transitions |\n| `MotionTokens.EasingStandardDecelerateCubicBezier` | `(0.0f, 0.0f, 0.0f, 1.0f)` | Entering | Simple enter — less expressive than Emphasized |\n| `MotionTokens.EasingStandardAccelerateCubicBezier` | `(0.3f, 0.0f, 1.0f, 1.0f)` | Exiting | Simple exit |\n| `MotionTokens.EasingStandardCubicBezier` | `(0.2f, 0.0f, 0.0f, 1.0f)` | Both | Simple state changes |\n| `MotionTokens.EasingLinearCubicBezier` | `(0.0f, 0.0f, 1.0f, 1.0f)` | — | Looping / repeating animations only |\n| `MotionTokens.EasingLegacyCubicBezier` | `(0.4f, 0.0f, 0.2f, 1.0f)` | — | `FastOutSlowInEasing` equivalent — do not use in new code |\n| `MotionTokens.EasingLegacyAccelerateCubicBezier` | `(0.4f, 0.0f, 1.0f, 1.0f)` | — | `FastOutLinearInEasing` equivalent — do not use in new code |\n| `MotionTokens.EasingLegacyDecelerateCubicBezier` | `(0.0f, 0.0f, 0.2f, 1.0f)` | — | `LinearOutSlowInEasing` equivalent — do not use in new code |\n\n> **Enter/exit rule (always):** Enter = Decelerate easing (fast start, gentle settle).\n> Exit = Accelerate easing (slow start, quick departure). Never use the same easing for both.\n> The `Legacy*` tokens are equivalent to the pre-M3 named constants — do not use them in new code.\n\n---\n\n## 5. Using Tokens in Compose Animation APIs\n\n### animate*AsState (prefer MotionScheme)\n\n```kotlin\n// Color — effects spec\nval color by animateColorAsState(\n    targetValue = if (selected) MaterialTheme.colorScheme.primary\n                  else MaterialTheme.colorScheme.surface,\n    animationSpec = MaterialTheme.motionScheme.defaultEffectsSpec(),\n    label = \"selection-color\"\n)\n\n// If explicit tween is required:\nval color by animateColorAsState(\n    targetValue = targetColor,\n    animationSpec = tween(\n        durationMillis = MotionTokens.DurationShort4.toInt(),   // 200ms\n        easing = MotionTokens.EasingStandardCubicBezier         // state change, not enter/exit\n    ),\n    label = \"color\"\n)\n```\n\n### AnimatedVisibility (asymmetric enter/exit)\n\nEnter and exit must use different durations and easing — exit is always faster.\n\n```kotlin\nAnimatedVisibility(\n    visible = visible,\n    enter = fadeIn(\n        animationSpec = tween(\n            durationMillis = MotionTokens.DurationMedium2.toInt(),      // 300ms\n            easing = MotionTokens.EasingEmphasizedDecelerateCubicBezier // entering\n        )\n    ) + slideInVertically(\n        animationSpec = tween(\n            durationMillis = MotionTokens.DurationMedium2.toInt(),\n            easing = MotionTokens.EasingEmphasizedDecelerateCubicBezier\n        ),\n        initialOffsetY = { it / 4 }\n    ),\n    exit = fadeOut(\n        animationSpec = tween(\n            durationMillis = MotionTokens.DurationShort4.toInt(),       // 200ms — exit is faster\n            easing = MotionTokens.EasingEmphasizedAccelerateCubicBezier // exiting\n        )\n    ) + slideOutVertically(\n        animationSpec = tween(\n            durationMillis = MotionTokens.DurationShort4.toInt(),\n            easing = MotionTokens.EasingEmphasizedAccelerateCubicBezier\n        ),\n        targetOffsetY = { it / 4 }\n    )\n) {\n    content()\n}\n```\n\n### updateTransition (multi-property, shared spec)\n\n```kotlin\nval transition = updateTransition(targetState = expanded, label = \"card\")\n\nval elevation by transition.animateDp(\n    transitionSpec = {\n        tween(\n            durationMillis = MotionTokens.DurationMedium1.toInt(),  // 250ms\n            easing = MotionTokens.EasingEmphasizedCubicBezier\n        )\n    },\n    label = \"elevation\"\n) { isExpanded -> if (isExpanded) 8.dp else 0.dp }\n\nval cornerRadius by transition.animateDp(\n    transitionSpec = {\n        tween(\n            durationMillis = MotionTokens.DurationMedium1.toInt(),\n            easing = MotionTokens.EasingEmphasizedCubicBezier\n        )\n    },\n    label = \"corner-radius\"\n) { isExpanded -> if (isExpanded) 0.dp else 12.dp }\n```\n\n### Shared element transitions\n\nShared elements cross screen boundaries — use Long range.\n\n```kotlin\nModifier.sharedElement(\n    state = rememberSharedContentState(key = \"hero-${item.id}\"),\n    animatedVisibilityScope = animatedVisibilityScope,\n    boundsTransform = { _, _ ->\n        tween(\n            durationMillis = MotionTokens.DurationLong2.toInt(),    // 500ms\n            easing = MotionTokens.EasingEmphasizedCubicBezier\n        )\n    }\n)\n```\n\n---\n\n## 6. Decision Tree\n\nPick the right duration by working through these questions in order:\n\n1. **Micro interaction?** (ripple, checkbox tick, toggle thumb snap)\n   → `DurationShort1` (50ms) or `DurationShort2` (100ms)\n\n2. **Component state change?** (button press feedback, chip select, icon swap, tab indicator)\n   → `DurationShort3` (150ms) or `DurationShort4` (200ms)\n\n3. **Container change?** (card expand, FAB extend/shrink, menu open, tooltip)\n   → `DurationMedium1` (250ms) or `DurationMedium2` (300ms) ← most common\n\n4. **Screen-level element?** (dialog enter, bottom sheet slide, search bar expand, nav drawer)\n   → `DurationMedium3` (350ms) or `DurationMedium4` (400ms)\n\n5. **Shared element / hero transition?** (image or card expands from list to detail screen)\n   → `DurationLong1` (450ms) or `DurationLong2` (500ms)\n\n6. **Full-screen complex morph?** (entire screen layout changes)\n   → `DurationLong3`–`DurationExtraLong1` (550ms–700ms)\n\n**Easing rule (always apply):**\n- Element arriving → `EasingEmphasizedDecelerateCubicBezier`\n- Element departing → `EasingEmphasizedAccelerateCubicBezier`\n- Element changing state (stays on screen) → `EasingEmphasizedCubicBezier`\n- Looping/infinite → `EasingLinearCubicBezier`\n- Prefer `MotionScheme` specs over manual easing for theme-aware components\n\n---\n\n## 7. Review Flags\n\nPatterns to catch in code review. See also `references/pr-review.md` Category 3.\n\n| Pattern in Code | Flag | Fix |\n|----------------|------|-----|\n| `tween(50)` | Hardcoded duration | `MotionTokens.DurationShort1.toInt()` |\n| `tween(100)` | Hardcoded duration | `MotionTokens.DurationShort2.toInt()` |\n| `tween(150)` | Hardcoded duration | `MotionTokens.DurationShort3.toInt()` |\n| `tween(200)` | Hardcoded duration | `MotionTokens.DurationShort4.toInt()` |\n| `tween(250)` | Hardcoded duration | `MotionTokens.DurationMedium1.toInt()` |\n| `tween(300)` | Hardcoded duration | `MotionTokens.DurationMedium2.toInt()` |\n| `tween(350)` | Hardcoded duration | `MotionTokens.DurationMedium3.toInt()` |\n| `tween(400)` | Hardcoded duration | `MotionTokens.DurationMedium4.toInt()` |\n| `tween(N)` with any integer literal | Hardcoded duration | Nearest `MotionTokens.Duration*` token |\n| `FastOutSlowInEasing` | Pre-M3 easing | `MotionTokens.EasingEmphasizedCubicBezier` |\n| `LinearOutSlowInEasing` | Pre-M3 easing | `MotionTokens.EasingEmphasizedDecelerateCubicBezier` |\n| `FastOutLinearInEasing` | Pre-M3 easing | `MotionTokens.EasingEmphasizedAccelerateCubicBezier` |\n| `animateColorAsState(target)` no `animationSpec` | Missing spec | `MaterialTheme.motionScheme.defaultEffectsSpec()` |\n| Same easing on both `enter` and `exit` | Wrong pairing | Decelerate for enter, Accelerate for exit |\n| Duration > 600ms on non-shared-element | Too slow | Reduce to `DurationLong1`–`DurationLong2` |\n| New component uses explicit `tween()` instead of `MotionScheme` | Not theme-aware | Use `MaterialTheme.motionScheme.defaultSpatialSpec()` / `defaultEffectsSpec()` |\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/modifiers.md",
    "content": "# Jetpack Compose Modifiers Reference\n\nModifiers are the primary way to decorate or augment a composable. They apply layout, drawing, gesture, and accessibility behavior. Understanding modifier ordering and the available APIs is critical for correctness and performance.\n\n## Modifier Chain Ordering\n\nOrder matters. Modifiers are applied left-to-right in the DSL, but conceptually they wrap bottom-to-top. Each modifier receives a lambda that draws/measures the content below it.\n\n```kotlin\n// Example: different results depending on order\nBox(\n    Modifier\n        .background(Color.Red)\n        .padding(16.dp)\n        .size(100.dp)\n)\n// Red background wraps the padded content, which wraps the 100x100 box\n\nBox(\n    Modifier\n        .size(100.dp)\n        .padding(16.dp)\n        .background(Color.Red)\n)\n// 100x100 box is padded, then the whole thing (132x132) gets red background\n```\n\n**Do:** Order modifiers from outer (layout/sizing) to inner (styling/interaction).\n**Don't:** Put `size` after `padding` if you want the padding included in the final size.\n\nSource: `compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Modifier.kt`\n\n## Common Modifier Patterns\n\n### Padding and Sizing\n\n```kotlin\n// Padding: external spacing around content\nBox(Modifier.padding(16.dp)) { }\n\n// Size: exact dimensions (overrides requested size from parent)\nBox(Modifier.size(100.dp)) { }\nBox(Modifier.size(width = 200.dp, height = 100.dp)) { }\n\n// FillMaxWidth/FillMaxHeight: expand to available space\nBox(Modifier.fillMaxWidth(0.8f)) { }  // 80% of parent width\nBox(Modifier.fillMaxSize()) { }       // 100% of parent\n\n// Do: use fillMaxWidth before adding padding for alignment clarity\nColumn(Modifier.fillMaxWidth()) {\n    Box(Modifier.padding(16.dp).fillMaxWidth()) { }\n}\n\n// Don't: apply fillMaxWidth after background if you want background to expand\n// Instead:\nBox(Modifier.fillMaxWidth().background(Color.Blue)) { }\n```\n\n### Background and Border\n\n```kotlin\n// Background applies a color to the surface\nBox(Modifier.background(Color.Blue)) { }\nBox(Modifier.background(Color.Blue, shape = RoundedCornerShape(8.dp))) { }\n\n// Border draws a stroke (order matters!)\nBox(\n    Modifier\n        .size(100.dp)\n        .border(2.dp, Color.Black, RoundedCornerShape(8.dp))\n        .background(Color.White)\n)\n// The border is drawn AFTER background in visual order (because modifiers below it are drawn first)\n\n// Combine background + border: apply border first in chain\nBox(\n    Modifier\n        .border(2.dp, Color.Black, RoundedCornerShape(8.dp))\n        .background(Color.White)\n)\n```\n\n### Clipping\n\n```kotlin\n// Clip content to a shape\nBox(Modifier.clip(RoundedCornerShape(8.dp))) {\n    Image(painter = painterResource(id = R.drawable.my_image), contentDescription = \"\")\n}\n\n// Do: apply clip before background if you want background inside the shape\nBox(\n    Modifier\n        .clip(RoundedCornerShape(8.dp))\n        .background(Color.Blue)\n) { }\n\n// Don't: apply background then clip (works but semantically wrong)\nBox(\n    Modifier\n        .background(Color.Blue)\n        .clip(RoundedCornerShape(8.dp))\n) { }\n```\n\n## Clickable and Combined Clickable\n\n```kotlin\n// Basic click handling with ripple effect (Material 3 default)\nButton(onClick = { }) { Text(\"Click me\") }\n\n// Manual clickable with ripple\nBox(\n    Modifier\n        .size(100.dp)\n        .clickable(\n            indication = ripple(),  // Material ripple feedback\n            interactionSource = remember { MutableInteractionSource() }\n        ) { /* handle click */ }\n)\n\n// Combined clickable: long press + double click + click\nBox(\n    Modifier\n        .combinedClickable(\n            onClick = { },\n            onLongClick = { },\n            onDoubleClick = { },\n            indication = ripple()\n        )\n) { }\n\n// Do: provide explicit interactionSource for testing/state observation\nval interactionSource = remember { MutableInteractionSource() }\nBox(\n    Modifier.clickable(\n        interactionSource = interactionSource,\n        indication = ripple()\n    ) { }\n)\n\n// Don't: forget indication parameter (will have no visual feedback)\nBox(Modifier.clickable { }) { }  // No ripple\n```\n\n## Modifier.composed vs Modifier.Node\n\nThe old API (`composed`) is being phased out in favor of the new `ModifierNodeElement` API. Both work, but new code should use the latter.\n\n### Old API: Modifier.composed\n\n```kotlin\nfun Modifier.myCustomModifier(value: String) = composed {\n    val state = remember { mutableStateOf(value) }\n    this.then(\n        Modifier\n            .background(Color.Blue)\n            .clickable { state.value = \"updated\" }\n    )\n}\n```\n\n- Creates a new composable scope\n- Captures composition locals\n- Causes recomposition when remember state changes\n- Deprecated but still supported\n\n### New API: Modifier.Node\n\n```kotlin\nclass MyCustomNode(val value: String) : Modifier.Node {\n    override fun onDetach() {\n        // Cleanup when removed\n    }\n}\n\ndata class MyCustomElement(val value: String) : ModifierNodeElement<MyCustomNode>() {\n    override fun create() = MyCustomNode(value)\n    override fun update(node: MyCustomNode) {\n        node.value = value\n    }\n}\n\nfun Modifier.myCustomModifier(value: String) = this.then(MyCustomElement(value))\n```\n\n**Do:** Use `Modifier.Node` for new custom modifiers. It's more efficient and doesn't create composition scopes.\n**Don't:** Create new `composed` modifiers; migrate existing ones to `Modifier.Node`.\n\nSource: `compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/modifier/ModifierNodeElement.kt`\n\n## Layout vs Drawing vs Pointer Input Modifiers\n\nModifiers fall into categories that affect when they execute:\n\n```kotlin\n// Layout modifier: affects measurement and layout pass\nfun Modifier.customSize(width: Dp, height: Dp) =\n    this.then(object : LayoutModifier {\n        override fun MeasureScope.measure(measurable: Measurable, constraints: Constraints) =\n            measurable.measure(Constraints.fixed(width.roundToPx(), height.roundToPx()))\n                .run { layout(width = size.width, height = size.height) { place(0, 0) } }\n    })\n\n// Drawing modifier: doesn't affect layout, just draws after content\nfun Modifier.customDraw() = drawBehind { drawCircle(Color.Red) }\n\n// Pointer input modifier: handles gestures/events\nfun Modifier.detectCustomGesture() = pointerInput(Unit) {\n    detectTapGestures { offset -> /* handle */ }\n}\n```\n\n**Do:** Use layout modifiers for sizing/positioning, drawing modifiers for visual effects, pointer modifiers for input.\n**Don't:** Use layout modifiers to create visual effects; use drawing modifiers instead.\n\n## Modifier.graphicsLayer — Performance Implications\n\n`graphicsLayer` applies transformations at the graphics rendering level. It's more efficient than recomposing for animations.\n\n```kotlin\n// Efficient: transforms applied on the graphics layer, no recomposition\nBox(\n    Modifier.graphicsLayer(\n        scaleX = 1.2f,\n        scaleY = 1.2f,\n        translationX = 10f,\n        rotationZ = 45f,\n        alpha = 0.8f\n    )\n) { }\n\n// Less efficient: recomposes every frame\nvar scaleX by remember { mutableStateOf(1f) }\nLaunchedEffect(Unit) {\n    while (true) {\n        scaleX = 1.2f\n        delay(16)\n    }\n}\nBox(Modifier.scale(scaleX)) { }\n```\n\n**Do:** Use `graphicsLayer` for animations and frequent property changes.\n**Don't:** Animate state values that trigger recomposition when `graphicsLayer` would suffice.\n\nSource: `compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/graphics/GraphicsLayerModifier.kt`\n\n## Modifier.semantics — Accessibility\n\nSemantics describe the meaning of UI elements for screen readers and accessibility tests.\n\n```kotlin\n// Add semantic label\nButton(onClick = { }) {\n    Icon(Icons.Default.Add, contentDescription = null)\n    Text(\"Add item\")\n}\n\n// Custom semantic properties\nBox(\n    Modifier\n        .size(100.dp)\n        .semantics {\n            contentDescription = \"Custom box\"\n            onClick(label = \"Activate\") { true }\n        }\n) { }\n\n// Do: always provide contentDescription for images\nImage(\n    painter = painterResource(id = R.drawable.icon),\n    contentDescription = \"User avatar\"\n)\n\n// Don't: forget contentDescription (screen readers won't announce it)\nImage(painter = painterResource(id = R.drawable.icon), contentDescription = null) // Wrong\n```\n\nSource: `compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/Semantics.kt`\n\n## Modifier.testTag — UI Testing\n\n```kotlin\n// Add a test tag for finding composables in tests\nBox(Modifier.testTag(\"my_box\")) { }\n\n// In tests:\ncomposeTestRule.onNodeWithTag(\"my_box\").performClick()\ncomposeTestRule.onNodeWithTag(\"my_box\").assertIsDisplayed()\n```\n\n**Do:** Use unique, descriptive test tags.\n**Don't:** Use test tags in production code for business logic.\n\n## Review Checklist: Modifier Ordering Bugs\n\n### Hardcoded Size After Caller's `modifier` Parameter\n\nWhen a composable accepts `modifier: Modifier = Modifier` and chains fixed `.height()` / `.width()` / `.size()` after it, caller size constraints are silently ignored or clamped.\n\n```kotlin\n// BAD: caller's height is outer constraint, component's 172.dp is inner — component always renders at 172dp\n@Composable\nfun BannerCard(\n    modifier: Modifier = Modifier,\n) {\n    Box(\n        modifier = modifier          // caller constraints applied first (outer)\n            .fillMaxWidth()\n            .height(172.dp)          // inner — wins when smaller, clamped when larger\n            .clip(RoundedCornerShape(18.dp))\n            .background(Color.Green.copy(alpha = 0.08f)),\n    )\n}\n\n// Caller expects 200dp but gets 172dp:\nBannerCard(modifier = Modifier.height(200.dp))\n\n// Caller expects 100dp — component gets clamped/squished:\nBannerCard(modifier = Modifier.height(100.dp))\n```\n\n**Why it happens:** Modifier chain resolves outer-to-inner (left-to-right). Outer constraint sets max bounds, inner constraint requests within those bounds. First size constraint wins as the ceiling.\n\n**Fix option 1:** Component defaults first, caller can override via `.then(modifier)`:\n```kotlin\n// GOOD: component sets defaults, caller's modifier applied last and can override\n@Composable\nfun BannerCard(\n    modifier: Modifier = Modifier,\n) {\n    Box(\n        modifier = Modifier\n            .fillMaxWidth()\n            .height(172.dp)\n            .clip(RoundedCornerShape(18.dp))\n            .background(Color.Green.copy(alpha = 0.08f))\n            .then(modifier),         // caller can override size\n    )\n}\n```\n\n**Fix option 2:** Use `defaultMinSize` for flexible sizing:\n```kotlin\n// GOOD: minimum guaranteed, caller can make it larger\n@Composable\nfun BannerCard(\n    modifier: Modifier = Modifier,\n) {\n    Box(\n        modifier = modifier\n            .fillMaxWidth()\n            .defaultMinSize(minHeight = 172.dp)  // floor, not ceiling\n            .clip(RoundedCornerShape(18.dp))\n            .background(Color.Green.copy(alpha = 0.08f)),\n    )\n}\n```\n\n**Rule:** When a composable accepts `modifier: Modifier = Modifier`, never chain fixed `.height()` / `.width()` / `.size()` after the caller's modifier — caller constraints become outer bounds and the component's fixed size either ignores or gets clamped by them. Use `.then(modifier)` at the end or `defaultMinSize` for flexible sizing. Flag in every PR review.\n\n---\n\n## Anti-patterns\n\n### Creating Modifiers in Composition\n\n```kotlin\n// Don't: creates a new Modifier every recomposition\n@Composable\nfun BadModifier() {\n    Box(Modifier.padding(16.dp).background(Color.Blue)) { }\n}\n\n// Do: extract to a variable or parameter\n@Composable\nfun GoodModifier(modifier: Modifier = Modifier) {\n    Box(modifier.padding(16.dp).background(Color.Blue)) { }\n}\n```\n\n### Conditional Modifier Chains Done Wrong\n\n```kotlin\n// Don't: breaks type checking and readability\nval mod = if (isSelected) Modifier.background(Color.Blue) else Modifier\nBox(mod.padding(16.dp)) { }\n\n// Do: use then() for conditional chaining\nBox(\n    Modifier\n        .padding(16.dp)\n        .then(if (isSelected) Modifier.background(Color.Blue) else Modifier)\n) { }\n```\n\n---\n\n**Summary:** Master modifier ordering, prefer `Modifier.Node` over `composed`, use `graphicsLayer` for animations, and always consider the semantic layer for accessibility.\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/multiplatform.md",
    "content": "# Compose Multiplatform (CMP) Reference\n\nReference: `compose-multiplatform` (JetBrains), `androidx.compose` (Google)\n\n## CMP Architecture Overview\n\nCompose Multiplatform uses a three-layer architecture:\n\n### Layer 1: commonMain (Shared UI Runtime)\n\nAll Compose runtime, foundation, material3, and navigation APIs live here. Rendering uses Skia (via Skiko) on non-Android platforms, and the native Android Compose renderer on Android.\n\n```kotlin\n// commonMain/kotlin/App.kt\n@Composable\nfun App() {\n    MaterialTheme {\n        var count by remember { mutableIntStateOf(0) }\n        Button(onClick = { count++ }) {\n            Text(\"Clicked $count times\")\n        }\n    }\n}\n```\n\nThis single composable renders natively on Android, Desktop (JVM), iOS, and WebAssembly.\n\n### Layer 2: Platform Source Sets\n\nPlatform-specific code lives in `androidMain`, `desktopMain`, `iosMain`, `wasmJsMain`. Use `expect`/`actual` to bridge.\n\n```\nsrc/\n  commonMain/kotlin/       # Shared UI + logic\n  androidMain/kotlin/      # Android-specific (AndroidView, Context)\n  desktopMain/kotlin/      # Desktop-specific (Window, MenuBar)\n  iosMain/kotlin/          # iOS-specific (UIKitView, NSBundle)\n  wasmJsMain/kotlin/       # Web-specific (ComposeViewport)\n```\n\n### Layer 3: Platform Entry Points\n\nEach platform has a different entry point to host the shared `App()` composable.\n\n```kotlin\n// androidMain — Standard Android Activity\nclass MainActivity : ComponentActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContent { App() }\n    }\n}\n\n// desktopMain — JVM window\nfun main() = application {\n    Window(\n        onCloseRequest = ::exitApplication,\n        title = \"My App\"\n    ) {\n        App()\n    }\n}\n\n// iosMain — UIKit integration\nfun MainViewController(): UIViewController =\n    ComposeUIViewController { App() }\n\n// wasmJsMain — Browser canvas\n@OptIn(ExperimentalComposeUiApi::class)\nfun main() {\n    ComposeViewport(document.body!!) {\n        App()\n    }\n}\n```\n\n---\n\n## API Availability Matrix\n\n| API | commonMain | Android | Desktop | iOS | Web |\n|-----|:----------:|:-------:|:-------:|:---:|:---:|\n| **Runtime** (`@Composable`, `remember`, `mutableStateOf`, `LaunchedEffect`, `derivedStateOf`) | Yes | Yes | Yes | Yes | Yes |\n| **Foundation** (`Box`, `Column`, `Row`, `LazyColumn`, `TextField`, `Canvas`) | Yes | Yes | Yes | Yes | Yes |\n| **Material3** (`Button`, `Card`, `Scaffold`, `TopAppBar`, `NavigationBar`) | Yes | Yes | Yes | Yes | Yes |\n| **Navigation Compose** (type-safe `@Serializable` routes, `NavHost`) | Yes | Yes | Yes | Yes | Yes |\n| **ViewModel** (`lifecycle-viewmodel-compose:2.10.0+`) | Yes | Yes | Yes | Yes | Yes |\n| **`collectAsState()`** | Yes | Yes | Yes | Yes | Yes |\n| **Compose Resources** (`Res.drawable.*`, `Res.string.*`, `Res.font.*`) | Yes | Yes | Yes | Yes | Yes |\n| `AndroidView` | -- | Yes | -- | -- | -- |\n| `BackHandler` | -- | Yes | -- | -- | -- |\n| `dynamicColorScheme()` | -- | Yes | -- | -- | -- |\n| `LocalContext` | -- | Yes | -- | -- | -- |\n| `collectAsStateWithLifecycle()` | -- | Yes | -- | -- | -- |\n| `hiltViewModel()` | -- | Yes | -- | -- | -- |\n| Baseline Profiles / Macrobenchmark | -- | Yes | -- | -- | -- |\n| `Window`, `MenuBar`, `Tray` | -- | -- | Yes | -- | -- |\n| `DialogWindow` | -- | -- | Yes | -- | -- |\n| `ComposePanel`, `SwingPanel` | -- | -- | Yes | -- | -- |\n| Scrollbar composables | -- | -- | Yes | -- | -- |\n| Keyboard shortcuts (`KeyShortcut`) | -- | -- | Yes | -- | -- |\n| Desktop notifications | -- | -- | Yes | -- | -- |\n| `UIKitView`, `UIKitViewController` | -- | -- | -- | Yes | -- |\n| `ComposeUIViewController`, `ComposeUIView` | -- | -- | -- | Yes | -- |\n| `PlatformImeOptions` | -- | -- | -- | Yes | -- |\n| `LocalUIViewController`, `LocalUIView` | -- | -- | -- | Yes | -- |\n| `ComposeViewport` | -- | -- | -- | -- | Yes |\n| Browser history integration | -- | -- | -- | -- | Yes |\n\n**Key insight:** The vast majority of the Compose API surface is available in `commonMain`. Platform-specific APIs exist for interop (embedding native views) and OS-level features (window management, system themes).\n\n---\n\n## expect/actual Patterns\n\n### Pattern 1: isSystemInDarkTheme()\n\nThe theme detection API is `expect` in commonMain with platform-specific implementations.\n\n```kotlin\n// commonMain\n@Composable\nexpect fun isSystemInDarkTheme(): Boolean\n```\n\n```kotlin\n// skikoMain (Desktop, iOS, Web shared actual)\n@Composable\nactual fun isSystemInDarkTheme(): Boolean {\n    val systemTheme = LocalSystemTheme.current\n    return systemTheme == SystemTheme.Dark\n}\n```\n\n```kotlin\n// androidMain\n@Composable\nactual fun isSystemInDarkTheme(): Boolean {\n    val uiMode = LocalContext.current.resources.configuration.uiMode\n    return (uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES\n}\n```\n\n### Pattern 2: ResourceReader\n\nThe resource reading interface has four platform actuals because each platform loads files differently.\n\n```kotlin\n// commonMain\ninternal expect fun getPlatformResourceReader(): ResourceReader\n\ninterface ResourceReader {\n    suspend fun read(path: String): ByteArray\n    suspend fun readPart(path: String, offset: Long, size: Long): ByteArray\n    fun getUri(path: String): String\n}\n```\n\n```kotlin\n// androidMain — uses AssetManager\ninternal actual fun getPlatformResourceReader(): ResourceReader =\n    object : ResourceReader {\n        override suspend fun read(path: String): ByteArray =\n            context.assets.open(path).use { it.readBytes() }\n        override fun getUri(path: String): String =\n            \"file:///android_asset/$path\"\n        // ...\n    }\n\n// desktopMain — uses ClassLoader\ninternal actual fun getPlatformResourceReader(): ResourceReader =\n    object : ResourceReader {\n        override suspend fun read(path: String): ByteArray =\n            this::class.java.classLoader!!.getResourceAsStream(path)!!.readBytes()\n        override fun getUri(path: String): String =\n            this::class.java.classLoader!!.getResource(path)!!.toURI().toString()\n        // ...\n    }\n\n// iosMain — uses NSBundle + NSFileManager\ninternal actual fun getPlatformResourceReader(): ResourceReader =\n    object : ResourceReader {\n        override suspend fun read(path: String): ByteArray {\n            val nsPath = NSBundle.mainBundle.resourcePath + \"/\" + path\n            return NSFileManager.defaultManager.contentsAtPath(nsPath)!!.toByteArray()\n        }\n        // ...\n    }\n\n// wasmJsMain — uses window.fetch()\ninternal actual fun getPlatformResourceReader(): ResourceReader =\n    object : ResourceReader {\n        override suspend fun read(path: String): ByteArray {\n            val response = window.fetch(path).await()\n            return response.arrayBuffer().await().toByteArray()\n        }\n        // ...\n    }\n```\n\n### Pattern 3: rememberResourceState (Sync vs Async)\n\nJVM and iOS can load resources synchronously. JS/WASM must load asynchronously (returns default value first, then updates).\n\n```kotlin\n// JVM/iOS (skikoMain without web)\n@Composable\ninternal actual fun <T> rememberResourceState(\n    key: Any,\n    getDefault: () -> T,\n    block: suspend () -> T\n): State<T> {\n    // Can block briefly to load synchronously on first composition\n    return remember(key) { mutableStateOf(runBlocking { block() }) }\n}\n\n// wasmJsMain\n@Composable\ninternal actual fun <T> rememberResourceState(\n    key: Any,\n    getDefault: () -> T,\n    block: suspend () -> T\n): State<T> {\n    val state = remember(key) { mutableStateOf(getDefault()) }\n    LaunchedEffect(key) {\n        state.value = block()  // Async update after initial render\n    }\n    return state\n}\n```\n\n**Pitfall:** On WASM, resources loaded with `Res.*` may flash a default value before the actual resource loads. Design UIs to handle this gracefully (use placeholders or loading states).\n\n### Pattern 4: Font Loading\n\nEach platform uses its native font system, so font instantiation is platform-specific.\n\n```kotlin\n// commonMain\n@Composable\nexpect fun Font(resource: FontResource, weight: FontWeight, style: FontStyle): Font\n\n// androidMain — Typeface from assets\n@Composable\nactual fun Font(resource: FontResource, weight: FontWeight, style: FontStyle): Font {\n    val typeface = remember(resource) { Typeface.createFromAsset(context.assets, resource.path) }\n    return AndroidFont(typeface, weight, style)\n}\n\n// desktopMain — java.awt.Font from classpath\n// iosMain — CTFontCreateWithFontDescriptor from bundle\n// wasmJsMain — FontFace API loaded via fetch\n```\n\n### Pattern 5: getSystemEnvironment\n\nReturns locale, theme, and density information per platform.\n\n```kotlin\n// commonMain\ninternal expect fun getSystemEnvironment(): ResourceEnvironment\n\ndata class ResourceEnvironment(\n    val language: LanguageQualifier,\n    val region: RegionQualifier,\n    val theme: ThemeQualifier,\n    val density: DensityQualifier\n)\n\n// androidMain — reads from Configuration + DisplayMetrics\n// desktopMain — reads from Locale.getDefault() + system theme detection\n// iosMain — reads from NSLocale.currentLocale + UITraitCollection\n// wasmJsMain — reads from navigator.language + matchMedia(\"(prefers-color-scheme: dark)\")\n```\n\n---\n\n## Resource System (Res.*)\n\n### Directory Structure\n\nPlace resources under `commonMain/composeResources/`:\n\n```\ncommonMain/\n  composeResources/\n    drawable/\n      icon.xml              # Vector drawable (works on ALL platforms)\n      logo.png\n    drawable-dark/\n      icon.xml              # Dark theme variant (auto-selected)\n    font/\n      roboto_regular.ttf\n      roboto_bold.ttf\n    values/\n      strings.xml           # Default strings\n    values-fr/\n      strings.xml           # French localization\n    files/\n      data.json             # Raw files\n```\n\n### Usage\n\n```kotlin\n// Images\n@Composable\nfun AppLogo() {\n    Image(\n        painter = painterResource(Res.drawable.logo),\n        contentDescription = \"App logo\"\n    )\n}\n\n// Strings (with arguments)\n@Composable\nfun Greeting(name: String) {\n    Text(stringResource(Res.string.greeting, name))\n}\n\n// Fonts\n@Composable\nfun StyledText() {\n    val fontFamily = FontFamily(Font(Res.font.roboto_regular))\n    Text(\"Hello\", fontFamily = fontFamily)\n}\n\n// Raw files\nval bytes: ByteArray = Res.readBytes(\"files/data.json\")\n```\n\n### Gotchas\n\n**Lottie is NOT KMP-compatible.** The standard `com.airbnb.lottie:lottie-compose` only works on Android. For multiplatform Lottie animations, use:\n- **Kottie** (`io.github.ismai117:kottie`) -- all CMP targets\n- **Compottie** (`io.github.alexzhirkevich:compottie`) -- all CMP targets\n\n**Multi-module font loading:** Fonts must be declared in the module that owns the `composeResources/` directory. In multi-module projects, place shared fonts in the top-level (app) module or create a shared resources module. Child modules cannot reference parent module resources directly.\n\n**Android XML vectors work everywhere.** Android-format `VectorDrawable` XML files placed in `drawable/` render correctly on all platforms via the CMP Skia-based renderer. No conversion needed.\n\n**Replace R.* with Res.*:**\n\n```kotlin\n// Android-only (will not compile in commonMain)\npainterResource(R.drawable.icon)\nstringResource(R.string.greeting)\n\n// CMP (works in commonMain)\npainterResource(Res.drawable.icon)\nstringResource(Res.string.greeting)\n```\n\n---\n\n## Migration from Android-Only to CMP\n\n### Dependency Replacement Table\n\n| Android-Only | CMP Replacement | Notes |\n|-------------|-----------------|-------|\n| Hilt (`hiltViewModel()`) | Koin (`koinViewModel()`) | Koin has first-class KMP support. Koin 4.0+ has Compose annotations. |\n| Retrofit | Ktor Client | Ktor has multiplatform HTTP engines per platform. |\n| Room | SQLDelight | SQLDelight generates Kotlin from SQL. Room KMP is experimental (2.7.0-alpha). |\n| Coil 2.x | Coil 3.x KMP | Coil 3.0+ is fully multiplatform. Same API. |\n| Lottie | Kottie / Compottie | See Lottie gotcha above. |\n| `R.drawable.*`, `R.string.*` | `Res.drawable.*`, `Res.string.*` | Compose Resources replaces Android resources. |\n| `collectAsStateWithLifecycle()` | `collectAsState()` | `collectAsState()` is available in commonMain. Lifecycle-awareness is Android-specific. |\n| `BackHandler` | `expect`/`actual` | Implement back handling per platform. Desktop/iOS have different back concepts. |\n| `LocalContext.current` | `expect`/`actual` | No universal replacement. Abstract platform needs behind an interface. |\n\n### Top 5 Migration Pitfalls\n\n**1. `LocalContext.current` sprinkled everywhere**\n\nThere is no KMP replacement for Android `Context`. Every usage must be audited and abstracted.\n\n```kotlin\n// Bad: Context usage scattered in composables\n@Composable\nfun ShareButton(text: String) {\n    val context = LocalContext.current  // Android-only!\n    Button(onClick = {\n        val intent = Intent(Intent.ACTION_SEND).apply { putExtra(Intent.EXTRA_TEXT, text) }\n        context.startActivity(intent)\n    }) { Text(\"Share\") }\n}\n\n// Good: Abstract behind expect/actual\n// commonMain\nexpect fun shareText(text: String)\n\n// androidMain\nactual fun shareText(text: String) {\n    val intent = Intent(Intent.ACTION_SEND).apply { putExtra(Intent.EXTRA_TEXT, text) }\n    applicationContext.startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK))\n}\n\n// iosMain\nactual fun shareText(text: String) {\n    val controller = UIActivityViewController(listOf(text), null)\n    UIApplication.sharedApplication.keyWindow?.rootViewController\n        ?.presentViewController(controller, true, null)\n}\n```\n\n**2. Compose Compiler 2.0.0 incorrect stability inference on non-JVM targets**\n\nThe Compose compiler may incorrectly mark classes as unstable on iOS/WASM targets, causing excessive recomposition. If you see performance issues on non-Android targets:\n\n```kotlin\n// Explicitly annotate shared data classes\n@Immutable\ndata class UiState(\n    val items: List<Item>,\n    val isLoading: Boolean\n)\n```\n\nAlways check compiler stability reports for all targets, not just Android.\n\n**3. Don't migrate bottom-up -- start from the app module**\n\nMigrating leaf modules first creates a broken build that stays broken for weeks. Instead:\n1. Add KMP plugin to the app module\n2. Move composables to `commonMain` one screen at a time\n3. Create `expect`/`actual` stubs for platform dependencies\n4. Migrate feature modules once the app module compiles\n\n**4. `rememberSaveable` + `Bundle` + `@Parcelize` is Android-only**\n\n`Bundle` and `@Parcelize` do not exist on non-Android targets. Use `@Serializable` with a custom `Saver` instead.\n\n```kotlin\n// Android-only (will not compile in commonMain)\n@Parcelize\ndata class FormState(val name: String, val email: String) : Parcelable\n\nvar state by rememberSaveable { mutableStateOf(FormState(\"\", \"\")) }\n\n// CMP-compatible\n@Serializable\ndata class FormState(val name: String, val email: String)\n\nval formStateSaver = Saver<FormState, String>(\n    save = { Json.encodeToString(it) },\n    restore = { Json.decodeFromString(it) }\n)\n\nvar state by rememberSaveable(stateSaver = formStateSaver) {\n    mutableStateOf(FormState(\"\", \"\"))\n}\n```\n\n**5. Version lockstep: Compose, Kotlin, Gradle, AGP**\n\nCMP has strict version compatibility requirements. Mismatched versions produce cryptic compiler errors.\n\n```kotlin\n// build.gradle.kts -- versions must be compatible\nplugins {\n    kotlin(\"multiplatform\") version \"2.1.20\"             // Kotlin version\n    id(\"org.jetbrains.compose\") version \"1.8.0\"          // CMP plugin version\n    id(\"org.jetbrains.kotlin.plugin.compose\") version \"2.1.20\" // Must match Kotlin\n}\n\n// Check compatibility at:\n// https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-compatibility-and-versioning.html\n```\n\n---\n\n## Navigation in CMP\n\n### Navigation Compose (Official -- Recommended)\n\nThe official `androidx.navigation:navigation-compose` is fully multiplatform as of Navigation 2.8.0+. Use `@Serializable` type-safe routes.\n\n```kotlin\n// commonMain -- works on all platforms\n@Serializable\ndata object Home\n\n@Serializable\ndata class Details(val id: Int)\n\n@Composable\nfun AppNavigation() {\n    val navController = rememberNavController()\n    NavHost(navController, startDestination = Home) {\n        composable<Home> {\n            HomeScreen(onItemClick = { id -> navController.navigate(Details(id)) })\n        }\n        composable<Details> { backStackEntry ->\n            val route = backStackEntry.toRoute<Details>()\n            DetailsScreen(itemId = route.id)\n        }\n    }\n}\n```\n\n**Deep link handling differs per platform.** On Android, deep links integrate with `Intent` and `AndroidManifest.xml`. On other platforms, deep links must be wired manually (e.g., custom URL scheme on iOS via `application(_:open:options:)`, browser URL on Web).\n\n### Navigation 3 (Experimental -- CMP 1.10+)\n\nNavigation 3 is a ground-up redesign. `navigation3-common` is multiplatform, but `navigation3-ui` is not yet fully KMP.\n\n```kotlin\n// Available in CMP 1.10+ (experimental)\n// navigation3-common: multiplatform\n// navigation3-ui: limited platform support (check release notes)\n```\n\nWait for stable releases before using in production multiplatform projects.\n\n### Voyager (Third-Party)\n\nSimple screen-based navigation. Good for small to medium apps.\n\n```kotlin\n// commonMain\nclass HomeScreen : Screen {\n    @Composable\n    override fun Content() {\n        val navigator = LocalNavigator.currentOrThrow\n        Button(onClick = { navigator.push(DetailsScreen(42)) }) {\n            Text(\"Go to Details\")\n        }\n    }\n}\n\nclass DetailsScreen(private val id: Int) : Screen {\n    @Composable\n    override fun Content() {\n        val screenModel = rememberScreenModel { DetailsScreenModel(id) }\n        // ScreenModel is Voyager's equivalent of ViewModel\n        Text(\"Details for $id\")\n    }\n}\n\n// Entry point\nNavigator(HomeScreen())\n```\n\n### Decompose (Third-Party)\n\nSeparates navigation logic from UI. Steeper learning curve but maximum testability and control. Navigation state is held in platform-agnostic `ComponentContext` objects.\n\n```kotlin\n// Navigation logic (pure Kotlin, no Compose dependency)\ninterface RootComponent {\n    val childStack: Value<ChildStack<*, Child>>\n    sealed class Child {\n        data class Home(val component: HomeComponent) : Child()\n        data class Details(val component: DetailsComponent) : Child()\n    }\n}\n\n// UI layer (Compose)\n@Composable\nfun RootContent(component: RootComponent) {\n    val childStack by component.childStack.subscribeAsState()\n    Children(childStack) { child ->\n        when (val instance = child.instance) {\n            is RootComponent.Child.Home -> HomeContent(instance.component)\n            is RootComponent.Child.Details -> DetailsContent(instance.component)\n        }\n    }\n}\n```\n\n### Navigation Decision Guide\n\n| Criteria | Navigation Compose | Voyager | Decompose |\n|----------|:-----------------:|:-------:|:---------:|\n| Official support | Yes (Google + JetBrains) | Community | Community |\n| Learning curve | Low | Low | High |\n| Type-safe routes | Yes (`@Serializable`) | Manual | Yes |\n| Testability | Moderate | Moderate | High |\n| All CMP targets | Yes | Yes | Yes |\n| ViewModel integration | Yes (`lifecycle-viewmodel`) | ScreenModel | ComponentContext |\n\n---\n\n## Anti-Patterns\n\n### Don't: Use hiltViewModel() in shared code\n\n```kotlin\n// Will not compile in commonMain -- Hilt is Android-only\n@Composable\nfun ProfileScreen() {\n    val viewModel: ProfileViewModel = hiltViewModel()  // Android-only!\n}\n\n// Use lifecycle-viewmodel-compose (KMP) or Koin\n@Composable\nfun ProfileScreen() {\n    val viewModel = viewModel { ProfileViewModel() }       // KMP ViewModel\n    // or\n    val viewModel = koinViewModel<ProfileViewModel>()      // Koin KMP\n}\n```\n\n### Don't: Use @Preview from the wrong package in commonMain\n\n```kotlin\n// Will not compile in commonMain\nimport androidx.compose.ui.tooling.preview.Preview  // Android-only package!\n\n@Preview\n@Composable\nfun MyPreview() { /* ... */ }\n\n// CMP preview support varies by IDE and target\n// Use Android Studio previews in androidMain only\n// For Desktop, run the app directly (hot reload is fast)\n```\n\n### Don't: Use R.* in shared code\n\n```kotlin\n// Will not compile in commonMain\nImage(painter = painterResource(R.drawable.icon), contentDescription = null)\nText(stringResource(R.string.title))\n\n// Use Compose Resources\nImage(painter = painterResource(Res.drawable.icon), contentDescription = null)\nText(stringResource(Res.string.title))\n```\n\n### Don't: Assume collectAsStateWithLifecycle exists in commonMain\n\n```kotlin\n// Will not compile in commonMain\nval state by viewModel.uiState.collectAsStateWithLifecycle()  // Android-only!\n\n// Use collectAsState() instead -- available everywhere\nval state by viewModel.uiState.collectAsState()\n\n// collectAsState() is sufficient for CMP. The lifecycle awareness of\n// collectAsStateWithLifecycle() is an Android optimization that stops\n// collection when the app is backgrounded. On Desktop/Web this is\n// unnecessary; on iOS, CMP handles lifecycle automatically.\n```\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/navigation.md",
    "content": "# Navigation in Jetpack Compose\n\nReference: `androidx/navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/`\n\n## Setup\n\n### Basic NavHost and NavController\n\n```kotlin\nval navController = rememberNavController()\n\nNavHost(\n    navController = navController,\n    startDestination = \"home\" // Use Route::class with type-safe navigation\n) {\n    composable<Home> {\n        HomeScreen(onNavigate = { navController.navigate(Details()) })\n    }\n}\n```\n\n`rememberNavController()` creates a `NavController` that survives recomposition. Always use it in `NavHost`—never create `NavController` in a ViewModel.\n\n## Type-Safe Navigation (Navigation 2.8+)\n\nUse `@Serializable` route classes instead of string routes. This is the recommended pattern.\n\n```kotlin\n@Serializable\ndata class Home(val userId: String? = null)\n\n@Serializable\ndata class Details(val itemId: Int)\n\nNavHost(navController, startDestination = Home()) {\n    composable<Home> { backStackEntry ->\n        val args = backStackEntry.toRoute<Home>()\n        HomeScreen(userId = args.userId)\n    }\n    composable<Details> { backStackEntry ->\n        val args = backStackEntry.toRoute<Details>()\n        DetailsScreen(itemId = args.itemId)\n    }\n}\n```\n\nSerialize complex types using `@Serializable` on nested data classes:\n\n```kotlin\n@Serializable\ndata class User(val id: Int, val name: String)\n\n@Serializable\ndata class UserProfile(val user: User)\n\n// Navigate:\nnavController.navigate(UserProfile(user = User(1, \"Alice\")))\n```\n\n## Declaring Destinations\n\n### composable — Screen destinations\n\n```kotlin\ncomposable<Route> { backStackEntry ->\n    ScreenContent()\n}\n```\n\n### dialog — Dialog destinations\n\n```kotlin\ndialog<Route> { backStackEntry ->\n    AlertDialog(...)\n}\n```\n\n### navigation — Nested graphs (feature modules)\n\n```kotlin\nnavigation<RootRoute>(startDestination = Home()) {\n    composable<Home> { HomeScreen() }\n    composable<Details> { DetailsScreen() }\n}\n```\n\n## Navigating\n\n### Navigate to a destination\n\n```kotlin\n// Type-safe\nnavController.navigate(Details(itemId = 42))\n\n// Avoid: string-based navigation\nnavController.navigate(\"details/42\") // Anti-pattern\n```\n\n### Pop back stack\n\n```kotlin\nnavController.popBackStack()\n\n// Pop with return value (save state before popping)\nnavController.previousBackStackEntry?.savedStateHandle?.set(\"key\", value)\nnavController.popBackStack()\n\n// In destination, retrieve:\nval result = navController.currentBackStackEntry?.savedStateHandle?.get<T>(\"key\")\n```\n\n### popUpTo — Clear back stack\n\n```kotlin\n// Navigate to Details, clearing Home from stack\nnavController.navigate(\n    Details(itemId = 42),\n    navOptions = navOptions {\n        popUpTo(Home::class) { inclusive = false }\n    }\n)\n\n// inclusive = true: Remove the target route too\nnavController.navigate(\n    Login(),\n    navOptions = navOptions {\n        popUpTo(Home::class) { inclusive = true }\n    }\n)\n\n// launchSingleTop: Reuse existing instance if already on stack\nnavController.navigate(\n    Details(itemId = 42),\n    navOptions = navOptions {\n        launchSingleTop = true\n    }\n)\n```\n\n## Arguments and Back Stack Data\n\nCompose Navigation handles serialization automatically with `@Serializable` routes.\n\n### Passing complex data\n\n```kotlin\n@Serializable\ndata class Message(val id: Int, val text: String, val metadata: Metadata)\n\n@Serializable\ndata class Metadata(val timestamp: Long, val priority: Int)\n\nnavController.navigate(Message(1, \"Hello\", Metadata(System.currentTimeMillis(), 1)))\n```\n\n### Result passing via SavedStateHandle\n\n```kotlin\n// Send result back\nnavController.previousBackStackEntry?.savedStateHandle?.set(\"result\", \"success\")\nnavController.popBackStack()\n\n// Receive in previous screen\nval result = navController.currentBackStackEntry?.savedStateHandle?.get<String>(\"result\")\n```\n\n## Nested Navigation Graphs\n\nOrganize related destinations into feature graphs.\n\n```kotlin\nnavigation<FeatureRoot>(startDestination = FeatureHome()) {\n    composable<FeatureHome> { FeatureHomeScreen(onNext = { navController.navigate(FeatureDetail()) }) }\n    composable<FeatureDetail> { FeatureDetailScreen() }\n}\n```\n\nBenefits: scoped ViewModels, separate back stack behavior, feature isolation.\n\n## Deep Links\n\nDeclare deep links to open your app from URLs or notifications.\n\n```kotlin\ncomposable<Details>(\n    deepLinks = listOf(\n        navDeepLink<Details>(\n            uriPattern = \"https://example.com/details/{itemId}\"\n        )\n    )\n) { backStackEntry ->\n    val args = backStackEntry.toRoute<Details>()\n    DetailsScreen(itemId = args.itemId)\n}\n\n// Navigate via deep link\nnavController.navigate(\"https://example.com/details/42\")\n```\n\nHandle in `AndroidManifest.xml`:\n\n```xml\n<activity android:name=\".MainActivity\">\n    <intent-filter>\n        <action android:name=\"android.intent.action.VIEW\" />\n        <category android:name=\"android.intent.category.DEFAULT\" />\n        <category android:name=\"android.intent.category.BROWSABLE\" />\n        <data android:scheme=\"https\" android:host=\"example.com\" />\n    </intent-filter>\n</activity>\n```\n\n## Back Stack Management\n\n### saveState / restoreState\n\nPreserve screen state during navigation:\n\n```kotlin\nnavController.navigate(\n    Details(itemId = 42),\n    navOptions = navOptions {\n        saveState = true\n        restoreState = true\n    }\n)\n```\n\n### Check current route\n\n```kotlin\nval currentRoute = navController.currentBackStackEntry?.destination?.route\n```\n\n### Observe back stack\n\n```kotlin\nval backStackEntry by navController.currentBackStackEntryAsState()\nval route = backStackEntry?.destination?.route\n```\n\n## Bottom Navigation Integration\n\n```kotlin\nvar selectedItem by remember { mutableStateOf(\"home\") }\nval navController = rememberNavController()\n\nScaffold(\n    bottomBar = {\n        NavigationBar {\n            NavigationBarItem(\n                selected = selectedItem == \"home\",\n                onClick = {\n                    selectedItem = \"home\"\n                    navController.navigate(Home()) {\n                        popUpTo(Home::class) { inclusive = true }\n                        launchSingleTop = true\n                    }\n                },\n                icon = { Icon(Icons.Default.Home, null) },\n                label = { Text(\"Home\") }\n            )\n            NavigationBarItem(\n                selected = selectedItem == \"profile\",\n                onClick = {\n                    selectedItem = \"profile\"\n                    navController.navigate(Profile()) {\n                        popUpTo(Home::class) { inclusive = false }\n                        launchSingleTop = true\n                    }\n                },\n                icon = { Icon(Icons.Default.Person, null) },\n                label = { Text(\"Profile\") }\n            )\n        }\n    }\n) {\n    NavHost(navController, startDestination = Home()) {\n        composable<Home> { HomeScreen() }\n        composable<Profile> { ProfileScreen() }\n    }\n}\n```\n\n## Shared Element Transitions\n\n```kotlin\nNavHost(navController, startDestination = List()) {\n    composable<List>(\n        sharedTransitionSpec = {\n            SharedTransitionLayout()\n        }\n    ) {\n        ListScreen()\n    }\n    composable<Detail>(\n        sharedTransitionSpec = {\n            SharedTransitionLayout()\n        }\n    ) {\n        DetailScreen()\n    }\n}\n```\n\nUse in screens:\n\n```kotlin\nImage(\n    painter = painterResource(id = R.drawable.image),\n    contentDescription = null,\n    modifier = Modifier.sharedBounds(\n        sharedContentState = rememberSharedContentState(key = \"image\"),\n        animatedVisibilityScope = this\n    )\n)\n```\n\n## ViewModel Scoping with Navigation\n\nUse `hiltViewModel()` to scope ViewModels to a back stack entry.\n\n```kotlin\ncomposable<Details> { backStackEntry ->\n    val viewModel: DetailsViewModel = hiltViewModel()\n    DetailsScreen(viewModel = viewModel)\n}\n```\n\nViewModels scoped this way survive configuration changes but are cleared when the back stack entry is removed.\n\n## Testing Navigation\n\nUse `TestNavHostController` to test navigation behavior.\n\n```kotlin\n@get:Rule\nval composeTestRule = createComposeRule()\n\n@Test\nfun navigateToDetails() {\n    val navController = TestNavHostController(ApplicationProvider.getApplicationContext())\n    navController.navigatorProvider.addNavigator(ComposeNavigator())\n\n    composeTestRule.setContent {\n        NavHost(navController, startDestination = Home()) {\n            composable<Home> { HomeScreen(onNavigate = { navController.navigate(Details()) }) }\n            composable<Details> { DetailsScreen() }\n        }\n    }\n\n    composeTestRule.onNodeWithTag(\"detail_button\").performClick()\n    assertEquals(Details::class.serializer().descriptor.serialName, navController.currentBackStackEntry?.destination?.route)\n}\n```\n\n## Anti-Patterns\n\n### Don't: Use string-based routes\n```kotlin\n// ❌ Anti-pattern\nnavController.navigate(\"details/42\")\n\n// ✅ Correct\nnavController.navigate(Details(itemId = 42))\n```\n\n### Don't: Create NavController in ViewModel\n```kotlin\n// ❌ Anti-pattern\nclass MyViewModel : ViewModel() {\n    val navController = NavController(context) // Wrong!\n}\n\n// ✅ Correct\n// NavController lives in NavHost, injected into composables\n```\n\n### Don't: Navigate in composition\n```kotlin\n// ❌ Anti-pattern\n@Composable\nfun MyScreen() {\n    if (condition) {\n        navController.navigate(Details()) // Navigates on every recomposition!\n    }\n}\n\n// ✅ Correct\n@Composable\nfun MyScreen() {\n    LaunchedEffect(condition) {\n        if (condition) {\n            navController.navigate(Details())\n        }\n    }\n}\n```\n\n### Don't: Mix navigation approaches\n```kotlin\n// ❌ Anti-pattern\nnavigation<Feature>(startDestination = \"home\") {\n    composable(\"home\") { } // String-based\n    composable<Details> { } // Type-safe mixed with strings\n}\n\n// ✅ Correct\n@Serializable\nobject FeatureHome\n\nnavigation<FeatureRoot>(startDestination = FeatureHome()) {\n    composable<FeatureHome> { }\n    composable<FeatureDetails> { }\n}\n```\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/performance.md",
    "content": "# Performance Optimization Reference\n\n## Three Phases: Composition, Layout, Drawing\n\nEvery frame consists of three phases. Understanding state reads in each phase prevents unnecessary recompositions.\n\n### Composition Phase\n- Executes composable functions, evaluates state reads\n- Generates lambda and instance allocations\n- **State reads here trigger recomposition** of the entire scope\n\n### Layout Phase\n- Calculates size and position, runs `measure` and `layout` blocks\n- Can read state without triggering composition recomposition\n- Mutable state reads OK; prefer `Modifier.offset { }` over `Modifier.offset()`\n\n### Drawing Phase\n- Emits draw operations, runs `Canvas` and custom `DrawScope`\n- Cannot read mutable state without stability warnings\n\n**Source**: `androidx/compose/runtime/Composer.kt`\n\n---\n\n## Recomposition Skipping with Compiler Reports\n\nThe Compose compiler generates `$changed` bitmasks to detect state changes. Enable compiler reports to inspect stability and skippability:\n\n```kotlin\n// build.gradle.kts\ncomposeCompiler {\n    reportsDestination = layout.buildDirectory.dir(\"compose_reports\")\n    metricsDestination = layout.buildDirectory.dir(\"compose_metrics\")\n}\n```\n\nAfter building (`./gradlew assembleRelease`), check the generated files in `build/compose_reports/`:\n\n- **`*_composables.txt`** — shows each composable's restartability and skippability:\n  ```\n  restartable skippable fun MyComponent(name: String, onClick: Function0<Unit>)\n  restartable fun UnstableComponent(items: List<Item>)  // NOT skippable — unstable param\n  ```\n\n- **`*_classes.txt`** — shows stability inference for each class:\n  ```\n  stable class User { stable val name: String }\n  unstable class ScreenState { unstable val items: List<Item> }\n  ```\n\nA composable missing `skippable` means the compiler cannot skip it during recomposition, even when inputs haven't changed. Fix by stabilizing its parameters (see Stability section below).\n\n### Stability — @Stable and @Immutable\n\nA type is **stable** if:\n- Its public properties are stable\n- Overrides to `equals()` and `hashCode()` are based on stable properties\n- Recomposition is skipped when the same instance is passed\n\nMark stable types explicitly:\n\n```kotlin\n@Immutable\ndata class Person(val name: String, val age: Int)\n\n@Stable\nclass UserViewModel : ViewModel {\n    private val _state = MutableState(UserState())\n    val state: State<UserState> = _state\n}\n\n// Composable receiving stable types can skip recomposition\n@Composable\nfun PersonCard(person: Person) {\n    Text(person.name)  // Skips if person unchanged\n}\n```\n\n**Avoid**: `@Stable` on data classes with mutable fields or non-final properties.\n\n---\n\n## Strong Skipping Mode (Default)\n\nAndroid Gradle Plugin 8.0+ and Compose compiler 1.5.0+ enable **strong skipping mode**. This changes how lambdas are treated:\n\nWithout strong skipping, every lambda is unstable. With it enabled:\n- Lambdas become stable if all captured variables are stable\n- Fewer unnecessary recompositions\n\n```kotlin\n// With strong skipping: lambda is stable if count is stable\n@Composable\nfun Counter(count: Int) {\n    Button(onClick = { println(count) }) {  // Stable lambda\n        Text(\"Count: $count\")\n    }\n}\n```\n\nCheck `build.gradle.kts`:\n```kotlin\nandroid {\n    composeOptions {\n        kotlinCompilerExtensionVersion = \"1.5.0\"\n    }\n}\n```\n\n---\n\n## Defer State Reads to Layout/Draw Phase\n\nReading state in composition triggers recomposition. Push reads to later phases:\n\n### Bad: Recomposition on Every Offset Change\n```kotlin\n@Composable\nfun Box(offsetX: State<Float>) {\n    val x = offsetX.value  // Reads in composition, triggers recomposition\n    Box(modifier = Modifier.offset(x.dp, 0.dp))\n}\n```\n\n### Good: Deferred Read in Layout Phase\n```kotlin\n@Composable\nfun Box(offsetX: State<Float>) {\n    Box(\n        modifier = Modifier.offset {\n            IntOffset(offsetX.value.toInt(), 0)  // Read in layout phase\n        }\n    )\n}\n```\n\nUse `Modifier.offset { }` (lambda) instead of `Modifier.offset()` (parameter) for state-dependent positioning.\n\n---\n\n## derivedStateOf — Reducing Recomposition Frequency\n\nWhen deriving expensive computations from state, wrap in `derivedStateOf` to dedup recompositions:\n\n```kotlin\n// Bad: recomposes on every items change\n@Composable\nfun SearchResults(items: List<Item>, query: String) {\n    val filtered = items.filter { query in it.title }  // Composition phase\n    LazyColumn {\n        items(filtered) { /* ... */ }\n    }\n}\n\n// Good: only recomposes if filtered result actually changes\n@Composable\nfun SearchResults(items: List<Item>, query: String) {\n    val filtered = remember(items, query) {\n        derivedStateOf { items.filter { query in it.title } }\n    }\n    LazyColumn {\n        items(filtered.value) { /* ... */ }\n    }\n}\n```\n\n`derivedStateOf` deduplicates downstream recompositions — two different filters yielding the same list trigger only one downstream recomposition.\n\n---\n\n## remember with Keys\n\nAvoid unnecessary recalculation:\n\n```kotlin\n// Recalculates on every recomposition\n@Composable\nfun ExpensiveItem(id: Int) {\n    val metadata = computeMetadata(id)  // Called every time\n    Text(metadata)\n}\n\n// Recalculates only when id changes\n@Composable\nfun ExpensiveItem(id: Int) {\n    val metadata = remember(id) { computeMetadata(id) }\n    Text(metadata)\n}\n\n// Multiple keys\n@Composable\nfun Item(id: Int, userId: Int) {\n    val data = remember(id, userId) { fetchData(id, userId) }\n    Text(data.toString())\n}\n```\n\nOmit `remember` if computation is cheap (string formatting, simple objects). Over-wrapping causes memory leaks.\n\n---\n\n## LazyList Performance — Keys and ContentType\n\n### Always Provide Keys\n\nKeys enable item reuse and animations:\n\n```kotlin\n// Bad: no keys, items recreated on every list change\nLazyColumn {\n    items(users) { user ->\n        UserRow(user)\n    }\n}\n\n// Good: keys enable reuse\nLazyColumn {\n    items(users, key = { it.id }) { user ->\n        UserRow(user)\n    }\n}\n```\n\n### ContentType for Efficient Reuse\n\n```kotlin\nsealed class ListItem {\n    data class Header(val title: String) : ListItem()\n    data class User(val user: User) : ListItem()\n}\n\nLazyColumn {\n    items(\n        items = items,\n        key = { it.hashCode() },\n        contentType = { item ->\n            when (item) {\n                is ListItem.Header -> \"header\"\n                is ListItem.User -> \"user\"\n            }\n        }\n    ) { item ->\n        when (item) {\n            is ListItem.Header -> HeaderRow(item.title)\n            is ListItem.User -> UserRow(item.user)\n        }\n    }\n}\n```\n\nWithout `contentType`, all items compete for one ViewHolder pool. With it, items reuse efficiently.\n\n### Avoid Allocations in Item Scope\n\n```kotlin\n// Bad: allocates on every recomposition\nLazyColumn {\n    items(users) { user ->\n        val userState = remember { mutableStateOf(user) }\n        UserRow(userState.value)\n    }\n}\n\n// Good: allocates once\nLazyColumn {\n    items(\n        items = users,\n        key = { it.id }\n    ) { user ->\n        UserRow(user)\n    }\n}\n```\n\n---\n\n## Baseline Profiles\n\nBaseline profiles instruct R8 to pre-compile hot code paths, reducing startup time and jank.\n\n### Generating Profiles\n\nUse Jetpack Macrobenchmark to record profiles:\n\n```kotlin\n@RunWith(AndroidBenchmarkRunner::class)\nclass StartupBenchmark {\n    @get:Rule\n    val benchmarkRule = MacrobenchmarkRule()\n\n    @Test\n    fun startupCompilation() = benchmarkRule.measureRepeated(\n        packageName = \"com.example.app\",\n        metrics = listOf(StartupTimings.FIRST_FRAME),\n        iterations = 10,\n        setupBlock = {\n            pressHome()\n            startActivityAndWait()\n        }\n    ) {\n        // Interact with app\n    }\n}\n```\n\nProfiles are generated in `baseline-prof.txt`:\n```\nandroidx/compose/runtime/Recomposer;startRecomposition()V\ncom/example/MyScreen;ComposableFunctionName(ILandroidx/compose/runtime/Composer;I)V\n```\n\n---\n\n## R8/ProGuard Compose Rules\n\nCompose includes default ProGuard rules. Ensure `shrinkResources true` and `minifyEnabled true`:\n\n```gradle\nandroid {\n    buildTypes {\n        release {\n            minifyEnabled true\n            shrinkResources true\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n```\n\nCustom rules to preserve stability:\n\n```proguard\n-keep @androidx.compose.runtime.Stable class **\n-keep @androidx.compose.runtime.Immutable class **\n-keepclassmembers class * {\n    @androidx.compose.runtime.Stable <methods>;\n}\n```\n\n---\n\n## Measuring Performance\n\n### Layout Inspector — Recomposition Counts\n\nIn Android Studio:\n1. Run app on device\n2. Open **Layout Inspector** (Tools > Layout Inspector)\n3. Select target process\n4. Check **Show Composition Counts** (toggle in inspector)\n\nRecomposition counts display how many times each composable was recomposed since inspection started.\n\n### Macrobenchmark — Frame Timing\n\n```kotlin\nbenchmarkRule.measureRepeated(\n    packageName = \"com.example.app\",\n    metrics = listOf(FrameTimingMetric()),\n    iterations = 10\n) {\n    // Interact: scroll, click, etc.\n}\n```\n\nReports frame times (ms), jank, jitter. Target <16.67ms for 60 fps.\n\n---\n\n## Common Hot Paths\n\n### String Formatting in Composition\n```kotlin\n// Bad: allocates string every recomposition\n@Composable\nfun Counter(count: Int) {\n    Text(\"Count: ${count}\")  // String.format called\n}\n\n// Still composed, but optimized\n@Composable\nfun Counter(count: Int) {\n    Text(buildString { append(\"Count: \"); append(count) })\n}\n```\n\n### List Filtering Without derivedStateOf\n```kotlin\n// Bad: filters every recomposition\n@Composable\nfun FilteredList(items: List<Item>, predicate: (Item) -> Boolean) {\n    LazyColumn {\n        items(items.filter(predicate)) { /* ... */ }\n    }\n}\n\n// Good\n@Composable\nfun FilteredList(items: List<Item>, predicate: (Item) -> Boolean) {\n    val filtered = remember(items, predicate) {\n        derivedStateOf { items.filter(predicate) }\n    }\n    LazyColumn {\n        items(filtered.value) { /* ... */ }\n    }\n}\n```\n\n### Creating Objects in Lambdas\n```kotlin\n// Bad\nButton(\n    colors = ButtonDefaults.buttonColors(\n        containerColor = if (isPressed) Color.Red else Color.Blue\n    )\n) { }\n\n// Good: compute once\nval buttonColors = remember(isPressed) {\n    ButtonDefaults.buttonColors(\n        containerColor = if (isPressed) Color.Red else Color.Blue\n    )\n}\nButton(colors = buttonColors) { }\n```\n\n---\n\n## Anti-Patterns\n\n### Wrapping Everything in remember\n```kotlin\n// Unnecessary\nval text = remember { \"Hello\" }\nval size = remember { 12.sp }\nval color = remember { Color.Black }\n```\n\n`remember` only for mutable state or expensive calculations.\n\n### Premature Optimization\nProfile first. Don't add `derivedStateOf` or `remember` without Layout Inspector data.\n\n### @Stable on Mutable Data Classes\n```kotlin\n// DON'T\n@Stable\ndata class MutableUser(val name: String, val age: MutableState<Int>)\n\n// DO\n@Immutable\ndata class User(val name: String, val age: Int)\n```\n\n---\n\n## Resources\n\n- **Compose Compiler Reports**: https://developer.android.com/develop/ui/compose/performance/stability-report\n- **Macrobenchmark**: https://developer.android.com/develop/ui/compose/performance/measurement\n- **Baseline Profiles**: https://developer.android.com/develop/ui/compose/performance/baseline-profiles\n\n---\n\n## Zero-Size DrawScope Guard\n\nDuring initial composition, a composable's size can be zero. This causes crashes in calculations like `size.minDimension / 2`.\n\n```kotlin\n// BAD: crashes when size is zero\nCanvas(modifier = Modifier.fillMaxSize()) {\n    val radius = size.minDimension / 2  // NaN or divide-by-zero\n    drawCircle(color = Color.Blue, radius = radius)\n}\n\n// GOOD: always guard\nCanvas(modifier = Modifier.fillMaxSize()) {\n    if (size.minDimension <= 0f) return@Canvas\n    val radius = size.minDimension / 2\n    drawCircle(color = Color.Blue, radius = radius)\n}\n```\n\nRule: Never use `fillMaxSize()` on Canvas without an explicit height constraint. Always guard DrawScope operations.\n\n---\n\n## Composition Tracing\n\nUse `trace()` for Perfetto/systrace integration:\n\n```kotlin\n@Composable\nfun ExpensiveScreen() {\n    trace(\"ExpensiveScreen\") {\n        // composable body — visible in system traces\n    }\n}\n```\n\nEnables identifying slow composables in production profiling without adding logging.\n\n---\n\n## movableContentOf\n\nAvoid recomposition when moving content between layout positions:\n\n```kotlin\nval movableContent = remember {\n    movableContentOf {\n        ExpensiveChild() // Only composed once, moved without recomposition\n    }\n}\n\nif (isExpanded) {\n    ExpandedLayout { movableContent() }\n} else {\n    CollapsedLayout { movableContent() }\n}\n```\n\nWithout `movableContentOf`, switching between layouts would dispose and recompose `ExpensiveChild`. With it, the content is moved, preserving state and avoiding recomposition.\n\n---\n\n## Compiler Reports (Expanded)\n\nEnable compiler reports to see which composables are skippable and which types are stable:\n\n```kotlin\n// build.gradle.kts\ncomposeCompiler {\n    reportsDestination = layout.buildDirectory.dir(\"compose_reports\")\n    metricsDestination = layout.buildDirectory.dir(\"compose_metrics\")\n}\n```\n\nAfter building, check the output files:\n\n- `*_composables.txt` — shows each composable's status:\n  ```\n  restartable skippable fun MyComponent(name: String, onClick: Function0<Unit>)\n  restartable fun UnstableComponent(items: List<Item>)  // NOT skippable!\n  ```\n\n- `*_classes.txt` — shows type stability:\n  ```\n  stable class User { stable val name: String }\n  unstable class ScreenState { unstable val items: List<Item> }\n  ```\n\nFix unstable types by:\n1. Using `@Stable` annotation on the class\n2. Using `kotlinx.collections.immutable.ImmutableList` instead of `List`\n3. Adding the class to `compose-stability-config.txt` for multi-module projects\n\n---\n\n## Production Performance Rules\n\n1. **R8: strip previews + semantics in release** — add to `proguard-rules.pro`:\n```\n-assumenosideeffects class androidx.compose.ui.tooling.preview.** { *; }\n```\n\n2. **`@Suppress(\"ComposeUnstableCollections\")`** — pragmatic skipping when stability isn't worth the complexity:\n```kotlin\n@Suppress(\"ComposeUnstableCollections\")\n@Composable\nfun ItemList(items: List<Item>) { // List is unstable but acceptable here\n    // ...\n}\n```\n\n3. **ImmutableList for stability** — Guava `ImmutableList` or `kotlinx.collections.immutable`:\n```kotlin\n// Makes the parameter stable, enabling recomposition skipping\n@Composable\nfun StableList(items: ImmutableList<Item>) { ... }\n```\n\n4. **ReportDrawnWhen** for startup performance:\n```kotlin\nReportDrawnWhen { items.isNotEmpty() }\n```\n\n5. **Canvas always explicitly sized** — never `fillMaxSize()` without a height constraint:\n```kotlin\n// BAD\nCanvas(Modifier.fillMaxSize()) { ... }\n\n// GOOD\nCanvas(Modifier.fillMaxWidth().height(200.dp)) { ... }\n```\n\n---\n\n## Compose Multiplatform Performance\n\nPerformance tooling differs across platforms:\n\n| Tool | Android | Desktop | iOS | Web |\n|------|---------|---------|-----|-----|\n| Baseline Profiles | Yes | No | No | No |\n| Macrobenchmark | Yes | No | No | No |\n| Layout Inspector | Yes (AS) | No | No | No |\n| Profiling | Android Studio | JMH | Instruments | Browser DevTools |\n| R8/ProGuard | Yes | ProGuard separately | N/A (Kotlin/Native) | N/A |\n\niOS-specific:\n- Kotlin/Native has different GC behavior than Android ART\n- Enable ProMotion with `CADisableMinimumFrameDurationOnPhone = true` in Info.plist\n- Use configurable frame rate API: increase for animations, decrease for static content\n\nDesktop JVM:\n- Different GC characteristics (G1GC vs ART)\n- JIT compilation warms up differently\n\nWeb/WASM:\n- Renders entire canvas per frame (unlike DOM partial repaints)\n- WASM GC behavior differs from JVM\n- Bundle size impacts initial load time\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/platform-specifics.md",
    "content": "# Platform-Specific APIs and Gotchas (Compose Multiplatform)\n\nCompose Multiplatform shares most UI code across platforms, but entry points, interop APIs, and runtime behavior differ significantly. This reference covers what you need to know per platform.\n\n---\n\n## 1. Desktop (JVM)\n\n### Entry Points\n\nThree ways to launch a Compose Desktop application:\n\n```kotlin\n// Standard — blocks the main thread until all windows close\nfun main() = application {\n    Window(onCloseRequest = ::exitApplication, title = \"My App\") {\n        App()\n    }\n}\n\n// Suspending — same behavior, usable from coroutines\nsuspend fun main() = awaitApplication {\n    Window(onCloseRequest = ::exitApplication, title = \"My App\") {\n        App()\n    }\n}\n\n// Non-blocking — launches in a CoroutineScope, does not block\nfun main() {\n    val scope = CoroutineScope(Dispatchers.Default)\n    scope.launchApplication {\n        Window(onCloseRequest = ::exitApplication, title = \"My App\") {\n            App()\n        }\n    }\n    // scope continues running other coroutines\n}\n```\n\n### Window Composable\n\n`Window` is the top-level container. Key parameters:\n\n| Parameter | Type | Default | Purpose |\n|-----------|------|---------|---------|\n| `onCloseRequest` | `() -> Unit` | required | Called when user clicks close. Use `::exitApplication` or custom logic |\n| `state` | `WindowState` | auto | Controls size, position, placement (maximized/minimized) |\n| `title` | `String` | `\"\"` | Window title bar text |\n| `icon` | `Painter?` | `null` | Window and taskbar icon |\n| `resizable` | `Boolean` | `true` | Whether user can resize |\n| `alwaysOnTop` | `Boolean` | `false` | Pin window above all others |\n| `visible` | `Boolean` | `true` | Show/hide without destroying |\n| `undecorated` | `Boolean` | `false` | Remove OS title bar and borders |\n| `transparent` | `Boolean` | `false` | Transparent background (requires `undecorated = true`) |\n\nFull example with MenuBar:\n\n```kotlin\nfun main() = application {\n    val windowState = rememberWindowState(\n        size = DpSize(800.dp, 600.dp),\n        position = WindowPosition(Alignment.Center)\n    )\n\n    Window(\n        onCloseRequest = ::exitApplication,\n        state = windowState,\n        title = \"My App\"\n    ) {\n        MenuBar {\n            Menu(\"File\") {\n                Item(\"New\", shortcut = KeyShortcut(Key.N, meta = true)) { /* handle */ }\n                Item(\"Open\", shortcut = KeyShortcut(Key.O, meta = true)) { /* handle */ }\n                Separator()\n                Item(\"Exit\", onClick = ::exitApplication)\n            }\n            Menu(\"Edit\") {\n                Item(\"Undo\", shortcut = KeyShortcut(Key.Z, meta = true)) { /* handle */ }\n                Item(\"Redo\", shortcut = KeyShortcut(Key.Z, meta = true, shift = true)) { /* handle */ }\n            }\n        }\n        App()\n    }\n}\n```\n\n### Multi-Window Management\n\n```kotlin\nfun main() = application {\n    var showSettings by remember { mutableStateOf(false) }\n\n    Window(onCloseRequest = ::exitApplication, title = \"Main\") {\n        Button(onClick = { showSettings = true }) { Text(\"Settings\") }\n        App()\n    }\n\n    if (showSettings) {\n        Window(\n            onCloseRequest = { showSettings = false },\n            title = \"Settings\",\n            state = rememberWindowState(size = DpSize(400.dp, 300.dp))\n        ) {\n            SettingsScreen()\n        }\n    }\n}\n```\n\n### Tray Icon\n\n```kotlin\nfun main() = application {\n    var isVisible by remember { mutableStateOf(true) }\n\n    Tray(\n        icon = painterResource(\"app_icon.png\"),\n        menu = {\n            Item(\"Show/Hide\", onClick = { isVisible = !isVisible })\n            Item(\"Exit\", onClick = ::exitApplication)\n        }\n    )\n\n    if (isVisible) {\n        Window(onCloseRequest = { isVisible = false }, title = \"My App\") {\n            App()\n        }\n    }\n}\n```\n\n**Gotcha:** On macOS, `Tray` responds to right-click only. Left-click shows nothing by default. This is OS behavior, not a bug.\n\n### DialogWindow\n\n```kotlin\nvar showDialog by remember { mutableStateOf(false) }\n\nif (showDialog) {\n    DialogWindow(\n        onCloseRequest = { showDialog = false },\n        title = \"Confirm Action\",\n        state = rememberDialogState(size = DpSize(350.dp, 200.dp))\n    ) {\n        Column(modifier = Modifier.padding(16.dp)) {\n            Text(\"Are you sure?\")\n            Row(horizontalArrangement = Arrangement.End, modifier = Modifier.fillMaxWidth()) {\n                TextButton(onClick = { showDialog = false }) { Text(\"Cancel\") }\n                Button(onClick = { /* confirm */ showDialog = false }) { Text(\"OK\") }\n            }\n        }\n    }\n}\n```\n\n### Interop: ComposePanel (Compose inside Swing/AWT)\n\nEmbed Compose content inside an existing Swing application:\n\n```kotlin\nfun main() {\n    SwingUtilities.invokeLater {\n        val frame = JFrame(\"Swing + Compose\")\n        val composePanel = ComposePanel()\n        composePanel.setContent {\n            MaterialTheme {\n                App()\n            }\n        }\n        // Add to any Swing container — JPanel, JLayeredPane, JSplitPane, etc.\n        frame.contentPane.add(composePanel, BorderLayout.CENTER)\n        frame.setSize(800, 600)\n        frame.defaultCloseOperation = JFrame.EXIT_ON_CLOSE\n        frame.isVisible = true\n    }\n}\n```\n\n### Interop: SwingPanel (Swing inside Compose)\n\nEmbed a Swing/AWT component inside Compose:\n\n```kotlin\n@Composable\nfun LegacyTableView(data: List<List<String>>) {\n    SwingPanel(\n        modifier = Modifier.fillMaxSize(),\n        factory = {\n            val model = DefaultTableModel(\n                data.map { it.toTypedArray() }.toTypedArray(),\n                arrayOf(\"Name\", \"Email\", \"Role\")\n            )\n            JScrollPane(JTable(model))\n        },\n        update = { scrollPane ->\n            // Called on recomposition — update the Swing component here\n        }\n    )\n}\n```\n\n### Scrollbar (Desktop-Only)\n\nDesktop has explicit scrollbar composables that do not exist on mobile platforms:\n\n```kotlin\n@Composable\nfun ScrollableContent() {\n    val scrollState = rememberScrollState()\n\n    Box(modifier = Modifier.fillMaxSize()) {\n        Column(\n            modifier = Modifier\n                .verticalScroll(scrollState)\n                .padding(end = 12.dp) // leave room for scrollbar\n        ) {\n            repeat(100) { Text(\"Item $it\", modifier = Modifier.padding(8.dp)) }\n        }\n\n        VerticalScrollbar(\n            adapter = rememberScrollbarAdapter(scrollState),\n            modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(),\n            style = ScrollbarStyle(\n                minimalHeight = 16.dp,\n                thickness = 8.dp,\n                shape = RoundedCornerShape(4.dp),\n                hoverDurationMillis = 300,\n                unhoverColor = Color.Black.copy(alpha = 0.12f),\n                hoverColor = Color.Black.copy(alpha = 0.50f)\n            )\n        )\n    }\n}\n\n// For LazyColumn:\nval lazyListState = rememberLazyListState()\nVerticalScrollbar(\n    adapter = rememberScrollbarAdapter(lazyListState),\n    modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight()\n)\n```\n\n`HorizontalScrollbar` works identically for horizontal scroll containers.\n\n**Key scrolling gotcha:** Desktop scrolling is mouse-wheel only. There are no touch physics, no momentum/fling, and no overscroll bounce effect. Scrolling feels \"mechanical\" compared to mobile. This is expected desktop behavior, not a bug.\n\n---\n\n## 2. iOS\n\n### Entry Point\n\nThe iOS entry point creates a `UIViewController` that hosts Compose content:\n\n```kotlin\n// In iosMain — typically in a file like MainViewController.kt\nfun MainViewController(): UIViewController = ComposeUIViewController { App() }\n```\n\nThis is called from Swift in your iOS app target:\n\n```swift\n// In Swift (e.g., ContentView.swift or AppDelegate)\nimport ComposeApp\n\nstruct ComposeView: UIViewControllerRepresentable {\n    func makeUIViewController(context: Context) -> UIViewController {\n        MainViewControllerKt.MainViewController()\n    }\n    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}\n}\n```\n\n### ComposeUIViewController Configuration\n\n```kotlin\nfun MainViewController(): UIViewController = ComposeUIViewController(\n    configure = {\n        opaque = true               // true = opaque background (better perf), false = transparent\n        parallelRendering = false    // experimental: parallel rendering pipeline\n        onFocusBehavior = OnFocusBehavior.FocusableAboveKeyboard  // auto-scroll focused field above keyboard\n    }\n) {\n    App()\n}\n```\n\n### UIKit Interop — UIKitView\n\nEmbed native UIKit views inside Compose:\n\n```kotlin\n@Composable\nfun NativeMapView(latitude: Double, longitude: Double) {\n    val region = MKCoordinateRegion(\n        CLLocationCoordinate2DMake(latitude, longitude),\n        MKCoordinateSpanMake(0.1, 0.1)\n    )\n\n    UIKitView(\n        factory = { MKMapView() },\n        modifier = Modifier.fillMaxSize(),\n        update = { mapView ->\n            mapView.setRegion(region, animated = true)\n            mapView.mapType = MKMapType.MKMapTypeStandard\n        },\n        properties = UIKitInteropProperties(\n            interactionMode = UIKitInteropInteractionMode.Cooperative(delayMillis = 150)\n        )\n    )\n}\n```\n\n**Interaction modes:**\n- `Cooperative(delayMillis)` — Compose gets first touch. After `delayMillis`, touch passes to UIKit. Use for maps, web views, scrollable native content.\n- `NonCooperative` — UIKit gets all touch events. Compose touch handling is blocked in the UIKitView area. Use only when the native view must own all gestures.\n\n### CompositionLocals for iOS\n\n```kotlin\n// Access the hosting UIViewController\nval viewController = LocalUIViewController.current\nviewController.presentViewController(picker, animated = true, completion = null)\n\n// Access the underlying UIView\nval uiView = LocalUIView.current\n```\n\n### Key Gotchas\n\n**DisposableEffect cleanup unreliable with UINavigationController:**\n`DisposableEffect.onDispose` may not fire when a Compose screen is popped from a `UINavigationController`. Do not rely on it for critical cleanup (e.g., releasing resources, stopping location updates). Use ViewModel `onCleared()` or explicit lifecycle observation instead.\n\n**Keyboard Done button inserts newline instead of submitting** (JetBrains/compose-multiplatform#3473):\nOn iOS, pressing \"Done\" on a `TextField` with `ImeAction.Done` may insert `\\n` instead of triggering `onImeAction`. Workaround:\n\n```kotlin\nTextField(\n    value = text,\n    onValueChange = { newText ->\n        // Filter out newlines inserted by Done key\n        if (\"\\n\" in newText && \"\\n\" !in text) {\n            onSubmit()\n        } else {\n            text = newText\n        }\n    },\n    keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done)\n)\n```\n\n**TextField in scrollable Column pushes TopAppBar off screen** (JetBrains/compose-multiplatform#3621):\nWhen a `TextField` inside a scrollable `Column` receives focus and the keyboard appears, the entire content shifts up, pushing the `TopAppBar` out of view. Mitigate by using `LazyColumn` or wrapping the scrollable area below the app bar with `imePadding()`.\n\n**Touch delay in Cooperative mode:**\nWith `UIKitInteropInteractionMode.Cooperative(delayMillis = 150)`, there is a noticeable ~150ms delay before UIKit views receive touch. Users may perceive maps/web views as unresponsive. Reduce `delayMillis` if the native view does not conflict with Compose gestures, but be aware that lower values increase accidental UIKit touch interception.\n\n**ProMotion 120Hz requires Info.plist entry:**\nCompose renders at 60Hz by default on ProMotion displays (iPhone 13 Pro+, iPad Pro). Add this to `Info.plist` to enable 120Hz:\n\n```xml\n<key>CADisableMinimumFrameDurationOnPhone</key>\n<true/>\n```\n\nWithout this, animations and scrolling will feel noticeably less smooth than native SwiftUI on the same hardware.\n\n**App size overhead:**\nA minimal Compose Multiplatform iOS app is approximately 24.8 MB, compared to ~1.7 MB for an equivalent native SwiftUI app. The Skia rendering engine adds 15-20 MB. This is a fixed cost that does not grow significantly with app complexity, but it matters for markets sensitive to download size.\n\n**Flows continue running in background** (JetBrains/compose-multiplatform#3889):\nUnlike Android (where lifecycle-aware collection pauses in the background), Compose for iOS does not automatically suspend `Flow` collection when the app moves to background. Flows will keep collecting, potentially wasting CPU and battery. You must observe `UIApplication` lifecycle notifications manually:\n\n```kotlin\n@Composable\nfun LifecycleAwareCollection(flow: Flow<Data>) {\n    val lifecycle = LocalLifecycleOwner.current.lifecycle\n    val data by flow.collectAsStateWithLifecycle(\n        initialValue = Data.Empty,\n        lifecycle = lifecycle\n    )\n    // Only collects when in foreground\n}\n```\n\nIf `collectAsStateWithLifecycle` is not available on your CMP version, use a `DisposableEffect` that observes `NSNotificationCenter` for `UIApplicationDidEnterBackgroundNotification` and `UIApplicationWillEnterForegroundNotification`.\n\n---\n\n## 3. Web / WASM\n\n### Entry Point\n\n```kotlin\nfun main() {\n    ComposeViewport(viewportContainerId = \"root\") {\n        App()\n    }\n}\n```\n\nThe corresponding HTML needs a container element:\n\n```html\n<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>My App</title>\n    <script src=\"skiko.js\"></script>\n    <script src=\"composeApp.js\"></script>\n</head>\n<body>\n    <div id=\"root\" style=\"width: 100vw; height: 100vh;\"></div>\n</body>\n</html>\n```\n\n### Fundamental Limitation: Canvas-Only Rendering\n\nCompose for Web renders EVERYTHING to a single `<canvas>` element. There are zero DOM elements for your UI content. This has severe consequences:\n\n| Feature | Works? | Explanation |\n|---------|--------|-------------|\n| Ctrl+F / Cmd+F text search | No | Canvas pixels, not DOM text |\n| Browser translate (Google Translate) | No | No DOM text to translate |\n| HTML form autofill | No | No `<input>` elements |\n| Browser context menus | No | Canvas intercepts right-click |\n| Password manager autofill | No | No `<input type=\"password\">` |\n| SEO / search engine indexing | No | Blank `<canvas>` to crawlers |\n| Server-side rendering (SSR) | No | Requires JS + WASM runtime |\n| Screen reader accessibility | Partial | Compose semantics mapped to ARIA, but limited |\n| Copy/paste text | Partial | Works within Compose, not with browser native |\n\n**If you need SEO, text search, or browser-native form behavior, Compose for Web is not the right choice.** Use Kobweb (Compose HTML) or a traditional web framework for content-heavy pages.\n\n### Navigation and Browser History\n\nRoutes integrate with the browser's History API:\n\n```kotlin\n// Routes update the URL bar — Back/Forward buttons work\n// The exact API depends on your navigation library (e.g., Voyager, Decompose)\n// Key behavior: browser URL updates reflect Compose navigation state\n```\n\n### Browser Compatibility\n\nCompose WASM requires WASM GC (Garbage Collection) support:\n\n| Browser | Minimum Version |\n|---------|----------------|\n| Chrome | 119+ |\n| Firefox | 120+ |\n| Safari | 18.2+ |\n| Edge | 119+ (Chromium-based) |\n\nOlder browsers will show a blank page. There is no graceful fallback.\n\n### Bundle Size\n\nExpect multi-megabyte downloads before first paint:\n- Skiko WASM module: ~5-8 MB\n- Application code: varies, but 2-5 MB typical\n- Total initial load: often 8-15 MB\n\nThis makes Compose WASM unsuitable for landing pages or content sites where first-paint speed matters. It works best for internal tools, dashboards, or app-like experiences where users accept a loading phase.\n\n---\n\n## 4. Performance Across Platforms\n\n### Rendering Stack\n\nEach platform uses a different rendering backend, but all go through Skia:\n\n| Platform | Skia Source | Graphics API | Notes |\n|----------|------------|--------------|-------|\n| Android | Built into the OS | OpenGL ES / Vulkan | No extra binary size. Vulkan on Android 10+ |\n| iOS | Bundled with app (Skiko) | Metal | Adds 15-20 MB to app size |\n| Desktop | Bundled with app (Skiko) | OpenGL / Metal (macOS) / DirectX (Windows) | Auto-selects best backend |\n| Web | Compiled to WASM (Skiko) | WebGL / WebGPU | Single `<canvas>`, all rendering via GPU |\n\n### iOS Performance (CMP 1.8+)\n\nPerformance has improved significantly since early versions:\n\n- **Startup time:** Comparable to native SwiftUI. Cold start overhead is minimal once Skia is initialized.\n- **Scrolling:** On par with SwiftUI, including 120Hz on ProMotion displays (with the Info.plist entry above).\n- **Complex animations:** Generally smooth, but frame drops can occur with deeply nested animated composables or heavy `Canvas` drawing during transitions. Profile with Instruments if you see jank.\n\n### Configurable Frame Rate\n\nFor battery optimization, you can configure the target frame rate:\n\n```kotlin\n// Reduce frame rate when idle or showing static content\n// Platform-specific API — check your CMP version for exact usage\nComposeUIViewController(\n    configure = {\n        // platformLayers configuration varies by version\n    }\n) {\n    App()\n}\n```\n\nOn iOS, this is particularly useful for apps that show mostly static content but occasionally animate. Reducing from 120Hz to 60Hz (or even 30Hz for static screens) can meaningfully improve battery life.\n\n### Cross-Platform Performance Tips\n\n1. **Avoid `Modifier.graphicsLayer` with `clip = true` on iOS** unless needed. Clipping with Skia on Metal has higher cost than native UIKit clipping.\n\n2. **Image decoding is synchronous on iOS** by default. Use `rememberAsyncImagePainter` (Coil) or similar to avoid blocking the main thread on image-heavy screens.\n\n3. **Desktop: disable vsync for benchmarking** but never in production. Without vsync, frame rates become erratic and tearing is visible.\n\n4. **Web: minimize composable count.** Every composable draws to canvas via WebGL. Complex UIs hit GPU limits faster than on native platforms.\n\n5. **Shared code performance is generally the same across platforms.** The Kotlin compiler generates platform-optimized bytecode. Performance differences come from the rendering backend, not from your composable logic.\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/pr-review.md",
    "content": "# PR Review Mode\n\nActivate when: input contains a GitHub PR URL (`github.com/.+/pull/\\d+`) or explicit review\nphrases: \"review this PR\", \"review this diff\", \"check this code\", \"what's wrong with this\".\n\nWhen Review Mode activates:\n1. Do **not** follow the generation workflow in `SKILL.md`\n2. Follow only this document\n3. Output a structured local report — do not post to GitHub\n\n---\n\n## Review Workflow\n\n### Step 1 — Fetch the diff\n\n```bash\ngh pr diff <PR_URL>\n```\n\nNote all changed `.kt` files. Store the output.\n\n### Step 2 — Fetch full file contents\n\nFor each changed `.kt` file, fetch the **complete file** — not just the diff lines.\n\n```bash\n# Get PR metadata\ngh pr view <PR_URL> --json headRefName,headRepository \\\n  --jq '{branch: .headRefName, repo: .headRepository.nameWithOwner}'\n\n# Fetch full file (replace {owner}, {repo}, {path}, {branch})\ngh api \"repos/{owner}/{repo}/contents/{path}?ref={branch}\" \\\n  --jq '.content' | base64 -d\n```\n\n**Why full files matter:** The diff shows what changed. The full file shows what the composable\nactually looks like — including whether a `modifier` parameter exists at all, and how modifier\nchains are structured across multiple lines. Single-line modifier patterns like\n`Row(modifier = Modifier.fillMaxWidth().padding(16.dp)) {` are invisible in a diff-only view\nwhen that line itself was not modified.\n\n### Step 3 — Scan project settings\n\nRun in priority order. Always run step d regardless of what lint config is found.\n\n**a. `.editorconfig`:**\n```bash\ncat .editorconfig 2>/dev/null || echo \"not found\"\n```\nNote: indent size, max line length, trailing comma rules under `[*.kt]`.\n\n**b. ktlint config:**\n```bash\ngrep -A 20 \"\\[\\*\\.kt\\]\" .editorconfig 2>/dev/null\ncat .ktlint 2>/dev/null || echo \"not found\"\n```\n\n**c. detekt:**\n```bash\nfind . -name \"detekt.yml\" -o -name \"detekt-config.yml\" 2>/dev/null | head -3\n```\nIf found, read it and note complexity, naming, and style rules.\n\n**d. Infer codebase conventions (always run):**\n```bash\n# Find 3–5 existing composable files NOT in the diff\nfind . -name \"*.kt\" -not -path \"*/build/*\" | xargs grep -l \"@Composable\" | \\\n  grep -v \"Test\" | head -5\n```\nFor each file, note:\n- Modifier chaining: one per line vs. inline on constructor line\n- Modifier parameter name: `modifier` vs `Modifier` (both are valid — note which team uses)\n- Trailing lambda vs. named `content =` on single-slot composables\n- Named parameter usage on single-arg calls\n\nBuild a **project profile**. Use it to suppress false positives — flag deviations from the\nteam's own conventions, not deviations from an external style guide.\n\n### Step 4 — Run the checklist\n\nEvaluate every changed composable against all 6 categories below.\nUse the **full file** from Step 2, not the diff from Step 1.\n\n### Step 5 — Output the report\n\nUse the format at the end of this document.\n\n---\n\n## Compose Review Checklist\n\n### Category 1: Modifier Hygiene\n\nScan the full file for each changed `@Composable` function.\n\n- [ ] **Modifier parameter present.** Every `@Composable` function that renders UI must have\n  a `modifier: Modifier = Modifier` parameter. Flag if absent.\n  Exception: private composables used only as internal implementation detail with no layout impact.\n\n- [ ] **Modifier passed to root element.** The `modifier` parameter must be applied to the\n  outermost layout composable in the function body — not ignored, not applied to an inner element,\n  not used on a sibling.\n\n- [ ] **Modifier not duplicated.** `modifier` must not be split across two sibling elements.\n  One root element receives it.\n\n- [ ] **Modifier ordering follows the paint model.** Work outward-in:\n  `size / fillMaxWidth` → `padding` → `background / border` → `clickable / pointerInput`.\n  Flag these specific reversals:\n  - `background()` before `padding()` when the intent is background-wraps-content\n    (`Modifier.padding(16.dp).background(Color.Red)` = background wraps the padding area;\n    `Modifier.background(Color.Red).padding(16.dp)` = background does NOT include the padding area)\n  - `clickable()` before `padding()` — shrinks the effective touch target\n  - `size()` or `fillMaxWidth()` after `padding()` — the size constraint no longer includes the padding\n\n- [ ] **Single-line modifier check.** Read the full constructor line even when unchanged in the diff.\n  Verify ordering is correct even when the entire modifier chain is written inline:\n  `Row(modifier = Modifier.fillMaxWidth().clickable { }.padding(16.dp))` — this has wrong ordering\n  (`clickable` before `padding` shrinks touch target).\n\n- [ ] **No `padding` + `offset` for the same adjustment.** `offset` does not affect layout;\n  `padding` does. They are not interchangeable.\n\n### Category 2: Recomposition\n\n- [ ] **No unstable parameter types** without stability annotations:\n  - Plain `List<T>` — compiler infers as unstable. Use `@Immutable` data class wrapper,\n    `ImmutableList<T>` (kotlinx-collections-immutable), or annotate the call site\n  - `HashMap`, `MutableMap`, any mutable collection — not stable\n  - Non-`data` class without `@Stable` — compiler cannot infer stability\n\n- [ ] **Lambdas not created inline without `remember`.** A new lambda instance on every\n  recomposition of the parent prevents the child from being skipped.\n  ```kotlin\n  // BAD — new lambda every parent recomposition\n  MyComposable(onClick = { doSomething() })\n\n  // OK — stable reference\n  val onClick = remember { { doSomething() } }\n  MyComposable(onClick = onClick)\n  ```\n  Exception: if strong skipping mode is enabled in the Compose compiler (`freeCompilerArgs +=\n  \"-P\", \"plugin:androidx.compose.compiler.plugins.kotlin:experimentalStrongSkipping=true\"`),\n  lambdas are stable by default.\n\n- [ ] **`derivedStateOf {}` used for computed values.** Flag values computed from state reads\n  inside a composable body without `remember { derivedStateOf { ... } }`:\n  ```kotlin\n  // BAD — recomputes and recomposes every time any state changes\n  val isValid = username.isNotEmpty() && password.length > 8\n\n  // OK\n  val isValid by remember { derivedStateOf { username.isNotEmpty() && password.length > 8 } }\n  ```\n\n- [ ] **`remember {}` keys are correct.**\n  - Missing keys but referencing an input variable inside — stale value bug\n  - Key that never changes (`remember(Unit)` or `remember(constant)`) — effectively `remember {}` with no recalculation\n\n### Category 3: M3 Motion\n\nCross-reference with `references/material3-motion.md` for token values and easing names.\n\n- [ ] **No hardcoded integer durations** in `tween()`, `spring()`, or `keyframes {}`. Flag any\n  `tween(N)` where N is a plain integer literal. Suggest nearest `MotionTokens.Duration*` token.\n\n- [ ] **No pre-M3 easing constants:**\n  - `FastOutSlowInEasing` → `MotionTokens.EasingEmphasizedCubicBezier`\n  - `LinearOutSlowInEasing` → `MotionTokens.EasingEmphasizedDecelerateCubicBezier`\n  - `FastOutLinearInEasing` → `MotionTokens.EasingEmphasizedAccelerateCubicBezier`\n\n- [ ] **`animateColorAsState` has an `animationSpec`.** No-spec `animateColorAsState(target)`\n  uses the default spring which is inappropriate for color transitions.\n  Suggest: `animationSpec = MaterialTheme.motionScheme.defaultEffectsSpec()`\n\n- [ ] **`AnimatedVisibility` enter/exit easing is asymmetric.** Enter must use Decelerate easing;\n  exit must use Accelerate easing. Same easing for both is incorrect.\n\n- [ ] **No non-shared-element animation > 600ms.** Flag durations above `DurationLong4` (600ms)\n  unless the animation is a shared element or full-screen transition.\n\n- [ ] **New components use `MotionScheme` not raw `tween()`.** A new component accepting no\n  `AnimationSpec` parameter should use `MaterialTheme.motionScheme.defaultSpatialSpec()` /\n  `defaultEffectsSpec()` to be theme-motion-aware.\n\n### Category 4: CMP Compatibility\n\nApply only to files whose path contains `commonMain` or has no platform-specific path segment.\n\n- [ ] No `android.*` imports (`android.content.Context`, `android.util.Log`, etc.)\n- [ ] No `androidx.*` imports that are Android-only. Check `references/multiplatform.md`\n  API availability matrix for what is available in `commonMain`.\n- [ ] No `LocalContext.current` — not available in CMP `commonMain`\n- [ ] No `Activity`, `Context`, or `Application` references\n- [ ] Resources via `Res.drawable.*` / `Res.string.*` — not `R.drawable.*` / `R.string.*`\n\n### Category 5: Lists & Keys\n\n- [ ] **Every `items()` call has a `key = {}`** in `LazyColumn`, `LazyRow`, `LazyVerticalGrid`,\n  `LazyHorizontalGrid`. Missing keys cause incorrect animations and item reuse bugs.\n  ```kotlin\n  // BAD\n  items(movies) { movie -> MovieCard(movie) }\n\n  // OK\n  items(movies, key = { it.id }) { movie -> MovieCard(movie) }\n  ```\n\n- [ ] **`contentType = {}` present for heterogeneous lists.** When a lazy list renders more than\n  one type of composable (e.g., headers + items), `contentType` must be specified so Compose\n  reuses composition nodes correctly.\n\n- [ ] **No `LazyColumn` directly nested inside `LazyColumn`** without a fixed height on the inner\n  one. Unbounded nested lazy lists throw `java.lang.IllegalStateException` at runtime.\n\n- [ ] **`TvLazyRow` / `TvLazyColumn` / `TvLazyVerticalGrid` / `TvLazyHorizontalGrid` from\n  `tv-foundation` flagged as deprecated.** Replace with standard Foundation equivalents.\n  See migration table in `references/tv-compose.md` Section 5.\n\n### Category 6: Atomic Design\n\nCross-reference with `references/atomic-design.md` for token patterns and naming rules.\n\n- [ ] **No hardcoded `Color(0xFF...)` inside composable bodies.** Colors must come from\n  `MaterialTheme.colorScheme.*` or an app-level brand token (`CompositionLocal`).\n  Exception: `Color.Transparent`, `Color.Unspecified`, and `Color.White`/`Color.Black` as\n  explicit design choices are acceptable.\n\n- [ ] **No hardcoded `fontSize`, `fontWeight`, or `TextStyle(...)`.** Typography must come from\n  `MaterialTheme.typography.*`. Flag any inline `TextStyle(fontSize = 14.sp)` or\n  `fontWeight = FontWeight.Bold` outside of a theme definition file.\n\n- [ ] **No magic number spacing (`16.dp`) without token.** If the project defines a spacing\n  scale (check for `CompositionLocal` with spacing values), flag raw `dp` values that should\n  use the scale. If no spacing scale exists, note it as a suggestion — not a critical issue.\n\n- [ ] **Composable names describe function, not context.** Flag composables matching these\n  patterns: `*For*` (e.g., `ButtonForSettings`), `*With*` (e.g., `CardWithRedBorder`),\n  `*In*` (e.g., `HeaderInHome`). Exception: `*WithDefaults` pattern used for providing\n  default parameters is acceptable.\n\n- [ ] **Public composables have `modifier: Modifier = Modifier`.** (Overlaps Category 1 — in\n  atomic context, additionally verify the modifier is passed to the root element and not\n  consumed by an inner element.)\n\n- [ ] **Composables rendering variable content have slot APIs.** Flag composables that hardcode\n  `Text(\"Submit\")`, `Icon(Icons.Default.Close, ...)`, or similar fixed content that should\n  be a slot parameter. Exception: internal/private composables with fixed content by design.\n\n- [ ] **Organisms do not directly reference ViewModel.** Any composable that combines multiple\n  UI components (organism-level) must accept data and callbacks as parameters. Flag direct\n  `viewModel()`, `hiltViewModel()`, or `koinViewModel()` calls inside organisms.\n  The screen-level composable is the correct place for ViewModel access.\n\n---\n\n## Output Report Format\n\n```\n## PR Review: <PR title> (#NNN)\nBranch: <head-branch> → <base-branch>\n\n### Project Profile\n- Code style: <inferred — e.g. \"modifier chains one per line\", \"trailing lambdas preferred\">\n- Lint config: <ktlint / detekt / neither found>\n- Conventions from: <files sampled>\n\n---\n\n### Issues\n\n#### Critical\nIssues that cause bugs, crashes, or correctness problems.\n\n- `path/File.kt:42` — `MyCard` is missing `modifier: Modifier = Modifier` parameter. All UI\n  composables must expose a modifier for caller layout control.\n  Fix: add `modifier: Modifier = Modifier` to the signature; pass to the root element.\n\n#### Suggestions\nStyle, M3 alignment, and performance improvements.\n\n- `path/File.kt:87` — `tween(300)` → `MotionTokens.DurationMedium2.toInt()` (300ms = Medium2)\n- `path/File.kt:103` — `FastOutSlowInEasing` → `MotionTokens.EasingEmphasizedCubicBezier`\n- `path/File.kt:115` — `items(movies)` missing `key = { it.id }` — add key to prevent reorder bugs\n\n#### Positive Patterns\nGood Compose usage — always include at least one.\n\n- `path/File.kt:55` — Correct `derivedStateOf {}` preventing redundant recompositions\n- `path/File.kt:71` — `sharedBounds()` used correctly for container-to-page expansion\n\n---\n\n### Summary\n<N> critical, <M> suggestions across <K> files reviewed.\n```\n\n**Sections policy:**\n- Critical and Suggestions are always present (write \"None found\" if empty)\n- Positive Patterns is always present — reviews must not read as a pure hit list\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/production-crash-playbook.md",
    "content": "# Production Crash Playbook for Jetpack Compose\n\nReal-world crash patterns observed in Compose applications at scale. Each section documents the root cause, the failing pattern, the fix, and the rule to prevent recurrence.\n\n---\n\n## 1. remember {} Without Configuration-Derived Key\n\n### Root Cause\n\n`remember {}` without keys caches the initial computation and never recalculates. When the remembered value derives from configuration state (screen dimensions, font scale, density), a configuration change (rotation, foldable posture, window resize) leaves the cached value stale.\n\n### Crash Pattern\n\n```kotlin\n// BAD: shimmerCount is cached from initial screenHeightDp, stale after rotation\n@Composable\nfun ShimmerList() {\n    val config = LocalConfiguration.current\n    val screenHeightDp = config.screenHeightDp\n    val itemHeightDp = 80\n\n    val shimmerCount = remember { (screenHeightDp / itemHeightDp).toInt() }\n\n    LazyColumn {\n        items(shimmerCount) { ShimmerItem() }\n    }\n}\n```\n\nAfter rotation, `screenHeightDp` changes but `shimmerCount` still holds the portrait value. The list renders the wrong number of shimmer placeholders. In extreme cases (foldable unfolding), the stale count causes layout overflow or zero items.\n\n### Fix\n\n```kotlin\n// GOOD: screenHeightDp is a key, so remember recalculates on config change\n@Composable\nfun ShimmerList() {\n    val config = LocalConfiguration.current\n    val screenHeightDp = config.screenHeightDp\n    val itemHeightDp = 80\n\n    val shimmerCount = remember(screenHeightDp) {\n        (screenHeightDp / itemHeightDp).toInt().coerceAtLeast(1)\n    }\n\n    LazyColumn {\n        items(shimmerCount) { ShimmerItem() }\n    }\n}\n```\n\n**Rule:** Any value derived from `LocalConfiguration`, `LocalDensity`, or `LocalLayoutDirection` MUST include that configuration source in `remember`'s key parameters. Audit all `remember {}` calls that reference `screenHeightDp`, `screenWidthDp`, `fontScale`, or `densityDpi`.\n\n---\n\n## 2. indexOf() Inside items {}\n\n### Root Cause\n\nUsing `list.indexOf(item)` inside a LazyColumn's `items {}` block is O(n) per item, making the overall list O(n^2). Worse, `indexOf` uses structural equality (`equals`). If the list contains recreated objects (new instances from a network response mapped to data classes), `indexOf` may return `-1`, which when passed as an index triggers `IndexOutOfBoundsException`.\n\n### Crash Pattern\n\n```kotlin\n// BAD: O(n^2) and crashes when indexOf returns -1\n@Composable\nfun MessageList(messages: List<Message>) {\n    LazyColumn {\n        items(messages) { message ->\n            val index = messages.indexOf(message)  // O(n) per item\n            MessageRow(\n                message = message,\n                isEven = index % 2 == 0  // -1 % 2 == -1, not a crash here\n            )\n        }\n    }\n}\n\n// Worse: using indexOf result as a direct index\nitems(messages) { message ->\n    val index = messages.indexOf(message)\n    val nextMessage = messages[index + 1]  // IndexOutOfBoundsException\n}\n```\n\n### Fix\n\n```kotlin\n// GOOD: Use itemsIndexed to get the index directly\n@Composable\nfun MessageList(messages: List<Message>) {\n    LazyColumn {\n        itemsIndexed(\n            items = messages,\n            key = { _, message -> message.id }\n        ) { index, message ->\n            MessageRow(\n                message = message,\n                isEven = index % 2 == 0\n            )\n        }\n    }\n}\n```\n\nIf you need `items` with a key but also need the index, use `items` with `key` and derive the index from the item itself if possible, or switch to `itemsIndexed`.\n\n**Rule:** Never call `indexOf()`, `lastIndexOf()`, or `indexOfFirst {}` inside a `LazyListScope` item factory. Use `itemsIndexed` for index access. Use `items(key = { ... })` for stable identity.\n\n---\n\n## 3. DrawScope Without Zero-Size Guard\n\n### Root Cause\n\nDuring initial composition, a `Canvas` composable may receive a `Size.Zero` (or `Size.Unspecified`) before layout completes, especially when using `fillMaxSize()` inside a parent that hasn't been measured yet. Dividing by zero-dimension values or computing radii from `size.minDimension` when it's zero produces `NaN` or `Infinity`, which crashes the Skia rendering pipeline.\n\n### Crash Pattern\n\n```kotlin\n// BAD: size.minDimension is 0 during initial composition\nCanvas(modifier = Modifier.fillMaxSize()) {\n    val radius = size.minDimension / 2\n    drawCircle(color = Color.Blue, radius = radius)\n}\n```\n\nOn certain devices or inside `SubcomposeLayout`, the first draw call fires with `size = Size(0, 0)`. The `drawCircle` call with `radius = 0f` may not crash, but derived math like `360f / size.width` produces `Infinity` and corrupts the draw path.\n\n### Fix\n\n```kotlin\n// GOOD: guard against zero size, and give Canvas an explicit size\nCanvas(\n    modifier = Modifier\n        .fillMaxWidth()\n        .height(200.dp)\n) {\n    if (size.minDimension <= 0f) return@Canvas\n    val radius = size.minDimension / 2\n    drawCircle(color = Color.Blue, radius = radius)\n}\n```\n\nFor dynamic sizing, use `Modifier.aspectRatio()` or `BoxWithConstraints` to guarantee non-zero dimensions before drawing:\n\n```kotlin\nBoxWithConstraints(modifier = Modifier.fillMaxWidth()) {\n    if (maxWidth > 0.dp && maxHeight > 0.dp) {\n        Canvas(modifier = Modifier.size(maxWidth, maxWidth)) {\n            val radius = size.minDimension / 2\n            drawCircle(color = Color.Blue, radius = radius)\n        }\n    }\n}\n```\n\n**Rule:** Always guard `DrawScope` blocks against zero-size conditions. Never use `fillMaxSize()` on `Canvas` without an explicit height constraint. Prefer `Modifier.size()`, `Modifier.height()`, or `Modifier.aspectRatio()` so Canvas always enters draw with known dimensions.\n\n---\n\n## 4. Duplicate LazyColumn Keys\n\n### Root Cause\n\n`LazyColumn` requires unique keys across all items. When the backend sends items without unique IDs, or when a WebSocket reconnection delivers duplicate messages before deduplication, duplicate keys cause `IllegalArgumentException: Key ... was already used`.\n\n### Crash Pattern\n\n```kotlin\n// BAD: backend sends duplicate IDs after WebSocket reconnect\ndata class Notification(val id: String, val text: String)\n\nLazyColumn {\n    items(\n        items = notifications,\n        key = { it.id }  // Crashes if two items share the same id\n    ) { notification ->\n        NotificationRow(notification)\n    }\n}\n```\n\n### Fix: Dedup Index Pattern\n\nAdd a `dedupIndex` field that is excluded from `equals`/`hashCode` but included in the key. This handles duplicates gracefully without losing data:\n\n```kotlin\ndata class Notification(\n    val id: String,\n    val text: String,\n    val timestamp: Long\n) {\n    // dedupIndex is NOT in the primary constructor, excluded from equals/hashCode\n    var dedupIndex: Int = 0\n}\n\nfun List<Notification>.withDedupIndex(): List<Notification> {\n    val seen = mutableMapOf<String, Int>()\n    return map { item ->\n        val count = seen.getOrDefault(item.id, 0)\n        seen[item.id] = count + 1\n        item.also { it.dedupIndex = count }\n    }\n}\n\n@Composable\nfun NotificationList(notifications: List<Notification>) {\n    val deduped = remember(notifications) { notifications.withDedupIndex() }\n\n    LazyColumn {\n        items(\n            items = deduped,\n            key = { \"${it.id}_${it.dedupIndex}\" }  // Guaranteed unique\n        ) { notification ->\n            NotificationRow(notification)\n        }\n    }\n}\n```\n\nAn alternative defensive approach using `distinctBy` when true duplicates should be dropped:\n\n```kotlin\nval uniqueNotifications = remember(notifications) {\n    notifications.distinctBy { it.id }\n}\n```\n\n**Rule:** Never trust backend data to provide unique keys. Either deduplicate with `distinctBy` or use the dedup-index pattern to make keys unique. Wrap key construction in a function that can be unit-tested.\n\n---\n\n## 5. derivedStateOf Driving Collection Size\n\n### Root Cause\n\n`derivedStateOf` recalculates lazily when its inputs change, but the recomposition that reads the derived value and the recomposition that reads the source collection may occur in different frames. When `derivedStateOf` exposes only a count, the `items(count)` call may use a stale count that is out of sync with the actual collection, causing `IndexOutOfBoundsException`.\n\n### Crash Pattern\n\n```kotlin\n// BAD: derive only the count; items {} reads allItems directly with stale count\n@Composable\nfun FilteredList(allItems: List<Item>, filter: String) {\n    val itemCount by remember {\n        derivedStateOf { allItems.count { it.name.contains(filter) } }\n    }\n\n    LazyColumn {\n        items(itemCount) { index ->\n            val item = allItems.filter { it.name.contains(filter) }[index]\n            // itemCount may be stale relative to allItems, IOOB crash\n            ItemRow(item)\n        }\n    }\n}\n```\n\n### Fix\n\n```kotlin\n// GOOD: derive the full filtered list; count and access are always consistent\n@Composable\nfun FilteredList(allItems: List<Item>, filter: String) {\n    val filteredItems by remember {\n        derivedStateOf { allItems.filter { it.name.contains(filter) } }\n    }\n\n    LazyColumn {\n        items(\n            items = filteredItems,\n            key = { it.id }\n        ) { item ->\n            ItemRow(item)\n        }\n    }\n}\n```\n\n**Rule:** `derivedStateOf` is appropriate for scroll direction, visibility thresholds, and validation states -- values that don't drive collection iteration. Never use `derivedStateOf` to expose a count or index that a `LazyList` will use to access a separate collection.\n\n---\n\n## 6. collectAsState vs collectAsStateWithLifecycle\n\n### Root Cause\n\n`collectAsState()` subscribes to a `Flow` and keeps collecting even when the app is in the background. This causes unnecessary work (network calls, database queries, sensor reads), battery drain, and stale state that flashes briefly when the user returns to the app.\n\n### The Difference\n\n```kotlin\n// BAD: continues collecting in background\n@Composable\nfun ProfileScreen(viewModel: ProfileViewModel) {\n    val state by viewModel.uiState.collectAsState()\n    ProfileContent(state)\n}\n\n// GOOD: stops collecting when lifecycle drops below STARTED\n@Composable\nfun ProfileScreen(viewModel: ProfileViewModel) {\n    val state by viewModel.uiState.collectAsStateWithLifecycle()\n    ProfileContent(state)\n}\n```\n\n`collectAsStateWithLifecycle` is part of `androidx.lifecycle:lifecycle-runtime-compose`. It automatically cancels collection when the `Lifecycle` drops below a configurable state (default: `Lifecycle.State.STARTED`).\n\n### Custom Lifecycle Minimum\n\n```kotlin\n// Collect only when RESUMED (stricter, for camera/location flows)\nval locationState by locationFlow.collectAsStateWithLifecycle(\n    minActiveState = Lifecycle.State.RESUMED\n)\n```\n\n### Compose Multiplatform Consideration\n\n`collectAsStateWithLifecycle` is Android-only because it depends on `androidx.lifecycle`. In Compose Multiplatform (CMP) projects, use `collectAsState()` on non-Android targets and `collectAsStateWithLifecycle()` on Android via an `expect`/`actual` pattern:\n\n```kotlin\n// commonMain\n@Composable\nexpect fun <T> Flow<T>.collectAsStateMultiplatform(\n    initial: T\n): State<T>\n\n// androidMain\n@Composable\nactual fun <T> Flow<T>.collectAsStateMultiplatform(\n    initial: T\n): State<T> = collectAsStateWithLifecycle(initialValue = initial)\n\n// iosMain / desktopMain / wasmJsMain\n@Composable\nactual fun <T> Flow<T>.collectAsStateMultiplatform(\n    initial: T\n): State<T> = collectAsState(initial = initial)\n```\n\n**Rule:** On Android, always use `collectAsStateWithLifecycle` for `StateFlow` and `SharedFlow`. Reserve `collectAsState` for Compose Multiplatform common code or non-lifecycle-aware contexts only.\n\n---\n\n## 7. SafeShimmerItem Pattern\n\n### Root Cause\n\nShimmer placeholders rendered via `SubcomposeLayout` can crash when the parent layout has zero size (see Section 3) or when the shimmer animation's `DrawScope` receives unexpected dimensions. A defensive wrapper prevents crashes while maintaining the shimmer UX.\n\n### Full Implementation\n\n```kotlin\n@Composable\nfun SafeShimmerItem(\n    modifier: Modifier = Modifier,\n    itemHeight: Dp = 80.dp,\n    shimmerColor: Color = Color.LightGray.copy(alpha = 0.6f),\n    highlightColor: Color = Color.LightGray.copy(alpha = 0.2f),\n) {\n    val transition = rememberInfiniteTransition(label = \"shimmer\")\n    val translateAnim by transition.animateFloat(\n        initialValue = 0f,\n        targetValue = 1000f,\n        animationSpec = infiniteRepeatable(\n            animation = tween(durationMillis = 1200, easing = LinearEasing),\n            repeatMode = RepeatMode.Restart\n        ),\n        label = \"shimmer_translate\"\n    )\n\n    val brush = Brush.linearGradient(\n        colors = listOf(shimmerColor, highlightColor, shimmerColor),\n        start = Offset(translateAnim - 500f, 0f),\n        end = Offset(translateAnim, 0f)\n    )\n\n    Box(\n        modifier = modifier\n            .fillMaxWidth()\n            .height(itemHeight)\n            .clip(RoundedCornerShape(8.dp))\n    ) {\n        val result = runCatching {\n            Canvas(modifier = Modifier.matchParentSize()) {\n                if (size.minDimension <= 0f) return@Canvas\n                drawRect(brush = brush)\n            }\n        }\n        if (result.isFailure) {\n            // Fallback: solid color placeholder when Canvas fails\n            Box(\n                modifier = Modifier\n                    .matchParentSize()\n                    .background(shimmerColor, RoundedCornerShape(8.dp))\n            )\n        }\n    }\n}\n```\n\n### Usage with Configuration-Aware Count\n\n```kotlin\n@Composable\nfun ShimmerLoadingList() {\n    val config = LocalConfiguration.current\n    val itemHeight = 80.dp\n    val shimmerCount = remember(config.screenHeightDp) {\n        (config.screenHeightDp / itemHeight.value).toInt().coerceAtLeast(1)\n    }\n\n    LazyColumn {\n        items(shimmerCount) {\n            SafeShimmerItem(itemHeight = itemHeight)\n        }\n    }\n}\n```\n\n**Rule:** Wrap all shimmer and placeholder drawing in `runCatching` or explicit size guards. Provide a solid-color fallback so the loading state is never invisible and never crashes.\n\n---\n\n## 8. Multi-Field Keys with Collision Prefixes\n\n### Root Cause\n\nWhen a `LazyColumn` displays items from multiple categories (live, archived, pinned), using the raw ID as the key causes collisions when the same underlying entity appears in multiple sections. For example, a message with `id = 42` could appear in both \"pinned\" and \"live\" sections.\n\n### Crash Pattern\n\n```kotlin\n// BAD: same message ID in pinned and live sections causes key collision\nLazyColumn {\n    items(pinnedMessages, key = { it.id }) { message ->\n        PinnedMessageRow(message)\n    }\n    items(liveMessages, key = { it.id }) { message ->\n        LiveMessageRow(message)\n    }\n}\n// IllegalArgumentException: Key 42 was already used\n```\n\n### Fix: Type-Prefixed Keys\n\n```kotlin\n// GOOD: prefix keys with section type to avoid collisions\nLazyColumn {\n    items(\n        items = pinnedMessages,\n        key = { \"pinned_${it.id}\" }\n    ) { message ->\n        PinnedMessageRow(message)\n    }\n    items(\n        items = liveMessages,\n        key = { \"live_${it.id}\" }\n    ) { message ->\n        LiveMessageRow(message)\n    }\n    items(\n        items = archivedMessages,\n        key = { \"archived_${it.id}\" }\n    ) { message ->\n        ArchivedMessageRow(message)\n    }\n}\n```\n\n### Sealed Class Alternative\n\nFor type safety, use a sealed class for keys:\n\n```kotlin\nsealed class ListKey {\n    data class Pinned(val id: Long) : ListKey()\n    data class Live(val id: Long) : ListKey()\n    data class Archived(val id: Long) : ListKey()\n}\n\nLazyColumn {\n    items(pinnedMessages, key = { ListKey.Pinned(it.id) }) { ... }\n    items(liveMessages, key = { ListKey.Live(it.id) }) { ... }\n    items(archivedMessages, key = { ListKey.Archived(it.id) }) { ... }\n}\n```\n\n**Rule:** When mixing item types in a single `LazyList`, always prefix or wrap keys with the item type. Use string prefixes for simplicity or sealed classes for compile-time safety.\n\n---\n\n## 9. Production State Rules\n\nThese rules prevent the most common state-related crashes and architectural mistakes in production Compose applications.\n\n### Rule 1: mutableStateOf ONLY in Composables, Never in ViewModels\n\n```kotlin\n// BAD: Compose state in ViewModel couples VM to Compose runtime\nclass ProfileViewModel : ViewModel() {\n    var name by mutableStateOf(\"\")  // Don't do this\n}\n\n// GOOD: Use coroutine-native state in ViewModel\nclass ProfileViewModel : ViewModel() {\n    private val _name = MutableStateFlow(\"\")\n    val name: StateFlow<String> = _name.asStateFlow()\n}\n```\n\nViewModels should expose `StateFlow` (via `MutableStateFlow` + `asStateFlow()`). Compose state (`mutableStateOf`) belongs in `@Composable` functions and state holder classes annotated with `@Stable`. This keeps ViewModels testable without the Compose runtime.\n\n### Rule 2: SharedFlow for Events, Not Channel\n\n```kotlin\n// BAD: Channel drops events when no collector is active\nclass OrderViewModel : ViewModel() {\n    private val _events = Channel<UiEvent>()\n    val events = _events.receiveAsFlow()\n}\n\n// GOOD: SharedFlow with buffer handles brief collector gaps\nclass OrderViewModel : ViewModel() {\n    private val _events = MutableSharedFlow<UiEvent>(\n        extraBufferCapacity = 1,\n        onBufferOverflow = BufferOverflow.DROP_OLDEST\n    )\n    val events: SharedFlow<UiEvent> = _events.asSharedFlow()\n}\n```\n\n`Channel` is a hot stream that requires an active collector. During configuration changes or lifecycle transitions, events are silently dropped. `SharedFlow` with `extraBufferCapacity = 1` buffers one event during brief collector gaps.\n\n### Rule 3: rememberSaveable Only at NavGraph Level\n\n```kotlin\n// BAD: rememberSaveable deep in a list item (bloats saved state bundle)\n@Composable\nfun ChatMessageItem(message: Message) {\n    var expanded by rememberSaveable { mutableStateOf(false) }\n    // Saved for every message in the list -- Bundle size explodes\n}\n\n// GOOD: rememberSaveable at screen level, remember inside items\n@Composable\nfun ChatScreen(viewModel: ChatViewModel) {\n    var searchQuery by rememberSaveable { mutableStateOf(\"\") }\n\n    LazyColumn {\n        items(messages, key = { it.id }) { message ->\n            var expanded by remember { mutableStateOf(false) }\n            ChatMessageItem(message, expanded)\n        }\n    }\n}\n```\n\n`rememberSaveable` serializes to the `Bundle`, which has a ~1MB limit on Android. Using it inside list items for per-item state quickly exceeds this limit and causes `TransactionTooLargeException`.\n\n### Rule 4: snapshotFlow + distinctUntilChanged for Reactive Scroll\n\n```kotlin\n// GOOD: efficient reactive scroll position monitoring\n@Composable\nfun ScrollAwareList(listState: LazyListState) {\n    val isScrolledPast = remember {\n        derivedStateOf { listState.firstVisibleItemIndex > 0 }\n    }\n\n    // For side effects based on scroll position\n    LaunchedEffect(listState) {\n        snapshotFlow { listState.firstVisibleItemIndex }\n            .distinctUntilChanged()\n            .collect { index ->\n                // Analytics, FAB visibility, header collapse\n            }\n    }\n}\n```\n\n`snapshotFlow` converts Compose snapshot state to a `Flow`, and `distinctUntilChanged()` prevents redundant emissions. Never poll scroll state in a recomposition-driven loop.\n\n### Rule 5: stateIn() with map() for Derived Flows\n\n```kotlin\n// GOOD: derive UI state from repository flow\nclass DashboardViewModel(repository: DashboardRepository) : ViewModel() {\n    val uiState: StateFlow<DashboardUiState> = repository.dashboardData\n        .map { data ->\n            DashboardUiState(\n                totalSales = data.sales.sumOf { it.amount },\n                topProduct = data.products.maxByOrNull { it.revenue }?.name.orEmpty(),\n                isLoading = false\n            )\n        }\n        .stateIn(\n            scope = viewModelScope,\n            started = SharingStarted.WhileSubscribed(5_000),\n            initialValue = DashboardUiState()\n        )\n}\n```\n\n`SharingStarted.WhileSubscribed(5_000)` keeps the upstream active for 5 seconds after the last subscriber detaches, surviving configuration changes without restarting the flow. Combine with `.map()` for derived transformations instead of creating separate `derivedStateOf` in the UI.\n\n---\n\n## 10. Production Performance Rules\n\n### Rule 1: @Stable on UI State, @Immutable on Data Models\n\n```kotlin\n// Data models from network/database: truly immutable\n@Immutable\ndata class Product(\n    val id: Long,\n    val name: String,\n    val price: Double,\n    val imageUrl: String\n)\n\n// UI state with observable mutations: stable contract\n@Stable\ndata class CartUiState(\n    val items: List<Product> = emptyList(),\n    val total: Double = 0.0,\n    val isLoading: Boolean = false\n)\n```\n\n`@Immutable` tells the compiler all properties will never change after construction. `@Stable` promises that changes will be notified to the Compose runtime. Misuse (e.g., `@Immutable` on a class with `var` properties) causes skipped recompositions and stale UI.\n\n### Rule 2: Canvas Always Explicitly Sized\n\n```kotlin\n// BAD: Canvas with fillMaxSize and no parent constraints\nCanvas(modifier = Modifier.fillMaxSize()) { /* may get zero size */ }\n\n// GOOD: explicit dimensions\nCanvas(modifier = Modifier.size(200.dp)) { ... }\n\n// GOOD: explicit height with flexible width\nCanvas(modifier = Modifier.fillMaxWidth().height(120.dp)) { ... }\n\n// GOOD: aspect ratio\nCanvas(modifier = Modifier.fillMaxWidth().aspectRatio(16f / 9f)) { ... }\n```\n\nSee Section 3 for detailed crash scenarios. Explicit sizing prevents zero-size draw calls.\n\n### Rule 3: ReportDrawnWhen for Startup Signals\n\n```kotlin\n@Composable\nfun HomeScreen(viewModel: HomeViewModel) {\n    val state by viewModel.uiState.collectAsStateWithLifecycle()\n\n    ReportDrawnWhen { state.isContentReady }\n\n    when {\n        state.isLoading -> ShimmerLoadingList()\n        state.isContentReady -> ContentList(state.items)\n    }\n}\n```\n\n`ReportDrawnWhen` signals to the system (and performance monitoring tools) when the screen has meaningful content. This is critical for accurate Time-To-Initial-Display (TTID) and Time-To-Full-Display (TTFD) metrics.\n\n### Rule 4: R8 Strip Previews and Semantics in Release\n\n```kotlin\n// In build.gradle.kts (app module)\nandroid {\n    buildTypes {\n        release {\n            isMinifyEnabled = true\n            isShrinkResources = true\n            proguardFiles(\n                getDefaultProguardFile(\"proguard-android-optimize.txt\"),\n                \"proguard-rules.pro\"\n            )\n        }\n    }\n}\n```\n\nIn `proguard-rules.pro`, R8 automatically strips `@Preview` composables from release builds. For semantics stripping in production (accessibility data you don't need in release), use `Modifier.clearAndSetSemantics {}` selectively rather than blanket removal.\n\n### Rule 5: Pragmatic Collection Stability\n\n```kotlin\n// When a composable receives a List that you know won't mutate:\n@Suppress(\"ComposeUnstableCollections\")\n@Composable\nfun ProductGrid(\n    products: List<Product>,  // Compiler sees List as unstable\n    onProductClick: (Product) -> Unit\n) {\n    LazyVerticalGrid(columns = GridCells.Fixed(2)) {\n        items(products, key = { it.id }) { product ->\n            ProductCard(product, onProductClick)\n        }\n    }\n}\n```\n\nThe Compose compiler treats `List`, `Map`, and `Set` as unstable because they are interfaces that could be backed by mutable implementations. Options to handle this:\n\n1. **`@Suppress(\"ComposeUnstableCollections\")`** -- pragmatic, per-function opt-out\n2. **Wrap in `@Immutable` holder** -- `@Immutable data class ProductList(val items: List<Product>)`\n3. **Use `kotlinx.collections.immutable`** -- `ImmutableList<Product>` is recognized as stable\n4. **Compose compiler stability config file** -- declare stable classes globally\n\nChoose based on team convention. Option 1 is fastest for existing codebases. Option 3 is cleanest for new projects.\n\n---\n\n## Quick Reference: Crash Pattern Checklist\n\n| Pattern | Symptom | Section |\n|---------|---------|---------|\n| `remember {}` without config key | Stale values after rotation | 1 |\n| `indexOf()` in `items {}` | O(n^2), IndexOutOfBoundsException | 2 |\n| Canvas with zero size | NaN/Infinity in draw, Skia crash | 3 |\n| Duplicate LazyColumn keys | IllegalArgumentException | 4 |\n| `derivedStateOf` for collection count | IndexOutOfBoundsException | 5 |\n| `collectAsState` in background | Battery drain, stale flash | 6 |\n| Unguarded shimmer drawing | Crash in SubcomposeLayout | 7 |\n| Key collision across item types | IllegalArgumentException | 8 |\n| `mutableStateOf` in ViewModel | Untestable, lifecycle mismatch | 9 |\n| Canvas with `fillMaxSize()` only | Zero-size draw crash | 10 |\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/side-effects.md",
    "content": "# Jetpack Compose Side Effects Reference\n\nCompose is declarative, but apps must interact with the imperative world: launch coroutines, register listeners, manage resources. Side effects are the bridge. Understanding when and how to use them is essential for correctness.\n\n## The Effect Mental Model\n\nCompose recomposes when state changes. Effects are blocks of code that run outside the normal composition and recomposition cycle:\n\n- **Composition**: Calculate the UI tree\n- **Side effects**: Run imperative code (coroutines, callbacks, lifecycle events)\n- **Layout**: Measure and position elements\n- **Drawing**: Render to screen\n\nEffects run *after* composition succeeds. If composition fails, the effect doesn't run.\n\n```kotlin\n@Composable\nfun MyScreen() {\n    // This runs during composition\n    val state = remember { mutableStateOf(\"initial\") }\n\n    // This runs AFTER composition, and only when 'state.value' changes\n    LaunchedEffect(state.value) {\n        println(\"State changed to: ${state.value}\")\n    }\n\n    // This runs after every composition (use sparingly)\n    SideEffect {\n        println(\"Recomposition happened\")\n    }\n\n    // This runs when composable leaves composition\n    DisposableEffect(Unit) {\n        onDispose {\n            println(\"Composable is leaving composition\")\n        }\n    }\n\n    Button(onClick = { state.value = \"updated\" }) {\n        Text(state.value)\n    }\n}\n```\n\n## SideEffect — After Every Successful Composition\n\n`SideEffect` runs after *every* successful composition. It has no cleanup, no keys, and always executes.\n\n```kotlin\n@Composable\nfun MyComposable() {\n    var clickCount by remember { mutableStateOf(0) }\n\n    // Runs after every recomposition\n    SideEffect {\n        println(\"Recomposed! Click count: $clickCount\")\n    }\n\n    Button(onClick = { clickCount++ }) {\n        Text(\"Clicks: $clickCount\")\n    }\n}\n```\n\n### Use Cases\n\n- Synchronizing Compose state with external systems (e.g., Analytics logging)\n- Updating non-Compose UI elements\n- One-way synchronization where cleanup isn't needed\n\n```kotlin\n@Composable\nfun TrackScreenView(screenName: String) {\n    SideEffect {\n        Analytics.logScreenView(screenName)\n    }\n}\n```\n\n**Do:** Use for simple, stateless synchronization.\n**Don't:** Use for resource allocation (use `DisposableEffect` instead).\n\nSource: `compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt`\n\n## LaunchedEffect(key) — Coroutines Scoped to Composition\n\n`LaunchedEffect` launches a coroutine in a scope tied to the composable's lifecycle. The coroutine is cancelled if the key changes or the composable leaves composition.\n\n```kotlin\n@Composable\nfun DataLoader(userId: String) {\n    var data by remember { mutableStateOf<String?>(null) }\n\n    // Coroutine runs when userId changes or composable enters composition\n    LaunchedEffect(userId) {\n        data = loadData(userId)  // suspend function\n    }\n\n    Text(data ?: \"Loading...\")\n}\n```\n\n### Key Selection\n\n```kotlin\n// Key = Unit: runs once when composable enters composition, never cancels/restarts\nLaunchedEffect(Unit) {\n    setupOnce()\n}\n\n// Key = specific value: reruns whenever the value changes\nvar userId by remember { mutableStateOf(\"user1\") }\nLaunchedEffect(userId) {\n    loadUserData(userId)  // reruns when userId changes\n}\n\n// Multiple keys: reruns if ANY key changes\nLaunchedEffect(userId, postId) {\n    loadUserAndPost(userId, postId)\n}\n\n// No key parameter (not recommended): equivalent to Unit\nLaunchedEffect {\n    setupOnce()\n}\n```\n\n### Common Mistake: Wrong Key Selection\n\n```kotlin\n// Don't: Key changes every recomposition (creates infinite loop)\n@Composable\nfun BadKeySelection() {\n    var count by remember { mutableStateOf(0) }\n    val randomKey = Random.nextInt()  // Changes every recomposition!\n\n    LaunchedEffect(randomKey) {\n        count++  // This launches infinitely\n    }\n\n    Text(\"Count: $count\")\n}\n\n// Do: Use stable keys that represent the data you depend on\n@Composable\nfun GoodKeySelection(userId: String) {\n    var userData by remember { mutableStateOf<User?>(null) }\n\n    LaunchedEffect(userId) {\n        userData = fetchUser(userId)\n    }\n\n    Text(userData?.name ?: \"Loading...\")\n}\n```\n\n### Cancellation Behavior\n\n```kotlin\n@Composable\nfun ResourceUser(shouldLoad: Boolean) {\n    LaunchedEffect(shouldLoad) {\n        if (shouldLoad) {\n            val resource = acquireResource()\n            try {\n                delay(5000)  // Long operation\n                processResource(resource)\n            } finally {\n                resource.close()  // Runs even if cancelled\n            }\n        }\n    }\n}\n\n// If shouldLoad becomes false, the LaunchedEffect coroutine is cancelled.\n// The finally block ensures cleanup.\n```\n\n## DisposableEffect(key) — For Cleanup\n\n`DisposableEffect` runs after composition and requires a cleanup function (onDispose). Use for listeners, registrations, and resources.\n\n```kotlin\n@Composable\nfun LocationListener(context: Context) {\n    DisposableEffect(context) {\n        val listener = LocationListener { location ->\n            println(\"Location: $location\")\n        }\n        // Register listener\n        locationManager.requestLocationUpdates(\n            LocationManager.GPS_PROVIDER,\n            0,\n            0f,\n            listener\n        )\n\n        // Cleanup: unregister listener\n        onDispose {\n            locationManager.removeUpdates(listener)\n        }\n    }\n}\n```\n\n### Common Pattern: Lifecycle Events\n\n```kotlin\n@Composable\nfun ScreenWithLifecycle() {\n    val lifecycle = LocalLifecycleOwner.current.lifecycle\n\n    DisposableEffect(lifecycle) {\n        val observer = LifecycleEventObserver { _, event ->\n            when (event) {\n                Lifecycle.Event.ON_RESUME -> println(\"Screen resumed\")\n                Lifecycle.Event.ON_PAUSE -> println(\"Screen paused\")\n                else -> {}\n            }\n        }\n        lifecycle.addObserver(observer)\n\n        onDispose {\n            lifecycle.removeObserver(observer)\n        }\n    }\n}\n```\n\n**Do:** Use `DisposableEffect` for every resource you allocate.\n**Don't:** Forget the `onDispose` block (resource leaks result).\n\nSource: `compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt`\n\n## rememberCoroutineScope — Launching from Event Handlers\n\n`rememberCoroutineScope` provides a coroutine scope tied to the composable. Use it to launch coroutines from event handlers (clicks, gestures).\n\n```kotlin\n@Composable\nfun ButtonWithAsync() {\n    val scope = rememberCoroutineScope()\n    var result by remember { mutableStateOf(\"\") }\n\n    Button(\n        onClick = {\n            // Launch coroutine from click handler\n            scope.launch {\n                result = fetchData()\n            }\n        }\n    ) {\n        Text(\"Fetch\")\n    }\n\n    Text(result)\n}\n```\n\n### Do vs Don't\n\n```kotlin\n// Don't: regular function scope doesn't work\n@Composable\nfun BadAsync() {\n    var result by remember { mutableStateOf(\"\") }\n\n    Button(\n        onClick = {\n            runBlocking {  // Blocks UI thread!\n                result = fetchData()\n            }\n        }\n    ) {\n        Text(\"Fetch\")\n    }\n}\n\n// Do: use rememberCoroutineScope\n@Composable\nfun GoodAsync() {\n    val scope = rememberCoroutineScope()\n    var result by remember { mutableStateOf(\"\") }\n\n    Button(\n        onClick = {\n            scope.launch {\n                result = fetchData()\n            }\n        }\n    ) {\n        Text(\"Fetch\")\n    }\n}\n```\n\n## rememberUpdatedState — Capturing Latest Values\n\nLong-running effects need the latest value of frequently-changing state, but you don't want to restart the effect on every change.\n\n```kotlin\n// Don't: effect restarts when callback changes\n@Composable\nfun BadCallback(onSuccess: (String) -> Unit) {\n    LaunchedEffect(onSuccess) {  // Restarts whenever onSuccess changes!\n        val result = expensiveOperation()\n        onSuccess(result)\n    }\n}\n\n// Do: use rememberUpdatedState to capture latest without restarting\n@Composable\nfun GoodCallback(onSuccess: (String) -> Unit) {\n    val updatedOnSuccess = rememberUpdatedState(onSuccess)\n\n    LaunchedEffect(Unit) {\n        val result = expensiveOperation()\n        updatedOnSuccess.value(result)\n    }\n}\n```\n\n### Another Example: Animations\n\n```kotlin\n@Composable\nfun AnimateWithCallback(\n    shouldAnimate: Boolean,\n    onAnimationEnd: () -> Unit\n) {\n    val updatedCallback = rememberUpdatedState(onAnimationEnd)\n    var progress by remember { mutableStateOf(0f) }\n\n    LaunchedEffect(shouldAnimate) {\n        if (shouldAnimate) {\n            while (progress < 1f) {\n                progress += 0.1f\n                delay(16)\n            }\n            updatedCallback.value()  // Call latest callback without restarting\n        }\n    }\n}\n```\n\n## produceState — Converting Non-Compose State to Compose State\n\n`produceState` converts imperative state sources (callbacks, flows, coroutines) into Compose state.\n\n```kotlin\n@Composable\nfun UserData(userId: String): State<User?> = produceState<User?>(initialValue = null) {\n    value = fetchUser(userId)\n\n    // Optional: for lifecycle cleanup\n    snapshotFlow { userId }.collect { newUserId ->\n        value = fetchUser(newUserId)\n    }\n}\n\n// Usage\n@Composable\nfun UserScreen(userId: String) {\n    val user by UserData(userId)\n    Text(user?.name ?: \"Loading...\")\n}\n```\n\n### Integration with Flows\n\n```kotlin\n@Composable\nfun <T> Flow<T>.collectAsState(initial: T): State<T> = produceState(initial) {\n    collect { value = it }\n}\n\n// Usage\n@Composable\nfun ObserveFlow(dataFlow: Flow<String>) {\n    val data by dataFlow.collectAsState(initial = \"\")\n    Text(data)\n}\n```\n\n## Effect Ordering and Lifecycle\n\nEffects execute in declaration order after composition:\n\n```kotlin\n@Composable\nfun EffectOrder() {\n    println(\"1. Composition\")\n\n    SideEffect {\n        println(\"4. Side effect (after every composition)\")\n    }\n\n    LaunchedEffect(Unit) {\n        println(\"3. Launched effect (async, but scheduled)\")\n        delay(100)\n        println(\"5. After delay in launched effect\")\n    }\n\n    DisposableEffect(Unit) {\n        println(\"2. Disposable effect setup (after composition)\")\n\n        onDispose {\n            println(\"6. Cleanup when leaving composition\")\n        }\n    }\n\n    println(\"End of composition body\")\n}\n\n// Output order (approximate):\n// 1. Composition\n// End of composition body\n// 2. Disposable effect setup (after composition)\n// 3. Launched effect (async, but scheduled)\n// 4. Side effect (after every composition)\n// 5. After delay in launched effect\n// [... later when composable leaves ...]\n// 6. Cleanup when leaving composition\n```\n\n## Common Mistakes\n\n### Using LaunchedEffect(Unit) When Key Should Change\n\n```kotlin\n// Don't: effect runs once, never updates\n@Composable\nfun BadSearch(query: String) {\n    var results by remember { mutableStateOf<List<String>>(emptyList()) }\n\n    LaunchedEffect(Unit) {\n        results = search(query)  // Only runs once!\n    }\n\n    Text(\"Results: ${results.size}\")\n}\n\n// Do: use query as key\n@Composable\nfun GoodSearch(query: String) {\n    var results by remember { mutableStateOf<List<String>>(emptyList()) }\n\n    LaunchedEffect(query) {\n        results = search(query)  // Reruns when query changes\n    }\n\n    Text(\"Results: ${results.size}\")\n}\n```\n\n### Forgetting Cleanup in DisposableEffect\n\n```kotlin\n// Don't: memory leak\n@Composable\nfun BadListener(context: Context) {\n    DisposableEffect(Unit) {\n        val listener = MyListener()\n        context.registerListener(listener)\n        // Missing: onDispose { context.unregisterListener(listener) }\n    }\n}\n\n// Do: always clean up\n@Composable\nfun GoodListener(context: Context) {\n    DisposableEffect(Unit) {\n        val listener = MyListener()\n        context.registerListener(listener)\n\n        onDispose {\n            context.unregisterListener(listener)\n        }\n    }\n}\n```\n\n### Capturing Mutable State Directly\n\n```kotlin\n// Don't: stale state in effect\n@Composable\nfun BadCapture() {\n    var count by remember { mutableStateOf(0) }\n\n    LaunchedEffect(Unit) {\n        delay(1000)\n        println(count)  // May be stale!\n    }\n\n    Button(onClick = { count++ }) { Text(\"Click\") }\n}\n\n// Do: use rememberUpdatedState or include in key\n@Composable\nfun GoodCapture() {\n    var count by remember { mutableStateOf(0) }\n\n    val updatedCount = rememberUpdatedState(count)\n    LaunchedEffect(Unit) {\n        delay(1000)\n        println(updatedCount.value)  // Always current\n    }\n\n    Button(onClick = { count++ }) { Text(\"Click\") }\n}\n```\n\n---\n\n**Summary:** Effects bridge declarative Compose with imperative systems. Master key selection in `LaunchedEffect`, always cleanup in `DisposableEffect`, use `rememberUpdatedState` for long-running effects that need fresh values, and prefer effect-based patterns over manual lifecycle management.\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/source-code/cmp-source.md",
    "content": "# Compose Multiplatform Source Reference\n\n> API signatures from [JetBrains/compose-multiplatform-core](https://github.com/JetBrains/compose-multiplatform-core) (branch: jb-main).\n> Each signature includes its source file path as a comment.\n\n---\n\n## Desktop APIs\n\n### Application Lifecycle\n\n```kotlin\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Application.desktop.kt\nfun application(\n    exitProcessOnExit: Boolean = true,\n    content: @Composable ApplicationScope.() -> Unit\n)\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Application.desktop.kt\nsuspend fun awaitApplication(\n    content: @Composable ApplicationScope.() -> Unit\n)\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Application.desktop.kt\n@Stable\ninterface ApplicationScope {\n    fun exitApplication()\n}\n```\n\n### Window\n\n```kotlin\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Window.desktop.kt\n@Composable\nfun Window(\n    onCloseRequest: () -> Unit,\n    state: WindowState = rememberWindowState(),\n    visible: Boolean = true,\n    title: String = \"Untitled\",\n    icon: Painter? = null,\n    undecorated: Boolean = false,\n    transparent: Boolean = false,\n    resizable: Boolean = true,\n    enabled: Boolean = true,\n    focusable: Boolean = true,\n    alwaysOnTop: Boolean = false,\n    onPreviewKeyEvent: (KeyEvent) -> Boolean = { false },\n    onKeyEvent: (KeyEvent) -> Boolean = { false },\n    content: @Composable FrameWindowScope.() -> Unit\n)\n```\n\n### WindowState\n\n```kotlin\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/WindowState.desktop.kt\n@Stable\ninterface WindowState {\n    var placement: WindowPlacement\n    var isMinimized: Boolean\n    var position: WindowPosition\n    var size: DpSize\n}\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/WindowState.desktop.kt\n@Composable\nfun rememberWindowState(\n    placement: WindowPlacement = WindowPlacement.Floating,\n    isMinimized: Boolean = false,\n    position: WindowPosition = WindowPosition.PlatformDefault,\n    size: DpSize = DpSize(800.dp, 600.dp)\n): WindowState\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/WindowPlacement.desktop.kt\nenum class WindowPlacement {\n    Floating,\n    Maximized,\n    Fullscreen\n}\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/WindowPosition.desktop.kt\n@Immutable\nsealed class WindowPosition {\n    object PlatformDefault : WindowPosition()\n\n    class Aligned(val alignment: Alignment) : WindowPosition()\n\n    class Absolute(val x: Dp, val y: Dp) : WindowPosition()\n}\n```\n\n### Tray\n\n```kotlin\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Tray.desktop.kt\n@Composable\nfun ApplicationScope.Tray(\n    icon: Painter,\n    state: TrayState = rememberTrayState(),\n    tooltip: String? = null,\n    onAction: () -> Unit = {},\n    menu: @Composable MenuScope.() -> Unit = {}\n)\n```\n\n### MenuBar and Menu Items\n\n```kotlin\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/MenuBar.desktop.kt\n@Composable\nfun FrameWindowScope.MenuBar(\n    content: @Composable MenuBarScope.() -> Unit\n)\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Menu.desktop.kt\n@Composable\nfun MenuScope.Menu(\n    text: String,\n    enabled: Boolean = true,\n    mnemonic: Char? = null,\n    content: @Composable MenuScope.() -> Unit\n)\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Menu.desktop.kt\n@Composable\nfun MenuScope.Item(\n    text: String,\n    icon: Painter? = null,\n    enabled: Boolean = true,\n    mnemonic: Char? = null,\n    shortcut: KeyShortcut? = null,\n    onClick: () -> Unit\n)\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Menu.desktop.kt\n@Composable\nfun MenuScope.CheckboxItem(\n    text: String,\n    checked: Boolean,\n    icon: Painter? = null,\n    enabled: Boolean = true,\n    mnemonic: Char? = null,\n    shortcut: KeyShortcut? = null,\n    onCheckedChange: (Boolean) -> Unit\n)\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Menu.desktop.kt\n@Composable\nfun MenuScope.RadioButtonItem(\n    text: String,\n    selected: Boolean,\n    icon: Painter? = null,\n    enabled: Boolean = true,\n    mnemonic: Char? = null,\n    shortcut: KeyShortcut? = null,\n    onClick: () -> Unit\n)\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Menu.desktop.kt\n@Composable\nfun MenuScope.Separator()\n```\n\n### DialogWindow\n\n```kotlin\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Dialog.desktop.kt\n@Composable\nfun DialogWindow(\n    onCloseRequest: () -> Unit,\n    state: DialogState = rememberDialogState(),\n    visible: Boolean = true,\n    title: String = \"Untitled\",\n    icon: Painter? = null,\n    undecorated: Boolean = false,\n    transparent: Boolean = false,\n    resizable: Boolean = true,\n    enabled: Boolean = true,\n    focusable: Boolean = true,\n    onPreviewKeyEvent: (KeyEvent) -> Boolean = { false },\n    onKeyEvent: (KeyEvent) -> Boolean = { false },\n    content: @Composable DialogWindowScope.() -> Unit\n)\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/DialogState.desktop.kt\n@Stable\ninterface DialogState {\n    var position: WindowPosition\n    var size: DpSize\n}\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/DialogState.desktop.kt\n@Composable\nfun rememberDialogState(\n    position: WindowPosition = WindowPosition.PlatformDefault,\n    size: DpSize = DpSize(400.dp, 300.dp)\n): DialogState\n```\n\n### Notification\n\n```kotlin\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/window/Notification.desktop.kt\nclass Notification(\n    val title: String,\n    val message: String,\n    val type: Type = Type.None\n) {\n    enum class Type {\n        None,\n        Info,\n        Warning,\n        Error\n    }\n}\n```\n\n### Swing / AWT Interop\n\n```kotlin\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/ComposePanel.desktop.kt\nclass ComposePanel : JLayeredPane() {\n    fun setContent(content: @Composable () -> Unit)\n    fun dispose()\n}\n\n// Source: compose/ui/ui/src/desktopMain/kotlin/androidx/compose/ui/awt/SwingPanel.desktop.kt\n@Composable\nfun <T : Component> SwingPanel(\n    factory: () -> T,\n    modifier: Modifier = Modifier,\n    update: (T) -> Unit = {},\n    background: Color = Color.White\n)\n```\n\n### Scrollbar\n\n```kotlin\n// Source: compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/Scrollbar.desktop.kt\n@Composable\nfun VerticalScrollbar(\n    adapter: ScrollbarAdapter,\n    modifier: Modifier = Modifier,\n    reverseLayout: Boolean = false,\n    style: ScrollbarStyle = LocalScrollbarStyle.current,\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }\n)\n\n// Source: compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/Scrollbar.desktop.kt\n@Composable\nfun HorizontalScrollbar(\n    adapter: ScrollbarAdapter,\n    modifier: Modifier = Modifier,\n    reverseLayout: Boolean = false,\n    style: ScrollbarStyle = LocalScrollbarStyle.current,\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }\n)\n\n// Source: compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/ScrollbarStyling.desktop.kt\n@Immutable\ndata class ScrollbarStyle(\n    val minimalHeight: Dp,\n    val thickness: Dp,\n    val shape: Shape,\n    val hoverDurationMillis: Int,\n    val unhoverColor: Color,\n    val hoverColor: Color\n)\n\n// Source: compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/ScrollbarStyling.desktop.kt\n@Composable\nfun defaultScrollbarStyle(): ScrollbarStyle\n\n// Source: compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/ScrollbarStyling.desktop.kt\nval LocalScrollbarStyle = staticCompositionLocalOf { defaultScrollbarStyle() }\n\n// Source: compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/Scrollbar.desktop.kt\n@Composable\nfun rememberScrollbarAdapter(\n    scrollState: ScrollState\n): ScrollbarAdapter\n\n@Composable\nfun rememberScrollbarAdapter(\n    scrollState: LazyListState\n): ScrollbarAdapter\n\n@Composable\nfun rememberScrollbarAdapter(\n    scrollState: LazyGridState\n): ScrollbarAdapter\n```\n\n---\n\n## iOS APIs\n\n### ComposeUIViewController\n\n```kotlin\n// Source: compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/ComposeUIViewController.uikit.kt\nfun ComposeUIViewController(\n    content: @Composable () -> Unit\n): UIViewController\n\n// Source: compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/ComposeUIViewController.uikit.kt\nfun ComposeUIViewController(\n    configure: ComposeUIViewControllerConfiguration.() -> Unit = {},\n    content: @Composable () -> Unit\n): UIViewController\n```\n\n### ComposeUIView (Experimental)\n\n```kotlin\n// Source: compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/ComposeUIView.uikit.kt\n@ExperimentalComposeApi\nfun ComposeUIView(\n    content: @Composable () -> Unit\n): UIView\n\n// Source: compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/ComposeUIView.uikit.kt\n@ExperimentalComposeApi\nfun ComposeUIView(\n    configure: ComposeUIViewControllerConfiguration.() -> Unit = {},\n    content: @Composable () -> Unit\n): UIView\n```\n\n### ComposeContainerConfiguration\n\n```kotlin\n// Source: compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/ComposeContainerConfiguration.uikit.kt\nclass ComposeUIViewControllerConfiguration {\n    var onFocusBehavior: OnFocusBehavior = OnFocusBehavior.FocusableAboveKeyboard\n    var opaque: Boolean = true\n    var parallelRendering: Boolean = false\n    var endEdgePanGestureBehavior: EndEdgePanGestureBehavior = EndEdgePanGestureBehavior.Disabled\n}\n\n// Source: compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/OnFocusBehavior.uikit.kt\nsealed interface OnFocusBehavior {\n    object DoNothing : OnFocusBehavior\n    object FocusableAboveKeyboard : OnFocusBehavior\n}\n\n// Source: compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/window/EndEdgePanGestureBehavior.uikit.kt\nsealed interface EndEdgePanGestureBehavior {\n    object Disabled : EndEdgePanGestureBehavior\n    object Back : EndEdgePanGestureBehavior\n    object Forward : EndEdgePanGestureBehavior\n}\n```\n\n### UIKit Interop\n\n```kotlin\n// Source: compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/interop/UIKitView.uikit.kt\n@Composable\nfun <T : UIView> UIKitView(\n    factory: () -> T,\n    modifier: Modifier = Modifier,\n    update: (T) -> Unit = {},\n    onRelease: (T) -> Unit = {},\n    onReset: ((T) -> Unit)? = null,\n    properties: UIKitInteropProperties = UIKitInteropProperties()\n)\n\n// Source: compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/interop/UIKitView.uikit.kt\n@Composable\nfun <T : UIViewController> UIKitViewController(\n    factory: () -> T,\n    modifier: Modifier = Modifier,\n    update: (T) -> Unit = {},\n    onRelease: (T) -> Unit = {},\n    onReset: ((T) -> Unit)? = null,\n    properties: UIKitInteropProperties = UIKitInteropProperties()\n)\n\n// Source: compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/interop/UIKitInteropProperties.uikit.kt\n@Immutable\nclass UIKitInteropProperties(\n    val interactionMode: UIKitInteropInteractionMode = UIKitInteropInteractionMode.Cooperative(),\n    val isNativeAccessibilityEnabled: Boolean = true,\n    val placedAsOverlay: Boolean = false\n)\n\n// Source: compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/interop/UIKitInteropInteractionMode.uikit.kt\nsealed interface UIKitInteropInteractionMode {\n    object NonCooperative : UIKitInteropInteractionMode\n    class Cooperative(val delayMillis: Long = 150) : UIKitInteropInteractionMode\n}\n```\n\n### iOS CompositionLocals\n\n```kotlin\n// Source: compose/ui/ui/src/uikitMain/kotlin/androidx/compose/ui/interop/LocalUIKitInterop.uikit.kt\nval LocalUIViewController: ProvidableCompositionLocal<UIViewController> =\n    staticCompositionLocalOf { error(\"CompositionLocal LocalUIViewController not provided\") }\n\nval LocalUIView: ProvidableCompositionLocal<UIView> =\n    staticCompositionLocalOf { error(\"CompositionLocal LocalUIView not provided\") }\n```\n\n---\n\n## Web / WASM APIs\n\n### ComposeViewport\n\n```kotlin\n// Source: compose/ui/ui/src/wasmJsMain/kotlin/androidx/compose/ui/window/ComposeViewport.wasmJs.kt\nfun ComposeViewport(\n    viewportContainerId: String,\n    configure: ComposeViewportConfiguration.() -> Unit = {},\n    content: @Composable () -> Unit\n)\n\n// Source: compose/ui/ui/src/wasmJsMain/kotlin/androidx/compose/ui/window/ComposeViewport.wasmJs.kt\nfun ComposeViewport(\n    viewportContainer: Element,\n    configure: ComposeViewportConfiguration.() -> Unit = {},\n    content: @Composable () -> Unit\n)\n\n// Source: compose/ui/ui/src/wasmJsMain/kotlin/androidx/compose/ui/window/ComposeViewportConfiguration.wasmJs.kt\nclass ComposeViewportConfiguration {\n    var isA11YEnabled: Boolean = true\n}\n```\n\n---\n\n## Shared / Skiko APIs\n\n### System Theme\n\n```kotlin\n// Source: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/SystemTheme.skiko.kt\nenum class SystemTheme {\n    Light,\n    Dark,\n    Unknown\n}\n\n// Source: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/SystemTheme.skiko.kt\nval LocalSystemTheme: ProvidableCompositionLocal<SystemTheme> =\n    staticCompositionLocalOf { SystemTheme.Unknown }\n```\n\n### ComposeScene\n\n```kotlin\n// Source: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ComposeScene.skiko.kt\nsealed interface ComposeScene : AutoCloseable {\n    val focusManager: FocusManager\n    var density: Density\n    var layoutDirection: LayoutDirection\n    var size: IntSize?\n    fun setContent(content: @Composable () -> Unit)\n    fun render(canvas: Canvas, nanoTime: Long)\n    fun sendPointerEvent(/* ... */)\n    fun sendKeyEvent(keyEvent: KeyEvent): Boolean\n    override fun close()\n}\n```\n\n### ImageComposeScene (Headless Rendering)\n\n```kotlin\n// Source: compose/ui/ui/src/skikoMain/kotlin/androidx/compose/ui/scene/ImageComposeScene.skiko.kt\nfun ImageComposeScene(\n    width: Int,\n    height: Int,\n    density: Density = Density(1f),\n    coroutineContext: CoroutineContext = Dispatchers.Unconfined,\n    content: @Composable () -> Unit = {}\n): ComposeScene\n```\n\n### isSystemInDarkTheme (expect/actual)\n\n```kotlin\n// Source: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/DarkTheme.kt\n@Composable\nexpect fun isSystemInDarkTheme(): Boolean\n\n// Source: compose/foundation/foundation/src/desktopMain/kotlin/androidx/compose/foundation/DarkTheme.desktop.kt\n@Composable\nactual fun isSystemInDarkTheme(): Boolean =\n    LocalSystemTheme.current == SystemTheme.Dark\n\n// Source: compose/foundation/foundation/src/uikitMain/kotlin/androidx/compose/foundation/DarkTheme.uikit.kt\n@Composable\nactual fun isSystemInDarkTheme(): Boolean { /* UIScreen.mainScreen traitCollection check */ }\n\n// Source: compose/foundation/foundation/src/wasmJsMain/kotlin/androidx/compose/foundation/DarkTheme.wasmJs.kt\n@Composable\nactual fun isSystemInDarkTheme(): Boolean { /* window.matchMedia(\"(prefers-color-scheme: dark)\") */ }\n```\n\n---\n\n## Resource System\n\n### Resource Types\n\n```kotlin\n// Source: components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/Resource.kt\n@Immutable\nsealed class Resource(\n    internal val id: String,\n    internal val items: Set<ResourceItem>\n)\n\n// Source: components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceItem.kt\n@Immutable\nclass ResourceItem(\n    internal val qualifiers: Set<Qualifier>,\n    internal val path: String,\n    internal val offset: Long,\n    internal val size: Long\n)\n```\n\n### ResourceReader (Platform Actuals)\n\n```kotlin\n// Source: components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceReader.kt\ninterface ResourceReader {\n    suspend fun read(path: String): ByteArray\n    suspend fun readPart(path: String, offset: Long, size: Long): ByteArray\n    fun getUri(path: String): String\n}\n\n// Platform actuals:\n// Source: components/resources/library/src/jvmMain/kotlin/org/jetbrains/compose/resources/ResourceReader.jvm.kt\n// Source: components/resources/library/src/iosMain/kotlin/org/jetbrains/compose/resources/ResourceReader.ios.kt\n// Source: components/resources/library/src/wasmJsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.wasmJs.kt\n// Source: components/resources/library/src/jsMain/kotlin/org/jetbrains/compose/resources/ResourceReader.js.kt\n```\n\n### rememberResourceState (expect/actual)\n\n```kotlin\n// Source: components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ResourceState.kt\n@Composable\nexpect fun <T> rememberResourceState(\n    key1: Any,\n    getDefault: () -> T,\n    block: suspend (ResourceEnvironment) -> T\n): State<T>\n\n// JVM/iOS actual: synchronous (blocking read, returns value immediately)\n// Source: components/resources/library/src/blockingMain/kotlin/org/jetbrains/compose/resources/ResourceState.blocking.kt\n\n// JS/WASM actual: asynchronous (suspending read, returns default then updates)\n// Source: components/resources/library/src/webMain/kotlin/org/jetbrains/compose/resources/ResourceState.web.kt\n```\n\n### Resource Composables\n\n```kotlin\n// Source: components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/StringResources.kt\n@Composable\nfun stringResource(resource: StringResource): String\n\n@Composable\nfun stringResource(resource: StringResource, vararg formatArgs: Any): String\n\n// Source: components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/ImageResources.kt\n@Composable\nfun painterResource(resource: DrawableResource): Painter\n\n@Composable\nfun imageResource(resource: DrawableResource): ImageBitmap\n\n// Source: components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/VectorResources.kt\n@Composable\nfun vectorResource(resource: DrawableResource): ImageVector\n\n// Source: components/resources/library/src/commonMain/kotlin/org/jetbrains/compose/resources/FontResources.kt\n@Composable\nexpect fun Font(\n    resource: FontResource,\n    weight: FontWeight = FontWeight.Normal,\n    style: FontStyle = FontStyle.Normal\n): Font\n```\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/source-code/foundation-source.md",
    "content": "# Compose Foundation Source Reference\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Clickable.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation\n\nimport androidx.collection.mutableLongObjectMapOf\nimport androidx.compose.foundation.ComposeFoundationFlags.isDelayPressesUsingGestureConsumptionEnabled\nimport androidx.compose.foundation.gestures.PressGestureScope\nimport androidx.compose.foundation.gestures.ScrollableContainerNode\nimport androidx.compose.foundation.gestures.changedToDownIgnoreConsumed\nimport androidx.compose.foundation.gestures.detectTapGestures\nimport androidx.compose.foundation.gestures.isChangedToDown\nimport androidx.compose.foundation.gestures.isDeepPress\nimport androidx.compose.foundation.interaction.HoverInteraction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.internal.requirePrecondition\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.focus.Focusability\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.hapticfeedback.HapticFeedback\nimport androidx.compose.ui.hapticfeedback.HapticFeedbackType\nimport androidx.compose.ui.input.indirect.IndirectPointerEvent\nimport androidx.compose.ui.input.indirect.IndirectPointerInputChange\nimport androidx.compose.ui.input.indirect.IndirectPointerInputModifierNode\nimport androidx.compose.ui.input.key.Key\nimport androidx.compose.ui.input.key.KeyEvent\nimport androidx.compose.ui.input.key.KeyEventType.Companion.KeyDown\nimport androidx.compose.ui.input.key.KeyEventType.Companion.KeyUp\nimport androidx.compose.ui.input.key.KeyInputModifierNode\nimport androidx.compose.ui.input.key.key\nimport androidx.compose.ui.input.key.type\nimport androidx.compose.ui.input.pointer.PointerEvent\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerEventType\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode\nimport androidx.compose.ui.input.pointer.changedToUp\nimport androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed\nimport androidx.compose.ui.input.pointer.isOutOfBounds\nimport androidx.compose.ui.node.CompositionLocalConsumerModifierNode\nimport androidx.compose.ui.node.DelegatableNode\nimport androidx.compose.ui.node.DelegatingNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.node.ObserverModifierNode\nimport androidx.compose.ui.node.PointerInputModifierNode\nimport androidx.compose.ui.node.SemanticsModifierNode\nimport androidx.compose.ui.node.TraversableNode\nimport androidx.compose.ui.node.currentValueOf\nimport androidx.compose.ui.node.invalidateSemantics\nimport androidx.compose.ui.node.observeReads\nimport androidx.compose.ui.node.requireDensity\nimport androidx.compose.ui.node.traverseAncestors\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalViewConfiguration\nimport androidx.compose.ui.platform.debugInspectorInfo\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.semantics.SemanticsPropertyReceiver\nimport androidx.compose.ui.semantics.disabled\nimport androidx.compose.ui.semantics.onClick\nimport androidx.compose.ui.semantics.onLongClick\nimport androidx.compose.ui.semantics.role\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.center\nimport androidx.compose.ui.unit.toOffset\nimport androidx.compose.ui.util.fastAll\nimport androidx.compose.ui.util.fastAny\nimport androidx.compose.ui.util.fastForEach\nimport kotlin.math.abs\nimport kotlin.math.max\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.cancelAndJoin\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.delay\nimport kotlinx.coroutines.launch\n\n/**\n * Configure component to receive clicks via input or accessibility \"click\" event.\n *\n * Add this modifier to the element to make it clickable within its bounds and show a default\n * indication when it's pressed.\n *\n * This version has no [MutableInteractionSource] or [Indication] parameters, the default indication\n * from [LocalIndication] will be used. To specify [MutableInteractionSource] or [Indication], use\n * the other overload.\n *\n * If you are only creating this clickable modifier inside composition, consider using the other\n * overload and explicitly passing `LocalIndication.current` for improved performance. For more\n * information see the documentation on the other overload.\n *\n * If you need to support double click or long click alongside the single click, consider using\n * [combinedClickable].\n *\n * ***Note*** Any removal operations on Android Views from `clickable` should wrap `onClick` in a\n * `post { }` block to guarantee the event dispatch completes before executing the removal. (You do\n * not need to do this when removing a composable because Compose guarantees it completes via the\n * snapshot state system.)\n *\n * @sample androidx.compose.foundation.samples.ClickableSample\n * @param enabled Controls the enabled state. When `false`, [onClick], and this modifier will appear\n *   disabled for accessibility services\n * @param onClickLabel semantic / accessibility label for the [onClick] action\n * @param role the type of user interface element. Accessibility services might use this to describe\n *   the element or do customizations\n * @param onClick will be called when user clicks on the element\n */\n@Deprecated(\n    message =\n        \"Replaced with new overload that only supports IndicationNodeFactory instances inside LocalIndication, and does not use composed\",\n    level = DeprecationLevel.HIDDEN,\n)\nfun Modifier.clickable(\n    enabled: Boolean = true,\n    onClickLabel: String? = null,\n    role: Role? = null,\n    onClick: () -> Unit,\n) =\n    composed(\n        inspectorInfo =\n            debugInspectorInfo {\n                name = \"clickable\"\n                properties[\"enabled\"] = enabled\n                properties[\"onClickLabel\"] = onClickLabel\n                properties[\"role\"] = role\n                properties[\"onClick\"] = onClick\n            }\n    ) {\n        val localIndication = LocalIndication.current\n        val interactionSource =\n            if (localIndication is IndicationNodeFactory) {\n                // We can fast path here as it will be created inside clickable lazily\n                null\n            } else {\n                // We need an interaction source to pass between the indication modifier and\n                // clickable, so\n                // by creating here we avoid another composed down the line\n                remember { MutableInteractionSource() }\n            }\n        Modifier.clickable(\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            onClick = onClick,\n            role = role,\n            indication = localIndication,\n            interactionSource = interactionSource,\n        )\n    }\n\n/**\n * Configure component to receive clicks via input or accessibility \"click\" event.\n *\n * Add this modifier to the element to make it clickable within its bounds and show a default\n * indication when it's pressed.\n *\n * This overload will use the [Indication] from [LocalIndication]. Use the other overload to\n * explicitly provide an [Indication] instance. Note that this overload only supports\n * [IndicationNodeFactory] instances provided through [LocalIndication] - it is strongly recommended\n * to migrate to [IndicationNodeFactory], but you can use the other overload if you still need to\n * support [Indication] instances that are not [IndicationNodeFactory].\n *\n * If [interactionSource] is `null`, an internal [MutableInteractionSource] will be lazily created\n * only when needed. This reduces the performance cost of clickable during composition, as creating\n * the [indication] can be delayed until there is an incoming\n * [androidx.compose.foundation.interaction.Interaction]. If you are only passing a remembered\n * [MutableInteractionSource] and you are never using it outside of clickable, it is recommended to\n * instead provide `null` to enable lazy creation. If you need the [Indication] to be created\n * eagerly, provide a remembered [MutableInteractionSource].\n *\n * If you need to support double click or long click alongside the single click, consider using\n * [combinedClickable].\n *\n * ***Note*** Any removal operations on Android Views from `clickable` should wrap `onClick` in a\n * `post { }` block to guarantee the event dispatch completes before executing the removal. (You do\n * not need to do this when removing a composable because Compose guarantees it completes via the\n * snapshot state system.)\n *\n * @sample androidx.compose.foundation.samples.ClickableSample\n * @param enabled Controls the enabled state. When `false`, [onClick], and this modifier will appear\n *   disabled for accessibility services\n * @param onClickLabel semantic / accessibility label for the [onClick] action\n * @param role the type of user interface element. Accessibility services might use this to describe\n *   the element or do customizations\n * @param interactionSource [MutableInteractionSource] that will be used to dispatch\n *   [PressInteraction.Press] when this clickable is pressed. If `null`, an internal\n *   [MutableInteractionSource] will be created if needed.\n * @param onClick will be called when user clicks on the element\n */\nfun Modifier.clickable(\n    enabled: Boolean = true,\n    onClickLabel: String? = null,\n    role: Role? = null,\n    interactionSource: MutableInteractionSource? = null,\n    onClick: () -> Unit,\n): Modifier {\n    return this.then(\n        ClickableElement(\n            interactionSource = interactionSource,\n            indicationNodeFactory = null,\n            useLocalIndication = true,\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            role = role,\n            onClick = onClick,\n        )\n    )\n}\n\n/**\n * Configure component to receive clicks via input or accessibility \"click\" event.\n *\n * Add this modifier to the element to make it clickable within its bounds and show an indication as\n * specified in [indication] parameter.\n *\n * If [interactionSource] is `null`, and [indication] is an [IndicationNodeFactory], an internal\n * [MutableInteractionSource] will be lazily created along with the [indication] only when needed.\n * This reduces the performance cost of clickable during composition, as creating the [indication]\n * can be delayed until there is an incoming [androidx.compose.foundation.interaction.Interaction].\n * If you are only passing a remembered [MutableInteractionSource] and you are never using it\n * outside of clickable, it is recommended to instead provide `null` to enable lazy creation. If you\n * need [indication] to be created eagerly, provide a remembered [MutableInteractionSource].\n *\n * If [indication] is _not_ an [IndicationNodeFactory], and instead implements the deprecated\n * [Indication.rememberUpdatedInstance] method, you should explicitly pass a remembered\n * [MutableInteractionSource] as a parameter for [interactionSource] instead of `null`, as this\n * cannot be lazily created inside clickable.\n *\n * If you need to support double click or long click alongside the single click, consider using\n * [combinedClickable].\n *\n * ***Note*** Any removal operations on Android Views from `clickable` should wrap `onClick` in a\n * `post { }` block to guarantee the event dispatch completes before executing the removal. (You do\n * not need to do this when removing a composable because Compose guarantees it completes via the\n * snapshot state system.)\n *\n * @sample androidx.compose.foundation.samples.ClickableSample\n * @param interactionSource [MutableInteractionSource] that will be used to dispatch\n *   [PressInteraction.Press] when this clickable is pressed. If `null`, an internal\n *   [MutableInteractionSource] will be created if needed.\n * @param indication indication to be shown when modified element is pressed. By default, indication\n *   from [LocalIndication] will be used. Pass `null` to show no indication, or current value from\n *   [LocalIndication] to show theme default\n * @param enabled Controls the enabled state. When `false`, [onClick], and this modifier will appear\n *   disabled for accessibility services\n * @param onClickLabel semantic / accessibility label for the [onClick] action\n * @param role the type of user interface element. Accessibility services might use this to describe\n *   the element or do customizations\n * @param onClick will be called when user clicks on the element\n */\nfun Modifier.clickable(\n    interactionSource: MutableInteractionSource?,\n    indication: Indication?,\n    enabled: Boolean = true,\n    onClickLabel: String? = null,\n    role: Role? = null,\n    onClick: () -> Unit,\n) =\n    clickableWithIndicationIfNeeded(\n        interactionSource = interactionSource,\n        indication = indication,\n    ) { intSource, indicationNodeFactory ->\n        ClickableElement(\n            interactionSource = intSource,\n            indicationNodeFactory = indicationNodeFactory,\n            useLocalIndication = false,\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            role = role,\n            onClick = onClick,\n        )\n    }\n\n/**\n * Configure component to receive clicks, double clicks and long clicks via input or accessibility\n * \"click\" event.\n *\n * Add this modifier to the element to make it clickable within its bounds.\n *\n * If you need only click handling, and no double or long clicks, consider using [clickable]\n *\n * This version has no [MutableInteractionSource] or [Indication] parameters, the default indication\n * from [LocalIndication] will be used. To specify [MutableInteractionSource] or [Indication], use\n * the other overload.\n *\n * If you are only creating this combinedClickable modifier inside composition, consider using the\n * other overload and explicitly passing `LocalIndication.current` for improved performance. For\n * more information see the documentation on the other overload.\n *\n * Note, if the modifier instance gets re-used between a key down and key up events, the ongoing\n * input will be aborted.\n *\n * ***Note*** Any removal operations on Android Views from `clickable` should wrap `onClick` in a\n * `post { }` block to guarantee the event dispatch completes before executing the removal. (You do\n * not need to do this when removing a composable because Compose guarantees it completes via the\n * snapshot state system.)\n *\n * @sample androidx.compose.foundation.samples.ClickableSample\n * @param enabled Controls the enabled state. When `false`, [onClick], [onLongClick] or\n *   [onDoubleClick] won't be invoked\n * @param onClickLabel semantic / accessibility label for the [onClick] action\n * @param role the type of user interface element. Accessibility services might use this to describe\n *   the element or do customizations\n * @param onLongClickLabel semantic / accessibility label for the [onLongClick] action\n * @param onLongClick will be called when user long presses on the element\n * @param onDoubleClick will be called when user double clicks on the element\n * @param hapticFeedbackEnabled whether to use the default [HapticFeedback] behavior\n * @param onClick will be called when user clicks on the element\n */\n@Deprecated(\n    message =\n        \"Replaced with new overload that only supports IndicationNodeFactory instances inside LocalIndication, and does not use composed\",\n    level = DeprecationLevel.HIDDEN,\n)\nfun Modifier.combinedClickable(\n    enabled: Boolean = true,\n    onClickLabel: String? = null,\n    role: Role? = null,\n    onLongClickLabel: String? = null,\n    onLongClick: (() -> Unit)? = null,\n    onDoubleClick: (() -> Unit)? = null,\n    hapticFeedbackEnabled: Boolean = true,\n    onClick: () -> Unit,\n) =\n    composed(\n        inspectorInfo =\n            debugInspectorInfo {\n                name = \"combinedClickable\"\n                properties[\"enabled\"] = enabled\n                properties[\"onClickLabel\"] = onClickLabel\n                properties[\"role\"] = role\n                properties[\"onClick\"] = onClick\n                properties[\"onDoubleClick\"] = onDoubleClick\n                properties[\"onLongClick\"] = onLongClick\n                properties[\"onLongClickLabel\"] = onLongClickLabel\n                properties[\"hapticFeedbackEnabled\"] = hapticFeedbackEnabled\n            }\n    ) {\n        val localIndication = LocalIndication.current\n        val interactionSource =\n            if (localIndication is IndicationNodeFactory) {\n                // We can fast path here as it will be created inside clickable lazily\n                null\n            } else {\n                // We need an interaction source to pass between the indication modifier and\n                // clickable, so\n                // by creating here we avoid another composed down the line\n                remember { MutableInteractionSource() }\n            }\n        Modifier.combinedClickable(\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            onLongClickLabel = onLongClickLabel,\n            onLongClick = onLongClick,\n            onDoubleClick = onDoubleClick,\n            onClick = onClick,\n            role = role,\n            indication = localIndication,\n            interactionSource = interactionSource,\n            hapticFeedbackEnabled = hapticFeedbackEnabled,\n        )\n    }\n\n/**\n * Configure component to receive clicks, double clicks and long clicks via input or accessibility\n * \"click\" event.\n *\n * Add this modifier to the element to make it clickable within its bounds.\n *\n * If you need only click handling, and no double or long clicks, consider using [clickable]\n *\n * This overload will use the [Indication] from [LocalIndication]. Use the other overload to\n * explicitly provide an [Indication] instance. Note that this overload only supports\n * [IndicationNodeFactory] instances provided through [LocalIndication] - it is strongly recommended\n * to migrate to [IndicationNodeFactory], but you can use the other overload if you still need to\n * support [Indication] instances that are not [IndicationNodeFactory].\n *\n * If [interactionSource] is `null`, an internal [MutableInteractionSource] will be lazily created\n * only when needed. This reduces the performance cost of combinedClickable during composition, as\n * creating the [indication] can be delayed until there is an incoming\n * [androidx.compose.foundation.interaction.Interaction]. If you are only passing a remembered\n * [MutableInteractionSource] and you are never using it outside of combinedClickable, it is\n * recommended to instead provide `null` to enable lazy creation. If you need the [Indication] to be\n * created eagerly, provide a remembered [MutableInteractionSource].\n *\n * Note, if the modifier instance gets re-used between a key down and key up events, the ongoing\n * input will be aborted.\n *\n * ***Note*** Any removal operations on Android Views from `clickable` should wrap `onClick` in a\n * `post { }` block to guarantee the event dispatch completes before executing the removal. (You do\n * not need to do this when removing a composable because Compose guarantees it completes via the\n * snapshot state system.)\n *\n * @sample androidx.compose.foundation.samples.ClickableSample\n * @param enabled Controls the enabled state. When `false`, [onClick], [onLongClick] or\n *   [onDoubleClick] won't be invoked\n * @param onClickLabel semantic / accessibility label for the [onClick] action\n * @param role the type of user interface element. Accessibility services might use this to describe\n *   the element or do customizations\n * @param onLongClickLabel semantic / accessibility label for the [onLongClick] action\n * @param onLongClick will be called when user long presses on the element\n * @param onDoubleClick will be called when user double clicks on the element\n * @param hapticFeedbackEnabled whether to use the default [HapticFeedback] behavior\n * @param interactionSource [MutableInteractionSource] that will be used to dispatch\n *   [PressInteraction.Press] when this clickable is pressed. If `null`, an internal\n *   [MutableInteractionSource] will be created if needed.\n * @param onClick will be called when user clicks on the element\n */\nfun Modifier.combinedClickable(\n    enabled: Boolean = true,\n    onClickLabel: String? = null,\n    role: Role? = null,\n    onLongClickLabel: String? = null,\n    onLongClick: (() -> Unit)? = null,\n    onDoubleClick: (() -> Unit)? = null,\n    hapticFeedbackEnabled: Boolean = true,\n    interactionSource: MutableInteractionSource? = null,\n    onClick: () -> Unit,\n): Modifier {\n    return this.then(\n        CombinedClickableElement(\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            onLongClickLabel = onLongClickLabel,\n            onLongClick = onLongClick,\n            onDoubleClick = onDoubleClick,\n            onClick = onClick,\n            role = role,\n            interactionSource = interactionSource,\n            indicationNodeFactory = null,\n            useLocalIndication = true,\n            hapticFeedbackEnabled = hapticFeedbackEnabled,\n        )\n    )\n}\n\n@Deprecated(message = \"Maintained for binary compatibility\", level = DeprecationLevel.HIDDEN)\nfun Modifier.combinedClickable(\n    enabled: Boolean = true,\n    onClickLabel: String? = null,\n    role: Role? = null,\n    onLongClickLabel: String? = null,\n    onLongClick: (() -> Unit)? = null,\n    onDoubleClick: (() -> Unit)? = null,\n    onClick: () -> Unit,\n) =\n    composed(\n        inspectorInfo =\n            debugInspectorInfo {\n                name = \"combinedClickable\"\n                properties[\"enabled\"] = enabled\n                properties[\"onClickLabel\"] = onClickLabel\n                properties[\"role\"] = role\n                properties[\"onClick\"] = onClick\n                properties[\"onDoubleClick\"] = onDoubleClick\n                properties[\"onLongClick\"] = onLongClick\n                properties[\"onLongClickLabel\"] = onLongClickLabel\n            }\n    ) {\n        val localIndication = LocalIndication.current\n        val interactionSource =\n            if (localIndication is IndicationNodeFactory) {\n                // We can fast path here as it will be created inside clickable lazily\n                null\n            } else {\n                // We need an interaction source to pass between the indication modifier and\n                // clickable, so\n                // by creating here we avoid another composed down the line\n                remember { MutableInteractionSource() }\n            }\n        Modifier.combinedClickable(\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            onLongClickLabel = onLongClickLabel,\n            onLongClick = onLongClick,\n            onDoubleClick = onDoubleClick,\n            onClick = onClick,\n            role = role,\n            indication = localIndication,\n            interactionSource = interactionSource,\n            hapticFeedbackEnabled = true,\n        )\n    }\n\n/**\n * Configure component to receive clicks, double clicks and long clicks via input or accessibility\n * \"click\" event.\n *\n * Add this modifier to the element to make it clickable within its bounds.\n *\n * If you need only click handling, and no double or long clicks, consider using [clickable].\n *\n * Add this modifier to the element to make it clickable within its bounds.\n *\n * If [interactionSource] is `null`, and [indication] is an [IndicationNodeFactory], an internal\n * [MutableInteractionSource] will be lazily created along with the [indication] only when needed.\n * This reduces the performance cost of clickable during composition, as creating the [indication]\n * can be delayed until there is an incoming [androidx.compose.foundation.interaction.Interaction].\n * If you are only passing a remembered [MutableInteractionSource] and you are never using it\n * outside of clickable, it is recommended to instead provide `null` to enable lazy creation. If you\n * need [indication] to be created eagerly, provide a remembered [MutableInteractionSource].\n *\n * If [indication] is _not_ an [IndicationNodeFactory], and instead implements the deprecated\n * [Indication.rememberUpdatedInstance] method, you should explicitly pass a remembered\n * [MutableInteractionSource] as a parameter for [interactionSource] instead of `null`, as this\n * cannot be lazily created inside clickable.\n *\n * Note, if the modifier instance gets re-used between a key down and key up events, the ongoing\n * input will be aborted.\n *\n * ***Note*** Any removal operations on Android Views from `clickable` should wrap `onClick` in a\n * `post { }` block to guarantee the event dispatch completes before executing the removal. (You do\n * not need to do this when removing a composable because Compose guarantees it completes via the\n * snapshot state system.)\n *\n * @sample androidx.compose.foundation.samples.ClickableSample\n * @param interactionSource [MutableInteractionSource] that will be used to emit\n *   [PressInteraction.Press] when this clickable is pressed. If `null`, an internal\n *   [MutableInteractionSource] will be created if needed.\n * @param indication indication to be shown when modified element is pressed. By default, indication\n *   from [LocalIndication] will be used. Pass `null` to show no indication, or current value from\n *   [LocalIndication] to show theme default\n * @param enabled Controls the enabled state. When `false`, [onClick], [onLongClick] or\n *   [onDoubleClick] won't be invoked\n * @param onClickLabel semantic / accessibility label for the [onClick] action\n * @param role the type of user interface element. Accessibility services might use this to describe\n *   the element or do customizations\n * @param onLongClickLabel semantic / accessibility label for the [onLongClick] action\n * @param onLongClick will be called when user long presses on the element\n * @param onDoubleClick will be called when user double clicks on the element\n * @param hapticFeedbackEnabled whether to use the default [HapticFeedback] behavior\n * @param onClick will be called when user clicks on the element\n */\nfun Modifier.combinedClickable(\n    interactionSource: MutableInteractionSource?,\n    indication: Indication?,\n    enabled: Boolean = true,\n    onClickLabel: String? = null,\n    role: Role? = null,\n    onLongClickLabel: String? = null,\n    onLongClick: (() -> Unit)? = null,\n    onDoubleClick: (() -> Unit)? = null,\n    hapticFeedbackEnabled: Boolean = true,\n    onClick: () -> Unit,\n) =\n    clickableWithIndicationIfNeeded(\n        interactionSource = interactionSource,\n        indication = indication,\n    ) { intSource, indicationNodeFactory ->\n        CombinedClickableElement(\n            interactionSource = intSource,\n            indicationNodeFactory = indicationNodeFactory,\n            useLocalIndication = false,\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            role = role,\n            onClick = onClick,\n            onLongClickLabel = onLongClickLabel,\n            onLongClick = onLongClick,\n            onDoubleClick = onDoubleClick,\n            hapticFeedbackEnabled = hapticFeedbackEnabled,\n        )\n    }\n\n@Deprecated(message = \"Maintained for binary compatibility\", level = DeprecationLevel.HIDDEN)\nfun Modifier.combinedClickable(\n    interactionSource: MutableInteractionSource?,\n    indication: Indication?,\n    enabled: Boolean = true,\n    onClickLabel: String? = null,\n    role: Role? = null,\n    onLongClickLabel: String? = null,\n    onLongClick: (() -> Unit)? = null,\n    onDoubleClick: (() -> Unit)? = null,\n    onClick: () -> Unit,\n) =\n    clickableWithIndicationIfNeeded(\n        interactionSource = interactionSource,\n        indication = indication,\n    ) { intSource, indicationNodeFactory ->\n        CombinedClickableElement(\n            interactionSource = intSource,\n            indicationNodeFactory = indicationNodeFactory,\n            useLocalIndication = false,\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            role = role,\n            onClick = onClick,\n            onLongClickLabel = onLongClickLabel,\n            onLongClick = onLongClick,\n            onDoubleClick = onDoubleClick,\n            hapticFeedbackEnabled = true,\n        )\n    }\n\n/**\n * Utility Modifier factory that handles edge cases for [interactionSource], and [indication].\n * [createClickable] is the lambda that creates the actual clickable element, which will be chained\n * with [Modifier.indication] if needed.\n */\ninternal inline fun Modifier.clickableWithIndicationIfNeeded(\n    interactionSource: MutableInteractionSource?,\n    indication: Indication?,\n    crossinline createClickable: (MutableInteractionSource?, IndicationNodeFactory?) -> Modifier,\n): Modifier {\n    return this.then(\n        when {\n            // Fast path - indication is managed internally\n            indication is IndicationNodeFactory -> createClickable(interactionSource, indication)\n            // Fast path - no need for indication\n            indication == null -> createClickable(interactionSource, null)\n            // Non-null Indication (not IndicationNodeFactory) with a non-null InteractionSource\n            interactionSource != null ->\n                Modifier.indication(interactionSource, indication)\n                    .then(createClickable(interactionSource, null))\n            // Non-null Indication (not IndicationNodeFactory) with a null InteractionSource, so we\n            // need\n            // to use composed to create an InteractionSource that can be shared. This should be a\n            // rare\n            // code path and can only be hit from new callers.\n            else ->\n                Modifier.composed {\n                    val newInteractionSource = remember { MutableInteractionSource() }\n                    Modifier.indication(newInteractionSource, indication)\n                        .then(createClickable(newInteractionSource, null))\n                }\n        }\n    )\n}\n\n/**\n * How long to wait before appearing 'pressed' (emitting [PressInteraction.Press]) - if a touch down\n * will quickly become a drag / scroll, this timeout means that we don't show a press effect.\n */\ninternal expect val TapIndicationDelay: Long\n\n/**\n * Returns whether the root Compose layout node is hosted in a scrollable container outside of\n * Compose. On Android this will be whether the root View is in a scrollable ViewGroup, as even if\n * nothing in the Compose part of the hierarchy is scrollable, if the View itself is in a scrollable\n * container, we still want to delay presses in case presses in Compose convert to a scroll outside\n * of Compose.\n *\n * Combine this with [hasScrollableContainer], which returns whether a [Modifier] is within a\n * scrollable Compose layout, to calculate whether this modifier is within some form of scrollable\n * container, and hence should delay presses.\n */\ninternal expect fun DelegatableNode.isComposeRootInScrollableContainer(): Boolean\n\n/**\n * Whether the specified [KeyEvent] should trigger a press for a clickable component, i.e. whether\n * it is associated with a press of an enter key or dpad centre.\n */\nprivate val KeyEvent.isPress: Boolean\n    get() = type == KeyDown && isEnter\n\n/**\n * Whether the specified [KeyEvent] should trigger a click for a clickable component, i.e. whether\n * it is associated with a release of an enter key or dpad centre.\n */\nprivate val KeyEvent.isClick: Boolean\n    get() = type == KeyUp && isEnter\n\nprivate val KeyEvent.isEnter: Boolean\n    get() =\n        when (key) {\n            Key.DirectionCenter,\n            Key.Enter,\n            Key.NumPadEnter,\n            Key.Spacebar -> true\n\n            else -> false\n        }\n\nprivate class ClickableElement(\n    private val interactionSource: MutableInteractionSource?,\n    private val indicationNodeFactory: IndicationNodeFactory?,\n    private val useLocalIndication: Boolean,\n    private val enabled: Boolean,\n    private val onClickLabel: String?,\n    private val role: Role?,\n    private val onClick: () -> Unit,\n) : ModifierNodeElement<ClickableNode>() {\n    override fun create() =\n        ClickableNode(\n            interactionSource = interactionSource,\n            indicationNodeFactory = indicationNodeFactory,\n            useLocalIndication = useLocalIndication,\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            role = role,\n            onClick = onClick,\n        )\n\n    override fun update(node: ClickableNode) {\n        node.update(\n            interactionSource = interactionSource,\n            indicationNodeFactory = indicationNodeFactory,\n            useLocalIndication = useLocalIndication,\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            role = role,\n            onClick = onClick,\n        )\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"clickable\"\n        properties[\"enabled\"] = enabled\n        properties[\"onClick\"] = onClick\n        properties[\"onClickLabel\"] = onClickLabel\n        properties[\"role\"] = role\n        properties[\"interactionSource\"] = interactionSource\n        properties[\"indicationNodeFactory\"] = indicationNodeFactory\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other === null) return false\n        if (this::class != other::class) return false\n\n        other as ClickableElement\n\n        if (interactionSource != other.interactionSource) return false\n        if (indicationNodeFactory != other.indicationNodeFactory) return false\n        if (useLocalIndication != other.useLocalIndication) return false\n        if (enabled != other.enabled) return false\n        if (onClickLabel != other.onClickLabel) return false\n        if (role != other.role) return false\n        if (onClick !== other.onClick) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = (interactionSource?.hashCode() ?: 0)\n        result = 31 * result + (indicationNodeFactory?.hashCode() ?: 0)\n        result = 31 * result + useLocalIndication.hashCode()\n        result = 31 * result + enabled.hashCode()\n        result = 31 * result + (onClickLabel?.hashCode() ?: 0)\n        result = 31 * result + (role?.hashCode() ?: 0)\n        result = 31 * result + onClick.hashCode()\n        return result\n    }\n}\n\nprivate class CombinedClickableElement(\n    private val interactionSource: MutableInteractionSource?,\n    private val indicationNodeFactory: IndicationNodeFactory?,\n    private val useLocalIndication: Boolean,\n    private val enabled: Boolean,\n    private val onClickLabel: String?,\n    private val role: Role?,\n    private val onClick: () -> Unit,\n    private val onLongClickLabel: String?,\n    private val onLongClick: (() -> Unit)?,\n    private val onDoubleClick: (() -> Unit)?,\n    private val hapticFeedbackEnabled: Boolean,\n) : ModifierNodeElement<CombinedClickableNode>() {\n    override fun create() =\n        CombinedClickableNode(\n            onClick = onClick,\n            onLongClickLabel = onLongClickLabel,\n            onLongClick = onLongClick,\n            onDoubleClick = onDoubleClick,\n            hapticFeedbackEnabled = hapticFeedbackEnabled,\n            interactionSource = interactionSource,\n            indicationNodeFactory = indicationNodeFactory,\n            useLocalIndication = useLocalIndication,\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            role = role,\n        )\n\n    override fun update(node: CombinedClickableNode) {\n        node.hapticFeedbackEnabled = hapticFeedbackEnabled\n        node.update(\n            onClick,\n            onLongClickLabel,\n            onLongClick,\n            onDoubleClick,\n            interactionSource,\n            indicationNodeFactory,\n            useLocalIndication,\n            enabled,\n            onClickLabel,\n            role,\n        )\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"combinedClickable\"\n        properties[\"indicationNodeFactory\"] = indicationNodeFactory\n        properties[\"interactionSource\"] = interactionSource\n        properties[\"enabled\"] = enabled\n        properties[\"onClickLabel\"] = onClickLabel\n        properties[\"role\"] = role\n        properties[\"onClick\"] = onClick\n        properties[\"onDoubleClick\"] = onDoubleClick\n        properties[\"onLongClick\"] = onLongClick\n        properties[\"onLongClickLabel\"] = onLongClickLabel\n        properties[\"hapticFeedbackEnabled\"] = hapticFeedbackEnabled\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other === null) return false\n        if (this::class != other::class) return false\n\n        other as CombinedClickableElement\n\n        if (interactionSource != other.interactionSource) return false\n        if (indicationNodeFactory != other.indicationNodeFactory) return false\n        if (useLocalIndication != other.useLocalIndication) return false\n        if (enabled != other.enabled) return false\n        if (onClickLabel != other.onClickLabel) return false\n        if (role != other.role) return false\n        if (onClick !== other.onClick) return false\n        if (onLongClickLabel != other.onLongClickLabel) return false\n        if (onLongClick !== other.onLongClick) return false\n        if (onDoubleClick !== other.onDoubleClick) return false\n        if (hapticFeedbackEnabled != other.hapticFeedbackEnabled) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = (interactionSource?.hashCode() ?: 0)\n        result = 31 * result + (indicationNodeFactory?.hashCode() ?: 0)\n        result = 31 * result + useLocalIndication.hashCode()\n        result = 31 * result + enabled.hashCode()\n        result = 31 * result + (onClickLabel?.hashCode() ?: 0)\n        result = 31 * result + (role?.hashCode() ?: 0)\n        result = 31 * result + onClick.hashCode()\n        result = 31 * result + (onLongClickLabel?.hashCode() ?: 0)\n        result = 31 * result + (onLongClick?.hashCode() ?: 0)\n        result = 31 * result + (onDoubleClick?.hashCode() ?: 0)\n        result = 31 * result + hapticFeedbackEnabled.hashCode()\n        return result\n    }\n}\n\ninternal open class ClickableNode(\n    interactionSource: MutableInteractionSource?,\n    indicationNodeFactory: IndicationNodeFactory?,\n    useLocalIndication: Boolean,\n    enabled: Boolean,\n    onClickLabel: String?,\n    role: Role?,\n    onClick: () -> Unit,\n) :\n    AbstractClickableNode(\n        interactionSource = interactionSource,\n        indicationNodeFactory = indicationNodeFactory,\n        useLocalIndication = useLocalIndication,\n        enabled = enabled,\n        onClickLabel = onClickLabel,\n        role = role,\n        onClick = onClick,\n    ) {\n\n    private var downEvent: PointerInputChange? = null\n    private var indirectDownEvent: IndirectPointerInputChange? = null\n\n    @OptIn(ExperimentalFoundationApi::class)\n    override fun onPointerEvent(\n        pointerEvent: PointerEvent,\n        pass: PointerEventPass,\n        bounds: IntSize,\n    ) {\n        super.onPointerEvent(pointerEvent, pass, bounds)\n        if (pass == PointerEventPass.Main) {\n            if (downEvent == null) {\n                if (pointerEvent.isChangedToDown(requireUnconsumed = true)) {\n                    handleDownEvent(pointerEvent.changes[0])\n                }\n            } else {\n                if (pointerEvent.changes.fastAll { it.changedToUp() }) {\n                    // All pointers are up\n                    handleUpEvent(pointerEvent.changes[0])\n                } else {\n                    // Other events need to be checked for consumption / bounds related\n                    // cancellation.\n                    handleNonUpEventIfNeeded(pointerEvent, bounds)\n                }\n            }\n        } else if (pass == PointerEventPass.Final) {\n            checkForCancellation(pointerEvent)\n        }\n    }\n\n    override fun onIndirectPointerEvent(event: IndirectPointerEvent, pass: PointerEventPass) {\n        super.onIndirectPointerEvent(event, pass)\n        if (pass == PointerEventPass.Main) {\n            if (indirectDownEvent == null) {\n                if (event.changes.fastAny { it.changedToDownIgnoreConsumed() }) {\n                    handleDownEvent(event.changes[0])\n                }\n            } else {\n                if (event.changes.fastAll { it.changedToUp() }) {\n                    // All pointers are up\n                    handleUpEvent(event.changes[0])\n                } else {\n                    // Other events need to be checked for consumption / exceeding touch slop\n                    handleNonUpEventIfNeeded(event)\n                }\n            }\n        } else if (pass == PointerEventPass.Final) {\n            checkForCancellation(event)\n        }\n    }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    private fun handleDownEvent(down: PointerInputChange) {\n        down.consume()\n        this.downEvent = down\n        if (enabled) {\n            if (isDelayPressesUsingGestureConsumptionEnabled) {\n                handlePressInteractionStart(down)\n            } else {\n                handlePressInteractionStart(down.position, false)\n            }\n        }\n    }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    private fun handleDownEvent(down: IndirectPointerInputChange) {\n        down.consume()\n        this.indirectDownEvent = down\n        if (enabled) {\n            if (isDelayPressesUsingGestureConsumptionEnabled) {\n                handlePressInteractionStart(down)\n            } else {\n                handlePressInteractionStart(down.position, true)\n            }\n        }\n    }\n\n    private fun handleUpEvent(up: PointerInputChange) {\n        up.consume()\n        if (enabled) {\n            handlePressInteractionRelease(downEvent!!.position, indirectPointer = false)\n            onClick()\n        }\n        this.downEvent = null\n    }\n\n    private fun handleUpEvent(up: IndirectPointerInputChange) {\n        up.consume()\n        if (enabled) {\n            handlePressInteractionRelease(indirectDownEvent!!.position, indirectPointer = true)\n            onClick()\n        }\n        this.indirectDownEvent = null\n    }\n\n    private fun handleNonUpEventIfNeeded(pointerEvent: PointerEvent, bounds: IntSize) {\n        val touchPadding = getExtendedTouchPadding(bounds)\n        if (\n            pointerEvent.changes.fastAny { it.isConsumed || it.isOutOfBounds(bounds, touchPadding) }\n        ) {\n            cancelInput(indirectPointer = false)\n        }\n    }\n\n    private fun handleNonUpEventIfNeeded(indirectPointerEvent: IndirectPointerEvent) {\n        val touchSlop = currentValueOf(LocalViewConfiguration).touchSlop\n        if (\n            indirectPointerEvent.changes.fastAny {\n                val distanceFromPress = it.position - indirectDownEvent!!.position\n                val isOutOfBounds = abs(distanceFromPress.getDistance()) > touchSlop\n                it.isConsumed || isOutOfBounds\n            }\n        ) {\n            cancelInput(indirectPointer = true)\n        }\n    }\n\n    private fun checkForCancellation(pointerEvent: PointerEvent) {\n        if (downEvent != null) {\n            // Check for cancel by position consumption. We can look on the Final pass of the\n            // existing pointer event because it comes after the pass we checked above.\n            if (pointerEvent.changes.fastAny { it.isConsumed && it != downEvent }) {\n                cancelInput(indirectPointer = false)\n            }\n        }\n    }\n\n    private fun checkForCancellation(indirectPointerEvent: IndirectPointerEvent) {\n        if (indirectDownEvent != null) {\n            // Check for cancel by position consumption. We can look on the Final pass of the\n            // existing pointer event because it comes after the pass we checked above.\n            if (indirectPointerEvent.changes.fastAny { it.isConsumed && it != indirectDownEvent }) {\n                cancelInput(indirectPointer = true)\n            }\n        }\n    }\n\n    override fun onCancelPointerInput() {\n        super.onCancelPointerInput()\n        cancelInput(indirectPointer = false)\n    }\n\n    override fun onCancelIndirectPointerInput() {\n        cancelInput(indirectPointer = true)\n    }\n\n    private fun cancelInput(indirectPointer: Boolean) {\n        // Don't cancel pointer events when cancelling indirect events (because of losing focus for\n        // example), and vice versa.\n        if (indirectPointer) {\n            indirectDownEvent = null\n        } else {\n            downEvent = null\n        }\n        handlePressInteractionCancel(indirectPointer = indirectPointer)\n    }\n\n    fun update(\n        interactionSource: MutableInteractionSource?,\n        indicationNodeFactory: IndicationNodeFactory?,\n        useLocalIndication: Boolean,\n        enabled: Boolean,\n        onClickLabel: String?,\n        role: Role?,\n        onClick: () -> Unit,\n    ) {\n        // enabled and onClick are captured inside callbacks, not as an input to detectTapGestures,\n        // so no need to reset pointer input handling when they change\n        updateCommon(\n            interactionSource = interactionSource,\n            indicationNodeFactory = indicationNodeFactory,\n            useLocalIndication = useLocalIndication,\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            role = role,\n            onClick = onClick,\n        )\n    }\n\n    final override fun onClickKeyDownEvent(event: KeyEvent) = false\n\n    final override fun onClickKeyUpEvent(event: KeyEvent): Boolean {\n        onClick()\n        return true\n    }\n}\n\nprivate class CombinedClickableNode(\n    onClick: () -> Unit,\n    private var onLongClickLabel: String?,\n    private var onLongClick: (() -> Unit)?,\n    private var onDoubleClick: (() -> Unit)?,\n    var hapticFeedbackEnabled: Boolean,\n    interactionSource: MutableInteractionSource?,\n    indicationNodeFactory: IndicationNodeFactory?,\n    useLocalIndication: Boolean,\n    enabled: Boolean,\n    onClickLabel: String?,\n    role: Role?,\n) :\n    CompositionLocalConsumerModifierNode,\n    AbstractClickableNode(\n        interactionSource = interactionSource,\n        indicationNodeFactory = indicationNodeFactory,\n        useLocalIndication = useLocalIndication,\n        enabled = enabled,\n        onClickLabel = onClickLabel,\n        role = role,\n        onClick = onClick,\n    ) {\n    class DoubleKeyClickState(val job: Job) {\n        var doubleTapMinTimeMillisElapsed: Boolean = false\n    }\n\n    private val longKeyPressJobs = mutableLongObjectMapOf<Job>()\n    private val doubleKeyClickStates = mutableLongObjectMapOf<DoubleKeyClickState>()\n    @OptIn(ExperimentalFoundationApi::class)\n    private val isSuspendingPointerInputEnabled =\n        !ComposeFoundationFlags.isNonSuspendingPointerInputInCombinedClickableEnabled\n    private var downEvent: PointerInputChange? = null\n    private var longPressJob: Job? = null\n    private var tapJob: Job? = null\n    private var isSecondTap = false\n    private var longPressTriggered = false\n    private var firstTapUpTime = -1L\n    private var ignoreNextUp = false\n\n    private var indirectDownEvent: IndirectPointerInputChange? = null\n    private var indirectLongPressJob: Job? = null\n    private var indirectTapJob: Job? = null\n    private var indirectIsSecondTap = false\n    private var indirectLongPressTriggered = false\n    private var indirectFirstTapUpTime = -1L\n    private var indirectIgnoreNextUp = false\n\n    override fun createPointerInputNodeIfNeeded(): SuspendingPointerInputModifierNode? {\n        if (isSuspendingPointerInputEnabled) {\n            return SuspendingPointerInputModifierNode {\n                detectTapGestures(\n                    onDoubleTap =\n                        if (enabled && onDoubleClick != null) {\n                            { onDoubleClick?.invoke() }\n                        } else null,\n                    onLongPress =\n                        if (enabled && onLongClick != null) {\n                            {\n                                onLongClick?.invoke()\n                                if (hapticFeedbackEnabled) {\n                                    currentValueOf(LocalHapticFeedback)\n                                        .performHapticFeedback(HapticFeedbackType.LongPress)\n                                }\n                            }\n                        } else null,\n                    onPress = { offset ->\n                        if (enabled) {\n                            handlePressInteraction(offset)\n                        }\n                    },\n                    onTap = {\n                        if (enabled) {\n                            onClick()\n                        }\n                    },\n                )\n            }\n        }\n        return null\n    }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    override fun onPointerEvent(\n        pointerEvent: PointerEvent,\n        pass: PointerEventPass,\n        bounds: IntSize,\n    ) {\n        super.onPointerEvent(pointerEvent, pass, bounds)\n        if (isSuspendingPointerInputEnabled) return\n\n        if (pass == PointerEventPass.Main) {\n            if (downEvent == null) {\n                if (pointerEvent.isChangedToDown(requireUnconsumed = true)) {\n                    handleDownEvent(pointerEvent.changes[0])\n                }\n            } else {\n                if (pointerEvent.isDeepPress) {\n                    handleDeepPress()\n                }\n\n                if (longPressTriggered) {\n                    // This branch specifically handles the case where the long press callback has\n                    // already been invoked.\n                    if (pointerEvent.changes.fastAll { it.changedToUpIgnoreConsumed() }) {\n                        // A long press already fired its callback and all the pointers are up. We\n                        // must reset our state even if the up event was already consumed by a\n                        // child.\n                        val up = pointerEvent.changes[0]\n                        up.consume()\n                        handleUpEvent(uptimeMillis = up.uptimeMillis, downChange = downEvent!!)\n                    } else {\n                        // Once a long press has triggered, consume every event until pointers are\n                        // up.\n                        pointerEvent.changes.fastForEach { it.consume() }\n                    }\n                    return\n                }\n\n                if (pointerEvent.changes.fastAll { it.changedToUp() }) {\n                    // All pointers are up\n                    val up = pointerEvent.changes[0]\n                    up.consume()\n                    handleUpEvent(uptimeMillis = up.uptimeMillis, downChange = downEvent!!)\n                } else {\n                    // Other events need to be checked for consumption / bounds related\n                    // cancellation.\n                    handleNonUpEventIfNeeded(pointerEvent, bounds)\n                }\n            }\n        } else if (pass == PointerEventPass.Final) {\n            checkForCancellation(pointerEvent)\n        }\n    }\n\n    override fun onIndirectPointerEvent(event: IndirectPointerEvent, pass: PointerEventPass) {\n        super.onIndirectPointerEvent(event, pass)\n        if (pass == PointerEventPass.Main) {\n            if (indirectDownEvent == null) {\n                if (event.changes.fastAny { it.changedToDownIgnoreConsumed() }) {\n                    handleDownEvent(event.changes[0])\n                }\n            } else {\n                if (indirectLongPressTriggered) {\n                    // This branch specifically handles the case where the long press callback has\n                    // already been invoked.\n                    if (event.changes.fastAll { it.changedToUpIgnoreConsumed() }) {\n                        // A long press already fired its callback and all the pointers are up. We\n                        // must reset our state even if the up event was already consumed by a\n                        // child.\n                        val up = event.changes[0]\n                        up.consume()\n                        handleUpEvent(\n                            uptimeMillis = up.uptimeMillis,\n                            downChange = indirectDownEvent!!,\n                        )\n                    } else {\n                        // Once a long press has triggered, consume every event until pointers are\n                        // up\n                        event.changes.fastForEach { it.consume() }\n                    }\n                    return\n                }\n\n                if (event.changes.fastAll { it.changedToUp() }) {\n                    // All pointers are up\n                    val up = event.changes[0]\n                    up.consume()\n                    handleUpEvent(uptimeMillis = up.uptimeMillis, downChange = indirectDownEvent!!)\n                } else {\n                    // Other events need to be checked for consumption / exceeding touch slop\n                    handleNonUpEventIfNeeded(event)\n                }\n            }\n        } else if (pass == PointerEventPass.Final) {\n            checkForCancellation(event)\n        }\n    }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    private fun handleDownEvent(down: PointerInputChange) {\n        down.consume()\n        this.downEvent = down\n\n        if (enabled) {\n            if (tapJob?.isActive == true) {\n                val minTime = currentValueOf(LocalViewConfiguration).doubleTapMinTimeMillis\n                if (down.uptimeMillis - firstTapUpTime < minTime) {\n                    ignoreNextUp = true\n                    // Ignore this down event, don't check for long press / emit press\n                    // interactions\n                    return\n                } else {\n                    isSecondTap = true\n                    tapJob?.cancel()\n                    tapJob = null\n                }\n            }\n            longPressTriggered = false\n\n            if (isDelayPressesUsingGestureConsumptionEnabled) {\n                handlePressInteractionStart(down)\n            } else {\n                handlePressInteractionStart(down.position, false)\n            }\n\n            if (onLongClick != null) {\n                longPressJob =\n                    coroutineScope.launch {\n                        delay(currentValueOf(LocalViewConfiguration).longPressTimeoutMillis)\n                        onLongClick?.invoke()\n                        if (hapticFeedbackEnabled) {\n                            currentValueOf(LocalHapticFeedback)\n                                .performHapticFeedback(HapticFeedbackType.LongPress)\n                        }\n                        longPressTriggered = true\n                        tapJob?.cancel()\n                        tapJob = null\n                        longPressJob = null\n                    }\n            }\n        }\n    }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    private fun handleDownEvent(down: IndirectPointerInputChange) {\n        down.consume()\n        this.indirectDownEvent = down\n\n        if (enabled) {\n            if (indirectTapJob?.isActive == true) {\n                val minTime = currentValueOf(LocalViewConfiguration).doubleTapMinTimeMillis\n                if (down.uptimeMillis - indirectFirstTapUpTime < minTime) {\n                    indirectIgnoreNextUp = true\n                    // Ignore this down event, don't check for long press / emit press\n                    // interactions\n                    return\n                } else {\n                    indirectIsSecondTap = true\n                    indirectTapJob?.cancel()\n                    indirectTapJob = null\n                }\n            }\n            indirectLongPressTriggered = false\n\n            if (isDelayPressesUsingGestureConsumptionEnabled) {\n                handlePressInteractionStart(down)\n            } else {\n                handlePressInteractionStart(down.position, true)\n            }\n\n            if (onLongClick != null) {\n                indirectLongPressJob =\n                    coroutineScope.launch {\n                        delay(currentValueOf(LocalViewConfiguration).longPressTimeoutMillis)\n                        onLongClick?.invoke()\n                        if (hapticFeedbackEnabled) {\n                            currentValueOf(LocalHapticFeedback)\n                                .performHapticFeedback(HapticFeedbackType.LongPress)\n                        }\n                        indirectLongPressTriggered = true\n                        indirectTapJob?.cancel()\n                        indirectTapJob = null\n                        indirectLongPressJob = null\n                    }\n            }\n        }\n    }\n\n    private fun handleUpEvent(uptimeMillis: Long, downChange: PointerInputChange) {\n        if (enabled && !ignoreNextUp) {\n            handlePressInteractionRelease(downChange.position, indirectPointer = false)\n            firstTapUpTime = uptimeMillis // store uptime for double tap check\n            if (!longPressTriggered) {\n                if (isSecondTap) {\n                    onDoubleClick?.invoke()\n                } else {\n                    if (onDoubleClick != null) {\n                        tapJob =\n                            coroutineScope.launch {\n                                delay(currentValueOf(LocalViewConfiguration).doubleTapTimeoutMillis)\n                                onClick()\n                                tapJob = null\n                            }\n                    } else {\n                        onClick()\n                    }\n                }\n            }\n        }\n        this.downEvent = null\n        ignoreNextUp = false\n        isSecondTap = false\n        longPressJob?.cancel()\n        longPressJob = null\n        longPressTriggered = false\n    }\n\n    private fun handleUpEvent(uptimeMillis: Long, downChange: IndirectPointerInputChange) {\n        if (enabled && !indirectIgnoreNextUp) {\n            handlePressInteractionRelease(downChange.position, indirectPointer = true)\n            indirectFirstTapUpTime = uptimeMillis // store uptime for double tap check\n            if (!indirectLongPressTriggered) {\n                if (indirectIsSecondTap) {\n                    onDoubleClick?.invoke()\n                } else {\n                    if (onDoubleClick != null) {\n                        indirectTapJob =\n                            coroutineScope.launch {\n                                delay(currentValueOf(LocalViewConfiguration).doubleTapTimeoutMillis)\n                                onClick()\n                                indirectTapJob = null\n                            }\n                    } else {\n                        onClick()\n                    }\n                }\n            }\n        }\n        this.indirectDownEvent = null\n        indirectIgnoreNextUp = false\n        indirectIsSecondTap = false\n        indirectLongPressJob?.cancel()\n        indirectLongPressJob = null\n        indirectLongPressTriggered = false\n    }\n\n    private fun handleNonUpEventIfNeeded(pointerEvent: PointerEvent, bounds: IntSize) {\n        val touchPadding = getExtendedTouchPadding(bounds)\n        if (\n            pointerEvent.changes.fastAny { change ->\n                change.isConsumed || change.isOutOfBounds(bounds, touchPadding)\n            }\n        ) {\n            cancelInput(indirectPointer = false)\n        }\n    }\n\n    private fun handleNonUpEventIfNeeded(indirectPointerEvent: IndirectPointerEvent) {\n        val touchSlop = currentValueOf(LocalViewConfiguration).touchSlop\n        if (\n            indirectPointerEvent.changes.fastAny { change ->\n                val distanceFromPress = change.position - indirectDownEvent!!.position\n                val isOutOfBounds = abs(distanceFromPress.getDistance()) > touchSlop\n                change.isConsumed || isOutOfBounds\n            }\n        ) {\n            cancelInput(indirectPointer = true)\n        }\n    }\n\n    private fun handleDeepPress() {\n        if (!longPressTriggered && enabled && onLongClick != null) {\n            longPressJob?.cancel()\n            longPressJob = null\n            onLongClick?.invoke()\n            if (hapticFeedbackEnabled) {\n                currentValueOf(LocalHapticFeedback)\n                    .performHapticFeedback(HapticFeedbackType.LongPress)\n            }\n            longPressTriggered = true\n        }\n    }\n\n    private fun checkForCancellation(pointerEvent: PointerEvent) {\n        if (downEvent != null && !longPressTriggered) {\n            // Check for cancel by position consumption. We can look on the Final pass of the\n            // existing pointer event because it comes after the pass we checked above. We ignore\n            // cases where the long press has already triggered, as in this case we will consume\n            // events ourselves until the pointer is released.\n            if (pointerEvent.changes.fastAny { it.isConsumed && it != downEvent }) {\n                // Canceled\n                cancelInput(indirectPointer = false)\n            }\n        }\n    }\n\n    private fun checkForCancellation(indirectPointerEvent: IndirectPointerEvent) {\n        if (indirectDownEvent != null && !indirectLongPressTriggered) {\n            // Check for cancel by position consumption. We can look on the Final pass of the\n            // existing pointer event because it comes after the pass we checked above. We ignore\n            // cases where the long press has already triggered, as in this case we will consume\n            // events ourselves until the pointer is released.\n            if (indirectPointerEvent.changes.fastAny { it.isConsumed && it != indirectDownEvent }) {\n                // Canceled\n                cancelInput(indirectPointer = true)\n            }\n        }\n    }\n\n    override fun onCancelPointerInput() {\n        super.onCancelPointerInput()\n        cancelInput(indirectPointer = false)\n    }\n\n    override fun onCancelIndirectPointerInput() {\n        cancelInput(indirectPointer = true)\n    }\n\n    private fun cancelInput(indirectPointer: Boolean) {\n        if (indirectPointer) {\n            indirectDownEvent = null\n            indirectLongPressJob?.cancel()\n            indirectLongPressJob = null\n            indirectTapJob?.cancel()\n            indirectTapJob = null\n            indirectIsSecondTap = false\n            indirectLongPressTriggered = false\n            indirectFirstTapUpTime = -1L\n            indirectIgnoreNextUp = false\n        } else {\n            downEvent = null\n            longPressJob?.cancel()\n            longPressJob = null\n            tapJob?.cancel()\n            tapJob = null\n            isSecondTap = false\n            longPressTriggered = false\n            firstTapUpTime = -1L\n            ignoreNextUp = false\n        }\n        handlePressInteractionCancel(indirectPointer)\n    }\n\n    fun update(\n        onClick: () -> Unit,\n        onLongClickLabel: String?,\n        onLongClick: (() -> Unit)?,\n        onDoubleClick: (() -> Unit)?,\n        interactionSource: MutableInteractionSource?,\n        indicationNodeFactory: IndicationNodeFactory?,\n        useLocalIndication: Boolean,\n        enabled: Boolean,\n        onClickLabel: String?,\n        role: Role?,\n    ) {\n        var resetPointerInputHandling = false\n\n        // onClick is captured inside a callback, not as an input to detectTapGestures,\n        // so no need to reset pointer input handling\n\n        if (this.onLongClickLabel != onLongClickLabel) {\n            this.onLongClickLabel = onLongClickLabel\n            invalidateSemantics()\n        }\n\n        // We capture onLongClick and onDoubleClick inside the callback, so if the lambda changes\n        // value we don't want to reset input handling - only reset if they go from not-defined to\n        // defined, and vice versa, as that is what is captured in the parameter to\n        // detectTapGestures.\n        if ((this.onLongClick == null) != (onLongClick == null)) {\n            // Adding or removing longClick should cancel any existing press interactions\n            disposeInteractions()\n            // Adding or removing longClick should add / remove the corresponding property\n            invalidateSemantics()\n            resetPointerInputHandling = true\n        }\n\n        this.onLongClick = onLongClick\n\n        if ((this.onDoubleClick == null) != (onDoubleClick == null)) {\n            resetPointerInputHandling = true\n        }\n        this.onDoubleClick = onDoubleClick\n\n        // enabled is captured as a parameter to detectTapGestures, so we need to restart detecting\n        // gestures if it changes.\n        if (this.enabled != enabled) {\n            resetPointerInputHandling = true\n            // Updating is handled inside updateCommon\n        }\n\n        updateCommon(\n            interactionSource = interactionSource,\n            indicationNodeFactory = indicationNodeFactory,\n            useLocalIndication = useLocalIndication,\n            enabled = enabled,\n            onClickLabel = onClickLabel,\n            role = role,\n            onClick = onClick,\n        )\n\n        if (resetPointerInputHandling) {\n            resetPointerInputHandler()\n            cancelInput(indirectPointer = false)\n            cancelInput(indirectPointer = true)\n        }\n    }\n\n    override fun SemanticsPropertyReceiver.applyAdditionalSemantics() {\n        if (onLongClick != null) {\n            onLongClick(\n                action = {\n                    onLongClick?.invoke()\n                    true\n                },\n                label = onLongClickLabel,\n            )\n        }\n    }\n\n    override fun onClickKeyDownEvent(event: KeyEvent): Boolean {\n        val keyCode = event.key.keyCode\n        var handledByLongClick = false\n        if (onLongClick != null) {\n            if (longKeyPressJobs[keyCode] == null) {\n                longKeyPressJobs[keyCode] =\n                    coroutineScope.launch {\n                        delay(currentValueOf(LocalViewConfiguration).longPressTimeoutMillis)\n                        onLongClick?.invoke()\n                    }\n                handledByLongClick = true\n            }\n        }\n        val doubleClickState = doubleKeyClickStates[keyCode]\n        // This is the second down event, so it might be a double click\n        if (doubleClickState != null) {\n            // Within the allowed timeout, so check if this is above the minimum time needed for\n            // a double click\n            if (doubleClickState.job.isActive) {\n                doubleClickState.job.cancel()\n                // If the second down was before the minimum double tap time, don't track this as\n                // a double click. Instead, we need to invoke onClick for the previous click, since\n                // that is now counted as a standalone click instead of the first of a double click.\n                if (!doubleClickState.doubleTapMinTimeMillisElapsed) {\n                    onClick()\n                    doubleKeyClickStates.remove(keyCode)\n                }\n            } else {\n                // We already invoked onClick because we passed the timeout, so stop tracking this\n                // as a double click\n                doubleKeyClickStates.remove(keyCode)\n            }\n        }\n        return handledByLongClick\n    }\n\n    override fun onClickKeyUpEvent(event: KeyEvent): Boolean {\n        val keyCode = event.key.keyCode\n        var longClickInvoked = false\n        if (longKeyPressJobs[keyCode] != null) {\n            longKeyPressJobs[keyCode]?.let {\n                if (it.isActive) {\n                    it.cancel()\n                } else {\n                    // If we already passed the timeout, we invoked long click already, and so\n                    // we shouldn't invoke onClick in this case\n                    longClickInvoked = true\n                }\n            }\n            longKeyPressJobs.remove(keyCode)\n        }\n        if (onDoubleClick != null) {\n            when {\n                // First click\n                doubleKeyClickStates[keyCode] == null -> {\n                    // We only track the second click if the first click was not a long click\n                    if (!longClickInvoked) {\n                        doubleKeyClickStates[keyCode] =\n                            DoubleKeyClickState(\n                                coroutineScope.launch {\n                                    val configuration = currentValueOf(LocalViewConfiguration)\n                                    val minTime = configuration.doubleTapMinTimeMillis\n                                    val timeout = configuration.doubleTapTimeoutMillis\n                                    delay(minTime)\n                                    doubleKeyClickStates[keyCode]?.doubleTapMinTimeMillisElapsed =\n                                        true\n                                    // Delay the remainder until we are at timeout\n                                    delay(timeout - minTime)\n                                    // If there was no second key press after the timeout, invoke\n                                    // onClick as normal\n                                    onClick()\n                                }\n                            )\n                    }\n                }\n                // Second click\n                else -> {\n                    // Invoke onDoubleClick if the second click was not a long click\n                    if (!longClickInvoked) {\n                        onDoubleClick?.invoke()\n                    }\n                    doubleKeyClickStates.remove(keyCode)\n                }\n            }\n        } else {\n            if (!longClickInvoked) {\n                onClick()\n            }\n        }\n        return true\n    }\n\n    override fun onCancelKeyInput() {\n        resetKeyPressState()\n    }\n\n    override fun onReset() {\n        super.onReset()\n        resetKeyPressState()\n    }\n\n    private fun resetKeyPressState() {\n        longKeyPressJobs.apply {\n            forEachValue { it.cancel() }\n            clear()\n        }\n        doubleKeyClickStates.apply {\n            forEachValue { it.job.cancel() }\n            clear()\n        }\n    }\n}\n\ninternal abstract class AbstractClickableNode(\n    private var interactionSource: MutableInteractionSource?,\n    private var indicationNodeFactory: IndicationNodeFactory?,\n    private var useLocalIndication: Boolean,\n    enabled: Boolean,\n    private var onClickLabel: String?,\n    private var role: Role?,\n    onClick: () -> Unit,\n) :\n    DelegatingNode(),\n    PointerInputModifierNode,\n    KeyInputModifierNode,\n    SemanticsModifierNode,\n    TraversableNode,\n    CompositionLocalConsumerModifierNode,\n    ObserverModifierNode,\n    IndirectPointerInputModifierNode,\n    GestureConnection {\n    protected var enabled = enabled\n        private set\n\n    protected var onClick = onClick\n        private set\n\n    final override val shouldAutoInvalidate: Boolean = false\n\n    private val focusableNode: FocusableNode =\n        FocusableNode(\n            interactionSource,\n            focusability = Focusability.SystemDefined,\n            onFocusChange = ::onFocusChange,\n        )\n\n    private var localIndicationNodeFactory: IndicationNodeFactory? = null\n\n    private var pointerInputNode: SuspendingPointerInputModifierNode? = null\n    private var gestureNode: DelegatableNode? = null\n    private var indicationNode: DelegatableNode? = null\n\n    private var pressInteraction: PressInteraction.Press? = null\n    private var hoverInteraction: HoverInteraction.Enter? = null\n    private val currentKeyPressInteractions = mutableLongObjectMapOf<PressInteraction.Press>()\n    private var centerOffset: Offset = Offset.Zero\n\n    private var indirectPointerPressInteraction: PressInteraction.Press? = null\n    private var indirectPointerEventPressPosition: Offset? = null\n\n    // Track separately from interactionSource, as we will create our own internal\n    // InteractionSource if needed\n    private var userProvidedInteractionSource: MutableInteractionSource? = interactionSource\n\n    private var lazilyCreateIndication = shouldLazilyCreateIndication()\n\n    private fun shouldLazilyCreateIndication() = userProvidedInteractionSource == null\n\n    /**\n     * Handles subclass-specific click related pointer input logic. Hover is already handled\n     * elsewhere, so this should only handle clicks.\n     *\n     * TODO(b/477836055) Migrate to non-suspending API.\n     */\n    open fun createPointerInputNodeIfNeeded(): SuspendingPointerInputModifierNode? = null\n\n    open fun SemanticsPropertyReceiver.applyAdditionalSemantics() {}\n\n    protected fun updateCommon(\n        interactionSource: MutableInteractionSource?,\n        indicationNodeFactory: IndicationNodeFactory?,\n        useLocalIndication: Boolean,\n        enabled: Boolean,\n        onClickLabel: String?,\n        role: Role?,\n        onClick: () -> Unit,\n    ) {\n        var isIndicationNodeDirty = false\n        // Compare against userProvidedInteractionSource, as we will create a new InteractionSource\n        // lazily if the userProvidedInteractionSource is null, and assign it to interactionSource\n        if (userProvidedInteractionSource != interactionSource) {\n            disposeInteractions()\n            userProvidedInteractionSource = interactionSource\n            this.interactionSource = interactionSource\n            isIndicationNodeDirty = true\n        }\n        if (this.indicationNodeFactory != indicationNodeFactory) {\n            this.indicationNodeFactory = indicationNodeFactory\n            isIndicationNodeDirty = true\n        }\n        if (this.useLocalIndication != useLocalIndication) {\n            this.useLocalIndication = useLocalIndication\n            if (useLocalIndication) {\n                // Need to update localIndicationNodeFactory, and start observing changes\n                onObservedReadsChanged()\n            }\n            isIndicationNodeDirty = true\n        }\n        if (this.enabled != enabled) {\n            if (enabled) {\n                delegate(focusableNode)\n            } else {\n                // TODO: Should we remove indicationNode? Previously we always emitted indication\n                undelegate(focusableNode)\n                disposeInteractions()\n            }\n            invalidateSemantics()\n            this.enabled = enabled\n        }\n        if (this.onClickLabel != onClickLabel) {\n            this.onClickLabel = onClickLabel\n            invalidateSemantics()\n        }\n        if (this.role != role) {\n            this.role = role\n            invalidateSemantics()\n        }\n        this.onClick = onClick\n        if (lazilyCreateIndication != shouldLazilyCreateIndication()) {\n            lazilyCreateIndication = shouldLazilyCreateIndication()\n            // If we are no longer lazily creating the node, and we haven't created the node yet,\n            // create it\n            if (!lazilyCreateIndication && indicationNode == null) isIndicationNodeDirty = true\n        }\n        // Create / recreate indication node\n        if (isIndicationNodeDirty) {\n            recreateIndicationIfNeeded()\n        }\n        focusableNode.update(this.interactionSource)\n    }\n\n    protected fun getExtendedTouchPadding(size: IntSize): Size {\n        // copied from SuspendingPointerInputModifierNodeImpl.extendedTouchPadding:\n        // TODO expose this as a new public api available outside of suspending apis b/422396609\n        val minimumTouchTargetSizeDp = currentValueOf(LocalViewConfiguration).minimumTouchTargetSize\n        val minimumTouchTargetSize = with(requireDensity()) { minimumTouchTargetSizeDp.toSize() }\n        val horizontal = max(0f, minimumTouchTargetSize.width - size.width) / 2f\n        val vertical = max(0f, minimumTouchTargetSize.height - size.height) / 2f\n        return Size(horizontal, vertical)\n    }\n\n    override fun onIndirectPointerEvent(event: IndirectPointerEvent, pass: PointerEventPass) {\n        initializeIndicationAndInteractionSourceIfNeeded()\n        if (enabled) {\n            initializeGestureCoordination()\n        }\n    }\n\n    final override fun onAttach() {\n        onObservedReadsChanged()\n        if (!lazilyCreateIndication) {\n            initializeIndicationAndInteractionSourceIfNeeded()\n        }\n        if (enabled) {\n            delegate(focusableNode)\n        }\n    }\n\n    override fun onObservedReadsChanged() {\n        if (useLocalIndication) {\n            observeReads {\n                val indication = currentValueOf(LocalIndication)\n                requirePrecondition(indication is IndicationNodeFactory) {\n                    unsupportedIndicationExceptionMessage(indication)\n                }\n                val previousFactory = localIndicationNodeFactory\n                localIndicationNodeFactory = indication\n                // If we are changing from a non-null factory to a different factory, recreate\n                // indication if needed\n                if (previousFactory != null && localIndicationNodeFactory != previousFactory) {\n                    recreateIndicationIfNeeded()\n                }\n            }\n        }\n    }\n\n    final override fun onDetach() {\n        disposeInteractions()\n        // If we lazily created an interaction source, reset it in case we are reused / moved. Note\n        // that we need to do it here instead of onReset() - since onReset won't be called in the\n        // movableContent case but we still want to dispose for that case\n        if (userProvidedInteractionSource == null) {\n            interactionSource = null\n        }\n        // Remove indication in case we are reused / moved - we will create a new node when needed\n        indicationNode?.let { undelegate(it) }\n        indicationNode = null\n\n        gestureNode?.let { undelegate(it) }\n        gestureNode = null\n    }\n\n    protected fun disposeInteractions() {\n        interactionSource?.let { interactionSource ->\n            pressInteraction?.let { oldValue ->\n                val interaction = PressInteraction.Cancel(oldValue)\n                interactionSource.tryEmit(interaction)\n            }\n            indirectPointerPressInteraction?.let { oldValue ->\n                val interaction = PressInteraction.Cancel(oldValue)\n                interactionSource.tryEmit(interaction)\n            }\n            hoverInteraction?.let { oldValue ->\n                val interaction = HoverInteraction.Exit(oldValue)\n                interactionSource.tryEmit(interaction)\n            }\n            currentKeyPressInteractions.forEachValue {\n                interactionSource.tryEmit(PressInteraction.Cancel(it))\n            }\n        }\n        pressInteraction = null\n        indirectPointerPressInteraction = null\n        indirectPointerEventPressPosition = null\n        hoverInteraction = null\n        currentKeyPressInteractions.clear()\n    }\n\n    private fun onFocusChange(isFocused: Boolean) {\n        if (isFocused) {\n            initializeIndicationAndInteractionSourceIfNeeded()\n        } else {\n            // If we are no longer focused while we are tracking existing key presses, we need to\n            // clear them and cancel the presses.\n            if (interactionSource != null) {\n                currentKeyPressInteractions.forEachValue {\n                    coroutineScope.launch { interactionSource?.emit(PressInteraction.Cancel(it)) }\n                }\n                indirectPointerPressInteraction?.let {\n                    coroutineScope.launch { interactionSource?.emit(PressInteraction.Cancel(it)) }\n                }\n            }\n            currentKeyPressInteractions.clear()\n            indirectPointerPressInteraction = null\n            onCancelKeyInput()\n        }\n    }\n\n    private fun recreateIndicationIfNeeded() {\n        // If we already created a node lazily, or we are not lazily creating the node, create\n        if (indicationNode != null || !lazilyCreateIndication) {\n            indicationNode?.let { undelegate(it) }\n            indicationNode = null\n            initializeIndicationAndInteractionSourceIfNeeded()\n        }\n    }\n\n    private fun initializeIndicationAndInteractionSourceIfNeeded() {\n        // We have already created the node, no need to do any work\n        if (indicationNode != null) return\n        val indicationFactory =\n            if (useLocalIndication) localIndicationNodeFactory else indicationNodeFactory\n        indicationFactory?.let { factory ->\n            if (interactionSource == null) {\n                interactionSource = MutableInteractionSource()\n            }\n            focusableNode.update(interactionSource)\n            val node = factory.create(interactionSource!!)\n            delegate(node)\n            indicationNode = node\n        }\n    }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    private fun initializeGestureCoordination() {\n        if (!isDelayPressesUsingGestureConsumptionEnabled) return\n        if (gestureNode == null) {\n            gestureNode = delegate(gestureNode(this))\n        }\n    }\n\n    override fun onPointerEvent(\n        pointerEvent: PointerEvent,\n        pass: PointerEventPass,\n        bounds: IntSize,\n    ) {\n        centerOffset = bounds.center.toOffset()\n        initializeIndicationAndInteractionSourceIfNeeded()\n        if (enabled) {\n            initializeGestureCoordination()\n            if (pass == PointerEventPass.Main) {\n                when (pointerEvent.type) {\n                    PointerEventType.Enter -> coroutineScope.launch { emitHoverEnter() }\n                    PointerEventType.Exit -> coroutineScope.launch { emitHoverExit() }\n                }\n            }\n        }\n        if (pointerInputNode == null) {\n            val node = createPointerInputNodeIfNeeded()\n            if (node != null) {\n                pointerInputNode = delegate(node)\n            }\n        }\n        pointerInputNode?.onPointerEvent(pointerEvent, pass, bounds)\n    }\n\n    override fun onCancelPointerInput() {\n        // Press cancellation is handled as part of detecting presses\n        interactionSource?.let { interactionSource ->\n            hoverInteraction?.let { oldValue ->\n                val interaction = HoverInteraction.Exit(oldValue)\n                interactionSource.tryEmit(interaction)\n            }\n        }\n        hoverInteraction = null\n        pointerInputNode?.onCancelPointerInput()\n    }\n\n    final override fun onKeyEvent(event: KeyEvent): Boolean {\n        // Key events usually require focus, but if a focused child does not handle the KeyEvent,\n        // the event can bubble up without this clickable ever being focused, and hence without\n        // this being initialized through the focus path\n        initializeIndicationAndInteractionSourceIfNeeded()\n        val keyCode = event.key.keyCode\n        return when {\n            enabled && event.isPress -> {\n                // If the key already exists in the map, keyEvent is a repeat event.\n                // We ignore it as we only want to emit an interaction for the initial key press.\n                var wasInteractionHandled = false\n                if (!currentKeyPressInteractions.containsKey(keyCode)) {\n                    val press = PressInteraction.Press(centerOffset)\n                    currentKeyPressInteractions[keyCode] = press\n                    // Even if the interactionSource is null, we still want to intercept the presses\n                    // so we always track them above, and return true\n                    if (interactionSource != null) {\n                        coroutineScope.launch { interactionSource?.emit(press) }\n                    }\n                    wasInteractionHandled = true\n                }\n                onClickKeyDownEvent(event) || wasInteractionHandled\n            }\n\n            enabled && event.isClick -> {\n                val press = currentKeyPressInteractions.remove(keyCode)\n                if (press != null) {\n                    if (interactionSource != null) {\n                        coroutineScope.launch {\n                            interactionSource?.emit(PressInteraction.Release(press))\n                        }\n                    }\n                    // Don't invoke onClick if we were not pressed - this could happen if we became\n                    // focused after the down event, or if the node was reused after the down event.\n                    onClickKeyUpEvent(event)\n                }\n                // Only consume if we were previously pressed for this key event\n                press != null\n            }\n\n            else -> false\n        }\n    }\n\n    protected abstract fun onClickKeyDownEvent(event: KeyEvent): Boolean\n\n    protected abstract fun onClickKeyUpEvent(event: KeyEvent): Boolean\n\n    /**\n     * Called when focus is lost, to allow cleaning up and resetting the state for ongoing key\n     * presses\n     */\n    protected open fun onCancelKeyInput() {}\n\n    final override fun onPreKeyEvent(event: KeyEvent) = false\n\n    final override val shouldMergeDescendantSemantics: Boolean\n        get() = true\n\n    final override fun SemanticsPropertyReceiver.applySemantics() {\n        if (this@AbstractClickableNode.role != null) {\n            role = this@AbstractClickableNode.role!!\n        }\n        onClick(\n            action = {\n                onClick()\n                true\n            },\n            label = onClickLabel,\n        )\n        if (enabled) {\n            with(focusableNode) { applySemantics() }\n        } else {\n            disabled()\n        }\n        applyAdditionalSemantics()\n    }\n\n    protected fun resetPointerInputHandler() = pointerInputNode?.resetPointerInputHandler()\n\n    private var delayJob: Job? = null\n\n    /** Handles emitting a [PressInteraction.Press]. */\n    protected fun handlePressInteractionStart(event: IndirectPointerInputChange) {\n        interactionSource?.let { interactionSource ->\n            val press = PressInteraction.Press(event.position)\n            if (delayPressInteraction(event)) {\n                delayJob =\n                    coroutineScope.launch {\n                        delay(TapIndicationDelay)\n                        interactionSource.emit(press)\n                        indirectPointerPressInteraction = press\n                    }\n            } else {\n                indirectPointerPressInteraction = press\n                coroutineScope.launch { interactionSource.emit(press) }\n            }\n        }\n    }\n\n    protected fun handlePressInteractionStart(event: PointerInputChange) {\n        interactionSource?.let { interactionSource ->\n            val press = PressInteraction.Press(event.position)\n            if (delayPressInteraction(event)) {\n                delayJob =\n                    coroutineScope.launch {\n                        delay(TapIndicationDelay)\n                        interactionSource.emit(press)\n                        pressInteraction = press\n                    }\n            } else {\n                pressInteraction = press\n                coroutineScope.launch { interactionSource.emit(press) }\n            }\n        }\n    }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    protected fun handlePressInteractionStart(offset: Offset, indirectPointer: Boolean) {\n        interactionSource?.let { interactionSource ->\n            val press = PressInteraction.Press(offset)\n            val shouldDelayPress =\n                if (isDelayPressesUsingGestureConsumptionEnabled) {\n                    delayPressInteraction(null)\n                } else {\n                    delayPressInteraction()\n                }\n            if (shouldDelayPress) {\n                delayJob =\n                    coroutineScope.launch {\n                        delay(TapIndicationDelay)\n                        interactionSource.emit(press)\n                        if (indirectPointer) {\n                            indirectPointerPressInteraction = press\n                        } else {\n                            pressInteraction = press\n                        }\n                    }\n            } else {\n                if (indirectPointer) {\n                    indirectPointerPressInteraction = press\n                } else {\n                    pressInteraction = press\n                }\n                coroutineScope.launch { interactionSource.emit(press) }\n            }\n        }\n    }\n\n    /**\n     * Handles emitting a [PressInteraction.Release].\n     *\n     * @param offset offset of the press\n     * @param indirectPointer whether the source of this press was indirect pointer. False for\n     *   pointer input.\n     */\n    protected fun handlePressInteractionRelease(offset: Offset, indirectPointer: Boolean) {\n        interactionSource?.let { interactionSource ->\n            // To resolve b/414319919 it is important that we capture a reference to `delayJob`\n            // outside the coroutine block - when the CPU is busy we can end up handling\n            // press-release-press before the coroutine starts to execute, which means we can launch\n            // two jobs and mutate delayJob twice. At the time this function is called, delayJob\n            // points to the correct corresponding press event, so we just reference this instance\n            // to make sure that there is no issue if coroutines are executed after the next set of\n            // gestures have been processed.\n            val job = delayJob\n            if (job?.isActive == true) {\n                // Immediately cancel the job to avoid a race condition from coroutine launching -\n                // if we wait until inside the launch to cancel it could be executed after the job\n                // is no longer active. An alternative approach would be to launch with\n                // start = CoroutineStart.UNDISPATCHED, but it is more reasonable to cancel\n                // outside the coroutine in any case.\n                job.cancel()\n                coroutineScope.launch {\n                    // Wait for cancelling the job to finish if needed\n                    job.join()\n                    // The press released successfully, before the timeout duration - emit the press\n                    // interaction instantly.\n                    val press = PressInteraction.Press(offset)\n                    val release = PressInteraction.Release(press)\n                    interactionSource.emit(press)\n                    interactionSource.emit(release)\n                }\n            } else {\n                val interaction =\n                    if (indirectPointer) indirectPointerPressInteraction else pressInteraction\n                interaction?.let {\n                    coroutineScope.launch {\n                        // Important that we capture `interaction` outside the `launch`, rather than\n                        // referring to it in here - the underlying fields are mutable and could\n                        // change by the time this coroutine is executed\n                        val endInteraction = PressInteraction.Release(it)\n                        interactionSource.emit(endInteraction)\n                    }\n                }\n            }\n            if (indirectPointer) {\n                indirectPointerPressInteraction = null\n            } else {\n                pressInteraction = null\n            }\n        }\n    }\n\n    /**\n     * Handles emitting a [PressInteraction.Cancel].\n     *\n     * @param indirectPointer whether the source of this press was indirect pointer. False for\n     *   pointer input.\n     */\n    protected fun handlePressInteractionCancel(indirectPointer: Boolean) {\n        interactionSource?.let { interactionSource ->\n            if (delayJob?.isActive == true) {\n                // We didn't finish sending the press, and we are cancelled, so we don't emit\n                // any interaction.\n                delayJob?.cancel()\n            } else {\n                val interaction =\n                    if (indirectPointer) indirectPointerPressInteraction else pressInteraction\n                interaction?.let {\n                    val endInteraction = PressInteraction.Cancel(it)\n                    // If this is being called from inside onDetach(), we are still attached, but\n                    // the scope will be cancelled soon after - so the launch {} might not even\n                    // start before it is cancelled. We don't want to use\n                    // CoroutineStart.UNDISPATCHED, or always call tryEmit() as this will break\n                    // other timing / cause some events to be missed for other cases. Instead just\n                    // make sure we call tryEmit if we cancel the scope, before we finish emitting.\n                    val handler =\n                        coroutineScope.coroutineContext[Job]?.invokeOnCompletion {\n                            interactionSource.tryEmit(endInteraction)\n                        }\n                    coroutineScope.launch {\n                        interactionSource.emit(endInteraction)\n                        handler?.dispose()\n                    }\n                }\n            }\n            if (indirectPointer) {\n                indirectPointerPressInteraction = null\n            } else {\n                pressInteraction = null\n            }\n        }\n    }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    protected suspend fun PressGestureScope.handlePressInteraction(offset: Offset) {\n        interactionSource?.let { interactionSource ->\n            coroutineScope {\n                val delayJob = launch {\n                    val shouldDelayPress =\n                        if (isDelayPressesUsingGestureConsumptionEnabled) {\n                            delayPressInteraction(null)\n                        } else {\n                            delayPressInteraction()\n                        }\n                    if (shouldDelayPress) {\n                        delay(TapIndicationDelay)\n                    }\n                    val press = PressInteraction.Press(offset)\n                    interactionSource.emit(press)\n                    pressInteraction = press\n                }\n                val success = tryAwaitRelease()\n                if (delayJob.isActive) {\n                    delayJob.cancelAndJoin()\n                    // The press released successfully, before the timeout duration - emit the press\n                    // interaction instantly. No else branch - if the press was cancelled before the\n                    // timeout, we don't want to emit a press interaction.\n                    if (success) {\n                        val press = PressInteraction.Press(offset)\n                        val release = PressInteraction.Release(press)\n                        interactionSource.emit(press)\n                        interactionSource.emit(release)\n                    }\n                } else {\n                    pressInteraction?.let { pressInteraction ->\n                        val endInteraction =\n                            if (success) {\n                                PressInteraction.Release(pressInteraction)\n                            } else {\n                                PressInteraction.Cancel(pressInteraction)\n                            }\n                        interactionSource.emit(endInteraction)\n                    }\n                }\n                pressInteraction = null\n            }\n        }\n    }\n\n    private fun delayPressInteraction(): Boolean =\n        hasScrollableContainer() || isComposeRootInScrollableContainer()\n\n    private fun delayPressInteraction(event: PointerInputChange?): Boolean {\n        val hasInterestedParent =\n            if (event == null) {\n                parentGestureConnection != null\n            } else {\n                hasInterestedParent(event)\n            }\n        return hasInterestedParent || isComposeRootInScrollableContainer()\n    }\n\n    private fun delayPressInteraction(event: IndirectPointerInputChange): Boolean =\n        hasInterestedParent(event) || isComposeRootInScrollableContainer()\n\n    private fun emitHoverEnter() {\n        if (hoverInteraction == null) {\n            val interaction = HoverInteraction.Enter()\n            interactionSource?.let { interactionSource ->\n                coroutineScope.launch { interactionSource.emit(interaction) }\n            }\n            hoverInteraction = interaction\n        }\n    }\n\n    private fun emitHoverExit() {\n        hoverInteraction?.let { oldValue ->\n            val interaction = HoverInteraction.Exit(oldValue)\n            interactionSource?.let { interactionSource ->\n                coroutineScope.launch { interactionSource.emit(interaction) }\n            }\n            hoverInteraction = null\n        }\n    }\n\n    override val traverseKey: Any = TraverseKey\n\n    companion object TraverseKey\n}\n\ninternal fun DelegatingNode.hasInterestedParent(event: IndirectPointerInputChange): Boolean {\n    var hasInterestedParent = false\n    traverseAncestorGestureConnections { coordinator ->\n        val isCoordinatorInterested = coordinator.isInterested(event)\n        hasInterestedParent = hasInterestedParent || isCoordinatorInterested\n        !hasInterestedParent\n    }\n    return hasInterestedParent\n}\n\ninternal fun DelegatingNode.hasInterestedParent(event: PointerInputChange): Boolean {\n    var hasInterestedParent = false\n    traverseAncestorGestureConnections { coordinator ->\n        val isCoordinatorInterested = coordinator.isInterested(event)\n        hasInterestedParent = hasInterestedParent || isCoordinatorInterested\n        !hasInterestedParent\n    }\n    return hasInterestedParent\n}\n\ninternal fun TraversableNode.hasScrollableContainer(): Boolean {\n    var hasScrollable = false\n    traverseAncestors(ScrollableContainerNode.TraverseKey) { node ->\n        hasScrollable = hasScrollable || (node as ScrollableContainerNode).enabled\n        !hasScrollable\n    }\n    return hasScrollable\n}\n\nprivate fun unsupportedIndicationExceptionMessage(indication: Indication): String {\n    return \"clickable only supports IndicationNodeFactory instances provided to LocalIndication, \" +\n        \"but Indication was provided instead. Either migrate the Indication implementation to \" +\n        \"implement IndicationNodeFactory, or use the other clickable overload that takes an \" +\n        \"Indication parameter, and explicitly pass LocalIndication.current there. The Indication\" +\n        \" instance provided here was: $indication\"\n}\n\nprivate fun IndirectPointerInputChange.changedToUp() = !isConsumed && previousPressed && !pressed\n\nprivate fun IndirectPointerInputChange.changedToUpIgnoreConsumed() = previousPressed && !pressed\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyList.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.lazy\n\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.OverscrollEffect\nimport androidx.compose.foundation.checkScrollableContainerConstraints\nimport androidx.compose.foundation.gestures.FlingBehavior\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.internal.requirePreconditionNotNull\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.lazy.layout.CacheWindowLogic\nimport androidx.compose.foundation.lazy.layout.LazyLayout\nimport androidx.compose.foundation.lazy.layout.LazyLayoutMeasurePolicy\nimport androidx.compose.foundation.lazy.layout.StickyItemsPlacement\nimport androidx.compose.foundation.lazy.layout.calculateLazyLayoutPinnedIndices\nimport androidx.compose.foundation.lazy.layout.lazyLayoutBeyondBoundsModifier\nimport androidx.compose.foundation.lazy.layout.lazyLayoutSemantics\nimport androidx.compose.foundation.scrollableArea\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.snapshots.Snapshot\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.GraphicsContext\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.platform.LocalGraphicsContext\nimport androidx.compose.ui.platform.LocalScrollCaptureInProgress\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.constrainHeight\nimport androidx.compose.ui.unit.constrainWidth\nimport androidx.compose.ui.unit.offset\nimport androidx.compose.ui.util.trace\nimport kotlinx.coroutines.CoroutineScope\n\n@OptIn(ExperimentalFoundationApi::class)\n@Composable\ninternal fun LazyList(\n    /** Modifier to be applied for the inner layout */\n    modifier: Modifier,\n    /** State controlling the scroll position */\n    state: LazyListState,\n    /** The inner padding to be added for the whole content(not for each individual item) */\n    contentPadding: PaddingValues,\n    /** reverse the direction of scrolling and layout */\n    reverseLayout: Boolean,\n    /** The layout orientation of the list */\n    isVertical: Boolean,\n    /** fling behavior to be used for flinging */\n    flingBehavior: FlingBehavior,\n    /** Whether scrolling via the user gestures is allowed. */\n    userScrollEnabled: Boolean,\n    /** The overscroll effect to render and dispatch events to */\n    overscrollEffect: OverscrollEffect?,\n    /** Number of items to layout before and after the visible items */\n    beyondBoundsItemCount: Int = defaultLazyListBeyondBoundsItemCount(),\n    /** The alignment to align items horizontally. Required when isVertical is true */\n    horizontalAlignment: Alignment.Horizontal? = null,\n    /** The vertical arrangement for items. Required when isVertical is true */\n    verticalArrangement: Arrangement.Vertical? = null,\n    /** The alignment to align items vertically. Required when isVertical is false */\n    verticalAlignment: Alignment.Vertical? = null,\n    /** The horizontal arrangement for items. Required when isVertical is false */\n    horizontalArrangement: Arrangement.Horizontal? = null,\n    /** The content of the list */\n    content: LazyListScope.() -> Unit,\n) {\n    val itemProviderLambda = rememberLazyListItemProviderLambda(state, content)\n\n    val semanticState = rememberLazyListSemanticState(state, isVertical)\n    val coroutineScope = rememberCoroutineScope()\n    val graphicsContext = LocalGraphicsContext.current\n    val stickyHeadersEnabled = !LocalScrollCaptureInProgress.current\n\n    val measurePolicy =\n        rememberLazyListMeasurePolicy(\n            itemProviderLambda,\n            state,\n            contentPadding,\n            reverseLayout,\n            isVertical,\n            beyondBoundsItemCount,\n            horizontalAlignment,\n            verticalAlignment,\n            horizontalArrangement,\n            verticalArrangement,\n            coroutineScope,\n            graphicsContext,\n            if (stickyHeadersEnabled) StickyItemsPlacement.StickToTopPlacement else null,\n        )\n\n    val orientation = if (isVertical) Orientation.Vertical else Orientation.Horizontal\n\n    val beyondBoundsModifier =\n        if (userScrollEnabled) {\n            Modifier.lazyLayoutBeyondBoundsModifier(\n                state =\n                    rememberLazyListBeyondBoundsState(\n                        state = state,\n                        beyondBoundsItemCount = beyondBoundsItemCount,\n                    ),\n                beyondBoundsInfo = state.beyondBoundsInfo,\n                reverseLayout = reverseLayout,\n                orientation = orientation,\n            )\n        } else {\n            Modifier\n        }\n\n    LazyLayout(\n        modifier =\n            modifier\n                .then(state.remeasurementModifier)\n                .then(state.awaitLayoutModifier)\n                .lazyLayoutSemantics(\n                    itemProviderLambda = itemProviderLambda,\n                    state = semanticState,\n                    orientation = orientation,\n                    userScrollEnabled = userScrollEnabled,\n                    reverseScrolling = reverseLayout,\n                )\n                .then(beyondBoundsModifier)\n                .then(state.itemAnimator.modifier)\n                .scrollableArea(\n                    state = state,\n                    orientation = orientation,\n                    enabled = userScrollEnabled,\n                    reverseScrolling = reverseLayout,\n                    flingBehavior = flingBehavior,\n                    interactionSource = state.internalInteractionSource,\n                    overscrollEffect = overscrollEffect,\n                ),\n        prefetchState = state.prefetchState,\n        measurePolicy = measurePolicy,\n        itemProvider = itemProviderLambda,\n    )\n}\n\n@ExperimentalFoundationApi\n@Composable\nprivate fun rememberLazyListMeasurePolicy(\n    /** Items provider of the list. */\n    itemProviderLambda: () -> LazyListItemProvider,\n    /** The state of the list. */\n    state: LazyListState,\n    /** The inner padding to be added for the whole content(nor for each individual item) */\n    contentPadding: PaddingValues,\n    /** reverse the direction of scrolling and layout */\n    reverseLayout: Boolean,\n    /** The layout orientation of the list */\n    isVertical: Boolean,\n    /** Number of items to layout before and after the visible items */\n    beyondBoundsItemCount: Int,\n    /** The alignment to align items horizontally */\n    horizontalAlignment: Alignment.Horizontal?,\n    /** The alignment to align items vertically */\n    verticalAlignment: Alignment.Vertical?,\n    /** The horizontal arrangement for items */\n    horizontalArrangement: Arrangement.Horizontal?,\n    /** The vertical arrangement for items */\n    verticalArrangement: Arrangement.Vertical?,\n    /** Scope for animations */\n    coroutineScope: CoroutineScope,\n    /** Used for creating graphics layers */\n    graphicsContext: GraphicsContext,\n    /** Scroll behavior for sticky items */\n    stickyItemsPlacement: StickyItemsPlacement?,\n) =\n    remember(\n        state,\n        contentPadding,\n        reverseLayout,\n        isVertical,\n        beyondBoundsItemCount,\n        horizontalAlignment,\n        verticalAlignment,\n        horizontalArrangement,\n        verticalArrangement,\n        graphicsContext,\n        stickyItemsPlacement,\n    ) {\n        LazyLayoutMeasurePolicy { containerConstraints ->\n            state.measurementScopeInvalidator.attachToScope()\n            // Tracks if the lookahead pass has occurred\n            val hasLookaheadOccurred = state.hasLookaheadOccurred || isLookingAhead\n            checkScrollableContainerConstraints(\n                containerConstraints,\n                if (isVertical) Orientation.Vertical else Orientation.Horizontal,\n            )\n\n            // resolve content paddings\n            val startPadding =\n                if (isVertical) {\n                    contentPadding.calculateLeftPadding(layoutDirection).roundToPx()\n                } else {\n                    // in horizontal configuration, padding is reversed by placeRelative\n                    contentPadding.calculateStartPadding(layoutDirection).roundToPx()\n                }\n\n            val endPadding =\n                if (isVertical) {\n                    contentPadding.calculateRightPadding(layoutDirection).roundToPx()\n                } else {\n                    // in horizontal configuration, padding is reversed by placeRelative\n                    contentPadding.calculateEndPadding(layoutDirection).roundToPx()\n                }\n            val topPadding = contentPadding.calculateTopPadding().roundToPx()\n            val bottomPadding = contentPadding.calculateBottomPadding().roundToPx()\n            val totalVerticalPadding = topPadding + bottomPadding\n            val totalHorizontalPadding = startPadding + endPadding\n            val totalMainAxisPadding =\n                if (isVertical) totalVerticalPadding else totalHorizontalPadding\n            val beforeContentPadding =\n                when {\n                    isVertical && !reverseLayout -> topPadding\n                    isVertical && reverseLayout -> bottomPadding\n                    !isVertical && !reverseLayout -> startPadding\n                    else -> endPadding // !isVertical && reverseLayout\n                }\n            val afterContentPadding = totalMainAxisPadding - beforeContentPadding\n            val contentConstraints =\n                containerConstraints.offset(-totalHorizontalPadding, -totalVerticalPadding)\n\n            val itemProvider = itemProviderLambda()\n            // this will update the scope used by the item composables\n            itemProvider.itemScope.setMaxSize(\n                width = contentConstraints.maxWidth,\n                height = contentConstraints.maxHeight,\n            )\n\n            val spaceBetweenItemsDp =\n                if (isVertical) {\n                    requirePreconditionNotNull(verticalArrangement) {\n                            \"null verticalArrangement when isVertical == true\"\n                        }\n                        .spacing\n                } else {\n                    requirePreconditionNotNull(horizontalArrangement) {\n                            \"null horizontalAlignment when isVertical == false\"\n                        }\n                        .spacing\n                }\n            val spaceBetweenItems = spaceBetweenItemsDp.roundToPx()\n\n            val itemsCount = itemProvider.itemCount\n\n            // can be negative if the content padding is larger than the max size from constraints\n            val mainAxisAvailableSize =\n                if (isVertical) {\n                    containerConstraints.maxHeight - totalVerticalPadding\n                } else {\n                    containerConstraints.maxWidth - totalHorizontalPadding\n                }\n            val visualItemOffset =\n                if (!reverseLayout || mainAxisAvailableSize > 0) {\n                    IntOffset(startPadding, topPadding)\n                } else {\n                    // When layout is reversed and paddings together take >100% of the available\n                    // space,\n                    // layout size is coerced to 0 when positioning. To take that space into\n                    // account,\n                    // we offset start padding by negative space between paddings.\n                    IntOffset(\n                        if (isVertical) startPadding else startPadding + mainAxisAvailableSize,\n                        if (isVertical) topPadding + mainAxisAvailableSize else topPadding,\n                    )\n                }\n\n            val measuredItemProvider =\n                object :\n                    LazyListMeasuredItemProvider(\n                        contentConstraints,\n                        isVertical,\n                        itemProvider,\n                        this,\n                    ) {\n                    override fun createItem(\n                        index: Int,\n                        key: Any,\n                        contentType: Any?,\n                        placeables: List<Placeable>,\n                        constraints: Constraints,\n                    ): LazyListMeasuredItem {\n                        // we add spaceBetweenItems as an extra spacing for all items apart from the\n                        // last one so\n                        // the lazy list measuring logic will take it into account.\n                        val spacing = if (index == itemsCount - 1) 0 else spaceBetweenItems\n                        return LazyListMeasuredItem(\n                            index = index,\n                            placeables = placeables,\n                            isVertical = isVertical,\n                            horizontalAlignment = horizontalAlignment,\n                            verticalAlignment = verticalAlignment,\n                            layoutDirection = layoutDirection,\n                            reverseLayout = reverseLayout,\n                            beforeContentPadding = beforeContentPadding,\n                            afterContentPadding = afterContentPadding,\n                            spacing = spacing,\n                            visualOffset = visualItemOffset,\n                            key = key,\n                            contentType = contentType,\n                            animator = state.itemAnimator,\n                            constraints = constraints,\n                        )\n                    }\n                }\n\n            val firstVisibleItemIndex: Int\n            val firstVisibleScrollOffset: Int\n            Snapshot.withoutReadObservation {\n                firstVisibleItemIndex =\n                    state.updateScrollPositionIfTheFirstItemWasMoved(\n                        itemProvider,\n                        state.firstVisibleItemIndex,\n                    )\n                firstVisibleScrollOffset = state.firstVisibleItemScrollOffset\n            }\n\n            val pinnedItems =\n                itemProvider.calculateLazyLayoutPinnedIndices(\n                    pinnedItemList = state.pinnedItems,\n                    beyondBoundsInfo = state.beyondBoundsInfo,\n                )\n\n            val scrollToBeConsumed =\n                if (isLookingAhead || !hasLookaheadOccurred) {\n                    state.scrollToBeConsumed\n                } else {\n                    state.scrollDeltaBetweenPasses\n                }\n\n            // todo: wrap with snapshot when b/341782245 is resolved\n            val measureResult =\n                measureLazyList(\n                    itemsCount = itemsCount,\n                    measuredItemProvider = measuredItemProvider,\n                    mainAxisAvailableSize = mainAxisAvailableSize,\n                    beforeContentPadding = beforeContentPadding,\n                    afterContentPadding = afterContentPadding,\n                    spaceBetweenItems = spaceBetweenItems,\n                    firstVisibleItemIndex = firstVisibleItemIndex,\n                    firstVisibleItemScrollOffset = firstVisibleScrollOffset,\n                    scrollToBeConsumed = scrollToBeConsumed,\n                    constraints = contentConstraints,\n                    isVertical = isVertical,\n                    verticalArrangement = verticalArrangement,\n                    horizontalArrangement = horizontalArrangement,\n                    reverseLayout = reverseLayout,\n                    density = this,\n                    itemAnimator = state.itemAnimator,\n                    beyondBoundsItemCount = beyondBoundsItemCount,\n                    pinnedItems = pinnedItems,\n                    hasLookaheadOccurred = hasLookaheadOccurred,\n                    isLookingAhead = isLookingAhead,\n                    coroutineScope = coroutineScope,\n                    placementScopeInvalidator = state.placementScopeInvalidator,\n                    graphicsContext = graphicsContext,\n                    stickyItemsPlacement = stickyItemsPlacement,\n                    layout = { width, height, placement ->\n                        layout(\n                            containerConstraints.constrainWidth(width + totalHorizontalPadding),\n                            containerConstraints.constrainHeight(height + totalVerticalPadding),\n                            emptyMap(),\n                            placement,\n                        )\n                    },\n                )\n\n            state.applyMeasureResult(measureResult, isLookingAhead)\n            // apply keep around after updating the strategy with measure result.\n            (state.prefetchStrategy as? CacheWindowLogic)?.keepAroundItems(\n                measureResult.visibleItemsInfo,\n                measuredItemProvider,\n            )\n            measureResult\n        }\n    }\n\n@OptIn(ExperimentalFoundationApi::class)\nprivate fun CacheWindowLogic.keepAroundItems(\n    visibleItemsList: List<LazyListMeasuredItem>,\n    measuredItemProvider: LazyListMeasuredItemProvider,\n) {\n    trace(\"compose:lazy:cache_window:keepAroundItems\") {\n        // only run if window and new layout info is available\n        if (hasValidBounds() && visibleItemsList.isNotEmpty()) {\n            val firstVisibleItemIndex = visibleItemsList.first().index\n            val lastVisibleItemIndex = visibleItemsList.last().index\n            // we must send a message in case of changing directions for items\n            // that were keep around and become prefetch forward\n            for (item in prefetchWindowStartLine..<firstVisibleItemIndex) {\n                measuredItemProvider.keepAround(item)\n            }\n\n            for (item in (lastVisibleItemIndex + 1)..prefetchWindowEndLine) {\n                measuredItemProvider.keepAround(item)\n            }\n        }\n    }\n}\n\n@Composable internal expect fun defaultLazyListBeyondBoundsItemCount(): Int\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListState.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.lazy\n\nimport androidx.annotation.IntRange as AndroidXIntRange\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.MutatePriority\nimport androidx.compose.foundation.ScrollIndicatorState\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.ScrollScope\nimport androidx.compose.foundation.gestures.ScrollableState\nimport androidx.compose.foundation.interaction.InteractionSource\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.internal.checkPrecondition\nimport androidx.compose.foundation.lazy.LazyListState.Companion.Saver\nimport androidx.compose.foundation.lazy.layout.AwaitFirstLayoutModifier\nimport androidx.compose.foundation.lazy.layout.CacheWindowLogic\nimport androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsInfo\nimport androidx.compose.foundation.lazy.layout.LazyLayoutCacheWindow\nimport androidx.compose.foundation.lazy.layout.LazyLayoutItemAnimator\nimport androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList\nimport androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState\nimport androidx.compose.foundation.lazy.layout.LazyLayoutScrollDeltaBetweenPasses\nimport androidx.compose.foundation.lazy.layout.ObservableScopeInvalidator\nimport androidx.compose.foundation.lazy.layout.animateScrollToItem\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.annotation.FrequentlyChangingValue\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.neverEqualPolicy\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.Saver\nimport androidx.compose.runtime.saveable.listSaver\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.snapshots.Snapshot\nimport androidx.compose.ui.layout.AlignmentLine\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.Remeasurement\nimport androidx.compose.ui.layout.RemeasurementModifier\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.util.fastRoundToInt\nimport androidx.compose.ui.util.traceValue\nimport kotlin.coroutines.EmptyCoroutineContext\nimport kotlin.math.abs\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.launch\n\n/**\n * Creates a [LazyListState] that is remembered across compositions.\n *\n * Changes to the provided initial values will **not** result in the state being recreated or\n * changed in any way if it has already been created.\n *\n * @param initialFirstVisibleItemIndex the initial value for [LazyListState.firstVisibleItemIndex]\n * @param initialFirstVisibleItemScrollOffset the initial value for\n *   [LazyListState.firstVisibleItemScrollOffset]\n */\n@Composable\nfun rememberLazyListState(\n    initialFirstVisibleItemIndex: Int = 0,\n    initialFirstVisibleItemScrollOffset: Int = 0,\n): LazyListState {\n    return rememberSaveable(saver = LazyListState.Saver) {\n        LazyListState(initialFirstVisibleItemIndex, initialFirstVisibleItemScrollOffset)\n    }\n}\n\n/**\n * Creates a [LazyListState] that is remembered across compositions.\n *\n * Changes to the provided initial values will **not** result in the state being recreated or\n * changed in any way if it has already been created.\n *\n * @param initialFirstVisibleItemIndex the initial value for [LazyListState.firstVisibleItemIndex]\n * @param initialFirstVisibleItemScrollOffset the initial value for\n *   [LazyListState.firstVisibleItemScrollOffset]\n * @param prefetchStrategy the [LazyListPrefetchStrategy] to use for prefetching content in this\n *   list\n */\n@ExperimentalFoundationApi\n@Composable\nfun rememberLazyListState(\n    initialFirstVisibleItemIndex: Int = 0,\n    initialFirstVisibleItemScrollOffset: Int = 0,\n    prefetchStrategy: LazyListPrefetchStrategy = remember { LazyListPrefetchStrategy() },\n): LazyListState {\n    return rememberSaveable(prefetchStrategy, saver = LazyListState.saver(prefetchStrategy)) {\n        LazyListState(\n            initialFirstVisibleItemIndex,\n            initialFirstVisibleItemScrollOffset,\n            prefetchStrategy,\n        )\n    }\n}\n\n/**\n * Creates a [LazyListState] that is remembered across compositions.\n *\n * Changes to the provided initial values will **not** result in the state being recreated or\n * changed in any way if it has already been created.\n *\n * @param cacheWindow specifies the size of the ahead and behind window to be used as per\n *   [LazyLayoutCacheWindow].\n * @param initialFirstVisibleItemIndex the initial value for [LazyListState.firstVisibleItemIndex]\n * @param initialFirstVisibleItemScrollOffset the initial value for\n *   [LazyListState.firstVisibleItemScrollOffset]\n */\n@ExperimentalFoundationApi\n@Composable\nfun rememberLazyListState(\n    cacheWindow: LazyLayoutCacheWindow,\n    initialFirstVisibleItemIndex: Int = 0,\n    initialFirstVisibleItemScrollOffset: Int = 0,\n): LazyListState {\n    return rememberSaveable(cacheWindow, saver = LazyListState.saver(cacheWindow)) {\n        LazyListState(\n            cacheWindow,\n            initialFirstVisibleItemIndex,\n            initialFirstVisibleItemScrollOffset,\n        )\n    }\n}\n\n/**\n * A state object that can be hoisted to control and observe scrolling.\n *\n * In most cases, this will be created via [rememberLazyListState].\n *\n * @param firstVisibleItemIndex the initial value for [LazyListState.firstVisibleItemIndex]\n * @param firstVisibleItemScrollOffset the initial value for\n *   [LazyListState.firstVisibleItemScrollOffset]\n * @param prefetchStrategy the [LazyListPrefetchStrategy] to use for prefetching content in this\n *   list\n */\n@OptIn(ExperimentalFoundationApi::class)\n@Stable\nclass LazyListState\n@ExperimentalFoundationApi\nconstructor(\n    firstVisibleItemIndex: Int = 0,\n    firstVisibleItemScrollOffset: Int = 0,\n    internal val prefetchStrategy: LazyListPrefetchStrategy = LazyListPrefetchStrategy(),\n) : ScrollableState {\n\n    /**\n     * @param cacheWindow specifies the size of the ahead and behind window to be used as per\n     *   [LazyLayoutCacheWindow].\n     * @param firstVisibleItemIndex the initial value for [LazyListState.firstVisibleItemIndex]\n     * @param firstVisibleItemScrollOffset the initial value for\n     *   [LazyListState.firstVisibleItemScrollOffset]\n     */\n    @ExperimentalFoundationApi\n    constructor(\n        cacheWindow: LazyLayoutCacheWindow,\n        firstVisibleItemIndex: Int = 0,\n        firstVisibleItemScrollOffset: Int = 0,\n    ) : this(\n        firstVisibleItemIndex,\n        firstVisibleItemScrollOffset,\n        LazyListCacheWindowStrategy(cacheWindow),\n    )\n\n    /**\n     * @param firstVisibleItemIndex the initial value for [LazyListState.firstVisibleItemIndex]\n     * @param firstVisibleItemScrollOffset the initial value for\n     *   [LazyListState.firstVisibleItemScrollOffset]\n     */\n    constructor(\n        firstVisibleItemIndex: Int = 0,\n        firstVisibleItemScrollOffset: Int = 0,\n    ) : this(firstVisibleItemIndex, firstVisibleItemScrollOffset, LazyListPrefetchStrategy())\n\n    internal var hasLookaheadOccurred: Boolean = false\n        private set\n\n    internal var approachLayoutInfo: LazyListMeasureResult? = null\n        private set\n\n    // always execute requests in high priority\n    private var executeRequestsInHighPriorityMode = false\n\n    /** The holder class for the current scroll position. */\n    private val scrollPosition =\n        LazyListScrollPosition(firstVisibleItemIndex, firstVisibleItemScrollOffset)\n\n    /**\n     * The index of the first item that is visible within the scrollable viewport area not including\n     * items in the content padding region. For the first visible item that includes items in the\n     * content padding please use [LazyListLayoutInfo.visibleItemsInfo].\n     *\n     * Note that this property is observable and if you use it in the composable function it will be\n     * recomposed on every change causing potential performance issues.\n     *\n     * If you want to run some side effects like sending an analytics event or updating a state\n     * based on this value consider using \"snapshotFlow\":\n     *\n     * @sample androidx.compose.foundation.samples.UsingListScrollPositionForSideEffectSample\n     *\n     * If you need to use it in the composition then consider wrapping the calculation into a\n     * derived state in order to only have recompositions when the derived value changes:\n     *\n     * @sample androidx.compose.foundation.samples.UsingListScrollPositionInCompositionSample\n     */\n    val firstVisibleItemIndex: Int\n        @FrequentlyChangingValue get() = scrollPosition.index\n\n    /**\n     * The scroll offset of the first visible item. Scrolling forward is positive - i.e., the amount\n     * that the item is offset backwards.\n     *\n     * Note that this property is observable and if you use it in the composable function it will be\n     * recomposed on every scroll causing potential performance issues.\n     *\n     * @see firstVisibleItemIndex for samples with the recommended usage patterns.\n     */\n    val firstVisibleItemScrollOffset: Int\n        @FrequentlyChangingValue get() = scrollPosition.scrollOffset\n\n    /** Backing state for [layoutInfo] */\n    private val layoutInfoState = mutableStateOf(EmptyLazyListMeasureResult, neverEqualPolicy())\n\n    /**\n     * The object of [LazyListLayoutInfo] calculated during the last layout pass. For example, you\n     * can use it to calculate what items are currently visible.\n     *\n     * Note that this property is observable and is updated after every scroll or remeasure. If you\n     * use it in the composable function it will be recomposed on every change causing potential\n     * performance issues including infinity recomposition loop. Therefore, avoid using it in the\n     * composition.\n     *\n     * If you want to run some side effects like sending an analytics event or updating a state\n     * based on this value consider using \"snapshotFlow\":\n     *\n     * @sample androidx.compose.foundation.samples.UsingListLayoutInfoForSideEffectSample\n     */\n    val layoutInfo: LazyListLayoutInfo\n        @FrequentlyChangingValue get() = layoutInfoState.value\n\n    /**\n     * [InteractionSource] that will be used to dispatch drag events when this list is being\n     * dragged. If you want to know whether the fling (or animated scroll) is in progress, use\n     * [isScrollInProgress].\n     */\n    val interactionSource: InteractionSource\n        get() = internalInteractionSource\n\n    internal val internalInteractionSource: MutableInteractionSource = MutableInteractionSource()\n\n    /**\n     * The amount of scroll to be consumed in the next layout pass. Scrolling forward is negative\n     * - that is, it is the amount that the items are offset in y\n     */\n    internal var scrollToBeConsumed = 0f\n        private set\n\n    internal val density: Density\n        get() = layoutInfoState.value.density\n\n    /**\n     * The ScrollableController instance. We keep it as we need to call stopAnimation on it once we\n     * reached the end of the list.\n     */\n    private val scrollableState = ScrollableState { -onScroll(-it) }\n\n    /** Only used for testing to confirm that we're not making too many measure passes */\n    /*@VisibleForTesting*/\n    internal var numMeasurePasses: Int = 0\n        private set\n\n    /** Only used for testing to disable prefetching when needed to test the main logic. */\n    /*@VisibleForTesting*/\n    internal var prefetchingEnabled: Boolean = true\n\n    /**\n     * The [Remeasurement] object associated with our layout. It allows us to remeasure\n     * synchronously during scroll.\n     */\n    internal var remeasurement: Remeasurement? = null\n        private set\n\n    /** The modifier which provides [remeasurement]. */\n    internal val remeasurementModifier =\n        object : RemeasurementModifier {\n            override fun onRemeasurementAvailable(remeasurement: Remeasurement) {\n                this@LazyListState.remeasurement = remeasurement\n            }\n        }\n\n    /**\n     * Provides a modifier which allows to delay some interactions (e.g. scroll) until layout is\n     * ready.\n     */\n    internal val awaitLayoutModifier = AwaitFirstLayoutModifier()\n\n    internal val itemAnimator = LazyLayoutItemAnimator<LazyListMeasuredItem>()\n\n    internal val beyondBoundsInfo = LazyLayoutBeyondBoundsInfo()\n\n    @Suppress(\"DEPRECATION\") // b/420551535\n    internal val prefetchState =\n        LazyLayoutPrefetchState(prefetchStrategy.prefetchScheduler) {\n            with(prefetchStrategy) {\n                onNestedPrefetch(Snapshot.withoutReadObservation { firstVisibleItemIndex })\n            }\n        }\n\n    private val prefetchScope: LazyListPrefetchScope =\n        object : LazyListPrefetchScope {\n            override fun schedulePrefetch(\n                index: Int,\n                onPrefetchFinished: (LazyListPrefetchResultScope.() -> Unit)?,\n            ): LazyLayoutPrefetchState.PrefetchHandle {\n                // Without read observation since this can be triggered from scroll - this will then\n                // cause us to recompose when the measure result changes. We don't care since the\n                // prefetch is best effort.\n                val lastMeasureResult = Snapshot.withoutReadObservation { layoutInfoState.value }\n                return prefetchState.schedulePrecompositionAndPremeasure(\n                    index,\n                    lastMeasureResult.childConstraints,\n                    executeRequestsInHighPriorityMode,\n                ) {\n                    if (onPrefetchFinished != null) {\n                        var mainAxisItemSize = 0\n                        repeat(placeablesCount) {\n                            mainAxisItemSize +=\n                                if (lastMeasureResult.orientation == Orientation.Vertical) {\n                                    getSize(it).height\n                                } else {\n                                    getSize(it).width\n                                }\n                        }\n\n                        onPrefetchFinished.invoke(\n                            LazyListPrefetchResultScopeImpl(index, mainAxisItemSize)\n                        )\n                    }\n                }\n            }\n        }\n\n    private val _scrollIndicatorState =\n        object : ScrollIndicatorState {\n            override val scrollOffset: Int\n                get() = calculateScrollOffset()\n\n            override val contentSize: Int\n                get() = layoutInfo.calculateContentSize()\n\n            override val viewportSize: Int\n                get() = layoutInfo.singleAxisViewportSize\n        }\n\n    private fun calculateScrollOffset(): Int {\n        return (layoutInfo.visibleItemsAverageSize() * firstVisibleItemIndex) +\n            firstVisibleItemScrollOffset\n    }\n\n    /** Stores currently pinned items which are always composed. */\n    internal val pinnedItems = LazyLayoutPinnedItemList()\n\n    internal val nearestRange: IntRange by scrollPosition.nearestRangeState\n\n    /**\n     * Instantly brings the item at [index] to the top of the viewport, offset by [scrollOffset]\n     * pixels.\n     *\n     * @param index the index to which to scroll. Must be non-negative.\n     * @param scrollOffset the offset that the item should end up after the scroll. Note that\n     *   positive offset refers to forward scroll, so in a top-to-bottom list, positive offset will\n     *   scroll the item further upward (taking it partly offscreen).\n     */\n    suspend fun scrollToItem(@AndroidXIntRange(from = 0) index: Int, scrollOffset: Int = 0) {\n        scroll { snapToItemIndexInternal(index, scrollOffset, forceRemeasure = true) }\n    }\n\n    internal val measurementScopeInvalidator = ObservableScopeInvalidator()\n\n    /**\n     * Requests the item at [index] to be at the start of the viewport during the next remeasure,\n     * offset by [scrollOffset], and schedules a remeasure.\n     *\n     * The scroll position will be updated to the requested position rather than maintain the index\n     * based on the first visible item key (when a data set change will also be applied during the\n     * next remeasure), but *only* for the next remeasure.\n     *\n     * Any scroll in progress will be cancelled.\n     *\n     * @param index the index to which to scroll. Must be non-negative.\n     * @param scrollOffset the offset that the item should end up after the scroll. Note that\n     *   positive offset refers to forward scroll, so in a top-to-bottom list, positive offset will\n     *   scroll the item further upward (taking it partly offscreen).\n     */\n    fun requestScrollToItem(@AndroidXIntRange(from = 0) index: Int, scrollOffset: Int = 0) {\n        // Cancel any scroll in progress.\n        if (isScrollInProgress) {\n            layoutInfoState.value.coroutineScope.launch { scroll {} }\n        }\n\n        snapToItemIndexInternal(index, scrollOffset, forceRemeasure = false)\n    }\n\n    /**\n     * Snaps to the requested scroll position. Synchronously executes remeasure if [forceRemeasure]\n     * is true, and schedules a remeasure if false.\n     */\n    internal fun snapToItemIndexInternal(index: Int, scrollOffset: Int, forceRemeasure: Boolean) {\n        val positionChanged =\n            scrollPosition.index != index || scrollPosition.scrollOffset != scrollOffset\n        // sometimes this method is called not to scroll, but to stay on the same index when\n        // the data changes, as by default we maintain the scroll position by key, not index.\n        // when this happens we don't need to reset the animations as from the user perspective\n        // we didn't scroll anywhere and if there is an offset change for an item, this change\n        // should be animated.\n        // however, when the request is to really scroll to a different position, we have to\n        // reset previously known item positions as we don't want offset changes to be animated.\n        // this offset should be considered as a scroll, not the placement change.\n        if (positionChanged) {\n            itemAnimator.reset()\n            // we changed positions, cancel existing requests and wait for the next scroll to\n            // refill the window\n            (prefetchStrategy as? CacheWindowLogic)?.resetStrategy()\n        }\n        scrollPosition.requestPositionAndForgetLastKnownKey(index, scrollOffset)\n\n        if (forceRemeasure) {\n            remeasurement?.forceRemeasure()\n        } else {\n            measurementScopeInvalidator.invalidateScope()\n        }\n    }\n\n    /**\n     * Call this function to take control of scrolling and gain the ability to send scroll events\n     * via [ScrollScope.scrollBy]. All actions that change the logical scroll position must be\n     * performed within a [scroll] block (even if they don't call any other methods on this object)\n     * in order to guarantee that mutual exclusion is enforced.\n     *\n     * If [scroll] is called from elsewhere, this will be canceled.\n     */\n    override suspend fun scroll(\n        scrollPriority: MutatePriority,\n        block: suspend ScrollScope.() -> Unit,\n    ) {\n        if (layoutInfoState.value === EmptyLazyListMeasureResult) {\n            awaitLayoutModifier.waitForFirstLayout()\n        }\n        scrollableState.scroll(scrollPriority, block)\n    }\n\n    override fun dispatchRawDelta(delta: Float): Float = scrollableState.dispatchRawDelta(delta)\n\n    override val isScrollInProgress: Boolean\n        get() = scrollableState.isScrollInProgress\n\n    override var canScrollForward: Boolean by mutableStateOf(false)\n        private set\n\n    override var canScrollBackward: Boolean by mutableStateOf(false)\n        private set\n\n    @get:Suppress(\"GetterSetterNames\")\n    override val lastScrolledForward: Boolean\n        get() = scrollableState.lastScrolledForward\n\n    @get:Suppress(\"GetterSetterNames\")\n    override val lastScrolledBackward: Boolean\n        get() = scrollableState.lastScrolledBackward\n\n    override val scrollIndicatorState: ScrollIndicatorState?\n        get() = _scrollIndicatorState\n\n    internal val placementScopeInvalidator = ObservableScopeInvalidator()\n\n    // TODO: Coroutine scrolling APIs will allow this to be private again once we have more\n    //  fine-grained control over scrolling\n    /*@VisibleForTesting*/\n    internal fun onScroll(distance: Float): Float {\n        if (distance < 0 && !canScrollForward || distance > 0 && !canScrollBackward) {\n            return 0f\n        }\n        checkPrecondition(abs(scrollToBeConsumed) <= 0.5f) {\n            \"entered drag with non-zero pending scroll\"\n        }\n        executeRequestsInHighPriorityMode = true\n        scrollToBeConsumed += distance\n\n        // scrollToBeConsumed will be consumed synchronously during the forceRemeasure invocation\n        // inside measuring we do scrollToBeConsumed.roundToInt() so there will be no scroll if\n        // we have less than 0.5 pixels\n        if (abs(scrollToBeConsumed) > 0.5f) {\n            val preScrollToBeConsumed = scrollToBeConsumed\n            val intDelta = scrollToBeConsumed.fastRoundToInt()\n\n            var scrolledLayoutInfo =\n                layoutInfoState.value.copyWithScrollDeltaWithoutRemeasure(\n                    delta = intDelta,\n                    updateAnimations = !hasLookaheadOccurred,\n                )\n            if (scrolledLayoutInfo != null && this.approachLayoutInfo != null) {\n                // if we were able to scroll the lookahead layout info without remeasure, lets\n                // try to do the same for approach layout info (sometimes they diverge).\n                val scrolledApproachLayoutInfo =\n                    approachLayoutInfo?.copyWithScrollDeltaWithoutRemeasure(\n                        delta = intDelta,\n                        updateAnimations = true,\n                    )\n                if (scrolledApproachLayoutInfo != null) {\n                    // we can apply scroll delta for both phases without remeasure\n                    approachLayoutInfo = scrolledApproachLayoutInfo\n                } else {\n                    // we can't apply scroll delta for approach, so we have to remeasure\n                    scrolledLayoutInfo = null\n                }\n            }\n\n            if (scrolledLayoutInfo != null) {\n                applyMeasureResult(\n                    result = scrolledLayoutInfo,\n                    isLookingAhead = hasLookaheadOccurred,\n                    visibleItemsStayedTheSame = true,\n                )\n                // we don't need to remeasure, so we only trigger re-placement:\n                placementScopeInvalidator.invalidateScope()\n\n                notifyPrefetchOnScroll(\n                    preScrollToBeConsumed - scrollToBeConsumed,\n                    scrolledLayoutInfo,\n                )\n            } else {\n                remeasurement?.forceRemeasure()\n                notifyPrefetchOnScroll(preScrollToBeConsumed - scrollToBeConsumed, this.layoutInfo)\n            }\n        }\n\n        // here scrollToBeConsumed is already consumed during the forceRemeasure invocation\n        if (abs(scrollToBeConsumed) <= 0.5f) {\n            // We consumed all of it - we'll hold onto the fractional scroll for later, so report\n            // that we consumed the whole thing\n            return distance\n        } else {\n            val scrollConsumed = distance - scrollToBeConsumed\n            // We did not consume all of it - return the rest to be consumed elsewhere (e.g.,\n            // nested scrolling)\n            scrollToBeConsumed = 0f // We're not consuming the rest, give it back\n            return scrollConsumed\n        }\n    }\n\n    private fun notifyPrefetchOnScroll(delta: Float, layoutInfo: LazyListLayoutInfo) {\n        if (prefetchingEnabled) {\n            with(prefetchStrategy) { prefetchScope.onScroll(delta, layoutInfo) }\n        }\n    }\n\n    /**\n     * Animate (smooth scroll) to the given item.\n     *\n     * @param index the index to which to scroll. Must be non-negative.\n     * @param scrollOffset the offset that the item should end up after the scroll. Note that\n     *   positive offset refers to forward scroll, so in a top-to-bottom list, positive offset will\n     *   scroll the item further upward (taking it partly offscreen).\n     */\n    suspend fun animateScrollToItem(@AndroidXIntRange(from = 0) index: Int, scrollOffset: Int = 0) {\n        scroll {\n            LazyLayoutScrollScope(this@LazyListState, this)\n                .animateScrollToItem(index, scrollOffset, NumberOfItemsToTeleport, density)\n        }\n    }\n\n    /** Updates the state with the new calculated scroll position and consumed scroll. */\n    internal fun applyMeasureResult(\n        result: LazyListMeasureResult,\n        isLookingAhead: Boolean,\n        visibleItemsStayedTheSame: Boolean = false,\n    ) {\n        // update the prefetch state with the number of nested prefetch items this layout\n        // should use.\n        prefetchState.idealNestedPrefetchCount = result.visibleItemsInfo.size\n\n        if (!isLookingAhead && hasLookaheadOccurred) {\n            // If there was already a lookahead pass, record this result as approach result\n            approachLayoutInfo = result\n            Snapshot.withoutReadObservation {\n                if (\n                    _lazyLayoutScrollDeltaBetweenPasses.isActive &&\n                        result.firstVisibleItem?.index == scrollPosition.index &&\n                        result.firstVisibleItemScrollOffset == scrollPosition.scrollOffset\n                ) {\n                    _lazyLayoutScrollDeltaBetweenPasses.stop()\n                }\n            }\n        } else {\n            if (isLookingAhead) {\n                hasLookaheadOccurred = true\n            }\n\n            canScrollBackward = result.canScrollBackward\n            canScrollForward = result.canScrollForward\n            scrollToBeConsumed -= result.consumedScroll\n            layoutInfoState.value = result\n\n            if (visibleItemsStayedTheSame) {\n                scrollPosition.updateScrollOffset(result.firstVisibleItemScrollOffset)\n            } else {\n                traceVisibleItems(result) // trace when visible window changed\n                scrollPosition.updateFromMeasureResult(result)\n                if (prefetchingEnabled) {\n                    with(prefetchStrategy) { prefetchScope.onVisibleItemsUpdated(result) }\n                }\n            }\n\n            if (isLookingAhead) {\n                _lazyLayoutScrollDeltaBetweenPasses.updateScrollDeltaForApproach(\n                    result.scrollBackAmount,\n                    result.density,\n                    result.coroutineScope,\n                )\n            }\n            numMeasurePasses++\n        }\n    }\n\n    private fun traceVisibleItems(measureResult: LazyListMeasureResult) {\n        val firstVisibleItem = measureResult.visibleItemsInfo.firstOrNull()\n        val lastVisibleItem = measureResult.visibleItemsInfo.lastOrNull()\n        traceValue(\"firstVisibleItem:index\", firstVisibleItem?.index?.toLong() ?: -1L)\n        traceValue(\"lastVisibleItem:index\", lastVisibleItem?.index?.toLong() ?: -1L)\n    }\n\n    internal val scrollDeltaBetweenPasses: Float\n        get() = _lazyLayoutScrollDeltaBetweenPasses.scrollDeltaBetweenPasses\n\n    private val _lazyLayoutScrollDeltaBetweenPasses = LazyLayoutScrollDeltaBetweenPasses()\n\n    /**\n     * When the user provided custom keys for the items we can try to detect when there were items\n     * added or removed before our current first visible item and keep this item as the first\n     * visible one even given that its index has been changed. The scroll position will not be\n     * updated if [requestScrollToItem] was called since the last time this method was called.\n     */\n    internal fun updateScrollPositionIfTheFirstItemWasMoved(\n        itemProvider: LazyListItemProvider,\n        firstItemIndex: Int,\n    ): Int = scrollPosition.updateScrollPositionIfTheFirstItemWasMoved(itemProvider, firstItemIndex)\n\n    companion object {\n        /** The default [Saver] implementation for [LazyListState]. */\n        val Saver: Saver<LazyListState, *> =\n            listSaver(\n                save = { listOf(it.firstVisibleItemIndex, it.firstVisibleItemScrollOffset) },\n                restore = {\n                    LazyListState(\n                        firstVisibleItemIndex = it[0],\n                        firstVisibleItemScrollOffset = it[1],\n                    )\n                },\n            )\n\n        /**\n         * A [Saver] implementation for [LazyListState] that handles setting a custom\n         * [LazyListPrefetchStrategy].\n         */\n        internal fun saver(prefetchStrategy: LazyListPrefetchStrategy): Saver<LazyListState, *> =\n            listSaver(\n                save = { listOf(it.firstVisibleItemIndex, it.firstVisibleItemScrollOffset) },\n                restore = {\n                    LazyListState(\n                        firstVisibleItemIndex = it[0],\n                        firstVisibleItemScrollOffset = it[1],\n                        prefetchStrategy,\n                    )\n                },\n            )\n\n        /**\n         * A [Saver] implementation for [LazyListState] that handles setting a custom\n         * [LazyLayoutCacheWindow].\n         */\n        internal fun saver(cacheWindow: LazyLayoutCacheWindow): Saver<LazyListState, *> =\n            listSaver(\n                save = { listOf(it.firstVisibleItemIndex, it.firstVisibleItemScrollOffset) },\n                restore = {\n                    LazyListState(\n                        firstVisibleItemIndex = it[0],\n                        firstVisibleItemScrollOffset = it[1],\n                        cacheWindow = cacheWindow,\n                    )\n                },\n            )\n    }\n}\n\nprivate val EmptyLazyListMeasureResult =\n    LazyListMeasureResult(\n        firstVisibleItem = null,\n        firstVisibleItemScrollOffset = 0,\n        canScrollForward = false,\n        consumedScroll = 0f,\n        measureResult =\n            object : MeasureResult {\n                override val width: Int = 0\n                override val height: Int = 0\n\n                @Suppress(\"PrimitiveInCollection\")\n                override val alignmentLines: Map<AlignmentLine, Int> = emptyMap()\n\n                override fun placeChildren() {}\n            },\n        scrollBackAmount = 0f,\n        visibleItemsInfo = emptyList(),\n        viewportStartOffset = 0,\n        viewportEndOffset = 0,\n        totalItemsCount = 0,\n        reverseLayout = false,\n        orientation = Orientation.Vertical,\n        afterContentPadding = 0,\n        mainAxisItemSpacing = 0,\n        remeasureNeeded = false,\n        coroutineScope = CoroutineScope(EmptyCoroutineContext),\n        density = Density(1f),\n        childConstraints = Constraints(),\n    )\n\nprivate const val NumberOfItemsToTeleport = 100\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyDsl.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.lazy\n\nimport androidx.compose.foundation.OverscrollEffect\nimport androidx.compose.foundation.gestures.FlingBehavior\nimport androidx.compose.foundation.gestures.ScrollableDefaults\nimport androidx.compose.foundation.internal.JvmDefaultWithCompatibility\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.rememberOverscrollEffect\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\n\n/** Receiver scope which is used by [LazyColumn] and [LazyRow]. */\n@LazyScopeMarker\n@JvmDefaultWithCompatibility\ninterface LazyListScope {\n    /**\n     * Adds a single item.\n     *\n     * @param key a stable and unique key representing the item. Using the same key for multiple\n     *   items in the list is not allowed. Type of the key should be saveable via Bundle on Android.\n     *   If null is passed the position in the list will represent the key. When you specify the key\n     *   the scroll position will be maintained based on the key, which means if you add/remove\n     *   items before the current visible item the item with the given key will be kept as the first\n     *   visible one. This can be overridden by calling 'requestScrollToItem' on the\n     *   'LazyListState'.\n     * @param contentType the type of the content of this item. The item compositions of the same\n     *   type could be reused more efficiently. Note that null is a valid type and items of such\n     *   type will be considered compatible.\n     * @param content the content of the item\n     */\n    fun item(\n        key: Any? = null,\n        contentType: Any? = null,\n        content: @Composable LazyItemScope.() -> Unit,\n    ) {\n        error(\"The method is not implemented\")\n    }\n\n    @Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\n    fun item(key: Any? = null, content: @Composable LazyItemScope.() -> Unit) {\n        item(key, null, content)\n    }\n\n    /**\n     * Adds a [count] of items.\n     *\n     * @param count the items count\n     * @param key a factory of stable and unique keys representing the item. Using the same key for\n     *   multiple items in the list is not allowed. Type of the key should be saveable via Bundle on\n     *   Android. If null is passed the position in the list will represent the key. When you\n     *   specify the key the scroll position will be maintained based on the key, which means if you\n     *   add/remove items before the current visible item the item with the given key will be kept\n     *   as the first visible one. This can be overridden by calling 'requestScrollToItem' on the\n     *   'LazyListState'.\n     * @param contentType a factory of the content types for the item. The item compositions of the\n     *   same type could be reused more efficiently. Note that null is a valid type and items of\n     *   such type will be considered compatible.\n     * @param itemContent the content displayed by a single item\n     */\n    fun items(\n        count: Int,\n        key: ((index: Int) -> Any)? = null,\n        contentType: (index: Int) -> Any? = { null },\n        itemContent: @Composable LazyItemScope.(index: Int) -> Unit,\n    ) {\n        error(\"The method is not implemented\")\n    }\n\n    @Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\n    fun items(\n        count: Int,\n        key: ((index: Int) -> Any)? = null,\n        itemContent: @Composable LazyItemScope.(index: Int) -> Unit,\n    ) {\n        items(count, key, { null }, itemContent)\n    }\n\n    /**\n     * Adds a sticky header item, which will remain pinned even when scrolling after it. The header\n     * will remain pinned until the next header will take its place.\n     *\n     * @sample androidx.compose.foundation.samples.StickyHeaderListSample\n     * @param key a stable and unique key representing the item. Using the same key for multiple\n     *   items in the list is not allowed. Type of the key should be saveable via Bundle on Android.\n     *   If null is passed the position in the list will represent the key. When you specify the key\n     *   the scroll position will be maintained based on the key, which means if you add/remove\n     *   items before the current visible item the item with the given key will be kept as the first\n     *   visible one. This can be overridden by calling 'requestScrollToItem' on the\n     *   'LazyListState'.\n     * @param contentType the type of the content of this item. The item compositions of the same\n     *   type could be reused more efficiently. Note that null is a valid type and items of such\n     *   type will be considered compatible.\n     * @param content the content of the header\n     */\n    @Deprecated(\n        \"Please use the overload with indexing capabilities.\",\n        level = DeprecationLevel.HIDDEN,\n        replaceWith = ReplaceWith(\"stickyHeader(key, contentType, { _ -> content() })\"),\n    )\n    fun stickyHeader(\n        key: Any? = null,\n        contentType: Any? = null,\n        content: @Composable LazyItemScope.() -> Unit,\n    ) = stickyHeader(key, contentType) { _ -> content() }\n\n    /**\n     * Adds a sticky header item, which will remain pinned even when scrolling after it. The header\n     * will remain pinned until the next header will take its place.\n     *\n     * @sample androidx.compose.foundation.samples.StickyHeaderListSample\n     * @sample androidx.compose.foundation.samples.StickyHeaderHeaderIndexSample\n     * @param key a stable and unique key representing the item. Using the same key for multiple\n     *   items in the list is not allowed. Type of the key should be saveable via Bundle on Android.\n     *   If null is passed the position in the list will represent the key. When you specify the key\n     *   the scroll position will be maintained based on the key, which means if you add/remove\n     *   items before the current visible item the item with the given key will be kept as the first\n     *   visible one. This can be overridden by calling 'requestScrollToItem' on the\n     *   'LazyListState'.\n     * @param contentType the type of the content of this item. The item compositions of the same\n     *   type could be reused more efficiently. Note that null is a valid type and items of such\n     *   type will be considered compatible.\n     * @param content the content of the header, the header index is provided, this is the item\n     *   position within the total set of items in this lazy list (the global index).\n     */\n    fun stickyHeader(\n        key: Any? = null,\n        contentType: Any? = null,\n        content: @Composable LazyItemScope.(Int) -> Unit,\n    ) {\n        item(key, contentType) { content.invoke(this, 0) }\n    }\n}\n\n/**\n * Adds a list of items.\n *\n * @param items the data list\n * @param key a factory of stable and unique keys representing the item. Using the same key for\n *   multiple items in the list is not allowed. Type of the key should be saveable via Bundle on\n *   Android. If null is passed the position in the list will represent the key. When you specify\n *   the key the scroll position will be maintained based on the key, which means if you add/remove\n *   items before the current visible item the item with the given key will be kept as the first\n *   visible one. This can be overridden by calling 'requestScrollToItem' on the 'LazyListState'.\n * @param contentType a factory of the content types for the item. The item compositions of the same\n *   type could be reused more efficiently. Note that null is a valid type and items of such type\n *   will be considered compatible.\n * @param itemContent the content displayed by a single item\n */\ninline fun <T> LazyListScope.items(\n    items: List<T>,\n    noinline key: ((item: T) -> Any)? = null,\n    noinline contentType: (item: T) -> Any? = { null },\n    crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit,\n) =\n    items(\n        count = items.size,\n        key = if (key != null) { index: Int -> key(items[index]) } else null,\n        contentType = { index: Int -> contentType(items[index]) },\n    ) {\n        itemContent(items[it])\n    }\n\n@Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\ninline fun <T> LazyListScope.items(\n    items: List<T>,\n    noinline key: ((item: T) -> Any)? = null,\n    crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit,\n) = items(items, key, itemContent = itemContent)\n\n/**\n * Adds a list of items where the content of an item is aware of its index.\n *\n * @param items the data list\n * @param key a factory of stable and unique keys representing the item. Using the same key for\n *   multiple items in the list is not allowed. Type of the key should be saveable via Bundle on\n *   Android. If null is passed the position in the list will represent the key. When you specify\n *   the key the scroll position will be maintained based on the key, which means if you add/remove\n *   items before the current visible item the item with the given key will be kept as the first\n *   visible one. This can be overridden by calling 'requestScrollToItem' on the 'LazyListState'.\n * @param contentType a factory of the content types for the item. The item compositions of the same\n *   type could be reused more efficiently. Note that null is a valid type and items of such type\n *   will be considered compatible.\n * @param itemContent the content displayed by a single item\n */\ninline fun <T> LazyListScope.itemsIndexed(\n    items: List<T>,\n    noinline key: ((index: Int, item: T) -> Any)? = null,\n    crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },\n    crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit,\n) =\n    items(\n        count = items.size,\n        key = if (key != null) { index: Int -> key(index, items[index]) } else null,\n        contentType = { index -> contentType(index, items[index]) },\n    ) {\n        itemContent(it, items[it])\n    }\n\n@Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\ninline fun <T> LazyListScope.itemsIndexed(\n    items: List<T>,\n    noinline key: ((index: Int, item: T) -> Any)? = null,\n    crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit,\n) = itemsIndexed(items, key, itemContent = itemContent)\n\n/**\n * Adds an array of items.\n *\n * @param items the data array\n * @param key a factory of stable and unique keys representing the item. Using the same key for\n *   multiple items in the list is not allowed. Type of the key should be saveable via Bundle on\n *   Android. If null is passed the position in the list will represent the key. When you specify\n *   the key the scroll position will be maintained based on the key, which means if you add/remove\n *   items before the current visible item the item with the given key will be kept as the first\n *   visible one. This can be overridden by calling 'requestScrollToItem' on the 'LazyListState'.\n * @param contentType a factory of the content types for the item. The item compositions of the same\n *   type could be reused more efficiently. Note that null is a valid type and items of such type\n *   will be considered compatible.\n * @param itemContent the content displayed by a single item\n */\ninline fun <T> LazyListScope.items(\n    items: Array<T>,\n    noinline key: ((item: T) -> Any)? = null,\n    noinline contentType: (item: T) -> Any? = { null },\n    crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit,\n) =\n    items(\n        count = items.size,\n        key = if (key != null) { index: Int -> key(items[index]) } else null,\n        contentType = { index: Int -> contentType(items[index]) },\n    ) {\n        itemContent(items[it])\n    }\n\n@Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\ninline fun <T> LazyListScope.items(\n    items: Array<T>,\n    noinline key: ((item: T) -> Any)? = null,\n    crossinline itemContent: @Composable LazyItemScope.(item: T) -> Unit,\n) = items(items, key, itemContent = itemContent)\n\n/**\n * Adds an array of items where the content of an item is aware of its index.\n *\n * @param items the data array\n * @param key a factory of stable and unique keys representing the item. Using the same key for\n *   multiple items in the list is not allowed. Type of the key should be saveable via Bundle on\n *   Android. If null is passed the position in the list will represent the key. When you specify\n *   the key the scroll position will be maintained based on the key, which means if you add/remove\n *   items before the current visible item the item with the given key will be kept as the first\n *   visible one. This can be overridden by calling 'requestScrollToItem' on the 'LazyListState'.\n * @param contentType a factory of the content types for the item. The item compositions of the same\n *   type could be reused more efficiently. Note that null is a valid type and items of such type\n *   will be considered compatible.\n * @param itemContent the content displayed by a single item\n */\ninline fun <T> LazyListScope.itemsIndexed(\n    items: Array<T>,\n    noinline key: ((index: Int, item: T) -> Any)? = null,\n    crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },\n    crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit,\n) =\n    items(\n        count = items.size,\n        key = if (key != null) { index: Int -> key(index, items[index]) } else null,\n        contentType = { index -> contentType(index, items[index]) },\n    ) {\n        itemContent(it, items[it])\n    }\n\n@Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\ninline fun <T> LazyListScope.itemsIndexed(\n    items: Array<T>,\n    noinline key: ((index: Int, item: T) -> Any)? = null,\n    crossinline itemContent: @Composable LazyItemScope.(index: Int, item: T) -> Unit,\n) = itemsIndexed(items, key, itemContent = itemContent)\n\n/**\n * The horizontally scrolling list that only composes and lays out the currently visible items. The\n * [content] block defines a DSL which allows you to emit items of different types. For example you\n * can use [LazyListScope.item] to add a single item and [LazyListScope.items] to add a list of\n * items.\n *\n * @sample androidx.compose.foundation.samples.LazyRowSample\n * @param modifier the modifier to apply to this layout\n * @param state the state object to be used to control or observe the list's state\n * @param contentPadding a padding around the whole content. This will add padding for the content\n *   after it has been clipped, which is not possible via [modifier] param. You can use it to add a\n *   padding before the first item or after the last one. If you want to add a spacing between each\n *   item use [horizontalArrangement].\n * @param reverseLayout reverse the direction of scrolling and layout. When `true`, items are laid\n *   out in the reverse order and [LazyListState.firstVisibleItemIndex] == 0 means that row is\n *   scrolled to the end. Note that [reverseLayout] does not change the behavior of\n *   [horizontalArrangement], e.g. with [Arrangement.Start] [123###] becomes [321###].\n * @param horizontalArrangement The horizontal arrangement of the layout's children. This allows to\n *   add a spacing between items and specify the arrangement of the items when we have not enough of\n *   them to fill the whole minimum size.\n * @param verticalAlignment the vertical alignment applied to the items\n * @param flingBehavior logic describing fling behavior.\n * @param userScrollEnabled whether the scrolling via the user gestures or accessibility actions is\n *   allowed. You can still scroll programmatically using the state even when it is disabled.\n * @param overscrollEffect the [OverscrollEffect] that will be used to render overscroll for this\n *   layout. Note that the [OverscrollEffect.node] will be applied internally as well - you do not\n *   need to use Modifier.overscroll separately.\n * @param content a block which describes the content. Inside this block you can use methods like\n *   [LazyListScope.item] to add a single item or [LazyListScope.items] to add a list of items.\n */\n@Composable\nfun LazyRow(\n    modifier: Modifier = Modifier,\n    state: LazyListState = rememberLazyListState(),\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    reverseLayout: Boolean = false,\n    horizontalArrangement: Arrangement.Horizontal =\n        if (!reverseLayout) Arrangement.Start else Arrangement.End,\n    verticalAlignment: Alignment.Vertical = Alignment.Top,\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),\n    userScrollEnabled: Boolean = true,\n    overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),\n    content: LazyListScope.() -> Unit,\n) {\n    LazyList(\n        modifier = modifier,\n        state = state,\n        contentPadding = contentPadding,\n        verticalAlignment = verticalAlignment,\n        horizontalArrangement = horizontalArrangement,\n        isVertical = false,\n        flingBehavior = flingBehavior,\n        reverseLayout = reverseLayout,\n        userScrollEnabled = userScrollEnabled,\n        overscrollEffect = overscrollEffect,\n        content = content,\n    )\n}\n\n/**\n * The vertically scrolling list that only composes and lays out the currently visible items. The\n * [content] block defines a DSL which allows you to emit items of different types. For example you\n * can use [LazyListScope.item] to add a single item and [LazyListScope.items] to add a list of\n * items.\n *\n * @sample androidx.compose.foundation.samples.LazyColumnSample\n * @param modifier the modifier to apply to this layout.\n * @param state the state object to be used to control or observe the list's state.\n * @param contentPadding a padding around the whole content. This will add padding for the. content\n *   after it has been clipped, which is not possible via [modifier] param. You can use it to add a\n *   padding before the first item or after the last one. If you want to add a spacing between each\n *   item use [verticalArrangement].\n * @param reverseLayout reverse the direction of scrolling and layout. When `true`, items are laid\n *   out in the reverse order and [LazyListState.firstVisibleItemIndex] == 0 means that column is\n *   scrolled to the bottom. Note that [reverseLayout] does not change the behavior of\n *   [verticalArrangement], e.g. with [Arrangement.Top] (top) 123### (bottom) becomes (top) 321###\n *   (bottom).\n * @param verticalArrangement The vertical arrangement of the layout's children. This allows to add\n *   a spacing between items and specify the arrangement of the items when we have not enough of\n *   them to fill the whole minimum size.\n * @param horizontalAlignment the horizontal alignment applied to the items.\n * @param flingBehavior logic describing fling behavior.\n * @param userScrollEnabled whether the scrolling via the user gestures or accessibility actions is\n *   allowed. You can still scroll programmatically using the state even when it is disabled\n * @param overscrollEffect the [OverscrollEffect] that will be used to render overscroll for this\n *   layout. Note that the [OverscrollEffect.node] will be applied internally as well - you do not\n *   need to use Modifier.overscroll separately.\n * @param content a block which describes the content. Inside this block you can use methods like\n *   [LazyListScope.item] to add a single item or [LazyListScope.items] to add a list of items.\n */\n@Composable\nfun LazyColumn(\n    modifier: Modifier = Modifier,\n    state: LazyListState = rememberLazyListState(),\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    reverseLayout: Boolean = false,\n    verticalArrangement: Arrangement.Vertical =\n        if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,\n    horizontalAlignment: Alignment.Horizontal = Alignment.Start,\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),\n    userScrollEnabled: Boolean = true,\n    overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),\n    content: LazyListScope.() -> Unit,\n) {\n    LazyList(\n        modifier = modifier,\n        state = state,\n        contentPadding = contentPadding,\n        flingBehavior = flingBehavior,\n        horizontalAlignment = horizontalAlignment,\n        verticalArrangement = verticalArrangement,\n        isVertical = true,\n        reverseLayout = reverseLayout,\n        userScrollEnabled = userScrollEnabled,\n        overscrollEffect = overscrollEffect,\n        content = content,\n    )\n}\n\n@Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun LazyColumn(\n    modifier: Modifier = Modifier,\n    state: LazyListState = rememberLazyListState(),\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    reverseLayout: Boolean = false,\n    verticalArrangement: Arrangement.Vertical =\n        if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,\n    horizontalAlignment: Alignment.Horizontal = Alignment.Start,\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),\n    userScrollEnabled: Boolean = true,\n    content: LazyListScope.() -> Unit,\n) {\n    LazyColumn(\n        modifier = modifier,\n        state = state,\n        contentPadding = contentPadding,\n        reverseLayout = reverseLayout,\n        verticalArrangement = verticalArrangement,\n        horizontalAlignment = horizontalAlignment,\n        flingBehavior = flingBehavior,\n        userScrollEnabled = userScrollEnabled,\n        overscrollEffect = rememberOverscrollEffect(),\n        content = content,\n    )\n}\n\n@Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun LazyColumn(\n    modifier: Modifier = Modifier,\n    state: LazyListState = rememberLazyListState(),\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    reverseLayout: Boolean = false,\n    verticalArrangement: Arrangement.Vertical =\n        if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,\n    horizontalAlignment: Alignment.Horizontal = Alignment.Start,\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),\n    content: LazyListScope.() -> Unit,\n) {\n    LazyColumn(\n        modifier = modifier,\n        state = state,\n        contentPadding = contentPadding,\n        reverseLayout = reverseLayout,\n        verticalArrangement = verticalArrangement,\n        horizontalAlignment = horizontalAlignment,\n        flingBehavior = flingBehavior,\n        userScrollEnabled = true,\n        content = content,\n    )\n}\n\n@Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun LazyRow(\n    modifier: Modifier = Modifier,\n    state: LazyListState = rememberLazyListState(),\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    reverseLayout: Boolean = false,\n    horizontalArrangement: Arrangement.Horizontal =\n        if (!reverseLayout) Arrangement.Start else Arrangement.End,\n    verticalAlignment: Alignment.Vertical = Alignment.Top,\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),\n    userScrollEnabled: Boolean = true,\n    content: LazyListScope.() -> Unit,\n) {\n    LazyRow(\n        modifier = modifier,\n        state = state,\n        contentPadding = contentPadding,\n        reverseLayout = reverseLayout,\n        horizontalArrangement = horizontalArrangement,\n        verticalAlignment = verticalAlignment,\n        flingBehavior = flingBehavior,\n        userScrollEnabled = userScrollEnabled,\n        overscrollEffect = rememberOverscrollEffect(),\n        content = content,\n    )\n}\n\n@Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun LazyRow(\n    modifier: Modifier = Modifier,\n    state: LazyListState = rememberLazyListState(),\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    reverseLayout: Boolean = false,\n    horizontalArrangement: Arrangement.Horizontal =\n        if (!reverseLayout) Arrangement.Start else Arrangement.End,\n    verticalAlignment: Alignment.Vertical = Alignment.Top,\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),\n    content: LazyListScope.() -> Unit,\n) {\n    LazyRow(\n        modifier = modifier,\n        state = state,\n        contentPadding = contentPadding,\n        reverseLayout = reverseLayout,\n        horizontalArrangement = horizontalArrangement,\n        verticalAlignment = verticalAlignment,\n        flingBehavior = flingBehavior,\n        userScrollEnabled = true,\n        content = content,\n    )\n}\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyListItemProvider.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.lazy\n\nimport androidx.collection.IntList\nimport androidx.compose.foundation.lazy.layout.LazyLayoutItemProvider\nimport androidx.compose.foundation.lazy.layout.LazyLayoutKeyIndexMap\nimport androidx.compose.foundation.lazy.layout.LazyLayoutPinnableItem\nimport androidx.compose.foundation.lazy.layout.NearestRangeKeyIndexMap\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.referentialEqualityPolicy\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberUpdatedState\n\ninternal interface LazyListItemProvider : LazyLayoutItemProvider {\n    val keyIndexMap: LazyLayoutKeyIndexMap\n    /** The list of indexes of the sticky header items */\n    val headerIndexes: IntList\n    /** The scope used by the item content lambdas */\n    val itemScope: LazyItemScopeImpl\n}\n\n@Composable\ninternal fun rememberLazyListItemProviderLambda(\n    state: LazyListState,\n    content: LazyListScope.() -> Unit,\n): () -> LazyListItemProvider {\n    val latestContent = rememberUpdatedState(content)\n    return remember(state) {\n        val scope = LazyItemScopeImpl()\n        val intervalContentState =\n            derivedStateOf(referentialEqualityPolicy()) {\n                LazyListIntervalContent(latestContent.value)\n            }\n        val itemProviderState =\n            derivedStateOf(referentialEqualityPolicy()) {\n                val intervalContent = intervalContentState.value\n                val map = NearestRangeKeyIndexMap(state.nearestRange, intervalContent)\n                LazyListItemProviderImpl(\n                    state = state,\n                    intervalContent = intervalContent,\n                    itemScope = scope,\n                    keyIndexMap = map,\n                )\n            }\n        itemProviderState::value\n    }\n}\n\nprivate class LazyListItemProviderImpl\nconstructor(\n    private val state: LazyListState,\n    private val intervalContent: LazyListIntervalContent,\n    override val itemScope: LazyItemScopeImpl,\n    override val keyIndexMap: LazyLayoutKeyIndexMap,\n) : LazyListItemProvider {\n\n    override val itemCount: Int\n        get() = intervalContent.itemCount\n\n    @Composable\n    override fun Item(index: Int, key: Any) {\n        LazyLayoutPinnableItem(key, index, state.pinnedItems) {\n            intervalContent.withInterval(index) { localIndex, content ->\n                content.item(itemScope, localIndex)\n            }\n        }\n    }\n\n    override fun getKey(index: Int): Any =\n        keyIndexMap.getKey(index) ?: intervalContent.getKey(index)\n\n    override fun getContentType(index: Int): Any? = intervalContent.getContentType(index)\n\n    override val headerIndexes: IntList\n        get() = intervalContent.headerIndexes\n\n    override fun getIndex(key: Any): Int = keyIndexMap.getIndex(key)\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is LazyListItemProviderImpl) return false\n\n        // the identity of this class is represented by intervalContent object.\n        // having equals() allows us to skip items recomposition when intervalContent didn't change\n        return intervalContent == other.intervalContent\n    }\n\n    override fun hashCode(): Int {\n        return intervalContent.hashCode()\n    }\n}\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGrid.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.lazy.grid\n\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.OverscrollEffect\nimport androidx.compose.foundation.checkScrollableContainerConstraints\nimport androidx.compose.foundation.gestures.FlingBehavior\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.ScrollableDefaults\nimport androidx.compose.foundation.internal.requirePreconditionNotNull\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.lazy.layout.CacheWindowLogic\nimport androidx.compose.foundation.lazy.layout.LazyLayout\nimport androidx.compose.foundation.lazy.layout.LazyLayoutMeasurePolicy\nimport androidx.compose.foundation.lazy.layout.StickyItemsPlacement\nimport androidx.compose.foundation.lazy.layout.calculateLazyLayoutPinnedIndices\nimport androidx.compose.foundation.lazy.layout.lazyLayoutBeyondBoundsModifier\nimport androidx.compose.foundation.lazy.layout.lazyLayoutSemantics\nimport androidx.compose.foundation.scrollableArea\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.snapshots.Snapshot\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.GraphicsContext\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.platform.LocalGraphicsContext\nimport androidx.compose.ui.platform.LocalScrollCaptureInProgress\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.constrainHeight\nimport androidx.compose.ui.unit.constrainWidth\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.offset\nimport androidx.compose.ui.util.fastForEach\nimport androidx.compose.ui.util.trace\nimport kotlinx.coroutines.CoroutineScope\n\n@OptIn(ExperimentalFoundationApi::class)\n@Composable\ninternal fun LazyGrid(\n    /** Modifier to be applied for the inner layout */\n    modifier: Modifier = Modifier,\n    /** State controlling the scroll position */\n    state: LazyGridState,\n    /** Prefix sums of cross axis sizes of slots per line, e.g. the columns for vertical grid. */\n    slots: LazyGridSlotsProvider,\n    /** The inner padding to be added for the whole content (not for each individual item) */\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    /** reverse the direction of scrolling and layout */\n    reverseLayout: Boolean = false,\n    /** The layout orientation of the grid */\n    isVertical: Boolean,\n    /** fling behavior to be used for flinging */\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),\n    /** Whether scrolling via the user gestures is allowed. */\n    userScrollEnabled: Boolean,\n    /** The overscroll effect to render and dispatch events to */\n    overscrollEffect: OverscrollEffect?,\n    /** The vertical arrangement for items/lines. */\n    verticalArrangement: Arrangement.Vertical,\n    /** The horizontal arrangement for items/lines. */\n    horizontalArrangement: Arrangement.Horizontal,\n    /** The content of the grid */\n    content: LazyGridScope.() -> Unit,\n) {\n    val itemProviderLambda = rememberLazyGridItemProviderLambda(state, content)\n\n    val semanticState = rememberLazyGridSemanticState(state, reverseLayout)\n\n    val coroutineScope = rememberCoroutineScope()\n    val graphicsContext = LocalGraphicsContext.current\n    val stickyHeadersEnabled = !LocalScrollCaptureInProgress.current\n\n    val measurePolicy =\n        rememberLazyGridMeasurePolicy(\n            itemProviderLambda,\n            state,\n            slots,\n            contentPadding,\n            reverseLayout,\n            isVertical,\n            horizontalArrangement,\n            verticalArrangement,\n            coroutineScope,\n            graphicsContext,\n            if (stickyHeadersEnabled) StickyItemsPlacement.StickToTopPlacement else null,\n        )\n\n    val orientation = if (isVertical) Orientation.Vertical else Orientation.Horizontal\n\n    val beyondBoundsModifier =\n        if (userScrollEnabled) {\n            Modifier.lazyLayoutBeyondBoundsModifier(\n                state = rememberLazyGridBeyondBoundsState(state = state),\n                beyondBoundsInfo = state.beyondBoundsInfo,\n                reverseLayout = reverseLayout,\n                orientation = orientation,\n            )\n        } else {\n            Modifier\n        }\n\n    LazyLayout(\n        modifier =\n            modifier\n                .then(state.remeasurementModifier)\n                .then(state.awaitLayoutModifier)\n                .lazyLayoutSemantics(\n                    itemProviderLambda = itemProviderLambda,\n                    state = semanticState,\n                    orientation = orientation,\n                    userScrollEnabled = userScrollEnabled,\n                    reverseScrolling = reverseLayout,\n                )\n                .then(beyondBoundsModifier)\n                .then(state.itemAnimator.modifier)\n                .scrollableArea(\n                    state = state,\n                    orientation = orientation,\n                    enabled = userScrollEnabled,\n                    reverseScrolling = reverseLayout,\n                    flingBehavior = flingBehavior,\n                    interactionSource = state.internalInteractionSource,\n                    overscrollEffect = overscrollEffect,\n                ),\n        prefetchState = state.prefetchState,\n        measurePolicy = measurePolicy,\n        itemProvider = itemProviderLambda,\n    )\n}\n\n/** lazy grid slots configuration */\ninternal class LazyGridSlots(val sizes: IntArray, val positions: IntArray)\n\n@OptIn(ExperimentalFoundationApi::class)\n@Composable\nprivate fun rememberLazyGridMeasurePolicy(\n    /** Items provider of the list. */\n    itemProviderLambda: () -> LazyGridItemProvider,\n    /** The state of the list. */\n    state: LazyGridState,\n    /** Prefix sums of cross axis sizes of slots of the grid. */\n    slots: LazyGridSlotsProvider,\n    /** The inner padding to be added for the whole content(nor for each individual item) */\n    contentPadding: PaddingValues,\n    /** reverse the direction of scrolling and layout */\n    reverseLayout: Boolean,\n    /** The layout orientation of the list */\n    isVertical: Boolean,\n    /** The horizontal arrangement for items */\n    horizontalArrangement: Arrangement.Horizontal?,\n    /** The vertical arrangement for items */\n    verticalArrangement: Arrangement.Vertical?,\n    /** Coroutine scope for item animations */\n    coroutineScope: CoroutineScope,\n    /** Used for creating graphics layers */\n    graphicsContext: GraphicsContext,\n    /** Configures the placement of sticky items */\n    stickyItemsScrollBehavior: StickyItemsPlacement?,\n) =\n    remember(\n        state,\n        slots,\n        contentPadding,\n        reverseLayout,\n        isVertical,\n        horizontalArrangement,\n        verticalArrangement,\n        graphicsContext,\n    ) {\n        LazyLayoutMeasurePolicy { containerConstraints ->\n            state.measurementScopeInvalidator.attachToScope()\n            // Tracks if the lookahead pass has occurred\n            val isInLookaheadScope = state.hasLookaheadOccurred || isLookingAhead\n            checkScrollableContainerConstraints(\n                containerConstraints,\n                if (isVertical) Orientation.Vertical else Orientation.Horizontal,\n            )\n\n            // resolve content paddings\n            val startPadding =\n                if (isVertical) {\n                    contentPadding.calculateLeftPadding(layoutDirection).roundToPx()\n                } else {\n                    // in horizontal configuration, padding is reversed by placeRelative\n                    contentPadding.calculateStartPadding(layoutDirection).roundToPx()\n                }\n\n            val endPadding =\n                if (isVertical) {\n                    contentPadding.calculateRightPadding(layoutDirection).roundToPx()\n                } else {\n                    // in horizontal configuration, padding is reversed by placeRelative\n                    contentPadding.calculateEndPadding(layoutDirection).roundToPx()\n                }\n            val topPadding = contentPadding.calculateTopPadding().roundToPx()\n            val bottomPadding = contentPadding.calculateBottomPadding().roundToPx()\n            val totalVerticalPadding = topPadding + bottomPadding\n            val totalHorizontalPadding = startPadding + endPadding\n            val totalMainAxisPadding =\n                if (isVertical) totalVerticalPadding else totalHorizontalPadding\n            val beforeContentPadding =\n                when {\n                    isVertical && !reverseLayout -> topPadding\n                    isVertical && reverseLayout -> bottomPadding\n                    !isVertical && !reverseLayout -> startPadding\n                    else -> endPadding // !isVertical && reverseLayout\n                }\n            val afterContentPadding = totalMainAxisPadding - beforeContentPadding\n            val contentConstraints =\n                containerConstraints.offset(-totalHorizontalPadding, -totalVerticalPadding)\n\n            val itemProvider = itemProviderLambda()\n            val spanLayoutProvider = itemProvider.spanLayoutProvider\n            val resolvedSlots = slots.invoke(density = this, constraints = contentConstraints)\n            val slotsPerLine = resolvedSlots.sizes.size\n            spanLayoutProvider.slotsPerLine = slotsPerLine\n\n            val spaceBetweenLinesDp =\n                if (isVertical) {\n                    requirePreconditionNotNull(verticalArrangement) {\n                            \"null verticalArrangement when isVertical == true\"\n                        }\n                        .spacing\n                } else {\n                    requirePreconditionNotNull(horizontalArrangement) {\n                            \"null horizontalArrangement when isVertical == false\"\n                        }\n                        .spacing\n                }\n            val spaceBetweenLines = spaceBetweenLinesDp.roundToPx()\n            val itemsCount = itemProvider.itemCount\n\n            // can be negative if the content padding is larger than the max size from constraints\n            val mainAxisAvailableSize =\n                if (isVertical) {\n                    containerConstraints.maxHeight - totalVerticalPadding\n                } else {\n                    containerConstraints.maxWidth - totalHorizontalPadding\n                }\n            val visualItemOffset =\n                if (!reverseLayout || mainAxisAvailableSize > 0) {\n                    IntOffset(startPadding, topPadding)\n                } else {\n                    // When layout is reversed and paddings together take >100% of the available\n                    // space,\n                    // layout size is coerced to 0 when positioning. To take that space into\n                    // account,\n                    // we offset start padding by negative space between paddings.\n                    IntOffset(\n                        if (isVertical) startPadding else startPadding + mainAxisAvailableSize,\n                        if (isVertical) topPadding + mainAxisAvailableSize else topPadding,\n                    )\n                }\n\n            val measuredItemProvider =\n                object : LazyGridMeasuredItemProvider(itemProvider, this, spaceBetweenLines) {\n                    override fun createItem(\n                        index: Int,\n                        key: Any,\n                        contentType: Any?,\n                        crossAxisSize: Int,\n                        mainAxisSpacing: Int,\n                        placeables: List<Placeable>,\n                        constraints: Constraints,\n                        lane: Int,\n                        span: Int,\n                    ) =\n                        LazyGridMeasuredItem(\n                            index = index,\n                            key = key,\n                            isVertical = isVertical,\n                            crossAxisSize = crossAxisSize,\n                            mainAxisSpacing = mainAxisSpacing,\n                            reverseLayout = reverseLayout,\n                            layoutDirection = layoutDirection,\n                            beforeContentPadding = beforeContentPadding,\n                            afterContentPadding = afterContentPadding,\n                            visualOffset = visualItemOffset,\n                            placeables = placeables,\n                            contentType = contentType,\n                            animator = state.itemAnimator,\n                            constraints = constraints,\n                            lane = lane,\n                            span = span,\n                        )\n                }\n            val measuredLineProvider =\n                object :\n                    LazyGridMeasuredLineProvider(\n                        isVertical = isVertical,\n                        slots = resolvedSlots,\n                        gridItemsCount = itemsCount,\n                        spaceBetweenLines = spaceBetweenLines,\n                        measuredItemProvider = measuredItemProvider,\n                        spanLayoutProvider = spanLayoutProvider,\n                    ) {\n                    override fun createLine(\n                        index: Int,\n                        items: Array<LazyGridMeasuredItem>,\n                        spans: List<GridItemSpan>,\n                        mainAxisSpacing: Int,\n                    ) =\n                        LazyGridMeasuredLine(\n                            index = index,\n                            items = items,\n                            spans = spans,\n                            slots = resolvedSlots,\n                            isVertical = isVertical,\n                            mainAxisSpacing = mainAxisSpacing,\n                        )\n                }\n            val prefetchInfoRetriever: (line: Int) -> List<Pair<Int, Constraints>> = { line ->\n                val lineConfiguration = spanLayoutProvider.getLineConfiguration(line)\n                var index = lineConfiguration.firstItemIndex\n                var slot = 0\n                val result = ArrayList<Pair<Int, Constraints>>(lineConfiguration.spans.size)\n                lineConfiguration.spans.fastForEach {\n                    val span = it.currentLineSpan\n                    result.add(index to measuredLineProvider.childConstraints(slot, span))\n                    ++index\n                    slot += span\n                }\n                result\n            }\n\n            val lineIndexProvider: (itemIndex: Int) -> Int = { itemIndex ->\n                spanLayoutProvider.getLineIndexOfItem(itemIndex)\n            }\n\n            val firstVisibleLineIndex: Int\n            val firstVisibleLineScrollOffset: Int\n\n            Snapshot.withoutReadObservation {\n                val index =\n                    state.updateScrollPositionIfTheFirstItemWasMoved(\n                        itemProvider,\n                        state.firstVisibleItemIndex,\n                    )\n                if (index < itemsCount || itemsCount <= 0) {\n                    firstVisibleLineIndex = spanLayoutProvider.getLineIndexOfItem(index)\n                    firstVisibleLineScrollOffset = state.firstVisibleItemScrollOffset\n                } else {\n                    // the data set has been updated and now we have less items that we were\n                    // scrolled to before\n                    firstVisibleLineIndex = spanLayoutProvider.getLineIndexOfItem(itemsCount - 1)\n                    firstVisibleLineScrollOffset = 0\n                }\n            }\n\n            val pinnedItems =\n                itemProvider.calculateLazyLayoutPinnedIndices(\n                    state.pinnedItems,\n                    state.beyondBoundsInfo,\n                )\n\n            val scrollToBeConsumed =\n                if (isLookingAhead || !isInLookaheadScope) {\n                    state.scrollToBeConsumed\n                } else {\n                    state.scrollDeltaBetweenPasses\n                }\n\n            // todo: wrap with snapshot when b/341782245 is resolved\n            val measureResult =\n                measureLazyGrid(\n                    itemsCount = itemsCount,\n                    measuredLineProvider = measuredLineProvider,\n                    measuredItemProvider = measuredItemProvider,\n                    mainAxisAvailableSize = mainAxisAvailableSize,\n                    beforeContentPadding = beforeContentPadding,\n                    afterContentPadding = afterContentPadding,\n                    spaceBetweenLines = spaceBetweenLines,\n                    firstVisibleLineIndex = firstVisibleLineIndex,\n                    firstVisibleLineScrollOffset = firstVisibleLineScrollOffset,\n                    scrollToBeConsumed = scrollToBeConsumed,\n                    constraints = contentConstraints,\n                    isVertical = isVertical,\n                    verticalArrangement = verticalArrangement,\n                    horizontalArrangement = horizontalArrangement,\n                    reverseLayout = reverseLayout,\n                    density = this,\n                    itemAnimator = state.itemAnimator,\n                    slotsPerLine = slotsPerLine,\n                    pinnedItems = pinnedItems,\n                    isInLookaheadScope = isInLookaheadScope,\n                    isLookingAhead = isLookingAhead,\n                    approachLayoutInfo = state.approachLayoutInfo,\n                    coroutineScope = coroutineScope,\n                    placementScopeInvalidator = state.placementScopeInvalidator,\n                    prefetchInfoRetriever = prefetchInfoRetriever,\n                    lineIndexProvider = lineIndexProvider,\n                    graphicsContext = graphicsContext,\n                    stickyItemsScrollBehavior = stickyItemsScrollBehavior,\n                    layout = { width, height, placement ->\n                        layout(\n                            containerConstraints.constrainWidth(width + totalHorizontalPadding),\n                            containerConstraints.constrainHeight(height + totalVerticalPadding),\n                            emptyMap(),\n                            placement,\n                        )\n                    },\n                )\n            state.applyMeasureResult(measureResult, isLookingAhead = isLookingAhead)\n            // apply keep around after updating the strategy with measure result.\n            (state.prefetchStrategy as? CacheWindowLogic)?.keepAroundItems(\n                measureResult.orientation,\n                measureResult.visibleItemsInfo,\n                measuredLineProvider,\n            )\n            measureResult\n        }\n    }\n\n@OptIn(ExperimentalFoundationApi::class)\nprivate fun CacheWindowLogic.keepAroundItems(\n    orientation: Orientation,\n    visibleItemsList: List<LazyGridMeasuredItem>,\n    measuredLineProvider: LazyGridMeasuredLineProvider,\n) {\n    trace(\"compose:lazy:cache_window:keepAroundItems\") {\n        // only run if window and new layout info is available\n        if (hasValidBounds() && visibleItemsList.isNotEmpty()) {\n            val firstVisibleItemIndex = visibleItemsList.first().lineIndex(orientation)\n            val lastVisibleItemIndex = visibleItemsList.last().lineIndex(orientation)\n            // we must send a message in case of changing directions for items\n            // that were keep around and become prefetch forward\n            for (line in prefetchWindowStartLine..<firstVisibleItemIndex) {\n                measuredLineProvider.keepAround(line)\n            }\n\n            for (line in (lastVisibleItemIndex + 1)..prefetchWindowEndLine) {\n                measuredLineProvider.keepAround(line)\n            }\n        }\n    }\n}\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridDsl.kt\n```kotlin\n/*\n * Copyright 2022 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.lazy.grid\n\nimport androidx.compose.foundation.OverscrollEffect\nimport androidx.compose.foundation.gestures.FlingBehavior\nimport androidx.compose.foundation.gestures.ScrollableDefaults\nimport androidx.compose.foundation.internal.requirePrecondition\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.rememberOverscrollEffect\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\n\n/**\n * A lazy vertical grid layout. It composes only visible rows of the grid.\n *\n * Sample:\n *\n * @sample androidx.compose.foundation.samples.LazyVerticalGridSample\n *\n * Sample with custom item spans:\n *\n * @sample androidx.compose.foundation.samples.LazyVerticalGridSpanSample\n * @param columns describes the count and the size of the grid's columns, see [GridCells] doc for\n *   more information\n * @param modifier the modifier to apply to this layout\n * @param state the state object to be used to control or observe the list's state\n * @param contentPadding specify a padding around the whole content\n * @param reverseLayout reverse the direction of scrolling and layout. When `true`, items will be\n *   laid out in the reverse order and [LazyGridState.firstVisibleItemIndex] == 0 means that grid is\n *   scrolled to the bottom. Note that [reverseLayout] does not change the behavior of\n *   [verticalArrangement], e.g. with [Arrangement.Top] (top) 123### (bottom) becomes (top) 321###\n *   (bottom).\n * @param verticalArrangement The vertical arrangement of the layout's children\n * @param horizontalArrangement The horizontal arrangement of the layout's children\n * @param flingBehavior logic describing fling behavior\n * @param userScrollEnabled whether the scrolling via the user gestures or accessibility actions is\n *   allowed. You can still scroll programmatically using the state even when it is disabled.\n * @param overscrollEffect the [OverscrollEffect] that will be used to render overscroll for this\n *   layout. Note that the [OverscrollEffect.node] will be applied internally as well - you do not\n *   need to use Modifier.overscroll separately.\n * @param content the [LazyGridScope] which describes the content\n */\n@Composable\nfun LazyVerticalGrid(\n    columns: GridCells,\n    modifier: Modifier = Modifier,\n    state: LazyGridState = rememberLazyGridState(),\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    reverseLayout: Boolean = false,\n    verticalArrangement: Arrangement.Vertical =\n        if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,\n    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),\n    userScrollEnabled: Boolean = true,\n    overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),\n    content: LazyGridScope.() -> Unit,\n) {\n    LazyGrid(\n        slots = rememberColumnWidthSums(columns, horizontalArrangement),\n        modifier = modifier,\n        state = state,\n        contentPadding = contentPadding,\n        reverseLayout = reverseLayout,\n        isVertical = true,\n        horizontalArrangement = horizontalArrangement,\n        verticalArrangement = verticalArrangement,\n        flingBehavior = flingBehavior,\n        userScrollEnabled = userScrollEnabled,\n        overscrollEffect = overscrollEffect,\n        content = content,\n    )\n}\n\n@Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun LazyVerticalGrid(\n    columns: GridCells,\n    modifier: Modifier = Modifier,\n    state: LazyGridState = rememberLazyGridState(),\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    reverseLayout: Boolean = false,\n    verticalArrangement: Arrangement.Vertical =\n        if (!reverseLayout) Arrangement.Top else Arrangement.Bottom,\n    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),\n    userScrollEnabled: Boolean = true,\n    content: LazyGridScope.() -> Unit,\n) {\n    LazyVerticalGrid(\n        columns = columns,\n        modifier = modifier,\n        state = state,\n        contentPadding = contentPadding,\n        reverseLayout = reverseLayout,\n        verticalArrangement = verticalArrangement,\n        horizontalArrangement = horizontalArrangement,\n        flingBehavior = flingBehavior,\n        userScrollEnabled = userScrollEnabled,\n        overscrollEffect = rememberOverscrollEffect(),\n        content = content,\n    )\n}\n\n/**\n * A lazy horizontal grid layout. It composes only visible columns of the grid.\n *\n * Sample:\n *\n * @sample androidx.compose.foundation.samples.LazyHorizontalGridSample\n *\n * Sample with custom item spans:\n *\n * @sample androidx.compose.foundation.samples.LazyHorizontalGridSpanSample\n * @param rows a class describing how cells form rows, see [GridCells] doc for more information\n * @param modifier the modifier to apply to this layout\n * @param state the state object to be used to control or observe the list's state\n * @param contentPadding specify a padding around the whole content\n * @param reverseLayout reverse the direction of scrolling and layout. When `true`, items are laid\n *   out in the reverse order and [LazyGridState.firstVisibleItemIndex] == 0 means that grid is\n *   scrolled to the end. Note that [reverseLayout] does not change the behavior of\n *   [horizontalArrangement], e.g. with [Arrangement.Start] [123###] becomes [321###].\n * @param verticalArrangement The vertical arrangement of the layout's children\n * @param horizontalArrangement The horizontal arrangement of the layout's children\n * @param flingBehavior logic describing fling behavior\n * @param userScrollEnabled whether the scrolling via the user gestures or accessibility actions is\n *   allowed. You can still scroll programmatically using the state even when it is disabled.\n * @param overscrollEffect the [OverscrollEffect] that will be used to render overscroll for this\n *   layout. Note that the [OverscrollEffect.node] will be applied internally as well - you do not\n *   need to use Modifier.overscroll separately.\n * @param content the [LazyGridScope] which describes the content\n */\n@Composable\nfun LazyHorizontalGrid(\n    rows: GridCells,\n    modifier: Modifier = Modifier,\n    state: LazyGridState = rememberLazyGridState(),\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    reverseLayout: Boolean = false,\n    horizontalArrangement: Arrangement.Horizontal =\n        if (!reverseLayout) Arrangement.Start else Arrangement.End,\n    verticalArrangement: Arrangement.Vertical = Arrangement.Top,\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),\n    userScrollEnabled: Boolean = true,\n    overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),\n    content: LazyGridScope.() -> Unit,\n) {\n    LazyGrid(\n        slots = rememberRowHeightSums(rows, verticalArrangement),\n        modifier = modifier,\n        state = state,\n        contentPadding = contentPadding,\n        reverseLayout = reverseLayout,\n        isVertical = false,\n        horizontalArrangement = horizontalArrangement,\n        verticalArrangement = verticalArrangement,\n        flingBehavior = flingBehavior,\n        userScrollEnabled = userScrollEnabled,\n        overscrollEffect = overscrollEffect,\n        content = content,\n    )\n}\n\n@Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun LazyHorizontalGrid(\n    rows: GridCells,\n    modifier: Modifier = Modifier,\n    state: LazyGridState = rememberLazyGridState(),\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    reverseLayout: Boolean = false,\n    horizontalArrangement: Arrangement.Horizontal =\n        if (!reverseLayout) Arrangement.Start else Arrangement.End,\n    verticalArrangement: Arrangement.Vertical = Arrangement.Top,\n    flingBehavior: FlingBehavior = ScrollableDefaults.flingBehavior(),\n    userScrollEnabled: Boolean = true,\n    content: LazyGridScope.() -> Unit,\n) {\n    LazyHorizontalGrid(\n        rows = rows,\n        modifier = modifier,\n        state = state,\n        contentPadding = contentPadding,\n        reverseLayout = reverseLayout,\n        horizontalArrangement = horizontalArrangement,\n        verticalArrangement = verticalArrangement,\n        flingBehavior = flingBehavior,\n        userScrollEnabled = userScrollEnabled,\n        overscrollEffect = rememberOverscrollEffect(),\n        content = content,\n    )\n}\n\n/** Returns prefix sums of column widths. */\n@Composable\nprivate fun rememberColumnWidthSums(\n    columns: GridCells,\n    horizontalArrangement: Arrangement.Horizontal,\n) =\n    remember<LazyGridSlotsProvider>(columns, horizontalArrangement) {\n        GridSlotCache { constraints ->\n            requirePrecondition(constraints.maxWidth != Constraints.Infinity) {\n                \"LazyVerticalGrid's width should be bound by parent.\"\n            }\n\n            val gridWidth = constraints.maxWidth\n            with(columns) {\n                calculateCrossAxisCellSizes(gridWidth, horizontalArrangement.spacing.roundToPx())\n                    .toIntArray()\n                    .let { sizes ->\n                        val positions = IntArray(sizes.size)\n                        with(horizontalArrangement) {\n                            arrange(gridWidth, sizes, LayoutDirection.Ltr, positions)\n                        }\n                        LazyGridSlots(sizes, positions)\n                    }\n            }\n        }\n    }\n\n/** Returns prefix sums of row heights. */\n@Composable\nprivate fun rememberRowHeightSums(rows: GridCells, verticalArrangement: Arrangement.Vertical) =\n    remember<LazyGridSlotsProvider>(rows, verticalArrangement) {\n        GridSlotCache { constraints ->\n            requirePrecondition(constraints.maxHeight != Constraints.Infinity) {\n                \"LazyHorizontalGrid's height should be bound by parent.\"\n            }\n\n            val gridHeight = constraints.maxHeight\n            with(rows) {\n                calculateCrossAxisCellSizes(gridHeight, verticalArrangement.spacing.roundToPx())\n                    .toIntArray()\n                    .let { sizes ->\n                        val positions = IntArray(sizes.size)\n                        with(verticalArrangement) { arrange(gridHeight, sizes, positions) }\n                        LazyGridSlots(sizes, positions)\n                    }\n            }\n        }\n    }\n\n// Note: Implementing function interface is prohibited in K/JS (class A: () -> Unit)\n// therefore we workaround this limitation by inheriting a fun interface instead\ninternal fun interface LazyGridSlotsProvider {\n    fun invoke(density: Density, constraints: Constraints): LazyGridSlots\n}\n\n/** measurement cache to avoid recalculating row/column sizes on each scroll. */\nprivate class GridSlotCache(private val calculation: Density.(Constraints) -> LazyGridSlots) :\n    LazyGridSlotsProvider {\n    private var cachedConstraints = Constraints()\n    private var cachedDensity: Float = 0f\n    private var cachedSizes: LazyGridSlots? = null\n\n    override fun invoke(density: Density, constraints: Constraints): LazyGridSlots {\n        with(density) {\n            if (\n                cachedSizes != null &&\n                    cachedConstraints == constraints &&\n                    cachedDensity == this.density\n            ) {\n                return cachedSizes!!\n            }\n\n            cachedConstraints = constraints\n            cachedDensity = this.density\n            return calculation(constraints).also { cachedSizes = it }\n        }\n    }\n}\n\n/**\n * This class describes the count and the sizes of columns in vertical grids, or rows in horizontal\n * grids.\n */\n@Stable\ninterface GridCells {\n    /**\n     * Calculates the number of cells and their cross axis size based on [availableSize] and\n     * [spacing].\n     *\n     * For example, in vertical grids, [spacing] is passed from the grid's [Arrangement.Horizontal].\n     * The [Arrangement.Horizontal] will also be used to arrange items in a row if the grid is wider\n     * than the calculated sum of columns.\n     *\n     * Note that the calculated cross axis sizes will be considered in an RTL-aware manner -- if the\n     * grid is vertical and the layout direction is RTL, the first width in the returned list will\n     * correspond to the rightmost column.\n     *\n     * @param availableSize available size on cross axis, e.g. width of [LazyVerticalGrid].\n     * @param spacing cross axis spacing, e.g. horizontal spacing for [LazyVerticalGrid]. The\n     *   spacing is passed from the corresponding [Arrangement] param of the lazy grid.\n     */\n    fun Density.calculateCrossAxisCellSizes(availableSize: Int, spacing: Int): List<Int>\n\n    /**\n     * Defines a grid with fixed number of rows or columns.\n     *\n     * For example, for the vertical [LazyVerticalGrid] Fixed(3) would mean that there are 3 columns\n     * 1/3 of the parent width.\n     */\n    class Fixed(private val count: Int) : GridCells {\n        init {\n            requirePrecondition(count > 0) { \"Provided count should be larger than zero\" }\n        }\n\n        override fun Density.calculateCrossAxisCellSizes(\n            availableSize: Int,\n            spacing: Int,\n        ): List<Int> {\n            return calculateCellsCrossAxisSizeImpl(availableSize, count, spacing)\n        }\n\n        override fun hashCode(): Int {\n            return -count // Different sign from Adaptive.\n        }\n\n        override fun equals(other: Any?): Boolean {\n            return other is Fixed && count == other.count\n        }\n    }\n\n    /**\n     * Defines a grid with as many rows or columns as possible on the condition that every cell has\n     * at least [minSize] space and all extra space distributed evenly.\n     *\n     * For example, for the vertical [LazyVerticalGrid] Adaptive(20.dp) would mean that there will\n     * be as many columns as possible and every column will be at least 20.dp and all the columns\n     * will have equal width. If the screen is 88.dp wide then there will be 4 columns 22.dp each.\n     */\n    class Adaptive(private val minSize: Dp) : GridCells {\n        init {\n            requirePrecondition(minSize > 0.dp) { \"Provided min size should be larger than zero.\" }\n        }\n\n        override fun Density.calculateCrossAxisCellSizes(\n            availableSize: Int,\n            spacing: Int,\n        ): List<Int> {\n            val count = maxOf((availableSize + spacing) / (minSize.roundToPx() + spacing), 1)\n            return calculateCellsCrossAxisSizeImpl(availableSize, count, spacing)\n        }\n\n        override fun hashCode(): Int {\n            return minSize.hashCode()\n        }\n\n        override fun equals(other: Any?): Boolean {\n            return other is Adaptive && minSize == other.minSize\n        }\n    }\n\n    /**\n     * Defines a grid with as many rows or columns as possible on the condition that every cell\n     * takes exactly [size] space. The remaining space will be arranged through [LazyGrid]\n     * arrangements on corresponding axis. If [size] is larger than container size, the cell will be\n     * size to match the container.\n     *\n     * For example, for the vertical [LazyGrid] FixedSize(20.dp) would mean that there will be as\n     * many columns as possible and every column will be exactly 20.dp. If the screen is 88.dp wide\n     * tne there will be 4 columns 20.dp each with remaining 8.dp distributed through\n     * [Arrangement.Horizontal].\n     */\n    class FixedSize(private val size: Dp) : GridCells {\n        init {\n            requirePrecondition(size > 0.dp) { \"Provided size should be larger than zero.\" }\n        }\n\n        override fun Density.calculateCrossAxisCellSizes(\n            availableSize: Int,\n            spacing: Int,\n        ): List<Int> {\n            val cellSize = size.roundToPx()\n            return if (cellSize + spacing < availableSize + spacing) {\n                val cellCount = (availableSize + spacing) / (cellSize + spacing)\n                List(cellCount) { cellSize }\n            } else {\n                List(1) { availableSize }\n            }\n        }\n\n        override fun hashCode(): Int {\n            return size.hashCode()\n        }\n\n        override fun equals(other: Any?): Boolean {\n            return other is FixedSize && size == other.size\n        }\n    }\n}\n\nprivate fun calculateCellsCrossAxisSizeImpl(\n    gridSize: Int,\n    slotCount: Int,\n    spacing: Int,\n): List<Int> {\n    val gridSizeWithoutSpacing = gridSize - spacing * (slotCount - 1)\n    val slotSize = gridSizeWithoutSpacing / slotCount\n    val remainingPixels = gridSizeWithoutSpacing % slotCount\n    return List(slotCount) { slotSize + if (it < remainingPixels) 1 else 0 }\n}\n\n/** Receiver scope which is used by [LazyVerticalGrid]. */\n@LazyGridScopeMarker\nsealed interface LazyGridScope {\n    /**\n     * Adds a single item to the scope.\n     *\n     * @param key a stable and unique key representing the item. Using the same key for multiple\n     *   items in the grid is not allowed. Type of the key should be saveable via Bundle on Android.\n     *   If null is passed the position in the grid will represent the key. When you specify the key\n     *   the scroll position will be maintained based on the key, which means if you add/remove\n     *   items before the current visible item the item with the given key will be kept as the first\n     *   visible one. This can be overridden by calling [LazyGridState.requestScrollToItem].\n     * @param span the span of the item. Default is 1x1. It is good practice to leave it `null` when\n     *   this matches the intended behavior, as providing a custom implementation impacts\n     *   performance\n     * @param contentType the type of the content of this item. The item compositions of the same\n     *   type could be reused more efficiently. Note that null is a valid type and items of such\n     *   type will be considered compatible.\n     * @param content the content of the item\n     */\n    fun item(\n        key: Any? = null,\n        span: (LazyGridItemSpanScope.() -> GridItemSpan)? = null,\n        contentType: Any? = null,\n        content: @Composable LazyGridItemScope.() -> Unit,\n    )\n\n    /**\n     * Adds a [count] of items.\n     *\n     * @param count the items count\n     * @param key a factory of stable and unique keys representing the item. Using the same key for\n     *   multiple items in the grid is not allowed. Type of the key should be saveable via Bundle on\n     *   Android. If null is passed the position in the grid will represent the key. When you\n     *   specify the key the scroll position will be maintained based on the key, which means if you\n     *   add/remove items before the current visible item the item with the given key will be kept\n     *   as the first visible one.This can be overridden by calling\n     *   [LazyGridState.requestScrollToItem].\n     * @param span define custom spans for the items. Default is 1x1. It is good practice to leave\n     *   it `null` when this matches the intended behavior, as providing a custom implementation\n     *   impacts performance\n     * @param contentType a factory of the content types for the item. The item compositions of the\n     *   same type could be reused more efficiently. Note that null is a valid type and items of\n     *   such type will be considered compatible.\n     * @param itemContent the content displayed by a single item\n     */\n    fun items(\n        count: Int,\n        key: ((index: Int) -> Any)? = null,\n        span: (LazyGridItemSpanScope.(index: Int) -> GridItemSpan)? = null,\n        contentType: (index: Int) -> Any? = { null },\n        itemContent: @Composable LazyGridItemScope.(index: Int) -> Unit,\n    )\n\n    /**\n     * Adds a sticky header item, which will remain pinned even when scrolling after it. The header\n     * will remain pinned until the next header will take its place. Sticky Headers are full span\n     * items, that is, they will occupy [LazyGridItemSpanScope.maxLineSpan].\n     *\n     * @sample androidx.compose.foundation.samples.StickyHeaderGridSample\n     * @param key a stable and unique key representing the item. Using the same key for multiple\n     *   items in the list is not allowed. Type of the key should be saveable via Bundle on Android.\n     *   If null is passed the position in the list will represent the key. When you specify the key\n     *   the scroll position will be maintained based on the key, which means if you add/remove\n     *   items before the current visible item the item with the given key will be kept as the first\n     *   visible one. This can be overridden by calling 'requestScrollToItem' on the\n     *   'LazyGridState'.\n     * @param contentType the type of the content of this item. The item compositions of the same\n     *   type could be reused more efficiently. Note that null is a valid type and items of such\n     *   type will be considered compatible.\n     * @param content the content of the header. The header index is provided, this is the item\n     *   position within the total set of items in this lazy list (the global index).\n     */\n    fun stickyHeader(\n        key: Any? = null,\n        contentType: Any? = null,\n        content: @Composable LazyGridItemScope.(Int) -> Unit,\n    )\n}\n\n/**\n * Adds a list of items.\n *\n * @param items the data list\n * @param key a factory of stable and unique keys representing the item. Using the same key for\n *   multiple items in the grid is not allowed. Type of the key should be saveable via Bundle on\n *   Android. If null is passed the position in the grid will represent the key. When you specify\n *   the key the scroll position will be maintained based on the key, which means if you add/remove\n *   items before the current visible item the item with the given key will be kept as the first\n *   visible one. This can be overridden by calling [LazyGridState.requestScrollToItem].\n * @param span define custom spans for the items. Default is 1x1. It is good practice to leave it\n *   `null` when this matches the intended behavior, as providing a custom implementation impacts\n *   performance\n * @param contentType a factory of the content types for the item. The item compositions of the same\n *   type could be reused more efficiently. Note that null is a valid type and items of such type\n *   will be considered compatible.\n * @param itemContent the content displayed by a single item\n */\ninline fun <T> LazyGridScope.items(\n    items: List<T>,\n    noinline key: ((item: T) -> Any)? = null,\n    noinline span: (LazyGridItemSpanScope.(item: T) -> GridItemSpan)? = null,\n    noinline contentType: (item: T) -> Any? = { null },\n    crossinline itemContent: @Composable LazyGridItemScope.(item: T) -> Unit,\n) =\n    items(\n        count = items.size,\n        key = if (key != null) { index: Int -> key(items[index]) } else null,\n        span =\n            if (span != null) {\n                { span(items[it]) }\n            } else null,\n        contentType = { index: Int -> contentType(items[index]) },\n    ) {\n        itemContent(items[it])\n    }\n\n/**\n * Adds a list of items where the content of an item is aware of its index.\n *\n * @param items the data list\n * @param key a factory of stable and unique keys representing the item. Using the same key for\n *   multiple items in the grid is not allowed. Type of the key should be saveable via Bundle on\n *   Android. If null is passed the position in the grid will represent the key. When you specify\n *   the key the scroll position will be maintained based on the key, which means if you add/remove\n *   items before the current visible item the item with the given key will be kept as the first\n *   visible one. This can be overridden by calling [LazyGridState.requestScrollToItem].\n * @param span define custom spans for the items. Default is 1x1. It is good practice to leave it\n *   `null` when this matches the intended behavior, as providing a custom implementation impacts\n *   performance\n * @param contentType a factory of the content types for the item. The item compositions of the same\n *   type could be reused more efficiently. Note that null is a valid type and items of such type\n *   will be considered compatible.\n * @param itemContent the content displayed by a single item\n */\ninline fun <T> LazyGridScope.itemsIndexed(\n    items: List<T>,\n    noinline key: ((index: Int, item: T) -> Any)? = null,\n    noinline span: (LazyGridItemSpanScope.(index: Int, item: T) -> GridItemSpan)? = null,\n    crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },\n    crossinline itemContent: @Composable LazyGridItemScope.(index: Int, item: T) -> Unit,\n) =\n    items(\n        count = items.size,\n        key = if (key != null) { index: Int -> key(index, items[index]) } else null,\n        span =\n            if (span != null) {\n                { span(it, items[it]) }\n            } else null,\n        contentType = { index -> contentType(index, items[index]) },\n    ) {\n        itemContent(it, items[it])\n    }\n\n/**\n * Adds an array of items.\n *\n * @param items the data array\n * @param key a factory of stable and unique keys representing the item. Using the same key for\n *   multiple items in the grid is not allowed. Type of the key should be saveable via Bundle on\n *   Android. If null is passed the position in the grid will represent the key. When you specify\n *   the key the scroll position will be maintained based on the key, which means if you add/remove\n *   items before the current visible item the item with the given key will be kept as the first\n *   visible one.This can be overridden by calling [LazyGridState.requestScrollToItem].\n * @param span define custom spans for the items. Default is 1x1. It is good practice to leave it\n *   `null` when this matches the intended behavior, as providing a custom implementation impacts\n *   performance\n * @param contentType a factory of the content types for the item. The item compositions of the same\n *   type could be reused more efficiently. Note that null is a valid type and items of such type\n *   will be considered compatible.\n * @param itemContent the content displayed by a single item\n */\ninline fun <T> LazyGridScope.items(\n    items: Array<T>,\n    noinline key: ((item: T) -> Any)? = null,\n    noinline span: (LazyGridItemSpanScope.(item: T) -> GridItemSpan)? = null,\n    noinline contentType: (item: T) -> Any? = { null },\n    crossinline itemContent: @Composable LazyGridItemScope.(item: T) -> Unit,\n) =\n    items(\n        count = items.size,\n        key = if (key != null) { index: Int -> key(items[index]) } else null,\n        span =\n            if (span != null) {\n                { span(items[it]) }\n            } else null,\n        contentType = { index: Int -> contentType(items[index]) },\n    ) {\n        itemContent(items[it])\n    }\n\n/**\n * Adds an array of items where the content of an item is aware of its index.\n *\n * @param items the data array\n * @param key a factory of stable and unique keys representing the item. Using the same key for\n *   multiple items in the grid is not allowed. Type of the key should be saveable via Bundle on\n *   Android. If null is passed the position in the grid will represent the key. When you specify\n *   the key the scroll position will be maintained based on the key, which means if you add/remove\n *   items before the current visible item the item with the given key will be kept as the first\n *   visible one. This can be overridden by calling [LazyGridState.requestScrollToItem].\n * @param span define custom spans for the items. Default is 1x1. It is good practice to leave it\n *   `null` when this matches the intended behavior, as providing a custom implementation impacts\n *   performance\n * @param contentType a factory of the content types for the item. The item compositions of the same\n *   type could be reused more efficiently. Note that null is a valid type and items of such type\n *   will be considered compatible.\n * @param itemContent the content displayed by a single item\n */\ninline fun <T> LazyGridScope.itemsIndexed(\n    items: Array<T>,\n    noinline key: ((index: Int, item: T) -> Any)? = null,\n    noinline span: (LazyGridItemSpanScope.(index: Int, item: T) -> GridItemSpan)? = null,\n    crossinline contentType: (index: Int, item: T) -> Any? = { _, _ -> null },\n    crossinline itemContent: @Composable LazyGridItemScope.(index: Int, item: T) -> Unit,\n) =\n    items(\n        count = items.size,\n        key = if (key != null) { index: Int -> key(index, items[index]) } else null,\n        span =\n            if (span != null) {\n                { span(it, items[it]) }\n            } else null,\n        contentType = { index -> contentType(index, items[index]) },\n    ) {\n        itemContent(it, items[it])\n    }\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/grid/LazyGridState.kt\n```kotlin\n/*\n * Copyright 2022 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.lazy.grid\n\nimport androidx.annotation.IntRange as AndroidXIntRange\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.MutatePriority\nimport androidx.compose.foundation.ScrollIndicatorState\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.ScrollScope\nimport androidx.compose.foundation.gestures.ScrollableState\nimport androidx.compose.foundation.gestures.stopScroll\nimport androidx.compose.foundation.interaction.InteractionSource\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.internal.checkPrecondition\nimport androidx.compose.foundation.lazy.grid.LazyGridState.Companion.Saver\nimport androidx.compose.foundation.lazy.layout.AwaitFirstLayoutModifier\nimport androidx.compose.foundation.lazy.layout.CacheWindowLogic\nimport androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsInfo\nimport androidx.compose.foundation.lazy.layout.LazyLayoutCacheWindow\nimport androidx.compose.foundation.lazy.layout.LazyLayoutItemAnimator\nimport androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList\nimport androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState\nimport androidx.compose.foundation.lazy.layout.LazyLayoutScrollDeltaBetweenPasses\nimport androidx.compose.foundation.lazy.layout.ObservableScopeInvalidator\nimport androidx.compose.foundation.lazy.layout.animateScrollToItem\nimport androidx.compose.foundation.lazy.singleAxisViewportSize\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.annotation.FrequentlyChangingValue\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.neverEqualPolicy\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.Saver\nimport androidx.compose.runtime.saveable.listSaver\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.snapshots.Snapshot\nimport androidx.compose.ui.layout.AlignmentLine\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.Remeasurement\nimport androidx.compose.ui.layout.RemeasurementModifier\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.util.fastForEach\nimport kotlin.coroutines.EmptyCoroutineContext\nimport kotlin.math.abs\nimport kotlin.math.roundToInt\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.launch\n\n/**\n * Creates a [LazyGridState] that is remembered across compositions.\n *\n * Changes to the provided initial values will **not** result in the state being recreated or\n * changed in any way if it has already been created.\n *\n * @param initialFirstVisibleItemIndex the initial value for [LazyGridState.firstVisibleItemIndex]\n * @param initialFirstVisibleItemScrollOffset the initial value for\n *   [LazyGridState.firstVisibleItemScrollOffset]\n */\n@Composable\nfun rememberLazyGridState(\n    initialFirstVisibleItemIndex: Int = 0,\n    initialFirstVisibleItemScrollOffset: Int = 0,\n): LazyGridState {\n    return rememberSaveable(saver = LazyGridState.Saver) {\n        LazyGridState(initialFirstVisibleItemIndex, initialFirstVisibleItemScrollOffset)\n    }\n}\n\n/**\n * Creates a [LazyGridState] that is remembered across compositions.\n *\n * Changes to the provided initial values will **not** result in the state being recreated or\n * changed in any way if it has already been created.\n *\n * @param initialFirstVisibleItemIndex the initial value for [LazyGridState.firstVisibleItemIndex]\n * @param initialFirstVisibleItemScrollOffset the initial value for\n *   [LazyGridState.firstVisibleItemScrollOffset]\n * @param prefetchStrategy the [LazyGridPrefetchStrategy] to use for prefetching content in this\n *   grid\n */\n@ExperimentalFoundationApi\n@Composable\nfun rememberLazyGridState(\n    initialFirstVisibleItemIndex: Int = 0,\n    initialFirstVisibleItemScrollOffset: Int = 0,\n    prefetchStrategy: LazyGridPrefetchStrategy = remember { LazyGridPrefetchStrategy() },\n): LazyGridState {\n    return rememberSaveable(prefetchStrategy, saver = LazyGridState.saver(prefetchStrategy)) {\n        LazyGridState(\n            initialFirstVisibleItemIndex,\n            initialFirstVisibleItemScrollOffset,\n            prefetchStrategy,\n        )\n    }\n}\n\n/**\n * Creates a [LazyGridState] that is remembered across compositions.\n *\n * Changes to the provided initial values will **not** result in the state being recreated or\n * changed in any way if it has already been created.\n *\n * @param cacheWindow specifies the size of the ahead and behind window to be used as per\n *   [LazyLayoutCacheWindow].\n * @param initialFirstVisibleItemIndex the initial value for [LazyGridState.firstVisibleItemIndex]\n * @param initialFirstVisibleItemScrollOffset the initial value for\n *   [LazyGridState.firstVisibleItemScrollOffset]\n */\n@ExperimentalFoundationApi\n@Composable\nfun rememberLazyGridState(\n    cacheWindow: LazyLayoutCacheWindow,\n    initialFirstVisibleItemIndex: Int = 0,\n    initialFirstVisibleItemScrollOffset: Int = 0,\n): LazyGridState {\n    return rememberSaveable(cacheWindow, saver = LazyGridState.saver(cacheWindow)) {\n        LazyGridState(\n            cacheWindow,\n            initialFirstVisibleItemIndex,\n            initialFirstVisibleItemScrollOffset,\n        )\n    }\n}\n\n/**\n * A state object that can be hoisted to control and observe scrolling.\n *\n * In most cases, this will be created via [rememberLazyGridState].\n *\n * @param firstVisibleItemIndex the initial value for [LazyGridState.firstVisibleItemIndex]\n * @param firstVisibleItemScrollOffset the initial value for\n *   [LazyGridState.firstVisibleItemScrollOffset]\n * @param prefetchStrategy the [LazyGridPrefetchStrategy] to use for prefetching content in this\n *   grid\n */\n@OptIn(ExperimentalFoundationApi::class)\n@Stable\nclass LazyGridState\n@ExperimentalFoundationApi\nconstructor(\n    firstVisibleItemIndex: Int = 0,\n    firstVisibleItemScrollOffset: Int = 0,\n    internal val prefetchStrategy: LazyGridPrefetchStrategy = LazyGridPrefetchStrategy(),\n) : ScrollableState {\n\n    /**\n     * @param cacheWindow specifies the size of the ahead and behind window to be used as per\n     *   [LazyLayoutCacheWindow].\n     * @param firstVisibleItemIndex the initial value for [LazyGridState.firstVisibleItemIndex]\n     * @param firstVisibleItemScrollOffset the initial value for\n     *   [LazyGridState.firstVisibleItemScrollOffset]\n     */\n    @ExperimentalFoundationApi\n    constructor(\n        cacheWindow: LazyLayoutCacheWindow,\n        firstVisibleItemIndex: Int = 0,\n        firstVisibleItemScrollOffset: Int = 0,\n    ) : this(\n        firstVisibleItemIndex,\n        firstVisibleItemScrollOffset,\n        LazyGridCacheWindowPrefetchStrategy(cacheWindow),\n    )\n\n    /**\n     * @param firstVisibleItemIndex the initial value for [LazyGridState.firstVisibleItemIndex]\n     * @param firstVisibleItemScrollOffset the initial value for\n     *   [LazyGridState.firstVisibleItemScrollOffset]\n     */\n    constructor(\n        firstVisibleItemIndex: Int = 0,\n        firstVisibleItemScrollOffset: Int = 0,\n    ) : this(firstVisibleItemIndex, firstVisibleItemScrollOffset, LazyGridPrefetchStrategy())\n\n    internal var hasLookaheadOccurred: Boolean = false\n        private set\n\n    internal var approachLayoutInfo: LazyGridMeasureResult? = null\n        private set\n\n    // always execute requests in high priority\n    private var executeRequestsInHighPriorityMode = false\n\n    /** The holder class for the current scroll position. */\n    private val scrollPosition =\n        LazyGridScrollPosition(firstVisibleItemIndex, firstVisibleItemScrollOffset)\n\n    /**\n     * The index of the first item that is visible within the scrollable viewport area, this means,\n     * not including items in the content padding region. For the first visible item that includes\n     * items in the content padding please use [LazyGridLayoutInfo.visibleItemsInfo].\n     *\n     * Note that this property is observable and if you use it in the composable function it will be\n     * recomposed on every change causing potential performance issues.\n     *\n     * If you want to run some side effects like sending an analytics event or updating a state\n     * based on this value consider using \"snapshotFlow\":\n     *\n     * @sample androidx.compose.foundation.samples.UsingGridScrollPositionForSideEffectSample\n     *\n     * If you need to use it in the composition then consider wrapping the calculation into a\n     * derived state in order to only have recompositions when the derived value changes:\n     *\n     * @sample androidx.compose.foundation.samples.UsingGridScrollPositionInCompositionSample\n     */\n    val firstVisibleItemIndex: Int\n        @FrequentlyChangingValue get() = scrollPosition.index\n\n    /**\n     * The scroll offset of the first visible item. Scrolling forward is positive - i.e., the amount\n     * that the item is offset backwards\n     */\n    val firstVisibleItemScrollOffset: Int\n        @FrequentlyChangingValue get() = scrollPosition.scrollOffset\n\n    /** Backing state for [layoutInfo] */\n    private val layoutInfoState = mutableStateOf(EmptyLazyGridLayoutInfo, neverEqualPolicy())\n\n    /**\n     * The object of [LazyGridLayoutInfo] calculated during the last layout pass. For example, you\n     * can use it to calculate what items are currently visible.\n     *\n     * Note that this property is observable and is updated after every scroll or remeasure. If you\n     * use it in the composable function it will be recomposed on every change causing potential\n     * performance issues including infinity recomposition loop. Therefore, avoid using it in the\n     * composition.\n     *\n     * If you want to run some side effects like sending an analytics event or updating a state\n     * based on this value consider using \"snapshotFlow\":\n     *\n     * @sample androidx.compose.foundation.samples.UsingGridLayoutInfoForSideEffectSample\n     */\n    val layoutInfo: LazyGridLayoutInfo\n        @FrequentlyChangingValue get() = layoutInfoState.value\n\n    /**\n     * [InteractionSource] that will be used to dispatch drag events when this grid is being\n     * dragged. If you want to know whether the fling (or animated scroll) is in progress, use\n     * [isScrollInProgress].\n     */\n    val interactionSource: InteractionSource\n        get() = internalInteractionSource\n\n    internal val internalInteractionSource: MutableInteractionSource = MutableInteractionSource()\n\n    /**\n     * The amount of scroll to be consumed in the next layout pass. Scrolling forward is negative\n     * - that is, it is the amount that the items are offset in y\n     */\n    internal var scrollToBeConsumed = 0f\n        private set\n\n    internal val slotsPerLine: Int\n        get() = layoutInfoState.value.slotsPerLine\n\n    internal val density: Density\n        get() = layoutInfoState.value.density\n\n    /**\n     * The ScrollableController instance. We keep it as we need to call stopAnimation on it once we\n     * reached the end of the grid.\n     */\n    private val scrollableState = ScrollableState { -onScroll(-it) }\n\n    /** Only used for testing to confirm that we're not making too many measure passes */\n    /*@VisibleForTesting*/\n    internal var numMeasurePasses: Int = 0\n        private set\n\n    /** Only used for testing to disable prefetching when needed to test the main logic. */\n    /*@VisibleForTesting*/\n    internal var prefetchingEnabled: Boolean = true\n\n    /**\n     * The [Remeasurement] object associated with our layout. It allows us to remeasure\n     * synchronously during scroll.\n     */\n    internal var remeasurement: Remeasurement? = null\n        private set\n\n    /** The modifier which provides [remeasurement]. */\n    internal val remeasurementModifier =\n        object : RemeasurementModifier {\n            override fun onRemeasurementAvailable(remeasurement: Remeasurement) {\n                this@LazyGridState.remeasurement = remeasurement\n            }\n        }\n\n    /**\n     * Provides a modifier which allows to delay some interactions (e.g. scroll) until layout is\n     * ready.\n     */\n    internal val awaitLayoutModifier = AwaitFirstLayoutModifier()\n\n    internal val itemAnimator = LazyLayoutItemAnimator<LazyGridMeasuredItem>()\n\n    internal val beyondBoundsInfo = LazyLayoutBeyondBoundsInfo()\n\n    @Suppress(\"DEPRECATION\") // b/420551535\n    internal val prefetchState =\n        LazyLayoutPrefetchState(prefetchStrategy.prefetchScheduler) {\n            with(prefetchStrategy) {\n                onNestedPrefetch(Snapshot.withoutReadObservation { firstVisibleItemIndex })\n            }\n        }\n\n    private val prefetchScope: LazyGridPrefetchScope =\n        object : LazyGridPrefetchScope {\n            override fun scheduleLinePrefetch(\n                lineIndex: Int\n            ): List<LazyLayoutPrefetchState.PrefetchHandle> {\n                return scheduleLinePrefetch(lineIndex, null)\n            }\n\n            @Suppress(\"PrimitiveInCollection\")\n            override fun scheduleLinePrefetch(\n                lineIndex: Int,\n                onPrefetchFinished: (LazyGridPrefetchResultScope.() -> Unit)?,\n            ): List<LazyLayoutPrefetchState.PrefetchHandle> {\n                // Without read observation since this can be triggered from scroll - this will then\n                // cause us to recompose when the measure result changes. We don't care since the\n                // prefetch is best effort.\n                val prefetchHandles = mutableListOf<LazyLayoutPrefetchState.PrefetchHandle>()\n                val itemSizes: MutableList<Int>? =\n                    if (onPrefetchFinished == null) null else mutableListOf()\n\n                Snapshot.withoutReadObservation {\n                    val layoutInfo =\n                        if (hasLookaheadOccurred) {\n                            approachLayoutInfo\n                        } else {\n                            layoutInfoState.value\n                        }\n\n                    layoutInfo?.let { measureResult ->\n                        var completedCount = 1\n                        val itemsInLineInfo = measureResult.prefetchInfoRetriever(lineIndex)\n                        itemsInLineInfo.fastForEach { lineInfo ->\n                            prefetchHandles.add(\n                                prefetchState.schedulePrecompositionAndPremeasure(\n                                    lineInfo.first,\n                                    lineInfo.second,\n                                    executeRequestsInHighPriorityMode,\n                                ) {\n                                    var itemMainAxisItemSize = 0\n                                    repeat(placeablesCount) {\n                                        itemMainAxisItemSize +=\n                                            if (measureResult.orientation == Orientation.Vertical) {\n                                                getSize(it).height\n                                            } else {\n                                                getSize(it).width\n                                            }\n                                    }\n\n                                    itemSizes?.add(itemMainAxisItemSize)\n                                    // all items in this line were prefetched, report the size\n                                    if (completedCount == itemsInLineInfo.size) {\n                                        if (onPrefetchFinished != null && itemSizes != null) {\n                                            onPrefetchFinished.invoke(\n                                                LazyGridPrefetchResultScopeImpl(\n                                                    lineIndex,\n                                                    itemSizes,\n                                                )\n                                            )\n                                        }\n                                    } else {\n                                        completedCount++\n                                    }\n                                }\n                            )\n                        }\n                    }\n                }\n                return prefetchHandles\n            }\n        }\n\n    private val _scrollIndicatorState =\n        object : ScrollIndicatorState {\n            override val scrollOffset: Int\n                get() = calculateScrollOffset()\n\n            override val contentSize: Int\n                get() = layoutInfo.calculateContentSize()\n\n            override val viewportSize: Int\n                get() = layoutInfo.singleAxisViewportSize\n        }\n\n    private fun calculateScrollOffset(): Int {\n        val info = layoutInfo\n        return (info.visibleLinesAverageMainAxisSize() * info.firstVisibleItemLineIndex) +\n            firstVisibleItemScrollOffset\n    }\n\n    /** Stores currently pinned items which are always composed. */\n    internal val pinnedItems = LazyLayoutPinnedItemList()\n\n    internal val nearestRange: IntRange by scrollPosition.nearestRangeState\n\n    internal val placementScopeInvalidator = ObservableScopeInvalidator()\n\n    /**\n     * Instantly brings the item at [index] to the top of the viewport, offset by [scrollOffset]\n     * pixels.\n     *\n     * @param index the index to which to scroll. Must be non-negative.\n     * @param scrollOffset the offset that the item should end up after the scroll. Note that\n     *   positive offset refers to forward scroll, so in a top-to-bottom list, positive offset will\n     *   scroll the item further upward (taking it partly offscreen).\n     */\n    suspend fun scrollToItem(@AndroidXIntRange(from = 0) index: Int, scrollOffset: Int = 0) {\n        scroll { snapToItemIndexInternal(index, scrollOffset, forceRemeasure = true) }\n    }\n\n    internal val measurementScopeInvalidator = ObservableScopeInvalidator()\n\n    /**\n     * Requests the item at [index] to be at the start of the viewport during the next remeasure,\n     * offset by [scrollOffset], and schedules a remeasure.\n     *\n     * The scroll position will be updated to the requested position rather than maintain the index\n     * based on the first visible item key (when a data set change will also be applied during the\n     * next remeasure), but *only* for the next remeasure.\n     *\n     * Any scroll in progress will be cancelled.\n     *\n     * @param index the index to which to scroll. Must be non-negative.\n     * @param scrollOffset the offset that the item should end up after the scroll. Note that\n     *   positive offset refers to forward scroll, so in a top-to-bottom list, positive offset will\n     *   scroll the item further upward (taking it partly offscreen).\n     */\n    fun requestScrollToItem(@AndroidXIntRange(from = 0) index: Int, scrollOffset: Int = 0) {\n        // Cancel any scroll in progress.\n        if (isScrollInProgress) {\n            layoutInfoState.value.coroutineScope.launch { stopScroll() }\n        }\n\n        snapToItemIndexInternal(index, scrollOffset, forceRemeasure = false)\n    }\n\n    internal fun snapToItemIndexInternal(index: Int, scrollOffset: Int, forceRemeasure: Boolean) {\n        val positionChanged =\n            scrollPosition.index != index || scrollPosition.scrollOffset != scrollOffset\n        // sometimes this method is called not to scroll, but to stay on the same index when\n        // the data changes, as by default we maintain the scroll position by key, not index.\n        // when this happens we don't need to reset the animations as from the user perspective\n        // we didn't scroll anywhere and if there is an offset change for an item, this change\n        // should be animated.\n        // however, when the request is to really scroll to a different position, we have to\n        // reset previously known item positions as we don't want offset changes to be animated.\n        // this offset should be considered as a scroll, not the placement change.\n        if (positionChanged) {\n            itemAnimator.reset()\n            // we changed positions, cancel existing requests and wait for the next scroll to\n            // refill the window\n            (prefetchStrategy as? CacheWindowLogic)?.resetStrategy()\n        }\n        scrollPosition.requestPositionAndForgetLastKnownKey(index, scrollOffset)\n        if (forceRemeasure) {\n            remeasurement?.forceRemeasure()\n        } else {\n            measurementScopeInvalidator.invalidateScope()\n        }\n    }\n\n    /**\n     * Call this function to take control of scrolling and gain the ability to send scroll events\n     * via [ScrollScope.scrollBy]. All actions that change the logical scroll position must be\n     * performed within a [scroll] block (even if they don't call any other methods on this object)\n     * in order to guarantee that mutual exclusion is enforced.\n     *\n     * If [scroll] is called from elsewhere, this will be canceled.\n     */\n    override suspend fun scroll(\n        scrollPriority: MutatePriority,\n        block: suspend ScrollScope.() -> Unit,\n    ) {\n        if (layoutInfoState.value === EmptyLazyGridLayoutInfo) {\n            awaitLayoutModifier.waitForFirstLayout()\n        }\n        scrollableState.scroll(scrollPriority, block)\n    }\n\n    override fun dispatchRawDelta(delta: Float): Float = scrollableState.dispatchRawDelta(delta)\n\n    override val isScrollInProgress: Boolean\n        get() = scrollableState.isScrollInProgress\n\n    override var canScrollForward: Boolean by mutableStateOf(false)\n        private set\n\n    override var canScrollBackward: Boolean by mutableStateOf(false)\n        private set\n\n    @get:Suppress(\"GetterSetterNames\")\n    override val lastScrolledForward: Boolean\n        get() = scrollableState.lastScrolledForward\n\n    @get:Suppress(\"GetterSetterNames\")\n    override val lastScrolledBackward: Boolean\n        get() = scrollableState.lastScrolledBackward\n\n    override val scrollIndicatorState: ScrollIndicatorState?\n        get() = _scrollIndicatorState\n\n    // TODO: Coroutine scrolling APIs will allow this to be private again once we have more\n    //  fine-grained control over scrolling\n    /*@VisibleForTesting*/\n    internal fun onScroll(distance: Float): Float {\n        if (distance < 0 && !canScrollForward || distance > 0 && !canScrollBackward) {\n            return 0f\n        }\n        checkPrecondition(abs(scrollToBeConsumed) <= 0.5f) {\n            \"entered drag with non-zero pending scroll\"\n        }\n        scrollToBeConsumed += distance\n\n        // scrollToBeConsumed will be consumed synchronously during the forceRemeasure invocation\n        // inside measuring we do scrollToBeConsumed.roundToInt() so there will be no scroll if\n        // we have less than 0.5 pixels\n        if (abs(scrollToBeConsumed) > 0.5f) {\n            val preScrollToBeConsumed = scrollToBeConsumed\n            val intDelta = scrollToBeConsumed.roundToInt()\n            var scrolledLayoutInfo =\n                layoutInfoState.value.copyWithScrollDeltaWithoutRemeasure(\n                    delta = intDelta,\n                    updateAnimations = !hasLookaheadOccurred,\n                )\n            if (scrolledLayoutInfo != null && this.approachLayoutInfo != null) {\n                // if we were able to scroll the lookahead layout info without remeasure, lets\n                // try to do the same for post lookahead layout info (sometimes they diverge).\n                val scrolledApproachLayoutInfo =\n                    approachLayoutInfo?.copyWithScrollDeltaWithoutRemeasure(\n                        delta = intDelta,\n                        updateAnimations = true,\n                    )\n                if (scrolledApproachLayoutInfo != null) {\n                    // we can apply scroll delta for both phases without remeasure\n                    approachLayoutInfo = scrolledApproachLayoutInfo\n                } else {\n                    // we can't apply scroll delta for post lookahead, so we have to remeasure\n                    scrolledLayoutInfo = null\n                }\n            }\n            if (scrolledLayoutInfo != null) {\n                applyMeasureResult(\n                    result = scrolledLayoutInfo,\n                    isLookingAhead = hasLookaheadOccurred,\n                    visibleItemsStayedTheSame = true,\n                )\n                // we don't need to remeasure, so we only trigger re-placement:\n                placementScopeInvalidator.invalidateScope()\n\n                notifyPrefetchOnScroll(\n                    preScrollToBeConsumed - scrollToBeConsumed,\n                    scrolledLayoutInfo,\n                )\n            } else {\n                remeasurement?.forceRemeasure()\n                notifyPrefetchOnScroll(preScrollToBeConsumed - scrollToBeConsumed, this.layoutInfo)\n            }\n        }\n\n        // here scrollToBeConsumed is already consumed during the forceRemeasure invocation\n        if (abs(scrollToBeConsumed) <= 0.5f) {\n            // We consumed all of it - we'll hold onto the fractional scroll for later, so report\n            // that we consumed the whole thing\n            return distance\n        } else {\n            val scrollConsumed = distance - scrollToBeConsumed\n            // We did not consume all of it - return the rest to be consumed elsewhere (e.g.,\n            // nested scrolling)\n            scrollToBeConsumed = 0f // We're not consuming the rest, give it back\n            return scrollConsumed\n        }\n    }\n\n    private fun notifyPrefetchOnScroll(delta: Float, layoutInfo: LazyGridLayoutInfo) {\n        if (prefetchingEnabled) {\n            with(prefetchStrategy) { prefetchScope.onScroll(delta, layoutInfo) }\n        }\n    }\n\n    private val numOfItemsToTeleport: Int\n        get() = 100 * slotsPerLine\n\n    /**\n     * Animate (smooth scroll) to the given item.\n     *\n     * @param index the index to which to scroll. Must be non-negative.\n     * @param scrollOffset the offset that the item should end up after the scroll. Note that\n     *   positive offset refers to forward scroll, so in a top-to-bottom list, positive offset will\n     *   scroll the item further upward (taking it partly offscreen).\n     */\n    suspend fun animateScrollToItem(@AndroidXIntRange(from = 0) index: Int, scrollOffset: Int = 0) {\n        scroll {\n            LazyLayoutScrollScope(this@LazyGridState, this)\n                .animateScrollToItem(index, scrollOffset, numOfItemsToTeleport, density)\n        }\n    }\n\n    /** Updates the state with the new calculated scroll position and consumed scroll. */\n    internal fun applyMeasureResult(\n        result: LazyGridMeasureResult,\n        isLookingAhead: Boolean,\n        visibleItemsStayedTheSame: Boolean = false,\n    ) {\n        // update the prefetch state with the number of nested prefetch items this layout\n        // should use.\n        prefetchState.idealNestedPrefetchCount = result.visibleItemsInfo.size\n\n        if (!isLookingAhead && hasLookaheadOccurred) {\n            // If there was already a lookahead pass, record this result as Approach result\n            approachLayoutInfo = result\n        } else {\n            if (isLookingAhead) {\n                hasLookaheadOccurred = true\n            }\n            scrollToBeConsumed -= result.consumedScroll\n            layoutInfoState.value = result\n\n            canScrollBackward = result.canScrollBackward\n            canScrollForward = result.canScrollForward\n\n            if (visibleItemsStayedTheSame) {\n                scrollPosition.updateScrollOffset(result.firstVisibleLineScrollOffset)\n            } else {\n                scrollPosition.updateFromMeasureResult(result)\n                if (prefetchingEnabled) {\n                    with(prefetchStrategy) { prefetchScope.onVisibleItemsUpdated(result) }\n                }\n            }\n\n            if (isLookingAhead) {\n                _lazyLayoutScrollDeltaBetweenPasses.updateScrollDeltaForApproach(\n                    result.scrollBackAmount,\n                    result.density,\n                    result.coroutineScope,\n                )\n            }\n            numMeasurePasses++\n        }\n    }\n\n    private val _lazyLayoutScrollDeltaBetweenPasses = LazyLayoutScrollDeltaBetweenPasses()\n\n    internal val scrollDeltaBetweenPasses\n        get() = _lazyLayoutScrollDeltaBetweenPasses.scrollDeltaBetweenPasses\n\n    /**\n     * When the user provided custom keys for the items we can try to detect when there were items\n     * added or removed before our current first visible item and keep this item as the first\n     * visible one even given that its index has been changed.\n     */\n    internal fun updateScrollPositionIfTheFirstItemWasMoved(\n        itemProvider: LazyGridItemProvider,\n        firstItemIndex: Int,\n    ): Int = scrollPosition.updateScrollPositionIfTheFirstItemWasMoved(itemProvider, firstItemIndex)\n\n    companion object {\n        /** The default [Saver] implementation for [LazyGridState]. */\n        val Saver: Saver<LazyGridState, *> =\n            listSaver(\n                save = { listOf(it.firstVisibleItemIndex, it.firstVisibleItemScrollOffset) },\n                restore = {\n                    LazyGridState(\n                        firstVisibleItemIndex = it[0],\n                        firstVisibleItemScrollOffset = it[1],\n                    )\n                },\n            )\n\n        /**\n         * A [Saver] implementation for [LazyGridState] that handles setting a custom\n         * [LazyGridPrefetchStrategy].\n         */\n        @ExperimentalFoundationApi\n        internal fun saver(prefetchStrategy: LazyGridPrefetchStrategy): Saver<LazyGridState, *> =\n            listSaver(\n                save = { listOf(it.firstVisibleItemIndex, it.firstVisibleItemScrollOffset) },\n                restore = {\n                    LazyGridState(\n                        firstVisibleItemIndex = it[0],\n                        firstVisibleItemScrollOffset = it[1],\n                        prefetchStrategy,\n                    )\n                },\n            )\n\n        /**\n         * A [Saver] implementation for [LazyGridState] that handles setting a custom\n         * [LazyLayoutCacheWindow].\n         */\n        @ExperimentalFoundationApi\n        internal fun saver(cacheWindow: LazyLayoutCacheWindow): Saver<LazyGridState, *> =\n            listSaver(\n                save = { listOf(it.firstVisibleItemIndex, it.firstVisibleItemScrollOffset) },\n                restore = {\n                    LazyGridState(\n                        cacheWindow = cacheWindow,\n                        firstVisibleItemIndex = it[0],\n                        firstVisibleItemScrollOffset = it[1],\n                    )\n                },\n            )\n    }\n}\n\nprivate val EmptyLazyGridLayoutInfo =\n    LazyGridMeasureResult(\n        firstVisibleLine = null,\n        firstVisibleLineScrollOffset = 0,\n        canScrollForward = false,\n        consumedScroll = 0f,\n        measureResult =\n            object : MeasureResult {\n                override val width: Int = 0\n                override val height: Int = 0\n\n                @Suppress(\"PrimitiveInCollection\")\n                override val alignmentLines: Map<AlignmentLine, Int> = emptyMap()\n\n                override fun placeChildren() {}\n            },\n        scrollBackAmount = 0f,\n        visibleItemsInfo = emptyList(),\n        viewportStartOffset = 0,\n        viewportEndOffset = 0,\n        totalItemsCount = 0,\n        reverseLayout = false,\n        orientation = Orientation.Vertical,\n        afterContentPadding = 0,\n        mainAxisItemSpacing = 0,\n        remeasureNeeded = false,\n        density = Density(1f),\n        slotsPerLine = 0,\n        coroutineScope = CoroutineScope(EmptyCoroutineContext),\n        prefetchInfoRetriever = { emptyList() },\n        lineIndexProvider = { -1 },\n    )\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicTextField.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.text\n\nimport androidx.compose.foundation.ComposeFoundationFlags\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.ScrollState\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.ScrollableDefaults\nimport androidx.compose.foundation.gestures.scrollable\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsFocusedAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.text.contextmenu.modifier.ToolbarRequesterImpl\nimport androidx.compose.foundation.text.handwriting.stylusHandwriting\nimport androidx.compose.foundation.text.input.InputTransformation\nimport androidx.compose.foundation.text.input.KeyboardActionHandler\nimport androidx.compose.foundation.text.input.OutputTransformation\nimport androidx.compose.foundation.text.input.TextFieldDecorator\nimport androidx.compose.foundation.text.input.TextFieldLineLimits\nimport androidx.compose.foundation.text.input.TextFieldLineLimits.MultiLine\nimport androidx.compose.foundation.text.input.TextFieldLineLimits.SingleLine\nimport androidx.compose.foundation.text.input.TextFieldState\nimport androidx.compose.foundation.text.input.internal.CodepointTransformation\nimport androidx.compose.foundation.text.input.internal.SingleLineCodepointTransformation\nimport androidx.compose.foundation.text.input.internal.TextFieldCoreModifier\nimport androidx.compose.foundation.text.input.internal.TextFieldDecoratorModifier\nimport androidx.compose.foundation.text.input.internal.TextFieldTextLayoutModifier\nimport androidx.compose.foundation.text.input.internal.TextLayoutState\nimport androidx.compose.foundation.text.input.internal.TransformedTextFieldState\nimport androidx.compose.foundation.text.input.internal.collectIsDragAndDropHoveredAsState\nimport androidx.compose.foundation.text.input.internal.selection.TextFieldSelectionState\nimport androidx.compose.foundation.text.input.internal.selection.TextFieldSelectionState.InputType\nimport androidx.compose.foundation.text.input.internal.selection.TextToolbarHandler\nimport androidx.compose.foundation.text.input.internal.selection.TextToolbarState\nimport androidx.compose.foundation.text.input.internal.selection.addBasicTextFieldTextContextMenuComponents\nimport androidx.compose.foundation.text.input.internal.selection.menuItem\nimport androidx.compose.foundation.text.selection.SelectedTextType\nimport androidx.compose.foundation.text.selection.SelectionHandle\nimport androidx.compose.foundation.text.selection.rememberPlatformSelectionBehaviors\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.input.pointer.PointerIcon\nimport androidx.compose.ui.input.pointer.pointerHoverIcon\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.layout.layout\nimport androidx.compose.ui.platform.LocalClipboard\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalHapticFeedback\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.platform.LocalTextToolbar\nimport androidx.compose.ui.platform.LocalWindowInfo\nimport androidx.compose.ui.platform.TextToolbarStatus\nimport androidx.compose.ui.text.TextLayoutResult\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.text.input.TextFieldValue\nimport androidx.compose.ui.text.input.VisualTransformation\nimport androidx.compose.ui.text.intl.LocaleList\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.DpSize\nimport androidx.compose.ui.unit.constrain\nimport androidx.compose.ui.unit.dp\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.CoroutineStart\nimport kotlinx.coroutines.channels.BufferOverflow\nimport kotlinx.coroutines.flow.MutableSharedFlow\nimport kotlinx.coroutines.launch\n\nprivate object BasicTextFieldDefaults {\n    val CursorBrush = SolidColor(Color.Black)\n}\n\n/**\n * Basic text composable that provides an interactive box that accepts text input through software\n * or hardware keyboard, but provides no decorations like hint or placeholder.\n *\n * All the editing state of this composable is hoisted through [state]. Whenever the contents of\n * this composable change via user input or semantics, [TextFieldState.text] gets updated.\n * Similarly, all the programmatic updates made to [state] also reflect on this composable.\n *\n * If you want to add decorations to your text field, such as icon or similar, and increase the hit\n * target area, use the decorator.\n *\n * In order to filter (e.g. only allow digits, limit the number of characters), or change (e.g.\n * convert every character to uppercase) the input received from the user, use an\n * [InputTransformation].\n *\n * Limiting the height of the [BasicTextField] in terms of line count and choosing a scroll\n * direction can be achieved by using [TextFieldLineLimits].\n *\n * Scroll state of the composable is also hoisted to enable observation and manipulation of the\n * scroll behavior by the developer, e.g. bringing a searched keyword into view by scrolling to its\n * position without focusing, or changing selection.\n *\n * It's also possible to internally wrap around an existing TextFieldState and expose a more\n * lightweight state hoisting mechanism through a value that dictates the content of the TextField\n * and an onValueChange callback that communicates the changes to this value.\n *\n * @param state [TextFieldState] object that holds the internal editing state of [BasicTextField].\n * @param modifier optional [Modifier] for this text field.\n * @param enabled controls the enabled state of the [BasicTextField]. When `false`, the text field\n *   will be neither editable nor focusable, the input of the text field will not be selectable.\n * @param readOnly controls the editable state of the [BasicTextField]. When `true`, the text field\n *   can not be modified, however, a user can focus it and copy text from it. Read-only text fields\n *   are usually used to display pre-filled forms that user can not edit.\n * @param inputTransformation Optional [InputTransformation] that will be used to transform changes\n *   to the [TextFieldState] made by the user. The transformation will be applied to changes made by\n *   hardware and software keyboard events, pasting or dropping text, accessibility services, and\n *   tests. The transformation will _not_ be applied when changing the [state] programmatically, or\n *   when the transformation is changed. If the transformation is changed on an existing text field,\n *   it will be applied to the next user edit. the transformation will not immediately affect the\n *   current [state].\n * @param textStyle Typographic and graphic style configuration for text content that's displayed in\n *   the editor.\n * @param keyboardOptions Software keyboard options that contain configurations such as\n *   [KeyboardType] and [ImeAction].\n * @param onKeyboardAction Called when the user presses the action button in the input method editor\n *   (IME), or by pressing the enter key on a hardware keyboard if the [lineLimits] is configured as\n *   [TextFieldLineLimits.SingleLine]. By default this parameter is null, and would execute the\n *   default behavior for a received IME Action e.g., [ImeAction.Done] would close the keyboard,\n *   [ImeAction.Next] would switch the focus to the next focusable item on the screen.\n * @param lineLimits Whether the text field should be [SingleLine], scroll horizontally, and ignore\n *   newlines; or [MultiLine] and grow and scroll vertically. If [SingleLine] is passed, all newline\n *   characters ('\\n') within the text will be replaced with regular whitespace (' '), ensuring that\n *   the contents of the text field are presented in a single line.\n * @param onTextLayout Callback that is executed when the text layout becomes queryable. The\n *   callback receives a function that returns a [TextLayoutResult] if the layout can be calculated,\n *   or null if it cannot. The function reads the layout result from a snapshot state object, and\n *   will invalidate its caller when the layout result changes. A [TextLayoutResult] object contains\n *   paragraph information, size of the text, baselines and other details. The callback can be used\n *   to add additional decoration or functionality to the text. For example, to draw a cursor or\n *   selection around the text. [Density] scope is the one that was used while creating the given\n *   text layout.\n * @param interactionSource the [MutableInteractionSource] representing the stream of [Interaction]s\n *   for this TextField. You can create and pass in your own remembered [MutableInteractionSource]\n *   if you want to observe [Interaction]s and customize the appearance / behavior of this TextField\n *   for different [Interaction]s.\n * @param cursorBrush [Brush] to paint cursor with. If [SolidColor] with [Color.Unspecified]\n *   provided, then no cursor will be drawn.\n * @param outputTransformation An [OutputTransformation] that transforms how the contents of the\n *   text field are presented.\n * @param decorator Allows to add decorations around text field, such as icon, placeholder, helper\n *   messages or similar, and automatically increase the hit target area of the text field.\n * @param scrollState Scroll state that manages either horizontal or vertical scroll of TextField.\n *   If [lineLimits] is [SingleLine], this text field is treated as single line with horizontal\n *   scroll behavior. In other cases the text field becomes vertically scrollable.\n * @sample androidx.compose.foundation.samples.BasicTextFieldDecoratorSample\n * @sample androidx.compose.foundation.samples.BasicTextFieldCustomInputTransformationSample\n * @sample androidx.compose.foundation.samples.BasicTextFieldWithValueOnValueChangeSample\n */\n// This takes a composable lambda, but it is not primarily a container.\n@Suppress(\"ComposableLambdaParameterPosition\")\n@Composable\nfun BasicTextField(\n    state: TextFieldState,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    readOnly: Boolean = false,\n    inputTransformation: InputTransformation? = null,\n    textStyle: TextStyle = TextStyle.Default,\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,\n    onKeyboardAction: KeyboardActionHandler? = null,\n    lineLimits: TextFieldLineLimits = TextFieldLineLimits.Default,\n    onTextLayout: (Density.(getResult: () -> TextLayoutResult?) -> Unit)? = null,\n    interactionSource: MutableInteractionSource? = null,\n    cursorBrush: Brush = BasicTextFieldDefaults.CursorBrush,\n    outputTransformation: OutputTransformation? = null,\n    decorator: TextFieldDecorator? = null,\n    scrollState: ScrollState = rememberScrollState(),\n    // Last parameter must not be a function unless it's intended to be commonly used as a trailing\n    // lambda.\n) {\n    BasicTextField(\n        state = state,\n        modifier = modifier,\n        enabled = enabled,\n        readOnly = readOnly,\n        inputTransformation = inputTransformation,\n        textStyle = textStyle,\n        keyboardOptions = keyboardOptions,\n        onKeyboardAction = onKeyboardAction,\n        lineLimits = lineLimits,\n        onTextLayout = onTextLayout,\n        interactionSource = interactionSource,\n        cursorBrush = cursorBrush,\n        codepointTransformation = null,\n        outputTransformation = outputTransformation,\n        decorator = decorator,\n        scrollState = scrollState,\n    )\n}\n\n/**\n * Internal core text field that accepts a [CodepointTransformation].\n *\n * @param codepointTransformation Visual transformation interface that provides a 1-to-1 mapping of\n *   codepoints.\n */\n// This takes a composable lambda, but it is not primarily a container.\n@Suppress(\"ComposableLambdaParameterPosition\")\n@Composable\ninternal fun BasicTextField(\n    state: TextFieldState,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    readOnly: Boolean = false,\n    inputTransformation: InputTransformation? = null,\n    textStyle: TextStyle = TextStyle.Default,\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,\n    onKeyboardAction: KeyboardActionHandler? = null,\n    lineLimits: TextFieldLineLimits = TextFieldLineLimits.Default,\n    onTextLayout: (Density.(getResult: () -> TextLayoutResult?) -> Unit)? = null,\n    interactionSource: MutableInteractionSource? = null,\n    cursorBrush: Brush = BasicTextFieldDefaults.CursorBrush,\n    codepointTransformation: CodepointTransformation? = null,\n    outputTransformation: OutputTransformation? = null,\n    decorator: TextFieldDecorator? = null,\n    scrollState: ScrollState = rememberScrollState(),\n    isPassword: Boolean = false,\n    // Last parameter must not be a function unless it's intended to be commonly used as a trailing\n    // lambda.\n) {\n    val density = LocalDensity.current\n    val layoutDirection = LocalLayoutDirection.current\n    val singleLine = lineLimits == SingleLine\n    // We're using this to communicate focus state to cursor for now.\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    val orientation = if (singleLine) Orientation.Horizontal else Orientation.Vertical\n    val isFocused = interactionSource.collectIsFocusedAsState().value\n    val isDragHovered = interactionSource.collectIsDragAndDropHoveredAsState().value\n    // Avoid reading LocalWindowInfo.current.isWindowFocused when the text field is not focused;\n    // otherwise all text fields in a window will be recomposed when it becomes focused.\n    val isWindowAndTextFieldFocused = isFocused && LocalWindowInfo.current.isWindowFocused\n    val stylusHandwritingTrigger = remember {\n        MutableSharedFlow<Unit>(replay = 1, onBufferOverflow = BufferOverflow.DROP_LATEST)\n    }\n\n    val transformedState =\n        remember(state, codepointTransformation, outputTransformation) {\n            // First prefer provided codepointTransformation if not null, e.g. BasicSecureTextField\n            // would send PasswordTransformation. Second, apply a SingleLineCodepointTransformation\n            // if\n            // text field is configured to be single line. Else, don't apply any visual\n            // transformation.\n            val appliedCodepointTransformation =\n                codepointTransformation ?: SingleLineCodepointTransformation.takeIf { singleLine }\n            TransformedTextFieldState(\n                textFieldState = state,\n                inputTransformation = inputTransformation,\n                codepointTransformation = appliedCodepointTransformation,\n                outputTransformation = outputTransformation,\n            )\n        }\n\n    // Invalidate textLayoutState if TextFieldState itself has changed, since TextLayoutState\n    // would be carrying an invalid TextFieldState in its nonMeasureInputs.\n    val textLayoutState = remember(transformedState) { TextLayoutState() }\n\n    // InputTransformation.keyboardOptions might be backed by Snapshot state.\n    // Read in a restartable composable scope to make sure the resolved value is always up-to-date.\n    val resolvedKeyboardOptions =\n        keyboardOptions.fillUnspecifiedValuesWith(inputTransformation?.keyboardOptions)\n\n    val coroutineScope = rememberCoroutineScope()\n    @OptIn(ExperimentalFoundationApi::class)\n    val platformSelectionBehaviors =\n        if (ComposeFoundationFlags.isSmartSelectionEnabled) {\n            val resolvedLocaleList = textStyle.localeList ?: LocaleList.current\n            rememberPlatformSelectionBehaviors(SelectedTextType.EditableText, resolvedLocaleList)\n        } else {\n            null\n        }\n    val toolbarRequester = remember { ToolbarRequesterImpl() }\n    val currentClipboard = LocalClipboard.current\n    val textFieldSelectionState =\n        remember(transformedState) {\n            TextFieldSelectionState(\n                textFieldState = transformedState,\n                textLayoutState = textLayoutState,\n                density = density,\n                enabled = enabled,\n                readOnly = readOnly,\n                isFocused = isWindowAndTextFieldFocused,\n                isPassword = isPassword,\n                toolbarRequester = toolbarRequester,\n                coroutineScope = coroutineScope,\n                platformSelectionBehaviors = platformSelectionBehaviors,\n                clipboard = currentClipboard,\n            )\n        }\n    val currentHapticFeedback = LocalHapticFeedback.current\n    val currentTextToolbar = LocalTextToolbar.current\n\n    val textToolbarHandler =\n        remember(coroutineScope, currentTextToolbar) {\n            object : TextToolbarHandler {\n                override suspend fun showTextToolbar(\n                    selectionState: TextFieldSelectionState,\n                    rect: Rect,\n                ) =\n                    with(selectionState) {\n                        selectionState.updateClipboardEntry()\n                        currentTextToolbar.showMenu(\n                            rect = rect,\n                            onCopyRequested =\n                                menuItem(canShowCopyMenuItem(), TextToolbarState.None) {\n                                    coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) {\n                                        copy()\n                                    }\n                                },\n                            onPasteRequested =\n                                menuItem(canShowPasteMenuItem(), TextToolbarState.None) {\n                                    coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) {\n                                        paste()\n                                    }\n                                },\n                            onCutRequested =\n                                menuItem(canShowCutMenuItem(), TextToolbarState.None) {\n                                    coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) {\n                                        cut()\n                                    }\n                                },\n                            onSelectAllRequested =\n                                menuItem(canShowSelectAllMenuItem(), TextToolbarState.Selection) {\n                                    selectAll()\n                                },\n                            onAutofillRequested =\n                                menuItem(canShowAutofillMenuItem(), TextToolbarState.None) {\n                                    autofill()\n                                },\n                        )\n                    }\n\n                override fun hideTextToolbar() {\n                    if (currentTextToolbar.status == TextToolbarStatus.Shown) {\n                        currentTextToolbar.hide()\n                    }\n                }\n            }\n        }\n\n    rememberClipboardEventsHandler(\n        isEnabled = isFocused,\n        onPaste = { textFieldSelectionState.onPasteEvent(it) },\n        onCopy = { textFieldSelectionState.copyWithResult() },\n        onCut = { textFieldSelectionState.cutWithResult() },\n    )\n\n    SideEffect {\n        // These properties are not backed by snapshot state, so they can't be updated directly in\n        // composition.\n        transformedState.update(inputTransformation)\n\n        textFieldSelectionState.update(\n            hapticFeedBack = currentHapticFeedback,\n            clipboard = currentClipboard,\n            density = density,\n            enabled = enabled,\n            readOnly = readOnly,\n            isPassword = isPassword,\n            showTextToolbar = textToolbarHandler,\n        )\n    }\n\n    DisposableEffect(textFieldSelectionState) { onDispose { textFieldSelectionState.dispose() } }\n\n    val overscrollEffect = rememberTextFieldOverscrollEffect()\n\n    val handwritingEnabled =\n        !isPassword &&\n            keyboardOptions.keyboardType != KeyboardType.Password &&\n            keyboardOptions.keyboardType != KeyboardType.NumberPassword\n    val decorationModifiers =\n        modifier\n            .stylusHandwriting(enabled, handwritingEnabled) {\n                // If this is a password field, we can't trigger handwriting.\n                // The expected behavior is 1) request focus 2) show software keyboard.\n                // Note: TextField will show software keyboard automatically when it\n                // gain focus. 3) show a toast message telling that handwriting is not\n                // supported for password fields. TODO(b/335294152)\n                if (handwritingEnabled) {\n                    // Send the handwriting start signal to platform.\n                    // The editor should send the signal when it is focused or is about\n                    // to gain focus, Here are more details:\n                    //   1) if the editor already has an active input session, the\n                    //   platform handwriting service should already listen to this flow\n                    //   and it'll start handwriting right away.\n                    //\n                    //   2) if the editor is not focused, but it'll be focused and\n                    //   create a new input session, one handwriting signal will be\n                    //   replayed when the platform collect this flow. And the platform\n                    //   should trigger handwriting accordingly.\n                    stylusHandwritingTrigger.tryEmit(Unit)\n                }\n            }\n            .then(\n                // semantics + some focus + input session + touch to focus\n                TextFieldDecoratorModifier(\n                    textFieldState = transformedState,\n                    textLayoutState = textLayoutState,\n                    textFieldSelectionState = textFieldSelectionState,\n                    filter = inputTransformation,\n                    enabled = enabled,\n                    readOnly = readOnly,\n                    keyboardOptions = resolvedKeyboardOptions,\n                    keyboardActionHandler = onKeyboardAction,\n                    singleLine = singleLine,\n                    interactionSource = interactionSource,\n                    isPassword = isPassword,\n                    stylusHandwritingTrigger = stylusHandwritingTrigger,\n                )\n            )\n            .scrollable(\n                state = scrollState,\n                orientation = orientation,\n                // Disable scrolling when textField is disabled or another dragging gesture is\n                // taking place\n                enabled =\n                    enabled && textFieldSelectionState.directDragGestureInitiator == InputType.None,\n                reverseDirection =\n                    ScrollableDefaults.reverseDirection(\n                        layoutDirection = layoutDirection,\n                        orientation = orientation,\n                        reverseScrolling = false,\n                    ),\n                interactionSource = interactionSource,\n                overscrollEffect = overscrollEffect,\n            )\n            .pointerHoverIcon(PointerIcon.Text)\n            .addContextMenuComponents(textFieldSelectionState, coroutineScope)\n\n    Box(decorationModifiers, propagateMinConstraints = true) {\n        ContextMenuArea(textFieldSelectionState, enabled) {\n            val nonNullDecorator = decorator ?: DefaultTextFieldDecorator\n            nonNullDecorator.Decoration {\n                val minLines: Int\n                val maxLines: Int\n                if (lineLimits is MultiLine) {\n                    minLines = lineLimits.minHeightInLines\n                    maxLines = lineLimits.maxHeightInLines\n                } else {\n                    minLines = 1\n                    maxLines = 1\n                }\n\n                Box(\n                    propagateMinConstraints = true,\n                    modifier =\n                        Modifier.minHeightForSingleLineField(textLayoutState)\n                            .heightInLines(\n                                textStyle = textStyle,\n                                minLines = minLines,\n                                maxLines = maxLines,\n                            )\n                            .textFieldMinSize(textStyle)\n                            .clipToBounds()\n                            .then(\n                                TextFieldCoreModifier(\n                                    isFocused = isWindowAndTextFieldFocused,\n                                    isDragHovered = isDragHovered,\n                                    textLayoutState = textLayoutState,\n                                    textFieldState = transformedState,\n                                    textFieldSelectionState = textFieldSelectionState,\n                                    cursorBrush = cursorBrush,\n                                    writeable = enabled && !readOnly,\n                                    scrollState = scrollState,\n                                    orientation = orientation,\n                                    toolbarRequester = toolbarRequester,\n                                    platformSelectionBehaviors = platformSelectionBehaviors,\n                                )\n                            ),\n                ) {\n                    Box(\n                        modifier =\n                            TextFieldTextLayoutModifier(\n                                textLayoutState = textLayoutState,\n                                textFieldState = transformedState,\n                                textStyle = textStyle,\n                                singleLine = singleLine,\n                                onTextLayout = onTextLayout,\n                                keyboardOptions = resolvedKeyboardOptions,\n                            )\n                    )\n\n                    if (\n                        enabled &&\n                            isWindowAndTextFieldFocused &&\n                            textFieldSelectionState.isInTouchMode\n                    ) {\n                        TextFieldSelectionHandles(selectionState = textFieldSelectionState)\n                        if (!readOnly) {\n                            TextFieldCursorHandle(selectionState = textFieldSelectionState)\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n@OptIn(ExperimentalFoundationApi::class)\nprivate fun Modifier.minHeightForSingleLineField(textLayoutState: TextLayoutState) =\n    if (ComposeFoundationFlags.isBasicTextFieldMinSizeOptimizationEnabled) {\n        layout { measurable, constraints ->\n            val wrappedConstraints =\n                constraints.constrain(\n                    Constraints(\n                        minWidth = 0,\n                        maxWidth = Constraints.Infinity,\n                        minHeight = textLayoutState.minHeightForSingleLineField.roundToPx(),\n                        maxHeight = Constraints.Infinity,\n                    )\n                )\n            val placeable = measurable.measure(wrappedConstraints)\n            layout(placeable.width, placeable.height) { placeable.placeRelative(0, 0) }\n        }\n    } else {\n        heightIn(min = textLayoutState.minHeightForSingleLineField)\n    }\n\n@OptIn(ExperimentalFoundationApi::class)\nprivate fun Modifier.addContextMenuComponents(\n    textFieldSelectionState: TextFieldSelectionState,\n    coroutineScope: CoroutineScope,\n): Modifier =\n    if (ComposeFoundationFlags.isNewContextMenuEnabled)\n        addBasicTextFieldTextContextMenuComponents(textFieldSelectionState, coroutineScope)\n    else this\n\n@Composable\ninternal fun TextFieldCursorHandle(selectionState: TextFieldSelectionState) {\n    // Does not recompose if only position of the handle changes.\n    val cursorHandleVisible by\n        remember(selectionState) {\n            derivedStateOf { selectionState.getCursorHandleState(includePosition = false).visible }\n        }\n    if (cursorHandleVisible) {\n        CursorHandle(\n            offsetProvider = {\n                selectionState.getCursorHandleState(includePosition = true).position\n            },\n            modifier =\n                Modifier.pointerInput(selectionState) {\n                    with(selectionState) { cursorHandleGestures() }\n                },\n            minTouchTargetSize = MinTouchTargetSizeForHandles,\n        )\n    }\n}\n\n@Composable\ninternal fun TextFieldSelectionHandles(selectionState: TextFieldSelectionState) {\n    // Does not recompose if only position of the handle changes.\n    val startHandleState by\n        remember(selectionState) {\n            derivedStateOf {\n                selectionState.getSelectionHandleState(\n                    isStartHandle = true,\n                    includePosition = false,\n                )\n            }\n        }\n    // Read once here to avoid repeating derived state reads\n    val startHandle = startHandleState\n    if (startHandle.visible) {\n        SelectionHandle(\n            offsetProvider = {\n                selectionState\n                    .getSelectionHandleState(isStartHandle = true, includePosition = true)\n                    .position\n            },\n            isStartHandle = true,\n            direction = startHandle.direction,\n            handlesCrossed = startHandle.handlesCrossed,\n            modifier =\n                Modifier.pointerInput(selectionState) {\n                    with(selectionState) { selectionHandleGestures(true) }\n                },\n            lineHeight = startHandle.lineHeight,\n            minTouchTargetSize = MinTouchTargetSizeForHandles,\n        )\n    }\n\n    // Does not recompose if only position of the handle changes.\n    val endHandleState by\n        remember(selectionState) {\n            derivedStateOf {\n                selectionState.getSelectionHandleState(\n                    isStartHandle = false,\n                    includePosition = false,\n                )\n            }\n        }\n    // Read once here to avoid repeating derived state reads\n    val endHandle = endHandleState\n    if (endHandle.visible) {\n        SelectionHandle(\n            offsetProvider = {\n                selectionState\n                    .getSelectionHandleState(isStartHandle = false, includePosition = true)\n                    .position\n            },\n            isStartHandle = false,\n            direction = endHandle.direction,\n            handlesCrossed = endHandle.handlesCrossed,\n            modifier =\n                Modifier.pointerInput(selectionState) {\n                    with(selectionState) { selectionHandleGestures(false) }\n                },\n            lineHeight = endHandle.lineHeight,\n            minTouchTargetSize = MinTouchTargetSizeForHandles,\n        )\n    }\n}\n\nprivate val DefaultTextFieldDecorator = TextFieldDecorator { it() }\n\n/**\n * Defines a minimum touch target area size for Selection and Cursor handles.\n *\n * Although BasicTextField is not part of Material spec, this accessibility feature is important\n * enough to be included at foundation layer, and also TextField cannot change selection handles\n * provided by BasicTextField to somehow achieve this accessibility requirement.\n *\n * This value is adopted from Android platform's TextView implementation.\n */\nprivate val MinTouchTargetSizeForHandles = DpSize(40.dp, 40.dp)\n\n/**\n * Basic composable that enables users to edit text via hardware or software keyboard, but provides\n * no decorations like hint or placeholder.\n *\n * Whenever the user edits the text, [onValueChange] is called with the most up to date state\n * represented by [String] with which developer is expected to update their state.\n *\n * Unlike [TextFieldValue] overload, this composable does not let the developer control selection,\n * cursor and text composition information. Please check [TextFieldValue] and corresponding\n * [BasicTextField] overload for more information.\n *\n * It is crucial that the value provided to the [onValueChange] is fed back into [BasicTextField] in\n * order to actually display and continue to edit that text in the field. The value you feed back\n * into the field may be different than the one provided to the [onValueChange] callback, however\n * the following caveats apply:\n * - The new value must be provided to [BasicTextField] immediately (i.e. by the next frame), or the\n *   text field may appear to glitch, e.g. the cursor may jump around. For more information about\n *   this requirement, see\n *   [this article](https://developer.android.com/jetpack/compose/text/user-input#state-practices).\n * - The value fed back into the field may be different from the one passed to [onValueChange],\n *   although this may result in the input connection being restarted, which can make the keyboard\n *   flicker for the user. This is acceptable when you're using the callback to, for example, filter\n *   out certain types of input, but should probably not be done on every update when entering\n *   freeform text.\n *\n * This composable provides basic text editing functionality, however does not include any\n * decorations such as borders, hints/placeholder. A design system based implementation such as\n * Material Design Filled text field is typically what is needed to cover most of the needs. This\n * composable is designed to be used when a custom implementation for different design system is\n * needed.\n *\n * Example usage:\n *\n * @sample androidx.compose.foundation.samples.BasicTextFieldWithStringSample\n *\n * For example, if you need to include a placeholder in your TextField, you can write a composable\n * using the decoration box like this:\n *\n * @sample androidx.compose.foundation.samples.PlaceholderBasicTextFieldSample\n *\n * If you want to add decorations to your text field, such as icon or similar, and increase the hit\n * target area, use the decoration box:\n *\n * @sample androidx.compose.foundation.samples.TextFieldWithIconSample\n *\n * In order to create formatted text field, for example for entering a phone number or a social\n * security number, use a [visualTransformation] parameter. Below is the example of the text field\n * for entering a credit card number:\n *\n * @sample androidx.compose.foundation.samples.CreditCardSample\n *\n * Note: This overload does not support [KeyboardOptions.showKeyboardOnFocus].\n *\n * @param value the input [String] text to be shown in the text field\n * @param onValueChange the callback that is triggered when the input service updates the text. An\n *   updated text comes as a parameter of the callback\n * @param modifier optional [Modifier] for this text field.\n * @param enabled controls the enabled state of the [BasicTextField]. When `false`, the text field\n *   will be neither editable nor focusable, the input of the text field will not be selectable\n * @param readOnly controls the editable state of the [BasicTextField]. When `true`, the text field\n *   can not be modified, however, a user can focus it and copy text from it. Read-only text fields\n *   are usually used to display pre-filled forms that user can not edit\n * @param textStyle Style configuration that applies at character level such as color, font etc.\n * @param keyboardOptions software keyboard options that contains configuration such as\n *   [KeyboardType] and [ImeAction].\n * @param keyboardActions when the input service emits an IME action, the corresponding callback is\n *   called. Note that this IME action may be different from what you specified in\n *   [KeyboardOptions.imeAction].\n * @param singleLine when set to true, this text field becomes a single horizontally scrolling text\n *   field instead of wrapping onto multiple lines. The keyboard will be informed to not show the\n *   return key as the [ImeAction]. [maxLines] and [minLines] are ignored as both are automatically\n *   set to 1.\n * @param maxLines the maximum height in terms of maximum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.\n * @param minLines the minimum height in terms of minimum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.\n * @param visualTransformation The visual transformation filter for changing the visual\n *   representation of the input. By default no visual transformation is applied.\n * @param onTextLayout Callback that is executed when a new text layout is calculated. A\n *   [TextLayoutResult] object that callback provides contains paragraph information, size of the\n *   text, baselines and other details. The callback can be used to add additional decoration or\n *   functionality to the text. For example, to draw a cursor or selection around the text.\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this text field. You can use this to change the text field's\n *   appearance or preview the text field in different states. Note that if `null` is provided,\n *   interactions will still happen internally.\n * @param cursorBrush [Brush] to paint cursor with. If [SolidColor] with [Color.Unspecified]\n *   provided, there will be no cursor drawn\n * @param decorationBox Composable lambda that allows to add decorations around text field, such as\n *   icon, placeholder, helper messages or similar, and automatically increase the hit target area\n *   of the text field. To allow you to control the placement of the inner text field relative to\n *   your decorations, the text field implementation will pass in a framework-controlled composable\n *   parameter \"innerTextField\" to the decorationBox lambda you provide. You must call\n *   innerTextField exactly once.\n */\n@Composable\nfun BasicTextField(\n    value: String,\n    onValueChange: (String) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    readOnly: Boolean = false,\n    textStyle: TextStyle = TextStyle.Default,\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,\n    keyboardActions: KeyboardActions = KeyboardActions.Default,\n    singleLine: Boolean = false,\n    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,\n    minLines: Int = 1,\n    visualTransformation: VisualTransformation = VisualTransformation.None,\n    onTextLayout: (TextLayoutResult) -> Unit = {},\n    interactionSource: MutableInteractionSource? = null,\n    cursorBrush: Brush = SolidColor(Color.Black),\n    decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =\n        @Composable { innerTextField -> innerTextField() },\n) {\n    // Holds the latest internal TextFieldValue state. We need to keep it to have the correct value\n    // of the composition.\n    var textFieldValueState by remember { mutableStateOf(TextFieldValue(text = value)) }\n    // Holds the latest TextFieldValue that BasicTextField was recomposed with. We couldn't simply\n    // pass `TextFieldValue(text = value)` to the CoreTextField because we need to preserve the\n    // composition.\n    val textFieldValue = textFieldValueState.copy(text = value)\n\n    SideEffect {\n        if (\n            textFieldValue.selection != textFieldValueState.selection ||\n                textFieldValue.composition != textFieldValueState.composition\n        ) {\n            textFieldValueState = textFieldValue\n        }\n    }\n    // Last String value that either text field was recomposed with or updated in the onValueChange\n    // callback. We keep track of it to prevent calling onValueChange(String) for same String when\n    // CoreTextField's onValueChange is called multiple times without recomposition in between.\n    var lastTextValue by remember(value) { mutableStateOf(value) }\n\n    CoreTextField(\n        value = textFieldValue,\n        onValueChange = { newTextFieldValueState ->\n            textFieldValueState = newTextFieldValueState\n\n            val stringChangedSinceLastInvocation = lastTextValue != newTextFieldValueState.text\n            lastTextValue = newTextFieldValueState.text\n\n            if (stringChangedSinceLastInvocation) {\n                onValueChange(newTextFieldValueState.text)\n            }\n        },\n        modifier = modifier,\n        textStyle = textStyle,\n        visualTransformation = visualTransformation,\n        onTextLayout = onTextLayout,\n        interactionSource = interactionSource,\n        cursorBrush = cursorBrush,\n        imeOptions = keyboardOptions.toImeOptions(singleLine = singleLine),\n        keyboardActions = keyboardActions,\n        softWrap = !singleLine,\n        minLines = if (singleLine) 1 else minLines,\n        maxLines = if (singleLine) 1 else maxLines,\n        decorationBox = decorationBox,\n        enabled = enabled,\n        readOnly = readOnly,\n    )\n}\n\n/**\n * Basic composable that enables users to edit text via hardware or software keyboard, but provides\n * no decorations like hint or placeholder.\n *\n * Whenever the user edits the text, [onValueChange] is called with the most up to date state\n * represented by [TextFieldValue]. [TextFieldValue] contains the text entered by user, as well as\n * selection, cursor and text composition information. Please check [TextFieldValue] for the\n * description of its contents.\n *\n * It is crucial that the value provided to the [onValueChange] is fed back into [BasicTextField] in\n * order to actually display and continue to edit that text in the field. The value you feed back\n * into the field may be different than the one provided to the [onValueChange] callback, however\n * the following caveats apply:\n * - The new value must be provided to [BasicTextField] immediately (i.e. by the next frame), or the\n *   text field may appear to glitch, e.g. the cursor may jump around. For more information about\n *   this requirement, see\n *   [this article](https://developer.android.com/jetpack/compose/text/user-input#state-practices).\n * - The value fed back into the field may be different from the one passed to [onValueChange],\n *   although this may result in the input connection being restarted, which can make the keyboard\n *   flicker for the user. This is acceptable when you're using the callback to, for example, filter\n *   out certain types of input, but should probably not be done on every update when entering\n *   freeform text.\n *\n * This composable provides basic text editing functionality, however does not include any\n * decorations such as borders, hints/placeholder. A design system based implementation such as\n * Material Design Filled text field is typically what is needed to cover most of the needs. This\n * composable is designed to be used when a custom implementation for different design system is\n * needed.\n *\n * Example usage:\n *\n * @sample androidx.compose.foundation.samples.BasicTextFieldSample\n *\n * For example, if you need to include a placeholder in your TextField, you can write a composable\n * using the decoration box like this:\n *\n * @sample androidx.compose.foundation.samples.PlaceholderBasicTextFieldSample\n *\n * If you want to add decorations to your text field, such as icon or similar, and increase the hit\n * target area, use the decoration box:\n *\n * @sample androidx.compose.foundation.samples.TextFieldWithIconSample\n *\n * Note: This overload does not support [KeyboardOptions.showKeyboardOnFocus].\n *\n * @param value The [androidx.compose.ui.text.input.TextFieldValue] to be shown in the\n *   [BasicTextField].\n * @param onValueChange Called when the input service updates the values in [TextFieldValue].\n * @param modifier optional [Modifier] for this text field.\n * @param enabled controls the enabled state of the [BasicTextField]. When `false`, the text field\n *   will be neither editable nor focusable, the input of the text field will not be selectable\n * @param readOnly controls the editable state of the [BasicTextField]. When `true`, the text field\n *   can not be modified, however, a user can focus it and copy text from it. Read-only text fields\n *   are usually used to display pre-filled forms that user can not edit\n * @param textStyle Style configuration that applies at character level such as color, font etc.\n * @param keyboardOptions software keyboard options that contains configuration such as\n *   [KeyboardType] and [ImeAction].\n * @param keyboardActions when the input service emits an IME action, the corresponding callback is\n *   called. Note that this IME action may be different from what you specified in\n *   [KeyboardOptions.imeAction].\n * @param singleLine when set to true, this text field becomes a single horizontally scrolling text\n *   field instead of wrapping onto multiple lines. The keyboard will be informed to not show the\n *   return key as the [ImeAction]. [maxLines] and [minLines] are ignored as both are automatically\n *   set to 1.\n * @param maxLines the maximum height in terms of maximum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.\n * @param minLines the minimum height in terms of minimum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.\n * @param visualTransformation The visual transformation filter for changing the visual\n *   representation of the input. By default no visual transformation is applied.\n * @param onTextLayout Callback that is executed when a new text layout is calculated. A\n *   [TextLayoutResult] object that callback provides contains paragraph information, size of the\n *   text, baselines and other details. The callback can be used to add additional decoration or\n *   functionality to the text. For example, to draw a cursor or selection around the text.\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this text field. You can use this to change the text field's\n *   appearance or preview the text field in different states. Note that if `null` is provided,\n *   interactions will still happen internally.\n * @param cursorBrush [Brush] to paint cursor with. If [SolidColor] with [Color.Unspecified]\n *   provided, there will be no cursor drawn\n * @param decorationBox Composable lambda that allows to add decorations around text field, such as\n *   icon, placeholder, helper messages or similar, and automatically increase the hit target area\n *   of the text field. To allow you to control the placement of the inner text field relative to\n *   your decorations, the text field implementation will pass in a framework-controlled composable\n *   parameter \"innerTextField\" to the decorationBox lambda you provide. You must call\n *   innerTextField exactly once.\n */\n@Composable\nfun BasicTextField(\n    value: TextFieldValue,\n    onValueChange: (TextFieldValue) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    readOnly: Boolean = false,\n    textStyle: TextStyle = TextStyle.Default,\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,\n    keyboardActions: KeyboardActions = KeyboardActions.Default,\n    singleLine: Boolean = false,\n    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,\n    minLines: Int = 1,\n    visualTransformation: VisualTransformation = VisualTransformation.None,\n    onTextLayout: (TextLayoutResult) -> Unit = {},\n    interactionSource: MutableInteractionSource? = null,\n    cursorBrush: Brush = SolidColor(Color.Black),\n    decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =\n        @Composable { innerTextField -> innerTextField() },\n) {\n    CoreTextField(\n        value = value,\n        onValueChange = {\n            if (value != it) {\n                onValueChange(it)\n            }\n        },\n        modifier = modifier,\n        textStyle = textStyle,\n        visualTransformation = visualTransformation,\n        onTextLayout = onTextLayout,\n        interactionSource = interactionSource,\n        cursorBrush = cursorBrush,\n        imeOptions = keyboardOptions.toImeOptions(singleLine = singleLine),\n        keyboardActions = keyboardActions,\n        softWrap = !singleLine,\n        minLines = if (singleLine) 1 else minLines,\n        maxLines = if (singleLine) 1 else maxLines,\n        decorationBox = decorationBox,\n        enabled = enabled,\n        readOnly = readOnly,\n    )\n}\n\n@Deprecated(\"Maintained for binary compatibility\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun BasicTextField(\n    value: String,\n    onValueChange: (String) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    readOnly: Boolean = false,\n    textStyle: TextStyle = TextStyle.Default,\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,\n    keyboardActions: KeyboardActions = KeyboardActions.Default,\n    singleLine: Boolean = false,\n    maxLines: Int = Int.MAX_VALUE,\n    visualTransformation: VisualTransformation = VisualTransformation.None,\n    onTextLayout: (TextLayoutResult) -> Unit = {},\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    cursorBrush: Brush = SolidColor(Color.Black),\n    decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =\n        @Composable { innerTextField -> innerTextField() },\n) {\n    BasicTextField(\n        value = value,\n        onValueChange = onValueChange,\n        modifier = modifier,\n        enabled = enabled,\n        readOnly = readOnly,\n        textStyle = textStyle,\n        keyboardOptions = keyboardOptions,\n        keyboardActions = keyboardActions,\n        singleLine = singleLine,\n        minLines = 1,\n        maxLines = maxLines,\n        visualTransformation = visualTransformation,\n        onTextLayout = onTextLayout,\n        interactionSource = interactionSource,\n        cursorBrush = cursorBrush,\n        decorationBox = decorationBox,\n    )\n}\n\n@Deprecated(\"Maintained for binary compatibility\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun BasicTextField(\n    value: TextFieldValue,\n    onValueChange: (TextFieldValue) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    readOnly: Boolean = false,\n    textStyle: TextStyle = TextStyle.Default,\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,\n    keyboardActions: KeyboardActions = KeyboardActions.Default,\n    singleLine: Boolean = false,\n    maxLines: Int = Int.MAX_VALUE,\n    visualTransformation: VisualTransformation = VisualTransformation.None,\n    onTextLayout: (TextLayoutResult) -> Unit = {},\n    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },\n    cursorBrush: Brush = SolidColor(Color.Black),\n    decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =\n        @Composable { innerTextField -> innerTextField() },\n) {\n    BasicTextField(\n        value = value,\n        onValueChange = onValueChange,\n        modifier = modifier,\n        enabled = enabled,\n        readOnly = readOnly,\n        textStyle = textStyle,\n        keyboardOptions = keyboardOptions,\n        keyboardActions = keyboardActions,\n        singleLine = singleLine,\n        minLines = 1,\n        maxLines = maxLines,\n        visualTransformation = visualTransformation,\n        onTextLayout = onTextLayout,\n        interactionSource = interactionSource,\n        cursorBrush = cursorBrush,\n        decorationBox = decorationBox,\n    )\n}\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/text/BasicText.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.text\n\nimport androidx.compose.foundation.text.modifiers.SelectableTextAnnotatedStringElement\nimport androidx.compose.foundation.text.modifiers.SelectionController\nimport androidx.compose.foundation.text.modifiers.TextAnnotatedStringElement\nimport androidx.compose.foundation.text.modifiers.TextAnnotatedStringNode\nimport androidx.compose.foundation.text.modifiers.TextStringSimpleElement\nimport androidx.compose.foundation.text.modifiers.hasLinks\nimport androidx.compose.foundation.text.selection.LocalSelectionRegistrar\nimport androidx.compose.foundation.text.selection.LocalTextSelectionColors\nimport androidx.compose.foundation.text.selection.SelectionRegistrar\nimport androidx.compose.foundation.text.selection.hasSelection\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.NonRestartableComposable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.Saver\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.graphics.ColorProducer\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.Measurable\nimport androidx.compose.ui.layout.MeasurePolicy\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.platform.LocalFontFamilyResolver\nimport androidx.compose.ui.text.AnnotatedString\nimport androidx.compose.ui.text.Placeholder\nimport androidx.compose.ui.text.TextLayoutResult\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.font.FontFamily\nimport androidx.compose.ui.text.style.TextOverflow\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Constraints.Companion.fitPrioritizingWidth\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.util.fastFilter\nimport androidx.compose.ui.util.fastForEach\nimport androidx.compose.ui.util.fastMapIndexedNotNull\nimport androidx.compose.ui.util.fastRoundToInt\nimport kotlin.math.floor\n\n/**\n * Basic element that displays text and provides semantics / accessibility information. Typically\n * you will instead want to use [androidx.compose.material.Text], which is a higher level Text\n * element that contains semantics and consumes style information from a theme.\n *\n * @param text The text to be displayed.\n * @param modifier [Modifier] to apply to this layout node.\n * @param style Style configuration for the text such as color, font, line height etc.\n * @param onTextLayout Callback that is executed when a new text layout is calculated. A\n *   [TextLayoutResult] object that callback provides contains paragraph information, size of the\n *   text, baselines and other details. The callback can be used to add additional decoration or\n *   functionality to the text. For example, to draw selection around the text.\n * @param overflow How visual overflow should be handled.\n * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the\n *   text will be positioned as if there was unlimited horizontal space. If [softWrap] is false,\n *   [overflow] and TextAlign may have unexpected effects.\n * @param maxLines An optional maximum number of lines for the text to span, wrapping if necessary.\n *   If the text exceeds the given number of lines, it will be truncated according to [overflow] and\n *   [softWrap]. It is required that 1 <= [minLines] <= [maxLines].\n * @param minLines The minimum height in terms of minimum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines].\n * @param color Overrides the text color provided in [style]\n * @param autoSize Enable auto sizing for this text composable. Finds the biggest font size that\n *   fits in the available space and lays the text out with this size. This performs multiple layout\n *   passes and can be slower than using a fixed font size. This takes precedence over sizes defined\n *   through [style]. See [TextAutoSize] and\n *   [androidx.compose.foundation.samples.TextAutoSizeBasicTextSample].\n */\n@Composable\nfun BasicText(\n    text: String,\n    modifier: Modifier = Modifier,\n    style: TextStyle = TextStyle.Default,\n    onTextLayout: ((TextLayoutResult) -> Unit)? = null,\n    overflow: TextOverflow = TextOverflow.Clip,\n    softWrap: Boolean = true,\n    maxLines: Int = Int.MAX_VALUE,\n    minLines: Int = 1,\n    color: ColorProducer? = null,\n    autoSize: TextAutoSize? = null,\n) {\n    validateMinMaxLines(minLines = minLines, maxLines = maxLines)\n    val selectionRegistrar = LocalSelectionRegistrar.current\n    val selectionController =\n        if (selectionRegistrar != null) {\n            val backgroundSelectionColor = LocalTextSelectionColors.current.backgroundColor\n            val selectableId =\n                rememberSaveable(selectionRegistrar, saver = selectionIdSaver(selectionRegistrar)) {\n                    selectionRegistrar.nextSelectableId()\n                }\n            remember(selectableId, selectionRegistrar, backgroundSelectionColor) {\n                SelectionController(selectableId, selectionRegistrar, backgroundSelectionColor)\n            }\n        } else {\n            null\n        }\n\n    val fontFamilyResolver = LocalFontFamilyResolver.current\n\n    BackgroundTextMeasurement(text = text, style = style, fontFamilyResolver = fontFamilyResolver)\n\n    val finalModifier =\n        if (selectionController != null || onTextLayout != null || autoSize != null) {\n            modifier.textModifier(\n                AnnotatedString(text = text),\n                style = style,\n                onTextLayout = onTextLayout,\n                overflow = overflow,\n                softWrap = softWrap,\n                maxLines = maxLines,\n                minLines = minLines,\n                fontFamilyResolver = LocalFontFamilyResolver.current,\n                placeholders = null,\n                onPlaceholderLayout = null,\n                selectionController = selectionController,\n                color = color,\n                onShowTranslation = null,\n                autoSize = autoSize,\n            )\n        } else {\n            modifier then\n                TextStringSimpleElement(\n                    text = text,\n                    style = style,\n                    fontFamilyResolver = fontFamilyResolver,\n                    overflow = overflow,\n                    softWrap = softWrap,\n                    maxLines = maxLines,\n                    minLines = minLines,\n                    color = color,\n                )\n        }\n    Layout(finalModifier, EmptyMeasurePolicy)\n}\n\n/**\n * Basic element that displays text and provides semantics / accessibility information. Typically\n * you will instead want to use [androidx.compose.material.Text], which is a higher level Text\n * element that contains semantics and consumes style information from a theme.\n *\n * @param text The text to be displayed.\n * @param modifier [Modifier] to apply to this layout node.\n * @param style Style configuration for the text such as color, font, line height etc.\n * @param onTextLayout Callback that is executed when a new text layout is calculated. A\n *   [TextLayoutResult] object that callback provides contains paragraph information, size of the\n *   text, baselines and other details. The callback can be used to add additional decoration or\n *   functionality to the text. For example, to draw selection around the text.\n * @param overflow How visual overflow should be handled.\n * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the\n *   text will be positioned as if there was unlimited horizontal space. If [softWrap] is false,\n *   [overflow] and TextAlign may have unexpected effects.\n * @param maxLines An optional maximum number of lines for the text to span, wrapping if necessary.\n *   If the text exceeds the given number of lines, it will be truncated according to [overflow] and\n *   [softWrap]. It is required that 1 <= [minLines] <= [maxLines].\n * @param minLines The minimum height in terms of minimum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines].\n * @param inlineContent A map store composables that replaces certain ranges of the text. It's used\n *   to insert composables into text layout. Check [InlineTextContent] for more information.\n * @param color Overrides the text color provided in [style]\n * @param autoSize Enable auto sizing for this text composable. Finds the biggest font size that\n *   fits in the available space and lays the text out with this size. This performs multiple layout\n *   passes and can be slower than using a fixed font size. This takes precedence over sizes defined\n *   through [style]. See [TextAutoSize] and\n *   [androidx.compose.foundation.samples.TextAutoSizeBasicTextSample].\n */\n@Composable\nfun BasicText(\n    text: AnnotatedString,\n    modifier: Modifier = Modifier,\n    style: TextStyle = TextStyle.Default,\n    onTextLayout: ((TextLayoutResult) -> Unit)? = null,\n    overflow: TextOverflow = TextOverflow.Clip,\n    softWrap: Boolean = true,\n    maxLines: Int = Int.MAX_VALUE,\n    minLines: Int = 1,\n    inlineContent: Map<String, InlineTextContent> = mapOf(),\n    color: ColorProducer? = null,\n    autoSize: TextAutoSize? = null,\n) {\n    validateMinMaxLines(minLines = minLines, maxLines = maxLines)\n    val selectionRegistrar = LocalSelectionRegistrar.current\n    val selectionController =\n        if (selectionRegistrar != null) {\n            val backgroundSelectionColor = LocalTextSelectionColors.current.backgroundColor\n            val selectableId =\n                rememberSaveable(selectionRegistrar, saver = selectionIdSaver(selectionRegistrar)) {\n                    selectionRegistrar.nextSelectableId()\n                }\n            remember(selectableId, selectionRegistrar, backgroundSelectionColor) {\n                SelectionController(selectableId, selectionRegistrar, backgroundSelectionColor)\n            }\n        } else {\n            null\n        }\n    val hasInlineContent = text.hasInlineContent()\n    val hasLinks = text.hasLinks()\n\n    val fontFamilyResolver = LocalFontFamilyResolver.current\n\n    if (!hasInlineContent && !hasLinks) {\n        BackgroundTextMeasurement(\n            text = text,\n            style = style,\n            fontFamilyResolver = fontFamilyResolver,\n            placeholders = null,\n        )\n\n        // this is the same as text: String, use all the early exits\n        Layout(\n            modifier =\n                modifier.textModifier(\n                    text = text,\n                    style = style,\n                    onTextLayout = onTextLayout,\n                    overflow = overflow,\n                    softWrap = softWrap,\n                    maxLines = maxLines,\n                    minLines = minLines,\n                    fontFamilyResolver = fontFamilyResolver,\n                    placeholders = null,\n                    onPlaceholderLayout = null,\n                    selectionController = selectionController,\n                    color = color,\n                    onShowTranslation = null,\n                    autoSize = autoSize,\n                ),\n            EmptyMeasurePolicy,\n        )\n    } else {\n        // takes into account text substitution (for translation) that is happening inside the\n        // TextAnnotatedStringNode\n        var displayedText by remember(text) { mutableStateOf(text) }\n\n        LayoutWithLinksAndInlineContent(\n            modifier = modifier,\n            text = displayedText,\n            onTextLayout = onTextLayout,\n            hasInlineContent = hasInlineContent,\n            inlineContent = inlineContent,\n            style = style,\n            overflow = overflow,\n            softWrap = softWrap,\n            maxLines = maxLines,\n            minLines = minLines,\n            fontFamilyResolver = fontFamilyResolver,\n            selectionController = selectionController,\n            color = color,\n            onShowTranslation = { substitutionValue ->\n                displayedText =\n                    if (substitutionValue.isShowingSubstitution) {\n                        substitutionValue.substitution\n                    } else {\n                        substitutionValue.original\n                    }\n            },\n            autoSize = autoSize,\n        )\n    }\n}\n\n/**\n * Basic element that displays text and provides semantics / accessibility information. Typically\n * you will instead want to use [androidx.compose.material.Text], which is a higher level Text\n * element that contains semantics and consumes style information from a theme.\n *\n * @param text The text to be displayed.\n * @param modifier [Modifier] to apply to this layout node.\n * @param style Style configuration for the text such as color, font, line height etc.\n * @param onTextLayout Callback that is executed when a new text layout is calculated. A\n *   [TextLayoutResult] object that callback provides contains paragraph information, size of the\n *   text, baselines and other details. The callback can be used to add additional decoration or\n *   functionality to the text. For example, to draw selection around the text.\n * @param overflow How visual overflow should be handled.\n * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the\n *   text will be positioned as if there was unlimited horizontal space. If [softWrap] is false,\n *   [overflow] and TextAlign may have unexpected effects.\n * @param maxLines An optional maximum number of lines for the text to span, wrapping if necessary.\n *   If the text exceeds the given number of lines, it will be truncated according to [overflow] and\n *   [softWrap]. It is required that 1 <= [minLines] <= [maxLines].\n * @param minLines The minimum height in terms of minimum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines].\n * @param color Overrides the text color provided in [style]\n */\n@Deprecated(\"Maintained for binary compatibility\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun BasicText(\n    text: String,\n    modifier: Modifier = Modifier,\n    style: TextStyle = TextStyle.Default,\n    onTextLayout: ((TextLayoutResult) -> Unit)? = null,\n    overflow: TextOverflow = TextOverflow.Clip,\n    softWrap: Boolean = true,\n    maxLines: Int = Int.MAX_VALUE,\n    minLines: Int = 1,\n    color: ColorProducer? = null,\n) {\n    BasicText(text, modifier, style, onTextLayout, overflow, softWrap, maxLines, minLines, color)\n}\n\n/**\n * Basic element that displays text and provides semantics / accessibility information. Typically\n * you will instead want to use [androidx.compose.material.Text], which is a higher level Text\n * element that contains semantics and consumes style information from a theme.\n *\n * @param text The text to be displayed.\n * @param modifier [Modifier] to apply to this layout node.\n * @param style Style configuration for the text such as color, font, line height etc.\n * @param onTextLayout Callback that is executed when a new text layout is calculated. A\n *   [TextLayoutResult] object that callback provides contains paragraph information, size of the\n *   text, baselines and other details. The callback can be used to add additional decoration or\n *   functionality to the text. For example, to draw selection around the text.\n * @param overflow How visual overflow should be handled.\n * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in the\n *   text will be positioned as if there was unlimited horizontal space. If [softWrap] is false,\n *   [overflow] and TextAlign may have unexpected effects.\n * @param maxLines An optional maximum number of lines for the text to span, wrapping if necessary.\n *   If the text exceeds the given number of lines, it will be truncated according to [overflow] and\n *   [softWrap]. It is required that 1 <= [minLines] <= [maxLines].\n * @param minLines The minimum height in terms of minimum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines].\n * @param inlineContent A map store composables that replaces certain ranges of the text. It's used\n *   to insert composables into text layout. Check [InlineTextContent] for more information.\n * @param color Overrides the text color provided in [style]\n */\n@Deprecated(\"Maintained for binary compatibility\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun BasicText(\n    text: AnnotatedString,\n    modifier: Modifier = Modifier,\n    style: TextStyle = TextStyle.Default,\n    onTextLayout: ((TextLayoutResult) -> Unit)? = null,\n    overflow: TextOverflow = TextOverflow.Clip,\n    softWrap: Boolean = true,\n    maxLines: Int = Int.MAX_VALUE,\n    minLines: Int = 1,\n    inlineContent: Map<String, InlineTextContent> = mapOf(),\n    color: ColorProducer? = null,\n) {\n    BasicText(\n        text,\n        modifier,\n        style,\n        onTextLayout,\n        overflow,\n        softWrap,\n        maxLines,\n        minLines,\n        inlineContent,\n        color,\n    )\n}\n\n@Deprecated(\"Maintained for binary compatibility\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun BasicText(\n    text: String,\n    modifier: Modifier = Modifier,\n    style: TextStyle = TextStyle.Default,\n    onTextLayout: ((TextLayoutResult) -> Unit)? = null,\n    overflow: TextOverflow = TextOverflow.Clip,\n    softWrap: Boolean = true,\n    maxLines: Int = Int.MAX_VALUE,\n) {\n    BasicText(\n        text = text,\n        modifier = modifier,\n        style = style,\n        onTextLayout = onTextLayout,\n        overflow = overflow,\n        softWrap = softWrap,\n        minLines = 1,\n        maxLines = maxLines,\n    )\n}\n\n@Deprecated(\"Maintained for binary compatibility\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun BasicText(\n    text: AnnotatedString,\n    modifier: Modifier = Modifier,\n    style: TextStyle = TextStyle.Default,\n    onTextLayout: ((TextLayoutResult) -> Unit)? = null,\n    overflow: TextOverflow = TextOverflow.Clip,\n    softWrap: Boolean = true,\n    maxLines: Int = Int.MAX_VALUE,\n    inlineContent: Map<String, InlineTextContent> = mapOf(),\n) {\n    BasicText(\n        text = text,\n        modifier = modifier,\n        style = style,\n        onTextLayout = onTextLayout,\n        overflow = overflow,\n        softWrap = softWrap,\n        maxLines = maxLines,\n        minLines = 1,\n        inlineContent = inlineContent,\n    )\n}\n\n@Deprecated(\"Maintained for binary compat\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun BasicText(\n    text: String,\n    modifier: Modifier = Modifier,\n    style: TextStyle = TextStyle.Default,\n    onTextLayout: ((TextLayoutResult) -> Unit)? = null,\n    overflow: TextOverflow = TextOverflow.Clip,\n    softWrap: Boolean = true,\n    maxLines: Int = Int.MAX_VALUE,\n    minLines: Int = 1,\n) = BasicText(text, modifier, style, onTextLayout, overflow, softWrap, maxLines, minLines)\n\n@Deprecated(\"Maintained for binary compat\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun BasicText(\n    text: AnnotatedString,\n    modifier: Modifier = Modifier,\n    style: TextStyle = TextStyle.Default,\n    onTextLayout: ((TextLayoutResult) -> Unit)? = null,\n    overflow: TextOverflow = TextOverflow.Clip,\n    softWrap: Boolean = true,\n    maxLines: Int = Int.MAX_VALUE,\n    minLines: Int = 1,\n    inlineContent: Map<String, InlineTextContent> = mapOf(),\n) =\n    BasicText(\n        text = text,\n        modifier = modifier,\n        style = style,\n        onTextLayout = onTextLayout,\n        overflow = overflow,\n        softWrap = softWrap,\n        maxLines = maxLines,\n        minLines = minLines,\n        inlineContent = inlineContent,\n    )\n\n/** A custom saver that won't save if no selection is active. */\nprivate fun selectionIdSaver(selectionRegistrar: SelectionRegistrar?) =\n    Saver<Long, Long>(\n        save = { if (selectionRegistrar.hasSelection(it)) it else null },\n        restore = { it },\n    )\n\nprivate object EmptyMeasurePolicy : MeasurePolicy {\n    private val placementBlock: Placeable.PlacementScope.() -> Unit = {}\n\n    override fun MeasureScope.measure(\n        measurables: List<Measurable>,\n        constraints: Constraints,\n    ): MeasureResult {\n        return layout(constraints.maxWidth, constraints.maxHeight, placementBlock = placementBlock)\n    }\n}\n\n/** Measure policy for inline content and links */\nprivate class TextMeasurePolicy(\n    private val shouldMeasureLinks: () -> Boolean,\n    private val placements: () -> List<Rect?>?,\n) : MeasurePolicy {\n    override fun MeasureScope.measure(\n        measurables: List<Measurable>,\n        constraints: Constraints,\n    ): MeasureResult {\n        // inline content\n        val inlineContentMeasurables =\n            measurables.fastFilter { it.parentData !is TextRangeLayoutModifier }\n        val inlineContentToPlace =\n            placements()?.fastMapIndexedNotNull { index, rect ->\n                // PlaceholderRect will be null if it's ellipsized. In that case, the corresponding\n                // inline children won't be measured or placed.\n                rect?.let {\n                    Pair(\n                        inlineContentMeasurables[index].measure(\n                            Constraints(\n                                maxWidth = floor(it.width).toInt(),\n                                maxHeight = floor(it.height).toInt(),\n                            )\n                        ),\n                        IntOffset(it.left.fastRoundToInt(), it.top.fastRoundToInt()),\n                    )\n                }\n            }\n\n        // links\n        val linksMeasurables = measurables.fastFilter { it.parentData is TextRangeLayoutModifier }\n        val linksToPlace =\n            measureWithTextRangeMeasureConstraints(\n                measurables = linksMeasurables,\n                shouldMeasureLinks = shouldMeasureLinks,\n            )\n\n        return layout(constraints.maxWidth, constraints.maxHeight) {\n            // inline content\n            inlineContentToPlace?.fastForEach { (placeable, position) -> placeable.place(position) }\n            // links\n            linksToPlace?.fastForEach { (placeable, measureResult) ->\n                placeable.place(measureResult?.invoke() ?: IntOffset.Zero)\n            }\n        }\n    }\n}\n\n/** Measure policy for links only */\nprivate class LinksTextMeasurePolicy(private val shouldMeasureLinks: () -> Boolean) :\n    MeasurePolicy {\n    override fun MeasureScope.measure(\n        measurables: List<Measurable>,\n        constraints: Constraints,\n    ): MeasureResult {\n        return layout(constraints.maxWidth, constraints.maxHeight) {\n            val linksToPlace =\n                measureWithTextRangeMeasureConstraints(\n                    measurables = measurables,\n                    shouldMeasureLinks = shouldMeasureLinks,\n                )\n            linksToPlace?.fastForEach { (placeable, measureResult) ->\n                placeable.place(measureResult?.invoke() ?: IntOffset.Zero)\n            }\n        }\n    }\n}\n\nprivate fun measureWithTextRangeMeasureConstraints(\n    measurables: List<Measurable>,\n    shouldMeasureLinks: () -> Boolean,\n): List<Pair<Placeable, (() -> IntOffset)?>>? {\n    return if (shouldMeasureLinks()) {\n        val textRangeLayoutMeasureScope = TextRangeLayoutMeasureScope()\n        measurables.fastMapIndexedNotNull { _, measurable ->\n            val rangeMeasurePolicy =\n                (measurable.parentData as TextRangeLayoutModifier).measurePolicy\n            val rangeMeasureResult =\n                with(rangeMeasurePolicy) { textRangeLayoutMeasureScope.measure() }\n            val placeable =\n                measurable.measure(\n                    fitPrioritizingWidth(\n                        minWidth = rangeMeasureResult.width,\n                        maxWidth = rangeMeasureResult.width,\n                        minHeight = rangeMeasureResult.height,\n                        maxHeight = rangeMeasureResult.height,\n                    )\n                )\n            Pair(placeable, rangeMeasureResult.place)\n        }\n    } else {\n        null\n    }\n}\n\nprivate fun Modifier.textModifier(\n    text: AnnotatedString,\n    style: TextStyle,\n    onTextLayout: ((TextLayoutResult) -> Unit)?,\n    overflow: TextOverflow,\n    softWrap: Boolean,\n    maxLines: Int,\n    minLines: Int,\n    fontFamilyResolver: FontFamily.Resolver,\n    placeholders: List<AnnotatedString.Range<Placeholder>>?,\n    onPlaceholderLayout: ((List<Rect?>) -> Unit)?,\n    selectionController: SelectionController?,\n    color: ColorProducer?,\n    onShowTranslation: ((TextAnnotatedStringNode.TextSubstitutionValue) -> Unit)?,\n    autoSize: TextAutoSize?,\n): Modifier {\n    if (selectionController == null) {\n        val staticTextModifier =\n            TextAnnotatedStringElement(\n                text,\n                style,\n                fontFamilyResolver,\n                onTextLayout,\n                overflow,\n                softWrap,\n                maxLines,\n                minLines,\n                placeholders,\n                onPlaceholderLayout,\n                null,\n                color,\n                autoSize,\n                onShowTranslation,\n            )\n        return this then Modifier /* selection position */ then staticTextModifier\n    } else {\n        val selectableTextModifier =\n            SelectableTextAnnotatedStringElement(\n                text,\n                style,\n                fontFamilyResolver,\n                onTextLayout,\n                overflow,\n                softWrap,\n                maxLines,\n                minLines,\n                placeholders,\n                onPlaceholderLayout,\n                selectionController,\n                color,\n                autoSize,\n            )\n        return this then selectionController.modifier then selectableTextModifier\n    }\n}\n\n@Composable\nprivate fun LayoutWithLinksAndInlineContent(\n    modifier: Modifier,\n    text: AnnotatedString,\n    onTextLayout: ((TextLayoutResult) -> Unit)?,\n    hasInlineContent: Boolean,\n    inlineContent: Map<String, InlineTextContent> = mapOf(),\n    style: TextStyle,\n    overflow: TextOverflow,\n    softWrap: Boolean,\n    maxLines: Int,\n    minLines: Int,\n    fontFamilyResolver: FontFamily.Resolver,\n    selectionController: SelectionController?,\n    color: ColorProducer?,\n    onShowTranslation: ((TextAnnotatedStringNode.TextSubstitutionValue) -> Unit)?,\n    autoSize: TextAutoSize?,\n) {\n\n    val textScope =\n        if (text.hasLinks()) {\n            remember(text) { TextLinkScope(text) }\n        } else null\n\n    // only adds additional span styles to the existing link annotations, doesn't semantically\n    // change the text\n    val styledText: () -> AnnotatedString =\n        if (text.hasLinks()) {\n            remember(text, textScope) { { textScope?.applyAnnotators() ?: text } }\n        } else {\n            { text }\n        }\n\n    // do the inline content allocs\n    val (placeholders, inlineComposables) =\n        if (hasInlineContent) {\n            text.resolveInlineContent(inlineContent = inlineContent)\n        } else Pair(null, null)\n\n    val measuredPlaceholderPositions =\n        if (hasInlineContent) {\n            remember<MutableState<List<Rect?>?>> { mutableStateOf(null) }\n        } else null\n\n    val onPlaceholderLayout: ((List<Rect?>) -> Unit)? =\n        if (hasInlineContent) {\n            { measuredPlaceholderPositions?.value = it }\n        } else null\n\n    BackgroundTextMeasurement(\n        text = text,\n        style = style,\n        fontFamilyResolver = fontFamilyResolver,\n        placeholders = placeholders,\n    )\n\n    Layout(\n        content = {\n            textScope?.LinksComposables()\n            inlineComposables?.let { InlineChildren(text = text, inlineContents = it) }\n        },\n        modifier =\n            modifier.textModifier(\n                text = styledText(),\n                style = style,\n                onTextLayout = {\n                    textScope?.textLayoutResult = it\n                    onTextLayout?.invoke(it)\n                },\n                overflow = overflow,\n                softWrap = softWrap,\n                maxLines = maxLines,\n                minLines = minLines,\n                fontFamilyResolver = fontFamilyResolver,\n                placeholders = placeholders,\n                onPlaceholderLayout = onPlaceholderLayout,\n                selectionController = selectionController,\n                color = color,\n                onShowTranslation = onShowTranslation,\n                autoSize = autoSize,\n            ),\n        measurePolicy =\n            if (!hasInlineContent) {\n                LinksTextMeasurePolicy(\n                    shouldMeasureLinks = { textScope?.let { it.shouldMeasureLinks() } ?: false }\n                )\n            } else {\n                TextMeasurePolicy(\n                    shouldMeasureLinks = { textScope?.let { it.shouldMeasureLinks() } ?: false },\n                    placements = { measuredPlaceholderPositions?.value },\n                )\n            },\n    )\n}\n\n/**\n * This function pre-measures the text on Android platform to warm the platform text layout cache in\n * a background thread before the actual text layout begins.\n */\n@Composable\n@NonRestartableComposable\ninternal expect fun BackgroundTextMeasurement(\n    text: String,\n    style: TextStyle,\n    fontFamilyResolver: FontFamily.Resolver,\n)\n\n/**\n * This function pre-measures the text on Android platform to warm the platform text layout cache in\n * a background thread before the actual text layout begins.\n */\n@Composable\n@NonRestartableComposable\ninternal expect fun BackgroundTextMeasurement(\n    text: AnnotatedString,\n    style: TextStyle,\n    fontFamilyResolver: FontFamily.Resolver,\n    placeholders: List<AnnotatedString.Range<Placeholder>>?,\n)\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Draggable.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.gestures\n\nimport androidx.compose.foundation.ComposeFoundationFlags.isDelayPressesUsingGestureConsumptionEnabled\nimport androidx.compose.foundation.ComposeFoundationFlags.isNestedDraggablesTouchConflictFixEnabled\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.GestureConnection\nimport androidx.compose.foundation.MutatePriority\nimport androidx.compose.foundation.MutatorMutex\nimport androidx.compose.foundation.gestureNode\nimport androidx.compose.foundation.gestures.DragEvent.DragCancelled\nimport androidx.compose.foundation.gestures.DragEvent.DragDelta\nimport androidx.compose.foundation.gestures.DragEvent.DragStarted\nimport androidx.compose.foundation.gestures.DragEvent.DragStopped\nimport androidx.compose.foundation.interaction.DragInteraction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.internal.JvmDefaultWithCompatibility\nimport androidx.compose.foundation.parentGestureConnection\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.ui.ExperimentalIndirectPointerApi\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.isSpecified\nimport androidx.compose.ui.input.indirect.IndirectPointerEvent\nimport androidx.compose.ui.input.indirect.IndirectPointerInputChange\nimport androidx.compose.ui.input.indirect.IndirectPointerInputModifierNode\nimport androidx.compose.ui.input.pointer.PointerEvent\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerId\nimport androidx.compose.ui.input.pointer.PointerInputChange\nimport androidx.compose.ui.input.pointer.PointerType\nimport androidx.compose.ui.input.pointer.changedToDownIgnoreConsumed\nimport androidx.compose.ui.input.pointer.changedToUpIgnoreConsumed\nimport androidx.compose.ui.input.pointer.pointerInput\nimport androidx.compose.ui.input.pointer.positionChange\nimport androidx.compose.ui.input.pointer.positionChangeIgnoreConsumed\nimport androidx.compose.ui.input.pointer.util.VelocityTracker\nimport androidx.compose.ui.input.pointer.util.addPointerInputChange\nimport androidx.compose.ui.layout.positionOnScreen\nimport androidx.compose.ui.node.CompositionLocalConsumerModifierNode\nimport androidx.compose.ui.node.DelegatableNode\nimport androidx.compose.ui.node.DelegatingNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.node.PointerInputModifierNode\nimport androidx.compose.ui.node.currentValueOf\nimport androidx.compose.ui.node.requireLayoutCoordinates\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.platform.LocalViewConfiguration\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.Velocity\nimport androidx.compose.ui.util.fastAll\nimport androidx.compose.ui.util.fastAny\nimport androidx.compose.ui.util.fastFirstOrNull\nimport kotlin.coroutines.cancellation.CancellationException\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.CoroutineStart\nimport kotlinx.coroutines.channels.Channel\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.isActive\nimport kotlinx.coroutines.launch\n\n/**\n * State of [draggable]. Allows for a granular control of how deltas are consumed by the user as\n * well as to write custom drag methods using [drag] suspend function.\n */\n@JvmDefaultWithCompatibility\ninterface DraggableState {\n    /**\n     * Call this function to take control of drag logic.\n     *\n     * All actions that change the logical drag position must be performed within a [drag] block\n     * (even if they don't call any other methods on this object) in order to guarantee that mutual\n     * exclusion is enforced.\n     *\n     * If [drag] is called from elsewhere with the [dragPriority] higher or equal to ongoing drag,\n     * ongoing drag will be canceled.\n     *\n     * @param dragPriority of the drag operation\n     * @param block to perform drag in\n     */\n    suspend fun drag(\n        dragPriority: MutatePriority = MutatePriority.Default,\n        block: suspend DragScope.() -> Unit,\n    )\n\n    /**\n     * Dispatch drag delta in pixels avoiding all drag related priority mechanisms.\n     *\n     * **NOTE:** unlike [drag], dispatching any delta with this method will bypass scrolling of any\n     * priority. This method will also ignore `reverseDirection` and other parameters set in\n     * [draggable].\n     *\n     * This method is used internally for low level operations, allowing implementers of\n     * [DraggableState] influence the consumption as suits them, e.g. introduce nested scrolling.\n     * Manually dispatching delta via this method will likely result in a bad user experience, you\n     * must prefer [drag] method over this one.\n     *\n     * @param delta amount of scroll dispatched in the nested drag process\n     */\n    fun dispatchRawDelta(delta: Float)\n}\n\n/** Scope used for suspending drag blocks */\ninterface DragScope {\n    /** Attempts to drag by [pixels] px. */\n    fun dragBy(pixels: Float)\n}\n\n/**\n * Default implementation of [DraggableState] interface that allows to pass a simple action that\n * will be invoked when the drag occurs.\n *\n * This is the simplest way to set up a [draggable] modifier. When constructing this\n * [DraggableState], you must provide a [onDelta] lambda, which will be invoked whenever drag\n * happens (by gesture input or a custom [DraggableState.drag] call) with the delta in pixels.\n *\n * If you are creating [DraggableState] in composition, consider using [rememberDraggableState].\n *\n * @param onDelta callback invoked when drag occurs. The callback receives the delta in pixels.\n */\nfun DraggableState(onDelta: (Float) -> Unit): DraggableState = DefaultDraggableState(onDelta)\n\n/**\n * Create and remember default implementation of [DraggableState] interface that allows to pass a\n * simple action that will be invoked when the drag occurs.\n *\n * This is the simplest way to set up a [draggable] modifier. When constructing this\n * [DraggableState], you must provide a [onDelta] lambda, which will be invoked whenever drag\n * happens (by gesture input or a custom [DraggableState.drag] call) with the delta in pixels.\n *\n * @param onDelta callback invoked when drag occurs. The callback receives the delta in pixels.\n */\n@Composable\nfun rememberDraggableState(onDelta: (Float) -> Unit): DraggableState {\n    val onDeltaState = rememberUpdatedState(onDelta)\n    return remember { DraggableState { onDeltaState.value.invoke(it) } }\n}\n\n/**\n * Configure touch dragging for the UI element in a single [Orientation]. The drag distance reported\n * to [DraggableState], allowing users to react on the drag delta and update their state.\n *\n * The common usecase for this component is when you need to be able to drag something inside the\n * component on the screen and represent this state via one float value\n *\n * If you need to control the whole dragging flow, consider using [pointerInput] instead with the\n * helper functions like [detectDragGestures].\n *\n * If you want to enable dragging in 2 dimensions, consider using [draggable2D].\n *\n * If you are implementing scroll/fling behavior, consider using [scrollable].\n *\n * @sample androidx.compose.foundation.samples.DraggableSample\n * @param state [DraggableState] state of the draggable. Defines how drag events will be interpreted\n *   by the user land logic.\n * @param orientation orientation of the drag\n * @param enabled whether or not drag is enabled\n * @param interactionSource [MutableInteractionSource] that will be used to emit\n *   [DragInteraction.Start] when this draggable is being dragged.\n * @param startDragImmediately when set to true, draggable will start dragging immediately and\n *   prevent other gesture detectors from reacting to \"down\" events (in order to block composed\n *   press-based gestures). This is intended to allow end users to \"catch\" an animating widget by\n *   pressing on it. It's useful to set it when value you're dragging is settling / animating.\n * @param onDragStarted callback that will be invoked when drag is about to start at the starting\n *   position, allowing user to suspend and perform preparation for drag, if desired. This suspend\n *   function is invoked with the draggable scope, allowing for async processing, if desired. Note\n *   that the scope used here is the one provided by the draggable node, for long running work that\n *   needs to outlast the modifier being in the composition you should use a scope that fits the\n *   lifecycle needed.\n * @param onDragStopped callback that will be invoked when drag is finished, allowing the user to\n *   react on velocity and process it. This suspend function is invoked with the draggable scope,\n *   allowing for async processing, if desired. Note that the scope used here is the one provided by\n *   the draggable node, for long running work that needs to outlast the modifier being in the\n *   composition you should use a scope that fits the lifecycle needed.\n * @param reverseDirection reverse the direction of the scroll, so top to bottom scroll will behave\n *   like bottom to top and left to right will behave like right to left.\n */\n@Stable\nfun Modifier.draggable(\n    state: DraggableState,\n    orientation: Orientation,\n    enabled: Boolean = true,\n    interactionSource: MutableInteractionSource? = null,\n    startDragImmediately: Boolean = false,\n    onDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit = NoOpOnDragStarted,\n    onDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit = NoOpOnDragStopped,\n    reverseDirection: Boolean = false,\n): Modifier =\n    this then\n        DraggableElement(\n            state = state,\n            orientation = orientation,\n            enabled = enabled,\n            interactionSource = interactionSource,\n            startDragImmediately = startDragImmediately,\n            onDragStarted = onDragStarted,\n            onDragStopped = onDragStopped,\n            reverseDirection = reverseDirection,\n        )\n\ninternal class DraggableElement(\n    private val state: DraggableState,\n    private val orientation: Orientation,\n    private val enabled: Boolean,\n    private val interactionSource: MutableInteractionSource?,\n    private val startDragImmediately: Boolean,\n    private val onDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit,\n    private val onDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit,\n    private val reverseDirection: Boolean,\n) : ModifierNodeElement<DraggableNode>() {\n    override fun create(): DraggableNode =\n        DraggableNode(\n            state,\n            CanDrag,\n            orientation,\n            enabled,\n            interactionSource,\n            startDragImmediately,\n            onDragStarted,\n            onDragStopped,\n            reverseDirection,\n        )\n\n    override fun update(node: DraggableNode) {\n        node.update(\n            state,\n            CanDrag,\n            orientation,\n            enabled,\n            interactionSource,\n            startDragImmediately,\n            onDragStarted,\n            onDragStopped,\n            reverseDirection,\n        )\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other === null) return false\n        if (this::class != other::class) return false\n\n        other as DraggableElement\n\n        if (state != other.state) return false\n        if (orientation != other.orientation) return false\n        if (enabled != other.enabled) return false\n        if (interactionSource != other.interactionSource) return false\n        if (startDragImmediately != other.startDragImmediately) return false\n        if (onDragStarted != other.onDragStarted) return false\n        if (onDragStopped != other.onDragStopped) return false\n        if (reverseDirection != other.reverseDirection) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = state.hashCode()\n        result = 31 * result + orientation.hashCode()\n        result = 31 * result + enabled.hashCode()\n        result = 31 * result + (interactionSource?.hashCode() ?: 0)\n        result = 31 * result + startDragImmediately.hashCode()\n        result = 31 * result + onDragStarted.hashCode()\n        result = 31 * result + onDragStopped.hashCode()\n        result = 31 * result + reverseDirection.hashCode()\n        return result\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"draggable\"\n        properties[\"orientation\"] = orientation\n        properties[\"enabled\"] = enabled\n        properties[\"reverseDirection\"] = reverseDirection\n        properties[\"interactionSource\"] = interactionSource\n        properties[\"startDragImmediately\"] = startDragImmediately\n        properties[\"onDragStarted\"] = onDragStarted\n        properties[\"onDragStopped\"] = onDragStopped\n        properties[\"state\"] = state\n    }\n\n    companion object {\n        val CanDrag: (PointerType) -> Boolean = { true }\n    }\n}\n\ninternal class DraggableNode(\n    private var state: DraggableState,\n    canDrag: (PointerType) -> Boolean,\n    private var orientation: Orientation,\n    enabled: Boolean,\n    interactionSource: MutableInteractionSource?,\n    private var startDragImmediately: Boolean,\n    private var onDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit,\n    private var onDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit,\n    private var reverseDirection: Boolean,\n) :\n    DragGestureNode(\n        canDrag = canDrag,\n        enabled = enabled,\n        interactionSource = interactionSource,\n        orientationLock = orientation,\n    ) {\n\n    override suspend fun drag(forEachDelta: suspend ((dragDelta: DragDelta) -> Unit) -> Unit) {\n        state.drag(MutatePriority.UserInput) {\n            forEachDelta { dragDelta ->\n                dragBy(dragDelta.delta.reverseIfNeeded().toFloat(orientation))\n            }\n        }\n    }\n\n    override fun onDragStarted(startedPosition: Offset) {\n        if (!isAttached || onDragStarted == NoOpOnDragStarted) return\n        coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) {\n            this@DraggableNode.onDragStarted(this, startedPosition)\n        }\n    }\n\n    override fun onDragStopped(event: DragStopped) {\n        if (!isAttached || onDragStopped == NoOpOnDragStopped) return\n        coroutineScope.launch(start = CoroutineStart.UNDISPATCHED) {\n            this@DraggableNode.onDragStopped(\n                this,\n                event.velocity.reverseIfNeeded().toFloat(orientation),\n            )\n        }\n    }\n\n    override fun startDragImmediately(): Boolean = startDragImmediately\n\n    fun update(\n        state: DraggableState,\n        canDrag: (PointerType) -> Boolean,\n        orientation: Orientation,\n        enabled: Boolean,\n        interactionSource: MutableInteractionSource?,\n        startDragImmediately: Boolean,\n        onDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit,\n        onDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit,\n        reverseDirection: Boolean,\n    ) {\n        var resetPointerInputHandling = false\n        if (this.state != state) {\n            this.state = state\n            resetPointerInputHandling = true\n        }\n        if (this.orientation != orientation) {\n            this.orientation = orientation\n            resetPointerInputHandling = true\n        }\n        if (this.reverseDirection != reverseDirection) {\n            this.reverseDirection = reverseDirection\n            resetPointerInputHandling = true\n        }\n\n        this.onDragStarted = onDragStarted\n        this.onDragStopped = onDragStopped\n        this.startDragImmediately = startDragImmediately\n\n        update(canDrag, enabled, interactionSource, orientation, resetPointerInputHandling)\n    }\n\n    private fun Velocity.reverseIfNeeded() = if (reverseDirection) this * -1f else this * 1f\n\n    private fun Offset.reverseIfNeeded() = if (reverseDirection) this * -1f else this * 1f\n}\n\n/** A node that performs drag gesture recognition and event propagation. */\n@OptIn(ExperimentalFoundationApi::class)\ninternal abstract class DragGestureNode(\n    canDrag: (PointerType) -> Boolean,\n    enabled: Boolean,\n    interactionSource: MutableInteractionSource?,\n    var orientationLock: Orientation?,\n) :\n    DelegatingNode(),\n    PointerInputModifierNode,\n    IndirectPointerInputModifierNode,\n    CompositionLocalConsumerModifierNode,\n    GestureConnection {\n\n    var canDrag = canDrag\n        private set\n\n    protected var enabled = enabled\n        private set\n\n    protected var interactionSource = interactionSource\n        private set\n\n    private var gestureNode: DelegatableNode? = null\n\n    // Use wrapper lambdas here to make sure that if these properties are updated while we suspend,\n    // we point to the new reference when we invoke them. startDragImmediately is a lambda since we\n    // need the most recent value passed to it from Scrollable.\n    private val _canDrag: (PointerType) -> Boolean = { this.canDrag(it) }\n    private var channel: Channel<DragEvent>? = null\n    private var dragInteraction: DragInteraction.Start? = null\n    internal var isListeningForEvents = false\n    internal var isListeningForPointerInputEvents = false\n\n    /** Store non-initialized states for re-use */\n    private var _awaitDownState: DragDetectionState.AwaitDown? = null\n    private val awaitDownState: DragDetectionState.AwaitDown\n        get() = _awaitDownState ?: DragDetectionState.AwaitDown().also { _awaitDownState = it }\n\n    private var _draggingState: DragDetectionState.Dragging? = null\n    private val draggingState: DragDetectionState.Dragging\n        get() = _draggingState ?: DragDetectionState.Dragging().also { _draggingState = it }\n\n    private var _awaitTouchSlopState: DragDetectionState.AwaitTouchSlop? = null\n    private val awaitTouchSlopState: DragDetectionState.AwaitTouchSlop\n        get() =\n            _awaitTouchSlopState\n                ?: DragDetectionState.AwaitTouchSlop().also { _awaitTouchSlopState = it }\n\n    private var _awaitGesturePickupState: DragDetectionState.AwaitGesturePickup? = null\n    private val awaitGesturePickupState: DragDetectionState.AwaitGesturePickup\n        get() =\n            _awaitGesturePickupState\n                ?: DragDetectionState.AwaitGesturePickup().also { _awaitGesturePickupState = it }\n\n    private var currentDragState: DragDetectionState? = null\n    private var velocityTracker: VelocityTracker? = null\n    private var previousPositionOnScreen = Offset.Unspecified\n    private var touchSlopDetector: TouchSlopDetector? = null\n    private var indirectPointerInputDragCycleDetector: IndirectPointerInputDragCycleDetector? = null\n\n    /**\n     * Accumulated position offset of this [Modifier.Node] that happened during a drag cycle. This\n     * is used to correct the pointer input events that are added to the Velocity Tracker. If this\n     * Node is static during the drag cycle, nothing will happen. On the other hand, if the position\n     * of this node changes during the drag cycle, we need to correct the Pointer Input used for the\n     * drag events, this is because Velocity Tracker doesn't have the knowledge about changes in the\n     * position of the container that uses it, and because each Pointer Input event is related to\n     * the container's root.\n     */\n    private var nodeOffset = Offset.Zero\n\n    /**\n     * Responsible for the dragging behavior between the start and the end of the drag. It\n     * continually invokes `forEachDelta` to process incoming events. In return, `forEachDelta`\n     * calls `dragBy` method to process each individual delta.\n     */\n    abstract suspend fun drag(forEachDelta: suspend ((dragDelta: DragDelta) -> Unit) -> Unit)\n\n    /**\n     * Passes the action needed when a drag starts. This gives the ability to pass the desired\n     * behavior from other nodes implementing AbstractDraggableNode\n     */\n    abstract fun onDragStarted(startedPosition: Offset)\n\n    /**\n     * Passes the action needed when a drag stops. This gives the ability to pass the desired\n     * behavior from other nodes implementing AbstractDraggableNode\n     */\n    abstract fun onDragStopped(event: DragStopped)\n\n    /**\n     * If touch slop recognition should be skipped. If this is true, this node will start\n     * recognizing drag events immediately without waiting for touch slop.\n     */\n    abstract fun startDragImmediately(): Boolean\n\n    private fun requireVelocityTracker(): VelocityTracker =\n        requireNotNull(velocityTracker) { \"Velocity Tracker not initialized.\" }\n\n    private fun requireChannel(): Channel<DragEvent> =\n        requireNotNull(channel) { \"Events channel not initialized.\" }\n\n    private fun requireTouchSlopDetector(): TouchSlopDetector =\n        requireNotNull(touchSlopDetector) { \"Touch slop detector not initialized.\" }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    private fun startListeningForEvents() {\n        isListeningForEvents = true\n\n        if (channel == null) {\n            channel = Channel(capacity = Channel.UNLIMITED)\n        }\n\n        /**\n         * To preserve the original behavior we had (before the Modifier.Node migration) we need to\n         * scope the DragStopped and DragCancel methods to the node's coroutine scope instead of\n         * using the one provided by the pointer input modifier, this is to ensure that even when\n         * the pointer input scope is reset we will continue any coroutine scope scope that we\n         * started from these methods while the pointer input scope was active.\n         */\n        coroutineScope.launch {\n            while (isActive) {\n                var event = channel?.receive()\n                if (event !is DragStarted) continue\n                processDragStart(event)\n                try {\n                    drag { processDelta ->\n                        while (event !is DragStopped && event !is DragCancelled) {\n                            (event as? DragDelta)?.let(processDelta)\n                            event = channel?.receive()\n                        }\n                    }\n                    if (event is DragStopped) {\n                        processDragStop(event as DragStopped)\n                    } else if (event is DragCancelled) {\n                        processDragCancel()\n                    }\n                } catch (c: CancellationException) {\n                    processDragCancel()\n                }\n            }\n        }\n    }\n\n    override fun onDetach() {\n        isListeningForEvents = false\n        disposeInteractionSource()\n        nodeOffset = Offset.Zero\n\n        gestureNode?.let { undelegate(it) }\n        gestureNode = null\n    }\n\n    protected fun initializeGestureCoordination() {\n        if (!isDelayPressesUsingGestureConsumptionEnabled) return\n        if (gestureNode == null) {\n            gestureNode = delegate(gestureNode(this))\n        }\n    }\n\n    @OptIn(ExperimentalIndirectPointerApi::class)\n    override fun isInterested(event: IndirectPointerInputChange): Boolean {\n        // for now, if this is a down event it may become a drag so we're\n        // interested.\n        return event.changedToDownIgnoreConsumed() && enabled\n    }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    override fun onPointerEvent(\n        pointerEvent: PointerEvent,\n        pass: PointerEventPass,\n        bounds: IntSize,\n    ) {\n        isListeningForPointerInputEvents = true\n        initializeGestureCoordination()\n        if (enabled) {\n            // initialize current state\n            if (currentDragState == null) currentDragState = awaitDownState\n            processRawPointerEvent(pointerEvent, pass)\n        }\n    }\n\n    override fun onIndirectPointerEvent(event: IndirectPointerEvent, pass: PointerEventPass) {\n        initializeGestureCoordination()\n        if (enabled) {\n            if (indirectPointerInputDragCycleDetector == null) {\n                indirectPointerInputDragCycleDetector = IndirectPointerInputDragCycleDetector(this)\n            }\n            indirectPointerInputDragCycleDetector?.processIndirectPointerInputEvent(event, pass)\n        }\n    }\n\n    override fun onCancelIndirectPointerInput() {\n        indirectPointerInputDragCycleDetector?.resetDragDetectionState()\n    }\n\n    /**\n     * Draggable containers will be interested in the following events:\n     * 1) DOWN events. They may become a drag gesture later.\n     * 2) The touch slop trigger event if the preceding deltas form an angle of interest. The touch\n     *    slop trigger event is when, effectively, draggables will start consuming. So at this\n     *    point, we look at the collected deltas since the first down event, and we decide if we're\n     *    interested based on the angle that those deltas form. We will favor vertical drags over\n     *    horizontal drags more because UX-wise there's more freedom and uncertainty when a user\n     *    performs a vertical gesture vs. a horizontal gesture.\n     */\n    override fun isInterested(event: PointerInputChange): Boolean {\n        if (event.changedToDownIgnoreConsumed()) return enabled\n        if (!isNestedDraggablesTouchConflictFixEnabled) return false\n        if (event.changedToUpIgnoreConsumed()) return false\n\n        if (touchSlopDetector == null) {\n            touchSlopDetector = TouchSlopDetector(orientationLock)\n        }\n\n        val touchSlop = currentValueOf(LocalViewConfiguration).touchSlop\n        val positionChange = event.positionChange()\n\n        return with(requireTouchSlopDetector()) {\n            getPostSlopOffset(positionChange, touchSlop, false) != Offset.Unspecified &&\n                isDeltaAtAngleOfInterest(positionChange)\n        }\n    }\n\n    override fun onCancelPointerInput() {\n        if (isListeningForPointerInputEvents) resetDragDetectionState()\n        isListeningForPointerInputEvents = false\n    }\n\n    private suspend fun processDragStart(event: DragStarted) {\n        dragInteraction?.let { oldInteraction ->\n            interactionSource?.emit(DragInteraction.Cancel(oldInteraction))\n        }\n        val interaction = DragInteraction.Start()\n        interactionSource?.emit(interaction)\n        dragInteraction = interaction\n        onDragStarted(event.startPoint)\n    }\n\n    private suspend fun processDragStop(event: DragStopped) {\n        dragInteraction?.let { interaction ->\n            interactionSource?.emit(DragInteraction.Stop(interaction))\n            dragInteraction = null\n        }\n        onDragStopped(event)\n    }\n\n    private suspend fun processDragCancel() {\n        dragInteraction?.let { interaction ->\n            interactionSource?.emit(DragInteraction.Cancel(interaction))\n            dragInteraction = null\n        }\n        onDragStopped(DragStopped(Velocity.Zero, isIndirectPointerEvent = false))\n    }\n\n    fun disposeInteractionSource() {\n        dragInteraction?.let { interaction ->\n            interactionSource?.tryEmit(DragInteraction.Cancel(interaction))\n            dragInteraction = null\n        }\n    }\n\n    fun update(\n        canDrag: (PointerType) -> Boolean = this.canDrag,\n        enabled: Boolean = this.enabled,\n        interactionSource: MutableInteractionSource? = this.interactionSource,\n        orientationLock: Orientation? = this.orientationLock,\n        shouldResetPointerInputHandling: Boolean = false,\n    ) {\n        var resetPointerInputHandling = shouldResetPointerInputHandling\n\n        this.canDrag = canDrag\n        if (this.enabled != enabled) {\n            this.enabled = enabled\n            if (!enabled) {\n                disposeInteractionSource()\n                indirectPointerInputDragCycleDetector = null\n            }\n            resetPointerInputHandling = true\n        }\n        if (this.interactionSource != interactionSource) {\n            disposeInteractionSource()\n            this.interactionSource = interactionSource\n        }\n\n        if (this.orientationLock != orientationLock) {\n            this.orientationLock = orientationLock\n            resetPointerInputHandling = true\n        }\n\n        if (resetPointerInputHandling) {\n            if (isListeningForPointerInputEvents) resetDragDetectionState()\n            indirectPointerInputDragCycleDetector?.resetDragDetectionState()\n        }\n    }\n\n    private fun processRawPointerEvent(pointerEvent: PointerEvent, pass: PointerEventPass) {\n        when (\n            val state = requireNotNull(currentDragState) { \"currentDragState should not be null\" }\n        ) {\n            is DragDetectionState.AwaitDown -> processInitialDownState(pointerEvent, pass, state)\n            is DragDetectionState.AwaitTouchSlop -> processAwaitTouchSlop(pointerEvent, pass, state)\n            is DragDetectionState.AwaitGesturePickup ->\n                processAwaitGesturePickup(pointerEvent, pass, state)\n\n            is DragDetectionState.Dragging -> processDraggingState(pointerEvent, pass, state)\n        }\n    }\n\n    private fun resetDragDetectionState() {\n        moveToAwaitDownState()\n        if (isListeningForEvents) sendDragCancelled()\n        velocityTracker = null\n    }\n\n    private fun moveToAwaitTouchSlopState(\n        initialDown: PointerInputChange,\n        pointerId: PointerId,\n        initialTouchSlopPositionChange: Offset = Offset.Zero,\n        verifyConsumptionInFinalPass: Boolean = false,\n    ) {\n        currentDragState =\n            awaitTouchSlopState.apply {\n                this.initialDown = initialDown\n                this.pointerId = pointerId\n                if (touchSlopDetector == null) {\n                    touchSlopDetector = TouchSlopDetector(orientationLock)\n                } else {\n                    touchSlopDetector?.orientation = orientationLock\n                    touchSlopDetector?.reset(initialTouchSlopPositionChange)\n                }\n                this.verifyConsumptionInFinalPass = verifyConsumptionInFinalPass\n            }\n    }\n\n    private fun moveToDraggingState(pointerId: PointerId) {\n        currentDragState = draggingState.apply { this.pointerId = pointerId }\n    }\n\n    private fun moveToAwaitDownState() {\n        currentDragState =\n            awaitDownState.apply {\n                awaitTouchSlop = DragDetectionState.AwaitDown.AwaitTouchSlop.NotInitialized\n                consumedOnInitial = false\n            }\n    }\n\n    private fun moveToAwaitGesturePickupState(\n        initialDown: PointerInputChange,\n        pointerId: PointerId,\n        touchSlopDetector: TouchSlopDetector,\n    ) {\n        currentDragState =\n            awaitGesturePickupState.apply {\n                this.initialDown = initialDown\n                this.pointerId = pointerId\n                this.touchSlopDetector = touchSlopDetector.also { it.reset() }\n            }\n    }\n\n    private fun processInitialDownState(\n        pointerEvent: PointerEvent,\n        pass: PointerEventPass,\n        state: DragDetectionState.AwaitDown,\n    ) {\n        /** Wait for a down event in any pass. */\n        if (pointerEvent.changes.isEmpty()) return\n        if (!pointerEvent.isChangedToDown(requireUnconsumed = false)) return\n\n        val firstDown = pointerEvent.changes.first()\n        val awaitTouchSlop =\n            when (state.awaitTouchSlop) {\n                DragDetectionState.AwaitDown.AwaitTouchSlop.NotInitialized -> {\n                    if (!startDragImmediately()) {\n                        DragDetectionState.AwaitDown.AwaitTouchSlop.Yes\n                    } else {\n                        DragDetectionState.AwaitDown.AwaitTouchSlop.No\n                    }\n                }\n\n                else -> state.awaitTouchSlop\n            }\n\n        // update the touch slop in the current state\n        state.awaitTouchSlop = awaitTouchSlop\n\n        if (pass == PointerEventPass.Initial) {\n            // If we shouldn't await touch slop, we consume the event immediately.\n            if (awaitTouchSlop == DragDetectionState.AwaitDown.AwaitTouchSlop.No) {\n                firstDown.consume()\n\n                // Change state properties so we dispatch only later, this aligns with the previous\n                // behavior where dispatching only happened during the main pass\n                state.consumedOnInitial = true\n            }\n        }\n\n        if (pass == PointerEventPass.Main) {\n            /**\n             * At this point we detected a Down event, if we should await the slop we move to the\n             * next state. If we shouldn't await the slop and we already consumed the event we\n             * dispatch the drag start events and start the dragging state.\n             */\n            if (awaitTouchSlop == DragDetectionState.AwaitDown.AwaitTouchSlop.Yes) {\n                moveToAwaitTouchSlopState(firstDown, firstDown.id)\n            } else if (state.consumedOnInitial) {\n                sendDragStart(firstDown, firstDown, Offset.Zero)\n                sendDragEvent(firstDown, Offset.Zero)\n                moveToDraggingState(firstDown.id)\n            }\n        }\n    }\n\n    private fun processAwaitTouchSlop(\n        pointerEvent: PointerEvent,\n        pass: PointerEventPass,\n        state: DragDetectionState.AwaitTouchSlop,\n    ) {\n        /** Slop detection only cares about the main and final passes */\n        if (pass == PointerEventPass.Initial) return\n        val eventFromPointerId = pointerEvent.changes.fastFirstOrNull { it.id == state.pointerId }\n\n        /**\n         * We lost this pointer, try to replace it. This is to cover the case where multiple\n         * pointers were down, but the original one we tracked (state.pointerId) is no longer down,\n         * try to move tracking to a different pointer\n         */\n        val dragEvent =\n            if (eventFromPointerId == null) {\n                val otherDown = pointerEvent.changes.fastFirstOrNull { it.pressed }\n                if (otherDown == null) {\n                    // There are no other pointers down, reset the state\n                    moveToAwaitDownState()\n                    return\n                } else {\n                    // a new pointer was found, update the current state.\n                    state.pointerId = otherDown.id\n                }\n                otherDown\n            } else {\n                eventFromPointerId\n            }\n\n        /**\n         * Slop detection routines happens during the Main pass. Do we have unconsumed events for\n         * this pointer?\n         */\n        if (pass == PointerEventPass.Main) {\n            if (!dragEvent.isConsumed) {\n                if (dragEvent.changedToUpIgnoreConsumed()) {\n                    /** The pointer lifted, look for another pointer */\n                    val otherDown = pointerEvent.changes.fastFirstOrNull { it.pressed }\n                    if (otherDown == null) {\n                        // There are no other pointers down, reset the state\n                        moveToAwaitDownState()\n                    } else {\n                        // a new pointer was found, update the current state.\n                        state.pointerId = otherDown.id\n                    }\n                } else {\n                    // this is a regular event (MOVE)\n                    val touchSlop =\n                        currentValueOf(LocalViewConfiguration).pointerSlop(dragEvent.type)\n\n                    // add data to the slop detector\n                    val postSlopOffset =\n                        requireTouchSlopDetector()\n                            .getPostSlopOffset(dragEvent.positionChangeIgnoreConsumed(), touchSlop)\n\n                    /**\n                     * Here we use the [gestureNode] and [GestureConnection] APIs to make a\n                     * decision. About this gesture. At this point we have all the triggers to start\n                     * a recognizing a gesture in this current\n                     * [androidx.compose.foundation.gestures.DragGestureNode]. This is the moment\n                     * that touch slop is recognized here in this node. During this time, before we\n                     * start consuming drag events we check the interested of the parent and our\n                     * self-interest. If the parent is interested and we're not (for this specific\n                     * event), we will give the parent a chance to do something by postponing the\n                     * remaining consumption to the final pass.\n                     */\n                    if (isNestedDraggablesTouchConflictFixEnabled) {\n                        if (postSlopOffset.isSpecified) {\n                            val isSelfInterested = isInterested(dragEvent)\n                            val isParentInterested =\n                                parentGestureConnection?.isInterested(dragEvent) == true\n                            if (!isSelfInterested && isParentInterested) {\n                                state.verifyConsumptionInFinalPass = true\n                            } else {\n                                dragEvent.consume()\n                                sendDragStart(state.initialDown!!, dragEvent, postSlopOffset)\n                                sendDragEvent(dragEvent, postSlopOffset)\n                                moveToDraggingState(dragEvent.id)\n                            }\n                        } else {\n                            state.verifyConsumptionInFinalPass = true\n                        }\n                    } else {\n                        if (postSlopOffset.isSpecified) {\n                            dragEvent.consume()\n                            sendDragStart(state.initialDown!!, dragEvent, postSlopOffset)\n                            sendDragEvent(dragEvent, postSlopOffset)\n                            moveToDraggingState(dragEvent.id)\n                        } else {\n                            state.verifyConsumptionInFinalPass = true\n                        }\n                    }\n                }\n            } else {\n                // This draggable \"lost\" the event as it was consumed by someone else, enter the\n                // gesture pickup state if the feature is enabled.\n                // Someone consumed this gesture, move this to the await pickup state.\n                moveToAwaitGesturePickupState(\n                    requireNotNull(state.initialDown) {\n                        \"AwaitTouchSlop.initialDown was not initialized\"\n                    },\n                    state.pointerId,\n                    requireNotNull(touchSlopDetector) {\n                        \"AwaitTouchSlop.touchSlopDetector was not initialized\"\n                    },\n                )\n            }\n        }\n\n        /**\n         * This checks 2 cases: 1) A parent consumed in the main pass and this child can only see\n         * that consumption during the final pass. 2) The parent actually consumed during the final\n         * pass.\n         */\n        if (pass == PointerEventPass.Final && state.verifyConsumptionInFinalPass) {\n            if (dragEvent.isConsumed) {\n                // This draggable \"lost\" the event as it was consumed by someone else, enter the\n                // gesture pickup state if the feature is enabled.\n                // Someone consumed this gesture, move this to the await pickup state.\n                moveToAwaitGesturePickupState(\n                    requireNotNull(state.initialDown) {\n                        \"AwaitTouchSlop.initialDown was not initialized\"\n                    },\n                    state.pointerId,\n                    requireNotNull(touchSlopDetector) {\n                        \"AwaitTouchSlop.touchSlopDetector was not initialized\"\n                    },\n                )\n            } else {\n                /**\n                 * Self and nobody consumed dragEvent. We will only get here if self didn't consume\n                 * in the main pass OR if self wasn't interested during the main pass. In this case\n                 * we remain in the awaitTouchSlop state and wait for more information (events).\n                 */\n                state.verifyConsumptionInFinalPass = false\n            }\n        }\n    }\n\n    private fun processAwaitGesturePickup(\n        pointerEvent: PointerEvent,\n        pass: PointerEventPass,\n        state: DragDetectionState.AwaitGesturePickup,\n    ) {\n        /**\n         * Drag pickup only happens during the final pass so we're sure nobody else was interested\n         * in this gesture.\n         */\n        if (pass != PointerEventPass.Final) return\n        val hasUnconsumedDrag = pointerEvent.changes.fastAll { !it.isConsumed }\n        val hasDownPointers = pointerEvent.changes.fastAny { it.pressed }\n        // all pointers are up, reset\n        if (!hasDownPointers || pointerEvent.changes.isEmpty()) {\n            moveToAwaitDownState()\n        } else if (hasUnconsumedDrag) {\n            // has pointers down with unconsumed events, a chance to pick up this gesture,\n            // move to the touch slop detection phase\n            val initialPositionChange =\n                pointerEvent.changes.first().position - state.initialDown!!.position\n\n            // await touch slop again, using the initial down as starting point.\n            // For most cases this should return immediately since we probably moved\n            // far enough from the initial down event.\n            moveToAwaitTouchSlopState(\n                requireNotNull(state.initialDown) {\n                    \"AwaitGesturePickup.initialDown was not initialized.\"\n                },\n                state.pointerId,\n                initialPositionChange,\n            )\n        }\n    }\n\n    private fun processDraggingState(\n        pointerEvent: PointerEvent,\n        pass: PointerEventPass,\n        state: DragDetectionState.Dragging,\n    ) {\n        if (pass != PointerEventPass.Main) return\n\n        val pointer = state.pointerId\n        val dragEvent = pointerEvent.changes.fastFirstOrNull { it.id == pointer } ?: return\n        if (dragEvent.changedToUpIgnoreConsumed()) {\n            val otherDown = pointerEvent.changes.fastFirstOrNull { it.pressed }\n            if (otherDown == null) {\n                // This is the last \"up\"\n                if (!dragEvent.isConsumed && dragEvent.changedToUpIgnoreConsumed()) {\n                    sendDragStopped(dragEvent)\n                } else {\n                    sendDragCancelled()\n                }\n                moveToAwaitDownState()\n            } else {\n                state.pointerId = otherDown.id\n            }\n        } else {\n            if (dragEvent.isConsumed) {\n                sendDragCancelled()\n            } else {\n                val positionChange = dragEvent.positionChangeIgnoreConsumed()\n\n                /**\n                 * During the gesture pickup we can pickup events at any direction so disable the\n                 * orientation lock.\n                 */\n                val motionChange = positionChange.getDistance()\n                if (motionChange != 0.0f) {\n                    val positionChange = dragEvent.positionChange()\n                    sendDragEvent(dragEvent, positionChange)\n                    dragEvent.consume()\n                }\n            }\n        }\n    }\n\n    private fun sendDragStart(\n        down: PointerInputChange,\n        slopTriggerChange: PointerInputChange,\n        overSlopOffset: Offset,\n    ) {\n        if (velocityTracker == null) velocityTracker = VelocityTracker()\n        requireVelocityTracker().addPointerInputChange(down)\n        val dragStartedOffset = slopTriggerChange.position - overSlopOffset\n        // the drag start event offset is the down event + touch slop value\n        // or in this case the event that triggered the touch slop minus\n        // the post slop offset\n        nodeOffset = Offset.Zero // restart node offset\n        if (canDrag(down.type)) {\n            if (!isListeningForEvents) {\n                if (channel == null) {\n                    channel = Channel(capacity = Channel.UNLIMITED)\n                }\n                startListeningForEvents()\n            }\n            previousPositionOnScreen = requireLayoutCoordinates().positionOnScreen()\n            requireChannel().trySend(DragStarted(dragStartedOffset))\n        }\n    }\n\n    private fun sendDragEvent(change: PointerInputChange, dragAmount: Offset) {\n        val currentPositionOnScreen = node.requireLayoutCoordinates().positionOnScreen()\n        // container changed positions\n        if (\n            previousPositionOnScreen != Offset.Unspecified &&\n                currentPositionOnScreen != previousPositionOnScreen\n        ) {\n            val delta = currentPositionOnScreen - previousPositionOnScreen\n            nodeOffset += delta\n        }\n        previousPositionOnScreen = currentPositionOnScreen\n        requireVelocityTracker().addPointerInputChange(event = change, offset = nodeOffset)\n        requireChannel().trySend(DragDelta(dragAmount, false))\n    }\n\n    private fun sendDragStopped(change: PointerInputChange) {\n        requireVelocityTracker().addPointerInputChange(change)\n        val maximumVelocity = currentValueOf(LocalViewConfiguration).maximumFlingVelocity\n        val velocity =\n            requireVelocityTracker().calculateVelocity(Velocity(maximumVelocity, maximumVelocity))\n        requireVelocityTracker().resetTracking()\n        requireChannel().trySend(DragStopped(velocity.toValidVelocity(), false))\n        isListeningForPointerInputEvents = false\n    }\n\n    private fun sendDragCancelled() {\n        requireChannel().trySend(DragCancelled)\n    }\n\n    fun onDragEvent(event: DragEvent) {\n        if (event is DragStarted && !isListeningForEvents) {\n            isListeningForEvents = true\n            startListeningForEvents()\n        }\n        requireChannel().trySend(event)\n    }\n}\n\nprivate class DefaultDraggableState(val onDelta: (Float) -> Unit) : DraggableState {\n\n    private val dragScope: DragScope =\n        object : DragScope {\n            override fun dragBy(pixels: Float): Unit = onDelta(pixels)\n        }\n\n    private val scrollMutex = MutatorMutex()\n\n    override suspend fun drag(\n        dragPriority: MutatePriority,\n        block: suspend DragScope.() -> Unit,\n    ): Unit = coroutineScope { scrollMutex.mutateWith(dragScope, dragPriority, block) }\n\n    override fun dispatchRawDelta(delta: Float) {\n        return onDelta(delta)\n    }\n}\n\ninternal sealed class DragEvent {\n    class DragStarted(val startPoint: Offset) : DragEvent()\n\n    class DragStopped(val velocity: Velocity, val isIndirectPointerEvent: Boolean) : DragEvent()\n\n    object DragCancelled : DragEvent()\n\n    class DragDelta(val delta: Offset, val isIndirectPointerEvent: Boolean) : DragEvent()\n}\n\ninternal fun Offset.toFloat(orientation: Orientation) =\n    if (orientation == Orientation.Vertical) this.y else this.x\n\nprivate fun Velocity.toFloat(orientation: Orientation) =\n    if (orientation == Orientation.Vertical) this.y else this.x\n\ninternal fun Velocity.toValidVelocity() =\n    Velocity(if (this.x.isNaN()) 0f else this.x, if (this.y.isNaN()) 0f else this.y)\n\nprivate val NoOpOnDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit = {}\nprivate val NoOpOnDragStopped: suspend CoroutineScope.(velocity: Float) -> Unit = {}\n\nprivate sealed class DragDetectionState {\n    /**\n     * Starter state for any drag gesture cycle. At this state we're waiting for a Down event to\n     * indicate that a drag gesture may start. Since drag gesture start at the initial pass we have\n     * the option to indicate if we consumed the event during the initial pass using\n     * [consumedOnInitial]. We also save the [awaitTouchSlop] between passes so we don't call the\n     * [DragGestureNode.startDragImmediately] as often.\n     */\n    class AwaitDown(\n        var awaitTouchSlop: AwaitTouchSlop = AwaitTouchSlop.NotInitialized,\n        var consumedOnInitial: Boolean = false,\n    ) : DragDetectionState() {\n\n        enum class AwaitTouchSlop {\n            Yes,\n            No,\n            NotInitialized,\n        }\n    }\n\n    /**\n     * If drag should wait for touch slop, after the initial down recognition we move to this state.\n     * Here we will collect drag events until touch slop is crossed.\n     */\n    class AwaitTouchSlop(\n        var initialDown: PointerInputChange? = null,\n        var pointerId: PointerId = PointerId(Long.MAX_VALUE),\n        var verifyConsumptionInFinalPass: Boolean = false,\n    ) : DragDetectionState()\n\n    /**\n     * Alternative state that implements the gesture pick up feature. If a draggable loses an event\n     * because someone else consumed it, it can still pick it up later if the consumer \"gives up\" on\n     * that gesture. Once a gesture is lost the draggable will pass on to this state until all\n     * fingers are up.\n     */\n    class AwaitGesturePickup(\n        var initialDown: PointerInputChange? = null,\n        var pointerId: PointerId = PointerId(Long.MAX_VALUE),\n        var touchSlopDetector: TouchSlopDetector? = null,\n    ) : DragDetectionState()\n\n    /** State where dragging is happening. */\n    class Dragging(var pointerId: PointerId = PointerId(Long.MAX_VALUE)) : DragDetectionState()\n}\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.gestures\n\nimport androidx.compose.animation.core.AnimationState\nimport androidx.compose.animation.core.DecayAnimationSpec\nimport androidx.compose.animation.core.animate\nimport androidx.compose.animation.core.animateDecay\nimport androidx.compose.animation.splineBasedDecay\nimport androidx.compose.foundation.ComposeFoundationFlags.isDelayPressesUsingGestureConsumptionEnabled\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.LocalOverscrollFactory\nimport androidx.compose.foundation.MutatePriority\nimport androidx.compose.foundation.OverscrollEffect\nimport androidx.compose.foundation.gestures.Orientation.Horizontal\nimport androidx.compose.foundation.gestures.Orientation.Vertical\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.internal.PlatformOptimizedCancellationException\nimport androidx.compose.foundation.relocation.BringIntoViewResponderNode\nimport androidx.compose.foundation.rememberOverscrollEffect\nimport androidx.compose.foundation.rememberPlatformOverscrollEffect\nimport androidx.compose.foundation.scrollableArea\nimport androidx.compose.foundation.verticalScroll\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.MotionDurationScale\nimport androidx.compose.ui.focus.FocusTargetModifierNode\nimport androidx.compose.ui.focus.Focusability\nimport androidx.compose.ui.focus.getFocusedRect\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.input.key.Key\nimport androidx.compose.ui.input.key.KeyEvent\nimport androidx.compose.ui.input.key.KeyEventType\nimport androidx.compose.ui.input.key.KeyInputModifierNode\nimport androidx.compose.ui.input.key.isCtrlPressed\nimport androidx.compose.ui.input.key.key\nimport androidx.compose.ui.input.key.type\nimport androidx.compose.ui.input.nestedscroll.NestedScrollConnection\nimport androidx.compose.ui.input.nestedscroll.NestedScrollDispatcher\nimport androidx.compose.ui.input.nestedscroll.NestedScrollSource\nimport androidx.compose.ui.input.nestedscroll.NestedScrollSource.Companion.SideEffect\nimport androidx.compose.ui.input.nestedscroll.NestedScrollSource.Companion.UserInput\nimport androidx.compose.ui.input.nestedscroll.nestedScrollModifierNode\nimport androidx.compose.ui.input.pointer.PointerEvent\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerEventType\nimport androidx.compose.ui.input.pointer.PointerType\nimport androidx.compose.ui.node.CompositionLocalConsumerModifierNode\nimport androidx.compose.ui.node.DelegatableNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.node.SemanticsModifierNode\nimport androidx.compose.ui.node.TraversableNode\nimport androidx.compose.ui.node.dispatchOnScrollChanged\nimport androidx.compose.ui.node.invalidateSemantics\nimport androidx.compose.ui.node.requireDensity\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.semantics.SemanticsPropertyReceiver\nimport androidx.compose.ui.semantics.scrollBy\nimport androidx.compose.ui.semantics.scrollByOffset\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.Velocity\nimport androidx.compose.ui.util.fastAny\nimport kotlin.math.PI\nimport kotlin.math.abs\nimport kotlin.math.absoluteValue\nimport kotlin.math.atan2\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.withContext\n\n/**\n * Configure touch scrolling and flinging for the UI element in a single [Orientation].\n *\n * Users should update their state themselves using default [ScrollableState] and its\n * `consumeScrollDelta` callback or by implementing [ScrollableState] interface manually and reflect\n * their own state in UI when using this component.\n *\n * `scrollable` is a low level modifier that handles low level scrolling input gestures, without\n * other behaviors commonly used for scrollable containers. For building scrollable containers, see\n * [androidx.compose.foundation.scrollableArea]. `scrollableArea` clips its content to its bounds,\n * renders overscroll, and adjusts the direction of scroll gestures to ensure that the content moves\n * with the user's gestures. See also [androidx.compose.foundation.verticalScroll] and\n * [androidx.compose.foundation.horizontalScroll] for high level scrollable containers that handle\n * layout and move the content as the user scrolls.\n *\n * If you don't need to have fling or nested scroll support, but want to make component simply\n * draggable, consider using [draggable].\n *\n * @sample androidx.compose.foundation.samples.ScrollableSample\n * @param state [ScrollableState] state of the scrollable. Defines how scroll events will be\n *   interpreted by the user land logic and contains useful information about on-going events.\n * @param orientation orientation of the scrolling\n * @param enabled whether or not scrolling in enabled\n * @param reverseDirection reverse the direction of the scroll, so top to bottom scroll will behave\n *   like bottom to top and left to right will behave like right to left.\n * @param flingBehavior logic describing fling behavior when drag has finished with velocity. If\n *   `null`, default from [ScrollableDefaults.flingBehavior] will be used.\n * @param interactionSource [MutableInteractionSource] that will be used to emit drag events when\n *   this scrollable is being dragged.\n */\n@Stable\nfun Modifier.scrollable(\n    state: ScrollableState,\n    orientation: Orientation,\n    enabled: Boolean = true,\n    reverseDirection: Boolean = false,\n    flingBehavior: FlingBehavior? = null,\n    interactionSource: MutableInteractionSource? = null,\n): Modifier =\n    scrollable(\n        state = state,\n        orientation = orientation,\n        enabled = enabled,\n        reverseDirection = reverseDirection,\n        flingBehavior = flingBehavior,\n        interactionSource = interactionSource,\n        overscrollEffect = null,\n    )\n\n/**\n * Configure touch scrolling and flinging for the UI element in a single [Orientation].\n *\n * Users should update their state themselves using default [ScrollableState] and its\n * `consumeScrollDelta` callback or by implementing [ScrollableState] interface manually and reflect\n * their own state in UI when using this component.\n *\n * `scrollable` is a low level modifier that handles low level scrolling input gestures, without\n * other behaviors commonly used for scrollable containers. For building scrollable containers, see\n * [androidx.compose.foundation.scrollableArea]. `scrollableArea` clips its content to its bounds,\n * renders overscroll, and adjusts the direction of scroll gestures to ensure that the content moves\n * with the user's gestures. See also [androidx.compose.foundation.verticalScroll] and\n * [androidx.compose.foundation.horizontalScroll] for high level scrollable containers that handle\n * layout and move the content as the user scrolls.\n *\n * If you don't need to have fling or nested scroll support, but want to make component simply\n * draggable, consider using [draggable].\n *\n * This overload provides the access to [OverscrollEffect] that defines the behaviour of the over\n * scrolling logic. Use [androidx.compose.foundation.rememberOverscrollEffect] to create an instance\n * of the current provided overscroll implementation. Note: compared to other APIs that accept\n * [overscrollEffect] such as [scrollableArea] and [verticalScroll], `scrollable` does not render\n * the overscroll, it only provides events. Manually add [androidx.compose.foundation.overscroll] to\n * render the overscroll or use other APIs.\n *\n * @sample androidx.compose.foundation.samples.ScrollableSample\n * @param state [ScrollableState] state of the scrollable. Defines how scroll events will be\n *   interpreted by the user land logic and contains useful information about on-going events.\n * @param orientation orientation of the scrolling\n * @param overscrollEffect effect to which the deltas will be fed when the scrollable have some\n *   scrolling delta left. Pass `null` for no overscroll. If you pass an effect you should also\n *   apply [androidx.compose.foundation.overscroll] modifier.\n * @param enabled whether or not scrolling in enabled\n * @param reverseDirection reverse the direction of the scroll, so top to bottom scroll will behave\n *   like bottom to top and left to right will behave like right to left.\n * @param flingBehavior logic describing fling behavior when drag has finished with velocity. If\n *   `null`, default from [ScrollableDefaults.flingBehavior] will be used.\n * @param interactionSource [MutableInteractionSource] that will be used to emit drag events when\n *   this scrollable is being dragged.\n * @param bringIntoViewSpec The configuration that this scrollable should use to perform scrolling\n *   when scroll requests are received from the focus system. If null is provided the system will\n *   use the behavior provided by [LocalBringIntoViewSpec] which by default has a platform dependent\n *   implementation.\n */\n@Stable\nfun Modifier.scrollable(\n    state: ScrollableState,\n    orientation: Orientation,\n    overscrollEffect: OverscrollEffect?,\n    enabled: Boolean = true,\n    reverseDirection: Boolean = false,\n    flingBehavior: FlingBehavior? = null,\n    interactionSource: MutableInteractionSource? = null,\n    bringIntoViewSpec: BringIntoViewSpec? = null,\n) =\n    this then\n        ScrollableElement(\n            state,\n            orientation,\n            overscrollEffect,\n            enabled,\n            reverseDirection,\n            flingBehavior,\n            interactionSource,\n            bringIntoViewSpec,\n        )\n\nprivate class ScrollableElement(\n    val state: ScrollableState,\n    val orientation: Orientation,\n    val overscrollEffect: OverscrollEffect?,\n    val enabled: Boolean,\n    val reverseDirection: Boolean,\n    val flingBehavior: FlingBehavior?,\n    val interactionSource: MutableInteractionSource?,\n    val bringIntoViewSpec: BringIntoViewSpec?,\n) : ModifierNodeElement<ScrollableNode>() {\n    override fun create(): ScrollableNode {\n        return ScrollableNode(\n            state,\n            overscrollEffect,\n            flingBehavior,\n            orientation,\n            enabled,\n            reverseDirection,\n            interactionSource,\n            bringIntoViewSpec,\n        )\n    }\n\n    override fun update(node: ScrollableNode) {\n        node.update(\n            state,\n            orientation,\n            overscrollEffect,\n            enabled,\n            reverseDirection,\n            flingBehavior,\n            interactionSource,\n            bringIntoViewSpec,\n        )\n    }\n\n    override fun hashCode(): Int {\n        var result = state.hashCode()\n        result = 31 * result + orientation.hashCode()\n        result = 31 * result + overscrollEffect.hashCode()\n        result = 31 * result + enabled.hashCode()\n        result = 31 * result + reverseDirection.hashCode()\n        result = 31 * result + flingBehavior.hashCode()\n        result = 31 * result + interactionSource.hashCode()\n        result = 31 * result + bringIntoViewSpec.hashCode()\n        return result\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n\n        if (other !is ScrollableElement) return false\n\n        if (state != other.state) return false\n        if (orientation != other.orientation) return false\n        if (overscrollEffect != other.overscrollEffect) return false\n        if (enabled != other.enabled) return false\n        if (reverseDirection != other.reverseDirection) return false\n        if (flingBehavior != other.flingBehavior) return false\n        if (interactionSource != other.interactionSource) return false\n        if (bringIntoViewSpec != other.bringIntoViewSpec) return false\n\n        return true\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"scrollable\"\n        properties[\"orientation\"] = orientation\n        properties[\"state\"] = state\n        properties[\"overscrollEffect\"] = overscrollEffect\n        properties[\"enabled\"] = enabled\n        properties[\"reverseDirection\"] = reverseDirection\n        properties[\"flingBehavior\"] = flingBehavior\n        properties[\"interactionSource\"] = interactionSource\n        properties[\"bringIntoViewSpec\"] = bringIntoViewSpec\n    }\n}\n\n@OptIn(ExperimentalFoundationApi::class)\ninternal class ScrollableNode(\n    state: ScrollableState,\n    private var overscrollEffect: OverscrollEffect?,\n    private var flingBehavior: FlingBehavior?,\n    orientation: Orientation,\n    enabled: Boolean,\n    reverseDirection: Boolean,\n    interactionSource: MutableInteractionSource?,\n    bringIntoViewSpec: BringIntoViewSpec?,\n) :\n    DragGestureNode(\n        canDrag = CanDragCalculation,\n        enabled = enabled,\n        interactionSource = interactionSource,\n        orientationLock = orientation,\n    ),\n    KeyInputModifierNode,\n    SemanticsModifierNode,\n    OnScrollChangedDispatcher {\n\n    override val shouldAutoInvalidate: Boolean = false\n\n    private val nestedScrollDispatcher = NestedScrollDispatcher()\n\n    // Place holder fling behavior, we'll initialize it when the density is available.\n    private val defaultFlingBehavior = platformScrollableDefaultFlingBehavior()\n\n    private val scrollingLogic =\n        ScrollingLogic(\n            scrollableState = state,\n            orientation = orientation,\n            overscrollEffect = overscrollEffect,\n            reverseDirection = reverseDirection,\n            flingBehavior = flingBehavior ?: defaultFlingBehavior,\n            nestedScrollDispatcher = nestedScrollDispatcher,\n            onScrollChangedDispatcher = this,\n            isScrollableNodeAttached = { isAttached },\n        )\n\n    private val nestedScrollConnection =\n        ScrollableNestedScrollConnection(enabled = enabled, scrollingLogic = scrollingLogic)\n\n    private val focusTargetModifierNode =\n        delegate(FocusTargetModifierNode(focusability = Focusability.Never))\n\n    private val contentInViewNode =\n        delegate(\n            ContentInViewNode(\n                orientation = orientation,\n                scrollingLogic = scrollingLogic,\n                reverseDirection = reverseDirection,\n                bringIntoViewSpec = bringIntoViewSpec,\n                getFocusedRect = { focusTargetModifierNode.getFocusedRect() },\n            )\n        )\n\n    private var scrollByAction: ((x: Float, y: Float) -> Boolean)? = null\n    private var scrollByOffsetAction: (suspend (Offset) -> Offset)? = null\n\n    private var mouseWheelScrollingLogic: MouseWheelScrollingLogic? = null\n    private var trackpadScrollingLogic: TrackpadScrollingLogic? = null\n\n    private var scrollableContainerNode: ScrollableContainerNode? = null\n\n    init {\n        /** Nested scrolling */\n        delegate(nestedScrollModifierNode(nestedScrollConnection, nestedScrollDispatcher))\n\n        /** Focus scrolling */\n        delegate(BringIntoViewResponderNode(contentInViewNode))\n\n        if (!isDelayPressesUsingGestureConsumptionEnabled) {\n            scrollableContainerNode = delegate(ScrollableContainerNode(enabled))\n        }\n    }\n\n    override fun dispatchScrollDeltaInfo(delta: Offset) {\n        if (!isAttached) return\n        dispatchOnScrollChanged(delta)\n    }\n\n    override suspend fun drag(\n        forEachDelta: suspend ((dragDelta: DragEvent.DragDelta) -> Unit) -> Unit\n    ) {\n        with(scrollingLogic) {\n            scroll(scrollPriority = MutatePriority.UserInput) {\n                forEachDelta {\n                    // Indirect pointer Events should be reverted to account for the reverse we\n                    // do in Scrollable. Regular touchscreen events are inverted in scrollable, but\n                    // that shouldn't happen for indirect pointer events, so we cancel the reverse\n                    // here.\n                    val invertIndirectPointer = if (it.isIndirectPointerEvent) -1f else 1f\n                    scrollByWithOverscroll(\n                        it.delta.singleAxisOffset() * invertIndirectPointer,\n                        source = UserInput,\n                    )\n                }\n            }\n        }\n    }\n\n    override fun onDragStarted(startedPosition: Offset) {}\n\n    override fun onDragStopped(event: DragEvent.DragStopped) {\n        nestedScrollDispatcher.coroutineScope.launch {\n            // Indirect pointer Events should be reverted to account for the reverse we\n            // do in Scrollable. Regular touchscreen events are inverted in scrollable, but\n            // that shouldn't happen for indirect pointer events, so we cancel the reverse\n            // here.\n            val invertIndirectPointer = if (event.isIndirectPointerEvent) -1f else 1f\n            scrollingLogic.onScrollStopped(\n                event.velocity * invertIndirectPointer,\n                isMouseWheel = false,\n            )\n        }\n    }\n\n    private fun onWheelScrollStopped(velocity: Velocity) {\n        nestedScrollDispatcher.coroutineScope.launch {\n            scrollingLogic.onScrollStopped(velocity, isMouseWheel = true)\n        }\n    }\n\n    private fun onTrackpadScrollStopped(velocity: Velocity) {\n        nestedScrollDispatcher.coroutineScope.launch {\n            scrollingLogic.onScrollStopped(velocity, isMouseWheel = false)\n        }\n    }\n\n    override fun startDragImmediately(): Boolean {\n        return scrollingLogic.shouldScrollImmediately()\n    }\n\n    private fun ensureMouseWheelScrollingLogicInitialized() {\n        if (mouseWheelScrollingLogic == null) {\n            mouseWheelScrollingLogic =\n                MouseWheelScrollingLogic(\n                    scrollingLogic = scrollingLogic,\n                    mouseWheelScrollConfig = platformScrollConfig(),\n                    onScrollStopped = ::onWheelScrollStopped,\n                    density = requireDensity(),\n                )\n        }\n\n        mouseWheelScrollingLogic?.startReceivingEvents(coroutineScope)\n    }\n\n    private fun ensureTrackpadScrollingLogicInitialized() {\n        if (trackpadScrollingLogic == null) {\n            trackpadScrollingLogic =\n                TrackpadScrollingLogic(\n                    scrollingLogic = scrollingLogic,\n                    onScrollStopped = ::onTrackpadScrollStopped,\n                    density = requireDensity(),\n                )\n        }\n\n        trackpadScrollingLogic?.startReceivingEvents(coroutineScope)\n    }\n\n    fun update(\n        state: ScrollableState,\n        orientation: Orientation,\n        overscrollEffect: OverscrollEffect?,\n        enabled: Boolean,\n        reverseDirection: Boolean,\n        flingBehavior: FlingBehavior?,\n        interactionSource: MutableInteractionSource?,\n        bringIntoViewSpec: BringIntoViewSpec?,\n    ) {\n        var shouldInvalidateSemantics = false\n        if (this.enabled != enabled) { // enabled changed\n            nestedScrollConnection.enabled = enabled\n            scrollableContainerNode?.update(enabled)\n            shouldInvalidateSemantics = true\n        }\n        // a new fling behavior was set, change the resolved one.\n        val resolvedFlingBehavior = flingBehavior ?: defaultFlingBehavior\n\n        val resetPointerInputHandling =\n            scrollingLogic.update(\n                scrollableState = state,\n                orientation = orientation,\n                overscrollEffect = overscrollEffect,\n                reverseDirection = reverseDirection,\n                flingBehavior = resolvedFlingBehavior,\n                nestedScrollDispatcher = nestedScrollDispatcher,\n            )\n        contentInViewNode.update(orientation, reverseDirection, bringIntoViewSpec)\n\n        this.overscrollEffect = overscrollEffect\n        this.flingBehavior = flingBehavior\n\n        // update DragGestureNode\n        update(\n            canDrag = CanDragCalculation,\n            enabled = enabled,\n            interactionSource = interactionSource,\n            orientationLock = if (scrollingLogic.isVertical()) Vertical else Horizontal,\n            shouldResetPointerInputHandling = resetPointerInputHandling,\n        )\n\n        if (shouldInvalidateSemantics) {\n            clearScrollSemanticsActions()\n            invalidateSemantics()\n        }\n    }\n\n    override fun onAttach() {\n        updateDefaultFlingBehavior()\n        mouseWheelScrollingLogic?.updateDensity(requireDensity())\n        trackpadScrollingLogic?.updateDensity(requireDensity())\n    }\n\n    private fun updateDefaultFlingBehavior() {\n        if (!isAttached) return\n        val density = requireDensity()\n        defaultFlingBehavior.updateDensity(density)\n    }\n\n    override fun onDensityChange() {\n        onCancelPointerInput()\n        updateDefaultFlingBehavior()\n        mouseWheelScrollingLogic?.updateDensity(requireDensity())\n        trackpadScrollingLogic?.updateDensity(requireDensity())\n    }\n\n    // Key handler for Page up/down scrolling behavior.\n    override fun onKeyEvent(event: KeyEvent): Boolean {\n        return if (\n            enabled &&\n                (event.key == Key.PageDown || event.key == Key.PageUp) &&\n                (event.type == KeyEventType.KeyDown) &&\n                (!event.isCtrlPressed)\n        ) {\n\n            val scrollAmount: Offset =\n                if (scrollingLogic.isVertical()) {\n                    val viewportHeight = contentInViewNode.viewportSizeOrZero.height\n\n                    val yAmount =\n                        if (event.key == Key.PageUp) {\n                            viewportHeight.toFloat()\n                        } else {\n                            -viewportHeight.toFloat()\n                        }\n\n                    Offset(0f, yAmount)\n                } else {\n                    val viewportWidth = contentInViewNode.viewportSizeOrZero.width\n\n                    val xAmount =\n                        if (event.key == Key.PageUp) {\n                            viewportWidth.toFloat()\n                        } else {\n                            -viewportWidth.toFloat()\n                        }\n\n                    Offset(xAmount, 0f)\n                }\n\n            // A coroutine is launched for every individual scroll event in the\n            // larger scroll gesture. If we see degradation in the future (that is,\n            // a fast scroll gesture on a slow device causes UI jank [not seen up to\n            // this point), we can switch to a more efficient solution where we\n            // lazily launch one coroutine (with the first event) and use a Channel\n            // to communicate the scroll amount to the UI thread.\n            coroutineScope.launch {\n                scrollingLogic.scroll(scrollPriority = MutatePriority.UserInput) {\n                    scrollBy(offset = scrollAmount, source = UserInput)\n                }\n            }\n            true\n        } else {\n            false\n        }\n    }\n\n    override fun onPreKeyEvent(event: KeyEvent) = false\n\n    // Forward all PointerInputModifierNode method calls to `mmouseWheelScrollNode.pointerInputNode`\n    // See explanation in `MouseWheelScrollNode.pointerInputNode`\n\n    override fun onPointerEvent(\n        pointerEvent: PointerEvent,\n        pass: PointerEventPass,\n        bounds: IntSize,\n    ) {\n        if (pointerEvent.changes.fastAny { canDrag.invoke(it.type) }) {\n            super.onPointerEvent(pointerEvent, pass, bounds)\n        }\n        initializeGestureCoordination()\n        if (enabled) {\n            if (pass == PointerEventPass.Initial && pointerEvent.type == PointerEventType.Scroll) {\n                ensureMouseWheelScrollingLogicInitialized()\n            }\n            mouseWheelScrollingLogic?.onPointerEvent(pointerEvent, pass, bounds)\n\n            if (\n                pass == PointerEventPass.Initial &&\n                    (pointerEvent.type == PointerEventType.PanStart ||\n                        pointerEvent.type == PointerEventType.PanMove ||\n                        pointerEvent.type == PointerEventType.PanEnd)\n            ) {\n                ensureTrackpadScrollingLogicInitialized()\n            }\n            trackpadScrollingLogic?.onPointerEvent(pointerEvent, pass, bounds)\n        }\n    }\n\n    override fun SemanticsPropertyReceiver.applySemantics() {\n        if (enabled && (scrollByAction == null || scrollByOffsetAction == null)) {\n            setScrollSemanticsActions()\n        }\n\n        scrollByAction?.let { scrollBy(action = it) }\n\n        scrollByOffsetAction?.let { scrollByOffset(action = it) }\n    }\n\n    private fun setScrollSemanticsActions() {\n        scrollByAction = { x, y ->\n            coroutineScope.launch { scrollingLogic.semanticsScrollBy(Offset(x, y)) }\n            true\n        }\n\n        scrollByOffsetAction = { offset -> scrollingLogic.semanticsScrollBy(offset) }\n    }\n\n    private fun clearScrollSemanticsActions() {\n        scrollByAction = null\n        scrollByOffsetAction = null\n    }\n}\n\n/** Contains the default values used by [scrollable] */\nobject ScrollableDefaults {\n\n    /** Create and remember default [FlingBehavior] that will represent natural fling curve. */\n    @Composable fun flingBehavior(): FlingBehavior = rememberPlatformDefaultFlingBehavior()\n\n    /**\n     * Returns a remembered [OverscrollEffect] created from the current value of\n     * [LocalOverscrollFactory].\n     *\n     * This API has been deprecated, and replaced with [rememberOverscrollEffect]\n     */\n    @Deprecated(\n        \"This API has been replaced with rememberOverscrollEffect, which queries theme provided OverscrollFactory values instead of the 'platform default' without customization.\",\n        replaceWith =\n            ReplaceWith(\n                \"rememberOverscrollEffect()\",\n                \"androidx.compose.foundation.rememberOverscrollEffect\",\n            ),\n    )\n    @Composable\n    fun overscrollEffect(): OverscrollEffect {\n        return rememberPlatformOverscrollEffect() ?: NoOpOverscrollEffect\n    }\n\n    private object NoOpOverscrollEffect : OverscrollEffect {\n        override fun applyToScroll(\n            delta: Offset,\n            source: NestedScrollSource,\n            performScroll: (Offset) -> Offset,\n        ): Offset = performScroll(delta)\n\n        override suspend fun applyToFling(\n            velocity: Velocity,\n            performFling: suspend (Velocity) -> Velocity,\n        ) {\n            performFling(velocity)\n        }\n\n        override val isInProgress: Boolean\n            get() = false\n\n        override val node: DelegatableNode\n            get() = object : Modifier.Node() {}\n    }\n\n    /**\n     * Calculates the final `reverseDirection` value for a scrollable component.\n     *\n     * This is a helper function used by [androidx.compose.foundation.scrollableArea] to determine\n     * whether to reverse the direction of scroll input. The goal is to provide a \"natural\"\n     * scrolling experience where content moves with the user's gesture, while also accounting for\n     * the [layoutDirection].\n     *\n     * The logic is as follows:\n     * 1. To achieve \"natural\" scrolling (content moves with the gesture), scroll deltas are\n     *    inverted. This function returns `true` by default when `reverseScrolling` is `false`.\n     * 2. In a Right-to-Left (`Rtl`) context with a `Horizontal` orientation, the direction is\n     *    flipped an additional time to maintain the natural feel, as the content is laid out from\n     *    right to left.\n     *\n     * @param layoutDirection current layout direction (e.g. from [LocalLayoutDirection])\n     * @param orientation orientation of scroll\n     * @param reverseScrolling whether scrolling direction should be reversed\n     * @return `true` if scroll direction should be reversed, `false` otherwise.\n     */\n    fun reverseDirection(\n        layoutDirection: LayoutDirection,\n        orientation: Orientation,\n        reverseScrolling: Boolean,\n    ): Boolean {\n        // A finger moves with the content, not with the viewport. Therefore,\n        // always reverse once to have \"natural\" gesture that goes reversed to layout\n        var reverseDirection = !reverseScrolling\n        // But if rtl and horizontal, things move the other way around\n        val isRtl = layoutDirection == LayoutDirection.Rtl\n        if (isRtl && orientation != Orientation.Vertical) {\n            reverseDirection = !reverseDirection\n        }\n        return reverseDirection\n    }\n}\n\ninternal interface ScrollConfig {\n\n    /** Enables animated transition of scroll on mouse wheel events. */\n    val isSmoothScrollingEnabled: Boolean\n        get() = true\n\n    fun isPreciseWheelScroll(event: PointerEvent): Boolean = false\n\n    fun Density.calculateMouseWheelScroll(event: PointerEvent, bounds: IntSize): Offset\n}\n\ninternal expect fun CompositionLocalConsumerModifierNode.platformScrollConfig(): ScrollConfig\n\n// TODO: provide public way to drag by mouse (especially requested for Pager)\ninternal val CanDragCalculation: (PointerType) -> Boolean = { type -> type != PointerType.Mouse }\n\n/**\n * Holds all scrolling related logic: controls nested scrolling, flinging, overscroll and delta\n * dispatching.\n */\ninternal class ScrollingLogic(\n    var scrollableState: ScrollableState,\n    private var overscrollEffect: OverscrollEffect?,\n    private var flingBehavior: FlingBehavior,\n    private var orientation: Orientation,\n    private var reverseDirection: Boolean,\n    private var nestedScrollDispatcher: NestedScrollDispatcher,\n    private var onScrollChangedDispatcher: OnScrollChangedDispatcher,\n    private val isScrollableNodeAttached: () -> Boolean,\n) : ScrollLogic {\n    // specifies if this scrollable node is currently flinging\n    override var isFlinging = false\n        private set\n\n    fun Float.toOffset(): Offset =\n        when {\n            this == 0f -> Offset.Zero\n            orientation == Horizontal -> Offset(this, 0f)\n            else -> Offset(0f, this)\n        }\n\n    fun Offset.singleAxisOffset(): Offset =\n        if (orientation == Horizontal) copy(y = 0f) else copy(x = 0f)\n\n    fun Offset.toFloat(): Float = if (orientation == Horizontal) this.x else this.y\n\n    /**\n     * Converts this offset to a single axis delta based on the derived angle from the x and y\n     * deltas.\n     *\n     * @return Returns a single axis delta based on the angle. If the angle is mostly horizontal,\n     *   and we are in a horizontal scrollable, this will return the x component. If the angle is\n     *   mostly vertical, and we are in a vertical scrollable, this will return the y component.\n     *   Otherwise, this will return 0. Mostly horizontal means angles smaller than\n     *   [VerticalAxisThresholdAngle].\n     */\n    fun Offset.toSingleAxisDeltaFromAngle(): Float {\n        val angle = atan2(this.y.absoluteValue, this.x.absoluteValue)\n        return if (angle >= VerticalAxisThresholdAngle) {\n            if (orientation == Vertical) this.y else 0f\n        } else {\n            if (orientation == Horizontal) this.x else 0f\n        }\n    }\n\n    fun Float.toVelocity(): Velocity =\n        when {\n            this == 0f -> Velocity.Zero\n            orientation == Horizontal -> Velocity(this, 0f)\n            else -> Velocity(0f, this)\n        }\n\n    private fun Velocity.toFloat(): Float = if (orientation == Horizontal) this.x else this.y\n\n    private fun Velocity.singleAxisVelocity(): Velocity =\n        if (orientation == Horizontal) copy(y = 0f) else copy(x = 0f)\n\n    private fun Velocity.update(newValue: Float): Velocity =\n        if (orientation == Horizontal) copy(x = newValue) else copy(y = newValue)\n\n    fun Float.reverseIfNeeded(): Float = if (reverseDirection) this * -1 else this\n\n    fun Offset.reverseIfNeeded(): Offset = if (reverseDirection) this * -1f else this\n\n    private var latestScrollSource = UserInput\n    private var outerStateScope = NoOpScrollScope\n\n    private val nestedScrollScope =\n        object : NestedScrollScope {\n            override fun scrollBy(offset: Offset, source: NestedScrollSource): Offset {\n                return with(outerStateScope) { performScroll(offset, source) }\n            }\n\n            override fun scrollByWithOverscroll(\n                offset: Offset,\n                source: NestedScrollSource,\n            ): Offset {\n                latestScrollSource = source\n                val overscroll = overscrollEffect\n                return if (overscroll != null && shouldDispatchOverscroll) {\n                    overscroll.applyToScroll(offset, latestScrollSource, performScrollForOverscroll)\n                } else {\n                    with(outerStateScope) { performScroll(offset, source) }\n                }\n            }\n        }\n\n    private val performScrollForOverscroll: (Offset) -> Offset = { delta ->\n        with(outerStateScope) { performScroll(delta, latestScrollSource) }\n    }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    private fun ScrollScope.performScroll(delta: Offset, source: NestedScrollSource): Offset {\n        val consumedByPreScroll = nestedScrollDispatcher.dispatchPreScroll(delta, source)\n\n        val scrollAvailableAfterPreScroll = delta - consumedByPreScroll\n\n        val singleAxisDeltaForSelfScroll =\n            scrollAvailableAfterPreScroll.singleAxisOffset().reverseIfNeeded().toFloat()\n\n        // Consume on a single axis.\n        val consumedBySelfScroll =\n            scrollBy(singleAxisDeltaForSelfScroll).toOffset().reverseIfNeeded()\n\n        // Trigger on scroll changed callback\n        onScrollChangedDispatcher.dispatchScrollDeltaInfo(consumedBySelfScroll)\n\n        val deltaAvailableAfterScroll = scrollAvailableAfterPreScroll - consumedBySelfScroll\n        val consumedByPostScroll =\n            nestedScrollDispatcher.dispatchPostScroll(\n                consumedBySelfScroll,\n                deltaAvailableAfterScroll,\n                source,\n            )\n        return consumedByPreScroll + consumedBySelfScroll + consumedByPostScroll\n    }\n\n    private val shouldDispatchOverscroll\n        get() = scrollableState.canScrollForward || scrollableState.canScrollBackward\n\n    override fun performRawScroll(scroll: Offset): Offset {\n        return if (scrollableState.isScrollInProgress) {\n            Offset.Zero\n        } else {\n            dispatchRawDelta(scroll)\n        }\n    }\n\n    private fun dispatchRawDelta(scroll: Offset): Offset {\n        return scrollableState\n            .dispatchRawDelta(scroll.toFloat().reverseIfNeeded())\n            .reverseIfNeeded()\n            .toOffset()\n    }\n\n    suspend fun onScrollStopped(initialVelocity: Velocity, isMouseWheel: Boolean) {\n        if (isMouseWheel && !flingBehavior.shouldBeTriggeredByMouseWheel) {\n            return\n        }\n        val availableVelocity = initialVelocity.singleAxisVelocity()\n\n        val performFling: suspend (Velocity) -> Velocity = { velocity ->\n            val preConsumedByParent = nestedScrollDispatcher.dispatchPreFling(velocity)\n            val available = velocity - preConsumedByParent\n\n            val velocityLeft = doFlingAnimation(available)\n\n            val consumedPost =\n                nestedScrollDispatcher.dispatchPostFling((available - velocityLeft), velocityLeft)\n            val totalLeft = velocityLeft - consumedPost\n            velocity - totalLeft\n        }\n\n        val overscroll = overscrollEffect\n        if (overscroll != null && shouldDispatchOverscroll) {\n            overscroll.applyToFling(availableVelocity, performFling)\n        } else {\n            performFling(availableVelocity)\n        }\n    }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    override suspend fun doFlingAnimation(available: Velocity): Velocity {\n        var result: Velocity = available\n        isFlinging = true\n        try {\n            scroll(scrollPriority = MutatePriority.Default) {\n                val nestedScrollScope = this\n                val reverseScope =\n                    object : ScrollScope {\n                        override fun scrollBy(pixels: Float): Float {\n                            // Fling has hit the bounds or node left composition,\n                            // cancel it to allow continuation. This will conclude this node's\n                            // fling,\n                            // allowing the onPostFling signal to be called\n                            // with the leftover velocity from the fling animation. Any nested\n                            // scroll\n                            // node above will be able to pick up the left over velocity and\n                            // continue\n                            // the fling.\n                            if (\n                                pixels.absoluteValue != 0.0f && !isScrollableNodeAttached.invoke()\n                            ) {\n                                throw FlingCancellationException()\n                            }\n\n                            return nestedScrollScope\n                                .scrollByWithOverscroll(\n                                    offset = pixels.toOffset().reverseIfNeeded(),\n                                    source = SideEffect,\n                                )\n                                .toFloat()\n                                .reverseIfNeeded()\n                        }\n                    }\n                with(reverseScope) {\n                    with(flingBehavior) {\n                        result =\n                            result.update(\n                                performFling(available.toFloat().reverseIfNeeded())\n                                    .reverseIfNeeded()\n                            )\n                    }\n                }\n            }\n        } finally {\n            isFlinging = false\n        }\n\n        return result\n    }\n\n    fun shouldScrollImmediately(): Boolean {\n        return scrollableState.isScrollInProgress || overscrollEffect?.isInProgress ?: false\n    }\n\n    /** Opens a scrolling session with nested scrolling and overscroll support. */\n    suspend fun scroll(\n        scrollPriority: MutatePriority = MutatePriority.Default,\n        block: suspend NestedScrollScope.() -> Unit,\n    ) {\n        scrollableState.scroll(scrollPriority) {\n            outerStateScope = this\n            block.invoke(nestedScrollScope)\n        }\n    }\n\n    /** @return true if the pointer input should be reset */\n    fun update(\n        scrollableState: ScrollableState,\n        orientation: Orientation,\n        overscrollEffect: OverscrollEffect?,\n        reverseDirection: Boolean,\n        flingBehavior: FlingBehavior,\n        nestedScrollDispatcher: NestedScrollDispatcher,\n    ): Boolean {\n        var resetPointerInputHandling = false\n        if (this.scrollableState != scrollableState) {\n            this.scrollableState = scrollableState\n            resetPointerInputHandling = true\n        }\n        this.overscrollEffect = overscrollEffect\n        if (this.orientation != orientation) {\n            this.orientation = orientation\n            resetPointerInputHandling = true\n        }\n        if (this.reverseDirection != reverseDirection) {\n            this.reverseDirection = reverseDirection\n            resetPointerInputHandling = true\n        }\n        this.flingBehavior = flingBehavior\n        this.nestedScrollDispatcher = nestedScrollDispatcher\n        return resetPointerInputHandling\n    }\n\n    fun isVertical(): Boolean = orientation == Vertical\n}\n\nprivate val NoOpScrollScope: ScrollScope =\n    object : ScrollScope {\n        override fun scrollBy(pixels: Float): Float = pixels\n    }\n\ninternal class ScrollableNestedScrollConnection(\n    val scrollingLogic: ScrollLogic,\n    var enabled: Boolean,\n) : NestedScrollConnection {\n\n    override fun onPostScroll(\n        consumed: Offset,\n        available: Offset,\n        source: NestedScrollSource,\n    ): Offset =\n        if (enabled) {\n            scrollingLogic.performRawScroll(available)\n        } else {\n            Offset.Zero\n        }\n\n    @OptIn(ExperimentalFoundationApi::class)\n    override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {\n        return if (enabled) {\n            val velocityLeft =\n                if (scrollingLogic.isFlinging) {\n                    Velocity.Zero\n                } else {\n                    scrollingLogic.doFlingAnimation(available)\n                }\n            available - velocityLeft\n        } else {\n            Velocity.Zero\n        }\n    }\n}\n\n/** Interface to allow re-use across Scrollable and Scrollable2D. */\ninternal interface ScrollLogic {\n    val isFlinging: Boolean\n\n    fun performRawScroll(scroll: Offset): Offset\n\n    suspend fun doFlingAnimation(available: Velocity): Velocity\n}\n\n/** Compatibility interface for default fling behaviors that depends on [Density]. */\ninternal interface ScrollableDefaultFlingBehavior : FlingBehavior {\n    /**\n     * Update the internal parameters of FlingBehavior in accordance with the new\n     * [androidx.compose.ui.unit.Density] value.\n     *\n     * @param density new density value.\n     */\n    fun updateDensity(density: Density) = Unit\n}\n\n/**\n * TODO: Move it to public interface Currently, default [FlingBehavior] is not triggered at all to\n *   avoid unexpected effects during regular scrolling. However, custom one must be triggered\n *   because it's used not only for \"inertia\", but also for snapping in\n *   [androidx.compose.foundation.pager.Pager] or\n *   [androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior].\n */\nprivate val FlingBehavior.shouldBeTriggeredByMouseWheel\n    get() = this !is ScrollableDefaultFlingBehavior\n\n/**\n * This method returns [ScrollableDefaultFlingBehavior] whose density will be managed by the\n * [ScrollableElement] because it's not created inside [Composable] context. This is different from\n * [rememberPlatformDefaultFlingBehavior] which creates [FlingBehavior] whose density depends on\n * [LocalDensity] and is automatically resolved.\n */\ninternal expect fun platformScrollableDefaultFlingBehavior(): ScrollableDefaultFlingBehavior\n\n/**\n * Create and remember default [FlingBehavior] that will represent natural platform fling decay\n * behavior.\n */\n@Composable internal expect fun rememberPlatformDefaultFlingBehavior(): FlingBehavior\n\ninternal class DefaultFlingBehavior(\n    private var flingDecay: DecayAnimationSpec<Float>,\n    private val motionDurationScale: MotionDurationScale = DefaultScrollMotionDurationScale,\n) : ScrollableDefaultFlingBehavior {\n\n    // For Testing\n    var lastAnimationCycleCount = 0\n\n    override suspend fun ScrollScope.performFling(initialVelocity: Float): Float {\n        lastAnimationCycleCount = 0\n        // come up with the better threshold, but we need it since spline curve gives us NaNs\n        return withContext(motionDurationScale) {\n            if (abs(initialVelocity) > 1f) {\n                var velocityLeft = initialVelocity\n                var lastValue = 0f\n                val animationState =\n                    AnimationState(initialValue = 0f, initialVelocity = initialVelocity)\n                try {\n                    animationState.animateDecay(flingDecay) {\n                        val delta = value - lastValue\n                        val consumed = scrollBy(delta)\n                        lastValue = value\n                        velocityLeft = this.velocity\n                        // avoid rounding errors and stop if anything is unconsumed\n                        if (abs(delta - consumed) > 0.5f) this.cancelAnimation()\n                        lastAnimationCycleCount++\n                    }\n                } catch (exception: CancellationException) {\n                    velocityLeft = animationState.velocity\n                }\n                velocityLeft\n            } else {\n                initialVelocity\n            }\n        }\n    }\n\n    override fun updateDensity(density: Density) {\n        flingDecay = splineBasedDecay(density)\n    }\n}\n\nprivate const val DefaultScrollMotionDurationScaleFactor = 1f\ninternal val DefaultScrollMotionDurationScale =\n    object : MotionDurationScale {\n        override val scaleFactor: Float\n            get() = DefaultScrollMotionDurationScaleFactor\n    }\n\n/**\n * (b/311181532): This could not be flattened so we moved it to TraversableNode, but ideally\n * ScrollabeNode should be the one to be travesable.\n */\ninternal class ScrollableContainerNode(enabled: Boolean) : Modifier.Node(), TraversableNode {\n    override val traverseKey: Any = TraverseKey\n\n    var enabled: Boolean = enabled\n        private set\n\n    companion object TraverseKey\n\n    fun update(enabled: Boolean) {\n        this.enabled = enabled\n    }\n}\n\ninternal val UnityDensity =\n    object : Density {\n        override val density: Float\n            get() = 1f\n\n        override val fontScale: Float\n            get() = 1f\n    }\n\n/** A scroll scope for nested scrolling and overscroll support. */\ninternal interface NestedScrollScope {\n    fun scrollBy(offset: Offset, source: NestedScrollSource): Offset\n\n    fun scrollByWithOverscroll(offset: Offset, source: NestedScrollSource): Offset\n}\n\n/**\n * Scroll deltas originating from the semantics system. Should be dispatched as an animation driven\n * event.\n */\nprivate suspend fun ScrollingLogic.semanticsScrollBy(offset: Offset): Offset {\n    var previousValue = 0f\n    scroll(scrollPriority = MutatePriority.Default) {\n        animate(0f, offset.toFloat()) { currentValue, _ ->\n            val delta = currentValue - previousValue\n            val consumed =\n                scrollBy(offset = delta.reverseIfNeeded().toOffset(), source = UserInput)\n                    .toFloat()\n                    .reverseIfNeeded()\n            previousValue += consumed\n        }\n    }\n    return previousValue.toOffset()\n}\n\ninternal class FlingCancellationException :\n    PlatformOptimizedCancellationException(\"The fling animation was cancelled\")\n\ninternal interface OnScrollChangedDispatcher {\n    fun dispatchScrollDeltaInfo(delta: Offset)\n}\n\nprivate const val VerticalAxisThresholdAngle = PI / 4\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Transformable.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.gestures\n\nimport androidx.compose.foundation.ComposeFoundationFlags\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.MutatePriority\nimport androidx.compose.foundation.gestures.TransformEvent.TransformDelta\nimport androidx.compose.foundation.gestures.TransformEvent.TransformStarted\nimport androidx.compose.foundation.gestures.TransformEvent.TransformStopped\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.input.pointer.AwaitPointerEventScope\nimport androidx.compose.ui.input.pointer.PointerEvent\nimport androidx.compose.ui.input.pointer.PointerEventPass\nimport androidx.compose.ui.input.pointer.PointerEventType\nimport androidx.compose.ui.input.pointer.PointerInputScope\nimport androidx.compose.ui.input.pointer.PointerType\nimport androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNode\nimport androidx.compose.ui.input.pointer.isCtrlPressed\nimport androidx.compose.ui.input.pointer.positionChanged\nimport androidx.compose.ui.node.CompositionLocalConsumerModifierNode\nimport androidx.compose.ui.node.DelegatingNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.node.PointerInputModifierNode\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.util.fastAny\nimport androidx.compose.ui.util.fastFold\nimport androidx.compose.ui.util.fastForEach\nimport kotlin.math.PI\nimport kotlin.math.abs\nimport kotlin.math.pow\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.CoroutineStart\nimport kotlinx.coroutines.channels.Channel\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.currentCoroutineContext\nimport kotlinx.coroutines.isActive\nimport kotlinx.coroutines.launch\n\n/**\n * Enable transformation gestures of the modified UI element.\n *\n * Users should update their state themselves using default [TransformableState] and its\n * `onTransformation` callback or by implementing [TransformableState] interface manually and\n * reflect their own state in UI when using this component.\n *\n * @sample androidx.compose.foundation.samples.TransformableSample\n * @param state [TransformableState] of the transformable. Defines how transformation events will be\n *   interpreted by the user land logic, contains useful information about on-going events and\n *   provides animation capabilities.\n * @param lockRotationOnZoomPan If `true`, rotation is allowed only if touch slop is detected for\n *   rotation before pan or zoom motions. If not, pan and zoom gestures will be detected, but\n *   rotation gestures will not be. If `false`, once touch slop is reached, all three gestures are\n *   detected.\n * @param enabled whether zooming by gestures is enabled or not\n */\nfun Modifier.transformable(\n    state: TransformableState,\n    lockRotationOnZoomPan: Boolean = false,\n    enabled: Boolean = true,\n) = transformable(state, { true }, lockRotationOnZoomPan, enabled)\n\n/**\n * Enable transformation gestures of the modified UI element.\n *\n * Users should update their state themselves using default [TransformableState] and its\n * `onTransformation` callback or by implementing [TransformableState] interface manually and\n * reflect their own state in UI when using this component.\n *\n * This overload of transformable modifier provides [canPan] parameter, which allows the caller to\n * control when the pan can start. making pan gesture to not to start when the scale is 1f makes\n * transformable modifiers to work well within the scrollable container. See example:\n *\n * @sample androidx.compose.foundation.samples.TransformableSampleInsideScroll\n * @param state [TransformableState] of the transformable. Defines how transformation events will be\n *   interpreted by the user land logic, contains useful information about on-going events and\n *   provides animation capabilities.\n * @param canPan whether the pan gesture can be performed or not given the pan offset\n * @param lockRotationOnZoomPan If `true`, rotation is allowed only if touch slop is detected for\n *   rotation before pan or zoom motions. If not, pan and zoom gestures will be detected, but\n *   rotation gestures will not be. If `false`, once touch slop is reached, all three gestures are\n *   detected.\n * @param enabled whether zooming by gestures is enabled or not\n */\nfun Modifier.transformable(\n    state: TransformableState,\n    canPan: (Offset) -> Boolean,\n    lockRotationOnZoomPan: Boolean = false,\n    enabled: Boolean = true,\n) = this then TransformableElement(state, canPan, lockRotationOnZoomPan, enabled)\n\nprivate class TransformableElement(\n    private val state: TransformableState,\n    private val canPan: (Offset) -> Boolean,\n    private val lockRotationOnZoomPan: Boolean,\n    private val enabled: Boolean,\n) : ModifierNodeElement<TransformableNode>() {\n    override fun create(): TransformableNode =\n        TransformableNode(state, canPan, lockRotationOnZoomPan, enabled)\n\n    override fun update(node: TransformableNode) {\n        node.update(state, canPan, lockRotationOnZoomPan, enabled)\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other === null) return false\n        if (this::class != other::class) return false\n\n        other as TransformableElement\n\n        if (state != other.state) return false\n        if (canPan !== other.canPan) return false\n        if (lockRotationOnZoomPan != other.lockRotationOnZoomPan) return false\n        if (enabled != other.enabled) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = state.hashCode()\n        result = 31 * result + canPan.hashCode()\n        result = 31 * result + lockRotationOnZoomPan.hashCode()\n        result = 31 * result + enabled.hashCode()\n        return result\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"transformable\"\n        properties[\"state\"] = state\n        properties[\"canPan\"] = canPan\n        properties[\"enabled\"] = enabled\n        properties[\"lockRotationOnZoomPan\"] = lockRotationOnZoomPan\n    }\n}\n\nprivate class TransformableNode(\n    private var state: TransformableState,\n    private var canPan: (Offset) -> Boolean,\n    private var lockRotationOnZoomPan: Boolean,\n    private var enabled: Boolean,\n) : DelegatingNode(), PointerInputModifierNode, CompositionLocalConsumerModifierNode {\n\n    private val updatedCanPan: (Offset) -> Boolean = { canPan.invoke(it) }\n    private val channel = Channel<TransformEvent>(capacity = Channel.UNLIMITED)\n\n    private var scrollConfig: ScrollConfig? = null\n\n    override fun onAttach() {\n        super.onAttach()\n        scrollConfig = platformScrollConfig()\n    }\n\n    private val pointerInputNode =\n        delegate(\n            SuspendingPointerInputModifierNode {\n                if (!enabled) return@SuspendingPointerInputModifierNode\n                coroutineScope {\n                    launch(start = CoroutineStart.UNDISPATCHED) {\n                        while (isActive) {\n                            var event = channel.receive()\n                            if (event !is TransformStarted) continue\n                            try {\n                                state.transform(MutatePriority.UserInput) {\n                                    while (event !is TransformStopped) {\n                                        (event as? TransformDelta)?.let {\n                                            transformByWithCentroid(\n                                                centroid = it.centroid,\n                                                zoomChange = it.zoomChange,\n                                                panChange = it.panChange,\n                                                rotationChange = it.rotationChange,\n                                            )\n                                        }\n                                        event = channel.receive()\n                                    }\n                                }\n                            } catch (_: CancellationException) {\n                                // ignore the cancellation and start over again.\n                            }\n                        }\n                    }\n\n                    awaitEachGesture {\n                        try {\n                            detectZoom(lockRotationOnZoomPan, channel, updatedCanPan)\n                        } catch (exception: CancellationException) {\n                            if (!isActive) throw exception\n                        } finally {\n                            channel.trySend(TransformStopped)\n                        }\n                    }\n                }\n            }\n        )\n\n    private var pointerInputModifierMouse: PointerInputModifierNode? = null\n\n    fun update(\n        state: TransformableState,\n        canPan: (Offset) -> Boolean,\n        lockRotationOnZoomPan: Boolean,\n        enabled: Boolean,\n    ) {\n        this.canPan = canPan\n        val needsReset =\n            this.state != state ||\n                this.enabled != enabled ||\n                this.lockRotationOnZoomPan != lockRotationOnZoomPan\n        if (needsReset) {\n            this.state = state\n            this.enabled = enabled\n            this.lockRotationOnZoomPan = lockRotationOnZoomPan\n            pointerInputNode.resetPointerInputHandler()\n        }\n    }\n\n    override fun onPointerEvent(\n        pointerEvent: PointerEvent,\n        pass: PointerEventPass,\n        bounds: IntSize,\n    ) {\n        val scrollConfig = scrollConfig\n        if (\n            enabled &&\n                pointerEvent.changes.fastAny { it.type == PointerType.Mouse } &&\n                scrollConfig != null &&\n                pointerInputModifierMouse == null\n        ) {\n            pointerInputModifierMouse =\n                delegate(\n                    SuspendingPointerInputModifierNode {\n                        detectNonTouchGestures(channel, scrollConfig)\n                    }\n                )\n        }\n        pointerInputNode.onPointerEvent(pointerEvent, pass, bounds)\n        pointerInputModifierMouse?.onPointerEvent(pointerEvent, pass, bounds)\n    }\n\n    override fun onCancelPointerInput() {\n        pointerInputNode.onCancelPointerInput()\n        pointerInputModifierMouse?.onCancelPointerInput()\n    }\n}\n\n// The factor used to covert the mouse scroll to zoom.\n// Every 545 pixels of scroll is converted into 2 times zoom. This value is calculated from\n// curve fitting the ChromeOS's zoom factors.\ninternal const val SCROLL_FACTOR = 545f\n\n/**\n * Convert non touch events into the appropriate transform events. There are 3 cases, where order of\n * determination matters:\n * - If Ctrl is pressed, and we get a scroll, either from a mouse wheel or a trackpad pan, we\n *   convert that scroll into an equivalent zoom\n * - If we get a trackpad pan, we convert that into a pan\n * - If we get a trackpad scale, we convert that into a zoom\n */\nprivate suspend fun PointerInputScope.detectNonTouchGestures(\n    channel: Channel<TransformEvent>,\n    scrollConfig: ScrollConfig,\n) {\n    val currentContext = currentCoroutineContext()\n    awaitPointerEventScope {\n        while (currentContext.isActive) {\n            try {\n                var zoomOffset: Offset?\n                var panOffset: Offset?\n                var scale: Float?\n                var pointer: PointerEvent\n                do {\n                    pointer = awaitPointerEvent()\n\n                    // Convert non touch events into the appropriate transform events.\n                    // There are 3 cases, where order of determination matters:\n                    // - If Ctrl is pressed, and we get a scroll, either from a mouse wheel or a\n                    //   trackpad pan, we convert that scroll into an equivalent zoom\n                    // - If we get a trackpad pan, we convert that into a pan\n                    // - If we get a trackpad scale, we convert that into a zoom\n                    zoomOffset = consumePointerEventAsCtrlScrollOrNull(pointer, scrollConfig)\n                    panOffset = consumePointerEventAsPanOrNull(pointer)\n                    scale = consumePointerEventAsScaleOrNull(pointer)\n                } while (zoomOffset == null && panOffset == null && scale == null)\n                if (zoomOffset != null) {\n                    var scrollDelta: Offset = zoomOffset\n                    channel.trySend(TransformStarted)\n                    while (true) {\n                        // This formula is curve fitting form Chrome OS's ctrl + scroll\n                        // implementation.\n                        val zoomChange = 2f.pow(scrollDelta.y / SCROLL_FACTOR)\n                        channel.trySend(\n                            TransformDelta(\n                                centroid = pointer.calculateCentroid { true },\n                                zoomChange = zoomChange,\n                                panChange = Offset.Zero,\n                                rotationChange = 0f,\n                            )\n                        )\n                        pointer = awaitPointerEvent()\n                        scrollDelta =\n                            consumePointerEventAsCtrlScrollOrNull(pointer, scrollConfig) ?: break\n                    }\n                } else if (panOffset != null) {\n                    var panDelta: Offset = panOffset\n                    channel.trySend(TransformStarted)\n                    while (true) {\n                        channel.trySend(\n                            TransformDelta(\n                                centroid = pointer.calculateCentroid { true },\n                                zoomChange = 1f,\n                                panChange = panDelta,\n                                rotationChange = 0f,\n                            )\n                        )\n                        pointer = awaitPointerEvent()\n                        panDelta = consumePointerEventAsPanOrNull(pointer) ?: break\n                    }\n                } else {\n                    var scaleDelta: Float =\n                        checkNotNull(scale) {\n                            \"One of zoomOffset, panOffset and scaleDelta must be non-null\"\n                        }\n                    channel.trySend(TransformStarted)\n                    while (true) {\n                        channel.trySend(\n                            TransformDelta(\n                                centroid = pointer.calculateCentroid { true },\n                                zoomChange = scaleDelta,\n                                panChange = Offset.Zero,\n                                rotationChange = 0f,\n                            )\n                        )\n                        pointer = awaitPointerEvent()\n                        scaleDelta = consumePointerEventAsScaleOrNull(pointer) ?: break\n                    }\n                }\n            } finally {\n                channel.trySend(TransformStopped)\n            }\n        }\n    }\n}\n\n/**\n * If the PointerEvent is a mouse scroll event that has non zero scrollDelta and the ctrl key is\n * pressed, its scrollDelta is returned. Otherwise, null is returned. The event is consumed when it\n * detects ctrl + mouse scroll.\n */\nprivate fun AwaitPointerEventScope.consumePointerEventAsCtrlScrollOrNull(\n    pointer: PointerEvent,\n    scrollConfig: ScrollConfig,\n): Offset? {\n    if (\n        !pointer.keyboardModifiers.isCtrlPressed ||\n            (pointer.type != PointerEventType.Scroll &&\n                pointer.type != PointerEventType.PanStart &&\n                pointer.type != PointerEventType.PanMove &&\n                pointer.type != PointerEventType.PanEnd)\n    ) {\n        return null\n    }\n    @OptIn(ExperimentalFoundationApi::class)\n    val scrollDelta =\n        with(scrollConfig) { calculateMouseWheelScroll(pointer, size) } +\n            if (ComposeFoundationFlags.isTrackpadGestureHandlingEnabled) {\n                (pointer.changes.firstOrNull()?.let {\n                    -it.panOffset +\n                        it.historical.fastFold(Offset.Zero) { acc, historicalChange ->\n                            acc - historicalChange.panOffset\n                        }\n                } ?: Offset.Zero)\n            } else {\n                Offset.Zero\n            }\n\n    if (scrollDelta == Offset.Zero) {\n        return null\n    }\n\n    pointer.changes.fastForEach { it.consume() }\n    return scrollDelta\n}\n\nprivate fun AwaitPointerEventScope.consumePointerEventAsPanOrNull(pointer: PointerEvent): Offset? {\n    @OptIn(ExperimentalFoundationApi::class)\n    if (\n        !ComposeFoundationFlags.isTrackpadGestureHandlingEnabled ||\n            (pointer.type != PointerEventType.PanStart &&\n                pointer.type != PointerEventType.PanMove &&\n                pointer.type != PointerEventType.PanEnd)\n    ) {\n        return null\n    }\n    val scrollDelta =\n        pointer.changes.firstOrNull()?.let {\n            -it.panOffset +\n                it.historical.fastFold(Offset.Zero) { acc, historicalChange ->\n                    acc - historicalChange.panOffset\n                }\n        } ?: Offset.Zero\n\n    if (scrollDelta == Offset.Zero) {\n        return null\n    }\n\n    pointer.changes.fastForEach { it.consume() }\n    return scrollDelta\n}\n\nprivate fun AwaitPointerEventScope.consumePointerEventAsScaleOrNull(pointer: PointerEvent): Float? {\n    @OptIn(ExperimentalFoundationApi::class)\n    if (\n        !ComposeFoundationFlags.isTrackpadGestureHandlingEnabled ||\n            (pointer.type != PointerEventType.ScaleStart &&\n                pointer.type != PointerEventType.ScaleChange &&\n                pointer.type != PointerEventType.ScaleEnd)\n    ) {\n        return null\n    }\n    var scaleDelta = 1f\n    pointer.changes.fastForEach {\n        scaleDelta *= it.scaleFactor\n        it.historical.fastForEach { scaleDelta *= it.scaleFactor }\n    }\n\n    if (scaleDelta == 1f) {\n        return null\n    }\n\n    pointer.changes.fastForEach { it.consume() }\n    return scaleDelta\n}\n\nprivate suspend fun AwaitPointerEventScope.detectZoom(\n    panZoomLock: Boolean,\n    channel: Channel<TransformEvent>,\n    canPan: (Offset) -> Boolean,\n) {\n    var rotation = 0f\n    var zoom = 1f\n    var pan = Offset.Zero\n    var pastTouchSlop = false\n    val touchSlop = viewConfiguration.touchSlop\n    var lockedToPanZoom = false\n    awaitFirstDown(requireUnconsumed = false)\n    do {\n        val event = awaitPointerEvent()\n        @OptIn(ExperimentalFoundationApi::class)\n        val canceled =\n            event.changes.fastAny { it.isConsumed } ||\n                (ComposeFoundationFlags.isTrackpadGestureHandlingEnabled &&\n                    (event.type == PointerEventType.PanStart ||\n                        event.type == PointerEventType.PanMove ||\n                        event.type == PointerEventType.PanEnd ||\n                        event.type == PointerEventType.ScaleStart ||\n                        event.type == PointerEventType.ScaleChange ||\n                        event.type == PointerEventType.ScaleEnd))\n        if (!canceled) {\n            val zoomChange = event.calculateZoom()\n            val rotationChange = event.calculateRotation()\n            val panChange = event.calculatePan()\n\n            if (!pastTouchSlop) {\n                zoom *= zoomChange\n                rotation += rotationChange\n                pan += panChange\n\n                val centroidSize = event.calculateCentroidSize(useCurrent = false)\n                val zoomMotion = abs(1 - zoom) * centroidSize\n                val rotationMotion = abs(rotation * PI.toFloat() * centroidSize / 180f)\n                val panMotion = pan.getDistance()\n\n                if (\n                    zoomMotion > touchSlop ||\n                        rotationMotion > touchSlop ||\n                        (panMotion > touchSlop && canPan.invoke(panChange))\n                ) {\n                    pastTouchSlop = true\n                    lockedToPanZoom = panZoomLock && rotationMotion < touchSlop\n                    channel.trySend(TransformStarted)\n                }\n            }\n\n            if (pastTouchSlop) {\n                val centroid = event.calculateCentroid(useCurrent = false)\n                val effectiveRotation = if (lockedToPanZoom) 0f else rotationChange\n                if (\n                    effectiveRotation != 0f ||\n                        zoomChange != 1f ||\n                        (panChange != Offset.Zero && canPan.invoke(panChange))\n                ) {\n                    channel.trySend(\n                        TransformDelta(centroid, zoomChange, panChange, effectiveRotation)\n                    )\n                }\n                event.changes.fastForEach {\n                    if (it.positionChanged()) {\n                        it.consume()\n                    }\n                }\n            }\n        } else {\n            channel.trySend(TransformStopped)\n        }\n        val finalEvent = awaitPointerEvent(pass = PointerEventPass.Final)\n        // someone consumed while we were waiting for touch slop\n        val finallyCanceled = finalEvent.changes.fastAny { it.isConsumed } && !pastTouchSlop\n    } while (!canceled && !finallyCanceled && event.changes.fastAny { it.pressed })\n}\n\nprivate sealed class TransformEvent {\n    object TransformStarted : TransformEvent()\n\n    object TransformStopped : TransformEvent()\n\n    class TransformDelta(\n        val centroid: Offset,\n        val zoomChange: Float,\n        val panChange: Offset,\n        val rotationChange: Float,\n    ) : TransformEvent()\n}\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Background.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation\n\nimport androidx.annotation.FloatRange\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.drawOutline\nimport androidx.compose.ui.graphics.drawscope.ContentDrawScope\nimport androidx.compose.ui.node.DrawModifierNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.node.ObserverModifierNode\nimport androidx.compose.ui.node.SemanticsModifierNode\nimport androidx.compose.ui.node.invalidateDraw\nimport androidx.compose.ui.node.invalidateSemantics\nimport androidx.compose.ui.node.observeReads\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.platform.debugInspectorInfo\nimport androidx.compose.ui.semantics.SemanticsPropertyReceiver\nimport androidx.compose.ui.semantics.shape\nimport androidx.compose.ui.unit.LayoutDirection\n\n/**\n * Draws [shape] with a solid [color] behind the content.\n *\n * @sample androidx.compose.foundation.samples.DrawBackgroundColor\n * @param color color to paint background with\n * @param shape desired shape of the background\n */\n@Stable\nfun Modifier.background(color: Color, shape: Shape = RectangleShape): Modifier {\n    val alpha = 1.0f // for solid colors\n    return this.then(\n        BackgroundElement(\n            color = color,\n            shape = shape,\n            alpha = alpha,\n            inspectorInfo =\n                debugInspectorInfo {\n                    name = \"background\"\n                    value = color\n                    properties[\"color\"] = color\n                    properties[\"shape\"] = shape\n                },\n        )\n    )\n}\n\n/**\n * Draws [shape] with [brush] behind the content.\n *\n * @sample androidx.compose.foundation.samples.DrawBackgroundShapedBrush\n * @param brush brush to paint background with\n * @param shape desired shape of the background\n * @param alpha Opacity to be applied to the [brush], with `0` being completely transparent and `1`\n *   being completely opaque. The value must be between `0` and `1`.\n */\n@Stable\nfun Modifier.background(\n    brush: Brush,\n    shape: Shape = RectangleShape,\n    @FloatRange(from = 0.0, to = 1.0) alpha: Float = 1.0f,\n) =\n    this.then(\n        BackgroundElement(\n            brush = brush,\n            alpha = alpha,\n            shape = shape,\n            inspectorInfo =\n                debugInspectorInfo {\n                    name = \"background\"\n                    properties[\"alpha\"] = alpha\n                    properties[\"brush\"] = brush\n                    properties[\"shape\"] = shape\n                },\n        )\n    )\n\nprivate class BackgroundElement(\n    private val color: Color = Color.Unspecified,\n    private val brush: Brush? = null,\n    private val alpha: Float,\n    private val shape: Shape,\n    private val inspectorInfo: InspectorInfo.() -> Unit,\n) : ModifierNodeElement<BackgroundNode>() {\n    override fun create(): BackgroundNode {\n        return BackgroundNode(color, brush, alpha, shape)\n    }\n\n    override fun update(node: BackgroundNode) {\n        node.color = color\n        node.brush = brush\n        node.alpha = alpha\n        if (node.shape != shape) {\n            node.shape = shape\n            node.invalidateSemantics()\n        }\n        node.invalidateDraw()\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        inspectorInfo()\n    }\n\n    override fun hashCode(): Int {\n        var result = color.hashCode()\n        result = 31 * result + (brush?.hashCode() ?: 0)\n        result = 31 * result + alpha.hashCode()\n        result = 31 * result + shape.hashCode()\n        return result\n    }\n\n    override fun equals(other: Any?): Boolean {\n        val otherModifier = other as? BackgroundElement ?: return false\n        return color == otherModifier.color &&\n            brush == otherModifier.brush &&\n            alpha == otherModifier.alpha &&\n            shape == otherModifier.shape\n    }\n}\n\nprivate class BackgroundNode(\n    var color: Color,\n    var brush: Brush?,\n    var alpha: Float,\n    var shape: Shape,\n) : DrawModifierNode, Modifier.Node(), ObserverModifierNode, SemanticsModifierNode {\n\n    override val shouldAutoInvalidate = false\n    override val isImportantForBounds = false\n\n    // Naively cache outline calculation if input parameters are the same, we manually observe\n    // reads inside shape#createOutline separately\n    private var lastSize: Size = Size.Unspecified\n    private var lastLayoutDirection: LayoutDirection? = null\n    private var lastOutline: Outline? = null\n    private var lastShape: Shape? = null\n    private var tmpOutline: Outline? = null\n\n    override fun ContentDrawScope.draw() {\n        if (shape === RectangleShape) {\n            // shortcut to avoid Outline calculation and allocation\n            drawRect()\n        } else {\n            drawOutline()\n        }\n        drawContent()\n    }\n\n    override fun onObservedReadsChanged() {\n        // Reset cached properties\n        lastSize = Size.Unspecified\n        lastLayoutDirection = null\n        lastOutline = null\n        lastShape = null\n        // Invalidate draw so we build the cache again - this is needed because observeReads within\n        // the draw scope obscures the state reads from the draw scope's observer\n        invalidateDraw()\n    }\n\n    private fun ContentDrawScope.drawRect() {\n        if (color != Color.Unspecified) drawRect(color = color)\n        brush?.let { drawRect(brush = it, alpha = alpha) }\n    }\n\n    private fun ContentDrawScope.drawOutline() {\n        val outline = getOutline()\n        if (color != Color.Unspecified) drawOutline(outline, color = color)\n        brush?.let { drawOutline(outline, brush = it, alpha = alpha) }\n    }\n\n    private fun ContentDrawScope.getOutline(): Outline {\n        val outline: Outline?\n        if (size == lastSize && layoutDirection == lastLayoutDirection && lastShape == shape) {\n            outline = lastOutline!!\n        } else {\n            // Manually observe reads so we can directly invalidate the outline when it changes\n            // Use tmpOutline to avoid creating an object reference to local var outline\n            observeReads { tmpOutline = shape.createOutline(size, layoutDirection, this) }\n            outline = tmpOutline\n            tmpOutline = null\n        }\n        lastOutline = outline\n        lastSize = size\n        lastLayoutDirection = layoutDirection\n        lastShape = shape\n        return outline!!\n    }\n\n    override fun SemanticsPropertyReceiver.applySemantics() {\n        this.shape = this@BackgroundNode.shape\n    }\n}\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/Border.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation\n\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.CacheDrawModifierNode\nimport androidx.compose.ui.draw.CacheDrawScope\nimport androidx.compose.ui.draw.DrawResult\nimport androidx.compose.ui.geometry.CornerRadius\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.RoundRect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.geometry.isSimple\nimport androidx.compose.ui.graphics.BlendMode\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.ClipOp\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.ImageBitmap\nimport androidx.compose.ui.graphics.ImageBitmapConfig\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathOperation\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.drawscope.CanvasDrawScope\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.Fill\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.drawscope.clipRect\nimport androidx.compose.ui.graphics.drawscope.scale\nimport androidx.compose.ui.graphics.drawscope.translate\nimport androidx.compose.ui.node.DelegatingNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.node.SemanticsModifierNode\nimport androidx.compose.ui.node.invalidateSemantics\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.semantics.SemanticsPropertyReceiver\nimport androidx.compose.ui.semantics.shape\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.toSize\nimport kotlin.math.ceil\nimport kotlin.math.max\nimport kotlin.math.min\n\n/**\n * Modify element to add border with appearance specified with a [border] and a [shape] and clip it.\n *\n * @sample androidx.compose.foundation.samples.BorderSample\n * @param border [BorderStroke] class that specifies border appearance, such as size and color\n * @param shape shape of the border\n */\n@Stable\nfun Modifier.border(border: BorderStroke, shape: Shape = RectangleShape) =\n    border(width = border.width, brush = border.brush, shape = shape)\n\n/**\n * Modify element to add border with appearance specified with a [width], a [color] and a [shape]\n * and clip it.\n *\n * @sample androidx.compose.foundation.samples.BorderSampleWithDataClass\n * @param width width of the border. Use [Dp.Hairline] for a hairline border.\n * @param color color to paint the border with\n * @param shape shape of the border\n */\n@Stable\nfun Modifier.border(width: Dp, color: Color, shape: Shape = RectangleShape) =\n    border(width, SolidColor(color), shape)\n\n/**\n * Modify element to add border with appearance specified with a [width], a [brush] and a [shape]\n * and clip it.\n *\n * @sample androidx.compose.foundation.samples.BorderSampleWithBrush\n * @sample androidx.compose.foundation.samples.BorderSampleWithDynamicData\n * @param width width of the border. Use [Dp.Hairline] for a hairline border.\n * @param brush brush to paint the border with\n * @param shape shape of the border\n */\n@Stable\nfun Modifier.border(width: Dp, brush: Brush, shape: Shape) =\n    this then BorderModifierNodeElement(width, brush, shape)\n\ninternal data class BorderModifierNodeElement(val width: Dp, val brush: Brush, val shape: Shape) :\n    ModifierNodeElement<BorderModifierNode>() {\n    override fun create() = BorderModifierNode(width, brush, shape)\n\n    override fun update(node: BorderModifierNode) {\n        node.width = width\n        node.brush = brush\n        node.shape = shape\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"border\"\n        properties[\"width\"] = width\n        if (brush is SolidColor) {\n            properties[\"color\"] = brush.value\n            value = brush.value\n        } else {\n            properties[\"brush\"] = brush\n        }\n        properties[\"shape\"] = shape\n    }\n}\n\ninternal class BorderModifierNode(\n    widthParameter: Dp,\n    brushParameter: Brush,\n    shapeParameter: Shape,\n) : DelegatingNode(), SemanticsModifierNode {\n\n    override val shouldAutoInvalidate: Boolean = false\n    override val isImportantForBounds = false\n\n    // BorderCache object that is lazily allocated depending on the type of shape\n    // This object is only used for generic shapes and rounded rectangles with different corner\n    // radius sizes.\n    // Note: Extension functions that use BorderCache are part of this class.\n    private var borderCache: BorderCache? = null\n\n    var width = widthParameter\n        set(value) {\n            if (field != value) {\n                field = value\n                drawWithCacheModifierNode.invalidateDrawCache()\n            }\n        }\n\n    var brush = brushParameter\n        set(value) {\n            if (field != value) {\n                field = value\n                drawWithCacheModifierNode.invalidateDrawCache()\n            }\n        }\n\n    var shape = shapeParameter\n        set(value) {\n            if (field != value) {\n                field = value\n                drawWithCacheModifierNode.invalidateDrawCache()\n                invalidateSemantics()\n            }\n        }\n\n    private val drawWithCacheModifierNode =\n        delegate(\n            CacheDrawModifierNode {\n                val hasValidBorderParams = width.toPx() >= 0f && size.minDimension > 0f\n                if (!hasValidBorderParams) {\n                    drawContentWithoutBorder()\n                } else {\n                    val strokeWidthPx =\n                        min(\n                            if (width == Dp.Hairline) 1f else ceil(width.toPx()),\n                            ceil(size.minDimension / 2),\n                        )\n                    val halfStroke = strokeWidthPx / 2\n                    val topLeft = Offset(halfStroke, halfStroke)\n                    val borderSize = Size(size.width - strokeWidthPx, size.height - strokeWidthPx)\n                    // The stroke is larger than the drawing area so just draw a full shape instead\n                    val fillArea = (strokeWidthPx * 2) > size.minDimension\n                    when (val outline = shape.createOutline(size, layoutDirection, this)) {\n                        is Outline.Generic ->\n                            drawGenericBorder(brush, outline, fillArea, strokeWidthPx)\n                        is Outline.Rounded ->\n                            drawRoundRectBorder(\n                                brush,\n                                outline,\n                                topLeft,\n                                borderSize,\n                                fillArea,\n                                strokeWidthPx,\n                            )\n                        is Outline.Rectangle ->\n                            drawRectBorder(brush, topLeft, borderSize, fillArea, strokeWidthPx)\n                    }\n                }\n            }\n        )\n\n    /**\n     * Border implementation for generic paths. Note it is possible to be given paths that do not\n     * make sense in the context of a border (ex. a figure 8 path or a non-enclosed shape) We do not\n     * handle that here as we expect developers to give us enclosed, non-overlapping paths.\n     */\n    private fun CacheDrawScope.drawGenericBorder(\n        brush: Brush,\n        outline: Outline.Generic,\n        fillArea: Boolean,\n        strokeWidth: Float,\n    ): DrawResult =\n        if (fillArea) {\n            onDrawWithContent {\n                drawContent()\n                drawPath(outline.path, brush = brush)\n            }\n        } else {\n            // Optimization, if we are only drawing a solid color border, we only need an alpha8\n            // mask as we can draw the mask with a tint.\n            // Otherwise we need to allocate a full ImageBitmap and draw it normally\n            val config: ImageBitmapConfig\n            val colorFilter: ColorFilter?\n            if (brush is SolidColor) {\n                config = ImageBitmapConfig.Alpha8\n                // The brush is drawn into the mask with the corresponding color including the\n                // alpha channel so when we tint we should not apply the alpha as it would end up\n                // modulating it twice\n                colorFilter = ColorFilter.tint(brush.value.copy(alpha = 1f))\n            } else {\n                config = ImageBitmapConfig.Argb8888\n                colorFilter = null\n            }\n\n            val pathBounds = outline.path.getBounds()\n            // Create a mask path that includes a rectangle with the original path cut out of it.\n            // Note: borderCache is part of the class that defines this extension function.\n            if (borderCache == null) {\n                borderCache = BorderCache()\n            }\n            val maskPath =\n                borderCache!!.obtainPath().apply {\n                    reset()\n                    addRect(pathBounds)\n                    op(this, outline.path, PathOperation.Difference)\n                }\n\n            val cacheImageBitmap: ImageBitmap\n            val pathBoundsSize =\n                IntSize(ceil(pathBounds.width).toInt(), ceil(pathBounds.height).toInt())\n            with(borderCache!!) {\n                // Draw into offscreen bitmap with the size of the path\n                // We need to draw into this intermediate bitmap to act as a layer\n                // and make sure that the clearing logic does not generate underdraw\n                // into the target we are rendering into\n                cacheImageBitmap =\n                    drawBorderCache(pathBoundsSize, config) {\n                        // Paths can have offsets, so translate to keep the drawn path\n                        // within the bounds of the mask bitmap\n                        translate(-pathBounds.left, -pathBounds.top) {\n                            // Draw the path with a stroke width twice the provided value.\n                            // Because strokes are centered, this will draw both and inner and\n                            // outer stroke with the desired stroke width\n                            drawPath(\n                                path = outline.path,\n                                brush = brush,\n                                style = Stroke(strokeWidth * 2),\n                            )\n\n                            // Scale the canvas slightly to cover the background that may be visible\n                            // after clearing the outer stroke\n                            scale((size.width + 1) / size.width, (size.height + 1) / size.height) {\n                                // Remove the outer stroke by clearing the inverted mask path\n                                drawPath(\n                                    path = maskPath,\n                                    brush = brush,\n                                    blendMode = BlendMode.Clear,\n                                )\n                            }\n                        }\n                    }\n            }\n\n            onDrawWithContent {\n                drawContent()\n                translate(pathBounds.left, pathBounds.top) {\n                    drawImage(cacheImageBitmap, srcSize = pathBoundsSize, colorFilter = colorFilter)\n                }\n            }\n        }\n\n    /** Border implementation for simple rounded rects and those with different corner radii */\n    private fun CacheDrawScope.drawRoundRectBorder(\n        brush: Brush,\n        outline: Outline.Rounded,\n        topLeft: Offset,\n        borderSize: Size,\n        fillArea: Boolean,\n        strokeWidth: Float,\n    ): DrawResult {\n        return if (outline.roundRect.isSimple) {\n            val cornerRadius = outline.roundRect.topLeftCornerRadius\n            val halfStroke = strokeWidth / 2\n            val borderStroke = Stroke(strokeWidth)\n            onDrawWithContent {\n                drawContent()\n                when {\n                    fillArea -> {\n                        // If the drawing area is smaller than the stroke being drawn\n                        // drawn all around it just draw a filled in rounded rect\n                        drawRoundRect(brush, cornerRadius = cornerRadius)\n                    }\n                    cornerRadius.x < halfStroke -> {\n                        // If the corner radius is smaller than half of the stroke width\n                        // then the interior curvature of the stroke will be a sharp edge\n                        // In this case just draw a normal filled in rounded rect with the\n                        // desired corner radius but clipping out the interior rectangle\n                        clipRect(\n                            strokeWidth,\n                            strokeWidth,\n                            size.width - strokeWidth,\n                            size.height - strokeWidth,\n                            clipOp = ClipOp.Difference,\n                        ) {\n                            drawRoundRect(brush, cornerRadius = cornerRadius)\n                        }\n                    }\n                    else -> {\n                        // Otherwise draw a stroked rounded rect with the corner radius\n                        // shrunk by half of the stroke width. This will ensure that the\n                        // outer curvature of the rounded rectangle will have the desired\n                        // corner radius.\n                        drawRoundRect(\n                            brush = brush,\n                            topLeft = topLeft,\n                            size = borderSize,\n                            cornerRadius = cornerRadius.shrink(halfStroke),\n                            style = borderStroke,\n                        )\n                    }\n                }\n            }\n        } else {\n            // Note: borderCache is part of the class that defines this extension function.\n            if (borderCache == null) {\n                borderCache = BorderCache()\n            }\n            val path = borderCache!!.obtainPath()\n            val roundedRectPath =\n                createRoundRectPath(path, outline.roundRect, strokeWidth, fillArea)\n            onDrawWithContent {\n                drawContent()\n                drawPath(roundedRectPath, brush = brush)\n            }\n        }\n    }\n\n    override fun SemanticsPropertyReceiver.applySemantics() {\n        shape = this@BorderModifierNode.shape\n    }\n}\n\n/**\n * Helper object that handles lazily allocating and re-using objects to render the border into an\n * offscreen ImageBitmap\n */\nprivate data class BorderCache(\n    private var imageBitmap: ImageBitmap? = null,\n    private var canvas: androidx.compose.ui.graphics.Canvas? = null,\n    private var canvasDrawScope: CanvasDrawScope? = null,\n    private var borderPath: Path? = null,\n) {\n    inline fun CacheDrawScope.drawBorderCache(\n        borderSize: IntSize,\n        config: ImageBitmapConfig,\n        block: DrawScope.() -> Unit,\n    ): ImageBitmap {\n\n        var targetImageBitmap = imageBitmap\n        var targetCanvas = canvas\n        // If we previously had allocated a full Argb888 ImageBitmap but are only requiring\n        // an alpha mask, just re-use the same ImageBitmap instead of allocating a new one\n        val compatibleConfig =\n            targetImageBitmap?.config == ImageBitmapConfig.Argb8888 ||\n                config == targetImageBitmap?.config\n        if (\n            targetImageBitmap == null ||\n                targetCanvas == null ||\n                size.width > targetImageBitmap.width ||\n                size.height > targetImageBitmap.height ||\n                !compatibleConfig\n        ) {\n            targetImageBitmap =\n                ImageBitmap(borderSize.width, borderSize.height, config = config).also {\n                    imageBitmap = it\n                }\n            targetCanvas =\n                androidx.compose.ui.graphics.Canvas(targetImageBitmap).also { canvas = it }\n        }\n\n        val targetDrawScope = canvasDrawScope ?: CanvasDrawScope().also { canvasDrawScope = it }\n        val drawSize = borderSize.toSize()\n        targetDrawScope.draw(this, layoutDirection, targetCanvas, drawSize) {\n            // Clear the previously rendered portion within this ImageBitmap as we could\n            // be re-using it\n            drawRect(color = Color.Black, size = drawSize, blendMode = BlendMode.Clear)\n            block()\n        }\n        targetImageBitmap.prepareToDraw()\n        return targetImageBitmap\n    }\n\n    fun obtainPath(): Path = borderPath ?: Path().also { borderPath = it }\n}\n\n/**\n * Border implementation for invalid parameters that just draws the content as the given border\n * parameters are infeasible (ex. negative border width)\n */\nprivate fun CacheDrawScope.drawContentWithoutBorder(): DrawResult = onDrawWithContent {\n    drawContent()\n}\n\n/** Border implementation for rectangular borders */\nprivate fun CacheDrawScope.drawRectBorder(\n    brush: Brush,\n    topLeft: Offset,\n    borderSize: Size,\n    fillArea: Boolean,\n    strokeWidthPx: Float,\n): DrawResult {\n    // If we are drawing a rectangular stroke, just offset it by half the stroke\n    // width as strokes are always drawn centered on their geometry.\n    // If the border is larger than the drawing area, just fill the area with a\n    // solid rectangle\n    val rectTopLeft = if (fillArea) Offset.Zero else topLeft\n    val size = if (fillArea) size else borderSize\n    val style = if (fillArea) Fill else Stroke(strokeWidthPx)\n    return onDrawWithContent {\n        drawContent()\n        drawRect(brush = brush, topLeft = rectTopLeft, size = size, style = style)\n    }\n}\n\n/**\n * Helper method that creates a round rect with the inner region removed by the given stroke width\n */\nprivate fun createRoundRectPath(\n    targetPath: Path,\n    roundedRect: RoundRect,\n    strokeWidth: Float,\n    fillArea: Boolean,\n): Path =\n    targetPath.apply {\n        reset()\n        addRoundRect(roundedRect)\n        if (!fillArea) {\n            val insetPath =\n                Path().apply { addRoundRect(createInsetRoundedRect(strokeWidth, roundedRect)) }\n            op(this, insetPath, PathOperation.Difference)\n        }\n    }\n\nprivate fun createInsetRoundedRect(widthPx: Float, roundedRect: RoundRect) =\n    RoundRect(\n        left = widthPx,\n        top = widthPx,\n        right = roundedRect.width - widthPx,\n        bottom = roundedRect.height - widthPx,\n        topLeftCornerRadius = roundedRect.topLeftCornerRadius.shrink(widthPx),\n        topRightCornerRadius = roundedRect.topRightCornerRadius.shrink(widthPx),\n        bottomLeftCornerRadius = roundedRect.bottomLeftCornerRadius.shrink(widthPx),\n        bottomRightCornerRadius = roundedRect.bottomRightCornerRadius.shrink(widthPx),\n    )\n\n/**\n * Helper method to shrink the corner radius by the given value, clamping to 0 if the resultant\n * corner radius would be negative\n */\nprivate fun CornerRadius.shrink(value: Float): CornerRadius =\n    CornerRadius(max(0f, this.x - value), max(0f, this.y - value))\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/shape/RoundedCornerShape.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.shape\n\nimport androidx.annotation.IntRange\nimport androidx.compose.ui.geometry.CornerRadius\nimport androidx.compose.ui.geometry.RoundRect\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.geometry.toRect\nimport androidx.compose.ui.graphics.Outline\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.LayoutDirection.Ltr\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.lerp\n\n/**\n * A shape describing the rectangle with rounded corners.\n *\n * This shape will automatically mirror the corner sizes in [LayoutDirection.Rtl], use\n * [AbsoluteRoundedCornerShape] for the layout direction unaware version of this shape.\n *\n * @param topStart a size of the top start corner\n * @param topEnd a size of the top end corner\n * @param bottomEnd a size of the bottom end corner\n * @param bottomStart a size of the bottom start corner\n */\nclass RoundedCornerShape(\n    topStart: CornerSize,\n    topEnd: CornerSize,\n    bottomEnd: CornerSize,\n    bottomStart: CornerSize,\n) :\n    CornerBasedShape(\n        topStart = topStart,\n        topEnd = topEnd,\n        bottomEnd = bottomEnd,\n        bottomStart = bottomStart,\n    ) {\n\n    override fun createOutline(\n        size: Size,\n        topStart: Float,\n        topEnd: Float,\n        bottomEnd: Float,\n        bottomStart: Float,\n        layoutDirection: LayoutDirection,\n    ): Outline {\n        return if (topStart + topEnd + bottomEnd + bottomStart == 0.0f) {\n            Outline.Rectangle(size.toRect())\n        } else {\n            Outline.Rounded(\n                RoundRect(\n                    rect = size.toRect(),\n                    topLeft = CornerRadius(if (layoutDirection == Ltr) topStart else topEnd),\n                    topRight = CornerRadius(if (layoutDirection == Ltr) topEnd else topStart),\n                    bottomRight =\n                        CornerRadius(if (layoutDirection == Ltr) bottomEnd else bottomStart),\n                    bottomLeft =\n                        CornerRadius(if (layoutDirection == Ltr) bottomStart else bottomEnd),\n                )\n            )\n        }\n    }\n\n    override fun copy(\n        topStart: CornerSize,\n        topEnd: CornerSize,\n        bottomEnd: CornerSize,\n        bottomStart: CornerSize,\n    ) =\n        RoundedCornerShape(\n            topStart = topStart,\n            topEnd = topEnd,\n            bottomEnd = bottomEnd,\n            bottomStart = bottomStart,\n        )\n\n    override fun toString(): String {\n        return \"RoundedCornerShape(topStart = $topStart, topEnd = $topEnd, bottomEnd = \" +\n            \"$bottomEnd, bottomStart = $bottomStart)\"\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is RoundedCornerShape) return false\n\n        if (topStart != other.topStart) return false\n        if (topEnd != other.topEnd) return false\n        if (bottomEnd != other.bottomEnd) return false\n        if (bottomStart != other.bottomStart) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = topStart.hashCode()\n        result = 31 * result + topEnd.hashCode()\n        result = 31 * result + bottomEnd.hashCode()\n        result = 31 * result + bottomStart.hashCode()\n        return result\n    }\n\n    override fun lerp(other: Any?, t: Float): Any? {\n        var other: Any? = other\n        if (other == RectangleShape || other == null) {\n            other = RoundedCornerShape(0f)\n        }\n        if (other is RoundedCornerShape) {\n            return lerp(this, other, t)\n        }\n        return null\n    }\n}\n\ninternal fun lerp(a: RoundedCornerShape, b: RoundedCornerShape, t: Float): RoundedCornerShape {\n    return RoundedCornerShape(\n        topStart = lerp(a.topStart, b.topStart, t),\n        topEnd = lerp(a.topEnd, b.topEnd, t),\n        bottomEnd = lerp(a.bottomEnd, b.bottomEnd, t),\n        bottomStart = lerp(a.bottomStart, b.bottomStart, t),\n    )\n}\n\ninternal fun lerp(a: CornerSize, b: CornerSize, t: Float): CornerSize {\n    return object : CornerSize {\n        override fun toPx(shapeSize: Size, density: Density): Float {\n            return lerp(a.toPx(shapeSize, density), b.toPx(shapeSize, density), t)\n        }\n    }\n}\n\n/** Circular [Shape] with all the corners sized as the 50 percent of the shape size. */\nval CircleShape = RoundedCornerShape(50)\n\n/**\n * Creates [RoundedCornerShape] with the same size applied for all four corners.\n *\n * @param corner [CornerSize] to apply.\n */\nfun RoundedCornerShape(corner: CornerSize) = RoundedCornerShape(corner, corner, corner, corner)\n\n/**\n * Creates [RoundedCornerShape] with the same size applied for all four corners.\n *\n * @param size Size in [Dp] to apply.\n */\nfun RoundedCornerShape(size: Dp) = RoundedCornerShape(CornerSize(size))\n\n/**\n * Creates [RoundedCornerShape] with the same size applied for all four corners.\n *\n * @param size Size in pixels to apply.\n */\nfun RoundedCornerShape(size: Float) = RoundedCornerShape(CornerSize(size))\n\n/**\n * Creates [RoundedCornerShape] with the same size applied for all four corners.\n *\n * @param percent Size in percents to apply.\n */\nfun RoundedCornerShape(percent: Int) = RoundedCornerShape(CornerSize(percent))\n\n/** Creates [RoundedCornerShape] with sizes defined in [Dp]. */\nfun RoundedCornerShape(\n    topStart: Dp = 0.dp,\n    topEnd: Dp = 0.dp,\n    bottomEnd: Dp = 0.dp,\n    bottomStart: Dp = 0.dp,\n) =\n    RoundedCornerShape(\n        topStart = CornerSize(topStart),\n        topEnd = CornerSize(topEnd),\n        bottomEnd = CornerSize(bottomEnd),\n        bottomStart = CornerSize(bottomStart),\n    )\n\n/** Creates [RoundedCornerShape] with sizes defined in pixels. */\nfun RoundedCornerShape(\n    topStart: Float = 0.0f,\n    topEnd: Float = 0.0f,\n    bottomEnd: Float = 0.0f,\n    bottomStart: Float = 0.0f,\n) =\n    RoundedCornerShape(\n        topStart = CornerSize(topStart),\n        topEnd = CornerSize(topEnd),\n        bottomEnd = CornerSize(bottomEnd),\n        bottomStart = CornerSize(bottomStart),\n    )\n\n/**\n * Creates [RoundedCornerShape] with sizes defined in percents of the shape's smaller side.\n *\n * @param topStartPercent The top start corner radius as a percentage of the smaller side, with a\n *   range of 0 - 100.\n * @param topEndPercent The top end corner radius as a percentage of the smaller side, with a range\n *   of 0 - 100.\n * @param bottomEndPercent The bottom end corner radius as a percentage of the smaller side, with a\n *   range of 0 - 100.\n * @param bottomStartPercent The bottom start corner radius as a percentage of the smaller side,\n *   with a range of 0 - 100.\n */\nfun RoundedCornerShape(\n    @IntRange(from = 0, to = 100) topStartPercent: Int = 0,\n    @IntRange(from = 0, to = 100) topEndPercent: Int = 0,\n    @IntRange(from = 0, to = 100) bottomEndPercent: Int = 0,\n    @IntRange(from = 0, to = 100) bottomStartPercent: Int = 0,\n) =\n    RoundedCornerShape(\n        topStart = CornerSize(topStartPercent),\n        topEnd = CornerSize(topEndPercent),\n        bottomEnd = CornerSize(bottomEndPercent),\n        bottomStart = CornerSize(bottomStartPercent),\n    )\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/Pager.kt\n```kotlin\n/*\n * Copyright 2023 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.foundation.pager\n\nimport androidx.annotation.FloatRange\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.DecayAnimationSpec\nimport androidx.compose.animation.core.Spring\nimport androidx.compose.animation.core.VisibilityThreshold\nimport androidx.compose.animation.core.spring\nimport androidx.compose.animation.rememberSplineBasedDecay\nimport androidx.compose.foundation.OverscrollEffect\nimport androidx.compose.foundation.gestures.FlingBehavior\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.TargetedFlingBehavior\nimport androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider\nimport androidx.compose.foundation.gestures.snapping.SnapPosition\nimport androidx.compose.foundation.gestures.snapping.calculateFinalSnappingBound\nimport androidx.compose.foundation.gestures.snapping.snapFlingBehavior\nimport androidx.compose.foundation.internal.requirePrecondition\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.rememberOverscrollEffect\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.input.nestedscroll.NestedScrollConnection\nimport androidx.compose.ui.input.nestedscroll.NestedScrollSource\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.semantics.pageDown\nimport androidx.compose.ui.semantics.pageLeft\nimport androidx.compose.ui.semantics.pageRight\nimport androidx.compose.ui.semantics.pageUp\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.Velocity\nimport androidx.compose.ui.unit.dp\nimport kotlin.math.abs\nimport kotlin.math.absoluteValue\nimport kotlin.math.roundToInt\nimport kotlin.math.sign\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.launch\n\n/**\n * A Pager that scrolls horizontally. Pages are lazily placed in accordance to the available\n * viewport size. By definition, pages in a [Pager] have the same size, defined by [pageSize] and\n * use a snap animation (provided by [flingBehavior] to scroll pages into a specific position). You\n * can use [beyondViewportPageCount] to place more pages before and after the visible pages.\n *\n * If you need snapping with pages of different size, you can use a [snapFlingBehavior] with a\n * [SnapLayoutInfoProvider] adapted to a LazyList.\n *\n * @param state The state to control this pager\n * @param modifier A modifier instance to be applied to this Pager outer layout\n * @param contentPadding a padding around the whole content. This will add padding for the content\n *   after it has been clipped, which is not possible via [modifier] param. You can use it to add a\n *   padding before the first page or after the last one. Use [pageSpacing] to add spacing between\n *   the pages.\n * @param pageSize Use this to change how the pages will look like inside this pager.\n * @param beyondViewportPageCount Pages to compose and layout before and after the list of visible\n *   pages. Note: Be aware that using a large value for [beyondViewportPageCount] will cause a lot\n *   of pages to be composed, measured and placed which will defeat the purpose of using lazy\n *   loading. This should be used as an optimization to pre-load a couple of pages before and after\n *   the visible ones. This does not include the pages automatically composed and laid out by the\n *   pre-fetcher in the direction of the scroll during scroll events.\n * @param pageSpacing The amount of space to be used to separate the pages in this Pager\n * @param verticalAlignment How pages are aligned vertically in this Pager.\n * @param flingBehavior The [TargetedFlingBehavior] to be used for post scroll gestures.\n * @param userScrollEnabled whether the scrolling via the user gestures or accessibility actions is\n *   allowed. You can still scroll programmatically using [PagerState.scroll] even when it is\n *   disabled.\n * @param reverseLayout reverse the direction of scrolling and layout.\n * @param key a stable and unique key representing the item. When you specify the key the scroll\n *   position will be maintained based on the key, which means if you add/remove items before the\n *   current visible item the item with the given key will be kept as the first visible one. If null\n *   is passed the position in the list will represent the key.\n * @param pageNestedScrollConnection A [NestedScrollConnection] that dictates how this [Pager]\n *   behaves with nested lists. The default behavior will see [Pager] to consume all nested deltas.\n * @param snapPosition The calculation of how this Pager will perform snapping of pages. Use this to\n *   provide different settling to different positions in the layout. This is used by [Pager] as a\n *   way to calculate [PagerState.currentPage], currentPage is the page closest to the snap position\n *   in the layout (e.g. if the snap position is the start of the layout, then currentPage will be\n *   the page closest to that).\n * @param overscrollEffect the [OverscrollEffect] that will be used to render overscroll for this\n *   Pager. Note that the [OverscrollEffect.node] will be applied internally as well - you do not\n *   need to use Modifier.overscroll separately.\n * @param pageContent This Pager's page Composable.\n * @sample androidx.compose.foundation.samples.SimpleHorizontalPagerSample\n * @sample androidx.compose.foundation.samples.HorizontalPagerWithScrollableContent\n * @see androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider for the implementation\n *   of a [SnapLayoutInfoProvider] that uses [androidx.compose.foundation.lazy.LazyListState].\n *\n * Please refer to the samples to learn how to use this API.\n */\n@Composable\nfun HorizontalPager(\n    state: PagerState,\n    modifier: Modifier = Modifier,\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    pageSize: PageSize = PageSize.Fill,\n    beyondViewportPageCount: Int = PagerDefaults.BeyondViewportPageCount,\n    pageSpacing: Dp = 0.dp,\n    verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,\n    flingBehavior: TargetedFlingBehavior = PagerDefaults.flingBehavior(state = state),\n    userScrollEnabled: Boolean = true,\n    reverseLayout: Boolean = false,\n    key: ((index: Int) -> Any)? = null,\n    pageNestedScrollConnection: NestedScrollConnection =\n        PagerDefaults.pageNestedScrollConnection(state, Orientation.Horizontal),\n    snapPosition: SnapPosition = SnapPosition.Start,\n    overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),\n    pageContent: @Composable PagerScope.(page: Int) -> Unit,\n) {\n    Pager(\n        state = state,\n        modifier = modifier,\n        contentPadding = contentPadding,\n        pageSize = pageSize,\n        beyondViewportPageCount = beyondViewportPageCount,\n        pageSpacing = pageSpacing,\n        orientation = Orientation.Horizontal,\n        verticalAlignment = verticalAlignment,\n        horizontalAlignment = Alignment.CenterHorizontally,\n        flingBehavior = flingBehavior,\n        userScrollEnabled = userScrollEnabled,\n        reverseLayout = reverseLayout,\n        key = key,\n        pageNestedScrollConnection = pageNestedScrollConnection,\n        snapPosition = snapPosition,\n        overscrollEffect = overscrollEffect,\n        pageContent = pageContent,\n    )\n}\n\n@Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun HorizontalPager(\n    state: PagerState,\n    modifier: Modifier = Modifier,\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    pageSize: PageSize = PageSize.Fill,\n    beyondViewportPageCount: Int = PagerDefaults.BeyondViewportPageCount,\n    pageSpacing: Dp = 0.dp,\n    verticalAlignment: Alignment.Vertical = Alignment.CenterVertically,\n    flingBehavior: TargetedFlingBehavior = PagerDefaults.flingBehavior(state = state),\n    userScrollEnabled: Boolean = true,\n    reverseLayout: Boolean = false,\n    key: ((index: Int) -> Any)? = null,\n    pageNestedScrollConnection: NestedScrollConnection =\n        PagerDefaults.pageNestedScrollConnection(state, Orientation.Horizontal),\n    snapPosition: SnapPosition = SnapPosition.Start,\n    pageContent: @Composable PagerScope.(page: Int) -> Unit,\n) {\n    HorizontalPager(\n        state = state,\n        modifier = modifier,\n        contentPadding = contentPadding,\n        pageSize = pageSize,\n        beyondViewportPageCount = beyondViewportPageCount,\n        pageSpacing = pageSpacing,\n        verticalAlignment = verticalAlignment,\n        flingBehavior = flingBehavior,\n        userScrollEnabled = userScrollEnabled,\n        reverseLayout = reverseLayout,\n        key = key,\n        pageNestedScrollConnection = pageNestedScrollConnection,\n        snapPosition = snapPosition,\n        overscrollEffect = rememberOverscrollEffect(),\n        pageContent = pageContent,\n    )\n}\n\n/**\n * A Pager that scrolls vertically. Pages are lazily placed in accordance to the available viewport\n * size. By definition, pages in a [Pager] have the same size, defined by [pageSize] and use a snap\n * animation (provided by [flingBehavior] to scroll pages into a specific position). You can use\n * [beyondViewportPageCount] to place more pages before and after the visible pages.\n *\n * If you need snapping with pages of different size, you can use a [snapFlingBehavior] with a\n * [SnapLayoutInfoProvider] adapted to a LazyList.\n *\n * @param state The state to control this pager\n * @param modifier A modifier instance to be apply to this Pager outer layout\n * @param contentPadding a padding around the whole content. This will add padding for the content\n *   after it has been clipped, which is not possible via [modifier] param. You can use it to add a\n *   padding before the first page or after the last one. Use [pageSpacing] to add spacing between\n *   the pages.\n * @param pageSize Use this to change how the pages will look like inside this pager.\n * @param beyondViewportPageCount Pages to compose and layout before and after the list of visible\n *   pages. Note: Be aware that using a large value for [beyondViewportPageCount] will cause a lot\n *   of pages to be composed, measured and placed which will defeat the purpose of using lazy\n *   loading. This should be used as an optimization to pre-load a couple of pages before and after\n *   the visible ones. This does not include the pages automatically composed and laid out by the\n *   pre-fetcher in\n *     * the direction of the scroll during scroll events.\n *\n * @param pageSpacing The amount of space to be used to separate the pages in this Pager\n * @param horizontalAlignment How pages are aligned horizontally in this Pager.\n * @param flingBehavior The [TargetedFlingBehavior] to be used for post scroll gestures.\n * @param userScrollEnabled whether the scrolling via the user gestures or accessibility actions is\n *   allowed. You can still scroll programmatically using [PagerState.scroll] even when it is\n *   disabled.\n * @param reverseLayout reverse the direction of scrolling and layout.\n * @param key a stable and unique key representing the item. When you specify the key the scroll\n *   position will be maintained based on the key, which means if you add/remove items before the\n *   current visible item the item with the given key will be kept as the first visible one. If null\n *   is passed the position in the list will represent the key.\n * @param pageNestedScrollConnection A [NestedScrollConnection] that dictates how this [Pager]\n *   behaves with nested lists. The default behavior will see [Pager] to consume all nested deltas.\n * @param snapPosition The calculation of how this Pager will perform snapping of Pages. Use this to\n *   provide different settling to different positions in the layout. This is used by [Pager] as a\n *   way to calculate [PagerState.currentPage], currentPage is the page closest to the snap position\n *   in the layout (e.g. if the snap position is the start of the layout, then currentPage will be\n *   the page closest to that).\n * @param overscrollEffect the [OverscrollEffect] that will be used to render overscroll for this\n *   Pager. Note that the [OverscrollEffect.node] will be applied internally as well - you do not\n *   need to use Modifier.overscroll separately.\n * @param pageContent This Pager's page Composable.\n * @sample androidx.compose.foundation.samples.SimpleVerticalPagerSample\n * @see androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider for the implementation\n *   of a [SnapLayoutInfoProvider] that uses [androidx.compose.foundation.lazy.LazyListState].\n *\n * Please refer to the sample to learn how to use this API.\n */\n@Composable\nfun VerticalPager(\n    state: PagerState,\n    modifier: Modifier = Modifier,\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    pageSize: PageSize = PageSize.Fill,\n    beyondViewportPageCount: Int = PagerDefaults.BeyondViewportPageCount,\n    pageSpacing: Dp = 0.dp,\n    horizontalAlignment: Alignment.Horizontal = Alignment.CenterHorizontally,\n    flingBehavior: TargetedFlingBehavior = PagerDefaults.flingBehavior(state = state),\n    userScrollEnabled: Boolean = true,\n    reverseLayout: Boolean = false,\n    key: ((index: Int) -> Any)? = null,\n    pageNestedScrollConnection: NestedScrollConnection =\n        PagerDefaults.pageNestedScrollConnection(state, Orientation.Vertical),\n    snapPosition: SnapPosition = SnapPosition.Start,\n    overscrollEffect: OverscrollEffect? = rememberOverscrollEffect(),\n    pageContent: @Composable PagerScope.(page: Int) -> Unit,\n) {\n    Pager(\n        state = state,\n        modifier = modifier,\n        contentPadding = contentPadding,\n        pageSize = pageSize,\n        beyondViewportPageCount = beyondViewportPageCount,\n        pageSpacing = pageSpacing,\n        orientation = Orientation.Vertical,\n        verticalAlignment = Alignment.CenterVertically,\n        horizontalAlignment = horizontalAlignment,\n        flingBehavior = flingBehavior,\n        userScrollEnabled = userScrollEnabled,\n        reverseLayout = reverseLayout,\n        key = key,\n        pageNestedScrollConnection = pageNestedScrollConnection,\n        snapPosition = snapPosition,\n        overscrollEffect = overscrollEffect,\n        pageContent = pageContent,\n    )\n}\n\n@Deprecated(\"Use the non deprecated overload\", level = DeprecationLevel.HIDDEN)\n@Composable\nfun VerticalPager(\n    state: PagerState,\n    modifier: Modifier = Modifier,\n    contentPadding: PaddingValues = PaddingValues(0.dp),\n    pageSize: PageSize = PageSize.Fill,\n    beyondViewportPageCount: Int = PagerDefaults.BeyondViewportPageCount,\n    pageSpacing: Dp = 0.dp,\n    horizontalAlignment: Alignment.Horizontal = Alignment.CenterHorizontally,\n    flingBehavior: TargetedFlingBehavior = PagerDefaults.flingBehavior(state = state),\n    userScrollEnabled: Boolean = true,\n    reverseLayout: Boolean = false,\n    key: ((index: Int) -> Any)? = null,\n    pageNestedScrollConnection: NestedScrollConnection =\n        PagerDefaults.pageNestedScrollConnection(state, Orientation.Vertical),\n    snapPosition: SnapPosition = SnapPosition.Start,\n    pageContent: @Composable PagerScope.(page: Int) -> Unit,\n) {\n    VerticalPager(\n        state = state,\n        modifier = modifier,\n        contentPadding = contentPadding,\n        pageSize = pageSize,\n        beyondViewportPageCount = beyondViewportPageCount,\n        pageSpacing = pageSpacing,\n        horizontalAlignment = horizontalAlignment,\n        flingBehavior = flingBehavior,\n        userScrollEnabled = userScrollEnabled,\n        reverseLayout = reverseLayout,\n        key = key,\n        pageNestedScrollConnection = pageNestedScrollConnection,\n        snapPosition = snapPosition,\n        overscrollEffect = rememberOverscrollEffect(),\n        pageContent = pageContent,\n    )\n}\n\n/** Contains the default values used by [Pager]. */\nobject PagerDefaults {\n\n    /**\n     * A [snapFlingBehavior] that will snap pages to the start of the layout. One can use the given\n     * parameters to control how the snapping animation will happen.\n     *\n     * @param state The [PagerState] that controls the which to which this FlingBehavior will be\n     *   applied to.\n     * @param pagerSnapDistance A way to control the snapping destination for this [Pager]. The\n     *   default behavior will result in any fling going to the next page in the direction of the\n     *   fling (if the fling has enough velocity, otherwise the Pager will bounce back). Use\n     *   [PagerSnapDistance.atMost] to define a maximum number of pages this [Pager] is allowed to\n     *   fling after scrolling is finished and fling has started.\n     * @param decayAnimationSpec The animation spec used to approach the target offset. When the\n     *   fling velocity is large enough. Large enough means large enough to naturally decay. For\n     *   single page snapping this usually never happens since there won't be enough space to run a\n     *   decay animation.\n     * @param snapAnimationSpec The animation spec used to finally snap to the position. This\n     *   animation will be often used in 2 cases: 1) There was enough space to an approach\n     *   animation, the Pager will use [snapAnimationSpec] in the last step of the animation to\n     *   settle the page into position. 2) There was not enough space to run the approach animation.\n     * @param snapPositionalThreshold If the fling has a low velocity (e.g. slow scroll), this fling\n     *   behavior will use this snap threshold in order to determine if the pager should snap back\n     *   or move forward. Use a number between 0 and 1 as a fraction of the page size that needs to\n     *   be scrolled before the Pager considers it should move to the next page. For instance, if\n     *   snapPositionalThreshold = 0.35, it means if this pager is scrolled with a slow velocity and\n     *   the Pager scrolls more than 35% of the page size, then will jump to the next page, if not\n     *   it scrolls back. Note that any fling that has high enough velocity will *always* move to\n     *   the next page in the direction of the fling.\n     * @return An instance of [FlingBehavior] that will perform Snapping to the next page by\n     *   default. The animation will be governed by the post scroll velocity and the Pager will use\n     *   either [snapAnimationSpec] or [decayAnimationSpec] to approach the snapped position If a\n     *   velocity is not high enough the pager will use [snapAnimationSpec] to reach the snapped\n     *   position. If the velocity is high enough, the Pager will use the logic described in\n     *   [decayAnimationSpec] and [snapAnimationSpec].\n     * @see androidx.compose.foundation.gestures.snapping.snapFlingBehavior for more information on\n     *   what which parameter controls in the overall snapping animation.\n     *\n     * The animation specs used by the fling behavior will depend on 2 factors:\n     * 1) The gesture velocity.\n     * 2) The target page proposed by [pagerSnapDistance].\n     *\n     * If you're using single page snapping (the most common use case for [Pager]), there won't be\n     * enough space to actually run a decay animation to approach the target page, so the Pager will\n     * always use the snapping animation from [snapAnimationSpec]. If you're using multi-page\n     * snapping (this means you're abs(targetPage - currentPage) > 1) the Pager may use\n     * [decayAnimationSpec] or [snapAnimationSpec] to approach the targetPage, it will depend on the\n     * velocity generated by the triggering gesture. If the gesture has a high enough velocity to\n     * approach the target page, the Pager will use [decayAnimationSpec] followed by\n     * [snapAnimationSpec] for the final step of the animation. If the gesture doesn't have enough\n     * velocity, the Pager will use [snapAnimationSpec] + [snapAnimationSpec] in a similar fashion.\n     */\n    @Composable\n    fun flingBehavior(\n        state: PagerState,\n        pagerSnapDistance: PagerSnapDistance = PagerSnapDistance.atMost(1),\n        decayAnimationSpec: DecayAnimationSpec<Float> = rememberSplineBasedDecay(),\n        snapAnimationSpec: AnimationSpec<Float> =\n            spring(\n                stiffness = Spring.StiffnessMediumLow,\n                visibilityThreshold = Int.VisibilityThreshold.toFloat(),\n            ),\n        @FloatRange(from = 0.0, to = 1.0) snapPositionalThreshold: Float = 0.5f,\n    ): TargetedFlingBehavior {\n        requirePrecondition(snapPositionalThreshold in 0f..1f) {\n            \"snapPositionalThreshold should be a number between 0 and 1. \" +\n                \"You've specified $snapPositionalThreshold\"\n        }\n        val density = LocalDensity.current\n        val layoutDirection = LocalLayoutDirection.current\n        return remember(\n            state,\n            decayAnimationSpec,\n            snapAnimationSpec,\n            pagerSnapDistance,\n            density,\n            layoutDirection,\n        ) {\n            val snapLayoutInfoProvider =\n                SnapLayoutInfoProvider(state, pagerSnapDistance) {\n                    flingVelocity,\n                    lowerBound,\n                    upperBound ->\n                    calculateFinalSnappingBound(\n                        pagerState = state,\n                        layoutDirection = layoutDirection,\n                        snapPositionalThreshold = snapPositionalThreshold,\n                        flingVelocity = flingVelocity,\n                        lowerBoundOffset = lowerBound,\n                        upperBoundOffset = upperBound,\n                    )\n                }\n\n            snapFlingBehavior(\n                snapLayoutInfoProvider = snapLayoutInfoProvider,\n                decayAnimationSpec = decayAnimationSpec,\n                snapAnimationSpec = snapAnimationSpec,\n            )\n        }\n    }\n\n    /**\n     * The default implementation of Pager's pageNestedScrollConnection.\n     *\n     * @param state state of the pager\n     * @param orientation The orientation of the pager. This will be used to determine which\n     *   direction the nested scroll connection will operate and react on.\n     */\n    @Composable\n    fun pageNestedScrollConnection(\n        state: PagerState,\n        orientation: Orientation,\n    ): NestedScrollConnection {\n        return remember(state, orientation) {\n            DefaultPagerNestedScrollConnection(state, orientation)\n        }\n    }\n\n    /**\n     * The default value of beyondViewportPageCount used to specify the number of pages to compose\n     * and layout before and after the visible pages. It does not include the pages automatically\n     * composed and laid out by the pre-fetcher in the direction of the scroll during scroll events.\n     */\n    const val BeyondViewportPageCount = 0\n}\n\ninternal fun SnapPosition.currentPageOffset(\n    layoutSize: Int,\n    pageSize: Int,\n    spaceBetweenPages: Int,\n    beforeContentPadding: Int,\n    afterContentPadding: Int,\n    currentPage: Int,\n    currentPageOffsetFraction: Float,\n    pageCount: Int,\n): Int {\n    val snapOffset =\n        position(\n            layoutSize,\n            pageSize,\n            beforeContentPadding,\n            afterContentPadding,\n            currentPage,\n            pageCount,\n        )\n\n    return (snapOffset - currentPageOffsetFraction * (pageSize + spaceBetweenPages)).roundToInt()\n}\n\nprivate class DefaultPagerNestedScrollConnection(\n    val state: PagerState,\n    val orientation: Orientation,\n) : NestedScrollConnection {\n\n    fun Velocity.consumeOnOrientation(orientation: Orientation): Velocity {\n        return if (orientation == Orientation.Vertical) {\n            copy(x = 0f)\n        } else {\n            copy(y = 0f)\n        }\n    }\n\n    override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {\n        return if (\n            // rounding error and drag only\n            source == NestedScrollSource.UserInput &&\n                abs(state.currentPageOffsetFraction) > 1e-6 &&\n                // only need to treat deltas on this Pager's orientation\n                available.toFloat().absoluteValue > 0f\n        ) {\n            // find the current and next page (in the direction of dragging)\n            val currentPageOffset = state.currentPageOffsetFraction * state.pageSize\n            val pageAvailableSpace = state.layoutInfo.pageSize + state.layoutInfo.pageSpacing\n            val nextClosestPageOffset =\n                currentPageOffset + pageAvailableSpace * -sign(state.currentPageOffsetFraction)\n\n            val minBound: Float\n            val maxBound: Float\n            // build min and max bounds in absolute coordinates for nested scroll\n            if (state.currentPageOffsetFraction > 0f) {\n                minBound = nextClosestPageOffset\n                maxBound = currentPageOffset\n            } else {\n                minBound = currentPageOffset\n                maxBound = nextClosestPageOffset\n            }\n\n            val delta = available.toFloat()\n            val coerced = delta.coerceIn(minBound, maxBound)\n            // dispatch and return reversed as usual\n            val consumed = -state.dispatchRawDelta(-coerced)\n            available.copy(\n                x = if (orientation == Orientation.Horizontal) consumed else available.x,\n                y = if (orientation == Orientation.Vertical) consumed else available.y,\n            )\n        } else {\n            Offset.Zero\n        }\n    }\n\n    private fun Offset.toFloat() = if (orientation == Orientation.Horizontal) x else y\n\n    override fun onPostScroll(\n        consumed: Offset,\n        available: Offset,\n        source: NestedScrollSource,\n    ): Offset {\n        if (source == NestedScrollSource.SideEffect && available.mainAxis() != 0f) {\n            throw CancellationException(\"Scroll cancelled\")\n        }\n        return Offset.Zero\n    }\n\n    override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {\n        return available.consumeOnOrientation(orientation)\n    }\n\n    private fun Offset.mainAxis(): Float =\n        if (orientation == Orientation.Horizontal) this.x else this.y\n}\n\ninternal fun Modifier.pagerSemantics(\n    state: PagerState,\n    isVertical: Boolean,\n    scope: CoroutineScope,\n    userScrollEnabled: Boolean,\n): Modifier {\n    fun performForwardPaging(): Boolean {\n        return if (state.canScrollForward) {\n            scope.launch { state.animateToNextPage() }\n            true\n        } else {\n            false\n        }\n    }\n\n    fun performBackwardPaging(): Boolean {\n        return if (state.canScrollBackward) {\n            scope.launch { state.animateToPreviousPage() }\n            true\n        } else {\n            false\n        }\n    }\n\n    return if (userScrollEnabled) {\n        this.then(\n            Modifier.semantics {\n                if (isVertical) {\n                    pageUp { performBackwardPaging() }\n                    pageDown { performForwardPaging() }\n                } else {\n                    pageLeft { performBackwardPaging() }\n                    pageRight { performForwardPaging() }\n                }\n            }\n        )\n    } else {\n        this then Modifier\n    }\n}\n\nprivate inline fun debugLog(generateMsg: () -> String) {\n    if (PagerDebugConfig.MainPagerComposable) {\n        println(\"Pager: ${generateMsg()}\")\n    }\n}\n\ninternal object PagerDebugConfig {\n    const val MainPagerComposable = false\n    const val PagerState = false\n    const val MeasureLogic = false\n    const val ScrollPosition = false\n    const val PagerSnapDistance = false\n    const val PagerSnapLayoutInfoProvider = false\n}\n```\n\n## File: compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/pager/PagerState.kt\n```kotlin\n/*\n * Copyright 2023 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@file:Suppress(\"DEPRECATION\")\n\npackage androidx.compose.foundation.pager\n\nimport androidx.annotation.FloatRange\nimport androidx.annotation.IntRange as AndroidXIntRange\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.animate\nimport androidx.compose.animation.core.spring\nimport androidx.compose.foundation.ComposeFoundationFlags.isCacheWindowForPagerEnabled\nimport androidx.compose.foundation.ExperimentalFoundationApi\nimport androidx.compose.foundation.MutatePriority\nimport androidx.compose.foundation.ScrollIndicatorState\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.ScrollScope\nimport androidx.compose.foundation.gestures.ScrollableState\nimport androidx.compose.foundation.gestures.snapping.SnapPosition\nimport androidx.compose.foundation.gestures.stopScroll\nimport androidx.compose.foundation.interaction.InteractionSource\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.internal.requirePrecondition\nimport androidx.compose.foundation.lazy.layout.AwaitFirstLayoutModifier\nimport androidx.compose.foundation.lazy.layout.LazyLayoutBeyondBoundsInfo\nimport androidx.compose.foundation.lazy.layout.LazyLayoutCacheWindow\nimport androidx.compose.foundation.lazy.layout.LazyLayoutPinnedItemList\nimport androidx.compose.foundation.lazy.layout.LazyLayoutPrefetchState\nimport androidx.compose.foundation.lazy.layout.LazyLayoutScrollScope\nimport androidx.compose.foundation.lazy.layout.ObservableScopeInvalidator\nimport androidx.compose.foundation.lazy.layout.PrefetchScheduler\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.annotation.FrequentlyChangingValue\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.neverEqualPolicy\nimport androidx.compose.runtime.saveable.Saver\nimport androidx.compose.runtime.saveable.listSaver\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.runtime.snapshots.Snapshot\nimport androidx.compose.runtime.structuralEqualityPolicy\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.layout.AlignmentLine\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.Remeasurement\nimport androidx.compose.ui.layout.RemeasurementModifier\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastCoerceAtMost\nimport kotlin.coroutines.EmptyCoroutineContext\nimport kotlin.math.abs\nimport kotlin.math.absoluteValue\nimport kotlin.math.roundToLong\nimport kotlin.math.sign\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.launch\n\n/**\n * Creates and remember a [PagerState] to be used with a [Pager]\n *\n * Please refer to the sample to learn how to use this API.\n *\n * @sample androidx.compose.foundation.samples.PagerWithStateSample\n * @param initialPage The pager that should be shown first.\n * @param initialPageOffsetFraction The offset of the initial page as a fraction of the page size.\n *   This should vary between -0.5 and 0.5 and indicates how to offset the initial page from the\n *   snapped position.\n * @param pageCount The amount of pages this Pager will have.\n */\n@Composable\nfun rememberPagerState(\n    initialPage: Int = 0,\n    @FloatRange(from = -0.5, to = 0.5) initialPageOffsetFraction: Float = 0f,\n    pageCount: () -> Int,\n): PagerState {\n    return rememberSaveable(saver = DefaultPagerState.Saver) {\n            DefaultPagerState(initialPage, initialPageOffsetFraction, pageCount)\n        }\n        .apply { pageCountState.value = pageCount }\n}\n\n/**\n * Creates a default [PagerState] to be used with a [Pager]\n *\n * Please refer to the sample to learn how to use this API.\n *\n * @sample androidx.compose.foundation.samples.PagerWithStateSample\n * @param currentPage The pager that should be shown first.\n * @param currentPageOffsetFraction The offset of the initial page as a fraction of the page size.\n *   This should vary between -0.5 and 0.5 and indicates how to offset the initial page from the\n *   snapped position.\n * @param pageCount The amount of pages this Pager will have.\n */\nfun PagerState(\n    currentPage: Int = 0,\n    @FloatRange(from = -0.5, to = 0.5) currentPageOffsetFraction: Float = 0f,\n    pageCount: () -> Int,\n): PagerState = DefaultPagerState(currentPage, currentPageOffsetFraction, pageCount)\n\nprivate class DefaultPagerState(\n    currentPage: Int,\n    currentPageOffsetFraction: Float,\n    updatedPageCount: () -> Int,\n) : PagerState(currentPage, currentPageOffsetFraction) {\n\n    var pageCountState = mutableStateOf(updatedPageCount)\n    override val pageCount: Int\n        get() = pageCountState.value.invoke()\n\n    companion object {\n        /** To keep current page and current page offset saved */\n        val Saver: Saver<DefaultPagerState, *> =\n            listSaver(\n                save = {\n                    listOf(\n                        it.currentPage,\n                        (it.currentPageOffsetFraction).coerceIn(MinPageOffset, MaxPageOffset),\n                        it.pageCount,\n                    )\n                },\n                restore = {\n                    DefaultPagerState(\n                        currentPage = it[0] as Int,\n                        currentPageOffsetFraction = it[1] as Float,\n                        updatedPageCount = { it[2] as Int },\n                    )\n                },\n            )\n    }\n}\n\n/** The state that can be used to control [VerticalPager] and [HorizontalPager] */\n@OptIn(ExperimentalFoundationApi::class)\n@Stable\nabstract class PagerState\ninternal constructor(\n    currentPage: Int = 0,\n    @FloatRange(from = -0.5, to = 0.5) currentPageOffsetFraction: Float = 0f,\n    prefetchScheduler: PrefetchScheduler? = null,\n) : ScrollableState {\n\n    /**\n     * @param currentPage The initial page to be displayed\n     * @param currentPageOffsetFraction The offset of the initial page with respect to the start of\n     *   the layout.\n     */\n    constructor(\n        currentPage: Int = 0,\n        @FloatRange(from = -0.5, to = 0.5) currentPageOffsetFraction: Float = 0f,\n    ) : this(currentPage, currentPageOffsetFraction, null)\n\n    internal var hasLookaheadOccurred: Boolean = false\n        private set\n\n    internal var approachLayoutInfo: PagerMeasureResult? = null\n        private set\n\n    /**\n     * The total amount of pages present in this pager. The source of this data should be\n     * observable.\n     */\n    abstract val pageCount: Int\n\n    init {\n        requirePrecondition(currentPageOffsetFraction in -0.5..0.5) {\n            \"currentPageOffsetFraction $currentPageOffsetFraction is \" +\n                \"not within the range -0.5 to 0.5\"\n        }\n    }\n\n    /** Difference between the last up and last down events of a scroll event. */\n    internal var upDownDifference: Offset by mutableStateOf(Offset.Zero)\n\n    private val scrollPosition = PagerScrollPosition(currentPage, currentPageOffsetFraction, this)\n\n    internal var firstVisiblePage = currentPage\n        private set\n\n    internal var firstVisiblePageOffset = 0\n        private set\n\n    internal var maxScrollOffset: Long = Long.MAX_VALUE\n\n    internal var minScrollOffset: Long = 0L\n\n    private var accumulator: Float = 0.0f\n\n    /**\n     * The prefetch will act after the measure pass has finished and it needs to know the magnitude\n     * and direction of the scroll that triggered the measure pass\n     */\n    private var previousPassDelta = 0f\n\n    /**\n     * The ScrollableController instance. We keep it as we need to call stopAnimation on it once we\n     * reached the end of the list.\n     */\n    private val scrollableState = ScrollableState { performScroll(it) }\n\n    /**\n     * Within the scrolling context we can use absolute positions to determine scroll deltas and max\n     * min scrolling.\n     */\n    private fun performScroll(delta: Float): Float {\n        val currentScrollPosition = currentAbsoluteScrollOffset()\n        debugLog {\n            \"\\nDelta=$delta \" +\n                \"\\ncurrentScrollPosition=$currentScrollPosition \" +\n                \"\\naccumulator=$accumulator\" +\n                \"\\nmaxScrollOffset=$maxScrollOffset\"\n        }\n\n        val decimalAccumulation = (delta + accumulator)\n        val decimalAccumulationInt = decimalAccumulation.roundToLong()\n        accumulator = decimalAccumulation - decimalAccumulationInt\n\n        // nothing to scroll\n        if (delta.absoluteValue < 1e-4f) return delta\n\n        /**\n         * The updated scroll position is the current position with the integer part of the delta\n         * and accumulator applied.\n         */\n        val updatedScrollPosition = (currentScrollPosition + decimalAccumulationInt)\n\n        /** Check if the scroll position may be larger than the maximum possible scroll. */\n        val coercedScrollPosition = updatedScrollPosition.coerceIn(minScrollOffset, maxScrollOffset)\n\n        /** Check if we actually coerced. */\n        val changed = updatedScrollPosition != coercedScrollPosition\n\n        /** Calculated the actual scroll delta to be applied */\n        val scrollDelta = coercedScrollPosition - currentScrollPosition\n\n        previousPassDelta = scrollDelta.toFloat()\n\n        if (scrollDelta.absoluteValue != 0L) {\n            isLastScrollForwardState.value = scrollDelta > 0.0f\n            isLastScrollBackwardState.value = scrollDelta < 0.0f\n        }\n\n        /** Apply the scroll delta */\n        var scrolledLayoutInfo =\n            pagerLayoutInfoState.value.copyWithScrollDeltaWithoutRemeasure(\n                delta = -scrollDelta.toInt()\n            )\n        if (scrolledLayoutInfo != null && this.approachLayoutInfo != null) {\n            // if we were able to scroll the lookahead layout info without remeasure, lets\n            // try to do the same for post lookahead layout info (sometimes they diverge).\n            val scrolledApproachLayoutInfo =\n                approachLayoutInfo?.copyWithScrollDeltaWithoutRemeasure(\n                    delta = -scrollDelta.toInt()\n                )\n            if (scrolledApproachLayoutInfo != null) {\n                // we can apply scroll delta for both phases without remeasure\n                approachLayoutInfo = scrolledApproachLayoutInfo\n            } else {\n                // we can't apply scroll delta for post lookahead, so we have to remeasure\n                scrolledLayoutInfo = null\n            }\n        }\n        if (scrolledLayoutInfo != null) {\n            debugLog { \"Will Apply Without Remeasure\" }\n            applyMeasureResult(\n                result = scrolledLayoutInfo,\n                isLookingAhead = hasLookaheadOccurred,\n                visibleItemsStayedTheSame = true,\n            )\n            // we don't need to remeasure, so we only trigger re-placement:\n            placementScopeInvalidator.invalidateScope()\n            layoutWithoutMeasurement++\n        } else {\n            debugLog { \"Will Apply With Remeasure\" }\n            scrollPosition.applyScrollDelta(scrollDelta.toInt())\n            remeasurement?.forceRemeasure()\n            layoutWithMeasurement++\n        }\n\n        // Return the consumed value.\n        return (if (changed) scrollDelta else delta).toFloat()\n    }\n\n    /** Only used for testing to confirm that we're not making too many measure passes */\n    internal val numMeasurePasses: Int\n        get() = layoutWithMeasurement + layoutWithoutMeasurement\n\n    internal var layoutWithMeasurement: Int = 0\n        private set\n\n    private var layoutWithoutMeasurement: Int = 0\n\n    /** Only used for testing to disable prefetching when needed to test the main logic. */\n    internal var prefetchingEnabled: Boolean = true\n\n    /**\n     * The index scheduled to be prefetched (or the last prefetched index if the prefetch is done).\n     */\n    private var indexToPrefetch = -1\n\n    /** The handle associated with the current index from [indexToPrefetch]. */\n    private var currentPrefetchHandle: LazyLayoutPrefetchState.PrefetchHandle? = null\n\n    /**\n     * Keeps the scrolling direction during the previous calculation in order to be able to detect\n     * the scrolling direction change.\n     */\n    private var wasPrefetchingForward = false\n\n    /** Backing state for PagerLayoutInfo */\n    private var pagerLayoutInfoState = mutableStateOf(EmptyLayoutInfo, neverEqualPolicy())\n\n    /**\n     * A [PagerLayoutInfo] that contains useful information about the Pager's last layout pass. For\n     * instance, you can query which pages are currently visible in the layout.\n     *\n     * This property is observable and is updated after every scroll or remeasure. If you use it in\n     * the composable function it will be recomposed on every change causing potential performance\n     * issues including infinity recomposition loop. Therefore, avoid using it in the composition.\n     *\n     * If you want to run some side effects like sending an analytics event or updating a state\n     * based on this value consider using \"snapshotFlow\":\n     *\n     * @sample androidx.compose.foundation.samples.UsingPagerLayoutInfoForSideEffectSample\n     */\n    val layoutInfo: PagerLayoutInfo\n        get() = pagerLayoutInfoState.value\n\n    internal val pageSpacing: Int\n        get() = pagerLayoutInfoState.value.pageSpacing\n\n    internal val pageSize: Int\n        get() = pagerLayoutInfoState.value.pageSize\n\n    internal var density: Density = UnitDensity\n\n    internal val pageSizeWithSpacing: Int\n        get() = pageSize + pageSpacing\n\n    // non state backed version\n    internal var latestPageSizeWithSpacing: Int = 0\n\n    /**\n     * How far the current page needs to scroll so the target page is considered to be the next\n     * page.\n     */\n    internal val positionThresholdFraction: Float\n        get() =\n            with(density) {\n                val minThreshold = minOf(DefaultPositionThreshold.toPx(), pageSize / 2f)\n                minThreshold / pageSize.toFloat()\n            }\n\n    internal val internalInteractionSource: MutableInteractionSource = MutableInteractionSource()\n\n    /**\n     * [InteractionSource] that will be used to dispatch drag events when this list is being\n     * dragged. If you want to know whether the fling (or animated scroll) is in progress, use\n     * [isScrollInProgress].\n     */\n    val interactionSource: InteractionSource\n        get() = internalInteractionSource\n\n    /**\n     * The page that sits closest to the snapped position. This is an observable value and will\n     * change as the pager scrolls either by gesture or animation.\n     *\n     * Please refer to the sample to learn how to use this API.\n     *\n     * @sample androidx.compose.foundation.samples.ObservingStateChangesInPagerStateSample\n     */\n    val currentPage: Int\n        get() = scrollPosition.currentPage\n\n    private var programmaticScrollTargetPage by mutableIntStateOf(-1)\n\n    private var settledPageState by mutableIntStateOf(currentPage)\n\n    /**\n     * The page that is currently \"settled\". This is an animation/gesture unaware page in the sense\n     * that it will not be updated while the pages are being scrolled, but rather when the\n     * animation/scroll settles.\n     *\n     * Please refer to the sample to learn how to use this API.\n     *\n     * @sample androidx.compose.foundation.samples.ObservingStateChangesInPagerStateSample\n     */\n    val settledPage by\n        derivedStateOf(structuralEqualityPolicy()) {\n            if (isScrollInProgress) {\n                settledPageState\n            } else {\n                this.currentPage\n            }\n        }\n\n    /**\n     * The page this [Pager] intends to settle to. During fling or animated scroll (from\n     * [animateScrollToPage] this will represent the page this pager intends to settle to. When no\n     * scroll is ongoing, this will be equal to [currentPage].\n     *\n     * Please refer to the sample to learn how to use this API.\n     *\n     * @sample androidx.compose.foundation.samples.ObservingStateChangesInPagerStateSample\n     */\n    val targetPage: Int by\n        derivedStateOf(structuralEqualityPolicy()) {\n            val finalPage =\n                if (!isScrollInProgress) {\n                    this.currentPage\n                } else if (programmaticScrollTargetPage != -1) {\n                    programmaticScrollTargetPage\n                } else {\n                    // act on scroll only\n                    if (abs(this.currentPageOffsetFraction) >= abs(positionThresholdFraction)) {\n                        if (lastScrolledForward) {\n                            firstVisiblePage + 1\n                        } else {\n                            firstVisiblePage\n                        }\n                    } else {\n                        this.currentPage\n                    }\n                }\n            finalPage.coerceInPageRange()\n        }\n\n    /**\n     * Indicates how far the current page is to the snapped position, this will vary from -0.5 (page\n     * is offset towards the start of the layout) to 0.5 (page is offset towards the end of the\n     * layout). This is 0.0 if the [currentPage] is in the snapped position. The value will flip\n     * once the current page changes.\n     *\n     * This property is observable and shouldn't be used as is in a composable function due to\n     * potential performance issues. To use it in the composition, please consider using a derived\n     * state (e.g [derivedStateOf]) to only have recompositions when the derived value changes.\n     *\n     * Please refer to the sample to learn how to use this API.\n     *\n     * @sample androidx.compose.foundation.samples.ObservingStateChangesInPagerStateSample\n     */\n    val currentPageOffsetFraction: Float\n        @FrequentlyChangingValue get() = scrollPosition.currentPageOffsetFraction\n\n    internal val prefetchState =\n        LazyLayoutPrefetchState(prefetchScheduler) {\n            Snapshot.withoutReadObservation { schedulePrecomposition(firstVisiblePage) }\n        }\n\n    /**\n     * Cache window in Pager Initial Layout prefetching happens after the initial measure pass and\n     * latestPageSizeWithSpacing is updated before the prefetching happens.\n     *\n     * For scroll backed prefetching we will use the last known latestPageSizeWithSpacing.\n     */\n    private val pagerCacheWindow =\n        object : LazyLayoutCacheWindow {\n            override fun Density.calculateAheadWindow(viewport: Int): Int =\n                latestPageSizeWithSpacing\n\n            override fun Density.calculateBehindWindow(viewport: Int): Int = 0\n        }\n\n    private val _scrollIndicatorState =\n        object : ScrollIndicatorState {\n            override val scrollOffset: Int\n                get() = calculateScrollOffset()\n\n            override val contentSize: Int\n                get() = layoutInfo.calculateContentSize(pageCount)\n\n            override val viewportSize: Int\n                get() = layoutInfo.mainAxisViewportSize\n        }\n\n    private fun calculateScrollOffset(): Int {\n        val totalScrollOffset =\n            (pageSizeWithSpacing * firstVisiblePage.toLong()) + firstVisiblePageOffset\n        return totalScrollOffset.fastCoerceAtMost(Int.MAX_VALUE.toLong()).toInt()\n    }\n\n    internal val cacheWindowLogic =\n        PagerCacheWindowLogic(pagerCacheWindow, prefetchState) { pageCount }\n\n    internal val beyondBoundsInfo = LazyLayoutBeyondBoundsInfo()\n\n    /**\n     * Provides a modifier which allows to delay some interactions (e.g. scroll) until layout is\n     * ready.\n     */\n    internal val awaitLayoutModifier = AwaitFirstLayoutModifier()\n\n    /**\n     * The [Remeasurement] object associated with our layout. It allows us to remeasure\n     * synchronously during scroll.\n     */\n    internal var remeasurement: Remeasurement? by mutableStateOf(null)\n        private set\n\n    /** The modifier which provides [remeasurement]. */\n    internal val remeasurementModifier =\n        object : RemeasurementModifier {\n            override fun onRemeasurementAvailable(remeasurement: Remeasurement) {\n                this@PagerState.remeasurement = remeasurement\n            }\n        }\n\n    /** Constraints passed to the prefetcher for premeasuring the prefetched items. */\n    internal var premeasureConstraints = Constraints()\n\n    /** Stores currently pinned pages which are always composed, used by for beyond bound pages. */\n    internal val pinnedPages = LazyLayoutPinnedItemList()\n\n    internal val nearestRange: IntRange by scrollPosition.nearestRangeState\n\n    internal val placementScopeInvalidator = ObservableScopeInvalidator()\n\n    /**\n     * Scroll (jump immediately) to a given [page].\n     *\n     * Please refer to the sample to learn how to use this API.\n     *\n     * @sample androidx.compose.foundation.samples.ScrollToPageSample\n     * @param page The destination page to scroll to\n     * @param pageOffsetFraction A fraction of the page size that indicates the offset the\n     *   destination page will be offset from its snapped position.\n     */\n    suspend fun scrollToPage(\n        page: Int,\n        @FloatRange(from = -0.5, to = 0.5) pageOffsetFraction: Float = 0f,\n    ) = scroll {\n        debugLog { \"Scroll from page=$currentPage to page=$page\" }\n        awaitScrollDependencies()\n        requirePrecondition(pageOffsetFraction in -0.5..0.5) {\n            \"pageOffsetFraction $pageOffsetFraction is not within the range -0.5 to 0.5\"\n        }\n        val targetPage = page.coerceInPageRange()\n        snapToItem(targetPage, pageOffsetFraction, forceRemeasure = true)\n    }\n\n    /**\n     * Jump immediately to a given [page] with a given [pageOffsetFraction] inside a [ScrollScope].\n     * Use this method to create custom animated scrolling experiences. This will update the value\n     * of [currentPage] and [currentPageOffsetFraction] immediately, but can only be used inside a\n     * [ScrollScope], use [scroll] to gain access to a [ScrollScope].\n     *\n     * Please refer to the sample to learn how to use this API.\n     *\n     * @sample androidx.compose.foundation.samples.PagerCustomAnimateScrollToPage\n     * @param page The destination page to scroll to\n     * @param pageOffsetFraction A fraction of the page size that indicates the offset the\n     *   destination page will be offset from its snapped position.\n     */\n    fun ScrollScope.updateCurrentPage(\n        page: Int,\n        @FloatRange(from = -0.5, to = 0.5) pageOffsetFraction: Float = 0.0f,\n    ) {\n        snapToItem(page, pageOffsetFraction, forceRemeasure = true)\n    }\n\n    /**\n     * Used to update [targetPage] during a programmatic scroll operation. This can only be called\n     * inside a [ScrollScope] and should be called anytime a custom scroll (through [scroll]) is\n     * executed in order to correctly update [targetPage]. This will not move the pages and it's\n     * still the responsibility of the caller to call [ScrollScope.scrollBy] in order to actually\n     * get to [targetPage]. By the end of the [scroll] block, when the [Pager] is no longer\n     * scrolling [targetPage] will assume the value of [currentPage].\n     *\n     * Please refer to the sample to learn how to use this API.\n     *\n     * @sample androidx.compose.foundation.samples.PagerCustomAnimateScrollToPage\n     */\n    fun ScrollScope.updateTargetPage(targetPage: Int) {\n        programmaticScrollTargetPage = targetPage.coerceInPageRange()\n    }\n\n    internal fun snapToItem(page: Int, offsetFraction: Float, forceRemeasure: Boolean) {\n        val positionChanged =\n            scrollPosition.currentPage != page ||\n                scrollPosition.currentPageOffsetFraction != offsetFraction\n        if (positionChanged) {\n            // we changed positions, cancel existing requests and wait for the next scroll to\n            // refill the window\n            cacheWindowLogic.resetStrategy()\n        }\n\n        scrollPosition.requestPositionAndForgetLastKnownKey(page, offsetFraction)\n        if (forceRemeasure) {\n            remeasurement?.forceRemeasure()\n        } else {\n            measurementScopeInvalidator.invalidateScope()\n        }\n    }\n\n    internal val measurementScopeInvalidator = ObservableScopeInvalidator()\n\n    /**\n     * Requests the [page] to be at the snapped position during the next remeasure, offset by\n     * [pageOffsetFraction], and schedules a remeasure.\n     *\n     * The scroll position will be updated to the requested position rather than maintain the index\n     * based on the current page key (when a data set change will also be applied during the next\n     * remeasure), but *only* for the next remeasure.\n     *\n     * Any scroll in progress will be cancelled.\n     *\n     * @param page the index to which to scroll. Must be non-negative.\n     * @param pageOffsetFraction the offset fraction that the page should end up after the scroll.\n     */\n    fun requestScrollToPage(\n        @AndroidXIntRange(from = 0) page: Int,\n        @FloatRange(from = -0.5, to = 0.5) pageOffsetFraction: Float = 0.0f,\n    ) {\n        // Cancel any scroll in progress.\n        if (isScrollInProgress) {\n            pagerLayoutInfoState.value.coroutineScope.launch { stopScroll() }\n        }\n\n        snapToItem(page, pageOffsetFraction, forceRemeasure = false)\n    }\n\n    /**\n     * Scroll animate to a given [page]'s closest snap position. If the [page] is too far away from\n     * [currentPage] we will not compose all pages in the way. We will pre-jump to a nearer page,\n     * compose and animate the rest of the pages until [page].\n     *\n     * Please refer to the sample to learn how to use this API.\n     *\n     * @sample androidx.compose.foundation.samples.AnimateScrollPageSample\n     * @param page The destination page to scroll to\n     * @param pageOffsetFraction A fraction of the page size that indicates the offset the\n     *   destination page will be offset from its snapped position.\n     * @param animationSpec An [AnimationSpec] to move between pages. We'll use a [spring] as the\n     *   default animation.\n     */\n    suspend fun animateScrollToPage(\n        page: Int,\n        @FloatRange(from = -0.5, to = 0.5) pageOffsetFraction: Float = 0f,\n        animationSpec: AnimationSpec<Float> = spring(),\n    ) {\n        if (\n            page == currentPage && currentPageOffsetFraction == pageOffsetFraction || pageCount == 0\n        )\n            return\n        awaitScrollDependencies()\n        requirePrecondition(pageOffsetFraction in -0.5..0.5) {\n            \"pageOffsetFraction $pageOffsetFraction is not within the range -0.5 to 0.5\"\n        }\n        val targetPage = page.coerceInPageRange()\n        val targetPageOffsetToSnappedPosition = (pageOffsetFraction * pageSizeWithSpacing)\n\n        scroll {\n            LazyLayoutScrollScope(this@PagerState, this)\n                .animateScrollToPage(\n                    targetPage,\n                    targetPageOffsetToSnappedPosition,\n                    animationSpec,\n                    updateTargetPage = { updateTargetPage(it) },\n                )\n        }\n    }\n\n    private suspend fun awaitScrollDependencies() {\n        if (pagerLayoutInfoState.value === EmptyLayoutInfo) {\n            awaitLayoutModifier.waitForFirstLayout()\n        }\n    }\n\n    override suspend fun scroll(\n        scrollPriority: MutatePriority,\n        block: suspend ScrollScope.() -> Unit,\n    ) {\n        awaitScrollDependencies()\n        // will scroll and it's not scrolling already update settled page\n        if (!isScrollInProgress) {\n            settledPageState = currentPage\n        }\n        scrollableState.scroll(scrollPriority, block)\n        programmaticScrollTargetPage = -1 // reset animated scroll target page indicator\n    }\n\n    override fun dispatchRawDelta(delta: Float): Float {\n        return scrollableState.dispatchRawDelta(delta)\n    }\n\n    override val isScrollInProgress: Boolean\n        get() = scrollableState.isScrollInProgress\n\n    final override var canScrollForward: Boolean by mutableStateOf(false)\n        private set\n\n    final override var canScrollBackward: Boolean by mutableStateOf(false)\n        private set\n\n    private val isLastScrollForwardState = mutableStateOf(false)\n    private val isLastScrollBackwardState = mutableStateOf(false)\n\n    @get:Suppress(\"GetterSetterNames\")\n    override val lastScrolledForward: Boolean\n        get() = isLastScrollForwardState.value\n\n    @get:Suppress(\"GetterSetterNames\")\n    override val lastScrolledBackward: Boolean\n        get() = isLastScrollBackwardState.value\n\n    override val scrollIndicatorState: ScrollIndicatorState?\n        get() = _scrollIndicatorState\n\n    /** Updates the state with the new calculated scroll position and consumed scroll. */\n    internal fun applyMeasureResult(\n        result: PagerMeasureResult,\n        isLookingAhead: Boolean,\n        visibleItemsStayedTheSame: Boolean = false,\n    ) {\n        // update the prefetch state with the number of nested prefetch items this layout\n        // should use.\n        prefetchState.idealNestedPrefetchCount = result.visiblePagesInfo.size\n\n        // Update non state backed page size info\n        latestPageSizeWithSpacing = result.pageSize + result.pageSpacing\n\n        if (!isLookingAhead && hasLookaheadOccurred) {\n            debugLog { \"Applying Approach Measure Result\" }\n            // If there was already a lookahead pass, record this result as Approach result\n            approachLayoutInfo = result\n        } else {\n            debugLog { \"Applying Measure Result\" }\n            if (isLookingAhead) {\n                hasLookaheadOccurred = true\n            }\n            if (visibleItemsStayedTheSame) {\n                scrollPosition.updateCurrentPageOffsetFraction(result.currentPageOffsetFraction)\n            } else {\n                scrollPosition.updateFromMeasureResult(result)\n                if (isCacheWindowForPagerEnabled) {\n                    if (prefetchingEnabled) {\n                        cacheWindowLogic.onVisibleItemsChanged(result)\n                    }\n                } else {\n                    cancelPrefetchIfVisibleItemsChanged(result)\n                }\n            }\n            pagerLayoutInfoState.value = result\n            canScrollForward = result.canScrollForward\n            canScrollBackward = result.canScrollBackward\n            result.firstVisiblePage?.let { firstVisiblePage = it.index }\n            firstVisiblePageOffset = result.firstVisiblePageScrollOffset\n            tryRunPrefetch(result)\n            maxScrollOffset = result.calculateNewMaxScrollOffset(pageCount)\n            minScrollOffset =\n                result.calculateNewMinScrollOffset(pageCount).coerceAtMost(maxScrollOffset)\n            debugLog { \"Finished Applying Measure Result\\nNew maxScrollOffset=$maxScrollOffset\" }\n        }\n    }\n\n    private fun tryRunPrefetch(result: PagerMeasureResult) =\n        Snapshot.withoutReadObservation {\n            if (!prefetchingEnabled) return\n            if (result.beyondViewportPageCount >= pageCount) return\n            if (abs(previousPassDelta) <= 0.5f) return\n            if (!isGestureActionMatchesScroll(previousPassDelta)) return\n            if (isCacheWindowForPagerEnabled) {\n                cacheWindowLogic.onScroll(previousPassDelta, result)\n            } else {\n                notifyPrefetch(previousPassDelta, result)\n            }\n        }\n\n    private fun Int.coerceInPageRange() =\n        if (pageCount > 0) {\n            coerceIn(0, pageCount - 1)\n        } else {\n            0\n        }\n\n    // check if the scrolling will be a result of a fling operation. That is, if the scrolling\n    // direction is in the opposite direction of the gesture movement. Also, return true if there\n    // is no applied gesture that causes the scrolling\n    private fun isGestureActionMatchesScroll(scrollDelta: Float): Boolean =\n        if (layoutInfo.orientation == Orientation.Vertical) {\n            sign(scrollDelta) == sign(-upDownDifference.y)\n        } else {\n            sign(scrollDelta) == sign(-upDownDifference.x)\n        } || isNotGestureAction()\n\n    internal fun isNotGestureAction(): Boolean =\n        upDownDifference.x.toInt() == 0 && upDownDifference.y.toInt() == 0\n\n    private fun notifyPrefetch(delta: Float, info: PagerLayoutInfo) {\n        if (!prefetchingEnabled) {\n            return\n        }\n\n        if (info.visiblePagesInfo.isNotEmpty()) {\n            val isPrefetchingForward = delta > 0\n            val indexToPrefetch = calculatePrefetchIndex(isPrefetchingForward, info)\n            if (indexToPrefetch in 0 until pageCount) {\n                if (indexToPrefetch != this.indexToPrefetch) {\n                    if (wasPrefetchingForward != isPrefetchingForward) {\n                        // the scrolling direction has been changed which means the last prefetched\n                        // is not going to be reached anytime soon so it is safer to dispose it.\n                        // if this item is already visible it is safe to call the method anyway\n                        // as it will be no-op\n                        currentPrefetchHandle?.cancel()\n                    }\n                    this.wasPrefetchingForward = isPrefetchingForward\n                    this.indexToPrefetch = indexToPrefetch\n                    currentPrefetchHandle =\n                        prefetchState.schedulePrecompositionAndPremeasure(\n                            indexToPrefetch,\n                            premeasureConstraints,\n                        )\n                }\n                if (isPrefetchingForward) {\n                    val lastItem = info.visiblePagesInfo.last()\n                    val pageSize = info.pageSize + info.pageSpacing\n                    val distanceToReachNextItem =\n                        lastItem.offset + pageSize - info.viewportEndOffset\n                    // if in the next frame we will get the same delta will we reach the item?\n                    if (distanceToReachNextItem < delta) {\n                        currentPrefetchHandle?.markAsUrgent()\n                    }\n                } else {\n                    val firstItem = info.visiblePagesInfo.first()\n                    val distanceToReachNextItem = info.viewportStartOffset - firstItem.offset\n                    // if in the next frame we will get the same delta will we reach the item?\n                    if (distanceToReachNextItem < -delta) {\n                        currentPrefetchHandle?.markAsUrgent()\n                    }\n                }\n            }\n        }\n    }\n\n    private fun cancelPrefetchIfVisibleItemsChanged(info: PagerLayoutInfo) {\n        if (indexToPrefetch != -1 && info.visiblePagesInfo.isNotEmpty()) {\n            val expectedPrefetchIndex = calculatePrefetchIndex(wasPrefetchingForward, info)\n            if (indexToPrefetch != expectedPrefetchIndex) {\n                indexToPrefetch = -1\n                currentPrefetchHandle?.cancel()\n                currentPrefetchHandle = null\n            }\n        }\n    }\n\n    /** Calculate the farthest page index that should be prefetched when scrolling. */\n    private fun calculatePrefetchIndex(forward: Boolean, info: PagerLayoutInfo): Int {\n        return if (forward) {\n            val offset = info.beyondViewportPageCount + PagesToPrefetch\n            if (offset < 0) { // Detect overflow from large beyondViewportPageCount\n                Int.MAX_VALUE\n            } else {\n                info.visiblePagesInfo.last().index + offset\n            }\n        } else {\n            info.visiblePagesInfo.first().index - info.beyondViewportPageCount - PagesToPrefetch\n        }\n    }\n\n    /**\n     * An utility function to help to calculate a given page's offset. This is an offset that\n     * represents how far [page] is from the settled position (represented by [currentPage] offset).\n     * The difference here is that [currentPageOffsetFraction] is a value between -0.5 and 0.5 and\n     * the value calculated by this function can be larger than these numbers if [page] is different\n     * than [currentPage].\n     *\n     * For instance, if currentPage=0 and we call [getOffsetDistanceInPages] for page 3, the result\n     * will be 3, meaning the given page is 3 pages away from the current page (the sign represent\n     * the direction of the offset, positive is forward, negative is backwards). Another example is\n     * if currentPage=3 and we call [getOffsetDistanceInPages] for page 1, the result would be -2,\n     * meaning we're 2 pages away (moving backwards) to the current page.\n     *\n     * This offset also works in conjunction with [currentPageOffsetFraction], so if [currentPage]\n     * is out of its snapped position (i.e. currentPageOffsetFraction!=0) then the calculated value\n     * will still represent the offset in number of pages (in this case, not whole pages). For\n     * instance, if currentPage=1 and we're slightly offset, currentPageOffsetFraction=0.2, if we\n     * call this to page 2, the result would be 0.8, that is 0.8 page away from current page (moving\n     * forward).\n     *\n     * @param page The page to calculate the offset from. This should be between 0 and [pageCount].\n     * @return The offset of [page] with respect to [currentPage].\n     */\n    fun getOffsetDistanceInPages(page: Int): Float {\n        requirePrecondition(page in 0..pageCount) {\n            \"page $page is not within the range 0 to $pageCount\"\n        }\n        return page - currentPage - currentPageOffsetFraction\n    }\n\n    /**\n     * When the user provided custom keys for the pages we can try to detect when there were pages\n     * added or removed before our current page and keep this page as the current one given that its\n     * index has been changed.\n     */\n    internal fun matchScrollPositionWithKey(\n        itemProvider: PagerLazyLayoutItemProvider,\n        currentPage: Int = Snapshot.withoutReadObservation { scrollPosition.currentPage },\n    ): Int = scrollPosition.matchPageWithKey(itemProvider, currentPage)\n}\n\ninternal suspend fun PagerState.animateToNextPage() {\n    if (currentPage + 1 < pageCount) animateScrollToPage(currentPage + 1)\n}\n\ninternal suspend fun PagerState.animateToPreviousPage() {\n    if (currentPage - 1 >= 0) animateScrollToPage(currentPage - 1)\n}\n\ninternal val DefaultPositionThreshold = 56.dp\nprivate const val MaxPagesForAnimateScroll = 3\ninternal const val PagesToPrefetch = 1\n\nprivate val UnitDensity =\n    object : Density {\n        override val density: Float = 1f\n        override val fontScale: Float = 1f\n    }\n\ninternal val EmptyLayoutInfo =\n    PagerMeasureResult(\n        visiblePagesInfo = emptyList(),\n        pageSize = 0,\n        pageSpacing = 0,\n        afterContentPadding = 0,\n        orientation = Orientation.Horizontal,\n        viewportStartOffset = 0,\n        viewportEndOffset = 0,\n        reverseLayout = false,\n        beyondViewportPageCount = 0,\n        firstVisiblePage = null,\n        firstVisiblePageScrollOffset = 0,\n        currentPage = null,\n        currentPageOffsetFraction = 0.0f,\n        canScrollForward = false,\n        snapPosition = SnapPosition.Start,\n        measureResult =\n            object : MeasureResult {\n                override val width: Int = 0\n\n                override val height: Int = 0\n\n                @Suppress(\"PrimitiveInCollection\")\n                override val alignmentLines: Map<AlignmentLine, Int> = mapOf()\n\n                override fun placeChildren() {}\n            },\n        remeasureNeeded = false,\n        coroutineScope = CoroutineScope(EmptyCoroutineContext),\n        density = UnitDensity,\n        childConstraints = Constraints(),\n    )\n\nprivate inline fun debugLog(generateMsg: () -> String) {\n    if (PagerDebugConfig.PagerState) {\n        println(\"PagerState: ${generateMsg()}\")\n    }\n}\n\ninternal fun PagerLayoutInfo.calculateNewMaxScrollOffset(pageCount: Int): Long {\n    val pageSizeWithSpacing = pageSpacing + pageSize\n    val maxScrollPossible =\n        (pageCount.toLong()) * pageSizeWithSpacing + beforeContentPadding + afterContentPadding -\n            pageSpacing\n    val layoutSize =\n        if (orientation == Orientation.Horizontal) viewportSize.width else viewportSize.height\n\n    /**\n     * We need to take into consideration the snap position for max scroll position. For instance,\n     * if SnapPosition.Start, the max scroll position is pageCount * pageSize - viewport. Now if\n     * SnapPosition.End, it should be pageCount * pageSize. Therefore, the snap position discount\n     * varies between 0 and viewport.\n     */\n    val snapPositionDiscount =\n        layoutSize -\n            (snapPosition.position(\n                    layoutSize = layoutSize,\n                    itemSize = pageSize,\n                    itemIndex = pageCount - 1,\n                    beforeContentPadding = beforeContentPadding,\n                    afterContentPadding = afterContentPadding,\n                    itemCount = pageCount,\n                ))\n                .coerceIn(0, layoutSize)\n\n    debugLog {\n        \"maxScrollPossible=$maxScrollPossible\" +\n            \"\\nsnapPositionDiscount=$snapPositionDiscount\" +\n            \"\\nlayoutSize=$layoutSize\"\n    }\n    return (maxScrollPossible - snapPositionDiscount).coerceAtLeast(0L)\n}\n\nprivate fun PagerMeasureResult.calculateNewMinScrollOffset(pageCount: Int): Long {\n    val layoutSize =\n        if (orientation == Orientation.Horizontal) viewportSize.width else viewportSize.height\n\n    return snapPosition\n        .position(\n            layoutSize = layoutSize,\n            itemSize = pageSize,\n            itemIndex = 0,\n            beforeContentPadding = beforeContentPadding,\n            afterContentPadding = afterContentPadding,\n            itemCount = pageCount,\n        )\n        .coerceIn(0, layoutSize)\n        .toLong()\n}\n\nprivate suspend fun LazyLayoutScrollScope.animateScrollToPage(\n    targetPage: Int,\n    targetPageOffsetToSnappedPosition: Float,\n    animationSpec: AnimationSpec<Float>,\n    updateTargetPage: ScrollScope.(Int) -> Unit,\n) {\n    updateTargetPage(targetPage)\n    val forward = targetPage > firstVisibleItemIndex\n    val visiblePages = lastVisibleItemIndex - firstVisibleItemIndex + 1\n    if (\n        ((forward && targetPage > lastVisibleItemIndex) ||\n            (!forward && targetPage < firstVisibleItemIndex)) &&\n            abs(targetPage - firstVisibleItemIndex) >= MaxPagesForAnimateScroll\n    ) {\n        val preJumpPosition =\n            if (forward) {\n                (targetPage - visiblePages).coerceAtLeast(firstVisibleItemIndex)\n            } else {\n                (targetPage + visiblePages).coerceAtMost(firstVisibleItemIndex)\n            }\n\n        debugLog { \"animateScrollToPage with pre-jump to position=$preJumpPosition\" }\n\n        // Pre-jump to 1 viewport away from destination page, if possible\n        snapToItem(preJumpPosition, 0)\n    }\n\n    // The final delta displacement will be the difference between the pages offsets\n    // discounting whatever offset the original page had scrolled plus the offset\n    // fraction requested by the user.\n    val displacement = calculateDistanceTo(targetPage) + targetPageOffsetToSnappedPosition\n\n    debugLog { \"animateScrollToPage $displacement pixels\" }\n    var previousValue = 0f\n    animate(0f, displacement, animationSpec = animationSpec) { currentValue, _ ->\n        val delta = currentValue - previousValue\n        val consumed = scrollBy(delta)\n        debugLog { \"Dispatched Delta=$delta Consumed=$consumed\" }\n        previousValue += consumed\n    }\n}\n```\n\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/source-code/material3-source.md",
    "content": "# Compose Material3 Source Reference\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/MaterialTheme.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.foundation.LocalIndication\nimport androidx.compose.foundation.text.selection.LocalTextSelectionColors\nimport androidx.compose.foundation.text.selection.TextSelectionColors\nimport androidx.compose.material3.MotionScheme.Companion.standard\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocal\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.ProvidableCompositionLocal\nimport androidx.compose.runtime.ReadOnlyComposable\nimport androidx.compose.runtime.compositionLocalWithComputedDefaultOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.staticCompositionLocalOf\n\n/**\n * Material Theming refers to the customization of your Material Design app to better reflect your\n * product’s brand.\n *\n * Material components such as [Button] and [Checkbox] use values provided here when retrieving\n * default values.\n *\n * All values may be set by providing this component with the [colorScheme][ColorScheme],\n * [typography][Typography] and [shapes][Shapes] attributes. Use this to configure the overall theme\n * of elements within this MaterialTheme.\n *\n * Any values that are not set will inherit the current value from the theme, falling back to the\n * defaults if there is no parent MaterialTheme. This allows using a MaterialTheme at the top of\n * your application, and then separate MaterialTheme(s) for different screens / parts of your UI,\n * overriding only the parts of the theme definition that need to change.\n *\n * @sample androidx.compose.material3.samples.MaterialThemeSample\n * @param colorScheme A complete definition of the Material Color theme for this hierarchy\n * @param shapes A set of corner shapes to be used as this hierarchy's shape system\n * @param typography A set of text styles to be used as this hierarchy's typography system\n * @param content The content inheriting this theme\n */\n@Composable\nfun MaterialTheme(\n    colorScheme: ColorScheme = MaterialTheme.colorScheme,\n    shapes: Shapes = MaterialTheme.shapes,\n    typography: Typography = MaterialTheme.typography,\n    content: @Composable () -> Unit,\n) =\n    MaterialTheme(\n        colorScheme = colorScheme,\n        motionScheme = MaterialTheme.motionScheme,\n        shapes = shapes,\n        typography = typography,\n        content = content,\n    )\n\n/**\n * Material Theming refers to the customization of your Material Design app to better reflect your\n * product’s brand.\n *\n * Material components such as [Button] and [Checkbox] use values provided here when retrieving\n * default values.\n *\n * All values may be set by providing this component with the [colorScheme][ColorScheme],\n * [typography][Typography] attributes. Use this to configure the overall theme of elements within\n * this MaterialTheme.\n *\n * Any values that are not set will inherit the current value from the theme, falling back to the\n * defaults if there is no parent MaterialTheme. This allows using a MaterialTheme at the top of\n * your application, and then separate MaterialTheme(s) for different screens / parts of your UI,\n * overriding only the parts of the theme definition that need to change.\n *\n * @param colorScheme A complete definition of the Material Color theme for this hierarchy\n * @param motionScheme A complete definition of the Material Motion scheme for this hierarchy\n * @param shapes A set of corner shapes to be used as this hierarchy's shape system\n * @param typography A set of text styles to be used as this hierarchy's typography system\n */\n@Composable\nfun MaterialTheme(\n    colorScheme: ColorScheme = MaterialTheme.colorScheme,\n    motionScheme: MotionScheme = MaterialTheme.motionScheme,\n    shapes: Shapes = MaterialTheme.shapes,\n    typography: Typography = MaterialTheme.typography,\n    content: @Composable () -> Unit,\n) {\n    val theme =\n        MaterialTheme.Values(\n            colorScheme = colorScheme,\n            motionScheme = motionScheme,\n            shapes = shapes,\n            typography = typography,\n        )\n    val rippleIndication = ripple()\n    val selectionColors = rememberTextSelectionColors(colorScheme)\n    CompositionLocalProvider(\n        _localMaterialTheme provides theme,\n        LocalIndication provides rippleIndication,\n        LocalTextSelectionColors provides selectionColors,\n    ) {\n        EnsurePrecisionPointerListenersRegistered {\n            ProvideTextStyle(value = typography.bodyLarge, content = content)\n        }\n    }\n}\n\n/**\n * Contains functions to access the current theme values provided at the call site's position in the\n * hierarchy.\n */\nobject MaterialTheme {\n\n    /**\n     * Retrieves the current [ColorScheme] at the call site's position in the hierarchy.\n     *\n     * @sample androidx.compose.material3.samples.ThemeColorSample\n     */\n    val colorScheme: ColorScheme\n        @Composable @ReadOnlyComposable get() = LocalMaterialTheme.current.colorScheme\n\n    /**\n     * Retrieves the current [Typography] at the call site's position in the hierarchy.\n     *\n     * @sample androidx.compose.material3.samples.ThemeTextStyleSample\n     */\n    val typography: Typography\n        @Composable @ReadOnlyComposable get() = LocalMaterialTheme.current.typography\n\n    /**\n     * Retrieves the current [Shapes] at the call site's position in the hierarchy.\n     *\n     * @sample androidx.compose.material3.samples.ThemeShapeSample\n     */\n    val shapes: Shapes\n        @Composable @ReadOnlyComposable get() = LocalMaterialTheme.current.shapes\n\n    /** Retrieves the current [MotionScheme] at the call site's position in the hierarchy. */\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    val motionScheme: MotionScheme\n        @Composable @ReadOnlyComposable get() = LocalMaterialTheme.current.motionScheme\n\n    /**\n     * [CompositionLocal] providing [MaterialThemeSubsystems] throughout the hierarchy. You can use\n     * properties in the companion object to access specific subsystems, for example [colorScheme].\n     * To provide a new value for this, use [MaterialTheme]. This API is exposed to allow retrieving\n     * values from inside CompositionLocalConsumerModifierNode implementations - in most cases you\n     * should use [colorScheme] and other properties directly.\n     */\n    val LocalMaterialTheme: CompositionLocal<Values>\n        get() = _localMaterialTheme\n\n    /**\n     * A read-only `CompositionLocal` that provides the current [MotionScheme] to Material 3\n     * components.\n     *\n     * The motion scheme is typically supplied by [MaterialTheme.motionScheme] and can be overridden\n     * for specific UI subtrees by wrapping it with another [MaterialTheme].\n     *\n     * This API is exposed to allow retrieving motion values from inside\n     * `CompositionLocalConsumerModifierNode` implementations, but in most cases it's recommended to\n     * read the motion values from [MaterialTheme.motionScheme].\n     */\n    @Suppress(\"ExperimentalPropertyAnnotation\")\n    @ExperimentalMaterial3ExpressiveApi\n    @Deprecated(\n        level = DeprecationLevel.WARNING,\n        message = \"Use [LocalMaterialTheme.current.motionScheme] instead\",\n    )\n    val LocalMotionScheme: CompositionLocal<MotionScheme>\n        get() = compositionLocalWithComputedDefaultOf {\n            LocalMaterialTheme.currentValue.motionScheme\n        }\n\n    /**\n     * Material 3 contains different theme subsystems to allow visual customization across a UI\n     * hierarchy.\n     *\n     * Components use properties provided here when retrieving default values.\n     *\n     * @property colorScheme [ColorScheme] used by material components\n     * @property typography [Typography] used by material components\n     * @property shapes [Shapes] used by material components\n     * @property motionScheme [MotionScheme] used by material components\n     */\n    @Immutable\n    class Values(\n        val colorScheme: ColorScheme = lightColorScheme(),\n        val typography: Typography = Typography(),\n        val shapes: Shapes = Shapes(),\n        val motionScheme: MotionScheme = standard(),\n    ) {\n        override fun equals(other: Any?): Boolean {\n            if (this === other) return true\n            if (other == null || this::class != other::class) return false\n\n            other as Values\n\n            if (colorScheme != other.colorScheme) return false\n            if (typography != other.typography) return false\n            if (shapes != other.shapes) return false\n            if (motionScheme != other.motionScheme) return false\n\n            return true\n        }\n\n        override fun hashCode(): Int {\n            var result = colorScheme.hashCode()\n            result = 31 * result + typography.hashCode()\n            result = 31 * result + shapes.hashCode()\n            result = 31 * result + motionScheme.hashCode()\n            return result\n        }\n\n        override fun toString(): String {\n            return \"Values(colorScheme=$colorScheme, \" +\n                \"typography=$typography, shapes=$shapes, motionScheme=$motionScheme)\"\n        }\n    }\n}\n\n/**\n * Material Expressive Theming refers to the customization of your Material Design app to better\n * reflect your product’s brand.\n *\n * Material components such as [Button] and [Checkbox] use values provided here when retrieving\n * default values.\n *\n * All values may be set by providing this component with the [colorScheme][ColorScheme],\n * [typography][Typography], [shapes][Shapes] attributes. Use this to configure the overall theme of\n * elements within this MaterialTheme.\n *\n * Any values that are not set will fall back to the defaults. To inherit the current value from the\n * theme, pass them into subsequent calls and override only the parts of the theme definition that\n * need to change.\n *\n * Alternatively, only call this function at the top of your application, and then call\n * [MaterialTheme] to specify separate MaterialTheme(s) for different screens / parts of your UI,\n * overriding only the parts of the theme definition that need to change.\n *\n * @sample androidx.compose.material3.samples.MaterialExpressiveThemeSample\n * @param colorScheme A complete definition of the Material Color theme for this hierarchy\n * @param motionScheme A complete definition of the Material motion theme for this hierarchy\n * @param shapes A set of corner shapes to be used as this hierarchy's shape system\n * @param typography A set of text styles to be used as this hierarchy's typography system\n * @param content The content inheriting this theme\n */\n@ExperimentalMaterial3ExpressiveApi\n@Composable\nfun MaterialExpressiveTheme(\n    colorScheme: ColorScheme? = null,\n    motionScheme: MotionScheme? = null,\n    shapes: Shapes? = null,\n    typography: Typography? = null,\n    content: @Composable () -> Unit,\n) {\n    if (LocalUsingExpressiveTheme.current) {\n        MaterialTheme(\n            colorScheme = colorScheme ?: MaterialTheme.colorScheme,\n            motionScheme = motionScheme ?: MaterialTheme.motionScheme,\n            typography = typography ?: MaterialTheme.typography,\n            shapes = shapes ?: MaterialTheme.shapes,\n            content = content,\n        )\n    } else {\n        CompositionLocalProvider(LocalUsingExpressiveTheme provides true) {\n            MaterialTheme(\n                colorScheme = colorScheme ?: expressiveLightColorScheme(),\n                motionScheme = motionScheme ?: MotionScheme.expressive(),\n                shapes = shapes ?: Shapes(),\n                // TODO: replace with calls to Expressive typography default\n                typography = typography ?: Typography(),\n                content = content,\n            )\n        }\n    }\n}\n\ninternal val LocalUsingExpressiveTheme = staticCompositionLocalOf { false }\n\n@Composable\n/*@VisibleForTesting*/\ninternal fun rememberTextSelectionColors(colorScheme: ColorScheme): TextSelectionColors {\n    val primaryColor = colorScheme.primary\n    return remember(primaryColor) {\n        TextSelectionColors(\n            handleColor = primaryColor,\n            backgroundColor = primaryColor.copy(alpha = TextSelectionBackgroundOpacity),\n        )\n    }\n}\n\n/*@VisibleForTesting*/\ninternal const val TextSelectionBackgroundOpacity = 0.4f\n\n/** Use [MaterialTheme.LocalMaterialTheme] to access this publicly. */\n@Suppress(\"CompositionLocalNaming\")\nprivate val _localMaterialTheme: ProvidableCompositionLocal<MaterialTheme.Values> =\n    staticCompositionLocalOf {\n        MaterialTheme.Values()\n    }\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ColorScheme.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.material3.tokens.ColorDarkTokens\nimport androidx.compose.material3.tokens.ColorLightTokens\nimport androidx.compose.material3.tokens.ColorSchemeKeyTokens\nimport androidx.compose.material3.tokens.PaletteTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.ReadOnlyComposable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.staticCompositionLocalOf\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport kotlin.math.ln\n\n/**\n * A color scheme holds all the named color parameters for a [MaterialTheme].\n *\n * Color schemes are designed to be harmonious, ensure accessible text, and distinguish UI elements\n * and surfaces from one another. There are two built-in baseline schemes, [lightColorScheme] and a\n * [darkColorScheme], that can be used as-is or customized.\n *\n * The Material color system and custom schemes provide default values for color as a starting point\n * for customization.\n *\n * To learn more about colors, see\n * [Material Design colors](https://m3.material.io/styles/color/system/overview).\n *\n * @property primary The primary color is the color displayed most frequently across your app’s\n *   screens and components.\n * @property onPrimary Color used for text and icons displayed on top of the primary color.\n * @property primaryContainer The preferred tonal color of containers.\n * @property onPrimaryContainer The color (and state variants) that should be used for content on\n *   top of [primaryContainer].\n * @property inversePrimary Color to be used as a \"primary\" color in places where the inverse color\n *   scheme is needed, such as the button on a SnackBar.\n * @property secondary The secondary color provides more ways to accent and distinguish your\n *   product. Secondary colors are best for:\n * - Floating action buttons\n * - Selection controls, like checkboxes and radio buttons\n * - Highlighting selected text\n * - Links and headlines\n *\n * @property onSecondary Color used for text and icons displayed on top of the secondary color.\n * @property secondaryContainer A tonal color to be used in containers.\n * @property onSecondaryContainer The color (and state variants) that should be used for content on\n *   top of [secondaryContainer].\n * @property tertiary The tertiary color that can be used to balance primary and secondary colors,\n *   or bring heightened attention to an element such as an input field.\n * @property onTertiary Color used for text and icons displayed on top of the tertiary color.\n * @property tertiaryContainer A tonal color to be used in containers.\n * @property onTertiaryContainer The color (and state variants) that should be used for content on\n *   top of [tertiaryContainer].\n * @property background The background color that appears behind scrollable content.\n * @property onBackground Color used for text and icons displayed on top of the background color.\n * @property surface The surface color that affect surfaces of components, such as cards, sheets,\n *   and menus.\n * @property onSurface Color used for text and icons displayed on top of the surface color.\n * @property surfaceVariant Another option for a color with similar uses of [surface].\n * @property onSurfaceVariant The color (and state variants) that can be used for content on top of\n *   [surface].\n * @property surfaceTint This color will be used by components that apply tonal elevation and is\n *   applied on top of [surface]. The higher the elevation the more this color is used.\n * @property inverseSurface A color that contrasts sharply with [surface]. Useful for surfaces that\n *   sit on top of other surfaces with [surface] color.\n * @property inverseOnSurface A color that contrasts well with [inverseSurface]. Useful for content\n *   that sits on top of containers that are [inverseSurface].\n * @property error The error color is used to indicate errors in components, such as invalid text in\n *   a text field.\n * @property onError Color used for text and icons displayed on top of the error color.\n * @property errorContainer The preferred tonal color of error containers.\n * @property onErrorContainer The color (and state variants) that should be used for content on top\n *   of [errorContainer].\n * @property outline Subtle color used for boundaries. Outline color role adds contrast for\n *   accessibility purposes.\n * @property outlineVariant Utility color used for boundaries for decorative elements when strong\n *   contrast is not required.\n * @property scrim Color of a scrim that obscures content.\n * @property surfaceBright A [surface] variant that is always brighter than [surface], whether in\n *   light or dark mode.\n * @property surfaceDim A [surface] variant that is always dimmer than [surface], whether in light\n *   or dark mode.\n * @property surfaceContainer A [surface] variant that affects containers of components, such as\n *   cards, sheets, and menus.\n * @property surfaceContainerHigh A [surface] variant for containers with higher emphasis than\n *   [surfaceContainer]. Use this role for content which requires more emphasis than\n *   [surfaceContainer].\n * @property surfaceContainerHighest A [surface] variant for containers with higher emphasis than\n *   [surfaceContainerHigh]. Use this role for content which requires more emphasis than\n *   [surfaceContainerHigh].\n * @property surfaceContainerLow A [surface] variant for containers with lower emphasis than\n *   [surfaceContainer]. Use this role for content which requires less emphasis than\n *   [surfaceContainer].\n * @property surfaceContainerLowest A [surface] variant for containers with lower emphasis than\n *   [surfaceContainerLow]. Use this role for content which requires less emphasis than\n *   [surfaceContainerLow].\n * @property primaryFixed A [primary] variant that maintains the same tone in light and dark themes.\n *   The fixed color role may be used instead of the equivalent container role in situations where\n *   such fixed behavior is desired.\n * @property primaryFixedDim A [primary] variant that maintains the same tone in light and dark\n *   themes. Dim roles provide a stronger, more emphasized tone relative to the equivalent fixed\n *   color.\n * @property onPrimaryFixed Color used for text and icons displayed on top of [primaryFixed] or\n *   [primaryFixedDim]. Maintains the same tone in light and dark themes.\n * @property onPrimaryFixedVariant An [onPrimaryFixed] variant which provides less emphasis. Useful\n *   when a strong contrast is not required.\n * @property secondaryFixed A [secondary] variant that maintains the same tone in light and dark\n *   themes. The fixed color role may be used instead of the equivalent container role in situations\n *   where such fixed behavior is desired.\n * @property secondaryFixedDim A [secondary] variant that maintains the same tone in light and dark\n *   themes. Dim roles provide a stronger, more emphasized tone relative to the equivalent fixed\n *   color.\n * @property onSecondaryFixed Color used for text and icons displayed on top of [secondaryFixed] or\n *   [secondaryFixedDim]. Maintains the same tone in light and dark themes.\n * @property onSecondaryFixedVariant An [onSecondaryFixed] variant which provides less emphasis.\n *   Useful when a strong contrast is not required.\n * @property tertiaryFixed A [tertiary] variant that maintains the same tone in light and dark\n *   themes. The fixed color role may be used instead of the equivalent container role in situations\n *   where such fixed behavior is desired.\n * @property tertiaryFixedDim A [tertiary] variant that maintains the same tone in light and dark\n *   themes. Dim roles provide a stronger, more emphasized tone relative to the equivalent fixed\n *   color.\n * @property onTertiaryFixed Color used for text and icons displayed on top of [tertiaryFixed] or\n *   [tertiaryFixedDim]. Maintains the same tone in light and dark themes.\n * @property onTertiaryFixedVariant An [onTertiaryFixed] variant which provides less emphasis.\n *   Useful when a strong contrast is not required.\n */\n@Immutable\nclass ColorScheme(\n    val primary: Color,\n    val onPrimary: Color,\n    val primaryContainer: Color,\n    val onPrimaryContainer: Color,\n    val inversePrimary: Color,\n    val secondary: Color,\n    val onSecondary: Color,\n    val secondaryContainer: Color,\n    val onSecondaryContainer: Color,\n    val tertiary: Color,\n    val onTertiary: Color,\n    val tertiaryContainer: Color,\n    val onTertiaryContainer: Color,\n    val background: Color,\n    val onBackground: Color,\n    val surface: Color,\n    val onSurface: Color,\n    val surfaceVariant: Color,\n    val onSurfaceVariant: Color,\n    val surfaceTint: Color,\n    val inverseSurface: Color,\n    val inverseOnSurface: Color,\n    val error: Color,\n    val onError: Color,\n    val errorContainer: Color,\n    val onErrorContainer: Color,\n    val outline: Color,\n    val outlineVariant: Color,\n    val scrim: Color,\n    val surfaceBright: Color,\n    val surfaceDim: Color,\n    val surfaceContainer: Color,\n    val surfaceContainerHigh: Color,\n    val surfaceContainerHighest: Color,\n    val surfaceContainerLow: Color,\n    val surfaceContainerLowest: Color,\n    val primaryFixed: Color,\n    val primaryFixedDim: Color,\n    val onPrimaryFixed: Color,\n    val onPrimaryFixedVariant: Color,\n    val secondaryFixed: Color,\n    val secondaryFixedDim: Color,\n    val onSecondaryFixed: Color,\n    val onSecondaryFixedVariant: Color,\n    val tertiaryFixed: Color,\n    val tertiaryFixedDim: Color,\n    val onTertiaryFixed: Color,\n    val onTertiaryFixedVariant: Color,\n) {\n    @Deprecated(\n        level = DeprecationLevel.WARNING,\n        message = \"Use constructor with additional 'fixed' container roles.\",\n        replaceWith =\n            ReplaceWith(\n                \"ColorScheme(primary,\\n\" +\n                    \"onPrimary,\\n\" +\n                    \"primaryContainer,\\n\" +\n                    \"onPrimaryContainer,\\n\" +\n                    \"inversePrimary,\\n\" +\n                    \"secondary,\\n\" +\n                    \"onSecondary,\\n\" +\n                    \"secondaryContainer,\\n\" +\n                    \"onSecondaryContainer,\\n\" +\n                    \"tertiary,\\n\" +\n                    \"onTertiary,\\n\" +\n                    \"tertiaryContainer,\\n\" +\n                    \"onTertiaryContainer,\\n\" +\n                    \"background,\\n\" +\n                    \"onBackground,\\n\" +\n                    \"surface,\\n\" +\n                    \"onSurface,\\n\" +\n                    \"surfaceVariant,\\n\" +\n                    \"onSurfaceVariant,\\n\" +\n                    \"surfaceTint,\\n\" +\n                    \"inverseSurface,\\n\" +\n                    \"inverseOnSurface,\\n\" +\n                    \"error,\\n\" +\n                    \"onError,\\n\" +\n                    \"errorContainer,\\n\" +\n                    \"onErrorContainer,\\n\" +\n                    \"outline,\\n\" +\n                    \"outlineVariant,\\n\" +\n                    \"scrim,\\n\" +\n                    \"surfaceBright,\\n\" +\n                    \"surfaceDim,\\n\" +\n                    \"surfaceContainer,\\n\" +\n                    \"surfaceContainerHigh,\\n\" +\n                    \"surfaceContainerHighest,\\n\" +\n                    \"surfaceContainerLow,\\n\" +\n                    \"surfaceContainerLowest,)\"\n            ),\n    )\n    constructor(\n        primary: Color,\n        onPrimary: Color,\n        primaryContainer: Color,\n        onPrimaryContainer: Color,\n        inversePrimary: Color,\n        secondary: Color,\n        onSecondary: Color,\n        secondaryContainer: Color,\n        onSecondaryContainer: Color,\n        tertiary: Color,\n        onTertiary: Color,\n        tertiaryContainer: Color,\n        onTertiaryContainer: Color,\n        background: Color,\n        onBackground: Color,\n        surface: Color,\n        onSurface: Color,\n        surfaceVariant: Color,\n        onSurfaceVariant: Color,\n        surfaceTint: Color,\n        inverseSurface: Color,\n        inverseOnSurface: Color,\n        error: Color,\n        onError: Color,\n        errorContainer: Color,\n        onErrorContainer: Color,\n        outline: Color,\n        outlineVariant: Color,\n        scrim: Color,\n        surfaceBright: Color,\n        surfaceDim: Color,\n        surfaceContainer: Color,\n        surfaceContainerHigh: Color,\n        surfaceContainerHighest: Color,\n        surfaceContainerLow: Color,\n        surfaceContainerLowest: Color,\n    ) : this(\n        primary = primary,\n        onPrimary = onPrimary,\n        primaryContainer = primaryContainer,\n        onPrimaryContainer = onPrimaryContainer,\n        inversePrimary = inversePrimary,\n        secondary = secondary,\n        onSecondary = onSecondary,\n        secondaryContainer = secondaryContainer,\n        onSecondaryContainer = onSecondaryContainer,\n        tertiary = tertiary,\n        onTertiary = onTertiary,\n        tertiaryContainer = tertiaryContainer,\n        onTertiaryContainer = onTertiaryContainer,\n        background = background,\n        onBackground = onBackground,\n        surface = surface,\n        onSurface = onSurface,\n        surfaceVariant = surfaceVariant,\n        onSurfaceVariant = onSurfaceVariant,\n        surfaceTint = surfaceTint,\n        inverseSurface = inverseSurface,\n        inverseOnSurface = inverseOnSurface,\n        error = error,\n        onError = onError,\n        errorContainer = errorContainer,\n        onErrorContainer = onErrorContainer,\n        outline = outline,\n        outlineVariant = outlineVariant,\n        scrim = scrim,\n        surfaceBright = surfaceBright,\n        surfaceDim = surfaceDim,\n        surfaceContainer = surfaceContainer,\n        surfaceContainerHigh = surfaceContainerHigh,\n        surfaceContainerHighest = surfaceContainerHighest,\n        surfaceContainerLow = surfaceContainerLow,\n        surfaceContainerLowest = surfaceContainerLowest,\n        primaryFixed = Color.Unspecified,\n        primaryFixedDim = Color.Unspecified,\n        onPrimaryFixed = Color.Unspecified,\n        onPrimaryFixedVariant = Color.Unspecified,\n        secondaryFixed = Color.Unspecified,\n        secondaryFixedDim = Color.Unspecified,\n        onSecondaryFixed = Color.Unspecified,\n        onSecondaryFixedVariant = Color.Unspecified,\n        tertiaryFixed = Color.Unspecified,\n        tertiaryFixedDim = Color.Unspecified,\n        onTertiaryFixed = Color.Unspecified,\n        onTertiaryFixedVariant = Color.Unspecified,\n    )\n\n    /** Returns a copy of this ColorScheme, optionally overriding some of the values. */\n    fun copy(\n        primary: Color = this.primary,\n        onPrimary: Color = this.onPrimary,\n        primaryContainer: Color = this.primaryContainer,\n        onPrimaryContainer: Color = this.onPrimaryContainer,\n        inversePrimary: Color = this.inversePrimary,\n        secondary: Color = this.secondary,\n        onSecondary: Color = this.onSecondary,\n        secondaryContainer: Color = this.secondaryContainer,\n        onSecondaryContainer: Color = this.onSecondaryContainer,\n        tertiary: Color = this.tertiary,\n        onTertiary: Color = this.onTertiary,\n        tertiaryContainer: Color = this.tertiaryContainer,\n        onTertiaryContainer: Color = this.onTertiaryContainer,\n        background: Color = this.background,\n        onBackground: Color = this.onBackground,\n        surface: Color = this.surface,\n        onSurface: Color = this.onSurface,\n        surfaceVariant: Color = this.surfaceVariant,\n        onSurfaceVariant: Color = this.onSurfaceVariant,\n        surfaceTint: Color = this.surfaceTint,\n        inverseSurface: Color = this.inverseSurface,\n        inverseOnSurface: Color = this.inverseOnSurface,\n        error: Color = this.error,\n        onError: Color = this.onError,\n        errorContainer: Color = this.errorContainer,\n        onErrorContainer: Color = this.onErrorContainer,\n        outline: Color = this.outline,\n        outlineVariant: Color = this.outlineVariant,\n        scrim: Color = this.scrim,\n        surfaceBright: Color = this.surfaceBright,\n        surfaceDim: Color = this.surfaceDim,\n        surfaceContainer: Color = this.surfaceContainer,\n        surfaceContainerHigh: Color = this.surfaceContainerHigh,\n        surfaceContainerHighest: Color = this.surfaceContainerHighest,\n        surfaceContainerLow: Color = this.surfaceContainerLow,\n        surfaceContainerLowest: Color = this.surfaceContainerLowest,\n        primaryFixed: Color = this.primaryFixed,\n        primaryFixedDim: Color = this.primaryFixedDim,\n        onPrimaryFixed: Color = this.onPrimaryFixed,\n        onPrimaryFixedVariant: Color = this.onPrimaryFixedVariant,\n        secondaryFixed: Color = this.secondaryFixed,\n        secondaryFixedDim: Color = this.secondaryFixedDim,\n        onSecondaryFixed: Color = this.onSecondaryFixed,\n        onSecondaryFixedVariant: Color = this.onSecondaryFixedVariant,\n        tertiaryFixed: Color = this.tertiaryFixed,\n        tertiaryFixedDim: Color = this.tertiaryFixedDim,\n        onTertiaryFixed: Color = this.onTertiaryFixed,\n        onTertiaryFixedVariant: Color = this.onTertiaryFixedVariant,\n    ): ColorScheme =\n        ColorScheme(\n            primary = primary,\n            onPrimary = onPrimary,\n            primaryContainer = primaryContainer,\n            onPrimaryContainer = onPrimaryContainer,\n            inversePrimary = inversePrimary,\n            secondary = secondary,\n            onSecondary = onSecondary,\n            secondaryContainer = secondaryContainer,\n            onSecondaryContainer = onSecondaryContainer,\n            tertiary = tertiary,\n            onTertiary = onTertiary,\n            tertiaryContainer = tertiaryContainer,\n            onTertiaryContainer = onTertiaryContainer,\n            background = background,\n            onBackground = onBackground,\n            surface = surface,\n            onSurface = onSurface,\n            surfaceVariant = surfaceVariant,\n            onSurfaceVariant = onSurfaceVariant,\n            surfaceTint = surfaceTint,\n            inverseSurface = inverseSurface,\n            inverseOnSurface = inverseOnSurface,\n            error = error,\n            onError = onError,\n            errorContainer = errorContainer,\n            onErrorContainer = onErrorContainer,\n            outline = outline,\n            outlineVariant = outlineVariant,\n            scrim = scrim,\n            surfaceBright = surfaceBright,\n            surfaceDim = surfaceDim,\n            surfaceContainer = surfaceContainer,\n            surfaceContainerHigh = surfaceContainerHigh,\n            surfaceContainerHighest = surfaceContainerHighest,\n            surfaceContainerLow = surfaceContainerLow,\n            surfaceContainerLowest = surfaceContainerLowest,\n            primaryFixed = primaryFixed,\n            primaryFixedDim = primaryFixedDim,\n            onPrimaryFixed = onPrimaryFixed,\n            onPrimaryFixedVariant = onPrimaryFixedVariant,\n            secondaryFixed = secondaryFixed,\n            secondaryFixedDim = secondaryFixedDim,\n            onSecondaryFixed = onSecondaryFixed,\n            onSecondaryFixedVariant = onSecondaryFixedVariant,\n            tertiaryFixed = tertiaryFixed,\n            tertiaryFixedDim = tertiaryFixedDim,\n            onTertiaryFixed = onTertiaryFixed,\n            onTertiaryFixedVariant = onTertiaryFixedVariant,\n        )\n\n    @Deprecated(\n        message =\n            \"Maintained for binary compatibility. Use overload with additional fixed roles \" +\n                \"instead\",\n        level = DeprecationLevel.HIDDEN,\n    )\n    fun copy(\n        primary: Color = this.primary,\n        onPrimary: Color = this.onPrimary,\n        primaryContainer: Color = this.primaryContainer,\n        onPrimaryContainer: Color = this.onPrimaryContainer,\n        inversePrimary: Color = this.inversePrimary,\n        secondary: Color = this.secondary,\n        onSecondary: Color = this.onSecondary,\n        secondaryContainer: Color = this.secondaryContainer,\n        onSecondaryContainer: Color = this.onSecondaryContainer,\n        tertiary: Color = this.tertiary,\n        onTertiary: Color = this.onTertiary,\n        tertiaryContainer: Color = this.tertiaryContainer,\n        onTertiaryContainer: Color = this.onTertiaryContainer,\n        background: Color = this.background,\n        onBackground: Color = this.onBackground,\n        surface: Color = this.surface,\n        onSurface: Color = this.onSurface,\n        surfaceVariant: Color = this.surfaceVariant,\n        onSurfaceVariant: Color = this.onSurfaceVariant,\n        surfaceTint: Color = this.surfaceTint,\n        inverseSurface: Color = this.inverseSurface,\n        inverseOnSurface: Color = this.inverseOnSurface,\n        error: Color = this.error,\n        onError: Color = this.onError,\n        errorContainer: Color = this.errorContainer,\n        onErrorContainer: Color = this.onErrorContainer,\n        outline: Color = this.outline,\n        outlineVariant: Color = this.outlineVariant,\n        scrim: Color = this.scrim,\n    ): ColorScheme =\n        copy(\n            primary = primary,\n            onPrimary = onPrimary,\n            primaryContainer = primaryContainer,\n            onPrimaryContainer = onPrimaryContainer,\n            inversePrimary = inversePrimary,\n            secondary = secondary,\n            onSecondary = onSecondary,\n            secondaryContainer = secondaryContainer,\n            onSecondaryContainer = onSecondaryContainer,\n            tertiary = tertiary,\n            onTertiary = onTertiary,\n            tertiaryContainer = tertiaryContainer,\n            onTertiaryContainer = onTertiaryContainer,\n            background = background,\n            onBackground = onBackground,\n            surface = surface,\n            onSurface = onSurface,\n            surfaceVariant = surfaceVariant,\n            onSurfaceVariant = onSurfaceVariant,\n            surfaceTint = surfaceTint,\n            inverseSurface = inverseSurface,\n            inverseOnSurface = inverseOnSurface,\n            error = error,\n            onError = onError,\n            errorContainer = errorContainer,\n            onErrorContainer = onErrorContainer,\n            outline = outline,\n            outlineVariant = outlineVariant,\n            scrim = scrim,\n        )\n\n    @Deprecated(\n        message =\n            \"Maintained for binary compatibility. Use overload with additional fixed roles \" +\n                \"instead\",\n        level = DeprecationLevel.HIDDEN,\n    )\n    fun copy(\n        primary: Color = this.primary,\n        onPrimary: Color = this.onPrimary,\n        primaryContainer: Color = this.primaryContainer,\n        onPrimaryContainer: Color = this.onPrimaryContainer,\n        inversePrimary: Color = this.inversePrimary,\n        secondary: Color = this.secondary,\n        onSecondary: Color = this.onSecondary,\n        secondaryContainer: Color = this.secondaryContainer,\n        onSecondaryContainer: Color = this.onSecondaryContainer,\n        tertiary: Color = this.tertiary,\n        onTertiary: Color = this.onTertiary,\n        tertiaryContainer: Color = this.tertiaryContainer,\n        onTertiaryContainer: Color = this.onTertiaryContainer,\n        background: Color = this.background,\n        onBackground: Color = this.onBackground,\n        surface: Color = this.surface,\n        onSurface: Color = this.onSurface,\n        surfaceVariant: Color = this.surfaceVariant,\n        onSurfaceVariant: Color = this.onSurfaceVariant,\n        surfaceTint: Color = this.surfaceTint,\n        inverseSurface: Color = this.inverseSurface,\n        inverseOnSurface: Color = this.inverseOnSurface,\n        error: Color = this.error,\n        onError: Color = this.onError,\n        errorContainer: Color = this.errorContainer,\n        onErrorContainer: Color = this.onErrorContainer,\n        outline: Color = this.outline,\n        outlineVariant: Color = this.outlineVariant,\n        scrim: Color = this.scrim,\n        surfaceBright: Color = this.surfaceBright,\n        surfaceDim: Color = this.surfaceDim,\n        surfaceContainer: Color = this.surfaceContainer,\n        surfaceContainerHigh: Color = this.surfaceContainerHigh,\n        surfaceContainerHighest: Color = this.surfaceContainerHighest,\n        surfaceContainerLow: Color = this.surfaceContainerLow,\n        surfaceContainerLowest: Color = this.surfaceContainerLowest,\n    ): ColorScheme =\n        copy(\n            primary = primary,\n            onPrimary = onPrimary,\n            primaryContainer = primaryContainer,\n            onPrimaryContainer = onPrimaryContainer,\n            inversePrimary = inversePrimary,\n            secondary = secondary,\n            onSecondary = onSecondary,\n            secondaryContainer = secondaryContainer,\n            onSecondaryContainer = onSecondaryContainer,\n            tertiary = tertiary,\n            onTertiary = onTertiary,\n            tertiaryContainer = tertiaryContainer,\n            onTertiaryContainer = onTertiaryContainer,\n            background = background,\n            onBackground = onBackground,\n            surface = surface,\n            onSurface = onSurface,\n            surfaceVariant = surfaceVariant,\n            onSurfaceVariant = onSurfaceVariant,\n            surfaceTint = surfaceTint,\n            inverseSurface = inverseSurface,\n            inverseOnSurface = inverseOnSurface,\n            error = error,\n            onError = onError,\n            errorContainer = errorContainer,\n            onErrorContainer = onErrorContainer,\n            outline = outline,\n            outlineVariant = outlineVariant,\n            scrim = scrim,\n            surfaceBright = surfaceBright,\n            surfaceDim = surfaceDim,\n            surfaceContainer = surfaceContainer,\n            surfaceContainerHigh = surfaceContainerHigh,\n            surfaceContainerHighest = surfaceContainerHighest,\n            surfaceContainerLow = surfaceContainerLow,\n            surfaceContainerLowest = surfaceContainerLowest,\n        )\n\n    override fun toString(): String {\n        return \"ColorScheme(\" +\n            \"primary=$primary\" +\n            \"onPrimary=$onPrimary\" +\n            \"primaryContainer=$primaryContainer\" +\n            \"onPrimaryContainer=$onPrimaryContainer\" +\n            \"inversePrimary=$inversePrimary\" +\n            \"secondary=$secondary\" +\n            \"onSecondary=$onSecondary\" +\n            \"secondaryContainer=$secondaryContainer\" +\n            \"onSecondaryContainer=$onSecondaryContainer\" +\n            \"tertiary=$tertiary\" +\n            \"onTertiary=$onTertiary\" +\n            \"tertiaryContainer=$tertiaryContainer\" +\n            \"onTertiaryContainer=$onTertiaryContainer\" +\n            \"background=$background\" +\n            \"onBackground=$onBackground\" +\n            \"surface=$surface\" +\n            \"onSurface=$onSurface\" +\n            \"surfaceVariant=$surfaceVariant\" +\n            \"onSurfaceVariant=$onSurfaceVariant\" +\n            \"surfaceTint=$surfaceTint\" +\n            \"inverseSurface=$inverseSurface\" +\n            \"inverseOnSurface=$inverseOnSurface\" +\n            \"error=$error\" +\n            \"onError=$onError\" +\n            \"errorContainer=$errorContainer\" +\n            \"onErrorContainer=$onErrorContainer\" +\n            \"outline=$outline\" +\n            \"outlineVariant=$outlineVariant\" +\n            \"scrim=$scrim\" +\n            \"surfaceBright=$surfaceBright\" +\n            \"surfaceDim=$surfaceDim\" +\n            \"surfaceContainer=$surfaceContainer\" +\n            \"surfaceContainerHigh=$surfaceContainerHigh\" +\n            \"surfaceContainerHighest=$surfaceContainerHighest\" +\n            \"surfaceContainerLow=$surfaceContainerLow\" +\n            \"surfaceContainerLowest=$surfaceContainerLowest\" +\n            \"primaryFixed=$primaryFixed\" +\n            \"primaryFixedDim=$primaryFixedDim\" +\n            \"onPrimaryFixed=$onPrimaryContainer\" +\n            \"onPrimaryFixedVariant=$onPrimaryFixedVariant\" +\n            \"secondaryFixed=$secondaryFixed\" +\n            \"secondaryFixedDim=$secondaryFixedDim\" +\n            \"onSecondaryFixed=$onSecondaryFixed\" +\n            \"onSecondaryFixedVariant=$onSecondaryFixedVariant\" +\n            \"tertiaryFixed=$tertiaryFixed\" +\n            \"tertiaryFixedDim=$tertiaryFixedDim\" +\n            \"onTertiaryFixed=$onTertiaryFixed\" +\n            \"onTertiaryFixedVariant=$onTertiaryFixedVariant\" +\n            \")\"\n    }\n\n    internal var defaultButtonColorsCached: ButtonColors? = null\n    internal var defaultElevatedButtonColorsCached: ButtonColors? = null\n    internal var defaultFilledTonalButtonColorsCached: ButtonColors? = null\n    internal var defaultOutlinedButtonColorsCached: ButtonColors? = null\n    internal var defaultTextButtonColorsCached: ButtonColors? = null\n\n    internal var defaultCardColorsCached: CardColors? = null\n    internal var defaultElevatedCardColorsCached: CardColors? = null\n    internal var defaultOutlinedCardColorsCached: CardColors? = null\n\n    internal var defaultAssistChipColorsCached: ChipColors? = null\n    internal var defaultElevatedAssistChipColorsCached: ChipColors? = null\n    internal var defaultSuggestionChipColorsCached: ChipColors? = null\n    internal var defaultElevatedSuggestionChipColorsCached: ChipColors? = null\n    internal var defaultFilterChipColorsCached: SelectableChipColors? = null\n    internal var defaultElevatedFilterChipColorsCached: SelectableChipColors? = null\n    internal var defaultInputChipColorsCached: SelectableChipColors? = null\n\n    internal var defaultVerticalDragHandleColorsCached: DragHandleColors? = null\n\n    @OptIn(ExperimentalMaterial3Api::class)\n    internal var defaultTopAppBarColorsCached: TopAppBarColors? = null\n\n    internal var defaultCheckboxColorsCached: CheckboxColors? = null\n\n    @OptIn(ExperimentalMaterial3Api::class)\n    internal var defaultDatePickerColorsCached: DatePickerColors? = null\n\n    internal var defaultIconButtonColorsCached: IconButtonColors? = null\n    internal var defaultIconButtonVibrantColorsCached: IconButtonColors? = null\n    internal var defaultIconToggleButtonColorsCached: IconToggleButtonColors? = null\n    internal var defaultIconToggleButtonVibrantColorsCached: IconToggleButtonColors? = null\n    internal var defaultFilledIconButtonColorsCached: IconButtonColors? = null\n    internal var defaultFilledIconToggleButtonColorsCached: IconToggleButtonColors? = null\n    internal var defaultFilledTonalIconButtonColorsCached: IconButtonColors? = null\n    internal var defaultFilledTonalIconToggleButtonColorsCached: IconToggleButtonColors? = null\n    internal var defaultOutlinedIconButtonColorsCached: IconButtonColors? = null\n    internal var defaultOutlinedIconButtonVibrantColorsCached: IconButtonColors? = null\n    internal var defaultOutlinedIconToggleButtonColorsCached: IconToggleButtonColors? = null\n    internal var defaultOutlinedIconToggleButtonVibrantColorsCached: IconToggleButtonColors? = null\n\n    internal var defaultToggleButtonColorsCached: ToggleButtonColors? = null\n    internal var defaultElevatedToggleButtonColorsCached: ToggleButtonColors? = null\n    internal var defaultTonalToggleButtonColorsCached: ToggleButtonColors? = null\n    internal var defaultOutlinedToggleButtonColorsCached: ToggleButtonColors? = null\n\n    internal var defaultListItemColorsCached: ListItemColors? = null\n    internal var defaultSegmentedListItemColorsCached: ListItemColors? = null\n\n    internal var defaultMenuItemColorsCached: MenuItemColors? = null\n    internal var defaultMenuSelectableItemColorsCached: MenuItemColors? = null\n    internal var defaultMenuSelectableItemVibrantColorsCached: MenuItemColors? = null\n\n    internal var defaultNavigationBarItemColorsCached: NavigationBarItemColors? = null\n    internal var defaultShortNavigationBarItemColorsCached: NavigationItemColors? = null\n\n    internal var defaultNavigationRailItemColorsCached: NavigationRailItemColors? = null\n    internal var defaultWideWideNavigationRailColorsCached: WideNavigationRailColors? = null\n    internal var defaultWideNavigationRailItemColorsCached: NavigationItemColors? = null\n\n    internal var defaultRadioButtonColorsCached: RadioButtonColors? = null\n\n    internal var defaultSegmentedButtonColorsCached: SegmentedButtonColors? = null\n\n    internal var defaultSliderColorsCached: SliderColors? = null\n\n    internal var defaultSwitchColorsCached: SwitchColors? = null\n\n    internal var defaultOutlinedTextFieldColorsCached: TextFieldColors? = null\n    internal var defaultTextFieldColorsCached: TextFieldColors? = null\n\n    @OptIn(ExperimentalMaterial3Api::class)\n    internal var defaultTimePickerColorsCached: TimePickerColors? = null\n\n    @OptIn(ExperimentalMaterial3Api::class)\n    internal var defaultRichTooltipColorsCached: RichTooltipColors? = null\n\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultFloatingToolbarStandardColorsCached: FloatingToolbarColors? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultFloatingToolbarVibrantColorsCached: FloatingToolbarColors? = null\n\n    @Deprecated(\n        level = DeprecationLevel.WARNING,\n        message = \"Use constructor with additional 'surfaceContainer' roles.\",\n        replaceWith =\n            ReplaceWith(\n                \"ColorScheme(primary,\\n\" +\n                    \"onPrimary,\\n\" +\n                    \"primaryContainer,\\n\" +\n                    \"onPrimaryContainer,\\n\" +\n                    \"inversePrimary,\\n\" +\n                    \"secondary,\\n\" +\n                    \"onSecondary,\\n\" +\n                    \"secondaryContainer,\\n\" +\n                    \"onSecondaryContainer,\\n\" +\n                    \"tertiary,\\n\" +\n                    \"onTertiary,\\n\" +\n                    \"tertiaryContainer,\\n\" +\n                    \"onTertiaryContainer,\\n\" +\n                    \"background,\\n\" +\n                    \"onBackground,\\n\" +\n                    \"surface,\\n\" +\n                    \"onSurface,\\n\" +\n                    \"surfaceVariant,\\n\" +\n                    \"onSurfaceVariant,\\n\" +\n                    \"surfaceTint,\\n\" +\n                    \"inverseSurface,\\n\" +\n                    \"inverseOnSurface,\\n\" +\n                    \"error,\\n\" +\n                    \"onError,\\n\" +\n                    \"errorContainer,\\n\" +\n                    \"onErrorContainer,\\n\" +\n                    \"outline,\\n\" +\n                    \"outlineVariant,\\n\" +\n                    \"scrim,\\n\" +\n                    \"surfaceBright,\\n\" +\n                    \"surfaceDim,\\n\" +\n                    \"surfaceContainer,\\n\" +\n                    \"surfaceContainerHigh,\\n\" +\n                    \"surfaceContainerHighest,\\n\" +\n                    \"surfaceContainerLow,\\n\" +\n                    \"surfaceContainerLowest,\\n\" +\n                    \"primaryFixed,\\n\" +\n                    \"primaryFixedDim,\\n\" +\n                    \"onPrimaryFixed,\\n\" +\n                    \"onPrimaryFixedVariant,\\n\" +\n                    \"secondaryFixed,\\n\" +\n                    \"secondaryFixedDim,\\n\" +\n                    \"onSecondaryFixed,\\n\" +\n                    \"onSecondaryFixedVariant,\\n\" +\n                    \"tertiaryFixed,\\n\" +\n                    \"tertiaryFixedDim,\\n\" +\n                    \"onTertiaryFixed,\\n\" +\n                    \"onTertiaryFixedVariant\" +\n                    \")\"\n            ),\n    )\n    constructor(\n        primary: Color,\n        onPrimary: Color,\n        primaryContainer: Color,\n        onPrimaryContainer: Color,\n        inversePrimary: Color,\n        secondary: Color,\n        onSecondary: Color,\n        secondaryContainer: Color,\n        onSecondaryContainer: Color,\n        tertiary: Color,\n        onTertiary: Color,\n        tertiaryContainer: Color,\n        onTertiaryContainer: Color,\n        background: Color,\n        onBackground: Color,\n        surface: Color,\n        onSurface: Color,\n        surfaceVariant: Color,\n        onSurfaceVariant: Color,\n        surfaceTint: Color,\n        inverseSurface: Color,\n        inverseOnSurface: Color,\n        error: Color,\n        onError: Color,\n        errorContainer: Color,\n        onErrorContainer: Color,\n        outline: Color,\n        outlineVariant: Color,\n        scrim: Color,\n    ) : this(\n        primary = primary,\n        onPrimary = onPrimary,\n        primaryContainer = primaryContainer,\n        onPrimaryContainer = onPrimaryContainer,\n        inversePrimary = inversePrimary,\n        secondary = secondary,\n        onSecondary = onSecondary,\n        secondaryContainer = secondaryContainer,\n        onSecondaryContainer = onSecondaryContainer,\n        tertiary = tertiary,\n        onTertiary = onTertiary,\n        tertiaryContainer = tertiaryContainer,\n        onTertiaryContainer = onTertiaryContainer,\n        background = background,\n        onBackground = onBackground,\n        surface = surface,\n        onSurface = onSurface,\n        surfaceVariant = surfaceVariant,\n        onSurfaceVariant = onSurfaceVariant,\n        surfaceTint = surfaceTint,\n        inverseSurface = inverseSurface,\n        inverseOnSurface = inverseOnSurface,\n        error = error,\n        onError = onError,\n        errorContainer = errorContainer,\n        onErrorContainer = onErrorContainer,\n        outline = outline,\n        outlineVariant = outlineVariant,\n        scrim = scrim,\n        surfaceBright = Color.Unspecified,\n        surfaceDim = Color.Unspecified,\n        surfaceContainer = Color.Unspecified,\n        surfaceContainerHigh = Color.Unspecified,\n        surfaceContainerHighest = Color.Unspecified,\n        surfaceContainerLow = Color.Unspecified,\n        surfaceContainerLowest = Color.Unspecified,\n        primaryFixed = Color.Unspecified,\n        primaryFixedDim = Color.Unspecified,\n        onPrimaryFixed = Color.Unspecified,\n        onPrimaryFixedVariant = Color.Unspecified,\n        secondaryFixed = Color.Unspecified,\n        secondaryFixedDim = Color.Unspecified,\n        onSecondaryFixed = Color.Unspecified,\n        onSecondaryFixedVariant = Color.Unspecified,\n        tertiaryFixed = Color.Unspecified,\n        tertiaryFixedDim = Color.Unspecified,\n        onTertiaryFixed = Color.Unspecified,\n        onTertiaryFixedVariant = Color.Unspecified,\n    )\n}\n\n/** Returns a light Material color scheme. */\nfun lightColorScheme(\n    primary: Color = ColorLightTokens.Primary,\n    onPrimary: Color = ColorLightTokens.OnPrimary,\n    primaryContainer: Color = ColorLightTokens.PrimaryContainer,\n    onPrimaryContainer: Color = ColorLightTokens.OnPrimaryContainer,\n    inversePrimary: Color = ColorLightTokens.InversePrimary,\n    secondary: Color = ColorLightTokens.Secondary,\n    onSecondary: Color = ColorLightTokens.OnSecondary,\n    secondaryContainer: Color = ColorLightTokens.SecondaryContainer,\n    onSecondaryContainer: Color = ColorLightTokens.OnSecondaryContainer,\n    tertiary: Color = ColorLightTokens.Tertiary,\n    onTertiary: Color = ColorLightTokens.OnTertiary,\n    tertiaryContainer: Color = ColorLightTokens.TertiaryContainer,\n    onTertiaryContainer: Color = ColorLightTokens.OnTertiaryContainer,\n    background: Color = ColorLightTokens.Background,\n    onBackground: Color = ColorLightTokens.OnBackground,\n    surface: Color = ColorLightTokens.Surface,\n    onSurface: Color = ColorLightTokens.OnSurface,\n    surfaceVariant: Color = ColorLightTokens.SurfaceVariant,\n    onSurfaceVariant: Color = ColorLightTokens.OnSurfaceVariant,\n    surfaceTint: Color = primary,\n    inverseSurface: Color = ColorLightTokens.InverseSurface,\n    inverseOnSurface: Color = ColorLightTokens.InverseOnSurface,\n    error: Color = ColorLightTokens.Error,\n    onError: Color = ColorLightTokens.OnError,\n    errorContainer: Color = ColorLightTokens.ErrorContainer,\n    onErrorContainer: Color = ColorLightTokens.OnErrorContainer,\n    outline: Color = ColorLightTokens.Outline,\n    outlineVariant: Color = ColorLightTokens.OutlineVariant,\n    scrim: Color = ColorLightTokens.Scrim,\n    surfaceBright: Color = ColorLightTokens.SurfaceBright,\n    surfaceContainer: Color = ColorLightTokens.SurfaceContainer,\n    surfaceContainerHigh: Color = ColorLightTokens.SurfaceContainerHigh,\n    surfaceContainerHighest: Color = ColorLightTokens.SurfaceContainerHighest,\n    surfaceContainerLow: Color = ColorLightTokens.SurfaceContainerLow,\n    surfaceContainerLowest: Color = ColorLightTokens.SurfaceContainerLowest,\n    surfaceDim: Color = ColorLightTokens.SurfaceDim,\n    primaryFixed: Color = ColorLightTokens.PrimaryFixed,\n    primaryFixedDim: Color = ColorLightTokens.PrimaryFixedDim,\n    onPrimaryFixed: Color = ColorLightTokens.OnPrimaryFixed,\n    onPrimaryFixedVariant: Color = ColorLightTokens.OnPrimaryFixedVariant,\n    secondaryFixed: Color = ColorLightTokens.SecondaryFixed,\n    secondaryFixedDim: Color = ColorLightTokens.SecondaryFixedDim,\n    onSecondaryFixed: Color = ColorLightTokens.OnSecondaryFixed,\n    onSecondaryFixedVariant: Color = ColorLightTokens.OnSecondaryFixedVariant,\n    tertiaryFixed: Color = ColorLightTokens.TertiaryFixed,\n    tertiaryFixedDim: Color = ColorLightTokens.TertiaryFixedDim,\n    onTertiaryFixed: Color = ColorLightTokens.OnTertiaryFixed,\n    onTertiaryFixedVariant: Color = ColorLightTokens.OnTertiaryFixedVariant,\n): ColorScheme =\n    ColorScheme(\n        primary = primary,\n        onPrimary = onPrimary,\n        primaryContainer = primaryContainer,\n        onPrimaryContainer = onPrimaryContainer,\n        inversePrimary = inversePrimary,\n        secondary = secondary,\n        onSecondary = onSecondary,\n        secondaryContainer = secondaryContainer,\n        onSecondaryContainer = onSecondaryContainer,\n        tertiary = tertiary,\n        onTertiary = onTertiary,\n        tertiaryContainer = tertiaryContainer,\n        onTertiaryContainer = onTertiaryContainer,\n        background = background,\n        onBackground = onBackground,\n        surface = surface,\n        onSurface = onSurface,\n        surfaceVariant = surfaceVariant,\n        onSurfaceVariant = onSurfaceVariant,\n        surfaceTint = surfaceTint,\n        inverseSurface = inverseSurface,\n        inverseOnSurface = inverseOnSurface,\n        error = error,\n        onError = onError,\n        errorContainer = errorContainer,\n        onErrorContainer = onErrorContainer,\n        outline = outline,\n        outlineVariant = outlineVariant,\n        scrim = scrim,\n        surfaceBright = surfaceBright,\n        surfaceContainer = surfaceContainer,\n        surfaceContainerHigh = surfaceContainerHigh,\n        surfaceContainerHighest = surfaceContainerHighest,\n        surfaceContainerLow = surfaceContainerLow,\n        surfaceContainerLowest = surfaceContainerLowest,\n        surfaceDim = surfaceDim,\n        primaryFixed = primaryFixed,\n        primaryFixedDim = primaryFixedDim,\n        onPrimaryFixed = onPrimaryFixed,\n        onPrimaryFixedVariant = onPrimaryFixedVariant,\n        secondaryFixed = secondaryFixed,\n        secondaryFixedDim = secondaryFixedDim,\n        onSecondaryFixed = onSecondaryFixed,\n        onSecondaryFixedVariant = onSecondaryFixedVariant,\n        tertiaryFixed = tertiaryFixed,\n        tertiaryFixedDim = tertiaryFixedDim,\n        onTertiaryFixed = onTertiaryFixed,\n        onTertiaryFixedVariant = onTertiaryFixedVariant,\n    )\n\n/** Returns a dark Material color scheme. */\nfun darkColorScheme(\n    primary: Color = ColorDarkTokens.Primary,\n    onPrimary: Color = ColorDarkTokens.OnPrimary,\n    primaryContainer: Color = ColorDarkTokens.PrimaryContainer,\n    onPrimaryContainer: Color = ColorDarkTokens.OnPrimaryContainer,\n    inversePrimary: Color = ColorDarkTokens.InversePrimary,\n    secondary: Color = ColorDarkTokens.Secondary,\n    onSecondary: Color = ColorDarkTokens.OnSecondary,\n    secondaryContainer: Color = ColorDarkTokens.SecondaryContainer,\n    onSecondaryContainer: Color = ColorDarkTokens.OnSecondaryContainer,\n    tertiary: Color = ColorDarkTokens.Tertiary,\n    onTertiary: Color = ColorDarkTokens.OnTertiary,\n    tertiaryContainer: Color = ColorDarkTokens.TertiaryContainer,\n    onTertiaryContainer: Color = ColorDarkTokens.OnTertiaryContainer,\n    background: Color = ColorDarkTokens.Background,\n    onBackground: Color = ColorDarkTokens.OnBackground,\n    surface: Color = ColorDarkTokens.Surface,\n    onSurface: Color = ColorDarkTokens.OnSurface,\n    surfaceVariant: Color = ColorDarkTokens.SurfaceVariant,\n    onSurfaceVariant: Color = ColorDarkTokens.OnSurfaceVariant,\n    surfaceTint: Color = primary,\n    inverseSurface: Color = ColorDarkTokens.InverseSurface,\n    inverseOnSurface: Color = ColorDarkTokens.InverseOnSurface,\n    error: Color = ColorDarkTokens.Error,\n    onError: Color = ColorDarkTokens.OnError,\n    errorContainer: Color = ColorDarkTokens.ErrorContainer,\n    onErrorContainer: Color = ColorDarkTokens.OnErrorContainer,\n    outline: Color = ColorDarkTokens.Outline,\n    outlineVariant: Color = ColorDarkTokens.OutlineVariant,\n    scrim: Color = ColorDarkTokens.Scrim,\n    surfaceBright: Color = ColorDarkTokens.SurfaceBright,\n    surfaceContainer: Color = ColorDarkTokens.SurfaceContainer,\n    surfaceContainerHigh: Color = ColorDarkTokens.SurfaceContainerHigh,\n    surfaceContainerHighest: Color = ColorDarkTokens.SurfaceContainerHighest,\n    surfaceContainerLow: Color = ColorDarkTokens.SurfaceContainerLow,\n    surfaceContainerLowest: Color = ColorDarkTokens.SurfaceContainerLowest,\n    surfaceDim: Color = ColorDarkTokens.SurfaceDim,\n    primaryFixed: Color = ColorDarkTokens.PrimaryFixed,\n    primaryFixedDim: Color = ColorDarkTokens.PrimaryFixedDim,\n    onPrimaryFixed: Color = ColorDarkTokens.OnPrimaryFixed,\n    onPrimaryFixedVariant: Color = ColorDarkTokens.OnPrimaryFixedVariant,\n    secondaryFixed: Color = ColorDarkTokens.SecondaryFixed,\n    secondaryFixedDim: Color = ColorDarkTokens.SecondaryFixedDim,\n    onSecondaryFixed: Color = ColorDarkTokens.OnSecondaryFixed,\n    onSecondaryFixedVariant: Color = ColorDarkTokens.OnSecondaryFixedVariant,\n    tertiaryFixed: Color = ColorDarkTokens.TertiaryFixed,\n    tertiaryFixedDim: Color = ColorDarkTokens.TertiaryFixedDim,\n    onTertiaryFixed: Color = ColorDarkTokens.OnTertiaryFixed,\n    onTertiaryFixedVariant: Color = ColorDarkTokens.OnTertiaryFixedVariant,\n): ColorScheme =\n    ColorScheme(\n        primary = primary,\n        onPrimary = onPrimary,\n        primaryContainer = primaryContainer,\n        onPrimaryContainer = onPrimaryContainer,\n        inversePrimary = inversePrimary,\n        secondary = secondary,\n        onSecondary = onSecondary,\n        secondaryContainer = secondaryContainer,\n        onSecondaryContainer = onSecondaryContainer,\n        tertiary = tertiary,\n        onTertiary = onTertiary,\n        tertiaryContainer = tertiaryContainer,\n        onTertiaryContainer = onTertiaryContainer,\n        background = background,\n        onBackground = onBackground,\n        surface = surface,\n        onSurface = onSurface,\n        surfaceVariant = surfaceVariant,\n        onSurfaceVariant = onSurfaceVariant,\n        surfaceTint = surfaceTint,\n        inverseSurface = inverseSurface,\n        inverseOnSurface = inverseOnSurface,\n        error = error,\n        onError = onError,\n        errorContainer = errorContainer,\n        onErrorContainer = onErrorContainer,\n        outline = outline,\n        outlineVariant = outlineVariant,\n        scrim = scrim,\n        surfaceBright = surfaceBright,\n        surfaceContainer = surfaceContainer,\n        surfaceContainerHigh = surfaceContainerHigh,\n        surfaceContainerHighest = surfaceContainerHighest,\n        surfaceContainerLow = surfaceContainerLow,\n        surfaceContainerLowest = surfaceContainerLowest,\n        surfaceDim = surfaceDim,\n        primaryFixed = primaryFixed,\n        primaryFixedDim = primaryFixedDim,\n        onPrimaryFixed = onPrimaryFixed,\n        onPrimaryFixedVariant = onPrimaryFixedVariant,\n        secondaryFixed = secondaryFixed,\n        secondaryFixedDim = secondaryFixedDim,\n        onSecondaryFixed = onSecondaryFixed,\n        onSecondaryFixedVariant = onSecondaryFixedVariant,\n        tertiaryFixed = tertiaryFixed,\n        tertiaryFixedDim = tertiaryFixedDim,\n        onTertiaryFixed = onTertiaryFixed,\n        onTertiaryFixedVariant = onTertiaryFixedVariant,\n    )\n\n/**\n * The Material color system contains pairs of colors that are typically used for the background and\n * content color inside a component. For example, a [Button] typically uses `primary` for its\n * background, and `onPrimary` for the color of its content (usually text or iconography).\n *\n * This function tries to match the provided [backgroundColor] to a 'background' color in this\n * [ColorScheme], and then will return the corresponding color used for content. For example, when\n * [backgroundColor] is [ColorScheme.primary], this will return [ColorScheme.onPrimary].\n *\n * If [backgroundColor] does not match a background color in the theme, this will return\n * [Color.Unspecified].\n *\n * @return the matching content color for [backgroundColor]. If [backgroundColor] is not present in\n *   the theme's [ColorScheme], then returns [Color.Unspecified].\n * @see contentColorFor\n */\n@Stable\nfun ColorScheme.contentColorFor(backgroundColor: Color): Color =\n    when (backgroundColor) {\n        primary -> onPrimary\n        secondary -> onSecondary\n        tertiary -> onTertiary\n        background -> onBackground\n        error -> onError\n        primaryContainer -> onPrimaryContainer\n        secondaryContainer -> onSecondaryContainer\n        tertiaryContainer -> onTertiaryContainer\n        errorContainer -> onErrorContainer\n        inverseSurface -> inverseOnSurface\n        surface -> onSurface\n        surfaceVariant -> onSurfaceVariant\n        surfaceBright -> onSurface\n        surfaceContainer -> onSurface\n        surfaceContainerHigh -> onSurface\n        surfaceContainerHighest -> onSurface\n        surfaceContainerLow -> onSurface\n        surfaceContainerLowest -> onSurface\n        surfaceDim -> onSurface\n        primaryFixed -> onPrimaryFixed\n        primaryFixedDim -> onPrimaryFixed\n        secondaryFixed -> onSecondaryFixed\n        secondaryFixedDim -> onSecondaryFixed\n        tertiaryFixed -> onTertiaryFixed\n        tertiaryFixedDim -> onTertiaryFixed\n        else -> Color.Unspecified\n    }\n\n/**\n * The Material color system contains pairs of colors that are typically used for the background and\n * content color inside a component. For example, a [Button] typically uses `primary` for its\n * background, and `onPrimary` for the color of its content (usually text or iconography).\n *\n * This function tries to match the provided [backgroundColor] to a 'background' color in this\n * [ColorScheme], and then will return the corresponding color used for content. For example, when\n * [backgroundColor] is [ColorScheme.primary], this will return [ColorScheme.onPrimary].\n *\n * If [backgroundColor] does not match a background color in the theme, this will return the current\n * value of [LocalContentColor] as a best-effort color.\n *\n * @return the matching content color for [backgroundColor]. If [backgroundColor] is not present in\n *   the theme's [ColorScheme], then returns the current value of [LocalContentColor].\n * @see ColorScheme.contentColorFor\n */\n@Composable\n@ReadOnlyComposable\nfun contentColorFor(backgroundColor: Color) =\n    MaterialTheme.colorScheme.contentColorFor(backgroundColor).takeOrElse {\n        LocalContentColor.current\n    }\n\n/**\n * Computes the surface tonal color at different elevation levels e.g. surface1 through surface5.\n *\n * @param elevation Elevation value used to compute alpha of the color overlay layer.\n * @return the [ColorScheme.surface] color with an alpha of the [ColorScheme.surfaceTint] color\n *   overlaid on top of it.\n */\n@Stable\nfun ColorScheme.surfaceColorAtElevation(elevation: Dp): Color {\n    if (elevation == 0.dp) return surface\n    val alpha = ((4.5f * ln(elevation.value + 1)) + 2f) / 100f\n    return surfaceTint.copy(alpha = alpha).compositeOver(surface)\n}\n\n/**\n * Returns a light Material color scheme.\n *\n * The default color scheme for [MaterialExpressiveTheme]. For dark mode, use [darkColorScheme].\n *\n * Example of MaterialExpressiveTheme toggling expressiveLightColorScheme and darkTheme.\n *\n * @sample androidx.compose.material3.samples.MaterialExpressiveThemeColorSchemeSample\n */\n@ExperimentalMaterial3ExpressiveApi\nfun expressiveLightColorScheme() =\n    lightColorScheme(\n        // TODO: Replace palette references with color token references when available.\n        onPrimaryContainer = PaletteTokens.Primary30,\n        onSecondaryContainer = PaletteTokens.Secondary30,\n        onTertiaryContainer = PaletteTokens.Tertiary30,\n        onErrorContainer = PaletteTokens.Error30,\n    )\n\n@Deprecated(\n    message =\n        \"Maintained for binary compatibility. Use overload with additional Fixed roles instead\",\n    level = DeprecationLevel.HIDDEN,\n)\n/** Returns a light Material color scheme. */\nfun lightColorScheme(\n    primary: Color = ColorLightTokens.Primary,\n    onPrimary: Color = ColorLightTokens.OnPrimary,\n    primaryContainer: Color = ColorLightTokens.PrimaryContainer,\n    onPrimaryContainer: Color = ColorLightTokens.OnPrimaryContainer,\n    inversePrimary: Color = ColorLightTokens.InversePrimary,\n    secondary: Color = ColorLightTokens.Secondary,\n    onSecondary: Color = ColorLightTokens.OnSecondary,\n    secondaryContainer: Color = ColorLightTokens.SecondaryContainer,\n    onSecondaryContainer: Color = ColorLightTokens.OnSecondaryContainer,\n    tertiary: Color = ColorLightTokens.Tertiary,\n    onTertiary: Color = ColorLightTokens.OnTertiary,\n    tertiaryContainer: Color = ColorLightTokens.TertiaryContainer,\n    onTertiaryContainer: Color = ColorLightTokens.OnTertiaryContainer,\n    background: Color = ColorLightTokens.Background,\n    onBackground: Color = ColorLightTokens.OnBackground,\n    surface: Color = ColorLightTokens.Surface,\n    onSurface: Color = ColorLightTokens.OnSurface,\n    surfaceVariant: Color = ColorLightTokens.SurfaceVariant,\n    onSurfaceVariant: Color = ColorLightTokens.OnSurfaceVariant,\n    surfaceTint: Color = primary,\n    inverseSurface: Color = ColorLightTokens.InverseSurface,\n    inverseOnSurface: Color = ColorLightTokens.InverseOnSurface,\n    error: Color = ColorLightTokens.Error,\n    onError: Color = ColorLightTokens.OnError,\n    errorContainer: Color = ColorLightTokens.ErrorContainer,\n    onErrorContainer: Color = ColorLightTokens.OnErrorContainer,\n    outline: Color = ColorLightTokens.Outline,\n    outlineVariant: Color = ColorLightTokens.OutlineVariant,\n    scrim: Color = ColorLightTokens.Scrim,\n    surfaceBright: Color = ColorLightTokens.SurfaceBright,\n    surfaceContainer: Color = ColorLightTokens.SurfaceContainer,\n    surfaceContainerHigh: Color = ColorLightTokens.SurfaceContainerHigh,\n    surfaceContainerHighest: Color = ColorLightTokens.SurfaceContainerHighest,\n    surfaceContainerLow: Color = ColorLightTokens.SurfaceContainerLow,\n    surfaceContainerLowest: Color = ColorLightTokens.SurfaceContainerLowest,\n    surfaceDim: Color = ColorLightTokens.SurfaceDim,\n): ColorScheme =\n    lightColorScheme(\n        primary = primary,\n        onPrimary = onPrimary,\n        primaryContainer = primaryContainer,\n        onPrimaryContainer = onPrimaryContainer,\n        inversePrimary = inversePrimary,\n        secondary = secondary,\n        onSecondary = onSecondary,\n        secondaryContainer = secondaryContainer,\n        onSecondaryContainer = onSecondaryContainer,\n        tertiary = tertiary,\n        onTertiary = onTertiary,\n        tertiaryContainer = tertiaryContainer,\n        onTertiaryContainer = onTertiaryContainer,\n        background = background,\n        onBackground = onBackground,\n        surface = surface,\n        onSurface = onSurface,\n        surfaceVariant = surfaceVariant,\n        onSurfaceVariant = onSurfaceVariant,\n        surfaceTint = surfaceTint,\n        inverseSurface = inverseSurface,\n        inverseOnSurface = inverseOnSurface,\n        error = error,\n        onError = onError,\n        errorContainer = errorContainer,\n        onErrorContainer = onErrorContainer,\n        outline = outline,\n        outlineVariant = outlineVariant,\n        scrim = scrim,\n        surfaceBright = surfaceBright,\n        surfaceContainer = surfaceContainer,\n        surfaceContainerHigh = surfaceContainerHigh,\n        surfaceContainerHighest = surfaceContainerHighest,\n        surfaceContainerLow = surfaceContainerLow,\n        surfaceContainerLowest = surfaceContainerLowest,\n        surfaceDim = surfaceDim,\n    )\n\n@Deprecated(\n    message =\n        \"Maintained for binary compatibility. Use overload with additional surface roles instead\",\n    level = DeprecationLevel.HIDDEN,\n)\nfun lightColorScheme(\n    primary: Color = ColorLightTokens.Primary,\n    onPrimary: Color = ColorLightTokens.OnPrimary,\n    primaryContainer: Color = ColorLightTokens.PrimaryContainer,\n    onPrimaryContainer: Color = ColorLightTokens.OnPrimaryContainer,\n    inversePrimary: Color = ColorLightTokens.InversePrimary,\n    secondary: Color = ColorLightTokens.Secondary,\n    onSecondary: Color = ColorLightTokens.OnSecondary,\n    secondaryContainer: Color = ColorLightTokens.SecondaryContainer,\n    onSecondaryContainer: Color = ColorLightTokens.OnSecondaryContainer,\n    tertiary: Color = ColorLightTokens.Tertiary,\n    onTertiary: Color = ColorLightTokens.OnTertiary,\n    tertiaryContainer: Color = ColorLightTokens.TertiaryContainer,\n    onTertiaryContainer: Color = ColorLightTokens.OnTertiaryContainer,\n    background: Color = ColorLightTokens.Background,\n    onBackground: Color = ColorLightTokens.OnBackground,\n    surface: Color = ColorLightTokens.Surface,\n    onSurface: Color = ColorLightTokens.OnSurface,\n    surfaceVariant: Color = ColorLightTokens.SurfaceVariant,\n    onSurfaceVariant: Color = ColorLightTokens.OnSurfaceVariant,\n    surfaceTint: Color = primary,\n    inverseSurface: Color = ColorLightTokens.InverseSurface,\n    inverseOnSurface: Color = ColorLightTokens.InverseOnSurface,\n    error: Color = ColorLightTokens.Error,\n    onError: Color = ColorLightTokens.OnError,\n    errorContainer: Color = ColorLightTokens.ErrorContainer,\n    onErrorContainer: Color = ColorLightTokens.OnErrorContainer,\n    outline: Color = ColorLightTokens.Outline,\n    outlineVariant: Color = ColorLightTokens.OutlineVariant,\n    scrim: Color = ColorLightTokens.Scrim,\n): ColorScheme =\n    lightColorScheme(\n        primary = primary,\n        onPrimary = onPrimary,\n        primaryContainer = primaryContainer,\n        onPrimaryContainer = onPrimaryContainer,\n        inversePrimary = inversePrimary,\n        secondary = secondary,\n        onSecondary = onSecondary,\n        secondaryContainer = secondaryContainer,\n        onSecondaryContainer = onSecondaryContainer,\n        tertiary = tertiary,\n        onTertiary = onTertiary,\n        tertiaryContainer = tertiaryContainer,\n        onTertiaryContainer = onTertiaryContainer,\n        background = background,\n        onBackground = onBackground,\n        surface = surface,\n        onSurface = onSurface,\n        surfaceVariant = surfaceVariant,\n        onSurfaceVariant = onSurfaceVariant,\n        surfaceTint = surfaceTint,\n        inverseSurface = inverseSurface,\n        inverseOnSurface = inverseOnSurface,\n        error = error,\n        onError = onError,\n        errorContainer = errorContainer,\n        onErrorContainer = onErrorContainer,\n        outline = outline,\n        outlineVariant = outlineVariant,\n        scrim = scrim,\n    )\n\n/** Returns a dark Material color scheme. */\n@Deprecated(\n    message =\n        \"Maintained for binary compatibility. Use overload with additional surface roles instead\",\n    level = DeprecationLevel.HIDDEN,\n)\nfun darkColorScheme(\n    primary: Color = ColorDarkTokens.Primary,\n    onPrimary: Color = ColorDarkTokens.OnPrimary,\n    primaryContainer: Color = ColorDarkTokens.PrimaryContainer,\n    onPrimaryContainer: Color = ColorDarkTokens.OnPrimaryContainer,\n    inversePrimary: Color = ColorDarkTokens.InversePrimary,\n    secondary: Color = ColorDarkTokens.Secondary,\n    onSecondary: Color = ColorDarkTokens.OnSecondary,\n    secondaryContainer: Color = ColorDarkTokens.SecondaryContainer,\n    onSecondaryContainer: Color = ColorDarkTokens.OnSecondaryContainer,\n    tertiary: Color = ColorDarkTokens.Tertiary,\n    onTertiary: Color = ColorDarkTokens.OnTertiary,\n    tertiaryContainer: Color = ColorDarkTokens.TertiaryContainer,\n    onTertiaryContainer: Color = ColorDarkTokens.OnTertiaryContainer,\n    background: Color = ColorDarkTokens.Background,\n    onBackground: Color = ColorDarkTokens.OnBackground,\n    surface: Color = ColorDarkTokens.Surface,\n    onSurface: Color = ColorDarkTokens.OnSurface,\n    surfaceVariant: Color = ColorDarkTokens.SurfaceVariant,\n    onSurfaceVariant: Color = ColorDarkTokens.OnSurfaceVariant,\n    surfaceTint: Color = primary,\n    inverseSurface: Color = ColorDarkTokens.InverseSurface,\n    inverseOnSurface: Color = ColorDarkTokens.InverseOnSurface,\n    error: Color = ColorDarkTokens.Error,\n    onError: Color = ColorDarkTokens.OnError,\n    errorContainer: Color = ColorDarkTokens.ErrorContainer,\n    onErrorContainer: Color = ColorDarkTokens.OnErrorContainer,\n    outline: Color = ColorDarkTokens.Outline,\n    outlineVariant: Color = ColorDarkTokens.OutlineVariant,\n    scrim: Color = ColorDarkTokens.Scrim,\n    surfaceBright: Color = ColorDarkTokens.SurfaceBright,\n    surfaceContainer: Color = ColorDarkTokens.SurfaceContainer,\n    surfaceContainerHigh: Color = ColorDarkTokens.SurfaceContainerHigh,\n    surfaceContainerHighest: Color = ColorDarkTokens.SurfaceContainerHighest,\n    surfaceContainerLow: Color = ColorDarkTokens.SurfaceContainerLow,\n    surfaceContainerLowest: Color = ColorDarkTokens.SurfaceContainerLowest,\n    surfaceDim: Color = ColorDarkTokens.SurfaceDim,\n): ColorScheme =\n    darkColorScheme(\n        primary = primary,\n        onPrimary = onPrimary,\n        primaryContainer = primaryContainer,\n        onPrimaryContainer = onPrimaryContainer,\n        inversePrimary = inversePrimary,\n        secondary = secondary,\n        onSecondary = onSecondary,\n        secondaryContainer = secondaryContainer,\n        onSecondaryContainer = onSecondaryContainer,\n        tertiary = tertiary,\n        onTertiary = onTertiary,\n        tertiaryContainer = tertiaryContainer,\n        onTertiaryContainer = onTertiaryContainer,\n        background = background,\n        onBackground = onBackground,\n        surface = surface,\n        onSurface = onSurface,\n        surfaceVariant = surfaceVariant,\n        onSurfaceVariant = onSurfaceVariant,\n        surfaceTint = surfaceTint,\n        inverseSurface = inverseSurface,\n        inverseOnSurface = inverseOnSurface,\n        error = error,\n        onError = onError,\n        errorContainer = errorContainer,\n        onErrorContainer = onErrorContainer,\n        outline = outline,\n        outlineVariant = outlineVariant,\n        scrim = scrim,\n        surfaceBright = surfaceBright,\n        surfaceContainer = surfaceContainer,\n        surfaceContainerHigh = surfaceContainerHigh,\n        surfaceContainerHighest = surfaceContainerHighest,\n        surfaceContainerLow = surfaceContainerLow,\n        surfaceContainerLowest = surfaceContainerLowest,\n        surfaceDim = surfaceDim,\n    )\n\n@Deprecated(\n    message =\n        \"Maintained for binary compatibility. Use overload with additional surface roles instead\",\n    level = DeprecationLevel.HIDDEN,\n)\nfun darkColorScheme(\n    primary: Color = ColorDarkTokens.Primary,\n    onPrimary: Color = ColorDarkTokens.OnPrimary,\n    primaryContainer: Color = ColorDarkTokens.PrimaryContainer,\n    onPrimaryContainer: Color = ColorDarkTokens.OnPrimaryContainer,\n    inversePrimary: Color = ColorDarkTokens.InversePrimary,\n    secondary: Color = ColorDarkTokens.Secondary,\n    onSecondary: Color = ColorDarkTokens.OnSecondary,\n    secondaryContainer: Color = ColorDarkTokens.SecondaryContainer,\n    onSecondaryContainer: Color = ColorDarkTokens.OnSecondaryContainer,\n    tertiary: Color = ColorDarkTokens.Tertiary,\n    onTertiary: Color = ColorDarkTokens.OnTertiary,\n    tertiaryContainer: Color = ColorDarkTokens.TertiaryContainer,\n    onTertiaryContainer: Color = ColorDarkTokens.OnTertiaryContainer,\n    background: Color = ColorDarkTokens.Background,\n    onBackground: Color = ColorDarkTokens.OnBackground,\n    surface: Color = ColorDarkTokens.Surface,\n    onSurface: Color = ColorDarkTokens.OnSurface,\n    surfaceVariant: Color = ColorDarkTokens.SurfaceVariant,\n    onSurfaceVariant: Color = ColorDarkTokens.OnSurfaceVariant,\n    surfaceTint: Color = primary,\n    inverseSurface: Color = ColorDarkTokens.InverseSurface,\n    inverseOnSurface: Color = ColorDarkTokens.InverseOnSurface,\n    error: Color = ColorDarkTokens.Error,\n    onError: Color = ColorDarkTokens.OnError,\n    errorContainer: Color = ColorDarkTokens.ErrorContainer,\n    onErrorContainer: Color = ColorDarkTokens.OnErrorContainer,\n    outline: Color = ColorDarkTokens.Outline,\n    outlineVariant: Color = ColorDarkTokens.OutlineVariant,\n    scrim: Color = ColorDarkTokens.Scrim,\n): ColorScheme =\n    darkColorScheme(\n        primary = primary,\n        onPrimary = onPrimary,\n        primaryContainer = primaryContainer,\n        onPrimaryContainer = onPrimaryContainer,\n        inversePrimary = inversePrimary,\n        secondary = secondary,\n        onSecondary = onSecondary,\n        secondaryContainer = secondaryContainer,\n        onSecondaryContainer = onSecondaryContainer,\n        tertiary = tertiary,\n        onTertiary = onTertiary,\n        tertiaryContainer = tertiaryContainer,\n        onTertiaryContainer = onTertiaryContainer,\n        background = background,\n        onBackground = onBackground,\n        surface = surface,\n        onSurface = onSurface,\n        surfaceVariant = surfaceVariant,\n        onSurfaceVariant = onSurfaceVariant,\n        surfaceTint = surfaceTint,\n        inverseSurface = inverseSurface,\n        inverseOnSurface = inverseOnSurface,\n        error = error,\n        onError = onError,\n        errorContainer = errorContainer,\n        onErrorContainer = onErrorContainer,\n        outline = outline,\n        outlineVariant = outlineVariant,\n        scrim = scrim,\n    )\n\n/**\n * Helper function for component color tokens. Here is an example on how to use component color\n * tokens: ``MaterialTheme.colorScheme.fromToken(ExtendedFabBranded.BrandedContainerColor)``\n */\n@Stable\ninternal fun ColorScheme.fromToken(value: ColorSchemeKeyTokens): Color {\n    return when (value) {\n        ColorSchemeKeyTokens.Background -> background\n        ColorSchemeKeyTokens.Error -> error\n        ColorSchemeKeyTokens.ErrorContainer -> errorContainer\n        ColorSchemeKeyTokens.InverseOnSurface -> inverseOnSurface\n        ColorSchemeKeyTokens.InversePrimary -> inversePrimary\n        ColorSchemeKeyTokens.InverseSurface -> inverseSurface\n        ColorSchemeKeyTokens.OnBackground -> onBackground\n        ColorSchemeKeyTokens.OnError -> onError\n        ColorSchemeKeyTokens.OnErrorContainer -> onErrorContainer\n        ColorSchemeKeyTokens.OnPrimary -> onPrimary\n        ColorSchemeKeyTokens.OnPrimaryContainer -> onPrimaryContainer\n        ColorSchemeKeyTokens.OnSecondary -> onSecondary\n        ColorSchemeKeyTokens.OnSecondaryContainer -> onSecondaryContainer\n        ColorSchemeKeyTokens.OnSurface -> onSurface\n        ColorSchemeKeyTokens.OnSurfaceVariant -> onSurfaceVariant\n        ColorSchemeKeyTokens.SurfaceTint -> surfaceTint\n        ColorSchemeKeyTokens.OnTertiary -> onTertiary\n        ColorSchemeKeyTokens.OnTertiaryContainer -> onTertiaryContainer\n        ColorSchemeKeyTokens.Outline -> outline\n        ColorSchemeKeyTokens.OutlineVariant -> outlineVariant\n        ColorSchemeKeyTokens.Primary -> primary\n        ColorSchemeKeyTokens.PrimaryContainer -> primaryContainer\n        ColorSchemeKeyTokens.Scrim -> scrim\n        ColorSchemeKeyTokens.Secondary -> secondary\n        ColorSchemeKeyTokens.SecondaryContainer -> secondaryContainer\n        ColorSchemeKeyTokens.Surface -> surface\n        ColorSchemeKeyTokens.SurfaceVariant -> surfaceVariant\n        ColorSchemeKeyTokens.SurfaceBright -> surfaceBright\n        ColorSchemeKeyTokens.SurfaceContainer -> surfaceContainer\n        ColorSchemeKeyTokens.SurfaceContainerHigh -> surfaceContainerHigh\n        ColorSchemeKeyTokens.SurfaceContainerHighest -> surfaceContainerHighest\n        ColorSchemeKeyTokens.SurfaceContainerLow -> surfaceContainerLow\n        ColorSchemeKeyTokens.SurfaceContainerLowest -> surfaceContainerLowest\n        ColorSchemeKeyTokens.SurfaceDim -> surfaceDim\n        ColorSchemeKeyTokens.Tertiary -> tertiary\n        ColorSchemeKeyTokens.TertiaryContainer -> tertiaryContainer\n        ColorSchemeKeyTokens.PrimaryFixed -> primaryFixed\n        ColorSchemeKeyTokens.PrimaryFixedDim -> primaryFixedDim\n        ColorSchemeKeyTokens.OnPrimaryFixed -> onPrimaryFixed\n        ColorSchemeKeyTokens.OnPrimaryFixedVariant -> onPrimaryFixedVariant\n        ColorSchemeKeyTokens.SecondaryFixed -> secondaryFixed\n        ColorSchemeKeyTokens.SecondaryFixedDim -> secondaryFixedDim\n        ColorSchemeKeyTokens.OnSecondaryFixed -> onSecondaryFixed\n        ColorSchemeKeyTokens.OnSecondaryFixedVariant -> onSecondaryFixedVariant\n        ColorSchemeKeyTokens.TertiaryFixed -> tertiaryFixed\n        ColorSchemeKeyTokens.TertiaryFixedDim -> tertiaryFixedDim\n        ColorSchemeKeyTokens.OnTertiaryFixed -> onTertiaryFixed\n        ColorSchemeKeyTokens.OnTertiaryFixedVariant -> onTertiaryFixedVariant\n    }\n}\n\n/**\n * A low level of alpha used to represent disabled components, such as text in a disabled Button.\n */\ninternal const val DisabledAlpha = 0.38f\n\n/**\n * Converts a color token key to the local color scheme provided by the theme The color is\n * subscribed to [MaterialTheme.colorScheme] changes.\n */\ninternal val ColorSchemeKeyTokens.value: Color\n    @ReadOnlyComposable @Composable get() = MaterialTheme.colorScheme.fromToken(this)\n\n/**\n * Returns [ColorScheme.surfaceColorAtElevation] with the provided elevation if\n * [LocalTonalElevationEnabled] is set to true, and the provided background color matches\n * [ColorScheme.surface]. Otherwise, the provided color is returned unchanged.\n *\n * @param backgroundColor The background color to compare to [ColorScheme.surface]\n * @param elevation The elevation provided to [ColorScheme.surfaceColorAtElevation] if\n *   [backgroundColor] matches surface.\n * @return [ColorScheme.surfaceColorAtElevation] at [elevation] if [backgroundColor] ==\n *   [ColorScheme.surface] and [LocalTonalElevationEnabled] is set to true. Else [backgroundColor]\n */\n@Composable\n@ReadOnlyComposable\ninternal fun ColorScheme.applyTonalElevation(backgroundColor: Color, elevation: Dp): Color {\n    val tonalElevationEnabled = LocalTonalElevationEnabled.current\n    return if (backgroundColor == surface && tonalElevationEnabled) {\n        surfaceColorAtElevation(elevation)\n    } else {\n        backgroundColor\n    }\n}\n\n/**\n * Composition Local used to check if [ColorScheme.applyTonalElevation] will be applied down the\n * tree.\n *\n * Setting this value to false will cause all subsequent surfaces down the tree to not apply\n * tonalElevation.\n */\nval LocalTonalElevationEnabled = staticCompositionLocalOf { true }\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Typography.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.material3.tokens.TypographyKeyTokens\nimport androidx.compose.material3.tokens.TypographyTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.ReadOnlyComposable\nimport androidx.compose.runtime.staticCompositionLocalOf\nimport androidx.compose.ui.text.TextStyle\n\n/**\n * The Material Design type scale includes a range of contrasting styles that support the needs of\n * your product and its content.\n *\n * Use typography to make writing legible and beautiful. Material's default type scale includes\n * contrasting and flexible styles to support a wide range of use cases.\n *\n * The type scale is a combination of thirteen styles that are supported by the type system. It\n * contains reusable categories of text, each with an intended application and meaning.\n *\n * The emphasized versions of the baseline styles add dynamism and personality to the baseline\n * styles. It can be used to further stylize select pieces of text. The emphasized states have\n * pragmatic uses, such as creating clearer division of content and drawing users' eyes to relevant\n * material.\n *\n * To learn more about typography, see\n * [Material Design typography](https://m3.material.io/styles/typography/overview).\n *\n * @property displayLarge displayLarge is the largest display text.\n * @property displayMedium displayMedium is the second largest display text.\n * @property displaySmall displaySmall is the smallest display text.\n * @property headlineLarge headlineLarge is the largest headline, reserved for short, important text\n *   or numerals. For headlines, you can choose an expressive font, such as a display, handwritten,\n *   or script style. These unconventional font designs have details and intricacy that help attract\n *   the eye.\n * @property headlineMedium headlineMedium is the second largest headline, reserved for short,\n *   important text or numerals. For headlines, you can choose an expressive font, such as a\n *   display, handwritten, or script style. These unconventional font designs have details and\n *   intricacy that help attract the eye.\n * @property headlineSmall headlineSmall is the smallest headline, reserved for short, important\n *   text or numerals. For headlines, you can choose an expressive font, such as a display,\n *   handwritten, or script style. These unconventional font designs have details and intricacy that\n *   help attract the eye.\n * @property titleLarge titleLarge is the largest title, and is typically reserved for\n *   medium-emphasis text that is shorter in length. Serif or sans serif typefaces work well for\n *   subtitles.\n * @property titleMedium titleMedium is the second largest title, and is typically reserved for\n *   medium-emphasis text that is shorter in length. Serif or sans serif typefaces work well for\n *   subtitles.\n * @property titleSmall titleSmall is the smallest title, and is typically reserved for\n *   medium-emphasis text that is shorter in length. Serif or sans serif typefaces work well for\n *   subtitles.\n * @property bodyLarge bodyLarge is the largest body, and is typically used for long-form writing as\n *   it works well for small text sizes. For longer sections of text, a serif or sans serif typeface\n *   is recommended.\n * @property bodyMedium bodyMedium is the second largest body, and is typically used for long-form\n *   writing as it works well for small text sizes. For longer sections of text, a serif or sans\n *   serif typeface is recommended.\n * @property bodySmall bodySmall is the smallest body, and is typically used for long-form writing\n *   as it works well for small text sizes. For longer sections of text, a serif or sans serif\n *   typeface is recommended.\n * @property labelLarge labelLarge text is a call to action used in different types of buttons (such\n *   as text, outlined and contained buttons) and in tabs, dialogs, and cards. Button text is\n *   typically sans serif, using all caps text.\n * @property labelMedium labelMedium is one of the smallest font sizes. It is used sparingly to\n *   annotate imagery or to introduce a headline.\n * @property labelSmall labelSmall is one of the smallest font sizes. It is used sparingly to\n *   annotate imagery or to introduce a headline.\n * @property displayLargeEmphasized an emphasized version of [displayLarge].\n * @property displayMediumEmphasized an emphasized version of [displayMedium].\n * @property displaySmallEmphasized an emphasized version of [displaySmall].\n * @property headlineLargeEmphasized an emphasized version of [headlineLarge].\n * @property headlineMediumEmphasized an emphasized version of [headlineMedium].\n * @property headlineSmallEmphasized an emphasized version of [headlineSmall].\n * @property titleLargeEmphasized an emphasized version of [titleLarge].\n * @property titleMediumEmphasized an emphasized version of [titleMedium].\n * @property titleSmallEmphasized an emphasized version of [titleSmall].\n * @property bodyLargeEmphasized an emphasized version of [bodyLarge].\n * @property bodyMediumEmphasized an emphasized version of [bodyMedium].\n * @property bodySmallEmphasized an emphasized version of [bodySmall].\n * @property labelLargeEmphasized an emphasized version of [labelLarge].\n * @property labelMediumEmphasized an emphasized version of [labelMedium].\n * @property labelSmallEmphasized an emphasized version of [labelSmall].\n */\n@Immutable\nclass Typography\n@ExperimentalMaterial3ExpressiveApi\nconstructor(\n    val displayLarge: TextStyle = TypographyTokens.DisplayLarge,\n    val displayMedium: TextStyle = TypographyTokens.DisplayMedium,\n    val displaySmall: TextStyle = TypographyTokens.DisplaySmall,\n    val headlineLarge: TextStyle = TypographyTokens.HeadlineLarge,\n    val headlineMedium: TextStyle = TypographyTokens.HeadlineMedium,\n    val headlineSmall: TextStyle = TypographyTokens.HeadlineSmall,\n    val titleLarge: TextStyle = TypographyTokens.TitleLarge,\n    val titleMedium: TextStyle = TypographyTokens.TitleMedium,\n    val titleSmall: TextStyle = TypographyTokens.TitleSmall,\n    val bodyLarge: TextStyle = TypographyTokens.BodyLarge,\n    val bodyMedium: TextStyle = TypographyTokens.BodyMedium,\n    val bodySmall: TextStyle = TypographyTokens.BodySmall,\n    val labelLarge: TextStyle = TypographyTokens.LabelLarge,\n    val labelMedium: TextStyle = TypographyTokens.LabelMedium,\n    val labelSmall: TextStyle = TypographyTokens.LabelSmall,\n    displayLargeEmphasized: TextStyle = TypographyTokens.DisplayLargeEmphasized,\n    displayMediumEmphasized: TextStyle = TypographyTokens.DisplayMediumEmphasized,\n    displaySmallEmphasized: TextStyle = TypographyTokens.DisplaySmallEmphasized,\n    headlineLargeEmphasized: TextStyle = TypographyTokens.HeadlineLargeEmphasized,\n    headlineMediumEmphasized: TextStyle = TypographyTokens.HeadlineMediumEmphasized,\n    headlineSmallEmphasized: TextStyle = TypographyTokens.HeadlineSmallEmphasized,\n    titleLargeEmphasized: TextStyle = TypographyTokens.TitleLargeEmphasized,\n    titleMediumEmphasized: TextStyle = TypographyTokens.TitleMediumEmphasized,\n    titleSmallEmphasized: TextStyle = TypographyTokens.TitleSmallEmphasized,\n    bodyLargeEmphasized: TextStyle = TypographyTokens.BodyLargeEmphasized,\n    bodyMediumEmphasized: TextStyle = TypographyTokens.BodyMediumEmphasized,\n    bodySmallEmphasized: TextStyle = TypographyTokens.BodySmallEmphasized,\n    labelLargeEmphasized: TextStyle = TypographyTokens.LabelLargeEmphasized,\n    labelMediumEmphasized: TextStyle = TypographyTokens.LabelMediumEmphasized,\n    labelSmallEmphasized: TextStyle = TypographyTokens.LabelSmallEmphasized,\n) {\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [displayLarge]. */\n    val displayLargeEmphasized = displayLargeEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [displayMedium]. */\n    val displayMediumEmphasized = displayMediumEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [displaySmall]. */\n    val displaySmallEmphasized = displaySmallEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [headlineLarge]. */\n    val headlineLargeEmphasized = headlineLargeEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [headlineMedium]. */\n    val headlineMediumEmphasized = headlineMediumEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [headlineSmall]. */\n    val headlineSmallEmphasized = headlineSmallEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [titleLarge]. */\n    val titleLargeEmphasized = titleLargeEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [titleMedium]. */\n    val titleMediumEmphasized = titleMediumEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [titleSmall]. */\n    val titleSmallEmphasized = titleSmallEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [bodyLarge]. */\n    val bodyLargeEmphasized = bodyLargeEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [bodyMedium]. */\n    val bodyMediumEmphasized = bodyMediumEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [bodySmall]. */\n    val bodySmallEmphasized = bodySmallEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [labelLarge]. */\n    val labelLargeEmphasized = labelLargeEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [labelMedium]. */\n    val labelMediumEmphasized = labelMediumEmphasized\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** an emphasized version of [labelSmall]. */\n    val labelSmallEmphasized = labelSmallEmphasized\n\n    /**\n     * The Material Design type scale includes a range of contrasting styles that support the needs\n     * of your product and its content.\n     *\n     * Use typography to make writing legible and beautiful. Material's default type scale includes\n     * contrasting and flexible styles to support a wide range of use cases.\n     *\n     * The type scale is a combination of thirteen styles that are supported by the type system. It\n     * contains reusable categories of text, each with an intended application and meaning.\n     *\n     * To learn more about typography, see\n     * [Material Design typography](https://m3.material.io/styles/typography/overview).\n     *\n     * @param displayLarge displayLarge is the largest display text.\n     * @param displayMedium displayMedium is the second largest display text.\n     * @param displaySmall displaySmall is the smallest display text.\n     * @param headlineLarge headlineLarge is the largest headline, reserved for short, important\n     *   text or numerals. For headlines, you can choose an expressive font, such as a display,\n     *   handwritten, or script style. These unconventional font designs have details and intricacy\n     *   that help attract the eye.\n     * @param headlineMedium headlineMedium is the second largest headline, reserved for short,\n     *   important text or numerals. For headlines, you can choose an expressive font, such as a\n     *   display, handwritten, or script style. These unconventional font designs have details and\n     *   intricacy that help attract the eye.\n     * @param headlineSmall headlineSmall is the smallest headline, reserved for short, important\n     *   text or numerals. For headlines, you can choose an expressive font, such as a display,\n     *   handwritten, or script style. These unconventional font designs have details and intricacy\n     *   that help attract the eye.\n     * @param titleLarge titleLarge is the largest title, and is typically reserved for\n     *   medium-emphasis text that is shorter in length. Serif or sans serif typefaces work well for\n     *   subtitles.\n     * @param titleMedium titleMedium is the second largest title, and is typically reserved for\n     *   medium-emphasis text that is shorter in length. Serif or sans serif typefaces work well for\n     *   subtitles.\n     * @param titleSmall titleSmall is the smallest title, and is typically reserved for\n     *   medium-emphasis text that is shorter in length. Serif or sans serif typefaces work well for\n     *   subtitles.\n     * @param bodyLarge bodyLarge is the largest body, and is typically used for long-form writing\n     *   as it works well for small text sizes. For longer sections of text, a serif or sans serif\n     *   typeface is recommended.\n     * @param bodyMedium bodyMedium is the second largest body, and is typically used for long-form\n     *   writing as it works well for small text sizes. For longer sections of text, a serif or sans\n     *   serif typeface is recommended.\n     * @param bodySmall bodySmall is the smallest body, and is typically used for long-form writing\n     *   as it works well for small text sizes. For longer sections of text, a serif or sans serif\n     *   typeface is recommended.\n     * @param labelLarge labelLarge text is a call to action used in different types of buttons\n     *   (such as text, outlined and contained buttons) and in tabs, dialogs, and cards. Button text\n     *   is typically sans serif, using all caps text.\n     * @param labelMedium labelMedium is one of the smallest font sizes. It is used sparingly to\n     *   annotate imagery or to introduce a headline.\n     * @param labelSmall labelSmall is one of the smallest font sizes. It is used sparingly to\n     *   annotate imagery or to introduce a headline.\n     */\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    constructor(\n        displayLarge: TextStyle = TypographyTokens.DisplayLarge,\n        displayMedium: TextStyle = TypographyTokens.DisplayMedium,\n        displaySmall: TextStyle = TypographyTokens.DisplaySmall,\n        headlineLarge: TextStyle = TypographyTokens.HeadlineLarge,\n        headlineMedium: TextStyle = TypographyTokens.HeadlineMedium,\n        headlineSmall: TextStyle = TypographyTokens.HeadlineSmall,\n        titleLarge: TextStyle = TypographyTokens.TitleLarge,\n        titleMedium: TextStyle = TypographyTokens.TitleMedium,\n        titleSmall: TextStyle = TypographyTokens.TitleSmall,\n        bodyLarge: TextStyle = TypographyTokens.BodyLarge,\n        bodyMedium: TextStyle = TypographyTokens.BodyMedium,\n        bodySmall: TextStyle = TypographyTokens.BodySmall,\n        labelLarge: TextStyle = TypographyTokens.LabelLarge,\n        labelMedium: TextStyle = TypographyTokens.LabelMedium,\n        labelSmall: TextStyle = TypographyTokens.LabelSmall,\n    ) : this(\n        displayLarge = displayLarge,\n        displayMedium = displayMedium,\n        displaySmall = displaySmall,\n        headlineLarge = headlineLarge,\n        headlineMedium = headlineMedium,\n        headlineSmall = headlineSmall,\n        titleLarge = titleLarge,\n        titleMedium = titleMedium,\n        titleSmall = titleSmall,\n        bodyLarge = bodyLarge,\n        bodyMedium = bodyMedium,\n        bodySmall = bodySmall,\n        labelLarge = labelLarge,\n        labelMedium = labelMedium,\n        labelSmall = labelSmall,\n        displayLargeEmphasized = displayLarge,\n        displayMediumEmphasized = displayMedium,\n        displaySmallEmphasized = displaySmall,\n        headlineLargeEmphasized = headlineLarge,\n        headlineMediumEmphasized = headlineMedium,\n        headlineSmallEmphasized = headlineSmall,\n        titleLargeEmphasized = titleLarge,\n        titleMediumEmphasized = titleMedium,\n        titleSmallEmphasized = titleSmall,\n        bodyLargeEmphasized = bodyLarge,\n        bodyMediumEmphasized = bodyMedium,\n        bodySmallEmphasized = bodySmall,\n        labelLargeEmphasized = labelLarge,\n        labelMediumEmphasized = labelMedium,\n        labelSmallEmphasized = labelSmall,\n    )\n\n    /** Returns a copy of this Typography, optionally overriding some of the values. */\n    @ExperimentalMaterial3ExpressiveApi\n    fun copy(\n        displayLarge: TextStyle = this.displayLarge,\n        displayMedium: TextStyle = this.displayMedium,\n        displaySmall: TextStyle = this.displaySmall,\n        headlineLarge: TextStyle = this.headlineLarge,\n        headlineMedium: TextStyle = this.headlineMedium,\n        headlineSmall: TextStyle = this.headlineSmall,\n        titleLarge: TextStyle = this.titleLarge,\n        titleMedium: TextStyle = this.titleMedium,\n        titleSmall: TextStyle = this.titleSmall,\n        bodyLarge: TextStyle = this.bodyLarge,\n        bodyMedium: TextStyle = this.bodyMedium,\n        bodySmall: TextStyle = this.bodySmall,\n        labelLarge: TextStyle = this.labelLarge,\n        labelMedium: TextStyle = this.labelMedium,\n        labelSmall: TextStyle = this.labelSmall,\n        displayLargeEmphasized: TextStyle = this.displayLargeEmphasized,\n        displayMediumEmphasized: TextStyle = this.displayMediumEmphasized,\n        displaySmallEmphasized: TextStyle = this.displaySmallEmphasized,\n        headlineLargeEmphasized: TextStyle = this.headlineLargeEmphasized,\n        headlineMediumEmphasized: TextStyle = this.headlineMediumEmphasized,\n        headlineSmallEmphasized: TextStyle = this.headlineSmallEmphasized,\n        titleLargeEmphasized: TextStyle = this.titleLargeEmphasized,\n        titleMediumEmphasized: TextStyle = this.titleMediumEmphasized,\n        titleSmallEmphasized: TextStyle = this.titleSmallEmphasized,\n        bodyLargeEmphasized: TextStyle = this.bodyLargeEmphasized,\n        bodyMediumEmphasized: TextStyle = this.bodyMediumEmphasized,\n        bodySmallEmphasized: TextStyle = this.bodySmallEmphasized,\n        labelLargeEmphasized: TextStyle = this.labelLargeEmphasized,\n        labelMediumEmphasized: TextStyle = this.labelMediumEmphasized,\n        labelSmallEmphasized: TextStyle = this.labelSmallEmphasized,\n    ): Typography =\n        Typography(\n            displayLarge = displayLarge,\n            displayMedium = displayMedium,\n            displaySmall = displaySmall,\n            headlineLarge = headlineLarge,\n            headlineMedium = headlineMedium,\n            headlineSmall = headlineSmall,\n            titleLarge = titleLarge,\n            titleMedium = titleMedium,\n            titleSmall = titleSmall,\n            bodyLarge = bodyLarge,\n            bodyMedium = bodyMedium,\n            bodySmall = bodySmall,\n            labelLarge = labelLarge,\n            labelMedium = labelMedium,\n            labelSmall = labelSmall,\n            displayLargeEmphasized = displayLargeEmphasized,\n            displayMediumEmphasized = displayMediumEmphasized,\n            displaySmallEmphasized = displaySmallEmphasized,\n            headlineLargeEmphasized = headlineLargeEmphasized,\n            headlineMediumEmphasized = headlineMediumEmphasized,\n            headlineSmallEmphasized = headlineSmallEmphasized,\n            titleLargeEmphasized = titleLargeEmphasized,\n            titleMediumEmphasized = titleMediumEmphasized,\n            titleSmallEmphasized = titleSmallEmphasized,\n            bodyLargeEmphasized = bodyLargeEmphasized,\n            bodyMediumEmphasized = bodyMediumEmphasized,\n            bodySmallEmphasized = bodySmallEmphasized,\n            labelLargeEmphasized = labelLargeEmphasized,\n            labelMediumEmphasized = labelMediumEmphasized,\n            labelSmallEmphasized = labelSmallEmphasized,\n        )\n\n    /** Returns a copy of this Typography, optionally overriding some of the values. */\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    fun copy(\n        displayLarge: TextStyle = this.displayLarge,\n        displayMedium: TextStyle = this.displayMedium,\n        displaySmall: TextStyle = this.displaySmall,\n        headlineLarge: TextStyle = this.headlineLarge,\n        headlineMedium: TextStyle = this.headlineMedium,\n        headlineSmall: TextStyle = this.headlineSmall,\n        titleLarge: TextStyle = this.titleLarge,\n        titleMedium: TextStyle = this.titleMedium,\n        titleSmall: TextStyle = this.titleSmall,\n        bodyLarge: TextStyle = this.bodyLarge,\n        bodyMedium: TextStyle = this.bodyMedium,\n        bodySmall: TextStyle = this.bodySmall,\n        labelLarge: TextStyle = this.labelLarge,\n        labelMedium: TextStyle = this.labelMedium,\n        labelSmall: TextStyle = this.labelSmall,\n    ): Typography =\n        copy(\n            displayLarge = displayLarge,\n            displayMedium = displayMedium,\n            displaySmall = displaySmall,\n            headlineLarge = headlineLarge,\n            headlineMedium = headlineMedium,\n            headlineSmall = headlineSmall,\n            titleLarge = titleLarge,\n            titleMedium = titleMedium,\n            titleSmall = titleSmall,\n            bodyLarge = bodyLarge,\n            bodyMedium = bodyMedium,\n            bodySmall = bodySmall,\n            labelLarge = labelLarge,\n            labelMedium = labelMedium,\n            labelSmall = labelSmall,\n            displayLargeEmphasized = this.displayLargeEmphasized,\n            displayMediumEmphasized = this.displayMediumEmphasized,\n            displaySmallEmphasized = this.displaySmallEmphasized,\n            headlineLargeEmphasized = this.headlineLargeEmphasized,\n            headlineMediumEmphasized = this.headlineMediumEmphasized,\n            headlineSmallEmphasized = this.headlineSmallEmphasized,\n            titleLargeEmphasized = this.titleLargeEmphasized,\n            titleMediumEmphasized = this.titleMediumEmphasized,\n            titleSmallEmphasized = this.titleSmallEmphasized,\n            bodyLargeEmphasized = this.bodyLargeEmphasized,\n            bodyMediumEmphasized = this.bodyMediumEmphasized,\n            bodySmallEmphasized = this.bodySmallEmphasized,\n            labelLargeEmphasized = this.labelLargeEmphasized,\n            labelMediumEmphasized = this.labelMediumEmphasized,\n            labelSmallEmphasized = this.labelSmallEmphasized,\n        )\n\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is Typography) return false\n\n        if (displayLarge != other.displayLarge) return false\n        if (displayMedium != other.displayMedium) return false\n        if (displaySmall != other.displaySmall) return false\n        if (headlineLarge != other.headlineLarge) return false\n        if (headlineMedium != other.headlineMedium) return false\n        if (headlineSmall != other.headlineSmall) return false\n        if (titleLarge != other.titleLarge) return false\n        if (titleMedium != other.titleMedium) return false\n        if (titleSmall != other.titleSmall) return false\n        if (bodyLarge != other.bodyLarge) return false\n        if (bodyMedium != other.bodyMedium) return false\n        if (bodySmall != other.bodySmall) return false\n        if (labelLarge != other.labelLarge) return false\n        if (labelMedium != other.labelMedium) return false\n        if (labelSmall != other.labelSmall) return false\n        if (displayLargeEmphasized != other.displayLargeEmphasized) return false\n        if (displayMediumEmphasized != other.displayMediumEmphasized) return false\n        if (displaySmallEmphasized != other.displaySmallEmphasized) return false\n        if (headlineLargeEmphasized != other.headlineLargeEmphasized) return false\n        if (headlineMediumEmphasized != other.headlineMediumEmphasized) return false\n        if (headlineSmallEmphasized != other.headlineSmallEmphasized) return false\n        if (titleLargeEmphasized != other.titleLargeEmphasized) return false\n        if (titleMediumEmphasized != other.titleMediumEmphasized) return false\n        if (titleSmallEmphasized != other.titleSmallEmphasized) return false\n        if (bodyLargeEmphasized != other.bodyLargeEmphasized) return false\n        if (bodyMediumEmphasized != other.bodyMediumEmphasized) return false\n        if (bodySmallEmphasized != other.bodySmallEmphasized) return false\n        if (labelLargeEmphasized != other.labelLargeEmphasized) return false\n        if (labelMediumEmphasized != other.labelMediumEmphasized) return false\n        if (labelSmallEmphasized != other.labelSmallEmphasized) return false\n        return true\n    }\n\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    override fun hashCode(): Int {\n        var result = displayLarge.hashCode()\n        result = 31 * result + displayMedium.hashCode()\n        result = 31 * result + displaySmall.hashCode()\n        result = 31 * result + headlineLarge.hashCode()\n        result = 31 * result + headlineMedium.hashCode()\n        result = 31 * result + headlineSmall.hashCode()\n        result = 31 * result + titleLarge.hashCode()\n        result = 31 * result + titleMedium.hashCode()\n        result = 31 * result + titleSmall.hashCode()\n        result = 31 * result + bodyLarge.hashCode()\n        result = 31 * result + bodyMedium.hashCode()\n        result = 31 * result + bodySmall.hashCode()\n        result = 31 * result + labelLarge.hashCode()\n        result = 31 * result + labelMedium.hashCode()\n        result = 31 * result + labelSmall.hashCode()\n        result = 31 * result + displayLargeEmphasized.hashCode()\n        result = 31 * result + displayMediumEmphasized.hashCode()\n        result = 31 * result + displaySmallEmphasized.hashCode()\n        result = 31 * result + headlineLargeEmphasized.hashCode()\n        result = 31 * result + headlineMediumEmphasized.hashCode()\n        result = 31 * result + headlineSmallEmphasized.hashCode()\n        result = 31 * result + titleLargeEmphasized.hashCode()\n        result = 31 * result + titleMediumEmphasized.hashCode()\n        result = 31 * result + titleSmallEmphasized.hashCode()\n        result = 31 * result + bodyLargeEmphasized.hashCode()\n        result = 31 * result + bodyMediumEmphasized.hashCode()\n        result = 31 * result + bodySmallEmphasized.hashCode()\n        result = 31 * result + labelLargeEmphasized.hashCode()\n        result = 31 * result + labelMediumEmphasized.hashCode()\n        result = 31 * result + labelSmallEmphasized.hashCode()\n        return result\n    }\n\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    override fun toString(): String {\n        return \"Typography(displayLarge=$displayLarge, displayMedium=$displayMedium,\" +\n            \"displaySmall=$displaySmall, \" +\n            \"headlineLarge=$headlineLarge, headlineMedium=$headlineMedium,\" +\n            \" headlineSmall=$headlineSmall, \" +\n            \"titleLarge=$titleLarge, titleMedium=$titleMedium, titleSmall=$titleSmall, \" +\n            \"bodyLarge=$bodyLarge, bodyMedium=$bodyMedium, bodySmall=$bodySmall, \" +\n            \"labelLarge=$labelLarge, labelMedium=$labelMedium, labelSmall=$labelSmall, \" +\n            \"displayLargeEmphasized=$displayLargeEmphasized, \" +\n            \"displayMediumEmphasized=$displayMediumEmphasized, \" +\n            \"displaySmallEmphasized=$displaySmallEmphasized, \" +\n            \"headlineLargeEmphasized=$headlineLargeEmphasized, \" +\n            \"headlineMediumEmphasized=$headlineMediumEmphasized, \" +\n            \"headlineSmallEmphasized=$headlineSmallEmphasized, \" +\n            \"titleLargeEmphasized=$titleLargeEmphasized, \" +\n            \"titleMediumEmphasized=$titleMediumEmphasized, \" +\n            \"titleSmallEmphasized=$titleSmallEmphasized, \" +\n            \"bodyLargeEmphasized=$bodyLargeEmphasized, \" +\n            \"bodyMediumEmphasized=$bodyMediumEmphasized, \" +\n            \"bodySmallEmphasized=$bodySmallEmphasized, \" +\n            \"labelLargeEmphasized=$labelLargeEmphasized, \" +\n            \"labelMediumEmphasized=$labelMediumEmphasized, \" +\n            \"labelSmallEmphasized=$labelSmallEmphasized)\"\n    }\n}\n\n/** Helper function for component typography tokens. */\n@OptIn(ExperimentalMaterial3ExpressiveApi::class)\ninternal fun Typography.fromToken(value: TypographyKeyTokens): TextStyle {\n    return when (value) {\n        TypographyKeyTokens.DisplayLarge -> displayLarge\n        TypographyKeyTokens.DisplayMedium -> displayMedium\n        TypographyKeyTokens.DisplaySmall -> displaySmall\n        TypographyKeyTokens.HeadlineLarge -> headlineLarge\n        TypographyKeyTokens.HeadlineMedium -> headlineMedium\n        TypographyKeyTokens.HeadlineSmall -> headlineSmall\n        TypographyKeyTokens.TitleLarge -> titleLarge\n        TypographyKeyTokens.TitleMedium -> titleMedium\n        TypographyKeyTokens.TitleSmall -> titleSmall\n        TypographyKeyTokens.BodyLarge -> bodyLarge\n        TypographyKeyTokens.BodyMedium -> bodyMedium\n        TypographyKeyTokens.BodySmall -> bodySmall\n        TypographyKeyTokens.LabelLarge -> labelLarge\n        TypographyKeyTokens.LabelMedium -> labelMedium\n        TypographyKeyTokens.LabelSmall -> labelSmall\n        TypographyKeyTokens.DisplayLargeEmphasized -> displayLargeEmphasized\n        TypographyKeyTokens.DisplayMediumEmphasized -> displayMediumEmphasized\n        TypographyKeyTokens.DisplaySmallEmphasized -> displaySmallEmphasized\n        TypographyKeyTokens.HeadlineLargeEmphasized -> headlineLargeEmphasized\n        TypographyKeyTokens.HeadlineMediumEmphasized -> headlineMediumEmphasized\n        TypographyKeyTokens.HeadlineSmallEmphasized -> headlineSmallEmphasized\n        TypographyKeyTokens.TitleLargeEmphasized -> titleLargeEmphasized\n        TypographyKeyTokens.TitleMediumEmphasized -> titleMediumEmphasized\n        TypographyKeyTokens.TitleSmallEmphasized -> titleSmallEmphasized\n        TypographyKeyTokens.BodyLargeEmphasized -> bodyLargeEmphasized\n        TypographyKeyTokens.BodyMediumEmphasized -> bodyMediumEmphasized\n        TypographyKeyTokens.BodySmallEmphasized -> bodySmallEmphasized\n        TypographyKeyTokens.LabelLargeEmphasized -> labelLargeEmphasized\n        TypographyKeyTokens.LabelMediumEmphasized -> labelMediumEmphasized\n        TypographyKeyTokens.LabelSmallEmphasized -> labelSmallEmphasized\n    }\n}\n\ninternal val TypographyKeyTokens.value: TextStyle\n    @Composable @ReadOnlyComposable get() = MaterialTheme.typography.fromToken(this)\n\ninternal val LocalTypography = staticCompositionLocalOf { Typography() }\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Shapes.kt\n```kotlin\n/*\n * Copyright 2022 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.foundation.shape.CircleShape\nimport androidx.compose.foundation.shape.CornerBasedShape\nimport androidx.compose.foundation.shape.CornerSize\nimport androidx.compose.material3.tokens.ShapeKeyTokens\nimport androidx.compose.material3.tokens.ShapeTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.ReadOnlyComposable\nimport androidx.compose.runtime.staticCompositionLocalOf\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.Shape\n\n/**\n * Material surfaces can be displayed in different shapes. Shapes direct attention, identify\n * components, communicate state, and express brand.\n *\n * The shape scale defines the style of container corners, offering a range of roundedness from\n * square to fully circular.\n *\n * There are different sizes of shapes:\n * - Extra Small\n * - Small\n * - Medium\n * - Large, Large Increased\n * - Extra Large, Extra Large Increased\n * - Extra Extra Large\n *\n * You can customize the shape system for all components in the [MaterialTheme] or you can do it on\n * a per component basis.\n *\n * You can change the shape that a component has by overriding the shape parameter for that\n * component. For example, by default, buttons use the shape style “full.” If your product requires\n * a smaller amount of roundedness, you can override the shape parameter with a different shape\n * value like [MaterialTheme.shapes.small].\n *\n * To learn more about shapes, see\n * [Material Design shapes](https://m3.material.io/styles/shape/overview).\n *\n * @param extraSmall A shape style with 4 same-sized corners whose size are bigger than\n *   [RectangleShape] and smaller than [Shapes.small]. By default autocomplete menu, select menu,\n *   snackbars, standard menu, and text fields use this shape.\n * @param small A shape style with 4 same-sized corners whose size are bigger than\n *   [Shapes.extraSmall] and smaller than [Shapes.medium]. By default chips use this shape.\n * @param medium A shape style with 4 same-sized corners whose size are bigger than [Shapes.small]\n *   and smaller than [Shapes.large]. By default cards and small FABs use this shape.\n * @param large A shape style with 4 same-sized corners whose size are bigger than [Shapes.medium]\n *   and smaller than [Shapes.extraLarge]. By default extended FABs, FABs, and navigation drawers\n *   use this shape.\n * @param extraLarge A shape style with 4 same-sized corners whose size are bigger than\n *   [Shapes.large] and smaller than [CircleShape]. By default large FABs use this shape.\n * @param largeIncreased A shape style with 4 same-sized corners whose size are bigger than\n *   [Shapes.medium] and smaller than [Shapes.extraLarge]. Slightly larger variant to\n *   [Shapes.large].\n * @param extraLargeIncreased A shape style with 4 same-sized corners whose size are bigger than\n *   [Shapes.large] and smaller than [Shapes.extraExtraLarge]. Slightly larger variant to\n *   [Shapes.extraLarge].\n * @param extraExtraLarge A shape style with 4 same-sized corners whose size are bigger than\n *   [Shapes.extraLarge] and smaller than [CircleShape].\n */\n// TODO: Update new shape descriptions to list what components leverage them by default.\n// TODO(b/368578382): Update 'increased' variant kdocs to reference design documentation.\n@Immutable\nclass Shapes\n@ExperimentalMaterial3ExpressiveApi\nconstructor(\n    // Shapes None and Full are omitted as None is a RectangleShape and Full is a CircleShape.\n    val extraSmall: CornerBasedShape = ShapeDefaults.ExtraSmall,\n    val small: CornerBasedShape = ShapeDefaults.Small,\n    val medium: CornerBasedShape = ShapeDefaults.Medium,\n    val large: CornerBasedShape = ShapeDefaults.Large,\n    val extraLarge: CornerBasedShape = ShapeDefaults.ExtraLarge,\n    largeIncreased: CornerBasedShape = ShapeDefaults.LargeIncreased,\n    extraLargeIncreased: CornerBasedShape = ShapeDefaults.ExtraLargeIncreased,\n    extraExtraLarge: CornerBasedShape = ShapeDefaults.ExtraExtraLarge,\n) {\n    @ExperimentalMaterial3ExpressiveApi\n    /**\n     * A shape style with 4 same-sized corners whose size are bigger than [Shapes.medium] and\n     * smaller than [Shapes.extraLarge]. Slightly larger variant to [Shapes.large].\n     */\n    val largeIncreased = largeIncreased\n\n    @ExperimentalMaterial3ExpressiveApi\n    /**\n     * A shape style with 4 same-sized corners whose size are bigger than [Shapes.large] and smaller\n     * than [Shapes.extraExtraLarge]. Slightly larger variant to [Shapes.extraLarge].\n     */\n    val extraLargeIncreased = extraLargeIncreased\n\n    @ExperimentalMaterial3ExpressiveApi\n    /**\n     * A shape style with 4 same-sized corners whose size are bigger than [Shapes.extraLarge] and\n     * smaller than [CircleShape].\n     */\n    val extraExtraLarge = extraExtraLarge\n\n    /**\n     * Material surfaces can be displayed in different shapes. Shapes direct attention, identify\n     * components, communicate state, and express brand.\n     *\n     * The shape scale defines the style of container corners, offering a range of roundedness from\n     * square to fully circular.\n     *\n     * There are different sizes of shapes:\n     * - Extra Small\n     * - Small\n     * - Medium\n     * - Large, Large Increased\n     * - Extra Large, Extra Large Increased\n     * - Extra Extra Large\n     *\n     * You can customize the shape system for all components in the [MaterialTheme] or you can do it\n     * on a per component basis.\n     *\n     * You can change the shape that a component has by overriding the shape parameter for that\n     * component. For example, by default, buttons use the shape style “full.” If your product\n     * requires a smaller amount of roundedness, you can override the shape parameter with a\n     * different shape value like [MaterialTheme.shapes.small].\n     *\n     * To learn more about shapes, see\n     * [Material Design shapes](https://m3.material.io/styles/shape/overview).\n     *\n     * @param extraSmall A shape style with 4 same-sized corners whose size are bigger than\n     *   [RectangleShape] and smaller than [Shapes.small]. By default autocomplete menu, select\n     *   menu, snackbars, standard menu, and text fields use this shape.\n     * @param small A shape style with 4 same-sized corners whose size are bigger than\n     *   [Shapes.extraSmall] and smaller than [Shapes.medium]. By default chips use this shape.\n     * @param medium A shape style with 4 same-sized corners whose size are bigger than\n     *   [Shapes.small] and smaller than [Shapes.large]. By default cards and small FABs use this\n     *   shape.\n     * @param large A shape style with 4 same-sized corners whose size are bigger than\n     *   [Shapes.medium] and smaller than [Shapes.extraLarge]. By default extended FABs, FABs, and\n     *   navigation drawers use this shape.\n     * @param extraLarge A shape style with 4 same-sized corners whose size are bigger than\n     *   [Shapes.large] and smaller than [CircleShape]. By default large FABs use this shape.\n     */\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    constructor(\n        extraSmall: CornerBasedShape = ShapeDefaults.ExtraSmall,\n        small: CornerBasedShape = ShapeDefaults.Small,\n        medium: CornerBasedShape = ShapeDefaults.Medium,\n        large: CornerBasedShape = ShapeDefaults.Large,\n        extraLarge: CornerBasedShape = ShapeDefaults.ExtraLarge,\n    ) : this(\n        extraSmall = extraSmall,\n        small = small,\n        medium = medium,\n        large = large,\n        extraLarge = extraLarge,\n        largeIncreased = ShapeDefaults.LargeIncreased,\n        extraLargeIncreased = ShapeDefaults.ExtraLargeIncreased,\n        extraExtraLarge = ShapeDefaults.ExtraExtraLarge,\n    )\n\n    /** Returns a copy of this Shapes, optionally overriding some of the values. */\n    @ExperimentalMaterial3ExpressiveApi\n    fun copy(\n        extraSmall: CornerBasedShape = this.extraSmall,\n        small: CornerBasedShape = this.small,\n        medium: CornerBasedShape = this.medium,\n        large: CornerBasedShape = this.large,\n        extraLarge: CornerBasedShape = this.extraLarge,\n        largeIncreased: CornerBasedShape = this.largeIncreased,\n        extraLargeIncreased: CornerBasedShape = this.extraLargeIncreased,\n        extraExtraLarge: CornerBasedShape = this.extraExtraLarge,\n    ): Shapes =\n        Shapes(\n            extraSmall = extraSmall,\n            small = small,\n            medium = medium,\n            large = large,\n            extraLarge = extraLarge,\n            largeIncreased = largeIncreased,\n            extraLargeIncreased = extraLargeIncreased,\n            extraExtraLarge = extraExtraLarge,\n        )\n\n    /** Returns a copy of this Shapes, optionally overriding some of the values. */\n    fun copy(\n        extraSmall: CornerBasedShape = this.extraSmall,\n        small: CornerBasedShape = this.small,\n        medium: CornerBasedShape = this.medium,\n        large: CornerBasedShape = this.large,\n        extraLarge: CornerBasedShape = this.extraLarge,\n    ): Shapes =\n        Shapes(\n            extraSmall = extraSmall,\n            small = small,\n            medium = medium,\n            large = large,\n            extraLarge = extraLarge,\n        )\n\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is Shapes) return false\n        if (extraSmall != other.extraSmall) return false\n        if (small != other.small) return false\n        if (medium != other.medium) return false\n        if (large != other.large) return false\n        if (extraLarge != other.extraLarge) return false\n        if (largeIncreased != other.largeIncreased) return false\n        if (extraLargeIncreased != other.extraLargeIncreased) return false\n        if (extraExtraLarge != other.extraExtraLarge) return false\n        return true\n    }\n\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    override fun hashCode(): Int {\n        var result = extraSmall.hashCode()\n        result = 31 * result + small.hashCode()\n        result = 31 * result + medium.hashCode()\n        result = 31 * result + large.hashCode()\n        result = 31 * result + extraLarge.hashCode()\n        result = 31 * result + largeIncreased.hashCode()\n        result = 31 * result + extraLargeIncreased.hashCode()\n        result = 31 * result + extraExtraLarge.hashCode()\n        return result\n    }\n\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    override fun toString(): String {\n        return \"Shapes(\" +\n            \"extraSmall=$extraSmall, \" +\n            \"small=$small, \" +\n            \"medium=$medium, \" +\n            \"large=$large, \" +\n            \"largeIncreased=$largeIncreased, \" +\n            \"extraLarge=$extraLarge, \" +\n            \"extralargeIncreased=$extraLargeIncreased, \" +\n            \"extraExtraLarge=$extraExtraLarge)\"\n    }\n\n    /** Cached shapes used in components */\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultButtonShapesCached: ButtonShapes? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultToggleButtonShapesCached: ToggleButtonShapes? = null\n    internal var defaultVerticalDragHandleShapesCached: DragHandleShapes? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultIconToggleButtonShapesCached: IconToggleButtonShapes? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultIconButtonShapesCached: IconButtonShapes? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultListItemShapesCached: ListItemShapes? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultMenuStandaloneItemShapesCached: MenuItemShapes? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultMenuLeadingItemShapesCached: MenuItemShapes? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultMenuMiddleItemShapesCached: MenuItemShapes? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultMenuTrailingItemShapesCached: MenuItemShapes? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultMenuStandaloneGroupShapesCached: MenuGroupShapes? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultMenuLeadingGroupShapesCached: MenuGroupShapes? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultMenuMiddleGroupShapesCached: MenuGroupShapes? = null\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal var defaultMenuTrailingGroupShapesCached: MenuGroupShapes? = null\n}\n\n/** Contains the default values used by [Shapes] */\nobject ShapeDefaults {\n    /** Extra small sized corner shape */\n    val ExtraSmall: CornerBasedShape = ShapeTokens.CornerExtraSmall\n\n    /** Small sized corner shape */\n    val Small: CornerBasedShape = ShapeTokens.CornerSmall\n\n    /** Medium sized corner shape */\n    val Medium: CornerBasedShape = ShapeTokens.CornerMedium\n\n    /** Large sized corner shape */\n    val Large: CornerBasedShape = ShapeTokens.CornerLarge\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** Large sized corner shape, slightly larger than [Large] */\n    val LargeIncreased: CornerBasedShape = ShapeTokens.CornerLargeIncreased\n\n    /** Extra large sized corner shape */\n    val ExtraLarge: CornerBasedShape = ShapeTokens.CornerExtraLarge\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** Extra large sized corner shape, slightly larger than [ExtraLarge] */\n    val ExtraLargeIncreased: CornerBasedShape = ShapeTokens.CornerExtraLargeIncreased\n\n    @ExperimentalMaterial3ExpressiveApi\n    /** An extra extra large (XXL) sized corner shape */\n    val ExtraExtraLarge: CornerBasedShape = ShapeTokens.CornerExtraExtraLarge\n\n    // TODO(b/368578382): Update 'increased' variant kdocs to reference design documentation.\n    /** A non-rounded corner size */\n    internal val CornerNone: CornerSize = ShapeTokens.CornerValueNone\n\n    /** An extra small rounded corner size */\n    internal val CornerExtraSmall: CornerSize = ShapeTokens.CornerValueExtraSmall\n\n    /** A small rounded corner size */\n    internal val CornerSmall: CornerSize = ShapeTokens.CornerValueSmall\n\n    /** A medium rounded corner size */\n    internal val CornerMedium: CornerSize = ShapeTokens.CornerValueMedium\n\n    /** A large rounded corner size */\n    internal val CornerLarge: CornerSize = ShapeTokens.CornerValueLarge\n\n    /** A large rounded corner size, slightly larger than [CornerLarge] */\n    internal val CornerLargeIncreased: CornerSize = ShapeTokens.CornerValueLargeIncreased\n\n    /** An extra large rounded corner size */\n    internal val CornerExtraLarge: CornerSize = ShapeTokens.CornerValueExtraLarge\n\n    /** An extra large rounded corner size, slightly larger than [CornerExtraLarge] */\n    internal val CornerExtraLargeIncreased: CornerSize = ShapeTokens.CornerValueExtraLargeIncreased\n\n    /** An extra extra large (XXL) rounded corner size */\n    internal val CornerExtraExtraLarge: CornerSize = ShapeTokens.CornerValueExtraExtraLarge\n\n    /** A fully rounded corner size */\n    internal val CornerFull: CornerSize = CornerSize(100)\n}\n\n/** Helper function for component shape tokens. Used to grab the top values of a shape parameter. */\ninternal fun CornerBasedShape.top(\n    bottomSize: CornerSize = ShapeDefaults.CornerNone\n): CornerBasedShape {\n    return copy(bottomStart = bottomSize, bottomEnd = bottomSize)\n}\n\n/**\n * Helper function for component shape tokens. Used to grab the bottom values of a shape parameter.\n */\ninternal fun CornerBasedShape.bottom(\n    topSize: CornerSize = ShapeDefaults.CornerNone\n): CornerBasedShape {\n    return copy(topStart = topSize, topEnd = topSize)\n}\n\n/**\n * Helper function for component shape tokens. Used to grab the start values of a shape parameter.\n */\ninternal fun CornerBasedShape.start(\n    endSize: CornerSize = ShapeDefaults.CornerNone\n): CornerBasedShape {\n    return copy(topEnd = endSize, bottomEnd = endSize)\n}\n\n/** Helper function for component shape tokens. Used to grab the end values of a shape parameter. */\ninternal fun CornerBasedShape.end(\n    startSize: CornerSize = ShapeDefaults.CornerNone\n): CornerBasedShape {\n    return copy(topStart = startSize, bottomStart = startSize)\n}\n\n/**\n * Helper function for component shape tokens. Here is an example on how to use component color\n * tokens: ``MaterialTheme.shapes.fromToken(FabPrimarySmallTokens.ContainerShape)``\n */\n@OptIn(ExperimentalMaterial3ExpressiveApi::class)\ninternal fun Shapes.fromToken(value: ShapeKeyTokens): Shape {\n    return when (value) {\n        ShapeKeyTokens.CornerExtraLarge -> extraLarge\n        ShapeKeyTokens.CornerExtraLargeIncreased -> extraLargeIncreased\n        ShapeKeyTokens.CornerExtraExtraLarge -> extraExtraLarge\n        ShapeKeyTokens.CornerExtraLargeTop -> extraLarge.top()\n        ShapeKeyTokens.CornerExtraSmall -> extraSmall\n        ShapeKeyTokens.CornerExtraSmallTop -> extraSmall.top()\n        ShapeKeyTokens.CornerFull -> CircleShape\n        ShapeKeyTokens.CornerLarge -> large\n        ShapeKeyTokens.CornerLargeIncreased -> largeIncreased\n        ShapeKeyTokens.CornerLargeEnd -> large.end()\n        ShapeKeyTokens.CornerLargeTop -> large.top()\n        ShapeKeyTokens.CornerMedium -> medium\n        ShapeKeyTokens.CornerNone -> RectangleShape\n        ShapeKeyTokens.CornerSmall -> small\n        ShapeKeyTokens.CornerLargeStart -> large.start()\n    }\n}\n\n/**\n * Converts a shape token key to the local shape provided by the theme The color is subscribed to\n * [LocalShapes] changes\n */\ninternal val ShapeKeyTokens.value: Shape\n    @Composable @ReadOnlyComposable get() = MaterialTheme.shapes.fromToken(this)\n\n/** CompositionLocal used to specify the default shapes for the surfaces. */\ninternal val LocalShapes = staticCompositionLocalOf { Shapes() }\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Button.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.FiniteAnimationSpec\nimport androidx.compose.animation.core.VectorConverter\nimport androidx.compose.foundation.BorderStroke\nimport androidx.compose.foundation.interaction.FocusInteraction\nimport androidx.compose.foundation.interaction.HoverInteraction\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.InteractionSource\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.interaction.collectIsPressedAsState\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.shape.CornerBasedShape\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material3.internal.ProvideContentColorTextStyle\nimport androidx.compose.material3.internal.animateElevation\nimport androidx.compose.material3.internal.rememberAnimatedShape\nimport androidx.compose.material3.tokens.BaselineButtonTokens\nimport androidx.compose.material3.tokens.ButtonLargeTokens\nimport androidx.compose.material3.tokens.ButtonMediumTokens\nimport androidx.compose.material3.tokens.ButtonSmallTokens\nimport androidx.compose.material3.tokens.ButtonXLargeTokens\nimport androidx.compose.material3.tokens.ButtonXSmallTokens\nimport androidx.compose.material3.tokens.ColorSchemeKeyTokens\nimport androidx.compose.material3.tokens.ElevatedButtonTokens\nimport androidx.compose.material3.tokens.FilledButtonTokens\nimport androidx.compose.material3.tokens.FilledTonalButtonTokens\nimport androidx.compose.material3.tokens.MotionSchemeKeyTokens\nimport androidx.compose.material3.tokens.OutlinedButtonTokens\nimport androidx.compose.material3.tokens.TextButtonTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.key\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.semantics.role\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\n\n/**\n * [Material Design button](https://m3.material.io/components/buttons/overview)\n *\n * Buttons help people initiate actions, from sending an email, to sharing a document, to liking a\n * post.\n *\n * ![Filled button\n * image](https://developer.android.com/images/reference/androidx/compose/material3/filled-button.png)\n *\n * Filled buttons are high-emphasis buttons. Filled buttons have the most visual impact after the\n * [FloatingActionButton], and should be used for important, final actions that complete a flow,\n * like \"Save\", \"Join now\", or \"Confirm\".\n *\n * @sample androidx.compose.material3.samples.ButtonSample\n * @sample androidx.compose.material3.samples.ButtonWithIconSample\n *\n * Button that uses a square shape instead of the default round shape:\n *\n * @sample androidx.compose.material3.samples.SquareButtonSample\n *\n * Button that utilizes the small design content padding:\n *\n * @sample androidx.compose.material3.samples.SmallButtonSample\n *\n * [Button] uses the small design spec as default. For a [Button] that uses the design for extra\n * small, medium, large, or extra large buttons:\n *\n * @sample androidx.compose.material3.samples.XSmallButtonWithIconSample\n * @sample androidx.compose.material3.samples.MediumButtonWithIconSample\n * @sample androidx.compose.material3.samples.LargeButtonWithIconSample\n * @sample androidx.compose.material3.samples.XLargeButtonWithIconSample\n *\n * Choose the best button for an action based on the amount of emphasis it needs. The more important\n * an action is, the higher emphasis its button should be.\n * - See [OutlinedButton] for a medium-emphasis button with a border.\n * - See [ElevatedButton] for an [FilledTonalButton] with a shadow.\n * - See [TextButton] for a low-emphasis button with no border.\n * - See [FilledTonalButton] for a middle ground between [OutlinedButton] and [Button].\n *\n * The default text style for internal [Text] components will be set to [Typography.labelLarge].\n *\n * @param onClick called when this button is clicked\n * @param modifier the [Modifier] to be applied to this button\n * @param enabled controls the enabled state of this button. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param shape defines the shape of this button's container, border (when [border] is not null),\n *   and shadow (when using [elevation])\n * @param colors [ButtonColors] that will be used to resolve the colors for this button in different\n *   states. See [ButtonDefaults.buttonColors].\n * @param elevation [ButtonElevation] used to resolve the elevation for this button in different\n *   states. This controls the size of the shadow below the button. See\n *   [ButtonElevation.shadowElevation].\n * @param border the border to draw around the container of this button\n * @param contentPadding the spacing values to apply internally between the container and the\n *   content\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this button. You can use this to change the button's appearance or\n *   preview the button in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @param content The content displayed on the button, expected to be text, icon or image.\n */\n@Composable\nfun Button(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    shape: Shape = ButtonDefaults.shape,\n    colors: ButtonColors = ButtonDefaults.buttonColors(),\n    elevation: ButtonElevation? = ButtonDefaults.buttonElevation(),\n    border: BorderStroke? = null,\n    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    val containerColor = colors.containerColor(enabled)\n    val contentColor = colors.contentColor(enabled)\n    val shadowElevation = elevation?.shadowElevation(enabled, interactionSource)?.value ?: 0.dp\n    Surface(\n        onClick = onClick,\n        modifier = modifier.semantics { role = Role.Button },\n        enabled = enabled,\n        shape = shape,\n        color = containerColor,\n        contentColor = contentColor,\n        shadowElevation = shadowElevation,\n        border = border,\n        interactionSource = interactionSource,\n    ) {\n        ProvideContentColorTextStyle(\n            contentColor = contentColor,\n            textStyle = MaterialTheme.typography.labelLarge,\n        ) {\n            Row(\n                Modifier.defaultMinSize(\n                        minWidth = ButtonDefaults.MinWidth,\n                        minHeight = ButtonDefaults.MinHeight,\n                    )\n                    .padding(contentPadding),\n                horizontalArrangement = Arrangement.Center,\n                verticalAlignment = Alignment.CenterVertically,\n                content = content,\n            )\n        }\n    }\n}\n\n// TODO add link to image of pressed button\n/**\n * [Material Design button](https://m3.material.io/components/buttons/overview)\n *\n * Buttons help people initiate actions, from sending an email, to sharing a document, to liking a\n * post. It also morphs between the shapes provided in [shapes] depending on the state of the\n * interaction with the button as long as the shapes provided our [CornerBasedShape]s. If a shape in\n * [shapes] isn't a [CornerBasedShape], then button will change between the [ButtonShapes] according\n * to user interaction.\n *\n * ![Filled button\n * image](https://developer.android.com/images/reference/androidx/compose/material3/filled-button.png)\n *\n * Filled buttons are high-emphasis buttons. Filled buttons have the most visual impact after the\n * [FloatingActionButton], and should be used for important, final actions that complete a flow,\n * like \"Save\", \"Join now\", or \"Confirm\".\n *\n * @sample androidx.compose.material3.samples.ButtonWithAnimatedShapeSample\n *\n * Choose the best button for an action based on the amount of emphasis it needs. The more important\n * an action is, the higher emphasis its button should be.\n * - See [OutlinedButton] for a medium-emphasis button with a border.\n * - See [ElevatedButton] for an [FilledTonalButton] with a shadow.\n * - See [TextButton] for a low-emphasis button with no border.\n * - See [FilledTonalButton] for a middle ground between [OutlinedButton] and [Button].\n *\n * The default text style for internal [Text] components will be set to [Typography.labelLarge].\n *\n * @param onClick called when this button is clicked\n * @param shapes the [ButtonShapes] that this button with morph between depending on the user's\n *   interaction with the button.\n * @param modifier the [Modifier] to be applied to this button\n * @param enabled controls the enabled state of this button. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param colors [ButtonColors] that will be used to resolve the colors for this button in different\n *   states. See [ButtonDefaults.buttonColors].\n * @param elevation [ButtonElevation] used to resolve the elevation for this button in different\n *   states. This controls the size of the shadow below the button. See\n *   [ButtonElevation.shadowElevation].\n * @param border the border to draw around the container of this button\n * @param contentPadding the spacing values to apply internally between the container and the\n *   content\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this button. You can use this to change the button's appearance or\n *   preview the button in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @param content The content displayed on the button, expected to be text, icon or image.\n */\n@Composable\n@ExperimentalMaterial3ExpressiveApi\nfun Button(\n    onClick: () -> Unit,\n    shapes: ButtonShapes,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: ButtonColors = ButtonDefaults.buttonColors(),\n    elevation: ButtonElevation? = ButtonDefaults.buttonElevation(),\n    border: BorderStroke? = null,\n    contentPadding: PaddingValues = ButtonDefaults.contentPaddingFor(ButtonDefaults.MinHeight),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    // TODO Load the motionScheme tokens from the component tokens file\n    // MotionSchemeKeyTokens.DefaultEffects is intentional here to prevent\n    // any bounce in this component.\n    val defaultAnimationSpec = MotionSchemeKeyTokens.DefaultEffects.value<Float>()\n    val pressed by interactionSource.collectIsPressedAsState()\n    val containerColor = colors.containerColor(enabled)\n    val contentColor = colors.contentColor(enabled)\n    val shadowElevation = elevation?.shadowElevation(enabled, interactionSource)?.value ?: 0.dp\n    val buttonShape = shapeByInteraction(shapes, pressed, defaultAnimationSpec)\n\n    Surface(\n        onClick = onClick,\n        modifier = modifier.semantics { role = Role.Button },\n        enabled = enabled,\n        shape = buttonShape,\n        color = containerColor,\n        contentColor = contentColor,\n        shadowElevation = shadowElevation,\n        border = border,\n        interactionSource = interactionSource,\n    ) {\n        ProvideContentColorTextStyle(\n            contentColor = contentColor,\n            textStyle = MaterialTheme.typography.labelLarge,\n        ) {\n            Row(\n                Modifier.defaultMinSize(\n                        minWidth = ButtonDefaults.MinWidth,\n                        minHeight = ButtonDefaults.MinHeight,\n                    )\n                    .padding(contentPadding),\n                horizontalArrangement = Arrangement.Center,\n                verticalAlignment = Alignment.CenterVertically,\n                content = content,\n            )\n        }\n    }\n}\n\n/**\n * [Material Design elevated button](https://m3.material.io/components/buttons/overview)\n *\n * Buttons help people initiate actions, from sending an email, to sharing a document, to liking a\n * post.\n *\n * ![Elevated button\n * image](https://developer.android.com/images/reference/androidx/compose/material3/elevated-button.png)\n *\n * Elevated buttons are high-emphasis buttons that are essentially [FilledTonalButton]s with a\n * shadow. To prevent shadow creep, only use them when absolutely necessary, such as when the button\n * requires visual separation from patterned container.\n *\n * @sample androidx.compose.material3.samples.ElevatedButtonSample\n *\n * Choose the best button for an action based on the amount of emphasis it needs. The more important\n * an action is, the higher emphasis its button should be.\n * - See [Button] for a high-emphasis button without a shadow, also known as a filled button.\n * - See [FilledTonalButton] for a middle ground between [OutlinedButton] and [Button].\n * - See [OutlinedButton] for a medium-emphasis button with a border.\n * - See [TextButton] for a low-emphasis button with no border.\n *\n * The default text style for internal [Text] components will be set to [Typography.labelLarge].\n *\n * @param onClick called when this button is clicked\n * @param modifier the [Modifier] to be applied to this button\n * @param enabled controls the enabled state of this button. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param shape defines the shape of this button's container, border (when [border] is not null),\n *   and shadow (when using [elevation])\n * @param colors [ButtonColors] that will be used to resolve the colors for this button in different\n *   states. See [ButtonDefaults.elevatedButtonColors].\n * @param elevation [ButtonElevation] used to resolve the elevation for this button in different\n *   states. This controls the size of the shadow below the button. Additionally, when the container\n *   color is [ColorScheme.surface], this controls the amount of primary color applied as an\n *   overlay. See [ButtonDefaults.elevatedButtonElevation].\n * @param border the border to draw around the container of this button\n * @param contentPadding the spacing values to apply internally between the container and the\n *   content\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this button. You can use this to change the button's appearance or\n *   preview the button in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @param content The content displayed on the button, expected to be text, icon or image.\n */\n@Composable\nfun ElevatedButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    shape: Shape = ButtonDefaults.elevatedShape,\n    colors: ButtonColors = ButtonDefaults.elevatedButtonColors(),\n    elevation: ButtonElevation? = ButtonDefaults.elevatedButtonElevation(),\n    border: BorderStroke? = null,\n    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) =\n    Button(\n        onClick = onClick,\n        modifier = modifier,\n        enabled = enabled,\n        shape = shape,\n        colors = colors,\n        elevation = elevation,\n        border = border,\n        contentPadding = contentPadding,\n        interactionSource = interactionSource,\n        content = content,\n    )\n\n// TODO add link to image of pressed elevated button\n/**\n * [Material Design elevated button](https://m3.material.io/components/buttons/overview)\n *\n * Buttons help people initiate actions, from sending an email, to sharing a document, to liking a\n * post. It also morphs between the shapes provided in [shapes] depending on the state of the\n * interaction with the button as long as the shapes provided our [CornerBasedShape]s. If a shape in\n * [shapes] isn't a [CornerBasedShape], then button will change between the [ButtonShapes] according\n * to user interaction.\n *\n * ![Elevated button\n * image](https://developer.android.com/images/reference/androidx/compose/material3/elevated-button.png)\n *\n * Elevated buttons are high-emphasis buttons that are essentially [FilledTonalButton]s with a\n * shadow. To prevent shadow creep, only use them when absolutely necessary, such as when the button\n * requires visual separation from patterned container.\n *\n * @sample androidx.compose.material3.samples.ElevatedButtonWithAnimatedShapeSample\n *\n * Choose the best button for an action based on the amount of emphasis it needs. The more important\n * an action is, the higher emphasis its button should be.\n * - See [Button] for a high-emphasis button without a shadow, also known as a filled button.\n * - See [FilledTonalButton] for a middle ground between [OutlinedButton] and [Button].\n * - See [OutlinedButton] for a medium-emphasis button with a border.\n * - See [TextButton] for a low-emphasis button with no border.\n *\n * The default text style for internal [Text] components will be set to [Typography.labelLarge].\n *\n * @param onClick called when this button is clicked\n * @param shapes the [ButtonShapes] that this button with morph between depending on the user's\n *   interaction with the button.\n * @param modifier the [Modifier] to be applied to this button\n * @param enabled controls the enabled state of this button. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param colors [ButtonColors] that will be used to resolve the colors for this button in different\n *   states. See [ButtonDefaults.elevatedButtonColors].\n * @param elevation [ButtonElevation] used to resolve the elevation for this button in different\n *   states. This controls the size of the shadow below the button. Additionally, when the container\n *   color is [ColorScheme.surface], this controls the amount of primary color applied as an\n *   overlay. See [ButtonDefaults.elevatedButtonElevation].\n * @param border the border to draw around the container of this button\n * @param contentPadding the spacing values to apply internally between the container and the\n *   content\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this button. You can use this to change the button's appearance or\n *   preview the button in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @param content The content displayed on the button, expected to be text, icon or image.\n */\n@Composable\n@ExperimentalMaterial3ExpressiveApi\nfun ElevatedButton(\n    onClick: () -> Unit,\n    shapes: ButtonShapes,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: ButtonColors = ButtonDefaults.elevatedButtonColors(),\n    elevation: ButtonElevation? = ButtonDefaults.elevatedButtonElevation(),\n    border: BorderStroke? = null,\n    contentPadding: PaddingValues = ButtonDefaults.contentPaddingFor(ButtonDefaults.MinHeight),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) =\n    Button(\n        onClick = onClick,\n        shapes = shapes,\n        modifier = modifier,\n        enabled = enabled,\n        colors = colors,\n        elevation = elevation,\n        border = border,\n        contentPadding = contentPadding,\n        interactionSource = interactionSource,\n        content = content,\n    )\n\n/**\n * [Material Design filled tonal button](https://m3.material.io/components/buttons/overview)\n *\n * Buttons help people initiate actions, from sending an email, to sharing a document, to liking a\n * post.\n *\n * ![Filled tonal button\n * image](https://developer.android.com/images/reference/androidx/compose/material3/filled-tonal-button.png)\n *\n * Filled tonal buttons are medium-emphasis buttons that is an alternative middle ground between\n * default [Button]s (filled) and [OutlinedButton]s. They can be used in contexts where\n * lower-priority button requires slightly more emphasis than an outline would give, such as \"Next\"\n * in an onboarding flow. Tonal buttons use the secondary color mapping.\n *\n * @sample androidx.compose.material3.samples.FilledTonalButtonSample\n *\n * Choose the best button for an action based on the amount of emphasis it needs. The more important\n * an action is, the higher emphasis its button should be.\n * - See [Button] for a high-emphasis button without a shadow, also known as a filled button.\n * - See [ElevatedButton] for a [FilledTonalButton] with a shadow.\n * - See [OutlinedButton] for a medium-emphasis button with a border.\n * - See [TextButton] for a low-emphasis button with no border.\n *\n * The default text style for internal [Text] components will be set to [Typography.labelLarge].\n *\n * @param onClick called when this button is clicked\n * @param modifier the [Modifier] to be applied to this button\n * @param enabled controls the enabled state of this button. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param shape defines the shape of this button's container, border (when [border] is not null),\n *   and shadow (when using [elevation])\n * @param colors [ButtonColors] that will be used to resolve the colors for this button in different\n *   states. See [ButtonDefaults.filledTonalButtonColors].\n * @param elevation [ButtonElevation] used to resolve the elevation for this button in different\n *   states. This controls the size of the shadow below the button. Additionally, when the container\n *   color is [ColorScheme.surface], this controls the amount of primary color applied as an\n *   overlay.\n * @param border the border to draw around the container of this button\n * @param contentPadding the spacing values to apply internally between the container and the\n *   content\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this button. You can use this to change the button's appearance or\n *   preview the button in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @param content The content displayed on the button, expected to be text, icon or image.\n */\n@Composable\nfun FilledTonalButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    shape: Shape = ButtonDefaults.filledTonalShape,\n    colors: ButtonColors = ButtonDefaults.filledTonalButtonColors(),\n    elevation: ButtonElevation? = ButtonDefaults.filledTonalButtonElevation(),\n    border: BorderStroke? = null,\n    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) =\n    Button(\n        onClick = onClick,\n        modifier = modifier,\n        enabled = enabled,\n        shape = shape,\n        colors = colors,\n        elevation = elevation,\n        border = border,\n        contentPadding = contentPadding,\n        interactionSource = interactionSource,\n        content = content,\n    )\n\n// TODO add link to image of pressed filled tonal button\n/**\n * [Material Design filled tonal button](https://m3.material.io/components/buttons/overview)\n *\n * Buttons help people initiate actions, from sending an email, to sharing a document, to liking a\n * post. It also morphs between the shapes provided in [shapes] depending on the state of the\n * interaction with the button as long as the shapes provided our [CornerBasedShape]s. If a shape in\n * [shapes] isn't a [CornerBasedShape], then button will change between the [ButtonShapes] according\n * to user interaction.\n *\n * ![Filled tonal button\n * image](https://developer.android.com/images/reference/androidx/compose/material3/filled-tonal-button.png)\n *\n * Filled tonal buttons are medium-emphasis buttons that is an alternative middle ground between\n * default [Button]s (filled) and [OutlinedButton]s. They can be used in contexts where\n * lower-priority button requires slightly more emphasis than an outline would give, such as \"Next\"\n * in an onboarding flow. Tonal buttons use the secondary color mapping.\n *\n * @sample androidx.compose.material3.samples.FilledTonalButtonWithAnimatedShapeSample\n *\n * Choose the best button for an action based on the amount of emphasis it needs. The more important\n * an action is, the higher emphasis its button should be.\n * - See [Button] for a high-emphasis button without a shadow, also known as a filled button.\n * - See [ElevatedButton] for a [FilledTonalButton] with a shadow.\n * - See [OutlinedButton] for a medium-emphasis button with a border.\n * - See [TextButton] for a low-emphasis button with no border.\n *\n * The default text style for internal [Text] components will be set to [Typography.labelLarge].\n *\n * @param onClick called when this button is clicked\n * @param shapes the [ButtonShapes] that this button with morph between depending on the user's\n *   interaction with the button.\n * @param modifier the [Modifier] to be applied to this button\n * @param enabled controls the enabled state of this button. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param colors [ButtonColors] that will be used to resolve the colors for this button in different\n *   states. See [ButtonDefaults.filledTonalButtonColors].\n * @param elevation [ButtonElevation] used to resolve the elevation for this button in different\n *   states. This controls the size of the shadow below the button. Additionally, when the container\n *   color is [ColorScheme.surface], this controls the amount of primary color applied as an\n *   overlay.\n * @param border the border to draw around the container of this button\n * @param contentPadding the spacing values to apply internally between the container and the\n *   content\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this button. You can use this to change the button's appearance or\n *   preview the button in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @param content The content displayed on the button, expected to be text, icon or image.\n */\n@Composable\n@ExperimentalMaterial3ExpressiveApi\nfun FilledTonalButton(\n    onClick: () -> Unit,\n    shapes: ButtonShapes,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: ButtonColors = ButtonDefaults.filledTonalButtonColors(),\n    elevation: ButtonElevation? = ButtonDefaults.filledTonalButtonElevation(),\n    border: BorderStroke? = null,\n    contentPadding: PaddingValues = ButtonDefaults.contentPaddingFor(ButtonDefaults.MinHeight),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) =\n    Button(\n        onClick = onClick,\n        shapes = shapes,\n        modifier = modifier,\n        enabled = enabled,\n        colors = colors,\n        elevation = elevation,\n        border = border,\n        contentPadding = contentPadding,\n        interactionSource = interactionSource,\n        content = content,\n    )\n\n/**\n * [Material Design outlined button](https://m3.material.io/components/buttons/overview)\n *\n * Buttons help people initiate actions, from sending an email, to sharing a document, to liking a\n * post.\n *\n * ![Outlined button\n * image](https://developer.android.com/images/reference/androidx/compose/material3/outlined-button.png)\n *\n * Outlined buttons are medium-emphasis buttons. They contain actions that are important, but are\n * not the primary action in an app. Outlined buttons pair well with [Button]s to indicate an\n * alternative, secondary action.\n *\n * @sample androidx.compose.material3.samples.OutlinedButtonSample\n *\n * Choose the best button for an action based on the amount of emphasis it needs. The more important\n * an action is, the higher emphasis its button should be.\n * - See [Button] for a high-emphasis button without a shadow, also known as a filled button.\n * - See [FilledTonalButton] for a middle ground between [OutlinedButton] and [Button].\n * - See [OutlinedButton] for a medium-emphasis button with a border.\n * - See [TextButton] for a low-emphasis button with no border.\n *\n * The default text style for internal [Text] components will be set to [Typography.labelLarge].\n *\n * @param onClick called when this button is clicked\n * @param modifier the [Modifier] to be applied to this button\n * @param enabled controls the enabled state of this button. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param shape defines the shape of this button's container, border (when [border] is not null),\n *   and shadow (when using [elevation]).\n * @param colors [ButtonColors] that will be used to resolve the colors for this button in different\n *   states. See [ButtonDefaults.outlinedButtonColors].\n * @param elevation [ButtonElevation] used to resolve the elevation for this button in different\n *   states. This controls the size of the shadow below the button. Additionally, when the container\n *   color is [ColorScheme.surface], this controls the amount of primary color applied as an\n *   overlay.\n * @param border the border to draw around the container of this button. Pass `null` for no border.\n * @param contentPadding the spacing values to apply internally between the container and the\n *   content\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this button. You can use this to change the button's appearance or\n *   preview the button in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @param content The content displayed on the button, expected to be text, icon or image.\n */\n@Composable\nfun OutlinedButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    shape: Shape = ButtonDefaults.outlinedShape,\n    colors: ButtonColors = ButtonDefaults.outlinedButtonColors(),\n    elevation: ButtonElevation? = null,\n    border: BorderStroke? = ButtonDefaults.outlinedButtonBorder(enabled),\n    contentPadding: PaddingValues = ButtonDefaults.ContentPadding,\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) =\n    Button(\n        onClick = onClick,\n        modifier = modifier,\n        enabled = enabled,\n        shape = shape,\n        colors = colors,\n        elevation = elevation,\n        border = border,\n        contentPadding = contentPadding,\n        interactionSource = interactionSource,\n        content = content,\n    )\n\n// TODO add link to image of pressed outlined button\n/**\n * [Material Design outlined button](https://m3.material.io/components/buttons/overview)\n *\n * Buttons help people initiate actions, from sending an email, to sharing a document, to liking a\n * post. It also morphs between the shapes provided in [shapes] depending on the state of the\n * interaction with the button as long as the shapes provided our [CornerBasedShape]s. If a shape in\n * [shapes] isn't a [CornerBasedShape], then button will change between the [ButtonShapes] according\n * to user interaction.\n *\n * ![Outlined button\n * image](https://developer.android.com/images/reference/androidx/compose/material3/outlined-button.png)\n *\n * Outlined buttons are medium-emphasis buttons. They contain actions that are important, but are\n * not the primary action in an app. Outlined buttons pair well with [Button]s to indicate an\n * alternative, secondary action.\n *\n * @sample androidx.compose.material3.samples.OutlinedButtonWithAnimatedShapeSample\n *\n * Choose the best button for an action based on the amount of emphasis it needs. The more important\n * an action is, the higher emphasis its button should be.\n * - See [Button] for a high-emphasis button without a shadow, also known as a filled button.\n * - See [FilledTonalButton] for a middle ground between [OutlinedButton] and [Button].\n * - See [OutlinedButton] for a medium-emphasis button with a border.\n * - See [TextButton] for a low-emphasis button with no border.\n *\n * The default text style for internal [Text] components will be set to [Typography.labelLarge].\n *\n * @param onClick called when this button is clicked\n * @param shapes the [ButtonShapes] that this button with morph between depending on the user's\n *   interaction with the button.\n * @param modifier the [Modifier] to be applied to this button\n * @param enabled controls the enabled state of this button. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param colors [ButtonColors] that will be used to resolve the colors for this button in different\n *   states. See [ButtonDefaults.outlinedButtonColors].\n * @param elevation [ButtonElevation] used to resolve the elevation for this button in different\n *   states. This controls the size of the shadow below the button. Additionally, when the container\n *   color is [ColorScheme.surface], this controls the amount of primary color applied as an\n *   overlay.\n * @param border the border to draw around the container of this button. Pass `null` for no border.\n * @param contentPadding the spacing values to apply internally between the container and the\n *   content\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this button. You can use this to change the button's appearance or\n *   preview the button in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @param content The content displayed on the button, expected to be text, icon or image.\n */\n@Composable\n@ExperimentalMaterial3ExpressiveApi\nfun OutlinedButton(\n    onClick: () -> Unit,\n    shapes: ButtonShapes,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: ButtonColors = ButtonDefaults.outlinedButtonColors(),\n    elevation: ButtonElevation? = null,\n    border: BorderStroke? = ButtonDefaults.outlinedButtonBorder(enabled),\n    contentPadding: PaddingValues = ButtonDefaults.contentPaddingFor(ButtonDefaults.MinHeight),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) =\n    Button(\n        onClick = onClick,\n        shapes = shapes,\n        modifier = modifier,\n        enabled = enabled,\n        colors = colors,\n        elevation = elevation,\n        border = border,\n        contentPadding = contentPadding,\n        interactionSource = interactionSource,\n        content = content,\n    )\n\n/**\n * [Material Design text button](https://m3.material.io/components/buttons/overview)\n *\n * Buttons help people initiate actions, from sending an email, to sharing a document, to liking a\n * post.\n *\n * ![Text button\n * image](https://developer.android.com/images/reference/androidx/compose/material3/text-button.png)\n *\n * Text buttons are typically used for less-pronounced actions, including those located in dialogs\n * and cards. In cards, text buttons help maintain an emphasis on card content. Text buttons are\n * used for the lowest priority actions, especially when presenting multiple options.\n *\n * @sample androidx.compose.material3.samples.TextButtonWithAnimatedShapeSample\n *\n * Choose the best button for an action based on the amount of emphasis it needs. The more important\n * an action is, the higher emphasis its button should be.\n * - See [Button] for a high-emphasis button without a shadow, also known as a filled button.\n * - See [ElevatedButton] for a [FilledTonalButton] with a shadow.\n * - See [FilledTonalButton] for a middle ground between [OutlinedButton] and [Button].\n * - See [OutlinedButton] for a medium-emphasis button with a border.\n *\n * The default text style for internal [Text] components will be set to [Typography.labelLarge].\n *\n * @param onClick called when this button is clicked\n * @param modifier the [Modifier] to be applied to this button\n * @param enabled controls the enabled state of this button. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param shape defines the shape of this button's container, border (when [border] is not null),\n *   and shadow (when using [elevation])\n * @param colors [ButtonColors] that will be used to resolve the colors for this button in different\n *   states. See [ButtonDefaults.textButtonColors].\n * @param elevation [ButtonElevation] used to resolve the elevation for this button in different\n *   states. This controls the size of the shadow below the button. Additionally, when the container\n *   color is [ColorScheme.surface], this controls the amount of primary color applied as an\n *   overlay. A TextButton typically has no elevation, and the default value is `null`. See\n *   [ElevatedButton] for a button with elevation.\n * @param border the border to draw around the container of this button\n * @param contentPadding the spacing values to apply internally between the container and the\n *   content\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this button. You can use this to change the button's appearance or\n *   preview the button in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @param content The content displayed on the button, expected to be text.\n */\n@Composable\nfun TextButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    shape: Shape = ButtonDefaults.textShape,\n    colors: ButtonColors = ButtonDefaults.textButtonColors(),\n    elevation: ButtonElevation? = null,\n    border: BorderStroke? = null,\n    contentPadding: PaddingValues = ButtonDefaults.TextButtonContentPadding,\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) =\n    Button(\n        onClick = onClick,\n        modifier = modifier,\n        enabled = enabled,\n        shape = shape,\n        colors = colors,\n        elevation = elevation,\n        border = border,\n        contentPadding = contentPadding,\n        interactionSource = interactionSource,\n        content = content,\n    )\n\n// TODO add link to image of pressed text button\n/**\n * [Material Design text button](https://m3.material.io/components/buttons/overview)\n *\n * Buttons help people initiate actions, from sending an email, to sharing a document, to liking a\n * post. It also morphs between the shapes provided in [shapes] depending on the state of the\n * interaction with the button as long as the shapes provided our [CornerBasedShape]s. If a shape in\n * [shapes] isn't a [CornerBasedShape], then button will change between the [ButtonShapes] according\n * to user interaction.\n *\n * ![Text button\n * image](https://developer.android.com/images/reference/androidx/compose/material3/text-button.png)\n *\n * Text buttons are typically used for less-pronounced actions, including those located in dialogs\n * and cards. In cards, text buttons help maintain an emphasis on card content. Text buttons are\n * used for the lowest priority actions, especially when presenting multiple options.\n *\n * @sample androidx.compose.material3.samples.TextButtonSample\n *\n * Choose the best button for an action based on the amount of emphasis it needs. The more important\n * an action is, the higher emphasis its button should be.\n * - See [Button] for a high-emphasis button without a shadow, also known as a filled button.\n * - See [ElevatedButton] for a [FilledTonalButton] with a shadow.\n * - See [FilledTonalButton] for a middle ground between [OutlinedButton] and [Button].\n * - See [OutlinedButton] for a medium-emphasis button with a border.\n *\n * The default text style for internal [Text] components will be set to [Typography.labelLarge].\n *\n * @param onClick called when this button is clicked\n * @param shapes the [ButtonShapes] that this button with morph between depending on the user's\n *   interaction with the button.\n * @param modifier the [Modifier] to be applied to this button\n * @param enabled controls the enabled state of this button. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param colors [ButtonColors] that will be used to resolve the colors for this button in different\n *   states. See [ButtonDefaults.textButtonColors].\n * @param elevation [ButtonElevation] used to resolve the elevation for this button in different\n *   states. This controls the size of the shadow below the button. Additionally, when the container\n *   color is [ColorScheme.surface], this controls the amount of primary color applied as an\n *   overlay. A TextButton typically has no elevation, and the default value is `null`. See\n *   [ElevatedButton] for a button with elevation.\n * @param border the border to draw around the container of this button\n * @param contentPadding the spacing values to apply internally between the container and the\n *   content\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this button. You can use this to change the button's appearance or\n *   preview the button in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @param content The content displayed on the button, expected to be text.\n */\n@ExperimentalMaterial3ExpressiveApi\n@Composable\nfun TextButton(\n    onClick: () -> Unit,\n    shapes: ButtonShapes,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: ButtonColors = ButtonDefaults.textButtonColors(),\n    elevation: ButtonElevation? = null,\n    border: BorderStroke? = null,\n    contentPadding: PaddingValues = ButtonDefaults.contentPaddingFor(ButtonDefaults.MinHeight),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) =\n    Button(\n        onClick = onClick,\n        shapes = shapes,\n        modifier = modifier,\n        enabled = enabled,\n        colors = colors,\n        elevation = elevation,\n        border = border,\n        contentPadding = contentPadding,\n        interactionSource = interactionSource,\n        content = content,\n    )\n\n// TODO(b/201341237): Use token values for 0 elevation?\n// TODO(b/201341237): Use token values for null border?\n// TODO(b/201341237): Use token values for no color (transparent)?\n/**\n * Contains the default values used by all 5 button types.\n *\n * Default values that apply to all buttons types are [MinWidth], [MinHeight], [IconSize], and\n * [IconSpacing].\n *\n * A default value that applies only to [Button], [ElevatedButton], [FilledTonalButton], and\n * [OutlinedButton] is [ContentPadding].\n *\n * Default values that apply only to [Button] are [buttonColors] and [buttonElevation]. Default\n * values that apply only to [ElevatedButton] are [elevatedButtonColors] and\n * [elevatedButtonElevation]. Default values that apply only to [FilledTonalButton] are\n * [filledTonalButtonColors] and [filledTonalButtonElevation]. A default value that applies only to\n * [OutlinedButton] is [outlinedButtonColors]. Default values that apply only to [TextButton] is\n * [textButtonColors].\n */\nobject ButtonDefaults {\n\n    private val ButtonLeadingSpace = BaselineButtonTokens.LeadingSpace\n    private val ButtonTrailingSpace = BaselineButtonTokens.TrailingSpace\n    private val ButtonWithIconStartpadding = 16.dp\n    private val SmallStartPadding = ButtonSmallTokens.LeadingSpace\n    private val SmallEndPadding = ButtonSmallTokens.TrailingSpace\n    private val ButtonVerticalPadding = 8.dp\n\n    /**\n     * The default content padding used by [Button], [ElevatedButton], [FilledTonalButton],\n     * [OutlinedButton], and [TextButton] buttons.\n     * - See [ButtonWithIconContentPadding] for content padding used by [Button] that contains\n     *   [Icon].\n     */\n    val ContentPadding =\n        PaddingValues(\n            start = ButtonLeadingSpace,\n            top = ButtonVerticalPadding,\n            end = ButtonTrailingSpace,\n            bottom = ButtonVerticalPadding,\n        )\n\n    /** The default content padding used by [Button] that contains an [Icon]. */\n    val ButtonWithIconContentPadding =\n        PaddingValues(\n            start = ButtonWithIconStartpadding,\n            top = ButtonVerticalPadding,\n            end = ButtonTrailingSpace,\n            bottom = ButtonVerticalPadding,\n        )\n\n    /** The default content padding used for small [Button] */\n    @Deprecated(\"For binary compatibility\", level = DeprecationLevel.HIDDEN)\n    @ExperimentalMaterial3ExpressiveApi\n    val SmallButtonContentPadding\n        get() =\n            PaddingValues(\n                start = SmallStartPadding,\n                top = ButtonVerticalPadding,\n                end = SmallEndPadding,\n                bottom = ButtonVerticalPadding,\n            )\n\n    /** The default content padding used for small [Button] */\n    @ExperimentalMaterial3ExpressiveApi\n    val SmallContentPadding\n        get() =\n            PaddingValues(\n                start = SmallStartPadding,\n                top = SmallVerticalPadding,\n                end = SmallEndPadding,\n                bottom = SmallVerticalPadding,\n            )\n\n    private fun getSmallContentPadding(hasStartIcon: Boolean, hasEndIcon: Boolean) =\n        PaddingValues(\n            start = if (hasStartIcon) IconSmallHorizontalPadding else SmallStartPadding,\n            top = SmallVerticalPadding,\n            end = if (hasEndIcon) IconSmallHorizontalPadding else SmallEndPadding,\n            bottom = SmallVerticalPadding,\n        )\n\n    /** Default content padding for an extra small button. */\n    @ExperimentalMaterial3ExpressiveApi\n    val ExtraSmallContentPadding\n        get() =\n            PaddingValues(\n                // TODO update with the value from ButtonXSmallTokens.kt once it's been corrected\n                start = 12.dp,\n                end = 12.dp,\n                top = 6.dp,\n                bottom = 6.dp,\n            )\n\n    /** Default content padding for a medium button. */\n    @ExperimentalMaterial3ExpressiveApi\n    val MediumContentPadding\n        get() =\n            PaddingValues(\n                start = MediumLeadingPadding,\n                top = MediumVerticalPadding,\n                end = MediumTrailingPadding,\n                bottom = MediumVerticalPadding,\n            )\n\n    private fun getMediumContentPadding(hasLeadingIcon: Boolean, hasTrailingIcon: Boolean) =\n        PaddingValues(\n            start = if (hasLeadingIcon) IconMediumLeadingPadding else MediumLeadingPadding,\n            top = MediumVerticalPadding,\n            end = if (hasTrailingIcon) IconMediumTrailingPadding else MediumTrailingPadding,\n            bottom = MediumVerticalPadding,\n        )\n\n    /** Default content padding for a large button. */\n    @ExperimentalMaterial3ExpressiveApi\n    val LargeContentPadding\n        get() =\n            PaddingValues(\n                start = LargeLeadingPadding,\n                top = LargeVerticalPadding,\n                end = LargeTrailingPadding,\n                bottom = LargeVerticalPadding,\n            )\n\n    private fun getLargeContentPadding(hasLeadingIcon: Boolean, hasTrailingIcon: Boolean) =\n        PaddingValues(\n            start = if (hasLeadingIcon) IconLargeLeadingPadding else LargeLeadingPadding,\n            top = LargeVerticalPadding,\n            end = if (hasTrailingIcon) IconLargeTrailingPadding else LargeTrailingPadding,\n            bottom = LargeVerticalPadding,\n        )\n\n    /** Default content padding for an extra large button. */\n    @ExperimentalMaterial3ExpressiveApi\n    val ExtraLargeContentPadding\n        get() =\n            PaddingValues(\n                start = ButtonXLargeTokens.LeadingSpace,\n                end = ButtonXLargeTokens.TrailingSpace,\n                top = 48.dp,\n                bottom = 48.dp,\n            )\n\n    private val TextButtonHorizontalPadding = 12.dp\n\n    /**\n     * The default content padding used by [TextButton].\n     * - See [TextButtonWithIconContentPadding] for content padding used by [TextButton] that\n     *   contains [Icon].\n     *\n     * Note: it's recommended to use [ContentPadding] instead for a more consistent look between all\n     * buttons variants.\n     */\n    val TextButtonContentPadding =\n        PaddingValues(\n            start = TextButtonHorizontalPadding,\n            top = ContentPadding.calculateTopPadding(),\n            end = TextButtonHorizontalPadding,\n            bottom = ContentPadding.calculateBottomPadding(),\n        )\n\n    private val TextButtonWithIconHorizontalEndPadding = 16.dp\n\n    /**\n     * The default content padding used by [TextButton] that contains an [Icon].\n     *\n     * Note: it's recommended to use [ButtonWithIconContentPadding] instead for a more consistent\n     * look between all buttons variants.\n     */\n    val TextButtonWithIconContentPadding =\n        PaddingValues(\n            start = TextButtonHorizontalPadding,\n            top = ContentPadding.calculateTopPadding(),\n            end = TextButtonWithIconHorizontalEndPadding,\n            bottom = ContentPadding.calculateBottomPadding(),\n        )\n\n    /**\n     * The default min width applied for small buttons. Note that you can override it by applying\n     * Modifier.widthIn directly on the button composable.\n     */\n    val MinWidth = 58.dp\n\n    /**\n     * The default min height applied for small buttons. Note that you can override it by applying\n     * Modifier.heightIn directly on the button composable.\n     */\n    val MinHeight =\n        if (shouldUsePrecisionPointerComponentSizing.value) {\n            36.dp\n        } else {\n            ButtonSmallTokens.ContainerHeight\n        }\n\n    /** The default height for a extra small button container. */\n    @ExperimentalMaterial3ExpressiveApi\n    val ExtraSmallContainerHeight = ButtonXSmallTokens.ContainerHeight\n\n    /** The default height for a medium button container. */\n    @ExperimentalMaterial3ExpressiveApi\n    val MediumContainerHeight =\n        if (shouldUsePrecisionPointerComponentSizing.value) {\n            46.dp\n        } else {\n            ButtonMediumTokens.ContainerHeight\n        }\n\n    /** The default height for a large button container. */\n    @ExperimentalMaterial3ExpressiveApi\n    val LargeContainerHeight =\n        if (shouldUsePrecisionPointerComponentSizing.value) {\n            54.dp\n        } else {\n            ButtonLargeTokens.ContainerHeight\n        }\n\n    /** The default height for a extra large button container. */\n    @ExperimentalMaterial3ExpressiveApi\n    val ExtraLargeContainerHeight = ButtonXLargeTokens.ContainerHeight\n\n    /** The default size of the icon when used inside a small button. */\n    // TODO update with the correct value in BaselineButtonTokens when available\n    val IconSize = 18.dp\n\n    /** The default size of the icon used inside an extra small button. */\n    @ExperimentalMaterial3ExpressiveApi val ExtraSmallIconSize = ButtonXSmallTokens.IconSize\n\n    /** The expressive size of the icon used inside a small button. */\n    @ExperimentalMaterial3ExpressiveApi val SmallIconSize = ButtonSmallTokens.IconSize\n\n    /** The default size of the icon used inside a medium button. */\n    @ExperimentalMaterial3ExpressiveApi val MediumIconSize = ButtonMediumTokens.IconSize\n\n    /** The default size of the icon used inside a large button. */\n    @ExperimentalMaterial3ExpressiveApi\n    val LargeIconSize =\n        if (shouldUsePrecisionPointerComponentSizing.value) {\n            24.dp\n        } else {\n            ButtonLargeTokens.IconSize\n        }\n\n    /** The default size of the icon used inside an extra large button. */\n    @ExperimentalMaterial3ExpressiveApi val ExtraLargeIconSize = ButtonXLargeTokens.IconSize\n\n    /**\n     * The default size of the spacing between an icon and a text when they used inside a small\n     * button.\n     */\n    val IconSpacing = ButtonSmallTokens.IconLabelSpace\n\n    /**\n     * The default spacing between an icon and a text when they used inside any extra small button.\n     */\n    // TODO use the value from ButtonXSmallTokens.kt once it's been corrected\n    @ExperimentalMaterial3ExpressiveApi val ExtraSmallIconSpacing = 4.dp\n\n    /** The default spacing between an icon and a text when they're inside any medium button. */\n    @ExperimentalMaterial3ExpressiveApi val MediumIconSpacing = ButtonMediumTokens.IconLabelSpace\n\n    /** The default spacing between an icon and a text when they're inside any large button. */\n    @ExperimentalMaterial3ExpressiveApi\n    val LargeIconSpacing =\n        if (shouldUsePrecisionPointerComponentSizing.value) {\n            8.dp\n        } else {\n            ButtonLargeTokens.IconLabelSpace\n        }\n\n    /**\n     * The default spacing between an icon and a text when they used inside any extra large button.\n     */\n    @ExperimentalMaterial3ExpressiveApi\n    val ExtraLargeIconSpacing = ButtonXLargeTokens.IconLabelSpace\n\n    /** Square shape for default buttons. */\n    @ExperimentalMaterial3ExpressiveApi\n    val squareShape: Shape\n        @Composable get() = ButtonSmallTokens.ContainerShapeSquare.value\n\n    /** Pressed shape for default buttons. */\n    @ExperimentalMaterial3ExpressiveApi\n    val pressedShape: Shape\n        @Composable get() = ButtonSmallTokens.PressedContainerShape.value\n\n    /** Pressed shape for extra small buttons. */\n    @ExperimentalMaterial3ExpressiveApi\n    val extraSmallPressedShape: Shape\n        @Composable get() = ButtonXSmallTokens.PressedContainerShape.value\n\n    /** Pressed shape for medium buttons. */\n    @ExperimentalMaterial3ExpressiveApi\n    val mediumPressedShape: Shape\n        @Composable get() = ButtonMediumTokens.PressedContainerShape.value\n\n    /** Pressed shape for large buttons. */\n    @ExperimentalMaterial3ExpressiveApi\n    val largePressedShape: Shape\n        @Composable get() = ButtonLargeTokens.PressedContainerShape.value\n\n    /** Pressed shape for extra large buttons. */\n    @ExperimentalMaterial3ExpressiveApi\n    val extraLargePressedShape: Shape\n        @Composable get() = ButtonXLargeTokens.PressedContainerShape.value\n\n    /** Default shape for a button. */\n    val shape: Shape\n        @Composable get() = ButtonSmallTokens.ContainerShapeRound.value\n\n    /** Default shape for an elevated button. */\n    val elevatedShape: Shape\n        @Composable get() = ButtonSmallTokens.ContainerShapeRound.value\n\n    /** Default shape for a filled tonal button. */\n    val filledTonalShape: Shape\n        @Composable get() = ButtonSmallTokens.ContainerShapeRound.value\n\n    /** Default shape for an outlined button. */\n    val outlinedShape: Shape\n        @Composable get() = ButtonSmallTokens.ContainerShapeRound.value\n\n    /** Default shape for a text button. */\n    val textShape: Shape\n        @Composable get() = ButtonSmallTokens.ContainerShapeRound.value\n\n    /**\n     * Creates a [ButtonShapes] that represents the default shape and pressed shape used in a\n     * button.\n     */\n    @ExperimentalMaterial3ExpressiveApi\n    @Composable\n    fun shapes() = MaterialTheme.shapes.defaultButtonShapes\n\n    /**\n     * Creates a [ButtonShapes] that represents the default shape and pressedShape used in a\n     * [Button] and its variants.\n     *\n     * @param shape the unchecked shape for [ButtonShapes]\n     * @param pressedShape the unchecked shape for [ButtonShapes]\n     */\n    @Composable\n    @ExperimentalMaterial3ExpressiveApi\n    fun shapes(shape: Shape? = null, pressedShape: Shape? = null): ButtonShapes =\n        MaterialTheme.shapes.defaultButtonShapes.copy(shape = shape, pressedShape = pressedShape)\n\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    internal val Shapes.defaultButtonShapes: ButtonShapes\n        get() {\n            return defaultButtonShapesCached\n                ?: ButtonShapes(\n                        shape = fromToken(ButtonSmallTokens.ContainerShapeRound),\n                        pressedShape = fromToken(ButtonSmallTokens.PressedContainerShape),\n                    )\n                    .also { defaultButtonShapesCached = it }\n        }\n\n    /**\n     * Creates a [ButtonColors] that represents the default container and content colors used in a\n     * [Button].\n     */\n    @Composable fun buttonColors() = MaterialTheme.colorScheme.defaultButtonColors\n\n    /**\n     * Creates a [ButtonColors] that represents the default container and content colors used in a\n     * [Button].\n     *\n     * @param containerColor the container color of this [Button] when enabled.\n     * @param contentColor the content color of this [Button] when enabled.\n     * @param disabledContainerColor the container color of this [Button] when not enabled.\n     * @param disabledContentColor the content color of this [Button] when not enabled.\n     */\n    @Composable\n    fun buttonColors(\n        containerColor: Color = Color.Unspecified,\n        contentColor: Color = Color.Unspecified,\n        disabledContainerColor: Color = Color.Unspecified,\n        disabledContentColor: Color = Color.Unspecified,\n    ): ButtonColors =\n        MaterialTheme.colorScheme.defaultButtonColors.copy(\n            containerColor = containerColor,\n            contentColor = contentColor,\n            disabledContainerColor = disabledContainerColor,\n            disabledContentColor = disabledContentColor,\n        )\n\n    internal val ColorScheme.defaultButtonColors: ButtonColors\n        get() {\n            return defaultButtonColorsCached\n                ?: ButtonColors(\n                        containerColor = fromToken(FilledButtonTokens.ContainerColor),\n                        contentColor = fromToken(FilledButtonTokens.LabelTextColor),\n                        disabledContainerColor =\n                            fromToken(FilledButtonTokens.DisabledContainerColor)\n                                .copy(alpha = FilledButtonTokens.DisabledContainerOpacity),\n                        disabledContentColor =\n                            fromToken(FilledButtonTokens.DisabledLabelTextColor)\n                                .copy(alpha = FilledButtonTokens.DisabledLabelTextOpacity),\n                    )\n                    .also { defaultButtonColorsCached = it }\n        }\n\n    /**\n     * Creates a [ButtonColors] that represents the default container and content colors used in an\n     * [ElevatedButton].\n     */\n    @Composable fun elevatedButtonColors() = MaterialTheme.colorScheme.defaultElevatedButtonColors\n\n    /**\n     * Creates a [ButtonColors] that represents the default container and content colors used in an\n     * [ElevatedButton].\n     *\n     * @param containerColor the container color of this [ElevatedButton] when enabled\n     * @param contentColor the content color of this [ElevatedButton] when enabled\n     * @param disabledContainerColor the container color of this [ElevatedButton] when not enabled\n     * @param disabledContentColor the content color of this [ElevatedButton] when not enabled\n     */\n    @Composable\n    fun elevatedButtonColors(\n        containerColor: Color = Color.Unspecified,\n        contentColor: Color = Color.Unspecified,\n        disabledContainerColor: Color = Color.Unspecified,\n        disabledContentColor: Color = Color.Unspecified,\n    ): ButtonColors =\n        MaterialTheme.colorScheme.defaultElevatedButtonColors.copy(\n            containerColor = containerColor,\n            contentColor = contentColor,\n            disabledContainerColor = disabledContainerColor,\n            disabledContentColor = disabledContentColor,\n        )\n\n    internal val ColorScheme.defaultElevatedButtonColors: ButtonColors\n        get() {\n            return defaultElevatedButtonColorsCached\n                ?: ButtonColors(\n                        containerColor = fromToken(ElevatedButtonTokens.ContainerColor),\n                        contentColor = fromToken(ElevatedButtonTokens.LabelTextColor),\n                        disabledContainerColor =\n                            fromToken(ElevatedButtonTokens.DisabledContainerColor)\n                                .copy(alpha = ElevatedButtonTokens.DisabledContainerOpacity),\n                        disabledContentColor =\n                            fromToken(ElevatedButtonTokens.DisabledLabelTextColor)\n                                .copy(alpha = ElevatedButtonTokens.DisabledLabelTextOpacity),\n                    )\n                    .also { defaultElevatedButtonColorsCached = it }\n        }\n\n    /**\n     * Creates a [ButtonColors] that represents the default container and content colors used in an\n     * [FilledTonalButton].\n     */\n    @Composable\n    fun filledTonalButtonColors() = MaterialTheme.colorScheme.defaultFilledTonalButtonColors\n\n    /**\n     * Creates a [ButtonColors] that represents the default container and content colors used in an\n     * [FilledTonalButton].\n     *\n     * @param containerColor the container color of this [FilledTonalButton] when enabled\n     * @param contentColor the content color of this [FilledTonalButton] when enabled\n     * @param disabledContainerColor the container color of this [FilledTonalButton] when not\n     *   enabled\n     * @param disabledContentColor the content color of this [FilledTonalButton] when not enabled\n     */\n    @Composable\n    fun filledTonalButtonColors(\n        containerColor: Color = Color.Unspecified,\n        contentColor: Color = Color.Unspecified,\n        disabledContainerColor: Color = Color.Unspecified,\n        disabledContentColor: Color = Color.Unspecified,\n    ): ButtonColors =\n        MaterialTheme.colorScheme.defaultFilledTonalButtonColors.copy(\n            containerColor = containerColor,\n            contentColor = contentColor,\n            disabledContainerColor = disabledContainerColor,\n            disabledContentColor = disabledContentColor,\n        )\n\n    internal val ColorScheme.defaultFilledTonalButtonColors: ButtonColors\n        get() {\n            return defaultFilledTonalButtonColorsCached\n                ?: ButtonColors(\n                        containerColor = fromToken(FilledTonalButtonTokens.ContainerColor),\n                        contentColor = fromToken(FilledTonalButtonTokens.LabelTextColor),\n                        disabledContainerColor =\n                            fromToken(FilledTonalButtonTokens.DisabledContainerColor)\n                                .copy(alpha = FilledTonalButtonTokens.DisabledContainerOpacity),\n                        disabledContentColor =\n                            fromToken(FilledTonalButtonTokens.DisabledLabelTextColor)\n                                .copy(alpha = FilledTonalButtonTokens.DisabledLabelTextOpacity),\n                    )\n                    .also { defaultFilledTonalButtonColorsCached = it }\n        }\n\n    /**\n     * Creates a [ButtonColors] that represents the default container and content colors used in an\n     * [OutlinedButton].\n     */\n    @Composable fun outlinedButtonColors() = MaterialTheme.colorScheme.defaultOutlinedButtonColors\n\n    /**\n     * Creates a [ButtonColors] that represents the default container and content colors used in an\n     * [OutlinedButton].\n     *\n     * @param containerColor the container color of this [OutlinedButton] when enabled\n     * @param contentColor the content color of this [OutlinedButton] when enabled\n     * @param disabledContainerColor the container color of this [OutlinedButton] when not enabled\n     * @param disabledContentColor the content color of this [OutlinedButton] when not enabled\n     */\n    @Composable\n    fun outlinedButtonColors(\n        containerColor: Color = Color.Unspecified,\n        contentColor: Color = Color.Unspecified,\n        disabledContainerColor: Color = Color.Unspecified,\n        disabledContentColor: Color = Color.Unspecified,\n    ): ButtonColors =\n        MaterialTheme.colorScheme.defaultOutlinedButtonColors.copy(\n            containerColor = containerColor,\n            contentColor = contentColor,\n            disabledContainerColor = disabledContainerColor,\n            disabledContentColor = disabledContentColor,\n        )\n\n    internal val ColorScheme.defaultOutlinedButtonColors: ButtonColors\n        get() {\n            return defaultOutlinedButtonColorsCached\n                ?: ButtonColors(\n                        containerColor = Color.Transparent,\n                        contentColor = fromToken(OutlinedButtonTokens.LabelTextColor),\n                        disabledContainerColor = Color.Transparent,\n                        disabledContentColor =\n                            fromToken(OutlinedButtonTokens.DisabledLabelTextColor)\n                                .copy(alpha = OutlinedButtonTokens.DisabledLabelTextOpacity),\n                    )\n                    .also { defaultOutlinedButtonColorsCached = it }\n        }\n\n    /**\n     * Creates a [ButtonColors] that represents the default container and content colors used in a\n     * [TextButton].\n     */\n    @Composable fun textButtonColors() = MaterialTheme.colorScheme.defaultTextButtonColors\n\n    /**\n     * Creates a [ButtonColors] that represents the default container and content colors used in a\n     * [TextButton].\n     *\n     * @param containerColor the container color of this [TextButton] when enabled\n     * @param contentColor the content color of this [TextButton] when enabled\n     * @param disabledContainerColor the container color of this [TextButton] when not enabled\n     * @param disabledContentColor the content color of this [TextButton] when not enabled\n     */\n    @Composable\n    fun textButtonColors(\n        containerColor: Color = Color.Unspecified,\n        contentColor: Color = Color.Unspecified,\n        disabledContainerColor: Color = Color.Unspecified,\n        disabledContentColor: Color = Color.Unspecified,\n    ): ButtonColors =\n        MaterialTheme.colorScheme.defaultTextButtonColors.copy(\n            containerColor = containerColor,\n            contentColor = contentColor,\n            disabledContainerColor = disabledContainerColor,\n            disabledContentColor = disabledContentColor,\n        )\n\n    internal val ColorScheme.defaultTextButtonColors: ButtonColors\n        get() {\n            return defaultTextButtonColorsCached\n                ?: ButtonColors(\n                        containerColor = Color.Transparent,\n                        // TODO replace with the token value once it's corrected\n                        contentColor = fromToken(ColorSchemeKeyTokens.Primary),\n                        disabledContainerColor = Color.Transparent,\n                        disabledContentColor =\n                            fromToken(TextButtonTokens.DisabledLabelColor)\n                                .copy(alpha = TextButtonTokens.DisabledLabelOpacity),\n                    )\n                    .also { defaultTextButtonColorsCached = it }\n        }\n\n    /**\n     * Creates a [ButtonElevation] that will animate between the provided values according to the\n     * Material specification for a [Button].\n     *\n     * @param defaultElevation the elevation used when the [Button] is enabled, and has no other\n     *   [Interaction]s.\n     * @param pressedElevation the elevation used when this [Button] is enabled and pressed.\n     * @param focusedElevation the elevation used when the [Button] is enabled and focused.\n     * @param hoveredElevation the elevation used when the [Button] is enabled and hovered.\n     * @param disabledElevation the elevation used when the [Button] is not enabled.\n     */\n    @Composable\n    fun buttonElevation(\n        defaultElevation: Dp = FilledButtonTokens.ContainerElevation,\n        pressedElevation: Dp = FilledButtonTokens.PressedContainerElevation,\n        focusedElevation: Dp = FilledButtonTokens.FocusedContainerElevation,\n        hoveredElevation: Dp = FilledButtonTokens.HoveredContainerElevation,\n        disabledElevation: Dp = FilledButtonTokens.DisabledContainerElevation,\n    ): ButtonElevation =\n        ButtonElevation(\n            defaultElevation = defaultElevation,\n            pressedElevation = pressedElevation,\n            focusedElevation = focusedElevation,\n            hoveredElevation = hoveredElevation,\n            disabledElevation = disabledElevation,\n        )\n\n    /**\n     * Creates a [ButtonElevation] that will animate between the provided values according to the\n     * Material specification for a [ElevatedButton].\n     *\n     * @param defaultElevation the elevation used when the [ElevatedButton] is enabled, and has no\n     *   other [Interaction]s.\n     * @param pressedElevation the elevation used when this [ElevatedButton] is enabled and pressed.\n     * @param focusedElevation the elevation used when the [ElevatedButton] is enabled and focused.\n     * @param hoveredElevation the elevation used when the [ElevatedButton] is enabled and hovered.\n     * @param disabledElevation the elevation used when the [ElevatedButton] is not enabled.\n     */\n    @Composable\n    fun elevatedButtonElevation(\n        defaultElevation: Dp = ElevatedButtonTokens.ContainerElevation,\n        pressedElevation: Dp = ElevatedButtonTokens.PressedContainerElevation,\n        focusedElevation: Dp = ElevatedButtonTokens.FocusedContainerElevation,\n        hoveredElevation: Dp = ElevatedButtonTokens.HoveredContainerElevation,\n        disabledElevation: Dp = ElevatedButtonTokens.DisabledContainerElevation,\n    ): ButtonElevation =\n        ButtonElevation(\n            defaultElevation = defaultElevation,\n            pressedElevation = pressedElevation,\n            focusedElevation = focusedElevation,\n            hoveredElevation = hoveredElevation,\n            disabledElevation = disabledElevation,\n        )\n\n    /**\n     * Creates a [ButtonElevation] that will animate between the provided values according to the\n     * Material specification for a [FilledTonalButton].\n     *\n     * @param defaultElevation the elevation used when the [FilledTonalButton] is enabled, and has\n     *   no other [Interaction]s.\n     * @param pressedElevation the elevation used when this [FilledTonalButton] is enabled and\n     *   pressed.\n     * @param focusedElevation the elevation used when the [FilledTonalButton] is enabled and\n     *   focused.\n     * @param hoveredElevation the elevation used when the [FilledTonalButton] is enabled and\n     *   hovered.\n     * @param disabledElevation the elevation used when the [FilledTonalButton] is not enabled.\n     */\n    @Composable\n    fun filledTonalButtonElevation(\n        defaultElevation: Dp = FilledTonalButtonTokens.ContainerElevation,\n        pressedElevation: Dp = FilledTonalButtonTokens.PressedContainerElevation,\n        focusedElevation: Dp = FilledTonalButtonTokens.FocusContainerElevation,\n        hoveredElevation: Dp = FilledTonalButtonTokens.HoverContainerElevation,\n        disabledElevation: Dp = 0.dp,\n    ): ButtonElevation =\n        ButtonElevation(\n            defaultElevation = defaultElevation,\n            pressedElevation = pressedElevation,\n            focusedElevation = focusedElevation,\n            hoveredElevation = hoveredElevation,\n            disabledElevation = disabledElevation,\n        )\n\n    /** The default [BorderStroke] used by [OutlinedButton]. */\n    val outlinedButtonBorder: BorderStroke\n        @Composable\n        @Deprecated(\n            message =\n                \"Please use the version that takes an `enabled` param to get the \" +\n                    \"`BorderStroke` with the correct opacity\",\n            replaceWith = ReplaceWith(\"outlinedButtonBorder(enabled)\"),\n        )\n        get() =\n            BorderStroke(\n                width = ButtonSmallTokens.OutlinedOutlineWidth,\n                color = OutlinedButtonTokens.OutlineColor.value,\n            )\n\n    /**\n     * The default [BorderStroke] used by [OutlinedButton].\n     *\n     * @param enabled whether the button is enabled\n     */\n    @Composable\n    fun outlinedButtonBorder(enabled: Boolean = true): BorderStroke =\n        BorderStroke(\n            width = ButtonSmallTokens.OutlinedOutlineWidth,\n            color =\n                if (enabled) {\n                    OutlinedButtonTokens.OutlineColor.value\n                } else {\n                    OutlinedButtonTokens.OutlineColor.value.copy(\n                        alpha = OutlinedButtonTokens.DisabledContainerOpacity\n                    )\n                },\n        )\n\n    /**\n     * Recommended [ButtonShapes] for a provided button height.\n     *\n     * @param buttonHeight The height of the button\n     */\n    @Composable\n    @ExperimentalMaterial3ExpressiveApi\n    fun shapesFor(buttonHeight: Dp): ButtonShapes {\n        val xSmallHeight = ExtraSmallContainerHeight\n        val smallHeight = MinHeight\n        val mediumHeight = MediumContainerHeight\n        val largeHeight = LargeContainerHeight\n        val xLargeHeight = ExtraLargeContainerHeight\n        return when {\n            buttonHeight <= (xSmallHeight + smallHeight) / 2 ->\n                shapes(shape = shape, pressedShape = extraSmallPressedShape)\n            buttonHeight <= (smallHeight + mediumHeight) / 2 -> shapes()\n            buttonHeight <= (mediumHeight + largeHeight) / 2 ->\n                shapes(shape = shape, pressedShape = mediumPressedShape)\n            buttonHeight <= (largeHeight + xLargeHeight) / 2 ->\n                shapes(shape = shape, pressedShape = largePressedShape)\n            else -> shapes(shape = shape, pressedShape = extraLargePressedShape)\n        }\n    }\n\n    /**\n     * Recommended [PaddingValues] for a provided button height.\n     *\n     * @param buttonHeight The height of the button\n     * @param hasStartIcon Whether the button has a leading icon\n     * @param hasEndIcon Whether the button has a trailing icon\n     */\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    fun contentPaddingFor(\n        buttonHeight: Dp,\n        hasStartIcon: Boolean = false,\n        hasEndIcon: Boolean = false,\n    ): PaddingValues {\n        val smallHeight = MinHeight\n        val mediumHeight = MediumContainerHeight\n        val largeHeight = LargeContainerHeight\n        val xLargeHeight = ExtraLargeContainerHeight\n        return when {\n            buttonHeight < smallHeight -> ExtraSmallContentPadding\n            buttonHeight < mediumHeight -> getSmallContentPadding(hasStartIcon, hasEndIcon)\n            buttonHeight < largeHeight -> getMediumContentPadding(hasStartIcon, hasEndIcon)\n            buttonHeight < xLargeHeight -> getLargeContentPadding(hasStartIcon, hasEndIcon)\n            else -> ExtraLargeContentPadding\n        }\n    }\n\n    /**\n     * Recommended [PaddingValues] for a provided button height.\n     *\n     * @param buttonHeight The height of the button\n     */\n    @Deprecated(\n        message = \"Deprecated in favor of function with hasLeadingIcon and hasTrailingIcon params\",\n        level = DeprecationLevel.HIDDEN,\n    )\n    @ExperimentalMaterial3ExpressiveApi\n    fun contentPaddingFor(buttonHeight: Dp): PaddingValues {\n        val smallHeight = MinHeight\n        val mediumHeight = MediumContainerHeight\n        val largeHeight = LargeContainerHeight\n        val xLargeHeight = ExtraLargeContainerHeight\n        return when {\n            buttonHeight < smallHeight -> ExtraSmallContentPadding\n            buttonHeight < mediumHeight -> SmallContentPadding\n            buttonHeight < largeHeight -> MediumContentPadding\n            buttonHeight < xLargeHeight -> LargeContentPadding\n            else -> ExtraLargeContentPadding\n        }\n    }\n\n    /**\n     * Recommended Icon size for a provided button height.\n     *\n     * @param buttonHeight The height of the button\n     */\n    @ExperimentalMaterial3ExpressiveApi\n    fun iconSizeFor(buttonHeight: Dp): Dp {\n        val smallHeight = MinHeight\n        val mediumHeight = MediumContainerHeight\n        val largeHeight = LargeContainerHeight\n        val xLargeHeight = ExtraLargeContainerHeight\n        return when {\n            buttonHeight < smallHeight -> ExtraSmallIconSize\n            buttonHeight < mediumHeight -> SmallIconSize\n            buttonHeight < largeHeight -> MediumIconSize\n            buttonHeight < xLargeHeight -> LargeIconSize\n            else -> ExtraLargeIconSize\n        }\n    }\n\n    /**\n     * Recommended spacing after an [Icon] for a provided button height.\n     *\n     * @param buttonHeight The height of the button\n     */\n    @ExperimentalMaterial3ExpressiveApi\n    fun iconSpacingFor(buttonHeight: Dp): Dp {\n        val smallHeight = MinHeight\n        val mediumHeight = MediumContainerHeight\n        val largeHeight = LargeContainerHeight\n        val xLargeHeight = ExtraLargeContainerHeight\n        return when {\n            buttonHeight < smallHeight -> ExtraSmallIconSpacing\n            buttonHeight < mediumHeight -> IconSpacing\n            buttonHeight < largeHeight -> MediumIconSpacing\n            buttonHeight < xLargeHeight -> LargeIconSpacing\n            else -> ExtraLargeIconSpacing\n        }\n    }\n\n    /**\n     * Recommended [TextStyle] for a [Text] provided a button height.\n     *\n     * @param buttonHeight The height of the button\n     */\n    @Composable\n    @ExperimentalMaterial3ExpressiveApi\n    fun textStyleFor(buttonHeight: Dp): TextStyle {\n        val mediumHeight = MediumContainerHeight\n        val largeHeight = LargeContainerHeight\n        val xLargeHeight = ExtraLargeContainerHeight\n        return when {\n            buttonHeight < mediumHeight -> MaterialTheme.typography.labelLarge\n            buttonHeight < largeHeight ->\n                if (shouldUsePrecisionPointerComponentSizing.value) {\n                    MaterialTheme.typography.titleMedium.copy(fontSize = 15.sp, lineHeight = 22.sp)\n                } else {\n                    MaterialTheme.typography.titleMedium\n                }\n            buttonHeight < xLargeHeight ->\n                if (shouldUsePrecisionPointerComponentSizing.value) {\n                    MaterialTheme.typography.headlineSmall.copy(\n                        fontSize = 18.sp,\n                        lineHeight = 26.sp,\n                    )\n                } else {\n                    MaterialTheme.typography.headlineSmall\n                }\n            else -> MaterialTheme.typography.headlineLarge\n        }\n    }\n\n    private val SmallVerticalPadding =\n        if (shouldUsePrecisionPointerComponentSizing.value) 8.dp else 10.dp\n    private val IconSmallHorizontalPadding =\n        if (shouldUsePrecisionPointerComponentSizing.value) 12.dp else SmallStartPadding\n    private val MediumLeadingPadding = ButtonMediumTokens.LeadingSpace\n    private val MediumTrailingPadding = ButtonMediumTokens.TrailingSpace\n    private val MediumVerticalPadding =\n        if (shouldUsePrecisionPointerComponentSizing.value) 12.dp else 16.dp\n    private val IconMediumLeadingPadding =\n        if (shouldUsePrecisionPointerComponentSizing.value) {\n            20.dp\n        } else {\n            ButtonMediumTokens.LeadingSpace\n        }\n    private val IconMediumTrailingPadding =\n        if (shouldUsePrecisionPointerComponentSizing.value) {\n            20.dp\n        } else {\n            ButtonMediumTokens.TrailingSpace\n        }\n    private val LargeVerticalPadding =\n        if (shouldUsePrecisionPointerComponentSizing.value) 14.dp else 32.dp\n    private val LargeLeadingPadding =\n        if (shouldUsePrecisionPointerComponentSizing.value) {\n            32.dp\n        } else {\n            ButtonLargeTokens.LeadingSpace\n        }\n    private val LargeTrailingPadding =\n        if (shouldUsePrecisionPointerComponentSizing.value) {\n            32.dp\n        } else {\n            ButtonLargeTokens.TrailingSpace\n        }\n    private val IconLargeLeadingPadding =\n        if (shouldUsePrecisionPointerComponentSizing.value) {\n            28.dp\n        } else {\n            ButtonLargeTokens.LeadingSpace\n        }\n    private val IconLargeTrailingPadding =\n        if (shouldUsePrecisionPointerComponentSizing.value) {\n            28.dp\n        } else {\n            ButtonLargeTokens.TrailingSpace\n        }\n}\n\n/**\n * Represents the elevation for a button in different states.\n * - See [ButtonDefaults.buttonElevation] for the default elevation used in a [Button].\n * - See [ButtonDefaults.elevatedButtonElevation] for the default elevation used in a\n *   [ElevatedButton].\n */\n@Stable\nclass ButtonElevation\ninternal constructor(\n    private val defaultElevation: Dp,\n    private val pressedElevation: Dp,\n    private val focusedElevation: Dp,\n    private val hoveredElevation: Dp,\n    private val disabledElevation: Dp,\n) {\n    /**\n     * Represents the shadow elevation used in a button, depending on its [enabled] state and\n     * [interactionSource].\n     *\n     * Shadow elevation is used to apply a shadow around the button to give it higher emphasis.\n     *\n     * @param enabled whether the button is enabled\n     * @param interactionSource the [InteractionSource] for this button\n     */\n    @Composable\n    internal fun shadowElevation(\n        enabled: Boolean,\n        interactionSource: InteractionSource,\n    ): State<Dp> {\n        return animateElevation(enabled = enabled, interactionSource = interactionSource)\n    }\n\n    @Composable\n    private fun animateElevation(\n        enabled: Boolean,\n        interactionSource: InteractionSource,\n    ): State<Dp> {\n        val interactions = remember { mutableStateListOf<Interaction>() }\n        LaunchedEffect(interactionSource) {\n            interactionSource.interactions.collect { interaction ->\n                when (interaction) {\n                    is HoverInteraction.Enter -> {\n                        interactions.add(interaction)\n                    }\n                    is HoverInteraction.Exit -> {\n                        interactions.remove(interaction.enter)\n                    }\n                    is FocusInteraction.Focus -> {\n                        interactions.add(interaction)\n                    }\n                    is FocusInteraction.Unfocus -> {\n                        interactions.remove(interaction.focus)\n                    }\n                    is PressInteraction.Press -> {\n                        interactions.add(interaction)\n                    }\n                    is PressInteraction.Release -> {\n                        interactions.remove(interaction.press)\n                    }\n                    is PressInteraction.Cancel -> {\n                        interactions.remove(interaction.press)\n                    }\n                }\n            }\n        }\n\n        val interaction = interactions.lastOrNull()\n\n        val target =\n            if (!enabled) {\n                disabledElevation\n            } else {\n                when (interaction) {\n                    is PressInteraction.Press -> pressedElevation\n                    is HoverInteraction.Enter -> hoveredElevation\n                    is FocusInteraction.Focus -> focusedElevation\n                    else -> defaultElevation\n                }\n            }\n\n        val animatable = remember { Animatable(target, Dp.VectorConverter) }\n\n        LaunchedEffect(target) {\n            if (animatable.targetValue != target) {\n                if (!enabled) {\n                    // No transition when moving to a disabled state\n                    animatable.snapTo(target)\n                } else {\n                    val lastInteraction =\n                        when (animatable.targetValue) {\n                            pressedElevation -> PressInteraction.Press(Offset.Zero)\n                            hoveredElevation -> HoverInteraction.Enter()\n                            focusedElevation -> FocusInteraction.Focus()\n                            else -> null\n                        }\n                    animatable.animateElevation(\n                        from = lastInteraction,\n                        to = interaction,\n                        target = target,\n                    )\n                }\n            }\n        }\n\n        return animatable.asState()\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is ButtonElevation) return false\n\n        if (defaultElevation != other.defaultElevation) return false\n        if (pressedElevation != other.pressedElevation) return false\n        if (focusedElevation != other.focusedElevation) return false\n        if (hoveredElevation != other.hoveredElevation) return false\n        if (disabledElevation != other.disabledElevation) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = defaultElevation.hashCode()\n        result = 31 * result + pressedElevation.hashCode()\n        result = 31 * result + focusedElevation.hashCode()\n        result = 31 * result + hoveredElevation.hashCode()\n        result = 31 * result + disabledElevation.hashCode()\n        return result\n    }\n}\n\n/**\n * Represents the container and content colors used in a button in different states.\n *\n * @param containerColor the container color of this [Button] when enabled.\n * @param contentColor the content color of this [Button] when enabled.\n * @param disabledContainerColor the container color of this [Button] when not enabled.\n * @param disabledContentColor the content color of this [Button] when not enabled.\n *     @constructor create an instance with arbitrary colors.\n * - See [ButtonDefaults.buttonColors] for the default colors used in a [Button].\n * - See [ButtonDefaults.elevatedButtonColors] for the default colors used in a [ElevatedButton].\n * - See [ButtonDefaults.textButtonColors] for the default colors used in a [TextButton].\n */\n@Immutable\nclass ButtonColors\nconstructor(\n    val containerColor: Color,\n    val contentColor: Color,\n    val disabledContainerColor: Color,\n    val disabledContentColor: Color,\n) {\n    /**\n     * Returns a copy of this ButtonColors, optionally overriding some of the values. This uses the\n     * Color.Unspecified to mean “use the value from the source”\n     */\n    fun copy(\n        containerColor: Color = this.containerColor,\n        contentColor: Color = this.contentColor,\n        disabledContainerColor: Color = this.disabledContainerColor,\n        disabledContentColor: Color = this.disabledContentColor,\n    ) =\n        ButtonColors(\n            containerColor.takeOrElse { this.containerColor },\n            contentColor.takeOrElse { this.contentColor },\n            disabledContainerColor.takeOrElse { this.disabledContainerColor },\n            disabledContentColor.takeOrElse { this.disabledContentColor },\n        )\n\n    /**\n     * Represents the container color for this button, depending on [enabled].\n     *\n     * @param enabled whether the button is enabled\n     */\n    @Stable\n    internal fun containerColor(enabled: Boolean): Color =\n        if (enabled) containerColor else disabledContainerColor\n\n    /**\n     * Represents the content color for this button, depending on [enabled].\n     *\n     * @param enabled whether the button is enabled\n     */\n    @Stable\n    internal fun contentColor(enabled: Boolean): Color =\n        if (enabled) contentColor else disabledContentColor\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is ButtonColors) return false\n\n        if (containerColor != other.containerColor) return false\n        if (contentColor != other.contentColor) return false\n        if (disabledContainerColor != other.disabledContainerColor) return false\n        if (disabledContentColor != other.disabledContentColor) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = containerColor.hashCode()\n        result = 31 * result + contentColor.hashCode()\n        result = 31 * result + disabledContainerColor.hashCode()\n        result = 31 * result + disabledContentColor.hashCode()\n        return result\n    }\n}\n\n/**\n * The shapes that will be used in buttons. Button will morph between these shapes depending on the\n * interaction of the button, assuming all of the shapes are [CornerBasedShape]s.\n *\n * @property shape is the active shape.\n * @property pressedShape is the pressed shape.\n */\n@ExperimentalMaterial3ExpressiveApi\n@Immutable\nclass ButtonShapes(val shape: Shape, val pressedShape: Shape) {\n    /** Returns a copy of this ButtonShapes, optionally overriding some of the values. */\n    fun copy(shape: Shape? = this.shape, pressedShape: Shape? = this.pressedShape) =\n        ButtonShapes(\n            shape = shape.takeOrElse { this.shape },\n            pressedShape = pressedShape.takeOrElse { this.pressedShape },\n        )\n\n    internal fun Shape?.takeOrElse(block: () -> Shape): Shape = this ?: block()\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is ButtonShapes) return false\n\n        if (shape != other.shape) return false\n        if (pressedShape != other.pressedShape) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = shape.hashCode()\n        result = 31 * result + pressedShape.hashCode()\n\n        return result\n    }\n}\n\n@OptIn(ExperimentalMaterial3ExpressiveApi::class)\ninternal val ButtonShapes.hasRoundedCornerShapes: Boolean\n    get() = shape is RoundedCornerShape && pressedShape is RoundedCornerShape\n\n@OptIn(ExperimentalMaterial3ExpressiveApi::class)\ninternal val ButtonShapes.hasCornerBasedShapes: Boolean\n    get() = shape is CornerBasedShape && pressedShape is CornerBasedShape\n\n@OptIn(ExperimentalMaterial3ExpressiveApi::class)\n@Composable\nprivate fun shapeByInteraction(\n    shapes: ButtonShapes,\n    pressed: Boolean,\n    animationSpec: FiniteAnimationSpec<Float>,\n): Shape {\n    val shape =\n        if (pressed) {\n            shapes.pressedShape\n        } else {\n            shapes.shape\n        }\n    if (shapes.hasRoundedCornerShapes)\n        return key(shapes) { rememberAnimatedShape(shape as RoundedCornerShape, animationSpec) }\n    else if (shapes.hasCornerBasedShapes)\n        return key(shapes) { rememberAnimatedShape(shape as CornerBasedShape, animationSpec) }\n\n    return shape\n}\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Card.kt\n```kotlin\n/*\n * Copyright 2022 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.VectorConverter\nimport androidx.compose.foundation.BorderStroke\nimport androidx.compose.foundation.interaction.DragInteraction\nimport androidx.compose.foundation.interaction.FocusInteraction\nimport androidx.compose.foundation.interaction.HoverInteraction\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.InteractionSource\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.material3.internal.animateElevation\nimport androidx.compose.material3.tokens.ElevatedCardTokens\nimport androidx.compose.material3.tokens.FilledCardTokens\nimport androidx.compose.material3.tokens.OutlinedCardTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.unit.Dp\n\n/**\n * [Material Design filled card](https://m3.material.io/components/cards/overview)\n *\n * Cards contain contain content and actions that relate information about a subject. Filled cards\n * provide subtle separation from the background. This has less emphasis than elevated or outlined\n * cards.\n *\n * This Card does not handle input events - see the other Card overloads if you want a clickable or\n * selectable Card.\n *\n * ![Filled card\n * image](https://developer.android.com/images/reference/androidx/compose/material3/filled-card.png)\n *\n * Card sample:\n *\n * @sample androidx.compose.material3.samples.CardSample\n * @param modifier the [Modifier] to be applied to this card\n * @param shape defines the shape of this card's container, border (when [border] is not null), and\n *   shadow (when using [elevation])\n * @param colors [CardColors] that will be used to resolve the colors used for this card in\n *   different states. See [CardDefaults.cardColors].\n * @param elevation [CardElevation] used to resolve the elevation for this card in different states.\n *   This controls the size of the shadow below the card. Additionally, when the container color is\n *   [ColorScheme.surface], this controls the amount of primary color applied as an overlay. See\n *   also: [Surface].\n * @param border the border to draw around the container of this card\n * @param content The content displayed on the card\n */\n@Composable\nfun Card(\n    modifier: Modifier = Modifier,\n    shape: Shape = CardDefaults.shape,\n    colors: CardColors = CardDefaults.cardColors(),\n    elevation: CardElevation = CardDefaults.cardElevation(),\n    border: BorderStroke? = null,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    Surface(\n        modifier = modifier,\n        shape = shape,\n        color = colors.containerColor(enabled = true),\n        contentColor = colors.contentColor(enabled = true),\n        shadowElevation = elevation.shadowElevation(enabled = true, interactionSource = null).value,\n        border = border,\n    ) {\n        Column(content = content)\n    }\n}\n\n/**\n * [Material Design filled card](https://m3.material.io/components/cards/overview)\n *\n * Cards contain contain content and actions that relate information about a subject. Filled cards\n * provide subtle separation from the background. This has less emphasis than elevated or outlined\n * cards.\n *\n * This Card handles click events, calling its [onClick] lambda.\n *\n * ![Filled card\n * image](https://developer.android.com/images/reference/androidx/compose/material3/filled-card.png)\n *\n * Clickable card sample:\n *\n * @sample androidx.compose.material3.samples.ClickableCardSample\n * @param onClick called when this card is clicked\n * @param modifier the [Modifier] to be applied to this card\n * @param enabled controls the enabled state of this card. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param shape defines the shape of this card's container, border (when [border] is not null), and\n *   shadow (when using [elevation])\n * @param colors [CardColors] that will be used to resolve the color(s) used for this card in\n *   different states. See [CardDefaults.cardColors].\n * @param elevation [CardElevation] used to resolve the elevation for this card in different states.\n *   This controls the size of the shadow below the card. Additionally, when the container color is\n *   [ColorScheme.surface], this controls the amount of primary color applied as an overlay. See\n *   also: [Surface].\n * @param border the border to draw around the container of this card\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this card. You can use this to change the card's appearance or\n *   preview the card in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @param content The content displayed on the card\n */\n@Composable\nfun Card(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    shape: Shape = CardDefaults.shape,\n    colors: CardColors = CardDefaults.cardColors(),\n    elevation: CardElevation = CardDefaults.cardElevation(),\n    border: BorderStroke? = null,\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    Surface(\n        onClick = onClick,\n        modifier = modifier,\n        enabled = enabled,\n        shape = shape,\n        color = colors.containerColor(enabled),\n        contentColor = colors.contentColor(enabled),\n        shadowElevation = elevation.shadowElevation(enabled, interactionSource).value,\n        border = border,\n        interactionSource = interactionSource,\n    ) {\n        Column(content = content)\n    }\n}\n\n/**\n * [Material Design elevated card](https://m3.material.io/components/cards/overview)\n *\n * Elevated cards contain content and actions that relate information about a subject. They have a\n * drop shadow, providing more separation from the background than filled cards, but less than\n * outlined cards.\n *\n * This ElevatedCard does not handle input events - see the other ElevatedCard overloads if you want\n * a clickable or selectable ElevatedCard.\n *\n * ![Elevated card\n * image](https://developer.android.com/images/reference/androidx/compose/material3/elevated-card.png)\n *\n * Elevated card sample:\n *\n * @sample androidx.compose.material3.samples.ElevatedCardSample\n * @param modifier the [Modifier] to be applied to this card\n * @param shape defines the shape of this card's container and shadow (when using [elevation])\n * @param colors [CardColors] that will be used to resolve the color(s) used for this card in\n *   different states. See [CardDefaults.elevatedCardElevation].\n * @param elevation [CardElevation] used to resolve the elevation for this card in different states.\n *   This controls the size of the shadow below the card. Additionally, when the container color is\n *   [ColorScheme.surface], this controls the amount of primary color applied as an overlay. See\n *   also: [Surface].\n * @param content The content displayed on the card\n */\n@Composable\nfun ElevatedCard(\n    modifier: Modifier = Modifier,\n    shape: Shape = CardDefaults.elevatedShape,\n    colors: CardColors = CardDefaults.elevatedCardColors(),\n    elevation: CardElevation = CardDefaults.elevatedCardElevation(),\n    content: @Composable ColumnScope.() -> Unit,\n) =\n    Card(\n        modifier = modifier,\n        shape = shape,\n        border = null,\n        elevation = elevation,\n        colors = colors,\n        content = content,\n    )\n\n/**\n * [Material Design elevated card](https://m3.material.io/components/cards/overview)\n *\n * Elevated cards contain content and actions that relate information about a subject. They have a\n * drop shadow, providing more separation from the background than filled cards, but less than\n * outlined cards.\n *\n * This ElevatedCard handles click events, calling its [onClick] lambda.\n *\n * ![Elevated card\n * image](https://developer.android.com/images/reference/androidx/compose/material3/elevated-card.png)\n *\n * Clickable elevated card sample:\n *\n * @sample androidx.compose.material3.samples.ClickableElevatedCardSample\n * @param onClick called when this card is clicked\n * @param modifier the [Modifier] to be applied to this card\n * @param enabled controls the enabled state of this card. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param shape defines the shape of this card's container and shadow (when using [elevation])\n * @param colors [CardColors] that will be used to resolve the color(s) used for this card in\n *   different states. See [CardDefaults.elevatedCardElevation].\n * @param elevation [CardElevation] used to resolve the elevation for this card in different states.\n *   This controls the size of the shadow below the card. Additionally, when the container color is\n *   [ColorScheme.surface], this controls the amount of primary color applied as an overlay. See\n *   also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this card. You can use this to change the card's appearance or\n *   preview the card in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @param content The content displayed on the card\n */\n@Composable\nfun ElevatedCard(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    shape: Shape = CardDefaults.elevatedShape,\n    colors: CardColors = CardDefaults.elevatedCardColors(),\n    elevation: CardElevation = CardDefaults.elevatedCardElevation(),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable ColumnScope.() -> Unit,\n) =\n    Card(\n        onClick = onClick,\n        modifier = modifier,\n        enabled = enabled,\n        shape = shape,\n        colors = colors,\n        elevation = elevation,\n        border = null,\n        interactionSource = interactionSource,\n        content = content,\n    )\n\n/**\n * [Material Design outlined card](https://m3.material.io/components/cards/overview)\n *\n * Outlined cards contain content and actions that relate information about a subject. They have a\n * visual boundary around the container. This can provide greater emphasis than the other types.\n *\n * This OutlinedCard does not handle input events - see the other OutlinedCard overloads if you want\n * a clickable or selectable OutlinedCard.\n *\n * ![Outlined card\n * image](https://developer.android.com/images/reference/androidx/compose/material3/outlined-card.png)\n *\n * Outlined card sample:\n *\n * @sample androidx.compose.material3.samples.OutlinedCardSample\n * @param modifier the [Modifier] to be applied to this card\n * @param shape defines the shape of this card's container, border (when [border] is not null), and\n *   shadow (when using [elevation])\n * @param colors [CardColors] that will be used to resolve the color(s) used for this card in\n *   different states. See [CardDefaults.outlinedCardColors].\n * @param elevation [CardElevation] used to resolve the elevation for this card in different states.\n *   This controls the size of the shadow below the card. Additionally, when the container color is\n *   [ColorScheme.surface], this controls the amount of primary color applied as an overlay. See\n *   also: [Surface].\n * @param border the border to draw around the container of this card\n * @param content The content displayed on the card\n */\n@Composable\nfun OutlinedCard(\n    modifier: Modifier = Modifier,\n    shape: Shape = CardDefaults.outlinedShape,\n    colors: CardColors = CardDefaults.outlinedCardColors(),\n    elevation: CardElevation = CardDefaults.outlinedCardElevation(),\n    border: BorderStroke = CardDefaults.outlinedCardBorder(),\n    content: @Composable ColumnScope.() -> Unit,\n) =\n    Card(\n        modifier = modifier,\n        shape = shape,\n        colors = colors,\n        elevation = elevation,\n        border = border,\n        content = content,\n    )\n\n/**\n * [Material Design outlined card](https://m3.material.io/components/cards/overview)\n *\n * Outlined cards contain content and actions that relate information about a subject. They have a\n * visual boundary around the container. This can provide greater emphasis than the other types.\n *\n * This OutlinedCard handles click events, calling its [onClick] lambda.\n *\n * ![Outlined card\n * image](https://developer.android.com/images/reference/androidx/compose/material3/outlined-card.png)\n *\n * Clickable outlined card sample:\n *\n * @sample androidx.compose.material3.samples.ClickableOutlinedCardSample\n * @param onClick called when this card is clicked\n * @param modifier the [Modifier] to be applied to this card\n * @param enabled controls the enabled state of this card. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param shape defines the shape of this card's container, border (when [border] is not null), and\n *   shadow (when using [elevation])\n * @param colors [CardColors] that will be used to resolve the color(s) used for this card in\n *   different states. See [CardDefaults.outlinedCardColors].\n * @param elevation [CardElevation] used to resolve the elevation for this card in different states.\n *   This controls the size of the shadow below the card. Additionally, when the container color is\n *   [ColorScheme.surface], this controls the amount of primary color applied as an overlay. See\n *   also: [Surface].\n * @param border the border to draw around the container of this card\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this card. You can use this to change the card's appearance or\n *   preview the card in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @param content The content displayed on the card\n */\n@Composable\nfun OutlinedCard(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    shape: Shape = CardDefaults.outlinedShape,\n    colors: CardColors = CardDefaults.outlinedCardColors(),\n    elevation: CardElevation = CardDefaults.outlinedCardElevation(),\n    border: BorderStroke = CardDefaults.outlinedCardBorder(enabled),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable ColumnScope.() -> Unit,\n) =\n    Card(\n        onClick = onClick,\n        modifier = modifier,\n        enabled = enabled,\n        shape = shape,\n        colors = colors,\n        elevation = elevation,\n        border = border,\n        interactionSource = interactionSource,\n        content = content,\n    )\n\n/** Contains the default values used by all card types. */\nobject CardDefaults {\n    // shape Defaults\n    /** Default shape for a card. */\n    val shape: Shape\n        @Composable get() = FilledCardTokens.ContainerShape.value\n\n    /** Default shape for an elevated card. */\n    val elevatedShape: Shape\n        @Composable get() = ElevatedCardTokens.ContainerShape.value\n\n    /** Default shape for an outlined card. */\n    val outlinedShape: Shape\n        @Composable get() = OutlinedCardTokens.ContainerShape.value\n\n    /**\n     * Creates a [CardElevation] that will animate between the provided values according to the\n     * Material specification for a [Card].\n     *\n     * @param defaultElevation the elevation used when the [Card] is has no other [Interaction]s.\n     * @param pressedElevation the elevation used when the [Card] is pressed.\n     * @param focusedElevation the elevation used when the [Card] is focused.\n     * @param hoveredElevation the elevation used when the [Card] is hovered.\n     * @param draggedElevation the elevation used when the [Card] is dragged.\n     * @param disabledElevation the elevation used when the [Card] is disabled.\n     */\n    @Composable\n    fun cardElevation(\n        defaultElevation: Dp = FilledCardTokens.ContainerElevation,\n        pressedElevation: Dp = FilledCardTokens.PressedContainerElevation,\n        focusedElevation: Dp = FilledCardTokens.FocusContainerElevation,\n        hoveredElevation: Dp = FilledCardTokens.HoverContainerElevation,\n        draggedElevation: Dp = FilledCardTokens.DraggedContainerElevation,\n        disabledElevation: Dp = FilledCardTokens.DisabledContainerElevation,\n    ): CardElevation =\n        CardElevation(\n            defaultElevation = defaultElevation,\n            pressedElevation = pressedElevation,\n            focusedElevation = focusedElevation,\n            hoveredElevation = hoveredElevation,\n            draggedElevation = draggedElevation,\n            disabledElevation = disabledElevation,\n        )\n\n    /**\n     * Creates a [CardElevation] that will animate between the provided values according to the\n     * Material specification for an [ElevatedCard].\n     *\n     * @param defaultElevation the elevation used when the [ElevatedCard] is has no other\n     *   [Interaction]s.\n     * @param pressedElevation the elevation used when the [ElevatedCard] is pressed.\n     * @param focusedElevation the elevation used when the [ElevatedCard] is focused.\n     * @param hoveredElevation the elevation used when the [ElevatedCard] is hovered.\n     * @param draggedElevation the elevation used when the [ElevatedCard] is dragged.\n     * @param disabledElevation the elevation used when the [Card] is disabled.\n     */\n    @Composable\n    fun elevatedCardElevation(\n        defaultElevation: Dp = ElevatedCardTokens.ContainerElevation,\n        pressedElevation: Dp = ElevatedCardTokens.PressedContainerElevation,\n        focusedElevation: Dp = ElevatedCardTokens.FocusContainerElevation,\n        hoveredElevation: Dp = ElevatedCardTokens.HoverContainerElevation,\n        draggedElevation: Dp = ElevatedCardTokens.DraggedContainerElevation,\n        disabledElevation: Dp = ElevatedCardTokens.DisabledContainerElevation,\n    ): CardElevation =\n        CardElevation(\n            defaultElevation = defaultElevation,\n            pressedElevation = pressedElevation,\n            focusedElevation = focusedElevation,\n            hoveredElevation = hoveredElevation,\n            draggedElevation = draggedElevation,\n            disabledElevation = disabledElevation,\n        )\n\n    /**\n     * Creates a [CardElevation] that will animate between the provided values according to the\n     * Material specification for an [OutlinedCard].\n     *\n     * @param defaultElevation the elevation used when the [OutlinedCard] is has no other\n     *   [Interaction]s.\n     * @param pressedElevation the elevation used when the [OutlinedCard] is pressed.\n     * @param focusedElevation the elevation used when the [OutlinedCard] is focused.\n     * @param hoveredElevation the elevation used when the [OutlinedCard] is hovered.\n     * @param draggedElevation the elevation used when the [OutlinedCard] is dragged.\n     */\n    @Composable\n    fun outlinedCardElevation(\n        defaultElevation: Dp = OutlinedCardTokens.ContainerElevation,\n        pressedElevation: Dp = defaultElevation,\n        focusedElevation: Dp = defaultElevation,\n        hoveredElevation: Dp = defaultElevation,\n        draggedElevation: Dp = OutlinedCardTokens.DraggedContainerElevation,\n        disabledElevation: Dp = OutlinedCardTokens.DisabledContainerElevation,\n    ): CardElevation =\n        CardElevation(\n            defaultElevation = defaultElevation,\n            pressedElevation = pressedElevation,\n            focusedElevation = focusedElevation,\n            hoveredElevation = hoveredElevation,\n            draggedElevation = draggedElevation,\n            disabledElevation = disabledElevation,\n        )\n\n    /**\n     * Creates a [CardColors] that represents the default container and content colors used in a\n     * [Card].\n     */\n    @Composable fun cardColors() = MaterialTheme.colorScheme.defaultCardColors\n\n    /**\n     * Creates a [CardColors] that represents the default container and content colors used in a\n     * [Card].\n     *\n     * @param containerColor the container color of this [Card] when enabled.\n     * @param contentColor the content color of this [Card] when enabled.\n     * @param disabledContainerColor the container color of this [Card] when not enabled.\n     * @param disabledContentColor the content color of this [Card] when not enabled.\n     */\n    @Composable\n    fun cardColors(\n        containerColor: Color = Color.Unspecified,\n        contentColor: Color = contentColorFor(containerColor),\n        disabledContainerColor: Color = Color.Unspecified,\n        disabledContentColor: Color = contentColor.copy(DisabledAlpha),\n    ): CardColors =\n        MaterialTheme.colorScheme.defaultCardColors.copy(\n            containerColor = containerColor,\n            contentColor = contentColor,\n            disabledContainerColor = disabledContainerColor,\n            disabledContentColor = disabledContentColor,\n        )\n\n    internal val ColorScheme.defaultCardColors: CardColors\n        get() {\n            return defaultCardColorsCached\n                ?: CardColors(\n                        containerColor = fromToken(FilledCardTokens.ContainerColor),\n                        contentColor = contentColorFor(fromToken(FilledCardTokens.ContainerColor)),\n                        disabledContainerColor =\n                            fromToken(FilledCardTokens.DisabledContainerColor)\n                                .copy(alpha = FilledCardTokens.DisabledContainerOpacity)\n                                .compositeOver(fromToken(FilledCardTokens.ContainerColor)),\n                        disabledContentColor =\n                            contentColorFor(fromToken(FilledCardTokens.ContainerColor))\n                                .copy(DisabledAlpha),\n                    )\n                    .also { defaultCardColorsCached = it }\n        }\n\n    /**\n     * Creates a [CardColors] that represents the default container and content colors used in an\n     * [ElevatedCard].\n     */\n    @Composable fun elevatedCardColors() = MaterialTheme.colorScheme.defaultElevatedCardColors\n\n    /**\n     * Creates a [CardColors] that represents the default container and content colors used in an\n     * [ElevatedCard].\n     *\n     * @param containerColor the container color of this [ElevatedCard] when enabled.\n     * @param contentColor the content color of this [ElevatedCard] when enabled.\n     * @param disabledContainerColor the container color of this [ElevatedCard] when not enabled.\n     * @param disabledContentColor the content color of this [ElevatedCard] when not enabled.\n     */\n    @Composable\n    fun elevatedCardColors(\n        containerColor: Color = Color.Unspecified,\n        contentColor: Color = contentColorFor(containerColor),\n        disabledContainerColor: Color = Color.Unspecified,\n        disabledContentColor: Color = contentColor.copy(DisabledAlpha),\n    ): CardColors =\n        MaterialTheme.colorScheme.defaultElevatedCardColors.copy(\n            containerColor = containerColor,\n            contentColor = contentColor,\n            disabledContainerColor = disabledContainerColor,\n            disabledContentColor = disabledContentColor,\n        )\n\n    internal val ColorScheme.defaultElevatedCardColors: CardColors\n        get() {\n            return defaultElevatedCardColorsCached\n                ?: CardColors(\n                        containerColor = fromToken(ElevatedCardTokens.ContainerColor),\n                        contentColor =\n                            contentColorFor(fromToken(ElevatedCardTokens.ContainerColor)),\n                        disabledContainerColor =\n                            fromToken(ElevatedCardTokens.DisabledContainerColor)\n                                .copy(alpha = ElevatedCardTokens.DisabledContainerOpacity)\n                                .compositeOver(\n                                    fromToken(ElevatedCardTokens.DisabledContainerColor)\n                                ),\n                        disabledContentColor =\n                            contentColorFor(fromToken(ElevatedCardTokens.ContainerColor))\n                                .copy(DisabledAlpha),\n                    )\n                    .also { defaultElevatedCardColorsCached = it }\n        }\n\n    /**\n     * Creates a [CardColors] that represents the default container and content colors used in an\n     * [OutlinedCard].\n     */\n    @Composable fun outlinedCardColors() = MaterialTheme.colorScheme.defaultOutlinedCardColors\n\n    /**\n     * Creates a [CardColors] that represents the default container and content colors used in an\n     * [OutlinedCard].\n     *\n     * @param containerColor the container color of this [OutlinedCard] when enabled.\n     * @param contentColor the content color of this [OutlinedCard] when enabled.\n     * @param disabledContainerColor the container color of this [OutlinedCard] when not enabled.\n     * @param disabledContentColor the content color of this [OutlinedCard] when not enabled.\n     */\n    @Composable\n    fun outlinedCardColors(\n        containerColor: Color = Color.Unspecified,\n        contentColor: Color = contentColorFor(containerColor),\n        disabledContainerColor: Color = Color.Unspecified,\n        disabledContentColor: Color = contentColorFor(containerColor).copy(DisabledAlpha),\n    ): CardColors =\n        MaterialTheme.colorScheme.defaultOutlinedCardColors.copy(\n            containerColor = containerColor,\n            contentColor = contentColor,\n            disabledContainerColor = disabledContainerColor,\n            disabledContentColor = disabledContentColor,\n        )\n\n    internal val ColorScheme.defaultOutlinedCardColors: CardColors\n        get() {\n            return defaultOutlinedCardColorsCached\n                ?: CardColors(\n                        containerColor = fromToken(OutlinedCardTokens.ContainerColor),\n                        contentColor =\n                            contentColorFor(fromToken(OutlinedCardTokens.ContainerColor)),\n                        disabledContainerColor = fromToken(OutlinedCardTokens.ContainerColor),\n                        disabledContentColor =\n                            contentColorFor(fromToken(OutlinedCardTokens.ContainerColor))\n                                .copy(DisabledAlpha),\n                    )\n                    .also { defaultOutlinedCardColorsCached = it }\n        }\n\n    /**\n     * Creates a [BorderStroke] that represents the default border used in [OutlinedCard].\n     *\n     * @param enabled whether the card is enabled\n     */\n    @Composable\n    fun outlinedCardBorder(enabled: Boolean = true): BorderStroke {\n        val color =\n            if (enabled) {\n                OutlinedCardTokens.OutlineColor.value\n            } else {\n                OutlinedCardTokens.DisabledOutlineColor.value\n                    .copy(alpha = OutlinedCardTokens.DisabledOutlineOpacity)\n                    .compositeOver(ElevatedCardTokens.ContainerColor.value)\n            }\n        return remember(color) { BorderStroke(OutlinedCardTokens.OutlineWidth, color) }\n    }\n}\n\n/**\n * Represents the elevation for a card in different states.\n * - See [CardDefaults.cardElevation] for the default elevation used in a [Card].\n * - See [CardDefaults.elevatedCardElevation] for the default elevation used in an [ElevatedCard].\n * - See [CardDefaults.outlinedCardElevation] for the default elevation used in an [OutlinedCard].\n */\n@Immutable\nclass CardElevation\ninternal constructor(\n    private val defaultElevation: Dp,\n    private val pressedElevation: Dp,\n    private val focusedElevation: Dp,\n    private val hoveredElevation: Dp,\n    private val draggedElevation: Dp,\n    private val disabledElevation: Dp,\n) {\n    /**\n     * Represents the shadow elevation used in a card, depending on its [enabled] state and\n     * [interactionSource].\n     *\n     * Shadow elevation is used to apply a shadow around the card to give it higher emphasis.\n     *\n     * @param enabled whether the card is enabled\n     * @param interactionSource the [InteractionSource] for this card\n     */\n    @Composable\n    internal fun shadowElevation(\n        enabled: Boolean,\n        interactionSource: InteractionSource?,\n    ): State<Dp> {\n        if (interactionSource == null) {\n            return remember { mutableStateOf(defaultElevation) }\n        }\n        return animateElevation(enabled = enabled, interactionSource = interactionSource)\n    }\n\n    @Composable\n    private fun animateElevation(\n        enabled: Boolean,\n        interactionSource: InteractionSource,\n    ): State<Dp> {\n        val interactions = remember { mutableStateListOf<Interaction>() }\n        LaunchedEffect(interactionSource) {\n            interactionSource.interactions.collect { interaction ->\n                when (interaction) {\n                    is HoverInteraction.Enter -> {\n                        interactions.add(interaction)\n                    }\n                    is HoverInteraction.Exit -> {\n                        interactions.remove(interaction.enter)\n                    }\n                    is FocusInteraction.Focus -> {\n                        interactions.add(interaction)\n                    }\n                    is FocusInteraction.Unfocus -> {\n                        interactions.remove(interaction.focus)\n                    }\n                    is PressInteraction.Press -> {\n                        interactions.add(interaction)\n                    }\n                    is PressInteraction.Release -> {\n                        interactions.remove(interaction.press)\n                    }\n                    is PressInteraction.Cancel -> {\n                        interactions.remove(interaction.press)\n                    }\n                    is DragInteraction.Start -> {\n                        interactions.add(interaction)\n                    }\n                    is DragInteraction.Stop -> {\n                        interactions.remove(interaction.start)\n                    }\n                    is DragInteraction.Cancel -> {\n                        interactions.remove(interaction.start)\n                    }\n                }\n            }\n        }\n\n        val interaction = interactions.lastOrNull()\n\n        val target =\n            if (!enabled) {\n                disabledElevation\n            } else {\n                when (interaction) {\n                    is PressInteraction.Press -> pressedElevation\n                    is HoverInteraction.Enter -> hoveredElevation\n                    is FocusInteraction.Focus -> focusedElevation\n                    is DragInteraction.Start -> draggedElevation\n                    else -> defaultElevation\n                }\n            }\n\n        val animatable = remember { Animatable(target, Dp.VectorConverter) }\n\n        LaunchedEffect(target) {\n            if (animatable.targetValue != target) {\n                if (!enabled) {\n                    // No transition when moving to a disabled state.\n                    animatable.snapTo(target)\n                } else {\n                    val lastInteraction =\n                        when (animatable.targetValue) {\n                            pressedElevation -> PressInteraction.Press(Offset.Zero)\n                            hoveredElevation -> HoverInteraction.Enter()\n                            focusedElevation -> FocusInteraction.Focus()\n                            draggedElevation -> DragInteraction.Start()\n                            else -> null\n                        }\n                    animatable.animateElevation(\n                        from = lastInteraction,\n                        to = interaction,\n                        target = target,\n                    )\n                }\n            }\n        }\n\n        return animatable.asState()\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is CardElevation) return false\n\n        if (defaultElevation != other.defaultElevation) return false\n        if (pressedElevation != other.pressedElevation) return false\n        if (focusedElevation != other.focusedElevation) return false\n        if (hoveredElevation != other.hoveredElevation) return false\n        if (disabledElevation != other.disabledElevation) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = defaultElevation.hashCode()\n        result = 31 * result + pressedElevation.hashCode()\n        result = 31 * result + focusedElevation.hashCode()\n        result = 31 * result + hoveredElevation.hashCode()\n        result = 31 * result + disabledElevation.hashCode()\n        return result\n    }\n}\n\n/**\n * Represents the container and content colors used in a card in different states.\n *\n * @param containerColor the container color of this [Card] when enabled.\n * @param contentColor the content color of this [Card] when enabled.\n * @param disabledContainerColor the container color of this [Card] when not enabled.\n * @param disabledContentColor the content color of this [Card] when not enabled.\n * @constructor create an instance with arbitrary colors.\n * - See [CardDefaults.cardColors] for the default colors used in a [Card].\n * - See [CardDefaults.elevatedCardColors] for the default colors used in a [ElevatedCard].\n * - See [CardDefaults.outlinedCardColors] for the default colors used in a [OutlinedCard].\n */\n@Immutable\nclass CardColors\nconstructor(\n    val containerColor: Color,\n    val contentColor: Color,\n    val disabledContainerColor: Color,\n    val disabledContentColor: Color,\n) {\n    /**\n     * Returns a copy of this CardColors, optionally overriding some of the values. This uses the\n     * Color.Unspecified to mean “use the value from the source”\n     */\n    fun copy(\n        containerColor: Color = this.containerColor,\n        contentColor: Color = this.contentColor,\n        disabledContainerColor: Color = this.disabledContainerColor,\n        disabledContentColor: Color = this.disabledContentColor,\n    ) =\n        CardColors(\n            containerColor.takeOrElse { this.containerColor },\n            contentColor.takeOrElse { this.contentColor },\n            disabledContainerColor.takeOrElse { this.disabledContainerColor },\n            disabledContentColor.takeOrElse { this.disabledContentColor },\n        )\n\n    /**\n     * Represents the container color for this card, depending on [enabled].\n     *\n     * @param enabled whether the card is enabled\n     */\n    @Stable\n    internal fun containerColor(enabled: Boolean): Color =\n        if (enabled) containerColor else disabledContainerColor\n\n    /**\n     * Represents the content color for this card, depending on [enabled].\n     *\n     * @param enabled whether the card is enabled\n     */\n    @Stable\n    internal fun contentColor(enabled: Boolean) =\n        if (enabled) contentColor else disabledContentColor\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is CardColors) return false\n\n        if (containerColor != other.containerColor) return false\n        if (contentColor != other.contentColor) return false\n        if (disabledContainerColor != other.disabledContainerColor) return false\n        if (disabledContentColor != other.disabledContentColor) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = containerColor.hashCode()\n        result = 31 * result + contentColor.hashCode()\n        result = 31 * result + disabledContainerColor.hashCode()\n        result = 31 * result + disabledContentColor.hashCode()\n        return result\n    }\n}\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Scaffold.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.asPaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.consumeWindowInsets\nimport androidx.compose.foundation.layout.exclude\nimport androidx.compose.foundation.layout.onConsumedWindowInsetsChanged\nimport androidx.compose.material3.internal.MutableWindowInsets\nimport androidx.compose.material3.internal.systemBarsForVisualComponents\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.layout.SubcomposeLayout\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.offset\n\n/**\n * [Material Design layout](https://m3.material.io/foundations/layout/understanding-layout/)\n *\n * Scaffold implements the basic Material Design visual layout structure.\n *\n * This component provides API to put together several Material components to construct your screen,\n * by ensuring proper layout strategy for them and collecting necessary data so these components\n * will work together correctly.\n *\n * Simple example of a Scaffold with [TopAppBar] and [FloatingActionButton]:\n *\n * @sample androidx.compose.material3.samples.SimpleScaffoldWithTopBar\n *\n * To show a [Snackbar], use [SnackbarHostState.showSnackbar].\n *\n * @sample androidx.compose.material3.samples.ScaffoldWithSimpleSnackbar\n * @param modifier the [Modifier] to be applied to this scaffold\n * @param topBar top app bar of the screen, typically a [TopAppBar]\n * @param bottomBar bottom bar of the screen, typically a [NavigationBar]\n * @param snackbarHost component to host [Snackbar]s that are pushed to be shown via\n *   [SnackbarHostState.showSnackbar], typically a [SnackbarHost]\n * @param floatingActionButton Main action button of the screen, typically a [FloatingActionButton]\n * @param floatingActionButtonPosition position of the FAB on the screen. See [FabPosition].\n * @param containerColor the color used for the background of this scaffold. Use [Color.Transparent]\n *   to have no color.\n * @param contentColor the preferred color for content inside this scaffold. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param contentWindowInsets window insets to be passed to [content] slot via [PaddingValues]\n *   params. Scaffold will take the insets into account from the top/bottom only if the [topBar]/\n *   [bottomBar] are not present, as the scaffold expect [topBar]/[bottomBar] to handle insets\n *   instead. Any insets consumed by other insets padding modifiers or [consumeWindowInsets] on a\n *   parent layout will be excluded from [contentWindowInsets].\n * @param content content of the screen. The lambda receives a [PaddingValues] that should be\n *   applied to the content root via [Modifier.padding] and [Modifier.consumeWindowInsets] to\n *   properly offset top and bottom bars. If using [Modifier.verticalScroll], apply this modifier to\n *   the child of the scroll, and not on the scroll itself.\n */\n@Composable\nfun Scaffold(\n    modifier: Modifier = Modifier,\n    topBar: @Composable () -> Unit = {},\n    bottomBar: @Composable () -> Unit = {},\n    snackbarHost: @Composable () -> Unit = {},\n    floatingActionButton: @Composable () -> Unit = {},\n    floatingActionButtonPosition: FabPosition = FabPosition.End,\n    containerColor: Color = MaterialTheme.colorScheme.background,\n    contentColor: Color = contentColorFor(containerColor),\n    contentWindowInsets: WindowInsets = ScaffoldDefaults.contentWindowInsets,\n    content: @Composable (PaddingValues) -> Unit,\n) {\n    val safeInsets = remember(contentWindowInsets) { MutableWindowInsets(contentWindowInsets) }\n    Surface(\n        modifier =\n            modifier.onConsumedWindowInsetsChanged { consumedWindowInsets ->\n                // Exclude currently consumed window insets from user provided contentWindowInsets\n                safeInsets.insets = contentWindowInsets.exclude(consumedWindowInsets)\n            },\n        color = containerColor,\n        contentColor = contentColor,\n    ) {\n        ScaffoldLayout(\n            fabPosition = floatingActionButtonPosition,\n            topBar = topBar,\n            bottomBar = bottomBar,\n            content = content,\n            snackbar = snackbarHost,\n            contentWindowInsets = safeInsets,\n            fab = floatingActionButton,\n        )\n    }\n}\n\n/**\n * Layout for a [Scaffold]'s content.\n *\n * @param fabPosition [FabPosition] for the FAB (if present)\n * @param topBar the content to place at the top of the [Scaffold], typically a [SmallTopAppBar]\n * @param content the main 'body' of the [Scaffold]\n * @param snackbar the [Snackbar] displayed on top of the [content]\n * @param fab the [FloatingActionButton] displayed on top of the [content], below the [snackbar] and\n *   above the [bottomBar]\n * @param bottomBar the content to place at the bottom of the [Scaffold], on top of the [content],\n *   typically a [NavigationBar].\n */\n@Composable\nprivate fun ScaffoldLayout(\n    fabPosition: FabPosition,\n    topBar: @Composable () -> Unit,\n    content: @Composable (PaddingValues) -> Unit,\n    snackbar: @Composable () -> Unit,\n    fab: @Composable () -> Unit,\n    contentWindowInsets: WindowInsets,\n    bottomBar: @Composable () -> Unit,\n) {\n    // Create the backing value for the content padding\n    // These values will be updated during measurement, but before subcomposing the body content\n    // Remembering and updating a single PaddingValues avoids needing to recompose when the values\n    // change\n    val contentPadding = remember {\n        object : PaddingValues {\n            var paddingHolder by mutableStateOf(PaddingValues(0.dp))\n\n            override fun calculateLeftPadding(layoutDirection: LayoutDirection): Dp =\n                paddingHolder.calculateLeftPadding(layoutDirection)\n\n            override fun calculateTopPadding(): Dp = paddingHolder.calculateTopPadding()\n\n            override fun calculateRightPadding(layoutDirection: LayoutDirection): Dp =\n                paddingHolder.calculateRightPadding(layoutDirection)\n\n            override fun calculateBottomPadding(): Dp = paddingHolder.calculateBottomPadding()\n        }\n    }\n\n    val topBarContent: @Composable () -> Unit = remember(topBar) { { Box { topBar() } } }\n    val snackbarContent: @Composable () -> Unit = remember(snackbar) { { Box { snackbar() } } }\n    val fabContent: @Composable () -> Unit = remember(fab) { { Box { fab() } } }\n    val bodyContent: @Composable () -> Unit =\n        remember(content, contentPadding) { { Box { content(contentPadding) } } }\n    val bottomBarContent: @Composable () -> Unit = remember(bottomBar) { { Box { bottomBar() } } }\n    SubcomposeLayout { constraints ->\n        val layoutWidth = constraints.maxWidth\n        val layoutHeight = constraints.maxHeight\n\n        val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)\n\n        // respect only bottom and horizontal for snackbar and fab\n        val leftInset = contentWindowInsets.getLeft(this@SubcomposeLayout, layoutDirection)\n        val rightInset = contentWindowInsets.getRight(this@SubcomposeLayout, layoutDirection)\n        val bottomInset = contentWindowInsets.getBottom(this@SubcomposeLayout)\n\n        val topBarPlaceable =\n            subcompose(ScaffoldLayoutContent.TopBar, topBarContent)\n                .first()\n                .measure(looseConstraints)\n\n        val snackbarPlaceable =\n            subcompose(ScaffoldLayoutContent.Snackbar, snackbarContent)\n                .first()\n                .measure(looseConstraints.offset(-leftInset - rightInset, -bottomInset))\n\n        val fabPlaceable =\n            subcompose(ScaffoldLayoutContent.Fab, fabContent)\n                .first()\n                .measure(looseConstraints.offset(-leftInset - rightInset, -bottomInset))\n\n        val isFabEmpty = fabPlaceable.width == 0 && fabPlaceable.height == 0\n        val fabPlacement =\n            if (!isFabEmpty) {\n                val fabWidth = fabPlaceable.width\n                val fabHeight = fabPlaceable.height\n                // FAB distance from the left of the layout, taking into account LTR / RTL\n                val fabLeftOffset =\n                    when (fabPosition) {\n                        FabPosition.Start -> {\n                            if (layoutDirection == LayoutDirection.Ltr) {\n                                FabSpacing.roundToPx() + leftInset\n                            } else {\n                                layoutWidth - FabSpacing.roundToPx() - fabWidth - rightInset\n                            }\n                        }\n                        FabPosition.End,\n                        FabPosition.EndOverlay -> {\n                            if (layoutDirection == LayoutDirection.Ltr) {\n                                layoutWidth - FabSpacing.roundToPx() - fabWidth - rightInset\n                            } else {\n                                FabSpacing.roundToPx() + leftInset\n                            }\n                        }\n                        else -> (layoutWidth - fabWidth + leftInset - rightInset) / 2\n                    }\n\n                FabPlacement(left = fabLeftOffset, width = fabWidth, height = fabHeight)\n            } else {\n                null\n            }\n\n        val bottomBarPlaceable =\n            subcompose(ScaffoldLayoutContent.BottomBar, bottomBarContent)\n                .first()\n                .measure(looseConstraints)\n\n        val isBottomBarEmpty = bottomBarPlaceable.width == 0 && bottomBarPlaceable.height == 0\n\n        val fabOffsetFromBottom =\n            fabPlacement?.let {\n                if (isBottomBarEmpty || fabPosition == FabPosition.EndOverlay) {\n                    it.height +\n                        FabSpacing.roundToPx() +\n                        contentWindowInsets.getBottom(this@SubcomposeLayout)\n                } else {\n                    // Total height is the bottom bar height + the FAB height + the padding\n                    // between the FAB and bottom bar\n                    bottomBarPlaceable.height + it.height + FabSpacing.roundToPx()\n                }\n            }\n\n        val snackbarHeight = snackbarPlaceable.height\n        val snackbarOffsetFromBottom =\n            if (snackbarHeight != 0) {\n                snackbarHeight +\n                    (fabOffsetFromBottom\n                        ?: bottomBarPlaceable.height.takeIf { !isBottomBarEmpty }\n                        ?: contentWindowInsets.getBottom(this@SubcomposeLayout))\n            } else {\n                0\n            }\n\n        // Update the backing state for the content padding before subcomposing the body\n        val insets = contentWindowInsets.asPaddingValues(this)\n        contentPadding.paddingHolder =\n            PaddingValues(\n                top =\n                    if (topBarPlaceable.width == 0 && topBarPlaceable.height == 0) {\n                        insets.calculateTopPadding()\n                    } else {\n                        topBarPlaceable.height.toDp()\n                    },\n                bottom =\n                    if (isBottomBarEmpty) {\n                        insets.calculateBottomPadding()\n                    } else {\n                        bottomBarPlaceable.height.toDp()\n                    },\n                start = insets.calculateStartPadding(layoutDirection),\n                end = insets.calculateEndPadding(layoutDirection),\n            )\n\n        val bodyContentPlaceable =\n            subcompose(ScaffoldLayoutContent.MainContent, bodyContent)\n                .first()\n                .measure(looseConstraints)\n\n        layout(layoutWidth, layoutHeight) {\n            // Placing to control drawing order to match default elevation of each placeable\n            bodyContentPlaceable.place(0, 0)\n            topBarPlaceable.place(0, 0)\n            snackbarPlaceable.place(\n                (layoutWidth - snackbarPlaceable.width +\n                    contentWindowInsets.getLeft(this@SubcomposeLayout, layoutDirection) -\n                    contentWindowInsets.getRight(this@SubcomposeLayout, layoutDirection)) / 2,\n                layoutHeight - snackbarOffsetFromBottom,\n            )\n            // The bottom bar is always at the bottom of the layout\n            bottomBarPlaceable.place(0, layoutHeight - (bottomBarPlaceable.height))\n            // Explicitly not using placeRelative here as `leftOffset` already accounts for RTL\n            fabPlacement?.let { placement ->\n                fabPlaceable.place(placement.left, layoutHeight - fabOffsetFromBottom!!)\n            }\n        }\n    }\n}\n\n/** Object containing various default values for [Scaffold] component. */\nobject ScaffoldDefaults {\n    /** Default insets to be used and consumed by the scaffold content slot */\n    val contentWindowInsets: WindowInsets\n        @Composable get() = WindowInsets.systemBarsForVisualComponents\n}\n\n/** The possible positions for a [FloatingActionButton] attached to a [Scaffold]. */\n@kotlin.jvm.JvmInline\nvalue class FabPosition internal constructor(@Suppress(\"unused\") private val value: Int) {\n    companion object {\n        /**\n         * Position FAB at the bottom of the screen at the start, above the [NavigationBar] (if it\n         * exists)\n         */\n        val Start = FabPosition(0)\n\n        /**\n         * Position FAB at the bottom of the screen in the center, above the [NavigationBar] (if it\n         * exists)\n         */\n        val Center = FabPosition(1)\n\n        /**\n         * Position FAB at the bottom of the screen at the end, above the [NavigationBar] (if it\n         * exists)\n         */\n        val End = FabPosition(2)\n\n        /**\n         * Position FAB at the bottom of the screen at the end, overlaying the [NavigationBar] (if\n         * it exists)\n         */\n        val EndOverlay = FabPosition(3)\n    }\n\n    override fun toString(): String {\n        return when (this) {\n            Start -> \"FabPosition.Start\"\n            Center -> \"FabPosition.Center\"\n            End -> \"FabPosition.End\"\n            else -> \"FabPosition.EndOverlay\"\n        }\n    }\n}\n\n/**\n * Placement information for a [FloatingActionButton] inside a [Scaffold].\n *\n * @property left the FAB's offset from the left edge of the bottom bar, already adjusted for RTL\n *   support\n * @property width the width of the FAB\n * @property height the height of the FAB\n */\n@Immutable internal class FabPlacement(val left: Int, val width: Int, val height: Int)\n\n// FAB spacing above the bottom bar / bottom of the Scaffold\nprivate val FabSpacing = 16.dp\n\nprivate enum class ScaffoldLayoutContent {\n    TopBar,\n    MainContent,\n    Snackbar,\n    Fab,\n    BottomBar,\n}\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationBar.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.indication\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.foundation.selection.selectable\nimport androidx.compose.foundation.selection.selectableGroup\nimport androidx.compose.material3.DefaultNavigationBarOverride.NavigationBar\nimport androidx.compose.material3.internal.MappedInteractionSource\nimport androidx.compose.material3.internal.ProvideContentColorTextStyle\nimport androidx.compose.material3.internal.systemBarsForVisualComponents\nimport androidx.compose.material3.tokens.ElevationTokens\nimport androidx.compose.material3.tokens.MotionSchemeKeyTokens\nimport androidx.compose.material3.tokens.NavigationBarTokens\nimport androidx.compose.material3.tokens.NavigationBarVerticalItemTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.ProvidableCompositionLocal\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.layout.layoutId\nimport androidx.compose.ui.layout.onSizeChanged\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.semantics.clearAndSetSemantics\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.constrainHeight\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastFirst\nimport androidx.compose.ui.util.fastFirstOrNull\nimport kotlin.math.roundToInt\n\n/**\n * [Material Design bottom navigation\n * bar](https://m3.material.io/components/navigation-bar/overview)\n *\n * Navigation bars offer a persistent and convenient way to switch between primary destinations in\n * an app.\n *\n * ![Navigation bar\n * image](https://developer.android.com/images/reference/androidx/compose/material3/navigation-bar.png)\n *\n * [NavigationBar] should contain three to five [NavigationBarItem]s, each representing a singular\n * destination.\n *\n * A simple example looks like:\n *\n * @sample androidx.compose.material3.samples.NavigationBarSample\n *\n * See [NavigationBarItem] for configuration specific to each item, and not the overall\n * [NavigationBar] component.\n *\n * @param modifier the [Modifier] to be applied to this navigation bar\n * @param containerColor the color used for the background of this navigation bar. Use\n *   [Color.Transparent] to have no color.\n * @param contentColor the preferred color for content inside this navigation bar. Defaults to\n *   either the matching content color for [containerColor], or to the current [LocalContentColor]\n *   if [containerColor] is not a color from the theme.\n * @param tonalElevation when [containerColor] is [ColorScheme.surface], a translucent primary color\n *   overlay is applied on top of the container. A higher tonal elevation value will result in a\n *   darker color in light theme and lighter color in dark theme. See also: [Surface].\n * @param windowInsets a window insets of the navigation bar.\n * @param content the content of this navigation bar, typically 3-5 [NavigationBarItem]s\n */\n@OptIn(ExperimentalMaterial3ComponentOverrideApi::class)\n@Composable\nfun NavigationBar(\n    modifier: Modifier = Modifier,\n    containerColor: Color = NavigationBarDefaults.containerColor,\n    contentColor: Color = MaterialTheme.colorScheme.contentColorFor(containerColor),\n    tonalElevation: Dp = NavigationBarDefaults.Elevation,\n    windowInsets: WindowInsets = NavigationBarDefaults.windowInsets,\n    content: @Composable RowScope.() -> Unit,\n) {\n    with(LocalNavigationBarOverride.current) {\n        NavigationBarOverrideScope(\n                modifier = modifier,\n                containerColor = containerColor,\n                contentColor = contentColor,\n                tonalElevation = tonalElevation,\n                windowInsets = windowInsets,\n                content = content,\n            )\n            .NavigationBar()\n    }\n}\n\n/**\n * This override provides the default behavior of the [NavigationBar] component.\n *\n * [NavigationBarOverride] used when no override is specified.\n */\n@ExperimentalMaterial3ComponentOverrideApi\nobject DefaultNavigationBarOverride : NavigationBarOverride {\n    @Composable\n    override fun NavigationBarOverrideScope.NavigationBar() {\n        Surface(\n            color = containerColor,\n            contentColor = contentColor,\n            tonalElevation = tonalElevation,\n            modifier = modifier,\n        ) {\n            Row(\n                modifier =\n                    Modifier.fillMaxWidth()\n                        .windowInsetsPadding(windowInsets)\n                        .defaultMinSize(minHeight = NavigationBarHeight)\n                        .selectableGroup(),\n                horizontalArrangement = Arrangement.spacedBy(NavigationBarItemHorizontalPadding),\n                verticalAlignment = Alignment.CenterVertically,\n                content = content,\n            )\n        }\n    }\n}\n\n/**\n * Material Design navigation bar item.\n *\n * Navigation bars offer a persistent and convenient way to switch between primary destinations in\n * an app.\n *\n * The recommended configuration for a [NavigationBarItem] depends on how many items there are\n * inside a [NavigationBar]:\n * - Three destinations: Display icons and text labels for all destinations.\n * - Four destinations: Active destinations display an icon and text label. Inactive destinations\n *   display icons, and text labels are recommended.\n * - Five destinations: Active destinations display an icon and text label. Inactive destinations\n *   use icons, and use text labels if space permits.\n *\n * A [NavigationBarItem] always shows text labels (if it exists) when selected. Showing text labels\n * if not selected is controlled by [alwaysShowLabel].\n *\n * @param selected whether this item is selected\n * @param onClick called when this item is clicked\n * @param icon icon for this item, typically an [Icon]\n * @param modifier the [Modifier] to be applied to this item\n * @param enabled controls the enabled state of this item. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param label optional text label for this item\n * @param alwaysShowLabel whether to always show the label for this item. If `false`, the label will\n *   only be shown when this item is selected.\n * @param colors [NavigationBarItemColors] that will be used to resolve the colors used for this\n *   item in different states. See [NavigationBarItemDefaults.colors].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this item. You can use this to change the item's appearance or\n *   preview the item in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n */\n@Composable\nfun RowScope.NavigationBarItem(\n    selected: Boolean,\n    onClick: () -> Unit,\n    icon: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    label: @Composable (() -> Unit)? = null,\n    alwaysShowLabel: Boolean = true,\n    colors: NavigationBarItemColors = NavigationBarItemDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    // TODO Load the motionScheme tokens from the component tokens file\n    val colorAnimationSpec = MotionSchemeKeyTokens.DefaultEffects.value<Color>()\n    val styledIcon =\n        @Composable {\n            val iconColor by\n                animateColorAsState(\n                    targetValue = colors.iconColor(selected = selected, enabled = enabled),\n                    animationSpec = colorAnimationSpec,\n                )\n            // If there's a label, don't have a11y services repeat the icon description.\n            val clearSemantics = label != null && (alwaysShowLabel || selected)\n            Box(modifier = if (clearSemantics) Modifier.clearAndSetSemantics {} else Modifier) {\n                CompositionLocalProvider(LocalContentColor provides iconColor, content = icon)\n            }\n        }\n\n    val styledLabel: @Composable (() -> Unit)? =\n        label?.let {\n            @Composable {\n                val style = NavigationBarTokens.LabelTextFont.value\n                val textColor by\n                    animateColorAsState(\n                        targetValue = colors.textColor(selected = selected, enabled = enabled),\n                        animationSpec = colorAnimationSpec,\n                    )\n                ProvideContentColorTextStyle(\n                    contentColor = textColor,\n                    textStyle = style,\n                    content = label,\n                )\n            }\n        }\n\n    var itemWidth by remember { mutableIntStateOf(0) }\n\n    Box(\n        modifier\n            .selectable(\n                selected = selected,\n                onClick = onClick,\n                enabled = enabled,\n                role = Role.Tab,\n                interactionSource = interactionSource,\n                indication = null,\n            )\n            .defaultMinSize(minHeight = NavigationBarHeight)\n            .weight(1f)\n            .onSizeChanged { itemWidth = it.width },\n        contentAlignment = Alignment.Center,\n        propagateMinConstraints = true,\n    ) {\n        val alphaAnimationProgress: State<Float> =\n            animateFloatAsState(\n                targetValue = if (selected) 1f else 0f,\n                // TODO Load the motionScheme tokens from the component tokens file\n                animationSpec = MotionSchemeKeyTokens.DefaultEffects.value(),\n            )\n        val sizeAnimationProgress: State<Float> =\n            animateFloatAsState(\n                targetValue = if (selected) 1f else 0f,\n                // TODO Load the motionScheme tokens from the component tokens file\n                animationSpec = MotionSchemeKeyTokens.FastSpatial.value(),\n            )\n        // The entire item is selectable, but only the indicator pill shows the ripple. To achieve\n        // this, we re-map the coordinates of the item's InteractionSource into the coordinates of\n        // the indicator.\n        val density = LocalDensity.current\n        val calculateDeltaOffset = {\n            with(density) {\n                val indicatorWidth =\n                    NavigationBarVerticalItemTokens.ActiveIndicatorWidth.roundToPx()\n                Offset((itemWidth - indicatorWidth).toFloat() / 2, IndicatorVerticalOffset.toPx())\n            }\n        }\n        val offsetInteractionSource =\n            remember(interactionSource, calculateDeltaOffset) {\n                MappedInteractionSource(interactionSource, calculateDeltaOffset)\n            }\n\n        // The indicator has a width-expansion animation which interferes with the timing of the\n        // ripple, which is why they are separate composables\n        val indicatorRipple =\n            @Composable {\n                Box(\n                    Modifier.layoutId(IndicatorRippleLayoutIdTag)\n                        .clip(NavigationBarTokens.ItemActiveIndicatorShape.value)\n                        .indication(offsetInteractionSource, ripple())\n                )\n            }\n        val indicator =\n            @Composable {\n                Box(\n                    Modifier.layoutId(IndicatorLayoutIdTag)\n                        .graphicsLayer { alpha = alphaAnimationProgress.value }\n                        .background(\n                            color = colors.indicatorColor,\n                            shape = NavigationBarTokens.ItemActiveIndicatorShape.value,\n                        )\n                )\n            }\n\n        NavigationBarItemLayout(\n            indicatorRipple = indicatorRipple,\n            indicator = indicator,\n            icon = styledIcon,\n            label = styledLabel,\n            alwaysShowLabel = alwaysShowLabel,\n            alphaAnimationProgress = { alphaAnimationProgress.value },\n            sizeAnimationProgress = { sizeAnimationProgress.value },\n        )\n    }\n}\n\n/** Defaults used in [NavigationBar]. */\nobject NavigationBarDefaults {\n    /** Default elevation for a navigation bar. */\n    val Elevation: Dp = ElevationTokens.Level0\n\n    /** Default color for a navigation bar. */\n    val containerColor: Color\n        @Composable get() = NavigationBarTokens.ContainerColor.value\n\n    /** Default window insets to be used and consumed by navigation bar */\n    val windowInsets: WindowInsets\n        @Composable\n        get() =\n            WindowInsets.systemBarsForVisualComponents.only(\n                WindowInsetsSides.Horizontal + WindowInsetsSides.Bottom\n            )\n}\n\n/** Defaults used in [NavigationBarItem]. */\nobject NavigationBarItemDefaults {\n\n    /**\n     * Creates a [NavigationBarItemColors] with the provided colors according to the Material\n     * specification.\n     */\n    @Composable fun colors() = MaterialTheme.colorScheme.defaultNavigationBarItemColors\n\n    /**\n     * Creates a [NavigationBarItemColors] with the provided colors according to the Material\n     * specification.\n     *\n     * @param selectedIconColor the color to use for the icon when the item is selected.\n     * @param selectedTextColor the color to use for the text label when the item is selected.\n     * @param indicatorColor the color to use for the indicator when the item is selected.\n     * @param unselectedIconColor the color to use for the icon when the item is unselected.\n     * @param unselectedTextColor the color to use for the text label when the item is unselected.\n     * @param disabledIconColor the color to use for the icon when the item is disabled.\n     * @param disabledTextColor the color to use for the text label when the item is disabled.\n     * @return the resulting [NavigationBarItemColors] used for [NavigationBarItem]\n     */\n    @Composable\n    fun colors(\n        selectedIconColor: Color = Color.Unspecified,\n        selectedTextColor: Color = Color.Unspecified,\n        indicatorColor: Color = Color.Unspecified,\n        unselectedIconColor: Color = Color.Unspecified,\n        unselectedTextColor: Color = Color.Unspecified,\n        disabledIconColor: Color = Color.Unspecified,\n        disabledTextColor: Color = Color.Unspecified,\n    ): NavigationBarItemColors =\n        MaterialTheme.colorScheme.defaultNavigationBarItemColors.copy(\n            selectedIconColor = selectedIconColor,\n            selectedTextColor = selectedTextColor,\n            selectedIndicatorColor = indicatorColor,\n            unselectedIconColor = unselectedIconColor,\n            unselectedTextColor = unselectedTextColor,\n            disabledIconColor = disabledIconColor,\n            disabledTextColor = disabledTextColor,\n        )\n\n    internal val ColorScheme.defaultNavigationBarItemColors: NavigationBarItemColors\n        get() {\n            return defaultNavigationBarItemColorsCached\n                ?: NavigationBarItemColors(\n                        selectedIconColor = fromToken(NavigationBarTokens.ItemActiveIconColor),\n                        selectedTextColor = fromToken(NavigationBarTokens.ItemActiveLabelTextColor),\n                        selectedIndicatorColor =\n                            fromToken(NavigationBarTokens.ItemActiveIndicatorColor),\n                        unselectedIconColor = fromToken(NavigationBarTokens.ItemInactiveIconColor),\n                        unselectedTextColor =\n                            fromToken(NavigationBarTokens.ItemInactiveLabelTextColor),\n                        disabledIconColor =\n                            fromToken(NavigationBarTokens.ItemInactiveIconColor)\n                                .copy(alpha = DisabledAlpha),\n                        disabledTextColor =\n                            fromToken(NavigationBarTokens.ItemInactiveLabelTextColor)\n                                .copy(alpha = DisabledAlpha),\n                    )\n                    .also { defaultNavigationBarItemColorsCached = it }\n        }\n\n    @Deprecated(\n        \"Use overload with disabledIconColor and disabledTextColor\",\n        level = DeprecationLevel.HIDDEN,\n    )\n    @Composable\n    fun colors(\n        selectedIconColor: Color = NavigationBarTokens.ItemActiveIconColor.value,\n        selectedTextColor: Color = NavigationBarTokens.ItemActiveLabelTextColor.value,\n        indicatorColor: Color = NavigationBarTokens.ItemActiveIndicatorColor.value,\n        unselectedIconColor: Color = NavigationBarTokens.ItemInactiveIconColor.value,\n        unselectedTextColor: Color = NavigationBarTokens.ItemInactiveLabelTextColor.value,\n    ): NavigationBarItemColors =\n        NavigationBarItemColors(\n            selectedIconColor = selectedIconColor,\n            selectedTextColor = selectedTextColor,\n            selectedIndicatorColor = indicatorColor,\n            unselectedIconColor = unselectedIconColor,\n            unselectedTextColor = unselectedTextColor,\n            disabledIconColor = unselectedIconColor.copy(alpha = DisabledAlpha),\n            disabledTextColor = unselectedTextColor.copy(alpha = DisabledAlpha),\n        )\n}\n\n/**\n * Represents the colors of the various elements of a navigation item.\n *\n * @param selectedIconColor the color to use for the icon when the item is selected.\n * @param selectedTextColor the color to use for the text label when the item is selected.\n * @param selectedIndicatorColor the color to use for the indicator when the item is selected.\n * @param unselectedIconColor the color to use for the icon when the item is unselected.\n * @param unselectedTextColor the color to use for the text label when the item is unselected.\n * @param disabledIconColor the color to use for the icon when the item is disabled.\n * @param disabledTextColor the color to use for the text label when the item is disabled.\n * @constructor create an instance with arbitrary colors.\n */\n@Immutable\nclass NavigationBarItemColors\nconstructor(\n    val selectedIconColor: Color,\n    val selectedTextColor: Color,\n    val selectedIndicatorColor: Color,\n    val unselectedIconColor: Color,\n    val unselectedTextColor: Color,\n    val disabledIconColor: Color,\n    val disabledTextColor: Color,\n) {\n    /**\n     * Returns a copy of this NavigationBarItemColors, optionally overriding some of the values.\n     * This uses the Color.Unspecified to mean “use the value from the source”\n     */\n    fun copy(\n        selectedIconColor: Color = this.selectedIconColor,\n        selectedTextColor: Color = this.selectedTextColor,\n        selectedIndicatorColor: Color = this.selectedIndicatorColor,\n        unselectedIconColor: Color = this.unselectedIconColor,\n        unselectedTextColor: Color = this.unselectedTextColor,\n        disabledIconColor: Color = this.disabledIconColor,\n        disabledTextColor: Color = this.disabledTextColor,\n    ) =\n        NavigationBarItemColors(\n            selectedIconColor.takeOrElse { this.selectedIconColor },\n            selectedTextColor.takeOrElse { this.selectedTextColor },\n            selectedIndicatorColor.takeOrElse { this.selectedIndicatorColor },\n            unselectedIconColor.takeOrElse { this.unselectedIconColor },\n            unselectedTextColor.takeOrElse { this.unselectedTextColor },\n            disabledIconColor.takeOrElse { this.disabledIconColor },\n            disabledTextColor.takeOrElse { this.disabledTextColor },\n        )\n\n    /**\n     * Represents the icon color for this item, depending on whether it is [selected].\n     *\n     * @param selected whether the item is selected\n     * @param enabled whether the item is enabled\n     */\n    @Stable\n    internal fun iconColor(selected: Boolean, enabled: Boolean): Color =\n        when {\n            !enabled -> disabledIconColor\n            selected -> selectedIconColor\n            else -> unselectedIconColor\n        }\n\n    /**\n     * Represents the text color for this item, depending on whether it is [selected].\n     *\n     * @param selected whether the item is selected\n     * @param enabled whether the item is enabled\n     */\n    @Stable\n    internal fun textColor(selected: Boolean, enabled: Boolean): Color =\n        when {\n            !enabled -> disabledTextColor\n            selected -> selectedTextColor\n            else -> unselectedTextColor\n        }\n\n    /** Represents the color of the indicator used for selected items. */\n    internal val indicatorColor: Color\n        get() = selectedIndicatorColor\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is NavigationBarItemColors) return false\n\n        if (selectedIconColor != other.selectedIconColor) return false\n        if (unselectedIconColor != other.unselectedIconColor) return false\n        if (selectedTextColor != other.selectedTextColor) return false\n        if (unselectedTextColor != other.unselectedTextColor) return false\n        if (selectedIndicatorColor != other.selectedIndicatorColor) return false\n        if (disabledIconColor != other.disabledIconColor) return false\n        if (disabledTextColor != other.disabledTextColor) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = selectedIconColor.hashCode()\n        result = 31 * result + unselectedIconColor.hashCode()\n        result = 31 * result + selectedTextColor.hashCode()\n        result = 31 * result + unselectedTextColor.hashCode()\n        result = 31 * result + selectedIndicatorColor.hashCode()\n        result = 31 * result + disabledIconColor.hashCode()\n        result = 31 * result + disabledTextColor.hashCode()\n\n        return result\n    }\n}\n\n/**\n * Base layout for a [NavigationBarItem].\n *\n * @param indicatorRipple indicator ripple for this item when it is selected\n * @param indicator indicator for this item when it is selected\n * @param icon icon for this item\n * @param label text label for this item\n * @param alwaysShowLabel whether to always show the label for this item. If false, the label will\n *   only be shown when this item is selected.\n * @param alphaAnimationProgress progress of the animation, where 0 represents the unselected state\n *   of this item and 1 represents the selected state. This value controls the indicator's opacity.\n * @param sizeAnimationProgress progress of the animation, where 0 represents the unselected state\n *   of this item and 1 represents the selected state. This value controls other values such as\n *   indicator size, icon and label positions, etc.\n */\n@Composable\nprivate fun NavigationBarItemLayout(\n    indicatorRipple: @Composable () -> Unit,\n    indicator: @Composable () -> Unit,\n    icon: @Composable () -> Unit,\n    label: @Composable (() -> Unit)?,\n    alwaysShowLabel: Boolean,\n    alphaAnimationProgress: () -> Float,\n    sizeAnimationProgress: () -> Float,\n) {\n    Layout(\n        modifier = Modifier.badgeBounds(),\n        content = {\n            indicatorRipple()\n            indicator()\n\n            Box(Modifier.layoutId(IconLayoutIdTag)) { icon() }\n\n            if (label != null) {\n                Box(\n                    Modifier.layoutId(LabelLayoutIdTag).graphicsLayer {\n                        alpha = if (alwaysShowLabel) 1f else alphaAnimationProgress()\n                    }\n                ) {\n                    label()\n                }\n            }\n        },\n    ) { measurables, constraints ->\n        @Suppress(\"NAME_SHADOWING\")\n        // Ensure that the progress is >= 0. It may be negative on bouncy springs, for example.\n        val animationProgress = sizeAnimationProgress().coerceAtLeast(0f)\n        val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)\n        val iconPlaceable =\n            measurables.fastFirst { it.layoutId == IconLayoutIdTag }.measure(looseConstraints)\n\n        val totalIndicatorWidth = iconPlaceable.width + (IndicatorHorizontalPadding * 2).roundToPx()\n        val animatedIndicatorWidth = (totalIndicatorWidth * animationProgress).roundToInt()\n        val indicatorHeight = iconPlaceable.height + (IndicatorVerticalPadding * 2).roundToPx()\n        val indicatorRipplePlaceable =\n            measurables\n                .fastFirst { it.layoutId == IndicatorRippleLayoutIdTag }\n                .measure(Constraints.fixed(width = totalIndicatorWidth, height = indicatorHeight))\n        val indicatorPlaceable =\n            measurables\n                .fastFirstOrNull { it.layoutId == IndicatorLayoutIdTag }\n                ?.measure(\n                    Constraints.fixed(width = animatedIndicatorWidth, height = indicatorHeight)\n                )\n\n        val labelPlaceable =\n            label?.let {\n                measurables.fastFirst { it.layoutId == LabelLayoutIdTag }.measure(looseConstraints)\n            }\n\n        if (label == null) {\n            placeIcon(iconPlaceable, indicatorRipplePlaceable, indicatorPlaceable, constraints)\n        } else {\n            placeLabelAndIcon(\n                labelPlaceable!!,\n                iconPlaceable,\n                indicatorRipplePlaceable,\n                indicatorPlaceable,\n                constraints,\n                alwaysShowLabel,\n                animationProgress,\n            )\n        }\n    }\n}\n\n/** Places the provided [Placeable]s in the center of the provided [constraints]. */\nprivate fun MeasureScope.placeIcon(\n    iconPlaceable: Placeable,\n    indicatorRipplePlaceable: Placeable,\n    indicatorPlaceable: Placeable?,\n    constraints: Constraints,\n): MeasureResult {\n    val width =\n        if (constraints.maxWidth == Constraints.Infinity) {\n            iconPlaceable.width + NavigationBarItemToIconMinimumPadding.roundToPx() * 2\n        } else {\n            constraints.maxWidth\n        }\n    val height = constraints.constrainHeight(NavigationBarHeight.roundToPx())\n\n    val iconX = (width - iconPlaceable.width) / 2\n    val iconY = (height - iconPlaceable.height) / 2\n\n    val rippleX = (width - indicatorRipplePlaceable.width) / 2\n    val rippleY = (height - indicatorRipplePlaceable.height) / 2\n\n    return layout(width, height) {\n        indicatorPlaceable?.let {\n            val indicatorX = (width - it.width) / 2\n            val indicatorY = (height - it.height) / 2\n            it.placeRelative(indicatorX, indicatorY)\n        }\n        iconPlaceable.placeRelative(iconX, iconY)\n        indicatorRipplePlaceable.placeRelative(rippleX, rippleY)\n    }\n}\n\n/**\n * Places the provided [Placeable]s in the correct position, depending on [alwaysShowLabel] and\n * [animationProgress].\n *\n * When [alwaysShowLabel] is true, the positions do not move. The [iconPlaceable] and\n * [labelPlaceable] will be placed together in the center with padding between them, according to\n * the spec.\n *\n * When [animationProgress] is 1 (representing the selected state), the positions will be the same\n * as above.\n *\n * Otherwise, when [animationProgress] is 0, [iconPlaceable] will be placed in the center, like in\n * [placeIcon], and [labelPlaceable] will not be shown.\n *\n * When [animationProgress] is animating between these values, [iconPlaceable] and [labelPlaceable]\n * will be placed at a corresponding interpolated position.\n *\n * [indicatorRipplePlaceable] and [indicatorPlaceable] will always be placed in such a way that to\n * share the same center as [iconPlaceable].\n *\n * @param labelPlaceable text label placeable inside this item\n * @param iconPlaceable icon placeable inside this item\n * @param indicatorRipplePlaceable indicator ripple placeable inside this item\n * @param indicatorPlaceable indicator placeable inside this item, if it exists\n * @param constraints constraints of the item\n * @param alwaysShowLabel whether to always show the label for this item. If true, icon and label\n *   positions will not change. If false, positions transition between 'centered icon with no label'\n *   and 'top aligned icon with label'.\n * @param animationProgress progress of the animation, where 0 represents the unselected state of\n *   this item and 1 represents the selected state. Values between 0 and 1 interpolate positions of\n *   the icon and label.\n */\nprivate fun MeasureScope.placeLabelAndIcon(\n    labelPlaceable: Placeable,\n    iconPlaceable: Placeable,\n    indicatorRipplePlaceable: Placeable,\n    indicatorPlaceable: Placeable?,\n    constraints: Constraints,\n    alwaysShowLabel: Boolean,\n    animationProgress: Float,\n): MeasureResult {\n    val contentHeight =\n        iconPlaceable.height +\n            IndicatorVerticalPadding.toPx() +\n            NavigationBarIndicatorToLabelPadding.toPx() +\n            labelPlaceable.height\n    val contentVerticalPadding =\n        ((constraints.minHeight - contentHeight) / 2).coerceAtLeast(IndicatorVerticalPadding.toPx())\n    val height = contentHeight + contentVerticalPadding * 2\n\n    // Icon (when selected) should be `contentVerticalPadding` from top\n    val selectedIconY = contentVerticalPadding\n    val unselectedIconY =\n        if (alwaysShowLabel) selectedIconY else (height - iconPlaceable.height) / 2\n\n    // How far the icon needs to move between unselected and selected states.\n    val iconDistance = unselectedIconY - selectedIconY\n\n    // The interpolated fraction of iconDistance that all placeables need to move based on\n    // animationProgress.\n    val offset = iconDistance * (1 - animationProgress)\n\n    // Label should be fixed padding below icon\n    val labelY =\n        selectedIconY +\n            iconPlaceable.height +\n            IndicatorVerticalPadding.toPx() +\n            NavigationBarIndicatorToLabelPadding.toPx()\n\n    val containerWidth =\n        if (constraints.maxWidth == Constraints.Infinity) {\n            iconPlaceable.width + NavigationBarItemToIconMinimumPadding.roundToPx() * 2\n        } else {\n            constraints.maxWidth\n        }\n\n    val labelX = (containerWidth - labelPlaceable.width) / 2\n    val iconX = (containerWidth - iconPlaceable.width) / 2\n\n    val rippleX = (containerWidth - indicatorRipplePlaceable.width) / 2\n    val rippleY = selectedIconY - IndicatorVerticalPadding.toPx()\n\n    return layout(containerWidth, height.roundToInt()) {\n        indicatorPlaceable?.let {\n            val indicatorX = (containerWidth - it.width) / 2\n            val indicatorY = selectedIconY - IndicatorVerticalPadding.roundToPx()\n            it.placeRelative(indicatorX, (indicatorY + offset).roundToInt())\n        }\n        if (alwaysShowLabel || animationProgress != 0f) {\n            labelPlaceable.placeRelative(labelX, (labelY + offset).roundToInt())\n        }\n        iconPlaceable.placeRelative(iconX, (selectedIconY + offset).roundToInt())\n        indicatorRipplePlaceable.placeRelative(rippleX, (rippleY + offset).roundToInt())\n    }\n}\n\nprivate const val IndicatorRippleLayoutIdTag: String = \"indicatorRipple\"\n\nprivate const val IndicatorLayoutIdTag: String = \"indicator\"\n\nprivate const val IconLayoutIdTag: String = \"icon\"\n\nprivate const val LabelLayoutIdTag: String = \"label\"\n\nprivate val NavigationBarHeight: Dp = NavigationBarTokens.TallContainerHeight\n\n/*@VisibleForTesting*/\ninternal val NavigationBarItemHorizontalPadding: Dp = 8.dp\n\n/*@VisibleForTesting*/\ninternal val NavigationBarIndicatorToLabelPadding: Dp = 4.dp\n\nprivate val IndicatorHorizontalPadding: Dp =\n    (NavigationBarVerticalItemTokens.ActiveIndicatorWidth -\n        NavigationBarVerticalItemTokens.IconSize) / 2\n\n/*@VisibleForTesting*/\ninternal val IndicatorVerticalPadding: Dp =\n    (NavigationBarVerticalItemTokens.ActiveIndicatorHeight -\n        NavigationBarVerticalItemTokens.IconSize) / 2\n\nprivate val IndicatorVerticalOffset: Dp = 12.dp\n\n/*@VisibleForTesting*/\ninternal val NavigationBarItemToIconMinimumPadding: Dp = 44.dp\n\n/**\n * Interface that allows libraries to override the behavior of the [NavigationBar] component.\n *\n * To override this component, implement the member function of this interface, then provide the\n * implementation to [LocalNavigationBarOverride] in the Compose hierarchy.\n */\n@ExperimentalMaterial3ComponentOverrideApi\ninterface NavigationBarOverride {\n    /** Behavior function that is called by the [NavigationBar] component. */\n    @Composable fun NavigationBarOverrideScope.NavigationBar()\n}\n\n/**\n * Parameters available to [NavigationBar].\n *\n * @param modifier the [Modifier] to be applied to this navigation bar\n * @param containerColor the color used for the background of this navigation bar. Use\n *   [Color.Transparent] to have no color.\n * @param contentColor the preferred color for content inside this navigation bar. Defaults to\n *   either the matching content color for [containerColor], or to the current [LocalContentColor]\n *   if [containerColor] is not a color from the theme.\n * @param tonalElevation when [containerColor] is [ColorScheme.surface], a translucent primary color\n *   overlay is applied on top of the container. A higher tonal elevation value will result in a\n *   darker color in light theme and lighter color in dark theme. See also: [Surface].\n * @param windowInsets a window insets of the navigation bar.\n * @param content the content of this navigation bar, typically 3-5 [NavigationBarItem]s\n */\n@ExperimentalMaterial3ComponentOverrideApi\nclass NavigationBarOverrideScope\ninternal constructor(\n    val modifier: Modifier = Modifier,\n    val containerColor: Color,\n    val contentColor: Color,\n    val tonalElevation: Dp,\n    val windowInsets: WindowInsets,\n    val content: @Composable RowScope.() -> Unit,\n)\n\n/** CompositionLocal containing the currently-selected [NavigationBarOverride]. */\n@ExperimentalMaterial3ComponentOverrideApi\nval LocalNavigationBarOverride: ProvidableCompositionLocal<NavigationBarOverride> =\n    compositionLocalOf {\n        DefaultNavigationBarOverride\n    }\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationRail.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.indication\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.foundation.selection.selectable\nimport androidx.compose.foundation.selection.selectableGroup\nimport androidx.compose.material3.DefaultNavigationRailOverride.NavigationRail\nimport androidx.compose.material3.internal.MappedInteractionSource\nimport androidx.compose.material3.internal.ProvideContentColorTextStyle\nimport androidx.compose.material3.internal.systemBarsForVisualComponents\nimport androidx.compose.material3.tokens.MotionSchemeKeyTokens\nimport androidx.compose.material3.tokens.NavigationRailBaselineItemTokens\nimport androidx.compose.material3.tokens.NavigationRailCollapsedTokens\nimport androidx.compose.material3.tokens.NavigationRailColorTokens\nimport androidx.compose.material3.tokens.NavigationRailVerticalItemTokens\nimport androidx.compose.material3.tokens.ShapeKeyTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.ProvidableCompositionLocal\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.layout.layoutId\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.semantics.clearAndSetSemantics\nimport androidx.compose.ui.semantics.isTraversalGroup\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.constrainHeight\nimport androidx.compose.ui.unit.constrainWidth\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastFirst\nimport androidx.compose.ui.util.fastFirstOrNull\nimport kotlin.math.roundToInt\n\n/**\n * [Material Design bottom navigation\n * rail](https://m3.material.io/components/navigation-rail/overview)\n *\n * Navigation rails provide access to primary destinations in apps when using tablet and desktop\n * screens.\n *\n * ![Navigation rail\n * image](https://developer.android.com/images/reference/androidx/compose/material3/navigation-rail.png)\n *\n * The navigation rail should be used to display three to seven app destinations and, optionally, a\n * [FloatingActionButton] or a logo header. Each destination is typically represented by an icon and\n * an optional text label.\n *\n * [NavigationRail] should contain multiple [NavigationRailItem]s, each representing a singular\n * destination.\n *\n * A simple example looks like:\n *\n * @sample androidx.compose.material3.samples.NavigationRailSample\n *\n * See [NavigationRailItem] for configuration specific to each item, and not the overall\n * NavigationRail component.\n *\n * @param modifier the [Modifier] to be applied to this navigation rail\n * @param containerColor the color used for the background of this navigation rail. Use\n *   [Color.Transparent] to have no color.\n * @param contentColor the preferred color for content inside this navigation rail. Defaults to\n *   either the matching content color for [containerColor], or to the current [LocalContentColor]\n *   if [containerColor] is not a color from the theme.\n * @param header optional header that may hold a [FloatingActionButton] or a logo\n * @param windowInsets a window insets of the navigation rail.\n * @param content the content of this navigation rail, typically 3-7 [NavigationRailItem]s\n */\n@OptIn(ExperimentalMaterial3ComponentOverrideApi::class)\n@Composable\nfun NavigationRail(\n    modifier: Modifier = Modifier,\n    containerColor: Color = NavigationRailDefaults.ContainerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    header: @Composable (ColumnScope.() -> Unit)? = null,\n    windowInsets: WindowInsets = NavigationRailDefaults.windowInsets,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    with(LocalNavigationRailOverride.current) {\n        NavigationRailOverrideScope(\n                modifier = modifier,\n                containerColor = containerColor,\n                contentColor = contentColor,\n                header = header,\n                windowInsets = windowInsets,\n                content = content,\n            )\n            .NavigationRail()\n    }\n}\n\n/**\n * This override provides the default behavior of the [NavigationRail] component.\n *\n * [NavigationRailOverride] used when no override is specified.\n */\n@ExperimentalMaterial3ComponentOverrideApi\nobject DefaultNavigationRailOverride : NavigationRailOverride {\n    @Composable\n    override fun NavigationRailOverrideScope.NavigationRail() {\n        Surface(color = containerColor, contentColor = contentColor, modifier = modifier) {\n            Column(\n                Modifier.fillMaxHeight()\n                    .windowInsetsPadding(windowInsets)\n                    .widthIn(min = NavigationRailCollapsedTokens.NarrowContainerWidth)\n                    .padding(vertical = NavigationRailVerticalPadding)\n                    .selectableGroup()\n                    .semantics { isTraversalGroup = true },\n                horizontalAlignment = Alignment.CenterHorizontally,\n                verticalArrangement = Arrangement.spacedBy(NavigationRailVerticalPadding),\n            ) {\n                val header = header\n                if (header != null) {\n                    header()\n                    Spacer(Modifier.height(NavigationRailHeaderPadding))\n                }\n                content()\n            }\n        }\n    }\n}\n\n/**\n * Material Design navigation rail item.\n *\n * A [NavigationRailItem] represents a destination within a [NavigationRail].\n *\n * Navigation rails provide access to primary destinations in apps when using tablet and desktop\n * screens.\n *\n * The text label is always shown (if it exists) when selected. Showing text labels if not selected\n * is controlled by [alwaysShowLabel].\n *\n * @param selected whether this item is selected\n * @param onClick called when this item is clicked\n * @param icon icon for this item, typically an [Icon]\n * @param modifier the [Modifier] to be applied to this item\n * @param enabled controls the enabled state of this item. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param label optional text label for this item\n * @param alwaysShowLabel whether to always show the label for this item. If false, the label will\n *   only be shown when this item is selected.\n * @param colors [NavigationRailItemColors] that will be used to resolve the colors used for this\n *   item in different states. See [NavigationRailItemDefaults.colors].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this item. You can use this to change the item's appearance or\n *   preview the item in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n */\n@Composable\nfun NavigationRailItem(\n    selected: Boolean,\n    onClick: () -> Unit,\n    icon: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    label: @Composable (() -> Unit)? = null,\n    alwaysShowLabel: Boolean = true,\n    colors: NavigationRailItemColors = NavigationRailItemDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    // TODO Load the motionScheme tokens from the component tokens file\n    val colorAnimationSpec = MotionSchemeKeyTokens.DefaultEffects.value<Color>()\n    val styledIcon =\n        @Composable {\n            val iconColor by\n                animateColorAsState(\n                    targetValue = colors.iconColor(selected = selected, enabled = enabled),\n                    animationSpec = colorAnimationSpec,\n                )\n            // If there's a label, don't have a11y services repeat the icon description.\n            val clearSemantics = label != null && (alwaysShowLabel || selected)\n            Box(modifier = if (clearSemantics) Modifier.clearAndSetSemantics {} else Modifier) {\n                CompositionLocalProvider(LocalContentColor provides iconColor, content = icon)\n            }\n        }\n\n    val styledLabel: @Composable (() -> Unit)? =\n        label?.let {\n            @Composable {\n                val style = NavigationRailVerticalItemTokens.LabelTextFont.value\n                val textColor by\n                    animateColorAsState(\n                        targetValue = colors.textColor(selected = selected, enabled = enabled),\n                        animationSpec = colorAnimationSpec,\n                    )\n                ProvideContentColorTextStyle(\n                    contentColor = textColor,\n                    textStyle = style,\n                    content = label,\n                )\n            }\n        }\n\n    Box(\n        modifier\n            .selectable(\n                selected = selected,\n                onClick = onClick,\n                enabled = enabled,\n                role = Role.Tab,\n                interactionSource = interactionSource,\n                indication = null,\n            )\n            .defaultMinSize(minHeight = NavigationRailItemHeight)\n            .widthIn(min = NavigationRailItemWidth),\n        contentAlignment = Alignment.Center,\n        propagateMinConstraints = true,\n    ) {\n        val alphaAnimationProgress: State<Float> =\n            animateFloatAsState(\n                targetValue = if (selected) 1f else 0f,\n                // TODO Load the motionScheme tokens from the component tokens file\n                animationSpec = MotionSchemeKeyTokens.DefaultEffects.value(),\n            )\n        val sizeAnimationProgress: State<Float> =\n            animateFloatAsState(\n                targetValue = if (selected) 1f else 0f,\n                // TODO Load the motionScheme tokens from the component tokens file\n                animationSpec = MotionSchemeKeyTokens.FastSpatial.value(),\n            )\n\n        // The entire item is selectable, but only the indicator pill shows the ripple. To achieve\n        // this, we re-map the coordinates of the item's InteractionSource into the coordinates of\n        // the indicator.\n        val density = LocalDensity.current\n        val calculateDeltaOffset = {\n            with(density) {\n                val itemWidth = NavigationRailItemWidth.roundToPx()\n                val indicatorWidth =\n                    NavigationRailVerticalItemTokens.ActiveIndicatorWidth.roundToPx()\n                Offset((itemWidth - indicatorWidth).toFloat() / 2, 0f)\n            }\n        }\n        val offsetInteractionSource =\n            remember(interactionSource, calculateDeltaOffset) {\n                MappedInteractionSource(interactionSource, calculateDeltaOffset)\n            }\n\n        val indicatorShape =\n            if (label != null) {\n                NavigationRailBaselineItemTokens.ActiveIndicatorShape.value\n            } else {\n                ShapeKeyTokens.CornerFull.value\n            }\n\n        // The indicator has a width-expansion animation which interferes with the timing of the\n        // ripple, which is why they are separate composables\n        val indicatorRipple =\n            @Composable {\n                Box(\n                    Modifier.layoutId(IndicatorRippleLayoutIdTag)\n                        .clip(indicatorShape)\n                        .indication(offsetInteractionSource, ripple())\n                )\n            }\n        val indicator =\n            @Composable {\n                Box(\n                    Modifier.layoutId(IndicatorLayoutIdTag)\n                        .graphicsLayer { alpha = alphaAnimationProgress.value }\n                        .background(color = colors.indicatorColor, shape = indicatorShape)\n                )\n            }\n\n        NavigationRailItemLayout(\n            indicatorRipple = indicatorRipple,\n            indicator = indicator,\n            icon = styledIcon,\n            label = styledLabel,\n            alwaysShowLabel = alwaysShowLabel,\n            alphaAnimationProgress = { alphaAnimationProgress.value },\n            sizeAnimationProgress = { sizeAnimationProgress.value },\n        )\n    }\n}\n\n/** Defaults used in [NavigationRail] */\nobject NavigationRailDefaults {\n    /** Default container color of a navigation rail. */\n    val ContainerColor: Color\n        @Composable get() = NavigationRailCollapsedTokens.ContainerColor.value\n\n    /** Default window insets for navigation rail. */\n    val windowInsets: WindowInsets\n        @Composable\n        get() =\n            WindowInsets.systemBarsForVisualComponents.only(\n                WindowInsetsSides.Vertical + WindowInsetsSides.Start\n            )\n}\n\n/** Defaults used in [NavigationRailItem]. */\nobject NavigationRailItemDefaults {\n    /**\n     * Creates a [NavigationRailItemColors] with the provided colors according to the Material\n     * specification.\n     */\n    @Composable fun colors() = MaterialTheme.colorScheme.defaultNavigationRailItemColors\n\n    /**\n     * Creates a [NavigationRailItemColors] with the provided colors according to the Material\n     * specification.\n     *\n     * @param selectedIconColor the color to use for the icon when the item is selected.\n     * @param selectedTextColor the color to use for the text label when the item is selected.\n     * @param indicatorColor the color to use for the indicator when the item is selected.\n     * @param unselectedIconColor the color to use for the icon when the item is unselected.\n     * @param unselectedTextColor the color to use for the text label when the item is unselected.\n     * @param disabledIconColor the color to use for the icon when the item is disabled.\n     * @param disabledTextColor the color to use for the text label when the item is disabled.\n     * @return the resulting [NavigationRailItemColors] used for [NavigationRailItem]\n     */\n    @Composable\n    fun colors(\n        selectedIconColor: Color = NavigationRailColorTokens.ItemActiveIcon.value,\n        selectedTextColor: Color = NavigationRailColorTokens.ItemActiveLabelText.value,\n        indicatorColor: Color = NavigationRailColorTokens.ItemActiveIndicator.value,\n        unselectedIconColor: Color = NavigationRailColorTokens.ItemInactiveIcon.value,\n        unselectedTextColor: Color = NavigationRailColorTokens.ItemInactiveLabelText.value,\n        disabledIconColor: Color = unselectedIconColor.copy(alpha = DisabledAlpha),\n        disabledTextColor: Color = unselectedTextColor.copy(alpha = DisabledAlpha),\n    ): NavigationRailItemColors =\n        MaterialTheme.colorScheme.defaultNavigationRailItemColors.copy(\n            selectedIconColor = selectedIconColor,\n            selectedTextColor = selectedTextColor,\n            selectedIndicatorColor = indicatorColor,\n            unselectedIconColor = unselectedIconColor,\n            unselectedTextColor = unselectedTextColor,\n            disabledIconColor = disabledIconColor,\n            disabledTextColor = disabledTextColor,\n        )\n\n    internal val ColorScheme.defaultNavigationRailItemColors: NavigationRailItemColors\n        get() {\n            return defaultNavigationRailItemColorsCached\n                ?: NavigationRailItemColors(\n                        selectedIconColor = fromToken(NavigationRailColorTokens.ItemActiveIcon),\n                        selectedTextColor =\n                            fromToken(NavigationRailColorTokens.ItemActiveLabelText),\n                        selectedIndicatorColor =\n                            fromToken(NavigationRailColorTokens.ItemActiveIndicator),\n                        unselectedIconColor = fromToken(NavigationRailColorTokens.ItemInactiveIcon),\n                        unselectedTextColor =\n                            fromToken(NavigationRailColorTokens.ItemInactiveLabelText),\n                        disabledIconColor =\n                            fromToken(NavigationRailColorTokens.ItemInactiveIcon)\n                                .copy(alpha = DisabledAlpha),\n                        disabledTextColor =\n                            fromToken(NavigationRailColorTokens.ItemInactiveLabelText)\n                                .copy(alpha = DisabledAlpha),\n                    )\n                    .also { defaultNavigationRailItemColorsCached = it }\n        }\n\n    @Deprecated(\n        \"Use overload with disabledIconColor and disabledTextColor\",\n        level = DeprecationLevel.HIDDEN,\n    )\n    @Composable\n    fun colors(\n        selectedIconColor: Color = NavigationRailColorTokens.ItemActiveIcon.value,\n        selectedTextColor: Color = NavigationRailColorTokens.ItemActiveLabelText.value,\n        indicatorColor: Color = NavigationRailColorTokens.ItemActiveIndicator.value,\n        unselectedIconColor: Color = NavigationRailColorTokens.ItemInactiveIcon.value,\n        unselectedTextColor: Color = NavigationRailColorTokens.ItemInactiveLabelText.value,\n    ): NavigationRailItemColors =\n        NavigationRailItemColors(\n            selectedIconColor = selectedIconColor,\n            selectedTextColor = selectedTextColor,\n            selectedIndicatorColor = indicatorColor,\n            unselectedIconColor = unselectedIconColor,\n            unselectedTextColor = unselectedTextColor,\n            disabledIconColor = unselectedIconColor.copy(alpha = DisabledAlpha),\n            disabledTextColor = unselectedTextColor.copy(alpha = DisabledAlpha),\n        )\n}\n\n/**\n * Represents the colors of the various elements of a navigation item.\n *\n * @param selectedIconColor the color to use for the icon when the item is selected.\n * @param selectedTextColor the color to use for the text label when the item is selected.\n * @param selectedIndicatorColor the color to use for the indicator when the item is selected.\n * @param unselectedIconColor the color to use for the icon when the item is unselected.\n * @param unselectedTextColor the color to use for the text label when the item is unselected.\n * @param disabledIconColor the color to use for the icon when the item is disabled.\n * @param disabledTextColor the color to use for the text label when the item is disabled.\n * @constructor create an instance with arbitrary colors.\n */\n@Immutable\nclass NavigationRailItemColors\nconstructor(\n    val selectedIconColor: Color,\n    val selectedTextColor: Color,\n    val selectedIndicatorColor: Color,\n    val unselectedIconColor: Color,\n    val unselectedTextColor: Color,\n    val disabledIconColor: Color,\n    val disabledTextColor: Color,\n) {\n    /**\n     * Returns a copy of this NavigationRailItemColors, optionally overriding some of the values.\n     * This uses the Color.Unspecified to mean “use the value from the source”\n     */\n    fun copy(\n        selectedIconColor: Color = this.selectedIconColor,\n        selectedTextColor: Color = this.selectedTextColor,\n        selectedIndicatorColor: Color = this.selectedIndicatorColor,\n        unselectedIconColor: Color = this.unselectedIconColor,\n        unselectedTextColor: Color = this.unselectedTextColor,\n        disabledIconColor: Color = this.disabledIconColor,\n        disabledTextColor: Color = this.disabledTextColor,\n    ) =\n        NavigationRailItemColors(\n            selectedIconColor.takeOrElse { this.selectedIconColor },\n            selectedTextColor.takeOrElse { this.selectedTextColor },\n            selectedIndicatorColor.takeOrElse { this.selectedIndicatorColor },\n            unselectedIconColor.takeOrElse { this.unselectedIconColor },\n            unselectedTextColor.takeOrElse { this.unselectedTextColor },\n            disabledIconColor.takeOrElse { this.disabledIconColor },\n            disabledTextColor.takeOrElse { this.disabledTextColor },\n        )\n\n    /**\n     * Represents the icon color for this item, depending on whether it is [selected].\n     *\n     * @param selected whether the item is selected\n     * @param enabled whether the item is enabled\n     */\n    @Stable\n    internal fun iconColor(selected: Boolean, enabled: Boolean): Color =\n        when {\n            !enabled -> disabledIconColor\n            selected -> selectedIconColor\n            else -> unselectedIconColor\n        }\n\n    /**\n     * Represents the text color for this item, depending on whether it is [selected].\n     *\n     * @param selected whether the item is selected\n     * @param enabled whether the item is enabled\n     */\n    @Stable\n    internal fun textColor(selected: Boolean, enabled: Boolean): Color =\n        when {\n            !enabled -> disabledTextColor\n            selected -> selectedTextColor\n            else -> unselectedTextColor\n        }\n\n    /** Represents the color of the indicator used for selected items. */\n    internal val indicatorColor: Color\n        get() = selectedIndicatorColor\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is NavigationRailItemColors) return false\n\n        if (selectedIconColor != other.selectedIconColor) return false\n        if (unselectedIconColor != other.unselectedIconColor) return false\n        if (selectedTextColor != other.selectedTextColor) return false\n        if (unselectedTextColor != other.unselectedTextColor) return false\n        if (selectedIndicatorColor != other.selectedIndicatorColor) return false\n        if (disabledIconColor != other.disabledIconColor) return false\n        if (disabledTextColor != other.disabledTextColor) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = selectedIconColor.hashCode()\n        result = 31 * result + unselectedIconColor.hashCode()\n        result = 31 * result + selectedTextColor.hashCode()\n        result = 31 * result + unselectedTextColor.hashCode()\n        result = 31 * result + selectedIndicatorColor.hashCode()\n        result = 31 * result + disabledIconColor.hashCode()\n        result = 31 * result + disabledTextColor.hashCode()\n\n        return result\n    }\n}\n\n/**\n * Base layout for a [NavigationRailItem].\n *\n * @param indicatorRipple indicator ripple for this item when it is selected\n * @param indicator indicator for this item when it is selected\n * @param icon icon for this item\n * @param label text label for this item\n * @param alwaysShowLabel whether to always show the label for this item. If false, the label will\n *   only be shown when this item is selected.\n * @param alphaAnimationProgress progress of the animation, where 0 represents the unselected state\n *   of this item and 1 represents the selected state. This value controls the indicator's color\n *   alpha.\n * @param sizeAnimationProgress progress of the animation, where 0 represents the unselected state\n *   of this item and 1 represents the selected state. This value controls other values such as\n *   indicator size, icon and label positions, etc.\n */\n@Composable\nprivate fun NavigationRailItemLayout(\n    indicatorRipple: @Composable () -> Unit,\n    indicator: @Composable () -> Unit,\n    icon: @Composable () -> Unit,\n    label: @Composable (() -> Unit)?,\n    alwaysShowLabel: Boolean,\n    alphaAnimationProgress: () -> Float,\n    sizeAnimationProgress: () -> Float,\n) {\n    Layout(\n        modifier = Modifier.badgeBounds(),\n        content = {\n            indicatorRipple()\n            indicator()\n\n            Box(Modifier.layoutId(IconLayoutIdTag)) { icon() }\n\n            if (label != null) {\n                Box(\n                    Modifier.layoutId(LabelLayoutIdTag).graphicsLayer {\n                        alpha = if (alwaysShowLabel) 1f else alphaAnimationProgress()\n                    }\n                ) {\n                    label()\n                }\n            }\n        },\n    ) { measurables, constraints ->\n        @Suppress(\"NAME_SHADOWING\")\n        // Ensure that the progress is >= 0. It may be negative on bouncy springs, for example.\n        val animationProgress = sizeAnimationProgress().coerceAtLeast(0f)\n        val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)\n        val iconPlaceable =\n            measurables.fastFirst { it.layoutId == IconLayoutIdTag }.measure(looseConstraints)\n\n        val totalIndicatorWidth = iconPlaceable.width + (IndicatorHorizontalPadding * 2).roundToPx()\n        val animatedIndicatorWidth = (totalIndicatorWidth * animationProgress).roundToInt()\n        val indicatorVerticalPadding =\n            if (label == null) {\n                IndicatorVerticalPaddingNoLabel\n            } else {\n                IndicatorVerticalPaddingWithLabel\n            }\n        val indicatorHeight = iconPlaceable.height + (indicatorVerticalPadding * 2).roundToPx()\n\n        val indicatorRipplePlaceable =\n            measurables\n                .fastFirst { it.layoutId == IndicatorRippleLayoutIdTag }\n                .measure(Constraints.fixed(width = totalIndicatorWidth, height = indicatorHeight))\n        val indicatorPlaceable =\n            measurables\n                .fastFirstOrNull { it.layoutId == IndicatorLayoutIdTag }\n                ?.measure(\n                    Constraints.fixed(width = animatedIndicatorWidth, height = indicatorHeight)\n                )\n\n        val labelPlaceable =\n            label?.let {\n                measurables.fastFirst { it.layoutId == LabelLayoutIdTag }.measure(looseConstraints)\n            }\n\n        if (label == null) {\n            placeIcon(iconPlaceable, indicatorRipplePlaceable, indicatorPlaceable, constraints)\n        } else {\n            placeLabelAndIcon(\n                labelPlaceable!!,\n                iconPlaceable,\n                indicatorRipplePlaceable,\n                indicatorPlaceable,\n                constraints,\n                alwaysShowLabel,\n                animationProgress,\n            )\n        }\n    }\n}\n\n/** Places the provided [Placeable]s in the center of the provided [constraints]. */\nprivate fun MeasureScope.placeIcon(\n    iconPlaceable: Placeable,\n    indicatorRipplePlaceable: Placeable,\n    indicatorPlaceable: Placeable?,\n    constraints: Constraints,\n): MeasureResult {\n    val width =\n        constraints.constrainWidth(\n            maxOf(\n                iconPlaceable.width,\n                indicatorRipplePlaceable.width,\n                indicatorPlaceable?.width ?: 0,\n            )\n        )\n    val height = constraints.constrainHeight(NavigationRailItemHeight.roundToPx())\n\n    val iconX = (width - iconPlaceable.width) / 2\n    val iconY = (height - iconPlaceable.height) / 2\n\n    val rippleX = (width - indicatorRipplePlaceable.width) / 2\n    val rippleY = (height - indicatorRipplePlaceable.height) / 2\n\n    return layout(width, height) {\n        indicatorPlaceable?.let {\n            val indicatorX = (width - it.width) / 2\n            val indicatorY = (height - it.height) / 2\n            it.placeRelative(indicatorX, indicatorY)\n        }\n        iconPlaceable.placeRelative(iconX, iconY)\n        indicatorRipplePlaceable.placeRelative(rippleX, rippleY)\n    }\n}\n\n/**\n * Places the provided [Placeable]s in the correct position, depending on [alwaysShowLabel] and\n * [animationProgress].\n *\n * When [alwaysShowLabel] is true, the positions do not move. The [iconPlaceable] and\n * [labelPlaceable] will be placed together in the center with padding between them, according to\n * the spec.\n *\n * When [animationProgress] is 1 (representing the selected state), the positions will be the same\n * as above.\n *\n * Otherwise, when [animationProgress] is 0, [iconPlaceable] will be placed in the center, like in\n * [placeIcon], and [labelPlaceable] will not be shown.\n *\n * When [animationProgress] is animating between these values, [iconPlaceable] and [labelPlaceable]\n * will be placed at a corresponding interpolated position.\n *\n * [indicatorRipplePlaceable] and [indicatorPlaceable] will always be placed in such a way that to\n * share the same center as [iconPlaceable].\n *\n * @param labelPlaceable text label placeable inside this item\n * @param iconPlaceable icon placeable inside this item\n * @param indicatorRipplePlaceable indicator ripple placeable inside this item\n * @param indicatorPlaceable indicator placeable inside this item, if it exists\n * @param constraints constraints of the item\n * @param alwaysShowLabel whether to always show the label for this item. If true, icon and label\n *   positions will not change. If false, positions transition between 'centered icon with no label'\n *   and 'top aligned icon with label'.\n * @param animationProgress progress of the animation, where 0 represents the unselected state of\n *   this item and 1 represents the selected state. Values between 0 and 1 interpolate positions of\n *   the icon and label.\n */\nprivate fun MeasureScope.placeLabelAndIcon(\n    labelPlaceable: Placeable,\n    iconPlaceable: Placeable,\n    indicatorRipplePlaceable: Placeable,\n    indicatorPlaceable: Placeable?,\n    constraints: Constraints,\n    alwaysShowLabel: Boolean,\n    animationProgress: Float,\n): MeasureResult {\n    val contentHeight =\n        iconPlaceable.height +\n            IndicatorVerticalPaddingWithLabel.toPx() +\n            NavigationRailItemVerticalPadding.toPx() +\n            labelPlaceable.height\n    val contentVerticalPadding =\n        ((constraints.minHeight - contentHeight) / 2).coerceAtLeast(\n            IndicatorVerticalPaddingWithLabel.toPx()\n        )\n    val height = contentHeight + contentVerticalPadding * 2\n\n    // Icon (when selected) should be `contentVerticalPadding` from the top\n    val selectedIconY = contentVerticalPadding\n    val unselectedIconY =\n        if (alwaysShowLabel) selectedIconY else (height - iconPlaceable.height) / 2\n\n    // How far the icon needs to move between unselected and selected states\n    val iconDistance = unselectedIconY - selectedIconY\n\n    // The interpolated fraction of iconDistance that all placeables need to move based on\n    // animationProgress, since the icon is higher in the selected state.\n    val offset = iconDistance * (1 - animationProgress)\n\n    // Label should be fixed padding below icon\n    val labelY =\n        selectedIconY +\n            iconPlaceable.height +\n            IndicatorVerticalPaddingWithLabel.toPx() +\n            NavigationRailItemVerticalPadding.toPx()\n\n    val width =\n        constraints.constrainWidth(\n            maxOf(iconPlaceable.width, labelPlaceable.width, indicatorPlaceable?.width ?: 0)\n        )\n    val labelX = (width - labelPlaceable.width) / 2\n    val iconX = (width - iconPlaceable.width) / 2\n    val rippleX = (width - indicatorRipplePlaceable.width) / 2\n    val rippleY = selectedIconY - IndicatorVerticalPaddingWithLabel.toPx()\n\n    return layout(width, height.roundToInt()) {\n        indicatorPlaceable?.let {\n            val indicatorX = (width - it.width) / 2\n            val indicatorY = selectedIconY - IndicatorVerticalPaddingWithLabel.toPx()\n            it.placeRelative(indicatorX, (indicatorY + offset).roundToInt())\n        }\n        if (alwaysShowLabel || animationProgress != 0f) {\n            labelPlaceable.placeRelative(labelX, (labelY + offset).roundToInt())\n        }\n        iconPlaceable.placeRelative(iconX, (selectedIconY + offset).roundToInt())\n        indicatorRipplePlaceable.placeRelative(rippleX, (rippleY + offset).roundToInt())\n    }\n}\n\nprivate const val IndicatorRippleLayoutIdTag: String = \"indicatorRipple\"\n\nprivate const val IndicatorLayoutIdTag: String = \"indicator\"\n\nprivate const val IconLayoutIdTag: String = \"icon\"\n\nprivate const val LabelLayoutIdTag: String = \"label\"\n\n/**\n * Vertical padding between the contents of the [NavigationRail] and its top/bottom, and internally\n * between items.\n */\ninternal val NavigationRailVerticalPadding: Dp = 4.dp\n\n/**\n * Padding at the bottom of the [NavigationRail]'s header. This padding will only be added when the\n * header is not null.\n */\nprivate val NavigationRailHeaderPadding: Dp = 8.dp\n\n/*@VisibleForTesting*/\n/** Width of an individual [NavigationRailItem]. */\ninternal val NavigationRailItemWidth: Dp = NavigationRailCollapsedTokens.NarrowContainerWidth\n\n/*@VisibleForTesting*/\n/** Height of an individual [NavigationRailItem]. */\ninternal val NavigationRailItemHeight: Dp = NavigationRailVerticalItemTokens.ActiveIndicatorWidth\n\n/*@VisibleForTesting*/\n/** Vertical padding between the contents of a [NavigationRailItem] and its top/bottom. */\ninternal val NavigationRailItemVerticalPadding: Dp = 4.dp\n\nprivate val IndicatorHorizontalPadding: Dp =\n    (NavigationRailVerticalItemTokens.ActiveIndicatorWidth -\n        NavigationRailBaselineItemTokens.IconSize) / 2\n\nprivate val IndicatorVerticalPaddingWithLabel: Dp =\n    (NavigationRailVerticalItemTokens.ActiveIndicatorHeight -\n        NavigationRailBaselineItemTokens.IconSize) / 2\n\nprivate val IndicatorVerticalPaddingNoLabel: Dp =\n    (NavigationRailVerticalItemTokens.ActiveIndicatorWidth -\n        NavigationRailBaselineItemTokens.IconSize) / 2\n\n/**\n * Interface that allows libraries to override the behavior of the [NavigationRail] component.\n *\n * To override this component, implement the member function of this interface, then provide the\n * implementation to [LocalNavigationRailOverride] in the Compose hierarchy.\n */\n@ExperimentalMaterial3ComponentOverrideApi\ninterface NavigationRailOverride {\n    /** Behavior function that is called by the [NavigationRail] component. */\n    @Composable fun NavigationRailOverrideScope.NavigationRail()\n}\n\n/**\n * Parameters available to [NavigationRail].\n *\n * @param modifier the [Modifier] to be applied to this navigation rail\n * @param containerColor the color used for the background of this navigation rail. Use\n *   [Color.Transparent] to have no color.\n * @param contentColor the preferred color for content inside this navigation rail. Defaults to\n *   either the matching content color for [containerColor], or to the current [LocalContentColor]\n *   if [containerColor] is not a color from the theme.\n * @param header optional header that may hold a [FloatingActionButton] or a logo\n * @param windowInsets a window insets of the navigation rail.\n * @param content the content of this navigation rail, typically 3-7 [NavigationRailItem]s\n */\n@ExperimentalMaterial3ComponentOverrideApi\nclass NavigationRailOverrideScope\ninternal constructor(\n    val modifier: Modifier = Modifier,\n    val containerColor: Color,\n    val contentColor: Color,\n    val header: @Composable (ColumnScope.() -> Unit)?,\n    val windowInsets: WindowInsets,\n    val content: @Composable ColumnScope.() -> Unit,\n)\n\n/** CompositionLocal containing the currently-selected [NavigationRailOverride]. */\n@ExperimentalMaterial3ComponentOverrideApi\nval LocalNavigationRailOverride: ProvidableCompositionLocal<NavigationRailOverride> =\n    compositionLocalOf {\n        DefaultNavigationRailOverride\n    }\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/NavigationDrawer.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.FiniteAnimationSpec\nimport androidx.compose.animation.core.TweenSpec\nimport androidx.compose.animation.core.animate\nimport androidx.compose.animation.core.snap\nimport androidx.compose.foundation.gestures.AnchoredDraggableDefaults\nimport androidx.compose.foundation.gestures.AnchoredDraggableState\nimport androidx.compose.foundation.gestures.DraggableAnchors\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.anchoredDraggable\nimport androidx.compose.foundation.gestures.snapTo\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.WindowInsetsSides\nimport androidx.compose.foundation.layout.fillMaxHeight\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.only\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.windowInsetsPadding\nimport androidx.compose.material3.internal.BackEventCompat\nimport androidx.compose.material3.internal.FloatProducer\nimport androidx.compose.material3.internal.PredictiveBack\nimport androidx.compose.material3.internal.PredictiveBackHandler\nimport androidx.compose.material3.internal.Strings\nimport androidx.compose.material3.internal.getString\nimport androidx.compose.material3.internal.systemBarsForVisualComponents\nimport androidx.compose.material3.tokens.ElevationTokens\nimport androidx.compose.material3.tokens.MotionSchemeKeyTokens\nimport androidx.compose.material3.tokens.NavigationDrawerTokens\nimport androidx.compose.material3.tokens.ScrimTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.runtime.saveable.Saver\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.focus.FocusRequester\nimport androidx.compose.ui.focus.focusRequester\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.GraphicsLayerScope\nimport androidx.compose.ui.graphics.RectangleShape\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.TransformOrigin\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.input.key.Key\nimport androidx.compose.ui.input.key.KeyEventType\nimport androidx.compose.ui.input.key.key\nimport androidx.compose.ui.input.key.onKeyEvent\nimport androidx.compose.ui.input.key.type\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.semantics.dismiss\nimport androidx.compose.ui.semantics.paneTitle\nimport androidx.compose.ui.semantics.role\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastForEach\nimport androidx.compose.ui.util.fastMap\nimport androidx.compose.ui.util.fastMaxOfOrNull\nimport androidx.compose.ui.util.lerp\nimport kotlin.math.roundToInt\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.launch\n\n/** Possible values of [DrawerState]. */\nenum class DrawerValue {\n    /** The state of the drawer when it is closed. */\n    Closed,\n\n    /** The state of the drawer when it is open. */\n    Open,\n}\n\n/**\n * State of the [ModalNavigationDrawer] and [DismissibleNavigationDrawer] composable.\n *\n * @param initialValue The initial value of the state.\n * @param confirmStateChange Optional callback invoked to confirm or veto a pending state change.\n */\n@Suppress(\"NotCloseable\")\n@Stable\nclass DrawerState(\n    initialValue: DrawerValue,\n    internal val confirmStateChange: (DrawerValue) -> Boolean = { true },\n) {\n\n    internal var anchoredDraggableMotionSpec: FiniteAnimationSpec<Float> =\n        AnchoredDraggableDefaultAnimationSpec\n\n    @Suppress(\"Deprecation\")\n    internal val anchoredDraggableState =\n        AnchoredDraggableState(\n            initialValue = initialValue,\n            snapAnimationSpec = anchoredDraggableMotionSpec,\n            decayAnimationSpec = AnchoredDraggableDefaults.DecayAnimationSpec,\n            confirmValueChange = confirmStateChange,\n            positionalThreshold = { distance: Float -> distance * DrawerPositionalThreshold },\n            velocityThreshold = { with(requireDensity()) { DrawerVelocityThreshold.toPx() } },\n        )\n\n    /** Whether the drawer is open. */\n    val isOpen: Boolean\n        get() = currentValue == DrawerValue.Open\n\n    /** Whether the drawer is closed. */\n    val isClosed: Boolean\n        get() = currentValue == DrawerValue.Closed\n\n    /**\n     * The current value of the state.\n     *\n     * If no swipe or animation is in progress, this corresponds to the start the drawer currently\n     * in. If a swipe or an animation is in progress, this corresponds the state drawer was in\n     * before the swipe or animation started.\n     */\n    val currentValue: DrawerValue\n        get() {\n            return anchoredDraggableState.settledValue\n        }\n\n    /** Whether the state is currently animating. */\n    val isAnimationRunning: Boolean\n        get() {\n            return anchoredDraggableState.isAnimationRunning\n        }\n\n    /**\n     * Open the drawer with animation and suspend until it if fully opened or animation has been\n     * cancelled. This method will throw [CancellationException] if the animation is interrupted\n     *\n     * @return the reason the open animation ended\n     */\n    suspend fun open() =\n        animateTo(targetValue = DrawerValue.Open, animationSpec = openDrawerMotionSpec)\n\n    /**\n     * Close the drawer with animation and suspend until it if fully closed or animation has been\n     * cancelled. This method will throw [CancellationException] if the animation is interrupted\n     *\n     * @return the reason the close animation ended\n     */\n    suspend fun close() =\n        animateTo(targetValue = DrawerValue.Closed, animationSpec = closeDrawerMotionSpec)\n\n    /**\n     * Set the state of the drawer with specific animation\n     *\n     * @param targetValue The new value to animate to.\n     * @param anim The animation that will be used to animate to the new value.\n     */\n    @Deprecated(\n        message =\n            \"This method has been replaced by the open and close methods. The animation \" +\n                \"spec is now an implementation detail of ModalDrawer.\"\n    )\n    suspend fun animateTo(targetValue: DrawerValue, anim: AnimationSpec<Float>) {\n        animateTo(targetValue = targetValue, animationSpec = anim)\n    }\n\n    /**\n     * Set the state without any animation and suspend until it's set\n     *\n     * @param targetValue The new target value\n     */\n    suspend fun snapTo(targetValue: DrawerValue) {\n        anchoredDraggableState.snapTo(targetValue)\n    }\n\n    /**\n     * The target value of the drawer state.\n     *\n     * If a swipe is in progress, this is the value that the Drawer would animate to if the swipe\n     * finishes. If an animation is running, this is the target value of that animation. Finally, if\n     * no swipe or animation is in progress, this is the same as the [currentValue].\n     */\n    val targetValue: DrawerValue\n        get() = anchoredDraggableState.targetValue\n\n    /**\n     * The current position (in pixels) of the drawer sheet, or Float.NaN before the offset is\n     * initialized.\n     *\n     * @see [AnchoredDraggableState.offset] for more information.\n     */\n    @Deprecated(\n        message =\n            \"Please access the offset through currentOffset, which returns the value \" +\n                \"directly instead of wrapping it in a state object.\",\n        replaceWith = ReplaceWith(\"currentOffset\"),\n    )\n    val offset: State<Float> =\n        object : State<Float> {\n            override val value: Float\n                get() = anchoredDraggableState.offset\n        }\n\n    /**\n     * The current position (in pixels) of the drawer sheet, or Float.NaN before the offset is\n     * initialized.\n     *\n     * @see [AnchoredDraggableState.offset] for more information.\n     */\n    val currentOffset: Float\n        get() = anchoredDraggableState.offset\n\n    internal var density: Density? by mutableStateOf(null)\n\n    internal var openDrawerMotionSpec: FiniteAnimationSpec<Float> = snap()\n\n    internal var closeDrawerMotionSpec: FiniteAnimationSpec<Float> = snap()\n\n    private fun requireDensity() =\n        requireNotNull(density) {\n            \"The density on DrawerState ($this) was not set. Did you use DrawerState\" +\n                \" with the ModalNavigationDrawer or DismissibleNavigationDrawer composables?\"\n        }\n\n    internal fun requireOffset(): Float = anchoredDraggableState.requireOffset()\n\n    private suspend fun animateTo(\n        targetValue: DrawerValue,\n        animationSpec: AnimationSpec<Float>,\n        velocity: Float = anchoredDraggableState.lastVelocity,\n    ) {\n        anchoredDraggableState.anchoredDrag(targetValue = targetValue) { anchors, latestTarget ->\n            val targetOffset = anchors.positionOf(latestTarget)\n            if (!targetOffset.isNaN()) {\n                var prev = if (currentOffset.isNaN()) 0f else currentOffset\n                animate(prev, targetOffset, velocity, animationSpec) { value, velocity ->\n                    // Our onDrag coerces the value within the bounds, but an animation may\n                    // overshoot, for example a spring animation or an overshooting interpolator\n                    // We respect the user's intention and allow the overshoot, but still use\n                    // DraggableState's drag for its mutex.\n                    dragTo(value, velocity)\n                    prev = value\n                }\n            }\n        }\n    }\n\n    companion object {\n        /** The default [Saver] implementation for [DrawerState]. */\n        fun Saver(confirmStateChange: (DrawerValue) -> Boolean) =\n            Saver<DrawerState, DrawerValue>(\n                save = { it.currentValue },\n                restore = { DrawerState(it, confirmStateChange) },\n            )\n    }\n}\n\n/**\n * Create and [remember] a [DrawerState].\n *\n * @param initialValue The initial value of the state.\n * @param confirmStateChange Optional callback invoked to confirm or veto a pending state change.\n */\n@Composable\nfun rememberDrawerState(\n    initialValue: DrawerValue,\n    confirmStateChange: (DrawerValue) -> Boolean = { true },\n): DrawerState {\n    return rememberSaveable(saver = DrawerState.Saver(confirmStateChange)) {\n        DrawerState(initialValue, confirmStateChange)\n    }\n}\n\n/**\n * [Material Design navigation drawer](https://m3.material.io/components/navigation-drawer/overview)\n *\n * Navigation drawers provide ergonomic access to destinations in an app.\n *\n * Modal navigation drawers block interaction with the rest of an app’s content with a scrim. They\n * are elevated above most of the app’s UI and don’t affect the screen’s layout grid.\n *\n * ![Navigation drawer\n * image](https://developer.android.com/images/reference/androidx/compose/material3/navigation-drawer.png)\n *\n * @sample androidx.compose.material3.samples.ModalNavigationDrawerSample\n * @param drawerContent content inside this drawer\n * @param modifier the [Modifier] to be applied to this drawer\n * @param drawerState state of the drawer\n * @param gesturesEnabled whether or not the drawer can be interacted by gestures\n * @param scrimColor color of the scrim that obscures content when the drawer is open\n * @param content content of the rest of the UI\n */\n@Composable\nfun ModalNavigationDrawer(\n    drawerContent: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),\n    gesturesEnabled: Boolean = true,\n    scrimColor: Color = DrawerDefaults.scrimColor,\n    content: @Composable () -> Unit,\n) {\n    val scope = rememberCoroutineScope()\n    val navigationMenu = getString(Strings.NavigationMenu)\n    val density = LocalDensity.current\n    var anchorsInitialized by remember { mutableStateOf(false) }\n    var minValue by remember(density) { mutableFloatStateOf(0f) }\n    val maxValue = 0f\n    val focusRequester = remember { FocusRequester() }\n\n    // TODO Load the motionScheme tokens from the component tokens file\n    val anchoredDraggableMotion: FiniteAnimationSpec<Float> =\n        MotionSchemeKeyTokens.DefaultSpatial.value()\n    val openMotion: FiniteAnimationSpec<Float> = MotionSchemeKeyTokens.DefaultSpatial.value()\n    val closeMotion: FiniteAnimationSpec<Float> = MotionSchemeKeyTokens.FastEffects.value()\n\n    SideEffect {\n        drawerState.density = density\n        drawerState.openDrawerMotionSpec = openMotion\n        drawerState.closeDrawerMotionSpec = closeMotion\n        drawerState.anchoredDraggableMotionSpec = anchoredDraggableMotion\n    }\n\n    LaunchedEffect(drawerState.isOpen) {\n        if (drawerState.isOpen) {\n            // Keyboard focus should go to first element of the drawer when it opens\n            focusRequester.requestFocus()\n        }\n    }\n\n    val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl\n    Box(\n        modifier\n            .fillMaxSize()\n            .anchoredDraggable(\n                state = drawerState.anchoredDraggableState,\n                orientation = Orientation.Horizontal,\n                enabled = gesturesEnabled,\n                reverseDirection = isRtl,\n            )\n    ) {\n        Box { content() }\n        val onDismissRequest = {\n            if (gesturesEnabled && drawerState.confirmStateChange(DrawerValue.Closed)) {\n                scope.launch { drawerState.close() }\n            }\n        }\n        Scrim(\n            contentDescription = getString(Strings.CloseDrawer),\n            onClick = if (drawerState.isOpen) onDismissRequest else null,\n            alpha = { calculateFraction(minValue, maxValue, drawerState.requireOffset()) },\n            color = scrimColor,\n        )\n        Layout(\n            content = drawerContent,\n            modifier =\n                Modifier.offset {\n                        drawerState.currentOffset.let { offset ->\n                            val offsetX =\n                                when {\n                                    !offset.isNaN() -> offset.roundToInt()\n                                    // If offset is NaN, set offset based on open/closed state\n                                    drawerState.isOpen -> 0\n                                    else -> -DrawerDefaults.MaximumDrawerWidth.roundToPx()\n                                }\n                            IntOffset(offsetX, 0)\n                        }\n                    }\n                    .semantics {\n                        paneTitle = navigationMenu\n                        if (drawerState.isOpen) {\n                            dismiss {\n                                if (drawerState.confirmStateChange(DrawerValue.Closed)) {\n                                    scope.launch { drawerState.close() }\n                                }\n                                true\n                            }\n                        }\n                    }\n                    .onKeyEvent {\n                        // Drawer should close via escape key.\n                        if (\n                            drawerState.isOpen &&\n                                it.type == KeyEventType.KeyUp &&\n                                it.key == Key.Escape\n                        ) {\n                            scope.launch { drawerState.close() }\n                            return@onKeyEvent true\n                        }\n                        return@onKeyEvent false\n                    }\n                    .focusRequester(focusRequester),\n        ) { measurables, constraints ->\n            val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)\n            val placeables = measurables.fastMap { it.measure(looseConstraints) }\n            val width = placeables.fastMaxOfOrNull { it.width } ?: 0\n            val height = placeables.fastMaxOfOrNull { it.height } ?: 0\n\n            layout(width, height) {\n                val currentClosedAnchor =\n                    drawerState.anchoredDraggableState.anchors.positionOf(DrawerValue.Closed)\n                val calculatedClosedAnchor = -width.toFloat()\n\n                if (!anchorsInitialized || currentClosedAnchor != calculatedClosedAnchor) {\n                    if (!anchorsInitialized) {\n                        anchorsInitialized = true\n                    }\n                    minValue = calculatedClosedAnchor\n                    drawerState.anchoredDraggableState.updateAnchors(\n                        DraggableAnchors {\n                            DrawerValue.Closed at minValue\n                            DrawerValue.Open at maxValue\n                        }\n                    )\n                }\n                val isDrawerVisible =\n                    calculateFraction(minValue, maxValue, drawerState.requireOffset()) != 0f\n                if (isDrawerVisible) {\n                    // Only place the drawer when it's visible so that keyboard focus doesn't\n                    // navigate to an offscreen element.\n                    placeables.fastForEach { it.placeRelative(0, 0) }\n                }\n            }\n        }\n    }\n}\n\n/**\n * [Material Design navigation drawer](https://m3.material.io/components/navigation-drawer/overview)\n *\n * Navigation drawers provide ergonomic access to destinations in an app. They’re often next to app\n * content and affect the screen’s layout grid.\n *\n * ![Navigation drawer\n * image](https://developer.android.com/images/reference/androidx/compose/material3/navigation-drawer.png)\n *\n * Dismissible standard drawers can be used for layouts that prioritize content (such as a photo\n * gallery) or for apps where users are unlikely to switch destinations often. They should use a\n * visible navigation menu icon to open and close the drawer.\n *\n * @sample androidx.compose.material3.samples.DismissibleNavigationDrawerSample\n * @param drawerContent content inside this drawer\n * @param modifier the [Modifier] to be applied to this drawer\n * @param drawerState state of the drawer\n * @param gesturesEnabled whether or not the drawer can be interacted by gestures\n * @param content content of the rest of the UI\n */\n@Composable\nfun DismissibleNavigationDrawer(\n    drawerContent: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),\n    gesturesEnabled: Boolean = true,\n    content: @Composable () -> Unit,\n) {\n    var anchorsInitialized by remember { mutableStateOf(false) }\n    val density = LocalDensity.current\n    val focusRequester = remember { FocusRequester() }\n\n    // TODO Load the motionScheme tokens from the component tokens file\n    val openMotion: FiniteAnimationSpec<Float> = MotionSchemeKeyTokens.DefaultSpatial.value()\n    val closeMotion: FiniteAnimationSpec<Float> = MotionSchemeKeyTokens.FastEffects.value()\n\n    SideEffect {\n        drawerState.density = density\n        drawerState.openDrawerMotionSpec = openMotion\n        drawerState.closeDrawerMotionSpec = closeMotion\n    }\n\n    LaunchedEffect(drawerState.isOpen) {\n        if (drawerState.isOpen) {\n            // Keyboard focus should go to first element of the drawer when it opens\n            focusRequester.requestFocus()\n        }\n    }\n\n    val scope = rememberCoroutineScope()\n    val navigationMenu = getString(Strings.NavigationMenu)\n\n    val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl\n    Box(\n        modifier.anchoredDraggable(\n            state = drawerState.anchoredDraggableState,\n            orientation = Orientation.Horizontal,\n            enabled = gesturesEnabled,\n            reverseDirection = isRtl,\n        )\n    ) {\n        Layout(\n            content = {\n                Box(\n                    Modifier.semantics {\n                            paneTitle = navigationMenu\n                            if (drawerState.isOpen) {\n                                dismiss {\n                                    if (drawerState.confirmStateChange(DrawerValue.Closed)) {\n                                        scope.launch { drawerState.close() }\n                                    }\n                                    true\n                                }\n                            }\n                        }\n                        .onKeyEvent {\n                            // Drawer should close via escape key.\n                            if (\n                                drawerState.isOpen &&\n                                    it.type == KeyEventType.KeyUp &&\n                                    it.key == Key.Escape\n                            ) {\n                                scope.launch { drawerState.close() }\n                                return@onKeyEvent true\n                            }\n                            return@onKeyEvent false\n                        }\n                        .focusRequester(focusRequester)\n                ) {\n                    drawerContent()\n                }\n                Box { content() }\n            }\n        ) { measurables, constraints ->\n            val sheetPlaceable = measurables[0].measure(constraints)\n            val contentPlaceable = measurables[1].measure(constraints)\n            layout(contentPlaceable.width, contentPlaceable.height) {\n                val currentClosedAnchor =\n                    drawerState.anchoredDraggableState.anchors.positionOf(DrawerValue.Closed)\n                val calculatedClosedAnchor = -sheetPlaceable.width.toFloat()\n\n                if (!anchorsInitialized || currentClosedAnchor != calculatedClosedAnchor) {\n                    if (!anchorsInitialized) {\n                        anchorsInitialized = true\n                    }\n                    drawerState.anchoredDraggableState.updateAnchors(\n                        DraggableAnchors {\n                            DrawerValue.Closed at calculatedClosedAnchor\n                            DrawerValue.Open at 0f\n                        }\n                    )\n                }\n\n                val contentX = sheetPlaceable.width + drawerState.requireOffset().roundToInt()\n                contentPlaceable.placeRelative(contentX, 0)\n                // The drawer is visible when the content has been offset.\n                if (contentX != 0) {\n                    // Only place the drawer when it's visible so that keyboard focus doesn't\n                    // navigate to an offscreen element.\n                    sheetPlaceable.placeRelative(drawerState.requireOffset().roundToInt(), 0)\n                }\n            }\n        }\n    }\n}\n\n/**\n * [Material Design navigation permanent\n * drawer](https://m3.material.io/components/navigation-drawer/overview)\n *\n * Navigation drawers provide ergonomic access to destinations in an app. They’re often next to app\n * content and affect the screen’s layout grid.\n *\n * ![Navigation drawer\n * image](https://developer.android.com/images/reference/androidx/compose/material3/navigation-drawer.png)\n *\n * The permanent navigation drawer is always visible and usually used for frequently switching\n * destinations. On mobile screens, use [ModalNavigationDrawer] instead.\n *\n * @sample androidx.compose.material3.samples.PermanentNavigationDrawerSample\n * @param drawerContent content inside this drawer\n * @param modifier the [Modifier] to be applied to this drawer\n * @param content content of the rest of the UI\n */\n@Composable\nfun PermanentNavigationDrawer(\n    drawerContent: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    content: @Composable () -> Unit,\n) {\n    Row(modifier.fillMaxSize()) {\n        drawerContent()\n        Box { content() }\n    }\n}\n\n/**\n * Content inside of a modal navigation drawer.\n *\n * Note: This version of [ModalDrawerSheet] does not handle back by default. For automatic back\n * handling and predictive back animations on Android 14+, use the [ModalDrawerSheet] that accepts\n * `drawerState` as a param.\n *\n * @param modifier the [Modifier] to be applied to this drawer's content\n * @param drawerShape defines the shape of this drawer's container\n * @param drawerContainerColor the color used for the background of this drawer. Use\n *   [Color.Transparent] to have no color.\n * @param drawerContentColor the preferred color for content inside this drawer. Defaults to either\n *   the matching content color for [drawerContainerColor], or to the current [LocalContentColor] if\n *   [drawerContainerColor] is not a color from the theme.\n * @param drawerTonalElevation when [drawerContainerColor] is [ColorScheme.surface], a translucent\n *   primary color overlay is applied on top of the container. A higher tonal elevation value will\n *   result in a darker color in light theme and lighter color in dark theme. See also: [Surface].\n * @param windowInsets a window insets for the sheet.\n * @param content content inside of a modal navigation drawer\n */\n@Composable\nfun ModalDrawerSheet(\n    modifier: Modifier = Modifier,\n    drawerShape: Shape = DrawerDefaults.shape,\n    drawerContainerColor: Color = DrawerDefaults.modalContainerColor,\n    drawerContentColor: Color = contentColorFor(drawerContainerColor),\n    drawerTonalElevation: Dp = DrawerDefaults.ModalDrawerElevation,\n    windowInsets: WindowInsets = DrawerDefaults.windowInsets,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    DrawerSheet(\n        drawerPredictiveBackState = null,\n        windowInsets = windowInsets,\n        modifier = modifier,\n        drawerShape = drawerShape,\n        drawerContainerColor = drawerContainerColor,\n        drawerContentColor = drawerContentColor,\n        drawerTonalElevation = drawerTonalElevation,\n        content = content,\n    )\n}\n\n/**\n * Content inside of a modal navigation drawer.\n *\n * Note: This version of [ModalDrawerSheet] requires a [drawerState] to be provided and will handle\n * back by default for all Android versions, as well as animate during predictive back on Android\n * 14+.\n *\n * @param drawerState state of the drawer\n * @param modifier the [Modifier] to be applied to this drawer's content\n * @param drawerShape defines the shape of this drawer's container\n * @param drawerContainerColor the color used for the background of this drawer. Use\n *   [Color.Transparent] to have no color.\n * @param drawerContentColor the preferred color for content inside this drawer. Defaults to either\n *   the matching content color for [drawerContainerColor], or to the current [LocalContentColor] if\n *   [drawerContainerColor] is not a color from the theme.\n * @param drawerTonalElevation when [drawerContainerColor] is [ColorScheme.surface], a translucent\n *   primary color overlay is applied on top of the container. A higher tonal elevation value will\n *   result in a darker color in light theme and lighter color in dark theme. See also: [Surface].\n * @param windowInsets a window insets for the sheet.\n * @param content content inside of a modal navigation drawer\n */\n@Composable\nfun ModalDrawerSheet(\n    drawerState: DrawerState,\n    modifier: Modifier = Modifier,\n    drawerShape: Shape = DrawerDefaults.shape,\n    drawerContainerColor: Color = DrawerDefaults.modalContainerColor,\n    drawerContentColor: Color = contentColorFor(drawerContainerColor),\n    drawerTonalElevation: Dp = DrawerDefaults.ModalDrawerElevation,\n    windowInsets: WindowInsets = DrawerDefaults.windowInsets,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    DrawerPredictiveBackHandler(drawerState) { drawerPredictiveBackState ->\n        DrawerSheet(\n            drawerPredictiveBackState = drawerPredictiveBackState,\n            windowInsets = windowInsets,\n            modifier = modifier,\n            drawerShape = drawerShape,\n            drawerContainerColor = drawerContainerColor,\n            drawerContentColor = drawerContentColor,\n            drawerTonalElevation = drawerTonalElevation,\n            drawerOffset = { drawerState.anchoredDraggableState.offset },\n            content = content,\n        )\n    }\n}\n\n/**\n * Content inside of a dismissible navigation drawer.\n *\n * Note: This version of [DismissibleDrawerSheet] does not handle back by default. For automatic\n * back handling and predictive back animations on Android 14+, use the [DismissibleDrawerSheet]\n * that accepts `drawerState` as a param.\n *\n * @param modifier the [Modifier] to be applied to this drawer's content\n * @param drawerShape defines the shape of this drawer's container\n * @param drawerContainerColor the color used for the background of this drawer. Use\n *   [Color.Transparent] to have no color.\n * @param drawerContentColor the preferred color for content inside this drawer. Defaults to either\n *   the matching content color for [drawerContainerColor], or to the current [LocalContentColor] if\n *   [drawerContainerColor] is not a color from the theme.\n * @param drawerTonalElevation when [drawerContainerColor] is [ColorScheme.surface], a translucent\n *   primary color overlay is applied on top of the container. A higher tonal elevation value will\n *   result in a darker color in light theme and lighter color in dark theme. See also: [Surface].\n * @param windowInsets a window insets for the sheet.\n * @param content content inside of a dismissible navigation drawer\n */\n@Composable\nfun DismissibleDrawerSheet(\n    modifier: Modifier = Modifier,\n    drawerShape: Shape = RectangleShape,\n    drawerContainerColor: Color = DrawerDefaults.standardContainerColor,\n    drawerContentColor: Color = contentColorFor(drawerContainerColor),\n    drawerTonalElevation: Dp = DrawerDefaults.DismissibleDrawerElevation,\n    windowInsets: WindowInsets = DrawerDefaults.windowInsets,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    DrawerSheet(\n        drawerPredictiveBackState = null,\n        windowInsets = windowInsets,\n        modifier = modifier,\n        drawerShape = drawerShape,\n        drawerContainerColor = drawerContainerColor,\n        drawerContentColor = drawerContentColor,\n        drawerTonalElevation = drawerTonalElevation,\n        content = content,\n    )\n}\n\n/**\n * Content inside of a dismissible navigation drawer.\n *\n * Note: This version of [DismissibleDrawerSheet] requires a [drawerState] to be provided and will\n * handle back by default for all Android versions, as well as animate during predictive back on\n * Android 14+.\n *\n * @param drawerState state of the drawer\n * @param modifier the [Modifier] to be applied to this drawer's content\n * @param drawerShape defines the shape of this drawer's container\n * @param drawerContainerColor the color used for the background of this drawer. Use\n *   [Color.Transparent] to have no color.\n * @param drawerContentColor the preferred color for content inside this drawer. Defaults to either\n *   the matching content color for [drawerContainerColor], or to the current [LocalContentColor] if\n *   [drawerContainerColor] is not a color from the theme.\n * @param drawerTonalElevation when [drawerContainerColor] is [ColorScheme.surface], a translucent\n *   primary color overlay is applied on top of the container. A higher tonal elevation value will\n *   result in a darker color in light theme and lighter color in dark theme. See also: [Surface].\n * @param windowInsets a window insets for the sheet.\n * @param content content inside of a dismissible navigation drawer\n */\n@Composable\nfun DismissibleDrawerSheet(\n    drawerState: DrawerState,\n    modifier: Modifier = Modifier,\n    drawerShape: Shape = RectangleShape,\n    drawerContainerColor: Color = DrawerDefaults.standardContainerColor,\n    drawerContentColor: Color = contentColorFor(drawerContainerColor),\n    drawerTonalElevation: Dp = DrawerDefaults.DismissibleDrawerElevation,\n    windowInsets: WindowInsets = DrawerDefaults.windowInsets,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    DrawerPredictiveBackHandler(drawerState) { drawerPredictiveBackState ->\n        DrawerSheet(\n            drawerPredictiveBackState = drawerPredictiveBackState,\n            windowInsets = windowInsets,\n            modifier = modifier,\n            drawerShape = drawerShape,\n            drawerContainerColor = drawerContainerColor,\n            drawerContentColor = drawerContentColor,\n            drawerTonalElevation = drawerTonalElevation,\n            drawerOffset = { drawerState.anchoredDraggableState.offset },\n            content = content,\n        )\n    }\n}\n\n/**\n * Content inside of a permanent navigation drawer.\n *\n * @param modifier the [Modifier] to be applied to this drawer's content\n * @param drawerShape defines the shape of this drawer's container\n * @param drawerContainerColor the color used for the background of this drawer. Use\n *   [Color.Transparent] to have no color.\n * @param drawerContentColor the preferred color for content inside this drawer. Defaults to either\n *   the matching content color for [drawerContainerColor], or to the current [LocalContentColor] if\n *   [drawerContainerColor] is not a color from the theme.\n * @param drawerTonalElevation when [drawerContainerColor] is [ColorScheme.surface], a translucent\n *   primary color overlay is applied on top of the container. A higher tonal elevation value will\n *   result in a darker color in light theme and lighter color in dark theme. See also: [Surface].\n * @param windowInsets a window insets for the sheet.\n * @param content content inside a permanent navigation drawer\n */\n@Composable\nfun PermanentDrawerSheet(\n    modifier: Modifier = Modifier,\n    drawerShape: Shape = RectangleShape,\n    drawerContainerColor: Color = DrawerDefaults.standardContainerColor,\n    drawerContentColor: Color = contentColorFor(drawerContainerColor),\n    drawerTonalElevation: Dp = DrawerDefaults.PermanentDrawerElevation,\n    windowInsets: WindowInsets = DrawerDefaults.windowInsets,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    val navigationMenu = getString(Strings.NavigationMenu)\n    DrawerSheet(\n        drawerPredictiveBackState = null,\n        windowInsets = windowInsets,\n        modifier = modifier.semantics { paneTitle = navigationMenu },\n        drawerShape = drawerShape,\n        drawerContainerColor = drawerContainerColor,\n        drawerContentColor = drawerContentColor,\n        drawerTonalElevation = drawerTonalElevation,\n        content = content,\n    )\n}\n\n@Composable\ninternal fun DrawerSheet(\n    drawerPredictiveBackState: DrawerPredictiveBackState?,\n    windowInsets: WindowInsets,\n    modifier: Modifier = Modifier,\n    drawerShape: Shape = RectangleShape,\n    drawerContainerColor: Color = DrawerDefaults.standardContainerColor,\n    drawerContentColor: Color = contentColorFor(drawerContainerColor),\n    drawerTonalElevation: Dp = DrawerDefaults.PermanentDrawerElevation,\n    drawerOffset: FloatProducer = FloatProducer { 0F },\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    val density = LocalDensity.current\n    val maxWidth = NavigationDrawerTokens.ContainerWidth\n    val maxWidthPx = with(density) { maxWidth.toPx() }\n    val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl\n    val predictiveBackDrawerContainerModifier =\n        if (drawerPredictiveBackState != null) {\n            Modifier.predictiveBackDrawerContainer(drawerPredictiveBackState, isRtl)\n        } else {\n            Modifier\n        }\n    Surface(\n        modifier =\n            modifier\n                .sizeIn(minWidth = MinimumDrawerWidth, maxWidth = maxWidth)\n                // Scale up the Surface horizontally in case the drawer offset it greater than zero.\n                // This is done to avoid showing a gap when the drawer opens and bounces when it's\n                // applied with a bouncy motion. Note that the content inside the Surface is scaled\n                // back down to maintain its aspect ratio (see below).\n                .horizontalScaleUp(\n                    drawerOffset = drawerOffset,\n                    drawerWidth = maxWidthPx,\n                    isRtl = isRtl,\n                )\n                .then(predictiveBackDrawerContainerModifier)\n                .fillMaxHeight(),\n        shape = drawerShape,\n        color = drawerContainerColor,\n        contentColor = drawerContentColor,\n        tonalElevation = drawerTonalElevation,\n    ) {\n        val predictiveBackDrawerChildModifier =\n            if (drawerPredictiveBackState != null)\n                Modifier.predictiveBackDrawerChild(drawerPredictiveBackState, isRtl)\n            else Modifier\n        Column(\n            Modifier.sizeIn(minWidth = MinimumDrawerWidth, maxWidth = maxWidth)\n                // Scale the content down in case the drawer offset is greater than one. The\n                // wrapping Surface is scaled up, so this is done to maintain the content's aspect\n                // ratio.\n                .horizontalScaleDown(\n                    drawerOffset = drawerOffset,\n                    drawerWidth = maxWidthPx,\n                    isRtl = isRtl,\n                )\n                .then(predictiveBackDrawerChildModifier)\n                .windowInsetsPadding(windowInsets),\n            content = content,\n        )\n    }\n}\n\n/**\n * A [Modifier] that scales up the drawing layer on the X axis in case the [drawerOffset] is greater\n * than zero. The scaling will ensure that there is no visible gap between the drawer and the edge\n * of the screen in case the drawer bounces when it opens due to a more expressive motion setting.\n *\n * A [horizontalScaleDown] should be applied to the content of the drawer to maintain the content\n * aspect ratio as the container scales up.\n *\n * @see horizontalScaleDown\n */\nprivate fun Modifier.horizontalScaleUp(\n    drawerOffset: FloatProducer,\n    drawerWidth: Float,\n    isRtl: Boolean,\n) = graphicsLayer {\n    val offset = drawerOffset()\n    scaleX = if (offset > 0f) 1f + offset / drawerWidth else 1f\n    transformOrigin = TransformOrigin(if (isRtl) 0f else 1f, 0.5f)\n}\n\n/**\n * A [Modifier] that scales down the drawing layer on the X axis in case the [drawerOffset] is\n * greater than zero. This modifier should be applied to the content inside a component that was\n * scaled up with a [horizontalScaleUp] modifier. It will ensure that the content maintains its\n * aspect ratio as the container scales up.\n *\n * @see horizontalScaleUp\n */\nprivate fun Modifier.horizontalScaleDown(\n    drawerOffset: FloatProducer,\n    drawerWidth: Float,\n    isRtl: Boolean,\n) = graphicsLayer {\n    val offset = drawerOffset()\n    scaleX = if (offset > 0f) 1 / (1f + offset / drawerWidth) else 1f\n    transformOrigin = TransformOrigin(if (isRtl) 0f else 1f, 0f)\n}\n\nprivate fun Modifier.predictiveBackDrawerContainer(\n    drawerPredictiveBackState: DrawerPredictiveBackState,\n    isRtl: Boolean,\n) = graphicsLayer {\n    scaleX = calculatePredictiveBackScaleX(drawerPredictiveBackState)\n    scaleY = calculatePredictiveBackScaleY(drawerPredictiveBackState)\n    transformOrigin = TransformOrigin(if (isRtl) 1f else 0f, 0.5f)\n}\n\nprivate fun Modifier.predictiveBackDrawerChild(\n    drawerPredictiveBackState: DrawerPredictiveBackState,\n    isRtl: Boolean,\n) = graphicsLayer {\n    // Preserve the original aspect ratio and container alignment of the child\n    // content, and add content margins.\n    val containerScaleX = calculatePredictiveBackScaleX(drawerPredictiveBackState)\n    val containerScaleY = calculatePredictiveBackScaleY(drawerPredictiveBackState)\n    scaleX = if (containerScaleX != 0f) containerScaleY / containerScaleX else 1f\n    transformOrigin = TransformOrigin(if (isRtl) 0f else 1f, 0f)\n}\n\nprivate fun GraphicsLayerScope.calculatePredictiveBackScaleX(\n    drawerPredictiveBackState: DrawerPredictiveBackState\n): Float {\n    val width = size.width\n    return if (width.isNaN() || width == 0f) {\n        1f\n    } else {\n        val scaleXDirection = if (drawerPredictiveBackState.swipeEdgeMatchesDrawer) 1 else -1\n        1f + drawerPredictiveBackState.scaleXDistance * scaleXDirection / width\n    }\n}\n\nprivate fun GraphicsLayerScope.calculatePredictiveBackScaleY(\n    drawerPredictiveBackState: DrawerPredictiveBackState\n): Float {\n    val height = size.height\n    return if (height.isNaN() || height == 0f) {\n        1f\n    } else {\n        1f - drawerPredictiveBackState.scaleYDistance / height\n    }\n}\n\n/**\n * Registers a [PredictiveBackHandler] and provides animation values in [DrawerPredictiveBackState]\n * based on back progress.\n *\n * @param drawerState state of the drawer\n * @param content content of the rest of the UI\n */\n@Composable\ninternal fun DrawerPredictiveBackHandler(\n    drawerState: DrawerState,\n    content: @Composable (DrawerPredictiveBackState) -> Unit,\n) {\n    val drawerPredictiveBackState = remember { DrawerPredictiveBackState() }\n    val scope = rememberCoroutineScope()\n    val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl\n    val maxScaleXDistanceGrow: Float\n    val maxScaleXDistanceShrink: Float\n    val maxScaleYDistance: Float\n    with(LocalDensity.current) {\n        maxScaleXDistanceGrow = PredictiveBackDrawerMaxScaleXDistanceGrow.toPx()\n        maxScaleXDistanceShrink = PredictiveBackDrawerMaxScaleXDistanceShrink.toPx()\n        maxScaleYDistance = PredictiveBackDrawerMaxScaleYDistance.toPx()\n    }\n\n    PredictiveBackHandler(enabled = drawerState.isOpen) { progress ->\n        try {\n            progress.collect { backEvent ->\n                drawerPredictiveBackState.update(\n                    PredictiveBack.transform(backEvent.progress),\n                    backEvent.swipeEdge == BackEventCompat.EDGE_LEFT,\n                    isRtl,\n                    maxScaleXDistanceGrow,\n                    maxScaleXDistanceShrink,\n                    maxScaleYDistance,\n                )\n            }\n        } catch (e: kotlin.coroutines.cancellation.CancellationException) {\n            drawerPredictiveBackState.clear()\n        } finally {\n            if (drawerPredictiveBackState.swipeEdgeMatchesDrawer) {\n                // If swipe edge matches drawer gravity and we've stretched the drawer horizontally,\n                // un-stretch it smoothly so that it hides completely during the drawer close.\n                scope.launch {\n                    animate(\n                        initialValue = drawerPredictiveBackState.scaleXDistance,\n                        targetValue = 0f,\n                    ) { value, _ ->\n                        drawerPredictiveBackState.scaleXDistance = value\n                    }\n                    drawerPredictiveBackState.clear()\n                }\n            }\n            drawerState.close()\n        }\n    }\n\n    LaunchedEffect(drawerState.isClosed) {\n        if (drawerState.isClosed) {\n            drawerPredictiveBackState.clear()\n        }\n    }\n\n    content(drawerPredictiveBackState)\n}\n\n/** Object to hold default values for [ModalNavigationDrawer] */\nobject DrawerDefaults {\n    /** Default Elevation for drawer container in the [ModalNavigationDrawer]. */\n    val ModalDrawerElevation = ElevationTokens.Level0\n\n    /** Default Elevation for drawer container in the [PermanentNavigationDrawer]. */\n    val PermanentDrawerElevation = NavigationDrawerTokens.StandardContainerElevation\n\n    /** Default Elevation for drawer container in the [DismissibleNavigationDrawer]. */\n    val DismissibleDrawerElevation = NavigationDrawerTokens.StandardContainerElevation\n\n    /** Default shape for a navigation drawer. */\n    val shape: Shape\n        @Composable get() = NavigationDrawerTokens.ContainerShape.value\n\n    /** Default color of the scrim that obscures content when the drawer is open */\n    val scrimColor: Color\n        @Composable get() = ScrimTokens.ContainerColor.value.copy(ScrimTokens.ContainerOpacity)\n\n    /** Default container color for a navigation drawer */\n    @Deprecated(\n        message = \"Please use standardContainerColor or modalContainerColor instead.\",\n        replaceWith = ReplaceWith(\"standardContainerColor\"),\n        level = DeprecationLevel.WARNING,\n    )\n    val containerColor: Color\n        @Composable get() = NavigationDrawerTokens.StandardContainerColor.value\n\n    /**\n     * Default container color for a [DismissibleNavigationDrawer] and [PermanentNavigationDrawer]\n     */\n    val standardContainerColor: Color\n        @Composable get() = NavigationDrawerTokens.StandardContainerColor.value\n\n    /** Default container color for a [ModalNavigationDrawer] */\n    val modalContainerColor: Color\n        @Composable get() = NavigationDrawerTokens.ModalContainerColor.value\n\n    /** Default and maximum width of a navigation drawer */\n    val MaximumDrawerWidth = NavigationDrawerTokens.ContainerWidth\n\n    /** Default window insets for drawer sheets */\n    val windowInsets: WindowInsets\n        @Composable\n        get() =\n            WindowInsets.systemBarsForVisualComponents.only(\n                WindowInsetsSides.Vertical + WindowInsetsSides.Start\n            )\n}\n\n/**\n * Material Design navigation drawer item.\n *\n * A [NavigationDrawerItem] represents a destination within drawers, either [ModalNavigationDrawer],\n * [PermanentNavigationDrawer] or [DismissibleNavigationDrawer].\n *\n * @sample androidx.compose.material3.samples.ModalNavigationDrawerSample\n * @param label text label for this item\n * @param selected whether this item is selected\n * @param onClick called when this item is clicked\n * @param modifier the [Modifier] to be applied to this item\n * @param icon optional icon for this item, typically an [Icon]\n * @param badge optional badge to show on this item from the end side\n * @param shape optional shape for the active indicator\n * @param colors [NavigationDrawerItemColors] that will be used to resolve the colors used for this\n *   item in different states. See [NavigationDrawerItemDefaults.colors].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this item. You can use this to change the item's appearance or\n *   preview the item in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n */\n@Composable\nfun NavigationDrawerItem(\n    label: @Composable () -> Unit,\n    selected: Boolean,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    icon: (@Composable () -> Unit)? = null,\n    badge: (@Composable () -> Unit)? = null,\n    shape: Shape = NavigationDrawerTokens.ActiveIndicatorShape.value,\n    colors: NavigationDrawerItemColors = NavigationDrawerItemDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    Surface(\n        selected = selected,\n        onClick = onClick,\n        modifier =\n            modifier\n                .semantics { role = Role.Tab }\n                .heightIn(min = NavigationDrawerTokens.ActiveIndicatorHeight)\n                .fillMaxWidth(),\n        shape = shape,\n        color = colors.containerColor(selected).value,\n        interactionSource = interactionSource,\n    ) {\n        Row(\n            Modifier.padding(start = 16.dp, end = 24.dp),\n            verticalAlignment = Alignment.CenterVertically,\n        ) {\n            if (icon != null) {\n                val iconColor = colors.iconColor(selected).value\n                CompositionLocalProvider(LocalContentColor provides iconColor, content = icon)\n                Spacer(Modifier.width(12.dp))\n            }\n            Box(Modifier.weight(1f)) {\n                val labelColor = colors.textColor(selected).value\n                CompositionLocalProvider(LocalContentColor provides labelColor, content = label)\n            }\n            if (badge != null) {\n                Spacer(Modifier.width(12.dp))\n                val badgeColor = colors.badgeColor(selected).value\n                CompositionLocalProvider(LocalContentColor provides badgeColor, content = badge)\n            }\n        }\n    }\n}\n\n/** Represents the colors of the various elements of a drawer item. */\n@Stable\ninterface NavigationDrawerItemColors {\n    /**\n     * Represents the icon color for this item, depending on whether it is [selected].\n     *\n     * @param selected whether the item is selected\n     */\n    @Composable fun iconColor(selected: Boolean): State<Color>\n\n    /**\n     * Represents the text color for this item, depending on whether it is [selected].\n     *\n     * @param selected whether the item is selected\n     */\n    @Composable fun textColor(selected: Boolean): State<Color>\n\n    /**\n     * Represents the badge color for this item, depending on whether it is [selected].\n     *\n     * @param selected whether the item is selected\n     */\n    @Composable fun badgeColor(selected: Boolean): State<Color>\n\n    /**\n     * Represents the container color for this item, depending on whether it is [selected].\n     *\n     * @param selected whether the item is selected\n     */\n    @Composable fun containerColor(selected: Boolean): State<Color>\n}\n\n/** Defaults used in [NavigationDrawerItem]. */\nobject NavigationDrawerItemDefaults {\n    /**\n     * Creates a [NavigationDrawerItemColors] with the provided colors according to the Material\n     * specification.\n     *\n     * @param selectedContainerColor the color to use for the background of the item when selected\n     * @param unselectedContainerColor the color to use for the background of the item when\n     *   unselected\n     * @param selectedIconColor the color to use for the icon when the item is selected.\n     * @param unselectedIconColor the color to use for the icon when the item is unselected.\n     * @param selectedTextColor the color to use for the text label when the item is selected.\n     * @param unselectedTextColor the color to use for the text label when the item is unselected.\n     * @param selectedBadgeColor the color to use for the badge when the item is selected.\n     * @param unselectedBadgeColor the color to use for the badge when the item is unselected.\n     * @return the resulting [NavigationDrawerItemColors] used for [NavigationDrawerItem]\n     */\n    @Composable\n    fun colors(\n        selectedContainerColor: Color = NavigationDrawerTokens.ActiveIndicatorColor.value,\n        unselectedContainerColor: Color = Color.Transparent,\n        selectedIconColor: Color = NavigationDrawerTokens.ActiveIconColor.value,\n        unselectedIconColor: Color = NavigationDrawerTokens.InactiveIconColor.value,\n        selectedTextColor: Color = NavigationDrawerTokens.ActiveLabelTextColor.value,\n        unselectedTextColor: Color = NavigationDrawerTokens.InactiveLabelTextColor.value,\n        selectedBadgeColor: Color = selectedTextColor,\n        unselectedBadgeColor: Color = unselectedTextColor,\n    ): NavigationDrawerItemColors =\n        DefaultDrawerItemsColor(\n            selectedIconColor,\n            unselectedIconColor,\n            selectedTextColor,\n            unselectedTextColor,\n            selectedContainerColor,\n            unselectedContainerColor,\n            selectedBadgeColor,\n            unselectedBadgeColor,\n        )\n\n    /**\n     * Default external padding for a [NavigationDrawerItem] according to the Material\n     * specification.\n     */\n    val ItemPadding = PaddingValues(horizontal = 12.dp)\n}\n\n@Stable\ninternal class DrawerPredictiveBackState {\n\n    var swipeEdgeMatchesDrawer by mutableStateOf(true)\n\n    var scaleXDistance by mutableFloatStateOf(0f)\n\n    var scaleYDistance by mutableFloatStateOf(0f)\n\n    fun update(\n        progress: Float,\n        swipeEdgeLeft: Boolean,\n        isRtl: Boolean,\n        maxScaleXDistanceGrow: Float,\n        maxScaleXDistanceShrink: Float,\n        maxScaleYDistance: Float,\n    ) {\n        swipeEdgeMatchesDrawer = swipeEdgeLeft != isRtl\n        val maxScaleXDistance =\n            if (swipeEdgeMatchesDrawer) maxScaleXDistanceGrow else maxScaleXDistanceShrink\n        scaleXDistance = lerp(0f, maxScaleXDistance, progress)\n        scaleYDistance = lerp(0f, maxScaleYDistance, progress)\n    }\n\n    fun clear() {\n        swipeEdgeMatchesDrawer = true\n        scaleXDistance = 0f\n        scaleYDistance = 0f\n    }\n}\n\nprivate class DefaultDrawerItemsColor(\n    val selectedIconColor: Color,\n    val unselectedIconColor: Color,\n    val selectedTextColor: Color,\n    val unselectedTextColor: Color,\n    val selectedContainerColor: Color,\n    val unselectedContainerColor: Color,\n    val selectedBadgeColor: Color,\n    val unselectedBadgeColor: Color,\n) : NavigationDrawerItemColors {\n    @Composable\n    override fun iconColor(selected: Boolean): State<Color> {\n        return rememberUpdatedState(if (selected) selectedIconColor else unselectedIconColor)\n    }\n\n    @Composable\n    override fun textColor(selected: Boolean): State<Color> {\n        return rememberUpdatedState(if (selected) selectedTextColor else unselectedTextColor)\n    }\n\n    @Composable\n    override fun containerColor(selected: Boolean): State<Color> {\n        return rememberUpdatedState(\n            if (selected) selectedContainerColor else unselectedContainerColor\n        )\n    }\n\n    @Composable\n    override fun badgeColor(selected: Boolean): State<Color> {\n        return rememberUpdatedState(if (selected) selectedBadgeColor else unselectedBadgeColor)\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is DefaultDrawerItemsColor) return false\n\n        if (selectedIconColor != other.selectedIconColor) return false\n        if (unselectedIconColor != other.unselectedIconColor) return false\n        if (selectedTextColor != other.selectedTextColor) return false\n        if (unselectedTextColor != other.unselectedTextColor) return false\n        if (selectedContainerColor != other.selectedContainerColor) return false\n        if (unselectedContainerColor != other.unselectedContainerColor) return false\n        if (selectedBadgeColor != other.selectedBadgeColor) return false\n        return unselectedBadgeColor == other.unselectedBadgeColor\n    }\n\n    override fun hashCode(): Int {\n        var result = selectedIconColor.hashCode()\n        result = 31 * result + unselectedIconColor.hashCode()\n        result = 31 * result + selectedTextColor.hashCode()\n        result = 31 * result + unselectedTextColor.hashCode()\n        result = 31 * result + selectedContainerColor.hashCode()\n        result = 31 * result + unselectedContainerColor.hashCode()\n        result = 31 * result + selectedBadgeColor.hashCode()\n        result = 31 * result + unselectedBadgeColor.hashCode()\n        return result\n    }\n}\n\nprivate fun calculateFraction(a: Float, b: Float, pos: Float) =\n    ((pos - a) / (b - a)).coerceIn(0f, 1f)\n\nprivate val DrawerPositionalThreshold = 0.5f\nprivate val DrawerVelocityThreshold = 400.dp\nprivate val MinimumDrawerWidth = 240.dp\n\ninternal val PredictiveBackDrawerMaxScaleXDistanceGrow = 12.dp\ninternal val PredictiveBackDrawerMaxScaleXDistanceShrink = 24.dp\ninternal val PredictiveBackDrawerMaxScaleYDistance = 48.dp\n\n// TODO: b/177571613 this should be a proper decay settling\n// this is taken from the DrawerLayout's DragViewHelper as a min duration.\nprivate val AnchoredDraggableDefaultAnimationSpec = TweenSpec<Float>(durationMillis = 256)\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt\n```kotlin\n/*\n * Copyright 2022 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.animation.VectorConverter\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.AnimationVector1D\nimport androidx.compose.animation.core.AnimationVector4D\nimport androidx.compose.animation.core.VectorConverter\nimport androidx.compose.animation.core.snap\nimport androidx.compose.foundation.ScrollState\nimport androidx.compose.foundation.interaction.FocusInteraction\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.InteractionSource\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsFocusedAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.wrapContentHeight\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.text.BasicTextField\nimport androidx.compose.foundation.text.KeyboardActions\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.foundation.text.input.InputTransformation\nimport androidx.compose.foundation.text.input.KeyboardActionHandler\nimport androidx.compose.foundation.text.input.OutputTransformation\nimport androidx.compose.foundation.text.input.TextFieldLineLimits\nimport androidx.compose.foundation.text.input.TextFieldLineLimits.MultiLine\nimport androidx.compose.foundation.text.input.TextFieldLineLimits.SingleLine\nimport androidx.compose.foundation.text.input.TextFieldState\nimport androidx.compose.foundation.text.selection.LocalTextSelectionColors\nimport androidx.compose.material3.MaterialTheme.LocalMaterialTheme\nimport androidx.compose.material3.TextFieldDefaults.defaultTextFieldColors\nimport androidx.compose.material3.internal.AboveLabelBottomPadding\nimport androidx.compose.material3.internal.AboveLabelHorizontalPadding\nimport androidx.compose.material3.internal.ContainerId\nimport androidx.compose.material3.internal.FloatProducer\nimport androidx.compose.material3.internal.LabelId\nimport androidx.compose.material3.internal.LeadingId\nimport androidx.compose.material3.internal.MinFocusedLabelLineHeight\nimport androidx.compose.material3.internal.MinSupportingTextLineHeight\nimport androidx.compose.material3.internal.MinTextLineHeight\nimport androidx.compose.material3.internal.PlaceholderId\nimport androidx.compose.material3.internal.PrefixId\nimport androidx.compose.material3.internal.PrefixSuffixTextPadding\nimport androidx.compose.material3.internal.Strings\nimport androidx.compose.material3.internal.SuffixId\nimport androidx.compose.material3.internal.SupportingId\nimport androidx.compose.material3.internal.TextFieldId\nimport androidx.compose.material3.internal.TrailingId\nimport androidx.compose.material3.internal.defaultErrorSemantics\nimport androidx.compose.material3.internal.expandedAlignment\nimport androidx.compose.material3.internal.getString\nimport androidx.compose.material3.internal.heightOrZero\nimport androidx.compose.material3.internal.layoutId\nimport androidx.compose.material3.internal.minimizedAlignment\nimport androidx.compose.material3.internal.minimizedLabelHalfHeight\nimport androidx.compose.material3.internal.subtractConstraintSafely\nimport androidx.compose.material3.internal.textFieldHorizontalIconPadding\nimport androidx.compose.material3.internal.textFieldLabelMinHeight\nimport androidx.compose.material3.internal.widthOrZero\nimport androidx.compose.material3.tokens.FilledTextFieldTokens\nimport androidx.compose.material3.tokens.MotionSchemeKeyTokens\nimport androidx.compose.material3.tokens.MotionTokens.EasingEmphasizedAccelerateCubicBezier\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.CacheDrawModifierNode\nimport androidx.compose.ui.geometry.Rect\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.addOutline\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.layout.IntrinsicMeasurable\nimport androidx.compose.ui.layout.IntrinsicMeasureScope\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.Measurable\nimport androidx.compose.ui.layout.MeasurePolicy\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.layout.layoutId\nimport androidx.compose.ui.node.CompositionLocalConsumerModifierNode\nimport androidx.compose.ui.node.DelegatingNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.node.currentValueOf\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.text.TextLayoutResult\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.text.input.TextFieldValue\nimport androidx.compose.ui.text.input.VisualTransformation\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.coerceAtLeast\nimport androidx.compose.ui.unit.constrainHeight\nimport androidx.compose.ui.unit.constrainWidth\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.lerp\nimport androidx.compose.ui.unit.offset\nimport androidx.compose.ui.util.fastFirst\nimport androidx.compose.ui.util.fastFirstOrNull\nimport androidx.compose.ui.util.lerp\nimport kotlin.math.max\nimport kotlin.math.roundToInt\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.launch\n\n/**\n * [Material Design filled text field](https://m3.material.io/components/text-fields/overview)\n *\n * Text fields allow users to enter text into a UI. They typically appear in forms and dialogs.\n * Filled text fields have more visual emphasis than outlined text fields, making them stand out\n * when surrounded by other content and components.\n *\n * ![Filled text field\n * image](https://developer.android.com/images/reference/androidx/compose/material3/filled-text-field.png)\n *\n * If you are looking for an outlined version, see [OutlinedTextField]. For a text field\n * specifically designed for passwords or other secure content, see [SecureTextField].\n *\n * This overload of [TextField] uses [TextFieldState] to keep track of its text content and position\n * of the cursor or selection.\n *\n * A simple single line text field looks like:\n *\n * @sample androidx.compose.material3.samples.SimpleTextFieldSample\n *\n * You can control the initial text input and selection:\n *\n * @sample androidx.compose.material3.samples.TextFieldWithInitialValueAndSelection\n *\n * Use input and output transformations to control user input and the displayed text:\n *\n * @sample androidx.compose.material3.samples.TextFieldWithTransformations\n *\n * You may provide a placeholder:\n *\n * @sample androidx.compose.material3.samples.TextFieldWithPlaceholder\n *\n * You can also provide leading and trailing icons:\n *\n * @sample androidx.compose.material3.samples.TextFieldWithIcons\n *\n * You can also provide a prefix or suffix to the text:\n *\n * @sample androidx.compose.material3.samples.TextFieldWithPrefixAndSuffix\n *\n * To handle the error input state, use [isError] parameter:\n *\n * @sample androidx.compose.material3.samples.TextFieldWithErrorState\n *\n * Additionally, you may provide additional message at the bottom:\n *\n * @sample androidx.compose.material3.samples.TextFieldWithSupportingText\n *\n * You can change the content padding to create a dense text field:\n *\n * @sample androidx.compose.material3.samples.DenseTextFieldContentPadding\n *\n * Hiding a software keyboard on IME action performed:\n *\n * @sample androidx.compose.material3.samples.TextFieldWithHideKeyboardOnImeAction\n * @param state [TextFieldState] object that holds the internal editing state of the text field.\n * @param modifier the [Modifier] to be applied to this text field.\n * @param enabled controls the enabled state of this text field. When `false`, this component will\n *   not respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param readOnly controls the editable state of the text field. When `true`, the text field cannot\n *   be modified. However, a user can focus it and copy text from it. Read-only text fields are\n *   usually used to display pre-filled forms that a user cannot edit.\n * @param textStyle the style to be applied to the input text. Defaults to [LocalTextStyle].\n * @param labelPosition the position of the label. See [TextFieldLabelPosition].\n * @param label the optional label to be displayed with this text field. The default text style uses\n *   [Typography.bodySmall] when minimized and [Typography.bodyLarge] when expanded.\n * @param placeholder the optional placeholder to be displayed when the input text is empty. The\n *   default text style uses [Typography.bodyLarge].\n * @param leadingIcon the optional leading icon to be displayed at the beginning of the text field\n *   container.\n * @param trailingIcon the optional trailing icon to be displayed at the end of the text field\n *   container.\n * @param prefix the optional prefix to be displayed before the input text in the text field.\n * @param suffix the optional suffix to be displayed after the input text in the text field.\n * @param supportingText the optional supporting text to be displayed below the text field.\n * @param isError indicates if the text field's current value is in error. When `true`, the\n *   components of the text field will be displayed in an error color, and an error will be\n *   announced to accessibility services.\n * @param inputTransformation optional [InputTransformation] that will be used to transform changes\n *   to the [TextFieldState] made by the user. The transformation will be applied to changes made by\n *   hardware and software keyboard events, pasting or dropping text, accessibility services, and\n *   tests. The transformation will _not_ be applied when changing the [state] programmatically, or\n *   when the transformation is changed. If the transformation is changed on an existing text field,\n *   it will be applied to the next user edit. The transformation will not immediately affect the\n *   current [state].\n * @param outputTransformation optional [OutputTransformation] that transforms how the contents of\n *   the text field are presented.\n * @param keyboardOptions software keyboard options that contains configuration such as\n *   [KeyboardType] and [ImeAction].\n * @param onKeyboardAction called when the user presses the action button in the input method editor\n *   (IME), or by pressing the enter key on a hardware keyboard. By default this parameter is null,\n *   and would execute the default behavior for a received IME Action e.g., [ImeAction.Done] would\n *   close the keyboard, [ImeAction.Next] would switch the focus to the next focusable item on the\n *   screen.\n * @param lineLimits whether the text field should be [SingleLine], scroll horizontally, and ignore\n *   newlines; or [MultiLine] and grow and scroll vertically. If [SingleLine] is passed, all newline\n *   characters ('\\n') within the text will be replaced with regular whitespace (' ').\n * @param onTextLayout Callback that is executed when the text layout becomes queryable. The\n *   callback receives a function that returns a [TextLayoutResult] if the layout can be calculated,\n *   or null if it cannot. The function reads the layout result from a snapshot state object, and\n *   will invalidate its caller when the layout result changes. A [TextLayoutResult] object contains\n *   paragraph information, size of the text, baselines and other details. [Density] scope is the\n *   one that was used while creating the given text layout.\n * @param scrollState scroll state that manages either horizontal or vertical scroll of the text\n *   field. If [lineLimits] is [SingleLine], this text field is treated as single line with\n *   horizontal scroll behavior. Otherwise, the text field becomes vertically scrollable.\n * @param shape defines the shape of this text field's container.\n * @param colors [TextFieldColors] that will be used to resolve the colors used for this text field\n *   in different states. See [TextFieldDefaults.colors].\n * @param contentPadding the padding applied to the inner text field that separates it from the\n *   surrounding elements of the text field. Note that the padding values may not be respected if\n *   they are incompatible with the text field's size constraints or layout. See\n *   [TextFieldDefaults.contentPaddingWithLabel] and [TextFieldDefaults.contentPaddingWithoutLabel].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this text field. You can use this to change the text field's\n *   appearance or preview the text field in different states. Note that if `null` is provided,\n *   interactions will still happen internally.\n */\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun TextField(\n    state: TextFieldState,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    readOnly: Boolean = false,\n    textStyle: TextStyle = LocalTextStyle.current,\n    labelPosition: TextFieldLabelPosition = TextFieldLabelPosition.Attached(),\n    label: @Composable (TextFieldLabelScope.() -> Unit)? = null,\n    placeholder: @Composable (() -> Unit)? = null,\n    leadingIcon: @Composable (() -> Unit)? = null,\n    trailingIcon: @Composable (() -> Unit)? = null,\n    prefix: @Composable (() -> Unit)? = null,\n    suffix: @Composable (() -> Unit)? = null,\n    supportingText: @Composable (() -> Unit)? = null,\n    isError: Boolean = false,\n    inputTransformation: InputTransformation? = null,\n    outputTransformation: OutputTransformation? = null,\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,\n    onKeyboardAction: KeyboardActionHandler? = null,\n    lineLimits: TextFieldLineLimits = TextFieldLineLimits.Default,\n    onTextLayout: (Density.(getResult: () -> TextLayoutResult?) -> Unit)? = null,\n    scrollState: ScrollState = rememberScrollState(),\n    shape: Shape = TextFieldDefaults.shape,\n    colors: TextFieldColors = TextFieldDefaults.colors(),\n    contentPadding: PaddingValues =\n        if (label == null || labelPosition is TextFieldLabelPosition.Above) {\n            TextFieldDefaults.contentPaddingWithoutLabel()\n        } else {\n            TextFieldDefaults.contentPaddingWithLabel()\n        },\n    interactionSource: MutableInteractionSource? = null,\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    // If color is not provided via the text style, use content color as a default\n    val textColor =\n        textStyle.color.takeOrElse {\n            val focused = interactionSource.collectIsFocusedAsState().value\n            colors.textColor(enabled, isError, focused)\n        }\n    val mergedTextStyle = textStyle.merge(TextStyle(color = textColor))\n\n    CompositionLocalProvider(LocalTextSelectionColors provides colors.textSelectionColors) {\n        BasicTextField(\n            state = state,\n            modifier =\n                modifier\n                    .defaultErrorSemantics(isError, getString(Strings.DefaultErrorMessage))\n                    .defaultMinSize(\n                        minWidth = TextFieldDefaults.MinWidth,\n                        minHeight = TextFieldDefaults.MinHeight,\n                    ),\n            enabled = enabled,\n            readOnly = readOnly,\n            textStyle = mergedTextStyle,\n            cursorBrush = SolidColor(colors.cursorColor(isError)),\n            keyboardOptions = keyboardOptions,\n            onKeyboardAction = onKeyboardAction,\n            lineLimits = lineLimits,\n            onTextLayout = onTextLayout,\n            interactionSource = interactionSource,\n            inputTransformation = inputTransformation,\n            outputTransformation = outputTransformation,\n            scrollState = scrollState,\n            decorator =\n                TextFieldDefaults.decorator(\n                    state = state,\n                    enabled = enabled,\n                    lineLimits = lineLimits,\n                    outputTransformation = outputTransformation,\n                    interactionSource = interactionSource,\n                    labelPosition = labelPosition,\n                    label = label,\n                    placeholder = placeholder,\n                    leadingIcon = leadingIcon,\n                    trailingIcon = trailingIcon,\n                    prefix = prefix,\n                    suffix = suffix,\n                    supportingText = supportingText,\n                    isError = isError,\n                    colors = colors,\n                    contentPadding = contentPadding,\n                    container = {\n                        TextFieldDefaults.Container(\n                            enabled = enabled,\n                            isError = isError,\n                            interactionSource = interactionSource,\n                            colors = colors,\n                            shape = shape,\n                        )\n                    },\n                ),\n        )\n    }\n}\n\n/**\n * [Material Design filled text field](https://m3.material.io/components/text-fields/overview)\n *\n * Text fields allow users to enter text into a UI. They typically appear in forms and dialogs.\n * Filled text fields have more visual emphasis than outlined text fields, making them stand out\n * when surrounded by other content and components.\n *\n * ![Filled text field\n * image](https://developer.android.com/images/reference/androidx/compose/material3/filled-text-field.png)\n *\n * If you are looking for an outlined version, see [OutlinedTextField].\n *\n * If apart from input text change you also want to observe the cursor location, selection range, or\n * IME composition use the TextField overload with the [TextFieldValue] parameter instead.\n *\n * @param value the input text to be shown in the text field\n * @param onValueChange the callback that is triggered when the input service updates the text. An\n *   updated text comes as a parameter of the callback\n * @param modifier the [Modifier] to be applied to this text field\n * @param enabled controls the enabled state of this text field. When `false`, this component will\n *   not respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param readOnly controls the editable state of the text field. When `true`, the text field cannot\n *   be modified. However, a user can focus it and copy text from it. Read-only text fields are\n *   usually used to display pre-filled forms that a user cannot edit.\n * @param textStyle the style to be applied to the input text. Defaults to [LocalTextStyle].\n * @param label the optional label to be displayed with this text field. The default text style uses\n *   [Typography.bodySmall] when minimized and [Typography.bodyLarge] when expanded.\n * @param placeholder the optional placeholder to be displayed when the text field is in focus and\n *   the input text is empty. The default text style for internal [Text] is [Typography.bodyLarge]\n * @param leadingIcon the optional leading icon to be displayed at the beginning of the text field\n *   container\n * @param trailingIcon the optional trailing icon to be displayed at the end of the text field\n *   container\n * @param prefix the optional prefix to be displayed before the input text in the text field\n * @param suffix the optional suffix to be displayed after the input text in the text field\n * @param supportingText the optional supporting text to be displayed below the text field\n * @param isError indicates if the text field's current value is in error. If set to true, the\n *   label, bottom indicator and trailing icon by default will be displayed in error color\n * @param visualTransformation transforms the visual representation of the input [value] For\n *   example, you can use\n *   [PasswordVisualTransformation][androidx.compose.ui.text.input.PasswordVisualTransformation] to\n *   create a password text field. By default, no visual transformation is applied.\n * @param keyboardOptions software keyboard options that contains configuration such as\n *   [KeyboardType] and [ImeAction].\n * @param keyboardActions when the input service emits an IME action, the corresponding callback is\n *   called. Note that this IME action may be different from what you specified in\n *   [KeyboardOptions.imeAction].\n * @param singleLine when `true`, this text field becomes a single horizontally scrolling text field\n *   instead of wrapping onto multiple lines. The keyboard will be informed to not show the return\n *   key as the [ImeAction]. Note that [maxLines] parameter will be ignored as the maxLines\n *   attribute will be automatically set to 1.\n * @param maxLines the maximum height in terms of maximum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.\n * @param minLines the minimum height in terms of minimum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this text field. You can use this to change the text field's\n *   appearance or preview the text field in different states. Note that if `null` is provided,\n *   interactions will still happen internally.\n * @param shape defines the shape of this text field's container\n * @param colors [TextFieldColors] that will be used to resolve the colors used for this text field\n *   in different states. See [TextFieldDefaults.colors].\n */\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun TextField(\n    value: String,\n    onValueChange: (String) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    readOnly: Boolean = false,\n    textStyle: TextStyle = LocalTextStyle.current,\n    label: @Composable (() -> Unit)? = null,\n    placeholder: @Composable (() -> Unit)? = null,\n    leadingIcon: @Composable (() -> Unit)? = null,\n    trailingIcon: @Composable (() -> Unit)? = null,\n    prefix: @Composable (() -> Unit)? = null,\n    suffix: @Composable (() -> Unit)? = null,\n    supportingText: @Composable (() -> Unit)? = null,\n    isError: Boolean = false,\n    visualTransformation: VisualTransformation = VisualTransformation.None,\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,\n    keyboardActions: KeyboardActions = KeyboardActions.Default,\n    singleLine: Boolean = false,\n    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,\n    minLines: Int = 1,\n    interactionSource: MutableInteractionSource? = null,\n    shape: Shape = TextFieldDefaults.shape,\n    colors: TextFieldColors = TextFieldDefaults.colors(),\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    // If color is not provided via the text style, use content color as a default\n    val textColor =\n        textStyle.color.takeOrElse {\n            val focused = interactionSource.collectIsFocusedAsState().value\n            colors.textColor(enabled, isError, focused)\n        }\n    val mergedTextStyle = textStyle.merge(TextStyle(color = textColor))\n\n    CompositionLocalProvider(LocalTextSelectionColors provides colors.textSelectionColors) {\n        BasicTextField(\n            value = value,\n            modifier =\n                modifier\n                    .defaultErrorSemantics(isError, getString(Strings.DefaultErrorMessage))\n                    .defaultMinSize(\n                        minWidth = TextFieldDefaults.MinWidth,\n                        minHeight = TextFieldDefaults.MinHeight,\n                    ),\n            onValueChange = onValueChange,\n            enabled = enabled,\n            readOnly = readOnly,\n            textStyle = mergedTextStyle,\n            cursorBrush = SolidColor(colors.cursorColor(isError)),\n            visualTransformation = visualTransformation,\n            keyboardOptions = keyboardOptions,\n            keyboardActions = keyboardActions,\n            interactionSource = interactionSource,\n            singleLine = singleLine,\n            maxLines = maxLines,\n            minLines = minLines,\n            decorationBox =\n                @Composable { innerTextField ->\n                    // places leading icon, text field with label and placeholder, trailing icon\n                    TextFieldDefaults.DecorationBox(\n                        value = value,\n                        visualTransformation = visualTransformation,\n                        innerTextField = innerTextField,\n                        placeholder = placeholder,\n                        label = label,\n                        leadingIcon = leadingIcon,\n                        trailingIcon = trailingIcon,\n                        prefix = prefix,\n                        suffix = suffix,\n                        supportingText = supportingText,\n                        shape = shape,\n                        singleLine = singleLine,\n                        enabled = enabled,\n                        isError = isError,\n                        interactionSource = interactionSource,\n                        colors = colors,\n                    )\n                },\n        )\n    }\n}\n\n/**\n * [Material Design filled text field](https://m3.material.io/components/text-fields/overview)\n *\n * Text fields allow users to enter text into a UI. They typically appear in forms and dialogs.\n * Filled text fields have more visual emphasis than outlined text fields, making them stand out\n * when surrounded by other content and components.\n *\n * ![Filled text field\n * image](https://developer.android.com/images/reference/androidx/compose/material3/filled-text-field.png)\n *\n * If you are looking for an outlined version, see [OutlinedTextField].\n *\n * This overload provides access to the input text, cursor position, selection range and IME\n * composition. If you only want to observe an input text change, use the TextField overload with\n * the [String] parameter instead.\n *\n * @param value the input [TextFieldValue] to be shown in the text field\n * @param onValueChange the callback that is triggered when the input service updates values in\n *   [TextFieldValue]. An updated [TextFieldValue] comes as a parameter of the callback\n * @param modifier the [Modifier] to be applied to this text field\n * @param enabled controls the enabled state of this text field. When `false`, this component will\n *   not respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param readOnly controls the editable state of the text field. When `true`, the text field cannot\n *   be modified. However, a user can focus it and copy text from it. Read-only text fields are\n *   usually used to display pre-filled forms that a user cannot edit.\n * @param textStyle the style to be applied to the input text. Defaults to [LocalTextStyle].\n * @param label the optional label to be displayed with this text field. The default text style uses\n *   [Typography.bodySmall] when minimized and [Typography.bodyLarge] when expanded.\n * @param placeholder the optional placeholder to be displayed when the text field is in focus and\n *   the input text is empty. The default text style for internal [Text] is [Typography.bodyLarge]\n * @param leadingIcon the optional leading icon to be displayed at the beginning of the text field\n *   container\n * @param trailingIcon the optional trailing icon to be displayed at the end of the text field\n *   container\n * @param prefix the optional prefix to be displayed before the input text in the text field\n * @param suffix the optional suffix to be displayed after the input text in the text field\n * @param supportingText the optional supporting text to be displayed below the text field\n * @param isError indicates if the text field's current value is in error state. If set to true, the\n *   label, bottom indicator and trailing icon by default will be displayed in error color\n * @param visualTransformation transforms the visual representation of the input [value]. For\n *   example, you can use\n *   [PasswordVisualTransformation][androidx.compose.ui.text.input.PasswordVisualTransformation] to\n *   create a password text field. By default, no visual transformation is applied.\n * @param keyboardOptions software keyboard options that contains configuration such as\n *   [KeyboardType] and [ImeAction].\n * @param keyboardActions when the input service emits an IME action, the corresponding callback is\n *   called. Note that this IME action may be different from what you specified in\n *   [KeyboardOptions.imeAction].\n * @param singleLine when `true`, this text field becomes a single horizontally scrolling text field\n *   instead of wrapping onto multiple lines. The keyboard will be informed to not show the return\n *   key as the [ImeAction]. Note that [maxLines] parameter will be ignored as the maxLines\n *   attribute will be automatically set to 1.\n * @param maxLines the maximum height in terms of maximum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.\n * @param minLines the minimum height in terms of minimum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this text field. You can use this to change the text field's\n *   appearance or preview the text field in different states. Note that if `null` is provided,\n *   interactions will still happen internally.\n * @param shape defines the shape of this text field's container\n * @param colors [TextFieldColors] that will be used to resolve the colors used for this text field\n *   in different states. See [TextFieldDefaults.colors].\n */\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun TextField(\n    value: TextFieldValue,\n    onValueChange: (TextFieldValue) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    readOnly: Boolean = false,\n    textStyle: TextStyle = LocalTextStyle.current,\n    label: @Composable (() -> Unit)? = null,\n    placeholder: @Composable (() -> Unit)? = null,\n    leadingIcon: @Composable (() -> Unit)? = null,\n    trailingIcon: @Composable (() -> Unit)? = null,\n    prefix: @Composable (() -> Unit)? = null,\n    suffix: @Composable (() -> Unit)? = null,\n    supportingText: @Composable (() -> Unit)? = null,\n    isError: Boolean = false,\n    visualTransformation: VisualTransformation = VisualTransformation.None,\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,\n    keyboardActions: KeyboardActions = KeyboardActions.Default,\n    singleLine: Boolean = false,\n    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,\n    minLines: Int = 1,\n    interactionSource: MutableInteractionSource? = null,\n    shape: Shape = TextFieldDefaults.shape,\n    colors: TextFieldColors = TextFieldDefaults.colors(),\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    // If color is not provided via the text style, use content color as a default\n    val textColor =\n        textStyle.color.takeOrElse {\n            val focused = interactionSource.collectIsFocusedAsState().value\n            colors.textColor(enabled, isError, focused)\n        }\n    val mergedTextStyle = textStyle.merge(TextStyle(color = textColor))\n\n    CompositionLocalProvider(LocalTextSelectionColors provides colors.textSelectionColors) {\n        BasicTextField(\n            value = value,\n            modifier =\n                modifier\n                    .defaultErrorSemantics(isError, getString(Strings.DefaultErrorMessage))\n                    .defaultMinSize(\n                        minWidth = TextFieldDefaults.MinWidth,\n                        minHeight = TextFieldDefaults.MinHeight,\n                    ),\n            onValueChange = onValueChange,\n            enabled = enabled,\n            readOnly = readOnly,\n            textStyle = mergedTextStyle,\n            cursorBrush = SolidColor(colors.cursorColor(isError)),\n            visualTransformation = visualTransformation,\n            keyboardOptions = keyboardOptions,\n            keyboardActions = keyboardActions,\n            interactionSource = interactionSource,\n            singleLine = singleLine,\n            maxLines = maxLines,\n            minLines = minLines,\n            decorationBox =\n                @Composable { innerTextField ->\n                    // places leading icon, text field with label and placeholder, trailing icon\n                    TextFieldDefaults.DecorationBox(\n                        value = value.text,\n                        visualTransformation = visualTransformation,\n                        innerTextField = innerTextField,\n                        placeholder = placeholder,\n                        label = label,\n                        leadingIcon = leadingIcon,\n                        trailingIcon = trailingIcon,\n                        prefix = prefix,\n                        suffix = suffix,\n                        supportingText = supportingText,\n                        shape = shape,\n                        singleLine = singleLine,\n                        enabled = enabled,\n                        isError = isError,\n                        interactionSource = interactionSource,\n                        colors = colors,\n                    )\n                },\n        )\n    }\n}\n\n/**\n * Composable responsible for measuring and laying out leading and trailing icons, label,\n * placeholder and the input field.\n */\n@Composable\ninternal fun TextFieldLayout(\n    modifier: Modifier,\n    textField: @Composable () -> Unit,\n    label: @Composable (() -> Unit)?,\n    placeholder: @Composable ((Modifier) -> Unit)?,\n    leading: @Composable (() -> Unit)?,\n    trailing: @Composable (() -> Unit)?,\n    prefix: @Composable (() -> Unit)?,\n    suffix: @Composable (() -> Unit)?,\n    singleLine: Boolean,\n    labelPosition: TextFieldLabelPosition,\n    labelProgress: FloatProducer,\n    container: @Composable () -> Unit,\n    supporting: @Composable (() -> Unit)?,\n    paddingValues: PaddingValues,\n) {\n    val minimizedLabelHalfHeight = minimizedLabelHalfHeight()\n    val measurePolicy =\n        remember(\n            singleLine,\n            labelPosition,\n            labelProgress,\n            paddingValues,\n            minimizedLabelHalfHeight,\n        ) {\n            TextFieldMeasurePolicy(\n                singleLine = singleLine,\n                labelPosition = labelPosition,\n                labelProgress = labelProgress,\n                paddingValues = paddingValues,\n                minimizedLabelHalfHeight = minimizedLabelHalfHeight,\n            )\n        }\n    val layoutDirection = LocalLayoutDirection.current\n    Layout(\n        modifier = modifier,\n        content = {\n            // The container is given as a Composable instead of a background modifier so that\n            // elements like supporting text can be placed outside of it while still contributing\n            // to the text field's measurements overall.\n            container()\n\n            if (leading != null) {\n                Box(\n                    modifier = Modifier.layoutId(LeadingId).minimumInteractiveComponentSize(),\n                    contentAlignment = Alignment.Center,\n                ) {\n                    leading()\n                }\n            }\n            if (trailing != null) {\n                Box(\n                    modifier = Modifier.layoutId(TrailingId).minimumInteractiveComponentSize(),\n                    contentAlignment = Alignment.Center,\n                ) {\n                    trailing()\n                }\n            }\n\n            val startTextFieldPadding = paddingValues.calculateStartPadding(layoutDirection)\n            val endTextFieldPadding = paddingValues.calculateEndPadding(layoutDirection)\n\n            val horizontalIconPadding = textFieldHorizontalIconPadding()\n            val startPadding =\n                if (leading != null) {\n                    (startTextFieldPadding - horizontalIconPadding).coerceAtLeast(0.dp)\n                } else {\n                    startTextFieldPadding\n                }\n            val endPadding =\n                if (trailing != null) {\n                    (endTextFieldPadding - horizontalIconPadding).coerceAtLeast(0.dp)\n                } else {\n                    endTextFieldPadding\n                }\n\n            if (prefix != null) {\n                Box(\n                    Modifier.layoutId(PrefixId)\n                        .heightIn(min = MinTextLineHeight)\n                        .wrapContentHeight()\n                        .padding(start = startPadding, end = PrefixSuffixTextPadding)\n                ) {\n                    prefix()\n                }\n            }\n            if (suffix != null) {\n                Box(\n                    Modifier.layoutId(SuffixId)\n                        .heightIn(min = MinTextLineHeight)\n                        .wrapContentHeight()\n                        .padding(start = PrefixSuffixTextPadding, end = endPadding)\n                ) {\n                    suffix()\n                }\n            }\n\n            val labelPadding =\n                if (labelPosition is TextFieldLabelPosition.Above) {\n                    Modifier.padding(\n                        start = AboveLabelHorizontalPadding,\n                        end = AboveLabelHorizontalPadding,\n                        bottom = AboveLabelBottomPadding,\n                    )\n                } else {\n                    Modifier.padding(start = startPadding, end = endPadding)\n                }\n            if (label != null) {\n                Box(\n                    Modifier.layoutId(LabelId)\n                        .textFieldLabelMinHeight {\n                            lerp(MinTextLineHeight, MinFocusedLabelLineHeight, labelProgress())\n                        }\n                        .wrapContentHeight()\n                        .then(labelPadding)\n                ) {\n                    label()\n                }\n            }\n\n            val textPadding =\n                Modifier.heightIn(min = MinTextLineHeight)\n                    .wrapContentHeight()\n                    .padding(\n                        start = if (prefix == null) startPadding else 0.dp,\n                        end = if (suffix == null) endPadding else 0.dp,\n                    )\n\n            if (placeholder != null) {\n                placeholder(Modifier.layoutId(PlaceholderId).then(textPadding))\n            }\n            Box(\n                modifier = Modifier.layoutId(TextFieldId).then(textPadding),\n                propagateMinConstraints = true,\n            ) {\n                textField()\n            }\n\n            if (supporting != null) {\n                @OptIn(ExperimentalMaterial3Api::class)\n                Box(\n                    Modifier.layoutId(SupportingId)\n                        .heightIn(min = MinSupportingTextLineHeight)\n                        .wrapContentHeight()\n                        .padding(TextFieldDefaults.supportingTextPadding())\n                ) {\n                    supporting()\n                }\n            }\n        },\n        measurePolicy = measurePolicy,\n    )\n}\n\nprivate class TextFieldMeasurePolicy(\n    private val singleLine: Boolean,\n    private val labelPosition: TextFieldLabelPosition,\n    private val labelProgress: FloatProducer,\n    private val paddingValues: PaddingValues,\n    private val minimizedLabelHalfHeight: Dp,\n) : MeasurePolicy {\n    override fun MeasureScope.measure(\n        measurables: List<Measurable>,\n        constraints: Constraints,\n    ): MeasureResult {\n        val labelProgress = labelProgress()\n        val topPaddingValue = paddingValues.calculateTopPadding().roundToPx()\n        val bottomPaddingValue = paddingValues.calculateBottomPadding().roundToPx()\n\n        var occupiedSpaceHorizontally = 0\n        var occupiedSpaceVertically = 0\n\n        val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)\n\n        // measure leading icon\n        val leadingPlaceable =\n            measurables.fastFirstOrNull { it.layoutId == LeadingId }?.measure(looseConstraints)\n        occupiedSpaceHorizontally += leadingPlaceable.widthOrZero\n        occupiedSpaceVertically = max(occupiedSpaceVertically, leadingPlaceable.heightOrZero)\n\n        // measure trailing icon\n        val trailingPlaceable =\n            measurables\n                .fastFirstOrNull { it.layoutId == TrailingId }\n                ?.measure(looseConstraints.offset(horizontal = -occupiedSpaceHorizontally))\n        occupiedSpaceHorizontally += trailingPlaceable.widthOrZero\n        occupiedSpaceVertically = max(occupiedSpaceVertically, trailingPlaceable.heightOrZero)\n\n        // measure prefix\n        val prefixPlaceable =\n            measurables\n                .fastFirstOrNull { it.layoutId == PrefixId }\n                ?.measure(looseConstraints.offset(horizontal = -occupiedSpaceHorizontally))\n        occupiedSpaceHorizontally += prefixPlaceable.widthOrZero\n        occupiedSpaceVertically = max(occupiedSpaceVertically, prefixPlaceable.heightOrZero)\n\n        // measure suffix\n        val suffixPlaceable =\n            measurables\n                .fastFirstOrNull { it.layoutId == SuffixId }\n                ?.measure(looseConstraints.offset(horizontal = -occupiedSpaceHorizontally))\n        occupiedSpaceHorizontally += suffixPlaceable.widthOrZero\n        occupiedSpaceVertically = max(occupiedSpaceVertically, suffixPlaceable.heightOrZero)\n\n        val isLabelAbove = labelPosition is TextFieldLabelPosition.Above\n        val labelMeasurable = measurables.fastFirstOrNull { it.layoutId == LabelId }\n        var labelPlaceable: Placeable? = null\n        val labelIntrinsicHeight: Int\n        if (!isLabelAbove) {\n            // if label is not Above, we can measure it like normal\n            val labelConstraints =\n                looseConstraints.offset(\n                    vertical = -bottomPaddingValue,\n                    horizontal = -occupiedSpaceHorizontally,\n                )\n            labelPlaceable = labelMeasurable?.measure(labelConstraints)\n            labelIntrinsicHeight = 0\n        } else {\n            // if label is Above, it must be measured after other elements, but we\n            // reserve space for it using its intrinsic height as a heuristic\n            labelIntrinsicHeight = labelMeasurable?.minIntrinsicHeight(constraints.minWidth) ?: 0\n        }\n\n        // supporting text must be measured after other elements, but we\n        // reserve space for it using its intrinsic height as a heuristic\n        val supportingMeasurable = measurables.fastFirstOrNull { it.layoutId == SupportingId }\n        val supportingIntrinsicHeight =\n            supportingMeasurable?.minIntrinsicHeight(constraints.minWidth) ?: 0\n\n        // at most one of these is non-zero\n        val labelHeightOrIntrinsic = labelPlaceable.heightOrZero + labelIntrinsicHeight\n\n        // measure input field\n        val effectiveTopOffset = topPaddingValue + labelHeightOrIntrinsic\n        val textFieldConstraints =\n            constraints\n                .copy(minHeight = 0)\n                .offset(\n                    vertical = -effectiveTopOffset - bottomPaddingValue - supportingIntrinsicHeight,\n                    horizontal = -occupiedSpaceHorizontally,\n                )\n        val textFieldPlaceable =\n            measurables.fastFirst { it.layoutId == TextFieldId }.measure(textFieldConstraints)\n\n        // measure placeholder\n        val placeholderConstraints = textFieldConstraints.copy(minWidth = 0)\n        val placeholderPlaceable =\n            measurables\n                .fastFirstOrNull { it.layoutId == PlaceholderId }\n                ?.measure(placeholderConstraints)\n\n        occupiedSpaceVertically =\n            max(\n                occupiedSpaceVertically,\n                max(textFieldPlaceable.heightOrZero, placeholderPlaceable.heightOrZero) +\n                    effectiveTopOffset +\n                    bottomPaddingValue,\n            )\n        val width =\n            calculateWidth(\n                leadingWidth = leadingPlaceable.widthOrZero,\n                trailingWidth = trailingPlaceable.widthOrZero,\n                prefixWidth = prefixPlaceable.widthOrZero,\n                suffixWidth = suffixPlaceable.widthOrZero,\n                textFieldWidth = textFieldPlaceable.width,\n                labelWidth = labelPlaceable.widthOrZero,\n                placeholderWidth = placeholderPlaceable.widthOrZero,\n                constraints = constraints,\n            )\n\n        if (isLabelAbove) {\n            // now that we know the width, measure label\n            val labelConstraints =\n                looseConstraints.copy(maxHeight = labelIntrinsicHeight, maxWidth = width)\n            labelPlaceable = labelMeasurable?.measure(labelConstraints)\n        }\n\n        // measure supporting text\n        val supportingConstraints =\n            looseConstraints\n                .offset(vertical = -occupiedSpaceVertically)\n                .copy(minHeight = 0, maxWidth = width)\n        val supportingPlaceable = supportingMeasurable?.measure(supportingConstraints)\n        val supportingHeight = supportingPlaceable.heightOrZero\n\n        val totalHeight =\n            calculateHeight(\n                textFieldHeight = textFieldPlaceable.height,\n                labelHeight = labelPlaceable.heightOrZero,\n                leadingHeight = leadingPlaceable.heightOrZero,\n                trailingHeight = trailingPlaceable.heightOrZero,\n                prefixHeight = prefixPlaceable.heightOrZero,\n                suffixHeight = suffixPlaceable.heightOrZero,\n                placeholderHeight = placeholderPlaceable.heightOrZero,\n                supportingHeight = supportingPlaceable.heightOrZero,\n                constraints = constraints,\n                isLabelAbove = isLabelAbove,\n                labelProgress = labelProgress,\n            )\n        val height =\n            totalHeight - supportingHeight - (if (isLabelAbove) labelPlaceable.heightOrZero else 0)\n\n        val containerPlaceable =\n            measurables\n                .fastFirst { it.layoutId == ContainerId }\n                .measure(\n                    Constraints(\n                        minWidth = if (width != Constraints.Infinity) width else 0,\n                        maxWidth = width,\n                        minHeight = if (height != Constraints.Infinity) height else 0,\n                        maxHeight = height,\n                    )\n                )\n\n        return layout(width, totalHeight) {\n            if (labelPlaceable != null) {\n                val labelStartY =\n                    when {\n                        isLabelAbove -> 0\n                        singleLine ->\n                            Alignment.CenterVertically.align(labelPlaceable.height, height)\n                        else ->\n                            // The padding defined by the user only applies to the text field when\n                            // the label is focused. More padding needs to be added when the text\n                            // field is unfocused.\n                            topPaddingValue + minimizedLabelHalfHeight.roundToPx()\n                    }\n                val labelEndY =\n                    when {\n                        isLabelAbove -> 0\n                        else -> topPaddingValue\n                    }\n                placeWithLabel(\n                    width = width,\n                    totalHeight = totalHeight,\n                    textfieldPlaceable = textFieldPlaceable,\n                    labelPlaceable = labelPlaceable,\n                    placeholderPlaceable = placeholderPlaceable,\n                    leadingPlaceable = leadingPlaceable,\n                    trailingPlaceable = trailingPlaceable,\n                    prefixPlaceable = prefixPlaceable,\n                    suffixPlaceable = suffixPlaceable,\n                    containerPlaceable = containerPlaceable,\n                    supportingPlaceable = supportingPlaceable,\n                    labelStartY = labelStartY,\n                    labelEndY = labelEndY,\n                    isLabelAbove = isLabelAbove,\n                    labelProgress = labelProgress,\n                    textPosition =\n                        topPaddingValue + (if (isLabelAbove) 0 else labelPlaceable.height),\n                    layoutDirection = layoutDirection,\n                )\n            } else {\n                placeWithoutLabel(\n                    width = width,\n                    totalHeight = totalHeight,\n                    textPlaceable = textFieldPlaceable,\n                    placeholderPlaceable = placeholderPlaceable,\n                    leadingPlaceable = leadingPlaceable,\n                    trailingPlaceable = trailingPlaceable,\n                    prefixPlaceable = prefixPlaceable,\n                    suffixPlaceable = suffixPlaceable,\n                    containerPlaceable = containerPlaceable,\n                    supportingPlaceable = supportingPlaceable,\n                    density = density,\n                )\n            }\n        }\n    }\n\n    override fun IntrinsicMeasureScope.maxIntrinsicHeight(\n        measurables: List<IntrinsicMeasurable>,\n        width: Int,\n    ): Int {\n        return intrinsicHeight(measurables, width) { intrinsicMeasurable, w ->\n            intrinsicMeasurable.maxIntrinsicHeight(w)\n        }\n    }\n\n    override fun IntrinsicMeasureScope.minIntrinsicHeight(\n        measurables: List<IntrinsicMeasurable>,\n        width: Int,\n    ): Int {\n        return intrinsicHeight(measurables, width) { intrinsicMeasurable, w ->\n            intrinsicMeasurable.minIntrinsicHeight(w)\n        }\n    }\n\n    override fun IntrinsicMeasureScope.maxIntrinsicWidth(\n        measurables: List<IntrinsicMeasurable>,\n        height: Int,\n    ): Int {\n        return intrinsicWidth(measurables, height) { intrinsicMeasurable, h ->\n            intrinsicMeasurable.maxIntrinsicWidth(h)\n        }\n    }\n\n    override fun IntrinsicMeasureScope.minIntrinsicWidth(\n        measurables: List<IntrinsicMeasurable>,\n        height: Int,\n    ): Int {\n        return intrinsicWidth(measurables, height) { intrinsicMeasurable, h ->\n            intrinsicMeasurable.minIntrinsicWidth(h)\n        }\n    }\n\n    private fun intrinsicWidth(\n        measurables: List<IntrinsicMeasurable>,\n        height: Int,\n        intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int,\n    ): Int {\n        val textFieldWidth =\n            intrinsicMeasurer(measurables.fastFirst { it.layoutId == TextFieldId }, height)\n        val labelWidth =\n            measurables\n                .fastFirstOrNull { it.layoutId == LabelId }\n                ?.let { intrinsicMeasurer(it, height) } ?: 0\n        val trailingWidth =\n            measurables\n                .fastFirstOrNull { it.layoutId == TrailingId }\n                ?.let { intrinsicMeasurer(it, height) } ?: 0\n        val prefixWidth =\n            measurables\n                .fastFirstOrNull { it.layoutId == PrefixId }\n                ?.let { intrinsicMeasurer(it, height) } ?: 0\n        val suffixWidth =\n            measurables\n                .fastFirstOrNull { it.layoutId == SuffixId }\n                ?.let { intrinsicMeasurer(it, height) } ?: 0\n        val leadingWidth =\n            measurables\n                .fastFirstOrNull { it.layoutId == LeadingId }\n                ?.let { intrinsicMeasurer(it, height) } ?: 0\n        val placeholderWidth =\n            measurables\n                .fastFirstOrNull { it.layoutId == PlaceholderId }\n                ?.let { intrinsicMeasurer(it, height) } ?: 0\n        return calculateWidth(\n            leadingWidth = leadingWidth,\n            trailingWidth = trailingWidth,\n            prefixWidth = prefixWidth,\n            suffixWidth = suffixWidth,\n            textFieldWidth = textFieldWidth,\n            labelWidth = labelWidth,\n            placeholderWidth = placeholderWidth,\n            constraints = Constraints(),\n        )\n    }\n\n    private fun IntrinsicMeasureScope.intrinsicHeight(\n        measurables: List<IntrinsicMeasurable>,\n        width: Int,\n        intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int,\n    ): Int {\n        var remainingWidth = width\n        val leadingHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == LeadingId }\n                ?.let {\n                    remainingWidth =\n                        remainingWidth.subtractConstraintSafely(\n                            it.maxIntrinsicWidth(Constraints.Infinity)\n                        )\n                    intrinsicMeasurer(it, width)\n                } ?: 0\n        val trailingHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == TrailingId }\n                ?.let {\n                    remainingWidth =\n                        remainingWidth.subtractConstraintSafely(\n                            it.maxIntrinsicWidth(Constraints.Infinity)\n                        )\n                    intrinsicMeasurer(it, width)\n                } ?: 0\n        val labelHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == LabelId }\n                ?.let { intrinsicMeasurer(it, remainingWidth) } ?: 0\n\n        val prefixHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == PrefixId }\n                ?.let {\n                    val height = intrinsicMeasurer(it, remainingWidth)\n                    remainingWidth =\n                        remainingWidth.subtractConstraintSafely(\n                            it.maxIntrinsicWidth(Constraints.Infinity)\n                        )\n                    height\n                } ?: 0\n        val suffixHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == SuffixId }\n                ?.let {\n                    val height = intrinsicMeasurer(it, remainingWidth)\n                    remainingWidth =\n                        remainingWidth.subtractConstraintSafely(\n                            it.maxIntrinsicWidth(Constraints.Infinity)\n                        )\n                    height\n                } ?: 0\n\n        val textFieldHeight =\n            intrinsicMeasurer(measurables.fastFirst { it.layoutId == TextFieldId }, remainingWidth)\n        val placeholderHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == PlaceholderId }\n                ?.let { intrinsicMeasurer(it, remainingWidth) } ?: 0\n\n        val supportingHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == SupportingId }\n                ?.let { intrinsicMeasurer(it, width) } ?: 0\n\n        return calculateHeight(\n            textFieldHeight = textFieldHeight,\n            labelHeight = labelHeight,\n            leadingHeight = leadingHeight,\n            trailingHeight = trailingHeight,\n            prefixHeight = prefixHeight,\n            suffixHeight = suffixHeight,\n            placeholderHeight = placeholderHeight,\n            supportingHeight = supportingHeight,\n            constraints = Constraints(),\n            isLabelAbove = labelPosition is TextFieldLabelPosition.Above,\n            labelProgress = labelProgress(),\n        )\n    }\n\n    private fun calculateWidth(\n        leadingWidth: Int,\n        trailingWidth: Int,\n        prefixWidth: Int,\n        suffixWidth: Int,\n        textFieldWidth: Int,\n        labelWidth: Int,\n        placeholderWidth: Int,\n        constraints: Constraints,\n    ): Int {\n        val affixTotalWidth = prefixWidth + suffixWidth\n        val middleSection =\n            maxOf(\n                textFieldWidth + affixTotalWidth,\n                placeholderWidth + affixTotalWidth,\n                // Prefix/suffix does not get applied to label\n                labelWidth,\n            )\n        val wrappedWidth = leadingWidth + middleSection + trailingWidth\n        return constraints.constrainWidth(wrappedWidth)\n    }\n\n    private fun Density.calculateHeight(\n        textFieldHeight: Int,\n        labelHeight: Int,\n        leadingHeight: Int,\n        trailingHeight: Int,\n        prefixHeight: Int,\n        suffixHeight: Int,\n        placeholderHeight: Int,\n        supportingHeight: Int,\n        constraints: Constraints,\n        isLabelAbove: Boolean,\n        labelProgress: Float,\n    ): Int {\n        val verticalPadding =\n            (paddingValues.calculateTopPadding() + paddingValues.calculateBottomPadding())\n                .roundToPx()\n\n        val inputFieldHeight =\n            maxOf(\n                textFieldHeight,\n                placeholderHeight,\n                prefixHeight,\n                suffixHeight,\n                if (isLabelAbove) 0 else lerp(labelHeight, 0, labelProgress),\n            )\n\n        val hasLabel = labelHeight > 0\n        val nonOverlappedLabelHeight =\n            if (hasLabel && !isLabelAbove) {\n                // The label animates from overlapping the input field to floating above it,\n                // so its contribution to the height calculation changes over time. A baseline\n                // height is provided in the unfocused state to keep the overall height consistent\n                // across the animation.\n                max(\n                    (minimizedLabelHalfHeight * 2).roundToPx(),\n                    lerp(\n                        0,\n                        labelHeight,\n                        EasingEmphasizedAccelerateCubicBezier.transform(labelProgress),\n                    ),\n                )\n            } else {\n                0\n            }\n\n        val middleSectionHeight = verticalPadding + nonOverlappedLabelHeight + inputFieldHeight\n\n        return constraints.constrainHeight(\n            (if (isLabelAbove) labelHeight else 0) +\n                maxOf(leadingHeight, trailingHeight, middleSectionHeight) +\n                supportingHeight\n        )\n    }\n\n    /**\n     * Places the provided text field, placeholder, and label in the TextField given the\n     * PaddingValues when there is a label. When there is no label, [placeWithoutLabel] is used\n     * instead.\n     */\n    private fun Placeable.PlacementScope.placeWithLabel(\n        width: Int,\n        totalHeight: Int,\n        textfieldPlaceable: Placeable,\n        labelPlaceable: Placeable,\n        placeholderPlaceable: Placeable?,\n        leadingPlaceable: Placeable?,\n        trailingPlaceable: Placeable?,\n        prefixPlaceable: Placeable?,\n        suffixPlaceable: Placeable?,\n        containerPlaceable: Placeable,\n        supportingPlaceable: Placeable?,\n        labelStartY: Int,\n        labelEndY: Int,\n        isLabelAbove: Boolean,\n        labelProgress: Float,\n        textPosition: Int,\n        layoutDirection: LayoutDirection,\n    ) {\n        val yOffset = if (isLabelAbove) labelPlaceable.height else 0\n\n        // place container\n        containerPlaceable.place(0, yOffset)\n\n        // Most elements should be positioned w.r.t the text field's \"visual\" height, i.e.,\n        // excluding the label (if it's Above) and the supporting text on bottom\n        val height =\n            totalHeight -\n                supportingPlaceable.heightOrZero -\n                (if (isLabelAbove) labelPlaceable.height else 0)\n\n        leadingPlaceable?.placeRelative(\n            0,\n            yOffset + Alignment.CenterVertically.align(leadingPlaceable.height, height),\n        )\n\n        val labelY = lerp(labelStartY, labelEndY, labelProgress)\n        if (isLabelAbove) {\n            val labelX =\n                labelPosition.minimizedAlignment.align(\n                    size = labelPlaceable.width,\n                    space = width,\n                    layoutDirection = layoutDirection,\n                )\n            // Not placeRelative because alignment already handles RTL\n            labelPlaceable.place(labelX, labelY)\n        } else {\n            val leftIconWidth =\n                if (layoutDirection == LayoutDirection.Ltr) leadingPlaceable.widthOrZero\n                else trailingPlaceable.widthOrZero\n            val labelStartX =\n                labelPosition.expandedAlignment.align(\n                    size = labelPlaceable.width,\n                    space = width - leadingPlaceable.widthOrZero - trailingPlaceable.widthOrZero,\n                    layoutDirection = layoutDirection,\n                ) + leftIconWidth\n            val labelEndX =\n                labelPosition.minimizedAlignment.align(\n                    size = labelPlaceable.width,\n                    space = width - leadingPlaceable.widthOrZero - trailingPlaceable.widthOrZero,\n                    layoutDirection = layoutDirection,\n                ) + leftIconWidth\n            val labelX = lerp(labelStartX, labelEndX, labelProgress)\n            // Not placeRelative because alignment already handles RTL\n            labelPlaceable.place(labelX, labelY)\n        }\n\n        prefixPlaceable?.placeRelative(leadingPlaceable.widthOrZero, yOffset + textPosition)\n\n        val textHorizontalPosition = leadingPlaceable.widthOrZero + prefixPlaceable.widthOrZero\n        textfieldPlaceable.placeRelative(textHorizontalPosition, yOffset + textPosition)\n        placeholderPlaceable?.placeRelative(textHorizontalPosition, yOffset + textPosition)\n\n        suffixPlaceable?.placeRelative(\n            width - trailingPlaceable.widthOrZero - suffixPlaceable.width,\n            yOffset + textPosition,\n        )\n\n        trailingPlaceable?.placeRelative(\n            width - trailingPlaceable.width,\n            yOffset + Alignment.CenterVertically.align(trailingPlaceable.height, height),\n        )\n\n        supportingPlaceable?.placeRelative(0, yOffset + height)\n    }\n\n    /**\n     * Places the provided text field and placeholder in [TextField] when there is no label. When\n     * there is a label, [placeWithLabel] is used\n     */\n    private fun Placeable.PlacementScope.placeWithoutLabel(\n        width: Int,\n        totalHeight: Int,\n        textPlaceable: Placeable,\n        placeholderPlaceable: Placeable?,\n        leadingPlaceable: Placeable?,\n        trailingPlaceable: Placeable?,\n        prefixPlaceable: Placeable?,\n        suffixPlaceable: Placeable?,\n        containerPlaceable: Placeable,\n        supportingPlaceable: Placeable?,\n        density: Float,\n    ) {\n        // place container\n        containerPlaceable.place(IntOffset.Zero)\n\n        // Most elements should be positioned w.r.t the text field's \"visual\" height, i.e.,\n        // excluding the supporting text on bottom\n        val height = totalHeight - supportingPlaceable.heightOrZero\n        val topPadding = (paddingValues.calculateTopPadding().value * density).roundToInt()\n\n        leadingPlaceable?.placeRelative(\n            0,\n            Alignment.CenterVertically.align(leadingPlaceable.height, height),\n        )\n\n        // Single line text field without label places its text components centered vertically.\n        // Multiline text field without label places its text components at the top with padding.\n        fun calculateVerticalPosition(placeable: Placeable): Int {\n            return if (singleLine) {\n                Alignment.CenterVertically.align(placeable.height, height)\n            } else {\n                topPadding\n            }\n        }\n\n        prefixPlaceable?.placeRelative(\n            leadingPlaceable.widthOrZero,\n            calculateVerticalPosition(prefixPlaceable),\n        )\n\n        val textHorizontalPosition = leadingPlaceable.widthOrZero + prefixPlaceable.widthOrZero\n\n        textPlaceable.placeRelative(\n            textHorizontalPosition,\n            calculateVerticalPosition(textPlaceable),\n        )\n\n        placeholderPlaceable?.placeRelative(\n            textHorizontalPosition,\n            calculateVerticalPosition(placeholderPlaceable),\n        )\n\n        suffixPlaceable?.placeRelative(\n            width - trailingPlaceable.widthOrZero - suffixPlaceable.width,\n            calculateVerticalPosition(suffixPlaceable),\n        )\n\n        trailingPlaceable?.placeRelative(\n            width - trailingPlaceable.width,\n            Alignment.CenterVertically.align(trailingPlaceable.height, height),\n        )\n\n        supportingPlaceable?.placeRelative(0, height)\n    }\n}\n\ninternal data class IndicatorLineElement(\n    val enabled: Boolean,\n    val isError: Boolean,\n    val interactionSource: InteractionSource,\n    val colors: TextFieldColors?,\n    val textFieldShape: Shape?,\n    val focusedIndicatorLineThickness: Dp,\n    val unfocusedIndicatorLineThickness: Dp,\n) : ModifierNodeElement<IndicatorLineNode>() {\n    override fun create(): IndicatorLineNode {\n        return IndicatorLineNode(\n            enabled = enabled,\n            isError = isError,\n            interactionSource = interactionSource,\n            colors = colors,\n            textFieldShape = textFieldShape,\n            focusedIndicatorWidth = focusedIndicatorLineThickness,\n            unfocusedIndicatorWidth = unfocusedIndicatorLineThickness,\n        )\n    }\n\n    override fun update(node: IndicatorLineNode) {\n        node.update(\n            enabled = enabled,\n            isError = isError,\n            interactionSource = interactionSource,\n            colors = colors,\n            textFieldShape = textFieldShape,\n            focusedIndicatorWidth = focusedIndicatorLineThickness,\n            unfocusedIndicatorWidth = unfocusedIndicatorLineThickness,\n        )\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"indicatorLine\"\n        properties[\"enabled\"] = enabled\n        properties[\"isError\"] = isError\n        properties[\"interactionSource\"] = interactionSource\n        properties[\"colors\"] = colors\n        properties[\"textFieldShape\"] = textFieldShape\n        properties[\"focusedIndicatorLineThickness\"] = focusedIndicatorLineThickness\n        properties[\"unfocusedIndicatorLineThickness\"] = unfocusedIndicatorLineThickness\n    }\n}\n\n@OptIn(ExperimentalMaterial3ExpressiveApi::class)\ninternal class IndicatorLineNode(\n    private var enabled: Boolean,\n    private var isError: Boolean,\n    private var interactionSource: InteractionSource,\n    colors: TextFieldColors?,\n    textFieldShape: Shape?,\n    private var focusedIndicatorWidth: Dp,\n    private var unfocusedIndicatorWidth: Dp,\n) : DelegatingNode(), CompositionLocalConsumerModifierNode {\n    private var focused = false\n    private var trackFocusStateJob: Job? = null\n\n    private var _colors: TextFieldColors? = colors\n    private val colors: TextFieldColors\n        get() =\n            _colors\n                ?: currentValueOf(LocalMaterialTheme)\n                    .colorScheme\n                    .defaultTextFieldColors(currentValueOf(LocalTextSelectionColors))\n\n    // Must be initialized in `onAttach` so `colors` can read from the `MaterialTheme`\n    private var colorAnimatable: Animatable<Color, AnimationVector4D>? = null\n\n    private var _shape: Shape? = textFieldShape\n        private set(value) {\n            if (field != value) {\n                field = value\n                drawWithCacheModifierNode.invalidateDrawCache()\n            }\n        }\n\n    private val shape: Shape\n        get() =\n            _shape\n                ?: currentValueOf(LocalMaterialTheme)\n                    .shapes\n                    .fromToken(FilledTextFieldTokens.ContainerShape)\n\n    private val widthAnimatable: Animatable<Dp, AnimationVector1D> =\n        Animatable(\n            initialValue =\n                if (focused && this.enabled) this.focusedIndicatorWidth\n                else this.unfocusedIndicatorWidth,\n            typeConverter = Dp.VectorConverter,\n        )\n\n    fun update(\n        enabled: Boolean,\n        isError: Boolean,\n        interactionSource: InteractionSource,\n        colors: TextFieldColors?,\n        textFieldShape: Shape?,\n        focusedIndicatorWidth: Dp,\n        unfocusedIndicatorWidth: Dp,\n    ) {\n        var shouldInvalidate = false\n\n        if (this.enabled != enabled) {\n            this.enabled = enabled\n            shouldInvalidate = true\n        }\n\n        if (this.isError != isError) {\n            this.isError = isError\n            shouldInvalidate = true\n        }\n\n        if (this.interactionSource !== interactionSource) {\n            this.interactionSource = interactionSource\n            trackFocusStateJob?.cancel()\n            trackFocusStateJob = coroutineScope.launch { trackFocusState() }\n        }\n\n        if (this._colors != colors) {\n            this._colors = colors\n            shouldInvalidate = true\n        }\n\n        if (this._shape != textFieldShape) {\n            this._shape = textFieldShape\n            shouldInvalidate = true\n        }\n\n        if (this.focusedIndicatorWidth != focusedIndicatorWidth) {\n            this.focusedIndicatorWidth = focusedIndicatorWidth\n            shouldInvalidate = true\n        }\n\n        if (this.unfocusedIndicatorWidth != unfocusedIndicatorWidth) {\n            this.unfocusedIndicatorWidth = unfocusedIndicatorWidth\n            shouldInvalidate = true\n        }\n\n        if (shouldInvalidate) {\n            invalidateIndicator()\n        }\n    }\n\n    override val shouldAutoInvalidate: Boolean\n        get() = false\n\n    override fun onAttach() {\n        trackFocusStateJob = coroutineScope.launch { trackFocusState() }\n        if (colorAnimatable == null) {\n            val initialColor = colors.indicatorColor(enabled, isError, focused)\n            colorAnimatable =\n                Animatable(\n                    initialValue = initialColor,\n                    typeConverter = Color.VectorConverter(initialColor.colorSpace),\n                )\n        }\n    }\n\n    /** Copied from [InteractionSource.collectIsFocusedAsState] */\n    private suspend fun trackFocusState() {\n        focused = false\n        val focusInteractions = mutableListOf<FocusInteraction.Focus>()\n        interactionSource.interactions.collect { interaction ->\n            when (interaction) {\n                is FocusInteraction.Focus -> focusInteractions.add(interaction)\n                is FocusInteraction.Unfocus -> focusInteractions.remove(interaction.focus)\n            }\n            val isFocused = focusInteractions.isNotEmpty()\n            if (isFocused != focused) {\n                focused = isFocused\n                invalidateIndicator()\n            }\n        }\n    }\n\n    private fun invalidateIndicator() {\n        coroutineScope.launch {\n            colorAnimatable?.animateTo(\n                targetValue = colors.indicatorColor(enabled, isError, focused),\n                animationSpec =\n                    if (enabled) {\n                        currentValueOf(LocalMaterialTheme)\n                            .motionScheme\n                            .fromToken<Color>(MotionSchemeKeyTokens.FastEffects)\n                    } else {\n                        snap()\n                    },\n            )\n        }\n        coroutineScope.launch {\n            widthAnimatable.animateTo(\n                targetValue =\n                    if (focused && enabled) focusedIndicatorWidth else unfocusedIndicatorWidth,\n                animationSpec =\n                    if (enabled) {\n                        currentValueOf(LocalMaterialTheme)\n                            .motionScheme\n                            .fromToken<Dp>(MotionSchemeKeyTokens.FastSpatial)\n                    } else {\n                        snap()\n                    },\n            )\n        }\n    }\n\n    private val drawWithCacheModifierNode =\n        delegate(\n            CacheDrawModifierNode {\n                val strokeWidth = widthAnimatable.value.toPx()\n                val textFieldShapePath =\n                    Path().apply {\n                        addOutline(\n                            this@IndicatorLineNode.shape.createOutline(\n                                size,\n                                layoutDirection,\n                                density = this@CacheDrawModifierNode,\n                            )\n                        )\n                    }\n                val linePath =\n                    Path().apply {\n                        addRect(\n                            Rect(\n                                left = 0f,\n                                top = size.height - strokeWidth,\n                                right = size.width,\n                                bottom = size.height,\n                            )\n                        )\n                    }\n                val clippedLine = linePath and textFieldShapePath\n\n                onDrawWithContent {\n                    drawContent()\n                    drawPath(path = clippedLine, brush = SolidColor(colorAnimatable!!.value))\n                }\n            }\n        )\n}\n\n/** Padding from text field top to label top, and from input field bottom to text field bottom */\n/*@VisibleForTesting*/\ninternal val TextFieldWithLabelVerticalPadding = 8.dp\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/OutlinedTextField.kt\n```kotlin\n/*\n * Copyright 2022 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.foundation.ScrollState\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.collectIsFocusedAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.calculateEndPadding\nimport androidx.compose.foundation.layout.calculateStartPadding\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.heightIn\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.wrapContentHeight\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.text.BasicTextField\nimport androidx.compose.foundation.text.KeyboardActions\nimport androidx.compose.foundation.text.KeyboardOptions\nimport androidx.compose.foundation.text.input.InputTransformation\nimport androidx.compose.foundation.text.input.KeyboardActionHandler\nimport androidx.compose.foundation.text.input.OutputTransformation\nimport androidx.compose.foundation.text.input.TextFieldLineLimits\nimport androidx.compose.foundation.text.input.TextFieldLineLimits.MultiLine\nimport androidx.compose.foundation.text.input.TextFieldLineLimits.SingleLine\nimport androidx.compose.foundation.text.input.TextFieldState\nimport androidx.compose.foundation.text.selection.LocalTextSelectionColors\nimport androidx.compose.material3.internal.AboveLabelBottomPadding\nimport androidx.compose.material3.internal.AboveLabelHorizontalPadding\nimport androidx.compose.material3.internal.ContainerId\nimport androidx.compose.material3.internal.FloatProducer\nimport androidx.compose.material3.internal.LabelId\nimport androidx.compose.material3.internal.LeadingId\nimport androidx.compose.material3.internal.MinFocusedLabelLineHeight\nimport androidx.compose.material3.internal.MinSupportingTextLineHeight\nimport androidx.compose.material3.internal.MinTextLineHeight\nimport androidx.compose.material3.internal.PlaceholderId\nimport androidx.compose.material3.internal.PrefixId\nimport androidx.compose.material3.internal.PrefixSuffixTextPadding\nimport androidx.compose.material3.internal.Strings\nimport androidx.compose.material3.internal.SuffixId\nimport androidx.compose.material3.internal.SupportingId\nimport androidx.compose.material3.internal.TextFieldId\nimport androidx.compose.material3.internal.TrailingId\nimport androidx.compose.material3.internal.defaultErrorSemantics\nimport androidx.compose.material3.internal.expandedAlignment\nimport androidx.compose.material3.internal.getString\nimport androidx.compose.material3.internal.heightOrZero\nimport androidx.compose.material3.internal.layoutId\nimport androidx.compose.material3.internal.minimizedAlignment\nimport androidx.compose.material3.internal.minimizedLabelHalfHeight\nimport androidx.compose.material3.internal.subtractConstraintSafely\nimport androidx.compose.material3.internal.textFieldHorizontalIconPadding\nimport androidx.compose.material3.internal.textFieldLabelMinHeight\nimport androidx.compose.material3.internal.widthOrZero\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.drawWithContent\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.ClipOp\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.drawscope.clipRect\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.layout.IntrinsicMeasurable\nimport androidx.compose.ui.layout.IntrinsicMeasureScope\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.Measurable\nimport androidx.compose.ui.layout.MeasurePolicy\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.layout.layoutId\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.text.TextLayoutResult\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.text.input.ImeAction\nimport androidx.compose.ui.text.input.KeyboardType\nimport androidx.compose.ui.text.input.TextFieldValue\nimport androidx.compose.ui.text.input.VisualTransformation\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.coerceAtLeast\nimport androidx.compose.ui.unit.constrainHeight\nimport androidx.compose.ui.unit.constrainWidth\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.lerp\nimport androidx.compose.ui.unit.offset\nimport androidx.compose.ui.util.fastFirst\nimport androidx.compose.ui.util.fastFirstOrNull\nimport androidx.compose.ui.util.lerp\nimport kotlin.math.max\nimport kotlin.math.roundToInt\n\n/**\n * [Material Design outlined text field](https://m3.material.io/components/text-fields/overview)\n *\n * Text fields allow users to enter text into a UI. They typically appear in forms and dialogs.\n * Outlined text fields have less visual emphasis than filled text fields. When they appear in\n * places like forms, where many text fields are placed together, their reduced emphasis helps\n * simplify the layout.\n *\n * ![Outlined text field\n * image](https://developer.android.com/images/reference/androidx/compose/material3/outlined-text-field.png)\n *\n * If you are looking for a filled version, see [TextField]. For a text field specifically designed\n * for passwords or other secure content, see [OutlinedSecureTextField].\n *\n * This overload of [OutlinedTextField] uses [TextFieldState] to keep track of its text content and\n * position of the cursor or selection.\n *\n * See example usage:\n *\n * @sample androidx.compose.material3.samples.SimpleOutlinedTextFieldSample\n * @sample androidx.compose.material3.samples.OutlinedTextFieldWithInitialValueAndSelection\n * @param state [TextFieldState] object that holds the internal editing state of the text field.\n * @param modifier the [Modifier] to be applied to this text field.\n * @param enabled controls the enabled state of this text field. When `false`, this component will\n *   not respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param readOnly controls the editable state of the text field. When `true`, the text field cannot\n *   be modified. However, a user can focus it and copy text from it. Read-only text fields are\n *   usually used to display pre-filled forms that a user cannot edit.\n * @param textStyle the style to be applied to the input text. Defaults to [LocalTextStyle].\n * @param labelPosition the position of the label. See [TextFieldLabelPosition].\n * @param label the optional label to be displayed with this text field. The default text style uses\n *   [Typography.bodySmall] when minimized and [Typography.bodyLarge] when expanded.\n * @param placeholder the optional placeholder to be displayed when the input text is empty. The\n *   default text style uses [Typography.bodyLarge].\n * @param leadingIcon the optional leading icon to be displayed at the beginning of the text field\n *   container.\n * @param trailingIcon the optional trailing icon to be displayed at the end of the text field\n *   container.\n * @param prefix the optional prefix to be displayed before the input text in the text field.\n * @param suffix the optional suffix to be displayed after the input text in the text field.\n * @param supportingText the optional supporting text to be displayed below the text field.\n * @param isError indicates if the text field's current value is in error. When `true`, the\n *   components of the text field will be displayed in an error color, and an error will be\n *   announced to accessibility services.\n * @param inputTransformation optional [InputTransformation] that will be used to transform changes\n *   to the [TextFieldState] made by the user. The transformation will be applied to changes made by\n *   hardware and software keyboard events, pasting or dropping text, accessibility services, and\n *   tests. The transformation will _not_ be applied when changing the [state] programmatically, or\n *   when the transformation is changed. If the transformation is changed on an existing text field,\n *   it will be applied to the next user edit. The transformation will not immediately affect the\n *   current [state].\n * @param outputTransformation optional [OutputTransformation] that transforms how the contents of\n *   the text field are presented.\n * @param keyboardOptions software keyboard options that contains configuration such as\n *   [KeyboardType] and [ImeAction].\n * @param onKeyboardAction called when the user presses the action button in the input method editor\n *   (IME), or by pressing the enter key on a hardware keyboard. By default this parameter is null,\n *   and would execute the default behavior for a received IME Action e.g., [ImeAction.Done] would\n *   close the keyboard, [ImeAction.Next] would switch the focus to the next focusable item on the\n *   screen.\n * @param lineLimits whether the text field should be [SingleLine], scroll horizontally, and ignore\n *   newlines; or [MultiLine] and grow and scroll vertically. If [SingleLine] is passed, all newline\n *   characters ('\\n') within the text will be replaced with regular whitespace (' ').\n * @param onTextLayout Callback that is executed when the text layout becomes queryable. The\n *   callback receives a function that returns a [TextLayoutResult] if the layout can be calculated,\n *   or null if it cannot. The function reads the layout result from a snapshot state object, and\n *   will invalidate its caller when the layout result changes. A [TextLayoutResult] object contains\n *   paragraph information, size of the text, baselines and other details. [Density] scope is the\n *   one that was used while creating the given text layout.\n * @param scrollState scroll state that manages either horizontal or vertical scroll of the text\n *   field. If [lineLimits] is [SingleLine], this text field is treated as single line with\n *   horizontal scroll behavior. Otherwise, the text field becomes vertically scrollable.\n * @param shape defines the shape of this text field's border.\n * @param colors [TextFieldColors] that will be used to resolve the colors used for this text field\n *   in different states. See [OutlinedTextFieldDefaults.colors].\n * @param contentPadding the padding applied to the inner text field that separates it from the\n *   surrounding elements of the text field. Note that the padding values may not be respected if\n *   they are incompatible with the text field's size constraints or layout. See\n *   [OutlinedTextFieldDefaults.contentPadding].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this text field. You can use this to change the text field's\n *   appearance or preview the text field in different states. Note that if `null` is provided,\n *   interactions will still happen internally.\n */\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun OutlinedTextField(\n    state: TextFieldState,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    readOnly: Boolean = false,\n    textStyle: TextStyle = LocalTextStyle.current,\n    labelPosition: TextFieldLabelPosition = TextFieldLabelPosition.Attached(),\n    label: @Composable (TextFieldLabelScope.() -> Unit)? = null,\n    placeholder: @Composable (() -> Unit)? = null,\n    leadingIcon: @Composable (() -> Unit)? = null,\n    trailingIcon: @Composable (() -> Unit)? = null,\n    prefix: @Composable (() -> Unit)? = null,\n    suffix: @Composable (() -> Unit)? = null,\n    supportingText: @Composable (() -> Unit)? = null,\n    isError: Boolean = false,\n    inputTransformation: InputTransformation? = null,\n    outputTransformation: OutputTransformation? = null,\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,\n    onKeyboardAction: KeyboardActionHandler? = null,\n    lineLimits: TextFieldLineLimits = TextFieldLineLimits.Default,\n    onTextLayout: (Density.(getResult: () -> TextLayoutResult?) -> Unit)? = null,\n    scrollState: ScrollState = rememberScrollState(),\n    shape: Shape = OutlinedTextFieldDefaults.shape,\n    colors: TextFieldColors = OutlinedTextFieldDefaults.colors(),\n    contentPadding: PaddingValues = OutlinedTextFieldDefaults.contentPadding(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    // If color is not provided via the text style, use content color as a default\n    val textColor =\n        textStyle.color.takeOrElse {\n            val focused = interactionSource.collectIsFocusedAsState().value\n            colors.textColor(enabled, isError, focused)\n        }\n    val mergedTextStyle = textStyle.merge(TextStyle(color = textColor))\n\n    CompositionLocalProvider(LocalTextSelectionColors provides colors.textSelectionColors) {\n        BasicTextField(\n            state = state,\n            modifier =\n                modifier\n                    .then(\n                        if (label != null && labelPosition !is TextFieldLabelPosition.Above) {\n                            Modifier\n                                // Merge semantics at the beginning of the modifier chain to ensure\n                                // padding is considered part of the text field.\n                                .semantics(mergeDescendants = true) {}\n                                .padding(top = minimizedLabelHalfHeight())\n                        } else {\n                            Modifier\n                        }\n                    )\n                    .defaultErrorSemantics(isError, getString(Strings.DefaultErrorMessage))\n                    .defaultMinSize(\n                        minWidth = OutlinedTextFieldDefaults.MinWidth,\n                        minHeight = OutlinedTextFieldDefaults.MinHeight,\n                    ),\n            enabled = enabled,\n            readOnly = readOnly,\n            textStyle = mergedTextStyle,\n            cursorBrush = SolidColor(colors.cursorColor(isError)),\n            keyboardOptions = keyboardOptions,\n            onKeyboardAction = onKeyboardAction,\n            lineLimits = lineLimits,\n            onTextLayout = onTextLayout,\n            interactionSource = interactionSource,\n            inputTransformation = inputTransformation,\n            outputTransformation = outputTransformation,\n            scrollState = scrollState,\n            decorator =\n                OutlinedTextFieldDefaults.decorator(\n                    state = state,\n                    enabled = enabled,\n                    lineLimits = lineLimits,\n                    outputTransformation = outputTransformation,\n                    interactionSource = interactionSource,\n                    labelPosition = labelPosition,\n                    label = label,\n                    placeholder = placeholder,\n                    leadingIcon = leadingIcon,\n                    trailingIcon = trailingIcon,\n                    prefix = prefix,\n                    suffix = suffix,\n                    supportingText = supportingText,\n                    isError = isError,\n                    colors = colors,\n                    contentPadding = contentPadding,\n                    container = {\n                        OutlinedTextFieldDefaults.Container(\n                            enabled = enabled,\n                            isError = isError,\n                            interactionSource = interactionSource,\n                            colors = colors,\n                            shape = shape,\n                        )\n                    },\n                ),\n        )\n    }\n}\n\n/**\n * [Material Design outlined text field](https://m3.material.io/components/text-fields/overview)\n *\n * Text fields allow users to enter text into a UI. They typically appear in forms and dialogs.\n * Outlined text fields have less visual emphasis than filled text fields. When they appear in\n * places like forms, where many text fields are placed together, their reduced emphasis helps\n * simplify the layout.\n *\n * ![Outlined text field\n * image](https://developer.android.com/images/reference/androidx/compose/material3/outlined-text-field.png)\n *\n * If apart from input text change you also want to observe the cursor location, selection range, or\n * IME composition use the OutlinedTextField overload with the [TextFieldValue] parameter instead.\n *\n * @param value the input text to be shown in the text field\n * @param onValueChange the callback that is triggered when the input service updates the text. An\n *   updated text comes as a parameter of the callback\n * @param modifier the [Modifier] to be applied to this text field\n * @param enabled controls the enabled state of this text field. When `false`, this component will\n *   not respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param readOnly controls the editable state of the text field. When `true`, the text field cannot\n *   be modified. However, a user can focus it and copy text from it. Read-only text fields are\n *   usually used to display pre-filled forms that a user cannot edit.\n * @param textStyle the style to be applied to the input text. Defaults to [LocalTextStyle].\n * @param label the optional label to be displayed with this text field. The default text style uses\n *   [Typography.bodySmall] when minimized and [Typography.bodyLarge] when expanded.\n * @param placeholder the optional placeholder to be displayed when the text field is in focus and\n *   the input text is empty. The default text style for internal [Text] is [Typography.bodyLarge]\n * @param leadingIcon the optional leading icon to be displayed at the beginning of the text field\n *   container\n * @param trailingIcon the optional trailing icon to be displayed at the end of the text field\n *   container\n * @param prefix the optional prefix to be displayed before the input text in the text field\n * @param suffix the optional suffix to be displayed after the input text in the text field\n * @param supportingText the optional supporting text to be displayed below the text field\n * @param isError indicates if the text field's current value is in error. If set to true, the\n *   label, bottom indicator and trailing icon by default will be displayed in error color\n * @param visualTransformation transforms the visual representation of the input [value] For\n *   example, you can use\n *   [PasswordVisualTransformation][androidx.compose.ui.text.input.PasswordVisualTransformation] to\n *   create a password text field. By default, no visual transformation is applied.\n * @param keyboardOptions software keyboard options that contains configuration such as\n *   [KeyboardType] and [ImeAction]\n * @param keyboardActions when the input service emits an IME action, the corresponding callback is\n *   called. Note that this IME action may be different from what you specified in\n *   [KeyboardOptions.imeAction]\n * @param singleLine when `true`, this text field becomes a single horizontally scrolling text field\n *   instead of wrapping onto multiple lines. The keyboard will be informed to not show the return\n *   key as the [ImeAction]. Note that [maxLines] parameter will be ignored as the maxLines\n *   attribute will be automatically set to 1.\n * @param maxLines the maximum height in terms of maximum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.\n * @param minLines the minimum height in terms of minimum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this text field. You can use this to change the text field's\n *   appearance or preview the text field in different states. Note that if `null` is provided,\n *   interactions will still happen internally.\n * @param shape defines the shape of this text field's border\n * @param colors [TextFieldColors] that will be used to resolve the colors used for this text field\n *   in different states. See [OutlinedTextFieldDefaults.colors].\n */\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun OutlinedTextField(\n    value: String,\n    onValueChange: (String) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    readOnly: Boolean = false,\n    textStyle: TextStyle = LocalTextStyle.current,\n    label: @Composable (() -> Unit)? = null,\n    placeholder: @Composable (() -> Unit)? = null,\n    leadingIcon: @Composable (() -> Unit)? = null,\n    trailingIcon: @Composable (() -> Unit)? = null,\n    prefix: @Composable (() -> Unit)? = null,\n    suffix: @Composable (() -> Unit)? = null,\n    supportingText: @Composable (() -> Unit)? = null,\n    isError: Boolean = false,\n    visualTransformation: VisualTransformation = VisualTransformation.None,\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,\n    keyboardActions: KeyboardActions = KeyboardActions.Default,\n    singleLine: Boolean = false,\n    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,\n    minLines: Int = 1,\n    interactionSource: MutableInteractionSource? = null,\n    shape: Shape = OutlinedTextFieldDefaults.shape,\n    colors: TextFieldColors = OutlinedTextFieldDefaults.colors(),\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    // If color is not provided via the text style, use content color as a default\n    val textColor =\n        textStyle.color.takeOrElse {\n            val focused = interactionSource.collectIsFocusedAsState().value\n            colors.textColor(enabled, isError, focused)\n        }\n    val mergedTextStyle = textStyle.merge(TextStyle(color = textColor))\n\n    CompositionLocalProvider(LocalTextSelectionColors provides colors.textSelectionColors) {\n        BasicTextField(\n            value = value,\n            modifier =\n                modifier\n                    .then(\n                        if (label != null) {\n                            Modifier\n                                // Merge semantics at the beginning of the modifier chain to ensure\n                                // padding is considered part of the text field.\n                                .semantics(mergeDescendants = true) {}\n                                .padding(top = minimizedLabelHalfHeight())\n                        } else {\n                            Modifier\n                        }\n                    )\n                    .defaultErrorSemantics(isError, getString(Strings.DefaultErrorMessage))\n                    .defaultMinSize(\n                        minWidth = OutlinedTextFieldDefaults.MinWidth,\n                        minHeight = OutlinedTextFieldDefaults.MinHeight,\n                    ),\n            onValueChange = onValueChange,\n            enabled = enabled,\n            readOnly = readOnly,\n            textStyle = mergedTextStyle,\n            cursorBrush = SolidColor(colors.cursorColor(isError)),\n            visualTransformation = visualTransformation,\n            keyboardOptions = keyboardOptions,\n            keyboardActions = keyboardActions,\n            interactionSource = interactionSource,\n            singleLine = singleLine,\n            maxLines = maxLines,\n            minLines = minLines,\n            decorationBox =\n                @Composable { innerTextField ->\n                    OutlinedTextFieldDefaults.DecorationBox(\n                        value = value,\n                        visualTransformation = visualTransformation,\n                        innerTextField = innerTextField,\n                        placeholder = placeholder,\n                        label = label,\n                        leadingIcon = leadingIcon,\n                        trailingIcon = trailingIcon,\n                        prefix = prefix,\n                        suffix = suffix,\n                        supportingText = supportingText,\n                        singleLine = singleLine,\n                        enabled = enabled,\n                        isError = isError,\n                        interactionSource = interactionSource,\n                        colors = colors,\n                        container = {\n                            OutlinedTextFieldDefaults.Container(\n                                enabled = enabled,\n                                isError = isError,\n                                interactionSource = interactionSource,\n                                colors = colors,\n                                shape = shape,\n                            )\n                        },\n                    )\n                },\n        )\n    }\n}\n\n/**\n * [Material Design outlined text field](https://m3.material.io/components/text-fields/overview)\n *\n * Text fields allow users to enter text into a UI. They typically appear in forms and dialogs.\n * Outlined text fields have less visual emphasis than filled text fields. When they appear in\n * places like forms, where many text fields are placed together, their reduced emphasis helps\n * simplify the layout.\n *\n * ![Outlined text field\n * image](https://developer.android.com/images/reference/androidx/compose/material3/outlined-text-field.png)\n *\n * This overload provides access to the input text, cursor position and selection range and IME\n * composition. If you only want to observe an input text change, use the OutlinedTextField overload\n * with the [String] parameter instead.\n *\n * @param value the input [TextFieldValue] to be shown in the text field\n * @param onValueChange the callback that is triggered when the input service updates values in\n *   [TextFieldValue]. An updated [TextFieldValue] comes as a parameter of the callback\n * @param modifier the [Modifier] to be applied to this text field\n * @param enabled controls the enabled state of this text field. When `false`, this component will\n *   not respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param readOnly controls the editable state of the text field. When `true`, the text field cannot\n *   be modified. However, a user can focus it and copy text from it. Read-only text fields are\n *   usually used to display pre-filled forms that a user cannot edit.\n * @param textStyle the style to be applied to the input text. Defaults to [LocalTextStyle].\n * @param label the optional label to be displayed with this text field. The default text style uses\n *   [Typography.bodySmall] when minimized and [Typography.bodyLarge] when expanded.\n * @param placeholder the optional placeholder to be displayed when the text field is in focus and\n *   the input text is empty. The default text style for internal [Text] is [Typography.bodyLarge]\n * @param leadingIcon the optional leading icon to be displayed at the beginning of the text field\n *   container\n * @param trailingIcon the optional trailing icon to be displayed at the end of the text field\n *   container\n * @param prefix the optional prefix to be displayed before the input text in the text field\n * @param suffix the optional suffix to be displayed after the input text in the text field\n * @param supportingText the optional supporting text to be displayed below the text field\n * @param isError indicates if the text field's current value is in error state. If set to true, the\n *   label, bottom indicator and trailing icon by default will be displayed in error color\n * @param visualTransformation transforms the visual representation of the input [value] For\n *   example, you can use\n *   [PasswordVisualTransformation][androidx.compose.ui.text.input.PasswordVisualTransformation] to\n *   create a password text field. By default, no visual transformation is applied.\n * @param keyboardOptions software keyboard options that contains configuration such as\n *   [KeyboardType] and [ImeAction]\n * @param keyboardActions when the input service emits an IME action, the corresponding callback is\n *   called. Note that this IME action may be different from what you specified in\n *   [KeyboardOptions.imeAction]\n * @param singleLine when `true`, this text field becomes a single horizontally scrolling text field\n *   instead of wrapping onto multiple lines. The keyboard will be informed to not show the return\n *   key as the [ImeAction]. Note that [maxLines] parameter will be ignored as the maxLines\n *   attribute will be automatically set to 1.\n * @param maxLines the maximum height in terms of maximum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.\n * @param minLines the minimum height in terms of minimum number of visible lines. It is required\n *   that 1 <= [minLines] <= [maxLines]. This parameter is ignored when [singleLine] is true.\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this text field. You can use this to change the text field's\n *   appearance or preview the text field in different states. Note that if `null` is provided,\n *   interactions will still happen internally.\n * @param shape defines the shape of this text field's border\n * @param colors [TextFieldColors] that will be used to resolve the colors used for this text field\n *   in different states. See [OutlinedTextFieldDefaults.colors].\n */\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun OutlinedTextField(\n    value: TextFieldValue,\n    onValueChange: (TextFieldValue) -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    readOnly: Boolean = false,\n    textStyle: TextStyle = LocalTextStyle.current,\n    label: @Composable (() -> Unit)? = null,\n    placeholder: @Composable (() -> Unit)? = null,\n    leadingIcon: @Composable (() -> Unit)? = null,\n    trailingIcon: @Composable (() -> Unit)? = null,\n    prefix: @Composable (() -> Unit)? = null,\n    suffix: @Composable (() -> Unit)? = null,\n    supportingText: @Composable (() -> Unit)? = null,\n    isError: Boolean = false,\n    visualTransformation: VisualTransformation = VisualTransformation.None,\n    keyboardOptions: KeyboardOptions = KeyboardOptions.Default,\n    keyboardActions: KeyboardActions = KeyboardActions.Default,\n    singleLine: Boolean = false,\n    maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,\n    minLines: Int = 1,\n    interactionSource: MutableInteractionSource? = null,\n    shape: Shape = OutlinedTextFieldDefaults.shape,\n    colors: TextFieldColors = OutlinedTextFieldDefaults.colors(),\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    // If color is not provided via the text style, use content color as a default\n    val textColor =\n        textStyle.color.takeOrElse {\n            val focused = interactionSource.collectIsFocusedAsState().value\n            colors.textColor(enabled, isError, focused)\n        }\n    val mergedTextStyle = textStyle.merge(TextStyle(color = textColor))\n\n    CompositionLocalProvider(LocalTextSelectionColors provides colors.textSelectionColors) {\n        BasicTextField(\n            value = value,\n            modifier =\n                modifier\n                    .then(\n                        if (label != null) {\n                            Modifier\n                                // Merge semantics at the beginning of the modifier chain to ensure\n                                // padding is considered part of the text field.\n                                .semantics(mergeDescendants = true) {}\n                                .padding(top = minimizedLabelHalfHeight())\n                        } else {\n                            Modifier\n                        }\n                    )\n                    .defaultErrorSemantics(isError, getString(Strings.DefaultErrorMessage))\n                    .defaultMinSize(\n                        minWidth = OutlinedTextFieldDefaults.MinWidth,\n                        minHeight = OutlinedTextFieldDefaults.MinHeight,\n                    ),\n            onValueChange = onValueChange,\n            enabled = enabled,\n            readOnly = readOnly,\n            textStyle = mergedTextStyle,\n            cursorBrush = SolidColor(colors.cursorColor(isError)),\n            visualTransformation = visualTransformation,\n            keyboardOptions = keyboardOptions,\n            keyboardActions = keyboardActions,\n            interactionSource = interactionSource,\n            singleLine = singleLine,\n            maxLines = maxLines,\n            minLines = minLines,\n            decorationBox =\n                @Composable { innerTextField ->\n                    OutlinedTextFieldDefaults.DecorationBox(\n                        value = value.text,\n                        visualTransformation = visualTransformation,\n                        innerTextField = innerTextField,\n                        placeholder = placeholder,\n                        label = label,\n                        leadingIcon = leadingIcon,\n                        trailingIcon = trailingIcon,\n                        prefix = prefix,\n                        suffix = suffix,\n                        supportingText = supportingText,\n                        singleLine = singleLine,\n                        enabled = enabled,\n                        isError = isError,\n                        interactionSource = interactionSource,\n                        colors = colors,\n                        container = {\n                            OutlinedTextFieldDefaults.Container(\n                                enabled = enabled,\n                                isError = isError,\n                                interactionSource = interactionSource,\n                                colors = colors,\n                                shape = shape,\n                            )\n                        },\n                    )\n                },\n        )\n    }\n}\n\n/**\n * Layout of the leading and trailing icons and the text field, label and placeholder in\n * [OutlinedTextField]. It doesn't use Row to position the icons and middle part because label\n * should not be positioned in the middle part.\n */\n@Composable\ninternal fun OutlinedTextFieldLayout(\n    modifier: Modifier,\n    textField: @Composable () -> Unit,\n    placeholder: @Composable ((Modifier) -> Unit)?,\n    label: @Composable (() -> Unit)?,\n    leading: @Composable (() -> Unit)?,\n    trailing: @Composable (() -> Unit)?,\n    prefix: @Composable (() -> Unit)?,\n    suffix: @Composable (() -> Unit)?,\n    singleLine: Boolean,\n    labelPosition: TextFieldLabelPosition,\n    labelProgress: FloatProducer,\n    onLabelMeasured: (Size) -> Unit,\n    container: @Composable () -> Unit,\n    supporting: @Composable (() -> Unit)?,\n    paddingValues: PaddingValues,\n) {\n    val horizontalIconPadding = textFieldHorizontalIconPadding()\n    val measurePolicy =\n        remember(\n            onLabelMeasured,\n            singleLine,\n            labelPosition,\n            labelProgress,\n            paddingValues,\n            horizontalIconPadding,\n        ) {\n            OutlinedTextFieldMeasurePolicy(\n                onLabelMeasured = onLabelMeasured,\n                singleLine = singleLine,\n                labelPosition = labelPosition,\n                labelProgress = labelProgress,\n                paddingValues = paddingValues,\n                horizontalIconPadding = horizontalIconPadding,\n            )\n        }\n    val layoutDirection = LocalLayoutDirection.current\n    Layout(\n        modifier = modifier,\n        content = {\n            container()\n\n            if (leading != null) {\n                Box(\n                    modifier = Modifier.layoutId(LeadingId).minimumInteractiveComponentSize(),\n                    contentAlignment = Alignment.Center,\n                ) {\n                    leading()\n                }\n            }\n            if (trailing != null) {\n                Box(\n                    modifier = Modifier.layoutId(TrailingId).minimumInteractiveComponentSize(),\n                    contentAlignment = Alignment.Center,\n                ) {\n                    trailing()\n                }\n            }\n\n            val startTextFieldPadding = paddingValues.calculateStartPadding(layoutDirection)\n            val endTextFieldPadding = paddingValues.calculateEndPadding(layoutDirection)\n\n            val startPadding =\n                if (leading != null) {\n                    (startTextFieldPadding - horizontalIconPadding).coerceAtLeast(0.dp)\n                } else {\n                    startTextFieldPadding\n                }\n            val endPadding =\n                if (trailing != null) {\n                    (endTextFieldPadding - horizontalIconPadding).coerceAtLeast(0.dp)\n                } else {\n                    endTextFieldPadding\n                }\n\n            if (prefix != null) {\n                Box(\n                    Modifier.layoutId(PrefixId)\n                        .heightIn(min = MinTextLineHeight)\n                        .wrapContentHeight()\n                        .padding(start = startPadding, end = PrefixSuffixTextPadding)\n                ) {\n                    prefix()\n                }\n            }\n            if (suffix != null) {\n                Box(\n                    Modifier.layoutId(SuffixId)\n                        .heightIn(min = MinTextLineHeight)\n                        .wrapContentHeight()\n                        .padding(start = PrefixSuffixTextPadding, end = endPadding)\n                ) {\n                    suffix()\n                }\n            }\n\n            val textPadding =\n                Modifier.heightIn(min = MinTextLineHeight)\n                    .wrapContentHeight()\n                    .padding(\n                        start = if (prefix == null) startPadding else 0.dp,\n                        end = if (suffix == null) endPadding else 0.dp,\n                    )\n\n            if (placeholder != null) {\n                placeholder(Modifier.layoutId(PlaceholderId).then(textPadding))\n            }\n\n            Box(\n                modifier = Modifier.layoutId(TextFieldId).then(textPadding),\n                propagateMinConstraints = true,\n            ) {\n                textField()\n            }\n\n            val labelPadding =\n                if (labelPosition is TextFieldLabelPosition.Above) {\n                    Modifier.padding(\n                        start = AboveLabelHorizontalPadding,\n                        end = AboveLabelHorizontalPadding,\n                        bottom = AboveLabelBottomPadding,\n                    )\n                } else {\n                    Modifier\n                }\n\n            if (label != null) {\n                Box(\n                    Modifier.textFieldLabelMinHeight {\n                            lerp(MinTextLineHeight, MinFocusedLabelLineHeight, labelProgress())\n                        }\n                        .wrapContentHeight()\n                        .layoutId(LabelId)\n                        .then(labelPadding)\n                ) {\n                    label()\n                }\n            }\n\n            if (supporting != null) {\n                Box(\n                    Modifier.layoutId(SupportingId)\n                        .heightIn(min = MinSupportingTextLineHeight)\n                        .wrapContentHeight()\n                        .padding(TextFieldDefaults.supportingTextPadding())\n                ) {\n                    supporting()\n                }\n            }\n        },\n        measurePolicy = measurePolicy,\n    )\n}\n\nprivate class OutlinedTextFieldMeasurePolicy(\n    private val onLabelMeasured: (Size) -> Unit,\n    private val singleLine: Boolean,\n    private val labelPosition: TextFieldLabelPosition,\n    private val labelProgress: FloatProducer,\n    private val paddingValues: PaddingValues,\n    private val horizontalIconPadding: Dp,\n) : MeasurePolicy {\n    override fun MeasureScope.measure(\n        measurables: List<Measurable>,\n        constraints: Constraints,\n    ): MeasureResult {\n        val labelProgress = labelProgress()\n        var occupiedSpaceHorizontally = 0\n        var occupiedSpaceVertically = 0\n        val bottomPadding = paddingValues.calculateBottomPadding().roundToPx()\n\n        val relaxedConstraints = constraints.copy(minWidth = 0, minHeight = 0)\n\n        // measure leading icon\n        val leadingPlaceable =\n            measurables.fastFirstOrNull { it.layoutId == LeadingId }?.measure(relaxedConstraints)\n        occupiedSpaceHorizontally += leadingPlaceable.widthOrZero\n        occupiedSpaceVertically = max(occupiedSpaceVertically, leadingPlaceable.heightOrZero)\n\n        // measure trailing icon\n        val trailingPlaceable =\n            measurables\n                .fastFirstOrNull { it.layoutId == TrailingId }\n                ?.measure(relaxedConstraints.offset(horizontal = -occupiedSpaceHorizontally))\n        occupiedSpaceHorizontally += trailingPlaceable.widthOrZero\n        occupiedSpaceVertically = max(occupiedSpaceVertically, trailingPlaceable.heightOrZero)\n\n        // measure prefix\n        val prefixPlaceable =\n            measurables\n                .fastFirstOrNull { it.layoutId == PrefixId }\n                ?.measure(relaxedConstraints.offset(horizontal = -occupiedSpaceHorizontally))\n        occupiedSpaceHorizontally += prefixPlaceable.widthOrZero\n        occupiedSpaceVertically = max(occupiedSpaceVertically, prefixPlaceable.heightOrZero)\n\n        // measure suffix\n        val suffixPlaceable =\n            measurables\n                .fastFirstOrNull { it.layoutId == SuffixId }\n                ?.measure(relaxedConstraints.offset(horizontal = -occupiedSpaceHorizontally))\n        occupiedSpaceHorizontally += suffixPlaceable.widthOrZero\n        occupiedSpaceVertically = max(occupiedSpaceVertically, suffixPlaceable.heightOrZero)\n\n        // measure label\n        val isLabelAbove = labelPosition is TextFieldLabelPosition.Above\n        val labelMeasurable = measurables.fastFirstOrNull { it.layoutId == LabelId }\n        var labelPlaceable: Placeable? = null\n        val labelIntrinsicHeight: Int\n        if (!isLabelAbove) {\n            // if label is not Above, we can measure it like normal\n            val totalHorizontalPadding =\n                paddingValues.calculateLeftPadding(layoutDirection).roundToPx() +\n                    paddingValues.calculateRightPadding(layoutDirection).roundToPx()\n            val labelHorizontalConstraintOffset =\n                lerp(\n                    occupiedSpaceHorizontally + totalHorizontalPadding, // label in middle\n                    totalHorizontalPadding, // label in outline\n                    labelProgress,\n                )\n            val labelConstraints =\n                relaxedConstraints.offset(\n                    horizontal = -labelHorizontalConstraintOffset,\n                    vertical = -bottomPadding,\n                )\n            labelPlaceable = labelMeasurable?.measure(labelConstraints)\n            val labelSize =\n                labelPlaceable?.let { Size(it.width.toFloat(), it.height.toFloat()) } ?: Size.Zero\n            onLabelMeasured(labelSize)\n            labelIntrinsicHeight = 0\n        } else {\n            // if label is Above, it must be measured after other elements, but we\n            // reserve space for it using its intrinsic height as a heuristic\n            labelIntrinsicHeight = labelMeasurable?.minIntrinsicHeight(constraints.minWidth) ?: 0\n        }\n\n        // supporting text must be measured after other elements, but we\n        // reserve space for it using its intrinsic height as a heuristic\n        val supportingMeasurable = measurables.fastFirstOrNull { it.layoutId == SupportingId }\n        val supportingIntrinsicHeight =\n            supportingMeasurable?.minIntrinsicHeight(constraints.minWidth) ?: 0\n\n        // measure text field\n        val topPadding =\n            if (isLabelAbove) {\n                paddingValues.calculateTopPadding().roundToPx()\n            } else {\n                max(\n                    labelPlaceable.heightOrZero / 2,\n                    paddingValues.calculateTopPadding().roundToPx(),\n                )\n            }\n        val textConstraints =\n            constraints\n                .offset(\n                    horizontal = -occupiedSpaceHorizontally,\n                    vertical =\n                        -bottomPadding -\n                            topPadding -\n                            labelIntrinsicHeight -\n                            supportingIntrinsicHeight,\n                )\n                .copy(minHeight = 0)\n        val textFieldPlaceable =\n            measurables.fastFirst { it.layoutId == TextFieldId }.measure(textConstraints)\n\n        // measure placeholder\n        val placeholderConstraints = textConstraints.copy(minWidth = 0)\n        val placeholderPlaceable =\n            measurables\n                .fastFirstOrNull { it.layoutId == PlaceholderId }\n                ?.measure(placeholderConstraints)\n\n        occupiedSpaceVertically =\n            max(\n                occupiedSpaceVertically,\n                max(textFieldPlaceable.heightOrZero, placeholderPlaceable.heightOrZero) +\n                    topPadding +\n                    bottomPadding,\n            )\n\n        val width =\n            calculateWidth(\n                leadingPlaceableWidth = leadingPlaceable.widthOrZero,\n                trailingPlaceableWidth = trailingPlaceable.widthOrZero,\n                prefixPlaceableWidth = prefixPlaceable.widthOrZero,\n                suffixPlaceableWidth = suffixPlaceable.widthOrZero,\n                textFieldPlaceableWidth = textFieldPlaceable.width,\n                labelPlaceableWidth = labelPlaceable.widthOrZero,\n                placeholderPlaceableWidth = placeholderPlaceable.widthOrZero,\n                constraints = constraints,\n                labelProgress = labelProgress,\n            )\n\n        if (isLabelAbove) {\n            // now that we know the width, measure label\n            val labelConstraints =\n                relaxedConstraints.copy(maxHeight = labelIntrinsicHeight, maxWidth = width)\n            labelPlaceable = labelMeasurable?.measure(labelConstraints)\n            val labelSize =\n                labelPlaceable?.let { Size(it.width.toFloat(), it.height.toFloat()) } ?: Size.Zero\n            onLabelMeasured(labelSize)\n        }\n\n        // measure supporting text\n        val supportingConstraints =\n            relaxedConstraints\n                .offset(vertical = -occupiedSpaceVertically)\n                .copy(minHeight = 0, maxWidth = width)\n        val supportingPlaceable = supportingMeasurable?.measure(supportingConstraints)\n        val supportingHeight = supportingPlaceable.heightOrZero\n\n        val totalHeight =\n            calculateHeight(\n                leadingHeight = leadingPlaceable.heightOrZero,\n                trailingHeight = trailingPlaceable.heightOrZero,\n                prefixHeight = prefixPlaceable.heightOrZero,\n                suffixHeight = suffixPlaceable.heightOrZero,\n                textFieldHeight = textFieldPlaceable.height,\n                labelHeight = labelPlaceable.heightOrZero,\n                placeholderHeight = placeholderPlaceable.heightOrZero,\n                supportingHeight = supportingPlaceable.heightOrZero,\n                constraints = constraints,\n                isLabelAbove = isLabelAbove,\n                labelProgress = labelProgress,\n            )\n        val height =\n            totalHeight - supportingHeight - (if (isLabelAbove) labelPlaceable.heightOrZero else 0)\n\n        val containerPlaceable =\n            measurables\n                .fastFirst { it.layoutId == ContainerId }\n                .measure(\n                    Constraints(\n                        minWidth = if (width != Constraints.Infinity) width else 0,\n                        maxWidth = width,\n                        minHeight = if (height != Constraints.Infinity) height else 0,\n                        maxHeight = height,\n                    )\n                )\n        return layout(width, totalHeight) {\n            place(\n                totalHeight = totalHeight,\n                width = width,\n                leadingPlaceable = leadingPlaceable,\n                trailingPlaceable = trailingPlaceable,\n                prefixPlaceable = prefixPlaceable,\n                suffixPlaceable = suffixPlaceable,\n                textFieldPlaceable = textFieldPlaceable,\n                labelPlaceable = labelPlaceable,\n                placeholderPlaceable = placeholderPlaceable,\n                containerPlaceable = containerPlaceable,\n                supportingPlaceable = supportingPlaceable,\n                density = density,\n                layoutDirection = layoutDirection,\n                isLabelAbove = isLabelAbove,\n                labelProgress = labelProgress,\n                iconPadding = horizontalIconPadding.toPx(),\n            )\n        }\n    }\n\n    override fun IntrinsicMeasureScope.maxIntrinsicHeight(\n        measurables: List<IntrinsicMeasurable>,\n        width: Int,\n    ): Int {\n        return intrinsicHeight(measurables, width) { intrinsicMeasurable, w ->\n            intrinsicMeasurable.maxIntrinsicHeight(w)\n        }\n    }\n\n    override fun IntrinsicMeasureScope.minIntrinsicHeight(\n        measurables: List<IntrinsicMeasurable>,\n        width: Int,\n    ): Int {\n        return intrinsicHeight(measurables, width) { intrinsicMeasurable, w ->\n            intrinsicMeasurable.minIntrinsicHeight(w)\n        }\n    }\n\n    override fun IntrinsicMeasureScope.maxIntrinsicWidth(\n        measurables: List<IntrinsicMeasurable>,\n        height: Int,\n    ): Int {\n        return intrinsicWidth(measurables, height) { intrinsicMeasurable, h ->\n            intrinsicMeasurable.maxIntrinsicWidth(h)\n        }\n    }\n\n    override fun IntrinsicMeasureScope.minIntrinsicWidth(\n        measurables: List<IntrinsicMeasurable>,\n        height: Int,\n    ): Int {\n        return intrinsicWidth(measurables, height) { intrinsicMeasurable, h ->\n            intrinsicMeasurable.minIntrinsicWidth(h)\n        }\n    }\n\n    private fun IntrinsicMeasureScope.intrinsicWidth(\n        measurables: List<IntrinsicMeasurable>,\n        height: Int,\n        intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int,\n    ): Int {\n        val textFieldWidth =\n            intrinsicMeasurer(measurables.fastFirst { it.layoutId == TextFieldId }, height)\n        val labelWidth =\n            measurables\n                .fastFirstOrNull { it.layoutId == LabelId }\n                ?.let { intrinsicMeasurer(it, height) } ?: 0\n        val trailingWidth =\n            measurables\n                .fastFirstOrNull { it.layoutId == TrailingId }\n                ?.let { intrinsicMeasurer(it, height) } ?: 0\n        val leadingWidth =\n            measurables\n                .fastFirstOrNull { it.layoutId == LeadingId }\n                ?.let { intrinsicMeasurer(it, height) } ?: 0\n        val prefixWidth =\n            measurables\n                .fastFirstOrNull { it.layoutId == PrefixId }\n                ?.let { intrinsicMeasurer(it, height) } ?: 0\n        val suffixWidth =\n            measurables\n                .fastFirstOrNull { it.layoutId == SuffixId }\n                ?.let { intrinsicMeasurer(it, height) } ?: 0\n        val placeholderWidth =\n            measurables\n                .fastFirstOrNull { it.layoutId == PlaceholderId }\n                ?.let { intrinsicMeasurer(it, height) } ?: 0\n        return calculateWidth(\n            leadingPlaceableWidth = leadingWidth,\n            trailingPlaceableWidth = trailingWidth,\n            prefixPlaceableWidth = prefixWidth,\n            suffixPlaceableWidth = suffixWidth,\n            textFieldPlaceableWidth = textFieldWidth,\n            labelPlaceableWidth = labelWidth,\n            placeholderPlaceableWidth = placeholderWidth,\n            constraints = Constraints(),\n            labelProgress = labelProgress(),\n        )\n    }\n\n    private fun IntrinsicMeasureScope.intrinsicHeight(\n        measurables: List<IntrinsicMeasurable>,\n        width: Int,\n        intrinsicMeasurer: (IntrinsicMeasurable, Int) -> Int,\n    ): Int {\n        val labelProgress = labelProgress()\n        var remainingWidth = width\n        val leadingHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == LeadingId }\n                ?.let {\n                    remainingWidth =\n                        remainingWidth.subtractConstraintSafely(\n                            it.maxIntrinsicWidth(Constraints.Infinity)\n                        )\n                    intrinsicMeasurer(it, width)\n                } ?: 0\n        val trailingHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == TrailingId }\n                ?.let {\n                    remainingWidth =\n                        remainingWidth.subtractConstraintSafely(\n                            it.maxIntrinsicWidth(Constraints.Infinity)\n                        )\n                    intrinsicMeasurer(it, width)\n                } ?: 0\n\n        val labelHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == LabelId }\n                ?.let { intrinsicMeasurer(it, lerp(remainingWidth, width, labelProgress)) } ?: 0\n\n        val prefixHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == PrefixId }\n                ?.let {\n                    val height = intrinsicMeasurer(it, remainingWidth)\n                    remainingWidth =\n                        remainingWidth.subtractConstraintSafely(\n                            it.maxIntrinsicWidth(Constraints.Infinity)\n                        )\n                    height\n                } ?: 0\n        val suffixHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == SuffixId }\n                ?.let {\n                    val height = intrinsicMeasurer(it, remainingWidth)\n                    remainingWidth =\n                        remainingWidth.subtractConstraintSafely(\n                            it.maxIntrinsicWidth(Constraints.Infinity)\n                        )\n                    height\n                } ?: 0\n\n        val textFieldHeight =\n            intrinsicMeasurer(measurables.fastFirst { it.layoutId == TextFieldId }, remainingWidth)\n\n        val placeholderHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == PlaceholderId }\n                ?.let { intrinsicMeasurer(it, remainingWidth) } ?: 0\n\n        val supportingHeight =\n            measurables\n                .fastFirstOrNull { it.layoutId == SupportingId }\n                ?.let { intrinsicMeasurer(it, width) } ?: 0\n\n        return calculateHeight(\n            leadingHeight = leadingHeight,\n            trailingHeight = trailingHeight,\n            prefixHeight = prefixHeight,\n            suffixHeight = suffixHeight,\n            textFieldHeight = textFieldHeight,\n            labelHeight = labelHeight,\n            placeholderHeight = placeholderHeight,\n            supportingHeight = supportingHeight,\n            constraints = Constraints(),\n            isLabelAbove = labelPosition is TextFieldLabelPosition.Above,\n            labelProgress = labelProgress,\n        )\n    }\n\n    /**\n     * Calculate the width of the [OutlinedTextField] given all elements that should be placed\n     * inside.\n     */\n    private fun Density.calculateWidth(\n        leadingPlaceableWidth: Int,\n        trailingPlaceableWidth: Int,\n        prefixPlaceableWidth: Int,\n        suffixPlaceableWidth: Int,\n        textFieldPlaceableWidth: Int,\n        labelPlaceableWidth: Int,\n        placeholderPlaceableWidth: Int,\n        constraints: Constraints,\n        labelProgress: Float,\n    ): Int {\n        val affixTotalWidth = prefixPlaceableWidth + suffixPlaceableWidth\n        val middleSection =\n            maxOf(\n                textFieldPlaceableWidth + affixTotalWidth,\n                placeholderPlaceableWidth + affixTotalWidth,\n                // Prefix/suffix does not get applied to label\n                lerp(labelPlaceableWidth, 0, labelProgress),\n            )\n        val wrappedWidth = leadingPlaceableWidth + middleSection + trailingPlaceableWidth\n\n        // Actual LayoutDirection doesn't matter; we only need the sum\n        val labelHorizontalPadding =\n            (paddingValues.calculateLeftPadding(LayoutDirection.Ltr) +\n                    paddingValues.calculateRightPadding(LayoutDirection.Ltr))\n                .toPx()\n        val focusedLabelWidth =\n            ((labelPlaceableWidth + labelHorizontalPadding) * labelProgress).roundToInt()\n        return constraints.constrainWidth(max(wrappedWidth, focusedLabelWidth))\n    }\n\n    /**\n     * Calculate the height of the [OutlinedTextField] given all elements that should be placed\n     * inside. This includes the supporting text, if it exists, even though this element is not\n     * \"visually\" inside the text field.\n     */\n    private fun Density.calculateHeight(\n        leadingHeight: Int,\n        trailingHeight: Int,\n        prefixHeight: Int,\n        suffixHeight: Int,\n        textFieldHeight: Int,\n        labelHeight: Int,\n        placeholderHeight: Int,\n        supportingHeight: Int,\n        constraints: Constraints,\n        isLabelAbove: Boolean,\n        labelProgress: Float,\n    ): Int {\n        val inputFieldHeight =\n            maxOf(\n                textFieldHeight,\n                placeholderHeight,\n                prefixHeight,\n                suffixHeight,\n                if (isLabelAbove) 0 else lerp(labelHeight, 0, labelProgress),\n            )\n        val topPadding = paddingValues.calculateTopPadding().toPx()\n        val actualTopPadding =\n            if (isLabelAbove) {\n                topPadding\n            } else {\n                lerp(topPadding, max(topPadding, labelHeight / 2f), labelProgress)\n            }\n        val bottomPadding = paddingValues.calculateBottomPadding().toPx()\n        val middleSectionHeight = actualTopPadding + inputFieldHeight + bottomPadding\n\n        return constraints.constrainHeight(\n            (if (isLabelAbove) labelHeight else 0) +\n                maxOf(leadingHeight, trailingHeight, middleSectionHeight.roundToInt()) +\n                supportingHeight\n        )\n    }\n\n    /**\n     * Places the provided text field, placeholder, label, optional leading and trailing icons\n     * inside the [OutlinedTextField]\n     */\n    private fun Placeable.PlacementScope.place(\n        totalHeight: Int,\n        width: Int,\n        leadingPlaceable: Placeable?,\n        trailingPlaceable: Placeable?,\n        prefixPlaceable: Placeable?,\n        suffixPlaceable: Placeable?,\n        textFieldPlaceable: Placeable,\n        labelPlaceable: Placeable?,\n        placeholderPlaceable: Placeable?,\n        containerPlaceable: Placeable,\n        supportingPlaceable: Placeable?,\n        density: Float,\n        layoutDirection: LayoutDirection,\n        isLabelAbove: Boolean,\n        labelProgress: Float,\n        iconPadding: Float,\n    ) {\n        val yOffset = if (isLabelAbove) labelPlaceable.heightOrZero else 0\n\n        // place container\n        containerPlaceable.place(0, yOffset)\n\n        // Most elements should be positioned w.r.t the text field's \"visual\" height, i.e.,\n        // excluding the label (if it's Above) and the supporting text on bottom\n        val height =\n            totalHeight -\n                supportingPlaceable.heightOrZero -\n                (if (isLabelAbove) labelPlaceable.heightOrZero else 0)\n\n        val topPadding = (paddingValues.calculateTopPadding().value * density).roundToInt()\n\n        // placed center vertically and to the start edge horizontally\n        leadingPlaceable?.placeRelative(\n            0,\n            yOffset + Alignment.CenterVertically.align(leadingPlaceable.height, height),\n        )\n\n        // label position is animated\n        // in single line text field, label is centered vertically before animation starts\n        labelPlaceable?.let {\n            val startY =\n                when {\n                    isLabelAbove -> 0\n                    singleLine -> Alignment.CenterVertically.align(it.height, height)\n                    else -> topPadding\n                }\n            val endY =\n                when {\n                    isLabelAbove -> 0\n                    else -> -(it.height / 2)\n                }\n            val positionY = lerp(startY, endY, labelProgress)\n\n            if (isLabelAbove) {\n                val positionX =\n                    labelPosition.minimizedAlignment.align(\n                        size = labelPlaceable.width,\n                        space = width,\n                        layoutDirection = layoutDirection,\n                    )\n                // Not placeRelative because alignment already handles RTL\n                labelPlaceable.place(positionX, positionY)\n            } else {\n                val startPadding =\n                    paddingValues.calculateStartPadding(layoutDirection).value * density\n                val endPadding = paddingValues.calculateEndPadding(layoutDirection).value * density\n                val leadingPlusPadding =\n                    if (leadingPlaceable == null) {\n                        startPadding\n                    } else {\n                        leadingPlaceable.width + (startPadding - iconPadding).coerceAtLeast(0f)\n                    }\n                val trailingPlusPadding =\n                    if (trailingPlaceable == null) {\n                        endPadding\n                    } else {\n                        trailingPlaceable.width + (endPadding - iconPadding).coerceAtLeast(0f)\n                    }\n                val leftPadding =\n                    if (layoutDirection == LayoutDirection.Ltr) startPadding else endPadding\n                val leftIconPlusPadding =\n                    if (layoutDirection == LayoutDirection.Ltr) leadingPlusPadding\n                    else trailingPlusPadding\n                val startX =\n                    labelPosition.expandedAlignment.align(\n                        size = labelPlaceable.width,\n                        space = width - (leadingPlusPadding + trailingPlusPadding).roundToInt(),\n                        layoutDirection = layoutDirection,\n                    ) + leftIconPlusPadding\n\n                val endX =\n                    labelPosition.minimizedAlignment.align(\n                        size = labelPlaceable.width,\n                        space = width - (startPadding + endPadding).roundToInt(),\n                        layoutDirection = layoutDirection,\n                    ) + leftPadding\n                val positionX = lerp(startX, endX, labelProgress).roundToInt()\n                // Not placeRelative because alignment already handles RTL\n                labelPlaceable.place(positionX, positionY)\n            }\n        }\n\n        fun calculateVerticalPosition(placeable: Placeable): Int {\n            val defaultPosition =\n                yOffset +\n                    if (singleLine) {\n                        // Single line text fields have text components centered vertically.\n                        Alignment.CenterVertically.align(placeable.height, height)\n                    } else {\n                        // Multiline text fields have text components aligned to top with padding.\n                        topPadding\n                    }\n            return if (labelPosition is TextFieldLabelPosition.Above) {\n                defaultPosition\n            } else {\n                // Ensure components are placed below label when it's in the border\n                max(defaultPosition, labelPlaceable.heightOrZero / 2)\n            }\n        }\n\n        prefixPlaceable?.placeRelative(\n            leadingPlaceable.widthOrZero,\n            calculateVerticalPosition(prefixPlaceable),\n        )\n\n        val textHorizontalPosition = leadingPlaceable.widthOrZero + prefixPlaceable.widthOrZero\n\n        textFieldPlaceable.placeRelative(\n            textHorizontalPosition,\n            calculateVerticalPosition(textFieldPlaceable),\n        )\n\n        // placed similar to the input text above\n        placeholderPlaceable?.placeRelative(\n            textHorizontalPosition,\n            calculateVerticalPosition(placeholderPlaceable),\n        )\n\n        suffixPlaceable?.placeRelative(\n            width - trailingPlaceable.widthOrZero - suffixPlaceable.width,\n            calculateVerticalPosition(suffixPlaceable),\n        )\n\n        // placed center vertically and to the end edge horizontally\n        trailingPlaceable?.placeRelative(\n            width - trailingPlaceable.width,\n            yOffset + Alignment.CenterVertically.align(trailingPlaceable.height, height),\n        )\n\n        // place supporting text\n        supportingPlaceable?.placeRelative(0, yOffset + height)\n    }\n}\n\ninternal fun Modifier.outlineCutout(\n    labelSize: () -> Size,\n    alignment: Alignment.Horizontal,\n    paddingValues: PaddingValues,\n) =\n    this.drawWithContent {\n        val labelSizeValue = labelSize()\n        val labelWidth = labelSizeValue.width\n        if (labelWidth > 0f) {\n            val innerPadding = OutlinedTextFieldInnerPadding.toPx()\n            val leftPadding = paddingValues.calculateLeftPadding(layoutDirection).toPx()\n            val rightPadding = paddingValues.calculateRightPadding(layoutDirection).toPx()\n            val labelCenter =\n                alignment.align(\n                    size = labelWidth.roundToInt(),\n                    space = (size.width - leftPadding - rightPadding).roundToInt(),\n                    layoutDirection = layoutDirection,\n                ) + leftPadding + (labelWidth / 2)\n            val left = (labelCenter - (labelWidth / 2) - innerPadding).coerceAtLeast(0f)\n            val right = (labelCenter + (labelWidth / 2) + innerPadding).coerceAtMost(size.width)\n            val labelHeight = labelSizeValue.height\n            // using label height as a cutout area to make sure that no hairline artifacts are\n            // left when we clip the border\n            clipRect(left, -labelHeight / 2, right, labelHeight / 2, ClipOp.Difference) {\n                this@drawWithContent.drawContent()\n            }\n        } else {\n            this@drawWithContent.drawContent()\n        }\n    }\n\nprivate val OutlinedTextFieldInnerPadding = 4.dp\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/BottomSheetScaffold.kt\n```kotlin\n/*\n * Copyright 2023 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.animation.core.FiniteAnimationSpec\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.gestures.AnchoredDraggableDefaults\nimport androidx.compose.foundation.gestures.DraggableAnchors\nimport androidx.compose.foundation.gestures.Orientation\nimport androidx.compose.foundation.gestures.anchoredDraggable\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.requiredHeightIn\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.material3.SheetValue.Expanded\nimport androidx.compose.material3.SheetValue.Hidden\nimport androidx.compose.material3.SheetValue.PartiallyExpanded\nimport androidx.compose.material3.internal.Strings\nimport androidx.compose.material3.internal.draggableAnchors\nimport androidx.compose.material3.internal.getString\nimport androidx.compose.material3.tokens.MotionSchemeKeyTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.input.nestedscroll.nestedScroll\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.semantics.collapse\nimport androidx.compose.ui.semantics.dismiss\nimport androidx.compose.ui.semantics.expand\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastForEach\nimport androidx.compose.ui.util.fastMap\nimport androidx.compose.ui.util.fastMaxOfOrNull\nimport kotlin.math.max\nimport kotlin.math.roundToInt\nimport kotlinx.coroutines.launch\n\n/**\n * [Material Design standard bottom sheet\n * scaffold](https://m3.material.io/components/bottom-sheets/overview)\n *\n * Standard bottom sheets co-exist with the screen’s main UI region and allow for simultaneously\n * viewing and interacting with both regions. They are commonly used to keep a feature or secondary\n * content visible on screen when content in main UI region is frequently scrolled or panned.\n *\n * ![Bottom sheet\n * image](https://developer.android.com/images/reference/androidx/compose/material3/bottom_sheet.png)\n *\n * This component provides API to put together several material components to construct your screen,\n * by ensuring proper layout strategy for them and collecting necessary data so these components\n * will work together correctly.\n *\n * A simple example of a standard bottom sheet looks like this:\n *\n * @sample androidx.compose.material3.samples.SimpleBottomSheetScaffoldSample\n * @param sheetContent the content of the bottom sheet\n * @param modifier the [Modifier] to be applied to the root of the scaffold\n * @param scaffoldState the state of the bottom sheet scaffold\n * @param sheetPeekHeight the height of the bottom sheet when it is collapsed\n * @param sheetMaxWidth [Dp] that defines what the maximum width the sheet will take. Pass in\n *   [Dp.Unspecified] for a sheet that spans the entire screen width.\n * @param sheetShape the shape of the bottom sheet\n * @param sheetContainerColor the background color of the bottom sheet\n * @param sheetContentColor the preferred content color provided by the bottom sheet to its\n *   children. Defaults to the matching content color for [sheetContainerColor], or if that is not a\n *   color from the theme, this will keep the same content color set above the bottom sheet.\n * @param sheetTonalElevation when [sheetContainerColor] is [ColorScheme.surface], a translucent\n *   primary color overlay is applied on top of the container. A higher tonal elevation value will\n *   result in a darker color in light theme and lighter color in dark theme. See also: [Surface].\n * @param sheetShadowElevation the shadow elevation of the bottom sheet\n * @param sheetDragHandle optional visual marker to pull the scaffold's bottom sheet\n * @param sheetSwipeEnabled whether the sheet swiping is enabled and should react to the user's\n *   input\n * @param topBar top app bar of the screen, typically a [TopAppBar]\n * @param snackbarHost component to host [Snackbar]s that are pushed to be shown via\n *   [SnackbarHostState.showSnackbar], typically a [SnackbarHost]\n * @param containerColor the color used for the background of this scaffold. Use [Color.Transparent]\n *   to have no color.\n * @param contentColor the preferred color for content inside this scaffold. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param content content of the screen. The lambda receives a [PaddingValues] that should be\n *   applied to the content root via [Modifier.padding] and [Modifier.consumeWindowInsets] to\n *   properly offset top and bottom bars. If using [Modifier.verticalScroll], apply this modifier to\n *   the child of the scroll, and not on the scroll itself.\n */\n@Composable\n@ExperimentalMaterial3Api\nfun BottomSheetScaffold(\n    sheetContent: @Composable ColumnScope.() -> Unit,\n    modifier: Modifier = Modifier,\n    scaffoldState: BottomSheetScaffoldState = rememberBottomSheetScaffoldState(),\n    sheetPeekHeight: Dp = BottomSheetDefaults.SheetPeekHeight,\n    sheetMaxWidth: Dp = BottomSheetDefaults.SheetMaxWidth,\n    sheetShape: Shape = BottomSheetDefaults.ExpandedShape,\n    sheetContainerColor: Color = BottomSheetDefaults.ContainerColor,\n    sheetContentColor: Color = contentColorFor(sheetContainerColor),\n    sheetTonalElevation: Dp = 0.dp,\n    sheetShadowElevation: Dp = BottomSheetDefaults.Elevation,\n    sheetDragHandle: @Composable (() -> Unit)? = { BottomSheetDefaults.DragHandle() },\n    sheetSwipeEnabled: Boolean = true,\n    topBar: @Composable (() -> Unit)? = null,\n    snackbarHost: @Composable (SnackbarHostState) -> Unit = { SnackbarHost(it) },\n    containerColor: Color = MaterialTheme.colorScheme.surface,\n    contentColor: Color = contentColorFor(containerColor),\n    content: @Composable (PaddingValues) -> Unit,\n) {\n    Box(modifier.fillMaxSize().background(containerColor)) {\n        // Using composition local provider instead of Surface as Surface implements .clip() which\n        // intercepts touch events in testing.\n        CompositionLocalProvider(LocalContentColor provides contentColor) {\n            BottomSheetScaffoldLayout(\n                topBar = topBar,\n                body = { content(PaddingValues(bottom = sheetPeekHeight)) },\n                snackbarHost = { snackbarHost(scaffoldState.snackbarHostState) },\n                sheetOffset = { scaffoldState.bottomSheetState.requireOffset() },\n                sheetState = scaffoldState.bottomSheetState,\n                bottomSheet = {\n                    StandardBottomSheet(\n                        state = scaffoldState.bottomSheetState,\n                        peekHeight = sheetPeekHeight,\n                        sheetMaxWidth = sheetMaxWidth,\n                        sheetSwipeEnabled = sheetSwipeEnabled,\n                        shape = sheetShape,\n                        containerColor = sheetContainerColor,\n                        contentColor = sheetContentColor,\n                        tonalElevation = sheetTonalElevation,\n                        shadowElevation = sheetShadowElevation,\n                        dragHandle = sheetDragHandle,\n                        content = sheetContent,\n                    )\n                },\n            )\n        }\n    }\n}\n\n/**\n * State of the [BottomSheetScaffold] composable.\n *\n * @param bottomSheetState the state of the persistent bottom sheet\n * @param snackbarHostState the [SnackbarHostState] used to show snackbars inside the scaffold\n */\n@ExperimentalMaterial3Api\n@Stable\nclass BottomSheetScaffoldState(\n    val bottomSheetState: SheetState,\n    val snackbarHostState: SnackbarHostState,\n)\n\n/**\n * Create and [remember] a [BottomSheetScaffoldState].\n *\n * @param bottomSheetState the state of the standard bottom sheet. See\n *   [rememberStandardBottomSheetState]\n * @param snackbarHostState the [SnackbarHostState] used to show snackbars inside the scaffold\n */\n@Composable\n@ExperimentalMaterial3Api\nfun rememberBottomSheetScaffoldState(\n    bottomSheetState: SheetState = rememberStandardBottomSheetState(),\n    snackbarHostState: SnackbarHostState = remember { SnackbarHostState() },\n): BottomSheetScaffoldState {\n    return remember(bottomSheetState, snackbarHostState) {\n        BottomSheetScaffoldState(\n            bottomSheetState = bottomSheetState,\n            snackbarHostState = snackbarHostState,\n        )\n    }\n}\n\n/**\n * Create and [remember] a [SheetState] for [BottomSheetScaffold].\n *\n * @param initialValue the initial value of the state. Should be either [PartiallyExpanded] or\n *   [Expanded] if [skipHiddenState] is true\n * @param confirmValueChange optional callback invoked to confirm or veto a pending state change\n * @param [skipHiddenState] whether Hidden state is skipped for [BottomSheetScaffold]\n */\n@Composable\n@ExperimentalMaterial3Api\nfun rememberStandardBottomSheetState(\n    initialValue: SheetValue = PartiallyExpanded,\n    confirmValueChange: (SheetValue) -> Boolean = { true },\n    skipHiddenState: Boolean = true,\n) =\n    rememberSheetState(\n        confirmValueChange = confirmValueChange,\n        initialValue = initialValue,\n        skipHiddenState = skipHiddenState,\n    )\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nprivate fun StandardBottomSheet(\n    state: SheetState,\n    peekHeight: Dp,\n    sheetMaxWidth: Dp,\n    sheetSwipeEnabled: Boolean,\n    shape: Shape,\n    containerColor: Color,\n    contentColor: Color,\n    tonalElevation: Dp,\n    shadowElevation: Dp,\n    dragHandle: @Composable (() -> Unit)?,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    // TODO Load the motionScheme tokens from the component tokens file\n    val anchoredDraggableMotion: FiniteAnimationSpec<Float> =\n        MotionSchemeKeyTokens.DefaultSpatial.value()\n    val showMotion: FiniteAnimationSpec<Float> = MotionSchemeKeyTokens.DefaultSpatial.value()\n    val hideMotion: FiniteAnimationSpec<Float> = MotionSchemeKeyTokens.FastEffects.value()\n\n    SideEffect {\n        state.showMotionSpec = showMotion\n        state.hideMotionSpec = hideMotion\n        state.anchoredDraggableMotionSpec = anchoredDraggableMotion\n    }\n\n    val scope = rememberCoroutineScope()\n    val orientation = Orientation.Vertical\n    val peekHeightPx = with(LocalDensity.current) { peekHeight.toPx() }\n    val anchoredDraggableFlingBehavior =\n        AnchoredDraggableDefaults.flingBehavior(\n            state = state.anchoredDraggableState,\n            positionalThreshold = { _ -> state.positionalThreshold.invoke() },\n            animationSpec = BottomSheetAnimationSpec,\n        )\n\n    val nestedScroll =\n        if (sheetSwipeEnabled) {\n            Modifier.nestedScroll(\n                remember(state.anchoredDraggableState) {\n                    ConsumeSwipeWithinBottomSheetBoundsNestedScrollConnection(\n                        sheetState = state,\n                        orientation = orientation,\n                        flingBehavior = anchoredDraggableFlingBehavior,\n                    )\n                }\n            )\n        } else {\n            Modifier\n        }\n    Surface(\n        modifier =\n            Modifier.widthIn(max = sheetMaxWidth)\n                .fillMaxWidth()\n                .requiredHeightIn(min = peekHeight)\n                .then(nestedScroll)\n                .draggableAnchors(state.anchoredDraggableState, orientation) {\n                    sheetSize,\n                    constraints ->\n                    val layoutHeight = constraints.maxHeight.toFloat()\n                    val sheetHeight = sheetSize.height.toFloat()\n\n                    val newAnchors = DraggableAnchors {\n                        val isHiddenAnchorAvailable =\n                            sheetHeight == 0f || peekHeightPx == 0f || !state.skipHiddenState\n\n                        // We are preserving ambiguous anchor reconciliation for first layout pass.\n                        // This handles the use case where sheetPeekHeight is backed by a mutable\n                        // value which is backed by 0.dp before being recalculated. We can assume\n                        // the state is in its first pass by asserting anchor sizes are zero, as we\n                        // enforce at least 1 anchor below. We then settle at partial as this is\n                        // the anchor external users have access to via sheetPeekHeight API.\n                        val isInitialLayout = state.anchoredDraggableState.anchors.size == 0\n                        val isStableAtPartial =\n                            state.currentValue == PartiallyExpanded && !state.isAnimationRunning\n\n                        val isAmbiguousPartialAllowed =\n                            peekHeightPx == 0f && (isInitialLayout || isStableAtPartial)\n\n                        val isPartiallyExpandedAnchorAvailable =\n                            !state.skipPartiallyExpanded &&\n                                (peekHeightPx > 0f || isAmbiguousPartialAllowed) &&\n                                peekHeightPx != sheetHeight\n\n                        val isExpandedAnchorAvailable = sheetHeight > 0f\n\n                        require(\n                            isHiddenAnchorAvailable ||\n                                isPartiallyExpandedAnchorAvailable ||\n                                isExpandedAnchorAvailable\n                        ) {\n                            \"BottomSheetScaffold: Require at least 1 anchor to be initialized\"\n                        }\n\n                        if (isPartiallyExpandedAnchorAvailable) {\n                            PartiallyExpanded at (layoutHeight - peekHeightPx)\n                        }\n                        if (isHiddenAnchorAvailable) {\n                            Hidden at layoutHeight\n                        }\n                        if (isExpandedAnchorAvailable) {\n                            Expanded at layoutHeight - sheetHeight\n                        }\n                    }\n                    val newTarget =\n                        when (val oldTarget = state.targetValue) {\n                            Hidden -> if (newAnchors.hasPositionFor(Hidden)) Hidden else oldTarget\n                            PartiallyExpanded ->\n                                when {\n                                    newAnchors.hasPositionFor(PartiallyExpanded) ->\n                                        PartiallyExpanded\n\n                                    newAnchors.hasPositionFor(Expanded) -> Expanded\n                                    newAnchors.hasPositionFor(Hidden) -> Hidden\n                                    else -> oldTarget\n                                }\n\n                            Expanded ->\n                                if (newAnchors.hasPositionFor(Expanded)) Expanded else Hidden\n                        }\n                    return@draggableAnchors newAnchors to newTarget\n                }\n                .anchoredDraggable(\n                    state = state.anchoredDraggableState,\n                    orientation = orientation,\n                    enabled = sheetSwipeEnabled,\n                    flingBehavior = anchoredDraggableFlingBehavior,\n                )\n                // Scale up the Surface vertically in case the sheet's offset overflows below the\n                // min anchor. This is done to avoid showing a gap when the sheet opens and bounces\n                // when it's applied with a bouncy motion. Note that the content inside the Surface\n                // is scaled back down to maintain its aspect ratio (see below).\n                .verticalScaleUp(state),\n        shape = shape,\n        color = containerColor,\n        contentColor = contentColor,\n        tonalElevation = tonalElevation,\n        shadowElevation = shadowElevation,\n    ) {\n        Column(\n            Modifier.fillMaxWidth()\n                // Scale the content down in case the sheet offset overflows below the min anchor.\n                // The wrapping Surface is scaled up, so this is done to maintain the content's\n                // aspect ratio.\n                .verticalScaleDown(state)\n        ) {\n            if (dragHandle != null) {\n                val partialExpandActionLabel =\n                    getString(Strings.BottomSheetPartialExpandDescription)\n                val dismissActionLabel = getString(Strings.BottomSheetDismissDescription)\n                val expandActionLabel = getString(Strings.BottomSheetExpandDescription)\n                DragHandleWithTooltip(\n                    modifier =\n                        Modifier.clickable {\n                                when (state.currentValue) {\n                                    Expanded ->\n                                        scope.launch {\n                                            if (!state.skipHiddenState) {\n                                                state.hide()\n                                            } else {\n                                                state.partialExpand()\n                                            }\n                                        }\n\n                                    PartiallyExpanded -> scope.launch { state.expand() }\n                                    else -> scope.launch { state.show() }\n                                }\n                            }\n                            .semantics(mergeDescendants = true) {\n                                with(state) {\n                                    // Provides semantics to interact with the bottomsheet if\n                                    // there is more than one anchor to swipe to and swiping is\n                                    // enabled.\n                                    if (\n                                        anchoredDraggableState.anchors.size > 1 && sheetSwipeEnabled\n                                    ) {\n                                        if (currentValue == PartiallyExpanded) {\n                                            expand(expandActionLabel) {\n                                                val canExpand = confirmValueChange(Expanded)\n                                                if (canExpand) {\n                                                    scope.launch { expand() }\n                                                }\n                                                return@expand canExpand\n                                            }\n                                        } else {\n                                            collapse(partialExpandActionLabel) {\n                                                val canPartiallyExpand =\n                                                    confirmValueChange(PartiallyExpanded)\n                                                scope.launch { partialExpand() }\n                                                return@collapse canPartiallyExpand\n                                            }\n                                        }\n                                        if (!state.skipHiddenState) {\n                                            dismiss(dismissActionLabel) {\n                                                val canHide = confirmValueChange(Hidden)\n                                                scope.launch { hide() }\n                                                return@dismiss canHide\n                                            }\n                                        }\n                                    }\n                                }\n                            },\n                    content = dragHandle,\n                )\n            }\n            content()\n        }\n    }\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nprivate fun BottomSheetScaffoldLayout(\n    topBar: @Composable (() -> Unit)?,\n    body: @Composable () -> Unit,\n    bottomSheet: @Composable () -> Unit,\n    snackbarHost: @Composable () -> Unit,\n    sheetOffset: () -> Float,\n    sheetState: SheetState,\n) {\n    Layout(\n        contents = listOf<@Composable () -> Unit>(topBar ?: {}, body, bottomSheet, snackbarHost)\n    ) {\n        (topBarMeasurables, bodyMeasurables, bottomSheetMeasurables, snackbarHostMeasurables),\n        constraints ->\n        val layoutWidth = constraints.maxWidth\n        val layoutHeight = constraints.maxHeight\n        val looseConstraints = constraints.copy(minWidth = 0, minHeight = 0)\n\n        val sheetPlaceables = bottomSheetMeasurables.fastMap { it.measure(looseConstraints) }\n\n        val topBarPlaceables = topBarMeasurables.fastMap { it.measure(looseConstraints) }\n        val topBarHeight = topBarPlaceables.fastMaxOfOrNull { it.height } ?: 0\n\n        val bodyConstraints = looseConstraints.copy(maxHeight = layoutHeight - topBarHeight)\n        val bodyPlaceables = bodyMeasurables.fastMap { it.measure(bodyConstraints) }\n\n        val snackbarPlaceables = snackbarHostMeasurables.fastMap { it.measure(looseConstraints) }\n\n        layout(layoutWidth, layoutHeight) {\n            val sheetWidth = sheetPlaceables.fastMaxOfOrNull { it.width } ?: 0\n            val sheetOffsetX = max(0, (layoutWidth - sheetWidth) / 2)\n\n            val snackbarWidth = snackbarPlaceables.fastMaxOfOrNull { it.width } ?: 0\n            val snackbarHeight = snackbarPlaceables.fastMaxOfOrNull { it.height } ?: 0\n            val snackbarOffsetX = (layoutWidth - snackbarWidth) / 2\n            val snackbarOffsetY =\n                when (sheetState.currentValue) {\n                    PartiallyExpanded -> sheetOffset().roundToInt() - snackbarHeight\n                    Expanded,\n                    Hidden -> layoutHeight - snackbarHeight\n                }\n\n            // Placement order is important for elevation\n            bodyPlaceables.fastForEach { it.placeRelative(0, topBarHeight) }\n            topBarPlaceables.fastForEach { it.placeRelative(0, 0) }\n            sheetPlaceables.fastForEach { it.placeRelative(sheetOffsetX, 0) }\n            snackbarPlaceables.fastForEach { it.placeRelative(snackbarOffsetX, snackbarOffsetY) }\n        }\n    }\n}\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/ModalBottomSheet.kt\n```kotlin\n/*\n * Copyright 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.animation.core.FiniteAnimationSpec\nimport androidx.compose.animation.core.animateFloatAsState\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.consumeWindowInsets\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.imePadding\nimport androidx.compose.material3.SheetValue.Expanded\nimport androidx.compose.material3.SheetValue.Hidden\nimport androidx.compose.material3.internal.Strings\nimport androidx.compose.material3.internal.getString\nimport androidx.compose.material3.tokens.MotionSchemeKeyTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment.Companion.TopCenter\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.semantics.isTraversalGroup\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport kotlinx.coroutines.launch\n\n/**\n * [Material Design modal bottom sheet](https://m3.material.io/components/bottom-sheets/overview)\n *\n * Modal bottom sheets are used as an alternative to inline menus or simple dialogs on mobile,\n * especially when offering a long list of action items, or when items require longer descriptions\n * and icons. Like dialogs, modal bottom sheets appear in front of app content, disabling all other\n * app functionality when they appear, and remaining on screen until confirmed, dismissed, or a\n * required action has been taken.\n *\n * ![Bottom sheet\n * image](https://developer.android.com/images/reference/androidx/compose/material3/bottom_sheet.png)\n *\n * A simple example of a modal bottom sheet looks like this:\n *\n * @sample androidx.compose.material3.samples.ModalBottomSheetSample\n * @param onDismissRequest Executes when the user clicks outside of the bottom sheet, after sheet\n *   animates to [Hidden].\n * @param modifier Optional [Modifier] for the bottom sheet.\n * @param sheetState The state of the bottom sheet.\n * @param sheetMaxWidth [Dp] that defines what the maximum width the sheet will take. Pass in\n *   [Dp.Unspecified] for a sheet that spans the entire screen width.\n * @param sheetGesturesEnabled Whether the bottom sheet can be interacted with by gestures.\n * @param shape The shape of the bottom sheet.\n * @param containerColor The color used for the background of this bottom sheet\n * @param contentColor The preferred color for content inside this bottom sheet. Defaults to either\n *   the matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param tonalElevation when [containerColor] is [ColorScheme.surface], a translucent primary color\n *   overlay is applied on top of the container. A higher tonal elevation value will result in a\n *   darker color in light theme and lighter color in dark theme. See also: [Surface].\n * @param scrimColor Color of the scrim that obscures content when the bottom sheet is open.\n * @param dragHandle Optional visual marker to swipe the bottom sheet.\n * @param contentWindowInsets callback which provides window insets to be passed to the bottom sheet\n *   content via [Modifier.windowInsetsPadding]. [ModalBottomSheet] will pre-emptively consume top\n *   insets based on it's current offset. This keeps content outside of the expected window insets\n *   at any position.\n * @param properties [ModalBottomSheetProperties] for further customization of this modal bottom\n *   sheet's window behavior.\n * @param content The content to be displayed inside the bottom sheet.\n */\n@Composable\n@ExperimentalMaterial3Api\nfun ModalBottomSheet(\n    onDismissRequest: () -> Unit,\n    modifier: Modifier = Modifier,\n    sheetState: SheetState = rememberModalBottomSheetState(),\n    sheetMaxWidth: Dp = BottomSheetDefaults.SheetMaxWidth,\n    sheetGesturesEnabled: Boolean = true,\n    shape: Shape = BottomSheetDefaults.ExpandedShape,\n    containerColor: Color = BottomSheetDefaults.ContainerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    tonalElevation: Dp = 0.dp,\n    scrimColor: Color = BottomSheetDefaults.ScrimColor,\n    dragHandle: @Composable (() -> Unit)? = { BottomSheetDefaults.DragHandle() },\n    contentWindowInsets: @Composable () -> WindowInsets = { BottomSheetDefaults.modalWindowInsets },\n    properties: ModalBottomSheetProperties = ModalBottomSheetProperties(),\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    // TODO Load the motionScheme tokens from the component tokens file\n    val anchoredDraggableMotion: FiniteAnimationSpec<Float> =\n        MotionSchemeKeyTokens.DefaultSpatial.value()\n    val showMotion: FiniteAnimationSpec<Float> = MotionSchemeKeyTokens.DefaultSpatial.value()\n    val hideMotion: FiniteAnimationSpec<Float> = MotionSchemeKeyTokens.FastEffects.value()\n\n    SideEffect {\n        sheetState.showMotionSpec = showMotion\n        sheetState.hideMotionSpec = hideMotion\n        sheetState.anchoredDraggableMotionSpec = anchoredDraggableMotion\n    }\n    val scope = rememberCoroutineScope()\n    val animateToDismiss: () -> Unit = {\n        if (sheetState.confirmValueChange(Hidden)) {\n            scope\n                .launch { sheetState.hide() }\n                .invokeOnCompletion {\n                    if (!sheetState.isVisible) {\n                        onDismissRequest()\n                    }\n                }\n        }\n    }\n\n    val settleToDismiss: () -> Unit = {\n        if (sheetState.currentValue == Expanded && sheetState.hasPartiallyExpandedState) {\n            // Smoothly animate away predictive back transformations since we are not fully\n            // dismissing. We don't need to do this in the else below because we want to\n            // preserve the predictive back transformations (scale) during the hide animation.\n            scope.launch { sheetState.partialExpand() }\n        } else { // Is expanded without collapsed state or is collapsed.\n            scope.launch { sheetState.hide() }.invokeOnCompletion { onDismissRequest() }\n        }\n    }\n\n    ModalBottomSheetDialog(\n        properties = properties,\n        contentColor = contentColor,\n        onDismissRequest = settleToDismiss,\n    ) {\n        Box(modifier = Modifier.fillMaxSize().imePadding().semantics { isTraversalGroup = true }) {\n            val sheetWindowInsets = remember(sheetState) { SheetWindowInsets(sheetState) }\n            val isScrimVisible: Boolean by remember {\n                derivedStateOf { sheetState.targetValue != Hidden }\n            }\n            val scrimAlpha by\n                animateFloatAsState(\n                    targetValue = if (isScrimVisible) 1f else 0f,\n                    animationSpec = MotionSchemeKeyTokens.DefaultEffects.value(),\n                    label = \"ScrimAlphaAnimation\",\n                )\n            Scrim(\n                contentDescription = getString(Strings.CloseSheet),\n                onClick = if (properties.shouldDismissOnClickOutside) animateToDismiss else null,\n                alpha = { scrimAlpha },\n                color = scrimColor,\n            )\n            BottomSheet(\n                modifier = modifier.align(TopCenter).consumeWindowInsets(sheetWindowInsets),\n                state = sheetState,\n                onDismissRequest = onDismissRequest,\n                maxWidth = sheetMaxWidth,\n                gesturesEnabled = sheetGesturesEnabled,\n                backHandlerEnabled = properties.shouldDismissOnBackPress,\n                shape = shape,\n                containerColor = containerColor,\n                contentColor = contentColor,\n                tonalElevation = tonalElevation,\n                dragHandle = dragHandle,\n                contentWindowInsets = contentWindowInsets,\n                content = content,\n            )\n        }\n    }\n    if (sheetState.hasExpandedState) {\n        LaunchedEffect(sheetState) { sheetState.show() }\n    }\n}\n\n/**\n * Properties used to customize the behavior of a [ModalBottomSheet].\n *\n * @param shouldDismissOnBackPress Whether the modal bottom sheet can be dismissed by pressing the\n *   back button. If true, pressing the back button will call onDismissRequest.\n * @param shouldDismissOnClickOutside Whether the modal bottom sheet can be dismissed by clicking on\n *   the scrim.\n */\n@Immutable\n@ExperimentalMaterial3Api\nexpect class ModalBottomSheetProperties(\n    shouldDismissOnBackPress: Boolean = true,\n    shouldDismissOnClickOutside: Boolean = true,\n) {\n    val shouldDismissOnBackPress: Boolean\n    val shouldDismissOnClickOutside: Boolean\n}\n\n/** Default values for [ModalBottomSheet] */\n@Immutable\n@ExperimentalMaterial3Api\nexpect object ModalBottomSheetDefaults {\n\n    /** Properties used to customize the behavior of a [ModalBottomSheet]. */\n    val properties: ModalBottomSheetProperties\n}\n\n/**\n * Create and [remember] a [SheetState] for [ModalBottomSheet].\n *\n * @param skipPartiallyExpanded Whether the partially expanded state, if the sheet is tall enough,\n *   should be skipped. If true, the sheet will always expand to the [Expanded] state and move to\n *   the [Hidden] state when hiding the sheet, either programmatically or by user interaction.\n * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change.\n */\n@Composable\n@ExperimentalMaterial3Api\nfun rememberModalBottomSheetState(\n    skipPartiallyExpanded: Boolean = false,\n    confirmValueChange: (SheetValue) -> Boolean = { true },\n) =\n    rememberSheetState(\n        skipPartiallyExpanded = skipPartiallyExpanded,\n        confirmValueChange = confirmValueChange,\n        initialValue = Hidden,\n    )\n\n@Stable\n@OptIn(ExperimentalMaterial3Api::class)\ninternal class SheetWindowInsets(private val state: SheetState) : WindowInsets {\n    override fun getLeft(density: Density, layoutDirection: LayoutDirection): Int = 0\n\n    override fun getTop(density: Density): Int {\n        val offset = state.anchoredDraggableState.offset\n        return if (offset.isNaN()) 0 else offset.toInt().coerceAtLeast(0)\n    }\n\n    override fun getRight(density: Density, layoutDirection: LayoutDirection): Int = 0\n\n    override fun getBottom(density: Density): Int = 0\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is SheetWindowInsets) return false\n        return state == other.state\n    }\n\n    override fun hashCode(): Int = state.hashCode()\n}\n\n/**\n * [Dialog]-like component providing default window behavior for [BottomSheet]. This implementation\n * explicitly provides a full-screen edge to edge layout.\n *\n * The dialog is visible as long as it is part of the composition hierarchy. In order to let the\n * user dismiss the Dialog, the implementation of onDismissRequest should contain a way to remove\n * the dialog from the composition hierarchy.\n *\n * You can add implement a custom [ModalBottomSheet] by leveraging this API alongside [BottomSheet],\n * [draggableAnchoredSheet], and [Scrim]:\n *\n * @sample androidx.compose.material3.samples.ManualModalBottomSheetSample\n * @param onDismissRequest Callback which executes when user tries to dismiss\n *   [ModalBottomSheetDialog].\n * @param contentColor The content color of this dialog. Used to inform the default behavior of the\n *   windows' system bars and content.\n * @param properties [ModalBottomSheetProperties] for further customization of this dialog.\n * @param content The content displayed in this [ModalBottomSheetDialog]. Usually [BottomSheet].\n */\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\ninternal expect fun ModalBottomSheetDialog(\n    onDismissRequest: () -> Unit = {},\n    contentColor: Color = contentColorFor(BottomSheetDefaults.ContainerColor),\n    properties: ModalBottomSheetProperties = ModalBottomSheetProperties(),\n    content: @Composable () -> Unit,\n)\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/AlertDialog.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.FlowRow\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.material3.internal.ProvideContentColorTextStyle\nimport androidx.compose.material3.internal.Strings\nimport androidx.compose.material3.internal.getString\nimport androidx.compose.material3.tokens.DialogTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.ProvidableCompositionLocal\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.semantics.paneTitle\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.takeOrElse\nimport androidx.compose.ui.window.Dialog\nimport androidx.compose.ui.window.DialogProperties\n\n/**\n * [Material Design basic dialog](https://m3.material.io/components/dialogs/overview)\n *\n * Dialogs provide important prompts in a user flow. They can require an action, communicate\n * information, or help users accomplish a task.\n *\n * ![Basic dialog\n * image](https://developer.android.com/images/reference/androidx/compose/material3/basic-dialog.png)\n *\n * The dialog will position its buttons, typically [TextButton]s, based on the available space. By\n * default it will try to place them horizontally next to each other and fallback to horizontal\n * placement if not enough space is available.\n *\n * Simple usage:\n *\n * @sample androidx.compose.material3.samples.AlertDialogSample\n *\n * Usage with a \"Hero\" icon:\n *\n * @sample androidx.compose.material3.samples.AlertDialogWithIconSample\n * @param onDismissRequest called when the user tries to dismiss the Dialog by clicking outside or\n *   pressing the back button. This is not called when the dismiss button is clicked.\n * @param confirmButton button which is meant to confirm a proposed action, thus resolving what\n *   triggered the dialog. The dialog does not set up any events for this button so they need to be\n *   set up by the caller.\n * @param modifier the [Modifier] to be applied to this dialog\n * @param dismissButton button which is meant to dismiss the dialog. The dialog does not set up any\n *   events for this button so they need to be set up by the caller.\n * @param icon optional icon that will appear above the [title] or above the [text], in case a title\n *   was not provided.\n * @param title title which should specify the purpose of the dialog. The title is not mandatory,\n *   because there may be sufficient information inside the [text].\n * @param text text which presents the details regarding the dialog's purpose.\n * @param shape defines the shape of this dialog's container\n * @param containerColor the color used for the background of this dialog. Use [Color.Transparent]\n *   to have no color.\n * @param iconContentColor the content color used for the icon.\n * @param titleContentColor the content color used for the title.\n * @param textContentColor the content color used for the text.\n * @param tonalElevation when [containerColor] is [ColorScheme.surface], a translucent primary color\n *   overlay is applied on top of the container. A higher tonal elevation value will result in a\n *   darker color in light theme and lighter color in dark theme. See also: [Surface].\n * @param properties typically platform specific properties to further configure the dialog.\n * @see BasicAlertDialog\n */\n@Composable\nexpect fun AlertDialog(\n    onDismissRequest: () -> Unit,\n    confirmButton: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    dismissButton: @Composable (() -> Unit)? = null,\n    icon: @Composable (() -> Unit)? = null,\n    title: @Composable (() -> Unit)? = null,\n    text: @Composable (() -> Unit)? = null,\n    shape: Shape = AlertDialogDefaults.shape,\n    containerColor: Color = AlertDialogDefaults.containerColor,\n    iconContentColor: Color = AlertDialogDefaults.iconContentColor,\n    titleContentColor: Color = AlertDialogDefaults.titleContentColor,\n    textContentColor: Color = AlertDialogDefaults.textContentColor,\n    tonalElevation: Dp = AlertDialogDefaults.TonalElevation,\n    properties: DialogProperties = DialogProperties(),\n)\n\n/**\n * [Basic alert dialog dialog](https://m3.material.io/components/dialogs/overview)\n *\n * Dialogs provide important prompts in a user flow. They can require an action, communicate\n * information, or help users accomplish a task.\n *\n * ![Basic dialog\n * image](https://developer.android.com/images/reference/androidx/compose/material3/basic-dialog.png)\n *\n * This basic alert dialog expects an arbitrary content that is defined by the caller. Note that\n * your content will need to define its own styling.\n *\n * By default, the displayed dialog has the minimum height and width that the Material Design spec\n * defines. If required, these constraints can be overwritten by providing a `width` or `height`\n * [Modifier]s.\n *\n * Basic alert dialog usage with custom content:\n *\n * @sample androidx.compose.material3.samples.BasicAlertDialogSample\n * @param onDismissRequest called when the user tries to dismiss the Dialog by clicking outside or\n *   pressing the back button. This is not called when the dismiss button is clicked.\n * @param modifier the [Modifier] to be applied to this dialog's content.\n * @param properties typically platform specific properties to further configure the dialog.\n * @param content the content of the dialog\n */\n@OptIn(ExperimentalMaterial3ComponentOverrideApi::class)\n@ExperimentalMaterial3Api\n@Composable\nfun BasicAlertDialog(\n    onDismissRequest: () -> Unit,\n    modifier: Modifier = Modifier,\n    properties: DialogProperties = DialogProperties(),\n    content: @Composable () -> Unit,\n) {\n    with(LocalBasicAlertDialogOverride.current) {\n        BasicAlertDialogOverrideScope(\n                onDismissRequest = onDismissRequest,\n                modifier = modifier,\n                properties = properties,\n                content = content,\n            )\n            .BasicAlertDialog()\n    }\n}\n\n/**\n * This override provides the default behavior of the [BasicAlertDialog] component.\n *\n * [BasicAlertDialogOverride] used when no override is specified.\n */\n@OptIn(ExperimentalMaterial3Api::class)\n@ExperimentalMaterial3ComponentOverrideApi\nobject DefaultBasicAlertDialogOverride : BasicAlertDialogOverride {\n    @Composable\n    override fun BasicAlertDialogOverrideScope.BasicAlertDialog() {\n        Dialog(onDismissRequest = onDismissRequest, properties = properties) {\n            val dialogPaneDescription = getString(Strings.Dialog)\n            Box(\n                modifier =\n                    modifier\n                        .sizeIn(minWidth = DialogMinWidth, maxWidth = DialogMaxWidth)\n                        .then(Modifier.semantics { paneTitle = dialogPaneDescription }),\n                propagateMinConstraints = true,\n            ) {\n                content()\n            }\n        }\n    }\n}\n\n/**\n * [Basic alert dialog dialog](https://m3.material.io/components/dialogs/overview)\n *\n * Dialogs provide important prompts in a user flow. They can require an action, communicate\n * information, or help users accomplish a task.\n *\n * ![Basic dialog\n * image](https://developer.android.com/images/reference/androidx/compose/material3/basic-dialog.png)\n *\n * This basic alert dialog expects an arbitrary content that is defined by the caller. Note that\n * your content will need to define its own styling.\n *\n * By default, the displayed dialog has the minimum height and width that the Material Design spec\n * defines. If required, these constraints can be overwritten by providing a `width` or `height`\n * [Modifier]s.\n *\n * Basic alert dialog usage with custom content:\n *\n * @sample androidx.compose.material3.samples.BasicAlertDialogSample\n * @param onDismissRequest called when the user tries to dismiss the Dialog by clicking outside or\n *   pressing the back button. This is not called when the dismiss button is clicked.\n * @param modifier the [Modifier] to be applied to this dialog's content.\n * @param properties typically platform specific properties to further configure the dialog.\n * @param content the content of the dialog\n */\n@Deprecated(\n    \"Use BasicAlertDialog instead\",\n    replaceWith = ReplaceWith(\"BasicAlertDialog(onDismissRequest, modifier, properties, content)\"),\n)\n@ExperimentalMaterial3Api\n@Composable\nfun AlertDialog(\n    onDismissRequest: () -> Unit,\n    modifier: Modifier = Modifier,\n    properties: DialogProperties = DialogProperties(),\n    content: @Composable () -> Unit,\n) = BasicAlertDialog(onDismissRequest, modifier, properties, content)\n\n/** Contains default values used for [AlertDialog] and [BasicAlertDialog]. */\nobject AlertDialogDefaults {\n    /** The default shape for alert dialogs */\n    val shape: Shape\n        @Composable get() = DialogTokens.ContainerShape.value\n\n    /** The default container color for alert dialogs */\n    val containerColor: Color\n        @Composable get() = DialogTokens.ContainerColor.value\n\n    /** The default icon color for alert dialogs */\n    val iconContentColor: Color\n        @Composable get() = DialogTokens.IconColor.value\n\n    /** The default title color for alert dialogs */\n    val titleContentColor: Color\n        @Composable get() = DialogTokens.HeadlineColor.value\n\n    /** The default text color for alert dialogs */\n    val textContentColor: Color\n        @Composable get() = DialogTokens.SupportingTextColor.value\n\n    /** The default tonal elevation for alert dialogs */\n    val TonalElevation: Dp = 0.dp\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\ninternal fun AlertDialogImpl(\n    onDismissRequest: () -> Unit,\n    confirmButton: @Composable () -> Unit,\n    modifier: Modifier,\n    dismissButton: @Composable (() -> Unit)?,\n    icon: @Composable (() -> Unit)?,\n    title: @Composable (() -> Unit)?,\n    text: @Composable (() -> Unit)?,\n    shape: Shape,\n    containerColor: Color,\n    iconContentColor: Color,\n    titleContentColor: Color,\n    textContentColor: Color,\n    tonalElevation: Dp,\n    properties: DialogProperties,\n) {\n    BasicAlertDialog(\n        onDismissRequest = onDismissRequest,\n        modifier = modifier,\n        properties = properties,\n    ) {\n        AlertDialogContent(\n            buttons = {\n                val buttonPaddingFromMICS =\n                    LocalMinimumInteractiveComponentSize.current.takeOrElse { 0.dp } -\n                        ButtonDefaults.MinHeight\n                AlertDialogFlowRow(\n                    mainAxisSpacing = ButtonsMainAxisSpacing,\n                    crossAxisSpacing =\n                        (ButtonsCrossAxisSpacing - buttonPaddingFromMICS).coerceIn(\n                            0.dp,\n                            ButtonsCrossAxisSpacing,\n                        ),\n                ) {\n                    confirmButton()\n                    dismissButton?.invoke()\n                }\n            },\n            icon = icon,\n            title = title,\n            text = text,\n            shape = shape,\n            containerColor = containerColor,\n            tonalElevation = tonalElevation,\n            // Note that a button content color is provided here from the dialog's token, but in\n            // most cases, TextButtons should be used for dismiss and confirm buttons. TextButtons\n            // will not consume this provided content color value, and will used their own defined\n            // or default colors.\n            buttonContentColor = DialogTokens.ActionLabelTextColor.value,\n            iconContentColor = iconContentColor,\n            titleContentColor = titleContentColor,\n            textContentColor = textContentColor,\n        )\n    }\n}\n\n@Composable\ninternal fun AlertDialogContent(\n    buttons: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    icon: (@Composable () -> Unit)?,\n    title: (@Composable () -> Unit)?,\n    text: @Composable (() -> Unit)?,\n    shape: Shape,\n    containerColor: Color,\n    tonalElevation: Dp,\n    buttonContentColor: Color,\n    iconContentColor: Color,\n    titleContentColor: Color,\n    textContentColor: Color,\n) {\n    Surface(\n        modifier = modifier,\n        shape = shape,\n        color = containerColor,\n        tonalElevation = tonalElevation,\n    ) {\n        Column(modifier = Modifier.padding(DialogPadding)) {\n            icon?.let {\n                CompositionLocalProvider(LocalContentColor provides iconContentColor) {\n                    Box(Modifier.padding(IconPadding).align(Alignment.CenterHorizontally)) {\n                        icon()\n                    }\n                }\n            }\n            title?.let {\n                ProvideContentColorTextStyle(\n                    contentColor = titleContentColor,\n                    textStyle = DialogTokens.HeadlineFont.value,\n                ) {\n                    Box(\n                        // Align the title to the center when an icon is present.\n                        Modifier.padding(TitlePadding)\n                            .align(\n                                if (icon == null) {\n                                    Alignment.Start\n                                } else {\n                                    Alignment.CenterHorizontally\n                                }\n                            )\n                    ) {\n                        title()\n                    }\n                }\n            }\n            text?.let {\n                val textStyle = DialogTokens.SupportingTextFont.value\n                ProvideContentColorTextStyle(\n                    contentColor = textContentColor,\n                    textStyle = textStyle,\n                ) {\n                    Box(\n                        Modifier.weight(weight = 1f, fill = false)\n                            .padding(TextPadding)\n                            .align(Alignment.Start)\n                    ) {\n                        text()\n                    }\n                }\n            }\n            Box(modifier = Modifier.align(Alignment.End)) {\n                val textStyle = DialogTokens.ActionLabelTextFont.value\n                ProvideContentColorTextStyle(\n                    contentColor = buttonContentColor,\n                    textStyle = textStyle,\n                    content = buttons,\n                )\n            }\n        }\n    }\n}\n\n/**\n * [FlowRow] for dialog buttons. The confirm button is expected to be the first child of [content].\n */\n@Composable\ninternal fun AlertDialogFlowRow(\n    mainAxisSpacing: Dp,\n    crossAxisSpacing: Dp,\n    content: @Composable () -> Unit,\n) {\n    val originalLayoutDirection = LocalLayoutDirection.current\n    // The confirm button comes BEFORE the dismiss button when stacked vertically,\n    // but AFTER the dismiss button when stacked horizontally.\n    CompositionLocalProvider(LocalLayoutDirection provides originalLayoutDirection.flip()) {\n        FlowRow(\n            horizontalArrangement = Arrangement.spacedBy(mainAxisSpacing),\n            verticalArrangement = Arrangement.spacedBy(crossAxisSpacing),\n        ) {\n            CompositionLocalProvider(\n                LocalLayoutDirection provides originalLayoutDirection,\n                content = content,\n            )\n        }\n    }\n}\n\nprivate fun LayoutDirection.flip(): LayoutDirection =\n    when (this) {\n        LayoutDirection.Ltr -> LayoutDirection.Rtl\n        LayoutDirection.Rtl -> LayoutDirection.Ltr\n    }\n\ninternal val DialogMinWidth = 280.dp\ninternal val DialogMaxWidth = 560.dp\n\nprivate val ButtonsMainAxisSpacing = 8.dp\nprivate val ButtonsCrossAxisSpacing = 8.dp\n\n// Paddings for each of the dialog's parts.\nprivate val DialogPadding = PaddingValues(all = 24.dp)\nprivate val IconPadding = PaddingValues(bottom = 16.dp)\nprivate val TitlePadding = PaddingValues(bottom = 16.dp)\nprivate val TextPadding = PaddingValues(bottom = 24.dp)\n\n/**\n * Interface that allows libraries to override the behavior of the [BasicAlertDialog] component.\n *\n * To override this component, implement the member function of this interface, then provide the\n * implementation to [LocalBasicAlertDialogOverride] in the Compose hierarchy.\n */\n@ExperimentalMaterial3ComponentOverrideApi\ninterface BasicAlertDialogOverride {\n    /** Behavior function that is called by the [BasicAlertDialog] component. */\n    @Composable fun BasicAlertDialogOverrideScope.BasicAlertDialog()\n}\n\n/**\n * Parameters available to [BasicAlertDialog].\n *\n * @param onDismissRequest called when the user tries to dismiss the Dialog by clicking outside or\n *   pressing the back button. This is not called when the dismiss button is clicked.\n * @param modifier the [Modifier] to be applied to this dialog's content.\n * @param properties typically platform specific properties to further configure the dialog.\n * @param content the content of the dialog\n */\n@ExperimentalMaterial3ComponentOverrideApi\nclass BasicAlertDialogOverrideScope\ninternal constructor(\n    val onDismissRequest: () -> Unit,\n    val modifier: Modifier = Modifier,\n    val properties: DialogProperties = DialogProperties(),\n    val content: @Composable () -> Unit,\n)\n\n/** CompositionLocal containing the currently-selected [BasicAlertDialogOverride]. */\n@ExperimentalMaterial3ComponentOverrideApi\nval LocalBasicAlertDialogOverride: ProvidableCompositionLocal<BasicAlertDialogOverride> =\n    compositionLocalOf {\n        DefaultBasicAlertDialogOverride\n    }\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Snackbar.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.paddingFromBaseline\nimport androidx.compose.foundation.layout.widthIn\nimport androidx.compose.material3.internal.Icons\nimport androidx.compose.material3.internal.Strings\nimport androidx.compose.material3.internal.getString\nimport androidx.compose.material3.tokens.SnackbarTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.layout.AlignmentLine\nimport androidx.compose.ui.layout.FirstBaseline\nimport androidx.compose.ui.layout.LastBaseline\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.layoutId\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastFirst\nimport androidx.compose.ui.util.fastFirstOrNull\nimport kotlin.math.max\nimport kotlin.math.min\n\n/**\n * [Material Design snackbar](https://m3.material.io/components/snackbar/overview)\n *\n * Snackbars provide brief messages about app processes at the bottom of the screen.\n *\n * ![Snackbar\n * image](https://developer.android.com/images/reference/androidx/compose/material3/snackbar.png)\n *\n * Snackbars inform users of a process that an app has performed or will perform. They appear\n * temporarily, towards the bottom of the screen. They shouldn’t interrupt the user experience, and\n * they don’t require user input to disappear.\n *\n * A Snackbar can contain a single action. \"Dismiss\" or \"cancel\" actions are optional.\n *\n * Snackbars with an action should not timeout or self-dismiss until the user performs another\n * action. Here, moving the keyboard focus indicator to navigate through interactive elements in a\n * page is not considered an action.\n *\n * This component provides only the visuals of the Snackbar. If you need to show a Snackbar with\n * defaults on the screen, use [SnackbarHostState.showSnackbar]:\n *\n * @sample androidx.compose.material3.samples.ScaffoldWithSimpleSnackbar\n *\n * If you want to customize appearance of the Snackbar, you can pass your own version as a child of\n * the [SnackbarHost] to the [Scaffold]:\n *\n * @sample androidx.compose.material3.samples.ScaffoldWithCustomSnackbar\n *\n * For a multiline sample following the Material recommended spec of a maximum of 2 lines, see:\n *\n * @sample androidx.compose.material3.samples.ScaffoldWithMultilineSnackbar\n * @param modifier the [Modifier] to be applied to this snackbar\n * @param action action / button component to add as an action to the snackbar. Consider using\n *   [ColorScheme.inversePrimary] as the color for the action, if you do not have a predefined color\n *   you wish to use instead.\n * @param dismissAction action / button component to add as an additional close affordance action\n *   when a snackbar is non self-dismissive. Consider using [ColorScheme.inverseOnSurface] as the\n *   color for the action, if you do not have a predefined color you wish to use instead.\n * @param actionOnNewLine whether or not action should be put on a separate line. Recommended for\n *   action with long action text.\n * @param shape defines the shape of this snackbar's container\n * @param containerColor the color used for the background of this snackbar. Use [Color.Transparent]\n *   to have no color.\n * @param contentColor the preferred color for content inside this snackbar\n * @param actionContentColor the preferred content color for the optional [action] inside this\n *   snackbar\n * @param dismissActionContentColor the preferred content color for the optional [dismissAction]\n *   inside this snackbar\n * @param content content to show information about a process that an app has performed or will\n *   perform\n */\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun Snackbar(\n    modifier: Modifier = Modifier,\n    action: @Composable (() -> Unit)? = null,\n    dismissAction: @Composable (() -> Unit)? = null,\n    actionOnNewLine: Boolean = false,\n    shape: Shape = SnackbarDefaults.shape,\n    containerColor: Color = SnackbarDefaults.color,\n    contentColor: Color = SnackbarDefaults.contentColor,\n    actionContentColor: Color = SnackbarDefaults.actionContentColor,\n    dismissActionContentColor: Color = SnackbarDefaults.dismissActionContentColor,\n    content: @Composable () -> Unit,\n) {\n    Surface(\n        modifier = modifier,\n        shape = shape,\n        color = containerColor,\n        contentColor = contentColor,\n        shadowElevation = SnackbarTokens.ContainerElevation,\n    ) {\n        val textStyle = SnackbarTokens.SupportingTextFont.value\n        val actionTextStyle = SnackbarTokens.ActionLabelTextFont.value\n        CompositionLocalProvider(LocalTextStyle provides textStyle) {\n            when {\n                actionOnNewLine && action != null ->\n                    if (ComposeMaterial3Flags.isSnackbarStylingFixEnabled) {\n                        NewLineButtonSnackbar(\n                            text = content,\n                            action = action,\n                            dismissAction = dismissAction,\n                            actionTextStyle = actionTextStyle,\n                            actionContentColor = actionContentColor,\n                            dismissActionContentColor = dismissActionContentColor,\n                        )\n                    } else {\n                        LegacyNewLineButtonSnackbar(\n                            text = content,\n                            action = action,\n                            dismissAction = dismissAction,\n                            actionTextStyle = actionTextStyle,\n                            actionContentColor = actionContentColor,\n                            dismissActionContentColor = dismissActionContentColor,\n                        )\n                    }\n\n                else ->\n                    if (ComposeMaterial3Flags.isSnackbarStylingFixEnabled) {\n                        OneRowSnackbar(\n                            text = content,\n                            action = action,\n                            dismissAction = dismissAction,\n                            actionTextStyle = actionTextStyle,\n                            actionTextColor = actionContentColor,\n                            dismissActionColor = dismissActionContentColor,\n                        )\n                    } else {\n                        LegacyOneRowSnackbar(\n                            text = content,\n                            action = action,\n                            dismissAction = dismissAction,\n                            actionTextStyle = actionTextStyle,\n                            actionTextColor = actionContentColor,\n                            dismissActionColor = dismissActionContentColor,\n                        )\n                    }\n            }\n        }\n    }\n}\n\n/**\n * [Material Design snackbar](https://m3.material.io/components/snackbar/overview)\n *\n * Snackbars provide brief messages about app processes at the bottom of the screen.\n *\n * ![Snackbar\n * image](https://developer.android.com/images/reference/androidx/compose/material3/snackbar.png)\n *\n * Snackbars inform users of a process that an app has performed or will perform. They appear\n * temporarily, towards the bottom of the screen. They shouldn’t interrupt the user experience, and\n * they don’t require user input to disappear.\n *\n * A Snackbar can contain a single action. \"Dismiss\" or \"cancel\" actions are optional.\n *\n * Snackbars with an action should not timeout or self-dismiss until the user performs another\n * action. Here, moving the keyboard focus indicator to navigate through interactive elements in a\n * page is not considered an action.\n *\n * This version of snackbar is designed to work with [SnackbarData] provided by the [SnackbarHost],\n * which is usually used inside of the [Scaffold].\n *\n * This components provides only the visuals of the Snackbar. If you need to show a Snackbar with\n * defaults on the screen, use [SnackbarHostState.showSnackbar]:\n *\n * @sample androidx.compose.material3.samples.ScaffoldWithSimpleSnackbar\n *\n * If you want to customize appearance of the Snackbar, you can pass your own version as a child of\n * the [SnackbarHost] to the [Scaffold]:\n *\n * @sample androidx.compose.material3.samples.ScaffoldWithCustomSnackbar\n *\n * When a [SnackbarData.visuals] sets the Snackbar's duration as [SnackbarDuration.Indefinite], it's\n * recommended to display an additional close affordance action. See\n * [SnackbarVisuals.withDismissAction]:\n *\n * @sample androidx.compose.material3.samples.ScaffoldWithIndefiniteSnackbar\n * @param snackbarData data about the current snackbar showing via [SnackbarHostState]\n * @param modifier the [Modifier] to be applied to this snackbar\n * @param actionOnNewLine whether or not action should be put on a separate line. Recommended for\n *   action with long action text.\n * @param shape defines the shape of this snackbar's container\n * @param containerColor the color used for the background of this snackbar. Use [Color.Transparent]\n *   to have no color.\n * @param contentColor the preferred color for content inside this snackbar\n * @param actionColor the color of the snackbar's action\n * @param actionContentColor the preferred content color for the optional action inside this\n *   snackbar. See [SnackbarVisuals.actionLabel].\n * @param dismissActionContentColor the preferred content color for the optional dismiss action\n *   inside this snackbar. See [SnackbarVisuals.withDismissAction].\n */\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun Snackbar(\n    snackbarData: SnackbarData,\n    modifier: Modifier = Modifier,\n    actionOnNewLine: Boolean = false,\n    shape: Shape = SnackbarDefaults.shape,\n    containerColor: Color = SnackbarDefaults.color,\n    contentColor: Color = SnackbarDefaults.contentColor,\n    actionColor: Color = SnackbarDefaults.actionColor,\n    actionContentColor: Color = SnackbarDefaults.actionContentColor,\n    dismissActionContentColor: Color = SnackbarDefaults.dismissActionContentColor,\n) {\n    val actionLabel = snackbarData.visuals.actionLabel\n    val actionComposable: (@Composable () -> Unit)? =\n        if (actionLabel != null) {\n            @Composable {\n                TextButton(\n                    colors = ButtonDefaults.textButtonColors(contentColor = actionColor),\n                    onClick = { snackbarData.performAction() },\n                    content = { Text(actionLabel) },\n                )\n            }\n        } else {\n            null\n        }\n    val dismissActionComposable: (@Composable () -> Unit)? =\n        if (snackbarData.visuals.withDismissAction) {\n            @Composable {\n                val contentDescription = getString(Strings.SnackbarDismiss)\n                TooltipBox(\n                    positionProvider =\n                        TooltipDefaults.rememberTooltipPositionProvider(\n                            TooltipAnchorPosition.Above\n                        ),\n                    tooltip = { PlainTooltip { Text(contentDescription) } },\n                    state = rememberTooltipState(),\n                ) {\n                    IconButton(\n                        onClick = { snackbarData.dismiss() },\n                        content = {\n                            Icon(Icons.Filled.Close, contentDescription = contentDescription)\n                        },\n                    )\n                }\n            }\n        } else {\n            null\n        }\n    Snackbar(\n        modifier = modifier.padding(12.dp),\n        action = actionComposable,\n        dismissAction = dismissActionComposable,\n        actionOnNewLine = actionOnNewLine,\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        actionContentColor = actionContentColor,\n        dismissActionContentColor = dismissActionContentColor,\n        content = { Text(snackbarData.visuals.message) },\n    )\n}\n\n@Composable\nprivate fun NewLineButtonSnackbar(\n    text: @Composable () -> Unit,\n    action: @Composable () -> Unit,\n    dismissAction: @Composable (() -> Unit)?,\n    actionTextStyle: TextStyle,\n    actionContentColor: Color,\n    dismissActionContentColor: Color,\n) {\n    Column(\n        modifier =\n            Modifier.widthIn(max = ContainerMaxWidth)\n                .fillMaxWidth()\n                .padding(start = HorizontalSpacing)\n    ) {\n        Box(\n            modifier =\n                Modifier.fillMaxWidth()\n                    .padding(vertical = SnackbarVerticalPadding)\n                    .padding(end = HorizontalSpacing)\n        ) {\n            text()\n        }\n\n        Row(\n            modifier =\n                Modifier.align(Alignment.End)\n                    .padding(\n                        bottom = ActionButtonBottomPadding,\n                        end = if (dismissAction == null) HorizontalSpacingButtonSide else 0.dp,\n                    ),\n            verticalAlignment = Alignment.CenterVertically,\n        ) {\n            CompositionLocalProvider(\n                LocalContentColor provides actionContentColor,\n                LocalTextStyle provides actionTextStyle,\n                content = action,\n            )\n            if (dismissAction != null) {\n                CompositionLocalProvider(\n                    LocalContentColor provides dismissActionContentColor,\n                    content = dismissAction,\n                )\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun LegacyNewLineButtonSnackbar(\n    text: @Composable () -> Unit,\n    action: @Composable () -> Unit,\n    dismissAction: @Composable (() -> Unit)?,\n    actionTextStyle: TextStyle,\n    actionContentColor: Color,\n    dismissActionContentColor: Color,\n) {\n    Column(\n        modifier =\n            Modifier\n                // Fill max width, up to ContainerMaxWidth.\n                .widthIn(max = ContainerMaxWidth)\n                .fillMaxWidth()\n                .padding(start = HorizontalSpacing, bottom = SeparateButtonExtraY)\n    ) {\n        Box(\n            Modifier.paddingFromBaseline(HeightToFirstLine, LongButtonVerticalOffset)\n                .padding(end = HorizontalSpacingButtonSide)\n        ) {\n            text()\n        }\n\n        Box(\n            Modifier.align(Alignment.End)\n                .padding(end = if (dismissAction == null) HorizontalSpacingButtonSide else 0.dp)\n        ) {\n            Row {\n                CompositionLocalProvider(\n                    LocalContentColor provides actionContentColor,\n                    LocalTextStyle provides actionTextStyle,\n                    content = action,\n                )\n                if (dismissAction != null) {\n                    CompositionLocalProvider(\n                        LocalContentColor provides dismissActionContentColor,\n                        content = dismissAction,\n                    )\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun LegacyOneRowSnackbar(\n    text: @Composable () -> Unit,\n    action: @Composable (() -> Unit)?,\n    dismissAction: @Composable (() -> Unit)?,\n    actionTextStyle: TextStyle,\n    actionTextColor: Color,\n    dismissActionColor: Color,\n) {\n    val textTag = \"text\"\n    val actionTag = \"action\"\n    val dismissActionTag = \"dismissAction\"\n    Layout(\n        {\n            Box(Modifier.layoutId(textTag).padding(vertical = LegacySnackbarVerticalPadding)) {\n                text()\n            }\n            if (action != null) {\n                Box(Modifier.layoutId(actionTag)) {\n                    CompositionLocalProvider(\n                        LocalContentColor provides actionTextColor,\n                        LocalTextStyle provides actionTextStyle,\n                        content = action,\n                    )\n                }\n            }\n            if (dismissAction != null) {\n                Box(Modifier.layoutId(dismissActionTag)) {\n                    CompositionLocalProvider(\n                        LocalContentColor provides dismissActionColor,\n                        content = dismissAction,\n                    )\n                }\n            }\n        },\n        modifier =\n            Modifier.padding(\n                start = HorizontalSpacing,\n                end = if (dismissAction == null) HorizontalSpacingButtonSide else 0.dp,\n            ),\n    ) { measurables, constraints ->\n        val containerWidth = min(constraints.maxWidth, ContainerMaxWidth.roundToPx())\n        val actionButtonPlaceable =\n            measurables.fastFirstOrNull { it.layoutId == actionTag }?.measure(constraints)\n        val dismissButtonPlaceable =\n            measurables.fastFirstOrNull { it.layoutId == dismissActionTag }?.measure(constraints)\n        val actionButtonWidth = actionButtonPlaceable?.width ?: 0\n        val actionButtonHeight = actionButtonPlaceable?.height ?: 0\n        val dismissButtonWidth = dismissButtonPlaceable?.width ?: 0\n        val dismissButtonHeight = dismissButtonPlaceable?.height ?: 0\n        val extraSpacingWidth = if (dismissButtonWidth == 0) TextEndExtraSpacing.roundToPx() else 0\n        val textMaxWidth =\n            (containerWidth - actionButtonWidth - dismissButtonWidth - extraSpacingWidth)\n                .coerceAtLeast(constraints.minWidth)\n        val textPlaceable =\n            measurables\n                .fastFirst { it.layoutId == textTag }\n                .measure(constraints.copy(minHeight = 0, maxWidth = textMaxWidth))\n\n        val firstTextBaseline = textPlaceable[FirstBaseline]\n        val lastTextBaseline = textPlaceable[LastBaseline]\n        val hasText =\n            firstTextBaseline != AlignmentLine.Unspecified &&\n                lastTextBaseline != AlignmentLine.Unspecified\n        val isOneLine = firstTextBaseline == lastTextBaseline || !hasText\n        val dismissButtonPlaceX = containerWidth - dismissButtonWidth\n        val actionButtonPlaceX = dismissButtonPlaceX - actionButtonWidth\n\n        val textPlaceY: Int\n        val containerHeight: Int\n        val actionButtonPlaceY: Int\n        if (isOneLine) {\n            val minContainerHeight = SnackbarTokens.SingleLineContainerHeight.roundToPx()\n            val contentHeight = max(actionButtonHeight, dismissButtonHeight)\n            containerHeight = max(minContainerHeight, contentHeight)\n            textPlaceY = (containerHeight - textPlaceable.height) / 2\n            actionButtonPlaceY =\n                if (actionButtonPlaceable != null) {\n                    actionButtonPlaceable[FirstBaseline].let {\n                        if (it != AlignmentLine.Unspecified) {\n                            textPlaceY + firstTextBaseline - it\n                        } else {\n                            0\n                        }\n                    }\n                } else {\n                    0\n                }\n        } else {\n            val baselineOffset = HeightToFirstLine.roundToPx()\n            textPlaceY = baselineOffset - firstTextBaseline\n            val minContainerHeight = SnackbarTokens.TwoLinesContainerHeight.roundToPx()\n            val contentHeight = textPlaceY + textPlaceable.height\n            containerHeight = max(minContainerHeight, contentHeight)\n            actionButtonPlaceY =\n                if (actionButtonPlaceable != null) {\n                    (containerHeight - actionButtonPlaceable.height) / 2\n                } else {\n                    0\n                }\n        }\n        val dismissButtonPlaceY =\n            if (dismissButtonPlaceable != null) {\n                (containerHeight - dismissButtonPlaceable.height) / 2\n            } else {\n                0\n            }\n\n        layout(containerWidth, containerHeight) {\n            textPlaceable.placeRelative(0, textPlaceY)\n            actionButtonPlaceable?.placeRelative(actionButtonPlaceX, actionButtonPlaceY)\n            dismissButtonPlaceable?.placeRelative(dismissButtonPlaceX, dismissButtonPlaceY)\n        }\n    }\n}\n\n@Composable\nprivate fun OneRowSnackbar(\n    text: @Composable () -> Unit,\n    action: @Composable (() -> Unit)?,\n    dismissAction: @Composable (() -> Unit)?,\n    actionTextStyle: TextStyle,\n    actionTextColor: Color,\n    dismissActionColor: Color,\n) {\n    val textTag = \"text\"\n    val actionTag = \"action\"\n    val dismissActionTag = \"dismissAction\"\n    Layout(\n        {\n            Box(Modifier.layoutId(textTag).padding(vertical = SnackbarVerticalPadding)) { text() }\n            if (action != null) {\n                Box(Modifier.layoutId(actionTag)) {\n                    CompositionLocalProvider(\n                        LocalContentColor provides actionTextColor,\n                        LocalTextStyle provides actionTextStyle,\n                        content = action,\n                    )\n                }\n            }\n            if (dismissAction != null) {\n                Box(Modifier.layoutId(dismissActionTag)) {\n                    CompositionLocalProvider(\n                        LocalContentColor provides dismissActionColor,\n                        content = dismissAction,\n                    )\n                }\n            }\n        },\n        modifier =\n            Modifier.padding(\n                start = HorizontalSpacing,\n                end = if (dismissAction == null) TextEndExtraSpacing else 0.dp,\n            ),\n    ) { measurables, constraints ->\n        val minContainerHeight = SnackbarTokens.SingleLineContainerHeight.roundToPx()\n        val containerWidth = min(constraints.maxWidth, ContainerMaxWidth.roundToPx())\n        val actionButtonPlaceable =\n            measurables.fastFirstOrNull { it.layoutId == actionTag }?.measure(constraints)\n        val dismissButtonPlaceable =\n            measurables.fastFirstOrNull { it.layoutId == dismissActionTag }?.measure(constraints)\n        val actionButtonWidth = actionButtonPlaceable?.width ?: 0\n        val dismissButtonWidth = dismissButtonPlaceable?.width ?: 0\n\n        val extraSpacingWidth = if (dismissButtonWidth == 0) TextEndExtraSpacing.roundToPx() else 0\n        val textMaxWidth =\n            (containerWidth - actionButtonWidth - dismissButtonWidth - extraSpacingWidth)\n                .coerceAtLeast(constraints.minWidth)\n        val textPlaceable =\n            measurables\n                .fastFirst { it.layoutId == textTag }\n                .measure(constraints.copy(minHeight = 0, maxWidth = textMaxWidth))\n\n        val containerHeight =\n            maxOf(\n                minContainerHeight,\n                textPlaceable.height,\n                actionButtonPlaceable?.height ?: 0,\n                dismissButtonPlaceable?.height ?: 0,\n            )\n\n        val dismissButtonPlaceX = containerWidth - dismissButtonWidth\n        val actionButtonPlaceX = dismissButtonPlaceX - actionButtonWidth\n\n        layout(containerWidth, containerHeight) {\n            textPlaceable.placeRelative(0, (containerHeight - textPlaceable.height) / 2)\n            actionButtonPlaceable?.placeRelative(\n                actionButtonPlaceX,\n                (containerHeight - actionButtonPlaceable.height) / 2,\n            )\n            dismissButtonPlaceable?.placeRelative(\n                dismissButtonPlaceX,\n                (containerHeight - dismissButtonPlaceable.height) / 2,\n            )\n        }\n    }\n}\n\n/** Contains the default values used for [Snackbar]. */\nobject SnackbarDefaults {\n    /** Default shape of a snackbar. */\n    val shape: Shape\n        @Composable get() = SnackbarTokens.ContainerShape.value\n\n    /** Default color of a snackbar. */\n    val color: Color\n        @Composable get() = SnackbarTokens.ContainerColor.value\n\n    /** Default content color of a snackbar. */\n    val contentColor: Color\n        @Composable get() = SnackbarTokens.SupportingTextColor.value\n\n    /** Default action color of a snackbar. */\n    val actionColor: Color\n        @Composable get() = SnackbarTokens.ActionLabelTextColor.value\n\n    /** Default action content color of a snackbar. */\n    val actionContentColor: Color\n        @Composable get() = SnackbarTokens.ActionLabelTextColor.value\n\n    /** Default dismiss action content color of a snackbar. */\n    val dismissActionContentColor: Color\n        @Composable get() = SnackbarTokens.IconColor.value\n}\n\nprivate val ContainerMaxWidth = 600.dp\nprivate val HeightToFirstLine = 30.dp\nprivate val HorizontalSpacing = 16.dp\nprivate val HorizontalSpacingButtonSide = 8.dp\nprivate val SeparateButtonExtraY = 2.dp\nprivate val LegacySnackbarVerticalPadding = 6.dp\nprivate val TextEndExtraSpacing = 8.dp\nprivate val LongButtonVerticalOffset = 12.dp\nprivate val SnackbarVerticalPadding = 14.dp\nprivate val ActionButtonBottomPadding = 4.dp\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/FloatingActionButton.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.animation.AnimatedVisibility\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.VectorConverter\nimport androidx.compose.animation.core.animateFloat\nimport androidx.compose.animation.core.updateTransition\nimport androidx.compose.animation.expandHorizontally\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.shrinkHorizontally\nimport androidx.compose.foundation.interaction.FocusInteraction\nimport androidx.compose.foundation.interaction.HoverInteraction\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.InteractionSource\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.RowScope\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.sizeIn\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.material3.MaterialTheme.LocalMaterialTheme\nimport androidx.compose.material3.internal.ProvideContentColorTextStyle\nimport androidx.compose.material3.internal.animateElevation\nimport androidx.compose.material3.tokens.ElevationTokens\nimport androidx.compose.material3.tokens.ExtendedFabLargeTokens\nimport androidx.compose.material3.tokens.ExtendedFabMediumTokens\nimport androidx.compose.material3.tokens.ExtendedFabPrimaryTokens\nimport androidx.compose.material3.tokens.ExtendedFabSmallTokens\nimport androidx.compose.material3.tokens.FabBaselineTokens\nimport androidx.compose.material3.tokens.FabLargeTokens\nimport androidx.compose.material3.tokens.FabMediumTokens\nimport androidx.compose.material3.tokens.FabPrimaryContainerTokens\nimport androidx.compose.material3.tokens.FabSmallTokens\nimport androidx.compose.material3.tokens.MotionSchemeKeyTokens\nimport androidx.compose.material3.tokens.TypographyKeyTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.CacheDrawModifierNode\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.drawscope.inset\nimport androidx.compose.ui.graphics.graphicsLayer\nimport androidx.compose.ui.graphics.layer.drawLayer\nimport androidx.compose.ui.layout.Measurable\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.layout.layout\nimport androidx.compose.ui.node.CompositionLocalConsumerModifierNode\nimport androidx.compose.ui.node.DelegatingNode\nimport androidx.compose.ui.node.LayoutModifierNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.node.currentValueOf\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.semantics.clearAndSetSemantics\nimport androidx.compose.ui.semantics.role\nimport androidx.compose.ui.semantics.semantics\nimport androidx.compose.ui.text.TextStyle\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.toIntSize\nimport androidx.compose.ui.unit.toOffset\nimport androidx.compose.ui.util.lerp\nimport kotlin.math.roundToInt\nimport kotlinx.coroutines.launch\n\n/**\n * [Material Design floating action\n * button](https://m3.material.io/components/floating-action-button/overview)\n *\n * The FAB represents the most important action on a screen. It puts key actions within reach.\n *\n * ![FAB image](https://developer.android.com/images/reference/androidx/compose/material3/fab.png)\n *\n * FAB typically contains an icon, for a FAB with text and an icon, see\n * [ExtendedFloatingActionButton].\n *\n * @sample androidx.compose.material3.samples.FloatingActionButtonSample\n * @param onClick called when this FAB is clicked\n * @param modifier the [Modifier] to be applied to this FAB\n * @param shape defines the shape of this FAB's container and shadow (when using [elevation])\n * @param containerColor the color used for the background of this FAB. Use [Color.Transparent] to\n *   have no color.\n * @param contentColor the preferred color for content inside this FAB. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param elevation [FloatingActionButtonElevation] used to resolve the elevation for this FAB in\n *   different states. This controls the size of the shadow below the FAB. Additionally, when the\n *   container color is [ColorScheme.surface], this controls the amount of primary color applied as\n *   an overlay. See also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance or\n *   preview the FAB in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @param content the content of this FAB, typically an [Icon]\n */\n@Composable\nfun FloatingActionButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    shape: Shape = FloatingActionButtonDefaults.shape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable () -> Unit,\n) =\n    FloatingActionButton(\n        onClick,\n        ExtendedFabPrimaryTokens.LabelTextFont.value,\n        FabBaselineTokens.ContainerWidth,\n        FabBaselineTokens.ContainerHeight,\n        modifier,\n        shape,\n        containerColor,\n        contentColor,\n        elevation,\n        interactionSource,\n        content,\n    )\n\n@Composable\nprivate fun FloatingActionButton(\n    onClick: () -> Unit,\n    textStyle: TextStyle,\n    minWidth: Dp,\n    minHeight: Dp,\n    modifier: Modifier = Modifier,\n    shape: Shape = FloatingActionButtonDefaults.shape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable () -> Unit,\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n    Surface(\n        onClick = onClick,\n        modifier = modifier.semantics { role = Role.Button },\n        shape = shape,\n        color = containerColor,\n        contentColor = contentColor,\n        tonalElevation = elevation.tonalElevation(),\n        shadowElevation = elevation.shadowElevation(interactionSource = interactionSource).value,\n        interactionSource = interactionSource,\n    ) {\n        ProvideContentColorTextStyle(contentColor = contentColor, textStyle = textStyle) {\n            Box(\n                modifier = Modifier.defaultMinSize(minWidth = minWidth, minHeight = minHeight),\n                contentAlignment = Alignment.Center,\n            ) {\n                content()\n            }\n        }\n    }\n}\n\n/**\n * [Material Design small floating action\n * button](https://m3.material.io/components/floating-action-button/overview)\n *\n * The FAB represents the most important action on a screen. It puts key actions within reach.\n *\n * ![Small FAB\n * image](https://developer.android.com/images/reference/androidx/compose/material3/small-fab.png)\n *\n * @sample androidx.compose.material3.samples.SmallFloatingActionButtonSample\n *\n * FABs can also be shown and hidden with an animation when the main content is scrolled:\n *\n * @sample androidx.compose.material3.samples.AnimatedFloatingActionButtonSample\n * @param onClick called when this FAB is clicked\n * @param modifier the [Modifier] to be applied to this FAB\n * @param shape defines the shape of this FAB's container and shadow (when using [elevation])\n * @param containerColor the color used for the background of this FAB. Use [Color.Transparent] to\n *   have no color.\n * @param contentColor the preferred color for content inside this FAB. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param elevation [FloatingActionButtonElevation] used to resolve the elevation for this FAB in\n *   different states. This controls the size of the shadow below the FAB. Additionally, when the\n *   container color is [ColorScheme.surface], this controls the amount of primary color applied as\n *   an overlay. See also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance or\n *   preview the FAB in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @param content the content of this FAB, typically an [Icon]\n */\n@Composable\nfun SmallFloatingActionButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    shape: Shape = FloatingActionButtonDefaults.smallShape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable () -> Unit,\n) {\n    FloatingActionButton(\n        onClick = onClick,\n        modifier =\n            modifier.sizeIn(\n                minWidth = FabSmallTokens.ContainerWidth,\n                minHeight = FabSmallTokens.ContainerHeight,\n            ),\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        elevation = elevation,\n        interactionSource = interactionSource,\n        content = content,\n    )\n}\n\n/**\n * [Material Design medium floating action\n * button](https://m3.material.io/components/floating-action-button/overview)\n *\n * The FAB represents the most important action on a screen. It puts key actions within reach.\n *\n * @sample androidx.compose.material3.samples.MediumFloatingActionButtonSample\n *\n * FABs can also be shown and hidden with an animation when the main content is scrolled:\n *\n * @sample androidx.compose.material3.samples.AnimatedFloatingActionButtonSample\n * @param onClick called when this FAB is clicked\n * @param modifier the [Modifier] to be applied to this FAB\n * @param shape defines the shape of this FAB's container and shadow (when using [elevation])\n * @param containerColor the color used for the background of this FAB. Use [Color.Transparent] to\n *   have no color.\n * @param contentColor the preferred color for content inside this FAB. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param elevation [FloatingActionButtonElevation] used to resolve the elevation for this FAB in\n *   different states. This controls the size of the shadow below the FAB. Additionally, when the\n *   container color is [ColorScheme.surface], this controls the amount of primary color applied as\n *   an overlay. See also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance or\n *   preview the FAB in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @param content the content of this FAB, typically an [Icon]\n */\n@ExperimentalMaterial3ExpressiveApi\n@Composable\nfun MediumFloatingActionButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    shape: Shape = FloatingActionButtonDefaults.mediumShape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable () -> Unit,\n) {\n    FloatingActionButton(\n        onClick = onClick,\n        modifier =\n            modifier.sizeIn(\n                minWidth = FabMediumTokens.ContainerWidth,\n                minHeight = FabMediumTokens.ContainerHeight,\n            ),\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        elevation = elevation,\n        interactionSource = interactionSource,\n        content = content,\n    )\n}\n\n/**\n * [Material Design large floating action\n * button](https://m3.material.io/components/floating-action-button/overview)\n *\n * The FAB represents the most important action on a screen. It puts key actions within reach.\n *\n * ![Large FAB\n * image](https://developer.android.com/images/reference/androidx/compose/material3/large-fab.png)\n *\n * @sample androidx.compose.material3.samples.LargeFloatingActionButtonSample\n *\n * FABs can also be shown and hidden with an animation when the main content is scrolled:\n *\n * @sample androidx.compose.material3.samples.AnimatedFloatingActionButtonSample\n * @param onClick called when this FAB is clicked\n * @param modifier the [Modifier] to be applied to this FAB\n * @param shape defines the shape of this FAB's container and shadow (when using [elevation])\n * @param containerColor the color used for the background of this FAB. Use [Color.Transparent] to\n *   have no color.\n * @param contentColor the preferred color for content inside this FAB. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param elevation [FloatingActionButtonElevation] used to resolve the elevation for this FAB in\n *   different states. This controls the size of the shadow below the FAB. Additionally, when the\n *   container color is [ColorScheme.surface], this controls the amount of primary color applied as\n *   an overlay. See also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance or\n *   preview the FAB in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @param content the content of this FAB, typically an [Icon]\n */\n@Composable\nfun LargeFloatingActionButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    shape: Shape = FloatingActionButtonDefaults.largeShape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable () -> Unit,\n) {\n    FloatingActionButton(\n        onClick = onClick,\n        modifier =\n            modifier.sizeIn(\n                minWidth = FabLargeTokens.ContainerWidth,\n                minHeight = FabLargeTokens.ContainerHeight,\n            ),\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        elevation = elevation,\n        interactionSource = interactionSource,\n        content = content,\n    )\n}\n\n// TODO link to image\n/**\n * [Material Design small extended floating action\n * button](https://m3.material.io/components/extended-fab/overview)\n *\n * Extended FABs help people take primary actions. They're wider than FABs to accommodate a text\n * label and larger target area.\n *\n * The other small extended floating action button overload supports a text label and icon.\n *\n * @sample androidx.compose.material3.samples.SmallExtendedFloatingActionButtonTextSample\n * @param onClick called when this FAB is clicked\n * @param modifier the [Modifier] to be applied to this FAB\n * @param shape defines the shape of this FAB's container and shadow (when using [elevation])\n * @param containerColor the color used for the background of this FAB. Use [Color.Transparent] to\n *   have no color.\n * @param contentColor the preferred color for content inside this FAB. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param elevation [FloatingActionButtonElevation] used to resolve the elevation for this FAB in\n *   different states. This controls the size of the shadow below the FAB. Additionally, when the\n *   container color is [ColorScheme.surface], this controls the amount of primary color applied as\n *   an overlay. See also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance or\n *   preview the FAB in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @param content the content of this FAB, typically a [Text] label\n */\n@ExperimentalMaterial3ExpressiveApi\n@Composable\nfun SmallExtendedFloatingActionButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    shape: Shape = FloatingActionButtonDefaults.smallExtendedFabShape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) {\n    FloatingActionButton(\n        onClick = onClick,\n        textStyle = SmallExtendedFabTextStyle.value,\n        minWidth = SmallExtendedFabMinimumWidth,\n        minHeight = SmallExtendedFabMinimumHeight,\n        modifier = modifier,\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        elevation = elevation,\n        interactionSource = interactionSource,\n    ) {\n        Row(\n            modifier =\n                Modifier.padding(\n                    start = SmallExtendedFabPaddingStart,\n                    end = SmallExtendedFabPaddingEnd,\n                ),\n            horizontalArrangement = Arrangement.Center,\n            verticalAlignment = Alignment.CenterVertically,\n            content = content,\n        )\n    }\n}\n\n// TODO link to image\n/**\n * [Material Design medium extended floating action\n * button](https://m3.material.io/components/extended-fab/overview)\n *\n * Extended FABs help people take primary actions. They're wider than FABs to accommodate a text\n * label and larger target area.\n *\n * The other medium extended floating action button overload supports a text label and icon.\n *\n * @sample androidx.compose.material3.samples.MediumExtendedFloatingActionButtonTextSample\n * @param onClick called when this FAB is clicked\n * @param modifier the [Modifier] to be applied to this FAB\n * @param shape defines the shape of this FAB's container and shadow (when using [elevation])\n * @param containerColor the color used for the background of this FAB. Use [Color.Transparent] to\n *   have no color.\n * @param contentColor the preferred color for content inside this FAB. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param elevation [FloatingActionButtonElevation] used to resolve the elevation for this FAB in\n *   different states. This controls the size of the shadow below the FAB. Additionally, when the\n *   container color is [ColorScheme.surface], this controls the amount of primary color applied as\n *   an overlay. See also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance or\n *   preview the FAB in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @param content the content of this FAB, typically a [Text] label\n */\n@ExperimentalMaterial3ExpressiveApi\n@Composable\nfun MediumExtendedFloatingActionButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    shape: Shape = FloatingActionButtonDefaults.mediumExtendedFabShape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) {\n    FloatingActionButton(\n        onClick = onClick,\n        textStyle = MediumExtendedFabTextStyle.value,\n        minWidth = MediumExtendedFabMinimumWidth,\n        minHeight = MediumExtendedFabMinimumHeight,\n        modifier = modifier,\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        elevation = elevation,\n        interactionSource = interactionSource,\n    ) {\n        Row(\n            modifier =\n                Modifier.padding(\n                    start = MediumExtendedFabPaddingStart,\n                    end = MediumExtendedFabPaddingEnd,\n                ),\n            horizontalArrangement = Arrangement.Center,\n            verticalAlignment = Alignment.CenterVertically,\n            content = content,\n        )\n    }\n}\n\n// TODO link to image\n/**\n * [Material Design large extended floating action\n * button](https://m3.material.io/components/extended-fab/overview)\n *\n * Extended FABs help people take primary actions. They're wider than FABs to accommodate a text\n * label and larger target area.\n *\n * The other large extended floating action button overload supports a text label and icon.\n *\n * @sample androidx.compose.material3.samples.LargeExtendedFloatingActionButtonTextSample\n * @param onClick called when this FAB is clicked\n * @param modifier the [Modifier] to be applied to this FAB\n * @param shape defines the shape of this FAB's container and shadow (when using [elevation])\n * @param containerColor the color used for the background of this FAB. Use [Color.Transparent] to\n *   have no color.\n * @param contentColor the preferred color for content inside this FAB. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param elevation [FloatingActionButtonElevation] used to resolve the elevation for this FAB in\n *   different states. This controls the size of the shadow below the FAB. Additionally, when the\n *   container color is [ColorScheme.surface], this controls the amount of primary color applied as\n *   an overlay. See also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance or\n *   preview the FAB in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @param content the content of this FAB, typically a [Text] label\n */\n@ExperimentalMaterial3ExpressiveApi\n@Composable\nfun LargeExtendedFloatingActionButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    shape: Shape = FloatingActionButtonDefaults.largeExtendedFabShape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) {\n    FloatingActionButton(\n        onClick = onClick,\n        textStyle = LargeExtendedFabTextStyle.value,\n        minWidth = LargeExtendedFabMinimumWidth,\n        minHeight = LargeExtendedFabMinimumHeight,\n        modifier = modifier,\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        elevation = elevation,\n        interactionSource = interactionSource,\n    ) {\n        Row(\n            modifier =\n                Modifier.padding(\n                    start = LargeExtendedFabPaddingStart,\n                    end = LargeExtendedFabPaddingEnd,\n                ),\n            horizontalArrangement = Arrangement.Center,\n            verticalAlignment = Alignment.CenterVertically,\n            content = content,\n        )\n    }\n}\n\n/**\n * [Material Design extended floating action\n * button](https://m3.material.io/components/extended-fab/overview)\n *\n * Extended FABs help people take primary actions. They're wider than FABs to accommodate a text\n * label and larger target area.\n *\n * ![Extended FAB\n * image](https://developer.android.com/images/reference/androidx/compose/material3/extended-fab.png)\n *\n * The other extended floating action button overload supports a text label and icon.\n *\n * @sample androidx.compose.material3.samples.ExtendedFloatingActionButtonTextSample\n * @param onClick called when this FAB is clicked\n * @param modifier the [Modifier] to be applied to this FAB\n * @param shape defines the shape of this FAB's container and shadow (when using [elevation])\n * @param containerColor the color used for the background of this FAB. Use [Color.Transparent] to\n *   have no color.\n * @param contentColor the preferred color for content inside this FAB. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param elevation [FloatingActionButtonElevation] used to resolve the elevation for this FAB in\n *   different states. This controls the size of the shadow below the FAB. Additionally, when the\n *   container color is [ColorScheme.surface], this controls the amount of primary color applied as\n *   an overlay. See also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance or\n *   preview the FAB in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @param content the content of this FAB, typically a [Text] label\n */\n@Composable\nfun ExtendedFloatingActionButton(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    shape: Shape = FloatingActionButtonDefaults.extendedFabShape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable RowScope.() -> Unit,\n) {\n    FloatingActionButton(\n        onClick = onClick,\n        modifier = modifier,\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        elevation = elevation,\n        interactionSource = interactionSource,\n    ) {\n        Row(\n            modifier =\n                Modifier.sizeIn(minWidth = ExtendedFabMinimumWidth)\n                    .padding(horizontal = ExtendedFabTextPadding),\n            horizontalArrangement = Arrangement.Center,\n            verticalAlignment = Alignment.CenterVertically,\n            content = content,\n        )\n    }\n}\n\n/**\n * [Material Design small extended floating action\n * button](https://m3.material.io/components/extended-fab/overview)\n *\n * Extended FABs help people take primary actions. They're wider than FABs to accommodate a text\n * label and larger target area.\n *\n * The other small extended floating action button overload is for FABs without an icon.\n *\n * Default content description for accessibility is extended from the extended fabs icon. For custom\n * behavior, you can provide your own via [Modifier.semantics].\n *\n * @sample androidx.compose.material3.samples.SmallExtendedFloatingActionButtonSample\n * @sample androidx.compose.material3.samples.SmallAnimatedExtendedFloatingActionButtonSample\n * @param text label displayed inside this FAB\n * @param icon icon for this FAB, typically an [Icon]\n * @param onClick called when this FAB is clicked\n * @param modifier the [Modifier] to be applied to this FAB\n * @param expanded controls the expansion state of this FAB. In an expanded state, the FAB will show\n *   both the [icon] and [text]. In a collapsed state, the FAB will show only the [icon].\n * @param shape defines the shape of this FAB's container and shadow (when using [elevation])\n * @param containerColor the color used for the background of this FAB. Use [Color.Transparent] to\n *   have no color.\n * @param contentColor the preferred color for content inside this FAB. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param elevation [FloatingActionButtonElevation] used to resolve the elevation for this FAB in\n *   different states. This controls the size of the shadow below the FAB. Additionally, when the\n *   container color is [ColorScheme.surface], this controls the amount of primary color applied as\n *   an overlay. See also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance or\n *   preview the FAB in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n */\n@ExperimentalMaterial3ExpressiveApi\n@Composable\nfun SmallExtendedFloatingActionButton(\n    text: @Composable () -> Unit,\n    icon: @Composable () -> Unit,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    expanded: Boolean = true,\n    shape: Shape = FloatingActionButtonDefaults.smallExtendedFabShape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n) =\n    ExtendedFloatingActionButton(\n        text = text,\n        icon = icon,\n        onClick = onClick,\n        textStyle = SmallExtendedFabTextStyle.value,\n        minWidth = SmallExtendedFabMinimumWidth,\n        minHeight = SmallExtendedFabMinimumHeight,\n        startPadding = SmallExtendedFabPaddingStart,\n        endPadding = SmallExtendedFabPaddingEnd,\n        iconPadding = SmallExtendedFabIconPadding,\n        modifier = modifier,\n        expanded = expanded,\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        elevation = elevation,\n        interactionSource = interactionSource,\n    )\n\n/**\n * [Material Design medium extended floating action\n * button](https://m3.material.io/components/extended-fab/overview)\n *\n * Extended FABs help people take primary actions. They're wider than FABs to accommodate a text\n * label and larger target area.\n *\n * The other medium extended floating action button overload is for FABs without an icon.\n *\n * Default content description for accessibility is extended from the extended fabs icon. For custom\n * behavior, you can provide your own via [Modifier.semantics].\n *\n * @sample androidx.compose.material3.samples.MediumExtendedFloatingActionButtonSample\n * @sample androidx.compose.material3.samples.MediumAnimatedExtendedFloatingActionButtonSample\n * @param text label displayed inside this FAB\n * @param icon icon for this FAB, typically an [Icon]\n * @param onClick called when this FAB is clicked\n * @param modifier the [Modifier] to be applied to this FAB\n * @param expanded controls the expansion state of this FAB. In an expanded state, the FAB will show\n *   both the [icon] and [text]. In a collapsed state, the FAB will show only the [icon].\n * @param shape defines the shape of this FAB's container and shadow (when using [elevation])\n * @param containerColor the color used for the background of this FAB. Use [Color.Transparent] to\n *   have no color.\n * @param contentColor the preferred color for content inside this FAB. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param elevation [FloatingActionButtonElevation] used to resolve the elevation for this FAB in\n *   different states. This controls the size of the shadow below the FAB. Additionally, when the\n *   container color is [ColorScheme.surface], this controls the amount of primary color applied as\n *   an overlay. See also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance or\n *   preview the FAB in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n */\n@ExperimentalMaterial3ExpressiveApi\n@Composable\nfun MediumExtendedFloatingActionButton(\n    text: @Composable () -> Unit,\n    icon: @Composable () -> Unit,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    expanded: Boolean = true,\n    shape: Shape = FloatingActionButtonDefaults.mediumExtendedFabShape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n) =\n    ExtendedFloatingActionButton(\n        text = text,\n        icon = icon,\n        onClick = onClick,\n        textStyle = MediumExtendedFabTextStyle.value,\n        minWidth = MediumExtendedFabMinimumWidth,\n        minHeight = MediumExtendedFabMinimumHeight,\n        startPadding = MediumExtendedFabPaddingStart,\n        endPadding = MediumExtendedFabPaddingEnd,\n        iconPadding = MediumExtendedFabIconPadding,\n        modifier = modifier,\n        expanded = expanded,\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        elevation = elevation,\n        interactionSource = interactionSource,\n    )\n\n/**\n * [Material Design large extended floating action\n * button](https://m3.material.io/components/extended-fab/overview)\n *\n * Extended FABs help people take primary actions. They're wider than FABs to accommodate a text\n * label and larger target area.\n *\n * The other large extended floating action button overload is for FABs without an icon.\n *\n * Default content description for accessibility is extended from the extended fabs icon. For custom\n * behavior, you can provide your own via [Modifier.semantics].\n *\n * @sample androidx.compose.material3.samples.LargeExtendedFloatingActionButtonSample\n * @sample androidx.compose.material3.samples.LargeAnimatedExtendedFloatingActionButtonSample\n * @param text label displayed inside this FAB\n * @param icon icon for this FAB, typically an [Icon]\n * @param onClick called when this FAB is clicked\n * @param modifier the [Modifier] to be applied to this FAB\n * @param expanded controls the expansion state of this FAB. In an expanded state, the FAB will show\n *   both the [icon] and [text]. In a collapsed state, the FAB will show only the [icon].\n * @param shape defines the shape of this FAB's container and shadow (when using [elevation])\n * @param containerColor the color used for the background of this FAB. Use [Color.Transparent] to\n *   have no color.\n * @param contentColor the preferred color for content inside this FAB. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param elevation [FloatingActionButtonElevation] used to resolve the elevation for this FAB in\n *   different states. This controls the size of the shadow below the FAB. Additionally, when the\n *   container color is [ColorScheme.surface], this controls the amount of primary color applied as\n *   an overlay. See also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance or\n *   preview the FAB in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n */\n@ExperimentalMaterial3ExpressiveApi\n@Composable\nfun LargeExtendedFloatingActionButton(\n    text: @Composable () -> Unit,\n    icon: @Composable () -> Unit,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    expanded: Boolean = true,\n    shape: Shape = FloatingActionButtonDefaults.largeExtendedFabShape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n) =\n    ExtendedFloatingActionButton(\n        text = text,\n        icon = icon,\n        onClick = onClick,\n        textStyle = LargeExtendedFabTextStyle.value,\n        minWidth = LargeExtendedFabMinimumWidth,\n        minHeight = LargeExtendedFabMinimumHeight,\n        startPadding = LargeExtendedFabPaddingStart,\n        endPadding = LargeExtendedFabPaddingEnd,\n        iconPadding = LargeExtendedFabIconPadding,\n        modifier = modifier,\n        expanded = expanded,\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        elevation = elevation,\n        interactionSource = interactionSource,\n    )\n\n/**\n * [Material Design extended floating action\n * button](https://m3.material.io/components/extended-fab/overview)\n *\n * Extended FABs help people take primary actions. They're wider than FABs to accommodate a text\n * label and larger target area.\n *\n * ![Extended FAB\n * image](https://developer.android.com/images/reference/androidx/compose/material3/extended-fab.png)\n *\n * The other extended floating action button overload is for FABs without an icon.\n *\n * Default content description for accessibility is extended from the extended fabs icon. For custom\n * behavior, you can provide your own via [Modifier.semantics].\n *\n * @sample androidx.compose.material3.samples.ExtendedFloatingActionButtonSample\n * @sample androidx.compose.material3.samples.AnimatedExtendedFloatingActionButtonSample\n * @param text label displayed inside this FAB\n * @param icon icon for this FAB, typically an [Icon]\n * @param onClick called when this FAB is clicked\n * @param modifier the [Modifier] to be applied to this FAB\n * @param expanded controls the expansion state of this FAB. In an expanded state, the FAB will show\n *   both the [icon] and [text]. In a collapsed state, the FAB will show only the [icon].\n * @param shape defines the shape of this FAB's container and shadow (when using [elevation])\n * @param containerColor the color used for the background of this FAB. Use [Color.Transparent] to\n *   have no color.\n * @param contentColor the preferred color for content inside this FAB. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param elevation [FloatingActionButtonElevation] used to resolve the elevation for this FAB in\n *   different states. This controls the size of the shadow below the FAB. Additionally, when the\n *   container color is [ColorScheme.surface], this controls the amount of primary color applied as\n *   an overlay. See also: [Surface].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this FAB. You can use this to change the FAB's appearance or\n *   preview the FAB in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n */\n@Composable\nfun ExtendedFloatingActionButton(\n    text: @Composable () -> Unit,\n    icon: @Composable () -> Unit,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    expanded: Boolean = true,\n    shape: Shape = FloatingActionButtonDefaults.extendedFabShape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    FloatingActionButton(\n        onClick = onClick,\n        modifier = modifier,\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        elevation = elevation,\n        interactionSource = interactionSource,\n    ) {\n        val startPadding = if (expanded) ExtendedFabStartIconPadding else 0.dp\n        val endPadding = if (expanded) ExtendedFabTextPadding else 0.dp\n\n        Row(\n            modifier =\n                Modifier.sizeIn(\n                        minWidth =\n                            if (expanded) {\n                                ExtendedFabMinimumWidth\n                            } else {\n                                FabBaselineTokens.ContainerWidth\n                            }\n                    )\n                    .padding(start = startPadding, end = endPadding),\n            verticalAlignment = Alignment.CenterVertically,\n            horizontalArrangement = if (expanded) Arrangement.Start else Arrangement.Center,\n        ) {\n            icon()\n            AnimatedVisibility(\n                visible = expanded,\n                enter = extendedFabExpandAnimation(),\n                exit = extendedFabCollapseAnimation(),\n            ) {\n                Row(Modifier.clearAndSetSemantics {}) {\n                    Spacer(Modifier.width(ExtendedFabEndIconPadding))\n                    text()\n                }\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun ExtendedFloatingActionButton(\n    text: @Composable () -> Unit,\n    icon: @Composable () -> Unit,\n    onClick: () -> Unit,\n    textStyle: TextStyle,\n    minWidth: Dp,\n    minHeight: Dp,\n    startPadding: Dp,\n    endPadding: Dp,\n    iconPadding: Dp,\n    modifier: Modifier = Modifier,\n    expanded: Boolean = true,\n    shape: Shape = FloatingActionButtonDefaults.extendedFabShape,\n    containerColor: Color = FloatingActionButtonDefaults.containerColor,\n    contentColor: Color = contentColorFor(containerColor),\n    elevation: FloatingActionButtonElevation = FloatingActionButtonDefaults.elevation(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    FloatingActionButton(\n        onClick = onClick,\n        textStyle = textStyle,\n        minWidth = Dp.Unspecified,\n        minHeight = Dp.Unspecified,\n        modifier = modifier,\n        shape = shape,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        elevation = elevation,\n        interactionSource = interactionSource,\n    ) {\n        val expandTransition = updateTransition(if (expanded) 1f else 0f, label = \"expanded state\")\n        // TODO Load the motionScheme tokens from the component tokens file\n        val sizeAnimationSpec = MotionSchemeKeyTokens.FastSpatial.value<Float>()\n        val opacityAnimationSpec = MotionSchemeKeyTokens.FastEffects.value<Float>()\n        val expandedWidthProgress =\n            expandTransition.animateFloat(transitionSpec = { sizeAnimationSpec }) { it }\n        val expandedAlphaProgress =\n            expandTransition.animateFloat(transitionSpec = { opacityAnimationSpec }) { it }\n        Row(\n            modifier =\n                Modifier.layout { measurable, constraints ->\n                        val expandedWidth = measurable.maxIntrinsicWidth(constraints.maxHeight)\n                        val width =\n                            lerp(minWidth.roundToPx(), expandedWidth, expandedWidthProgress.value)\n                        val placeable = measurable.measure(constraints)\n                        layout(width, placeable.height) { placeable.place(0, 0) }\n                    }\n                    .sizeIn(minWidth = minWidth, minHeight = minHeight)\n                    .padding(start = startPadding, end = endPadding),\n            verticalAlignment = Alignment.CenterVertically,\n        ) {\n            icon()\n            val fullyCollapsed =\n                remember(expandTransition) {\n                    derivedStateOf {\n                        expandTransition.currentState == 0f && !expandTransition.isRunning\n                    }\n                }\n            if (!fullyCollapsed.value) {\n                Row(\n                    Modifier.clearAndSetSemantics {}\n                        .graphicsLayer { alpha = expandedAlphaProgress.value }\n                ) {\n                    Spacer(Modifier.width(iconPadding))\n                    text()\n                }\n            }\n        }\n    }\n}\n\n/** Contains the default values used by [FloatingActionButton] */\nobject FloatingActionButtonDefaults {\n    internal val ShowHideTargetScale = 0.2f\n\n    /** The recommended size of the icon inside a [MediumFloatingActionButton]. */\n    @ExperimentalMaterial3ExpressiveApi val MediumIconSize = FabMediumTokens.IconSize\n\n    /** The recommended size of the icon inside a [LargeFloatingActionButton]. */\n    val LargeIconSize = 36.dp // TODO: FabLargeTokens.IconSize is incorrect\n\n    /** Default shape for a floating action button. */\n    val shape: Shape\n        @Composable get() = FabBaselineTokens.ContainerShape.value\n\n    /** Default shape for a small floating action button. */\n    val smallShape: Shape\n        @Composable get() = FabSmallTokens.ContainerShape.value\n\n    /** Default shape for a medium floating action button. */\n    @ExperimentalMaterial3ExpressiveApi\n    val mediumShape: Shape\n        @Composable get() = ShapeDefaults.LargeIncreased // TODO: update to use token\n\n    /** Default shape for a large floating action button. */\n    val largeShape: Shape\n        @Composable get() = FabLargeTokens.ContainerShape.value\n\n    /** Default shape for an extended floating action button. */\n    val extendedFabShape: Shape\n        @Composable get() = ExtendedFabPrimaryTokens.ContainerShape.value\n\n    /** Default shape for a small extended floating action button. */\n    @ExperimentalMaterial3ExpressiveApi\n    val smallExtendedFabShape: Shape\n        @Composable get() = ExtendedFabSmallTokens.ContainerShape.value\n\n    /** Default shape for a medium extended floating action button. */\n    @ExperimentalMaterial3ExpressiveApi\n    val mediumExtendedFabShape: Shape\n        @Composable get() = ShapeDefaults.LargeIncreased // TODO: update to use token\n\n    /** Default shape for a large extended floating action button. */\n    @ExperimentalMaterial3ExpressiveApi\n    val largeExtendedFabShape: Shape\n        @Composable get() = ExtendedFabLargeTokens.ContainerShape.value\n\n    /** Default container color for a floating action button. */\n    val containerColor: Color\n        @Composable get() = FabPrimaryContainerTokens.ContainerColor.value\n\n    /**\n     * Creates a [FloatingActionButtonElevation] that represents the elevation of a\n     * [FloatingActionButton] in different states. For use cases in which a less prominent\n     * [FloatingActionButton] is possible consider the [loweredElevation].\n     *\n     * @param defaultElevation the elevation used when the [FloatingActionButton] has no other\n     *   [Interaction]s.\n     * @param pressedElevation the elevation used when the [FloatingActionButton] is pressed.\n     * @param focusedElevation the elevation used when the [FloatingActionButton] is focused.\n     * @param hoveredElevation the elevation used when the [FloatingActionButton] is hovered.\n     */\n    @Composable\n    fun elevation(\n        defaultElevation: Dp = FabPrimaryContainerTokens.ContainerElevation,\n        pressedElevation: Dp = FabPrimaryContainerTokens.PressedContainerElevation,\n        focusedElevation: Dp = FabPrimaryContainerTokens.FocusedContainerElevation,\n        hoveredElevation: Dp = FabPrimaryContainerTokens.HoveredContainerElevation,\n    ): FloatingActionButtonElevation =\n        FloatingActionButtonElevation(\n            defaultElevation = defaultElevation,\n            pressedElevation = pressedElevation,\n            focusedElevation = focusedElevation,\n            hoveredElevation = hoveredElevation,\n        )\n\n    /**\n     * Use this to create a [FloatingActionButton] with a lowered elevation for less emphasis. Use\n     * [elevation] to get a normal [FloatingActionButton].\n     *\n     * @param defaultElevation the elevation used when the [FloatingActionButton] has no other\n     *   [Interaction]s.\n     * @param pressedElevation the elevation used when the [FloatingActionButton] is pressed.\n     * @param focusedElevation the elevation used when the [FloatingActionButton] is focused.\n     * @param hoveredElevation the elevation used when the [FloatingActionButton] is hovered.\n     */\n    @Composable\n    fun loweredElevation(\n        defaultElevation: Dp = ElevationTokens.Level1,\n        pressedElevation: Dp = ElevationTokens.Level1,\n        focusedElevation: Dp = ElevationTokens.Level1,\n        hoveredElevation: Dp = ElevationTokens.Level2,\n    ): FloatingActionButtonElevation =\n        FloatingActionButtonElevation(\n            defaultElevation = defaultElevation,\n            pressedElevation = pressedElevation,\n            focusedElevation = focusedElevation,\n            hoveredElevation = hoveredElevation,\n        )\n\n    /**\n     * Use this to create a [FloatingActionButton] that represents the default elevation of a\n     * [FloatingActionButton] used for [BottomAppBar] in different states.\n     *\n     * @param defaultElevation the elevation used when the [FloatingActionButton] has no other\n     *   [Interaction]s.\n     * @param pressedElevation the elevation used when the [FloatingActionButton] is pressed.\n     * @param focusedElevation the elevation used when the [FloatingActionButton] is focused.\n     * @param hoveredElevation the elevation used when the [FloatingActionButton] is hovered.\n     */\n    fun bottomAppBarFabElevation(\n        defaultElevation: Dp = 0.dp,\n        pressedElevation: Dp = 0.dp,\n        focusedElevation: Dp = 0.dp,\n        hoveredElevation: Dp = 0.dp,\n    ): FloatingActionButtonElevation =\n        FloatingActionButtonElevation(\n            defaultElevation,\n            pressedElevation,\n            focusedElevation,\n            hoveredElevation,\n        )\n}\n\n/**\n * Apply this modifier to a [FloatingActionButton] to show or hide it with an animation, typically\n * based on the app's main content scrolling.\n *\n * @param visible whether the FAB should be shown or hidden with an animation\n * @param alignment the direction towards which the FAB should be scaled to and from\n * @param targetScale the initial scale value when showing the FAB and the final scale value when\n *   hiding the FAB\n * @param scaleAnimationSpec the [AnimationSpec] to use for the scale part of the animation, if null\n *   the Fast Spatial spring spec from the [MotionScheme] will be used\n * @param alphaAnimationSpec the [AnimationSpec] to use for the alpha part of the animation, if null\n *   the Fast Effects spring spec from the [MotionScheme] will be used\n * @sample androidx.compose.material3.samples.AnimatedFloatingActionButtonSample\n */\n@ExperimentalMaterial3ExpressiveApi\nfun Modifier.animateFloatingActionButton(\n    visible: Boolean,\n    alignment: Alignment,\n    targetScale: Float = FloatingActionButtonDefaults.ShowHideTargetScale,\n    scaleAnimationSpec: AnimationSpec<Float>? = null,\n    alphaAnimationSpec: AnimationSpec<Float>? = null,\n): Modifier {\n    return this.then(\n        FabVisibleModifier(\n            visible = visible,\n            alignment = alignment,\n            targetScale = targetScale,\n            scaleAnimationSpec = scaleAnimationSpec,\n            alphaAnimationSpec = alphaAnimationSpec,\n        )\n    )\n}\n\ninternal data class FabVisibleModifier(\n    private val visible: Boolean,\n    private val alignment: Alignment,\n    private val targetScale: Float,\n    private val scaleAnimationSpec: AnimationSpec<Float>? = null,\n    private val alphaAnimationSpec: AnimationSpec<Float>? = null,\n) : ModifierNodeElement<FabVisibleNode>() {\n\n    override fun create(): FabVisibleNode =\n        FabVisibleNode(\n            visible = visible,\n            alignment = alignment,\n            targetScale = targetScale,\n            scaleAnimationSpec = scaleAnimationSpec,\n            alphaAnimationSpec = alphaAnimationSpec,\n        )\n\n    override fun update(node: FabVisibleNode) {\n        node.updateNode(\n            visible = visible,\n            alignment = alignment,\n            targetScale = targetScale,\n            scaleAnimationSpec = scaleAnimationSpec,\n            alphaAnimationSpec = alphaAnimationSpec,\n        )\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        // Show nothing in the inspector.\n    }\n}\n\ninternal class FabVisibleNode(\n    visible: Boolean,\n    private var alignment: Alignment,\n    private var targetScale: Float,\n    private var scaleAnimationSpec: AnimationSpec<Float>? = null,\n    private var alphaAnimationSpec: AnimationSpec<Float>? = null,\n) : DelegatingNode(), LayoutModifierNode, CompositionLocalConsumerModifierNode {\n\n    private val scaleAnimatable = Animatable(if (visible) 1f else 0f)\n    private val alphaAnimatable = Animatable(if (visible) 1f else 0f)\n\n    init {\n        delegate(\n            CacheDrawModifierNode {\n                val layer = obtainGraphicsLayer()\n                // Use a larger layer size to make sure the elevation shadow doesn't get clipped\n                // and offset via layer.topLeft and DrawScope.inset to preserve the visual\n                // position of the FAB.\n                val layerInsetSize = 16.dp.toPx()\n                val layerSize =\n                    Size(size.width + layerInsetSize * 2f, size.height + layerInsetSize * 2f)\n                        .toIntSize()\n                val nodeSize = size.toIntSize()\n\n                layer.apply {\n                    topLeft = IntOffset(-layerInsetSize.roundToInt(), -layerInsetSize.roundToInt())\n\n                    alpha = alphaAnimatable.value\n\n                    // Scale towards the direction of the provided alignment\n                    val alignOffset = alignment.align(IntSize(1, 1), nodeSize, layoutDirection)\n                    pivotOffset = alignOffset.toOffset() + Offset(layerInsetSize, layerInsetSize)\n                    scaleX = lerp(targetScale, 1f, scaleAnimatable.value)\n                    scaleY = lerp(targetScale, 1f, scaleAnimatable.value)\n\n                    record(size = layerSize) {\n                        inset(layerInsetSize, layerInsetSize) { this@record.drawContent() }\n                    }\n                }\n\n                onDrawWithContent { drawLayer(layer) }\n            }\n        )\n    }\n\n    @OptIn(ExperimentalMaterial3ExpressiveApi::class)\n    fun updateNode(\n        visible: Boolean,\n        alignment: Alignment,\n        targetScale: Float,\n        scaleAnimationSpec: AnimationSpec<Float>?,\n        alphaAnimationSpec: AnimationSpec<Float>?,\n    ) {\n        this.alignment = alignment\n        this.targetScale = targetScale\n        this.scaleAnimationSpec = scaleAnimationSpec\n        this.alphaAnimationSpec = alphaAnimationSpec\n\n        coroutineScope.launch {\n            // TODO Load the motionScheme tokens from the component tokens file\n            scaleAnimatable.animateTo(\n                targetValue = if (visible) 1f else 0f,\n                animationSpec =\n                    scaleAnimationSpec\n                        ?: currentValueOf(LocalMaterialTheme).motionScheme.fastSpatialSpec<Float>(),\n            )\n        }\n\n        coroutineScope.launch {\n            // TODO Load the motionScheme tokens from the component tokens file\n            alphaAnimatable.animateTo(\n                targetValue = if (visible) 1f else 0f,\n                animationSpec =\n                    alphaAnimationSpec\n                        ?: currentValueOf(LocalMaterialTheme).motionScheme.fastEffectsSpec<Float>(),\n            )\n        }\n    }\n\n    override fun MeasureScope.measure(\n        measurable: Measurable,\n        constraints: Constraints,\n    ): MeasureResult {\n        if (alphaAnimatable.value == 0f) {\n            return layout(0, 0) {}\n        }\n        val placeable = measurable.measure(constraints)\n        return layout(placeable.width, placeable.height) { placeable.place(0, 0) }\n    }\n}\n\n/**\n * Represents the tonal and shadow elevation for a floating action button in different states.\n *\n * See [FloatingActionButtonDefaults.elevation] for the default elevation used in a\n * [FloatingActionButton] and [ExtendedFloatingActionButton].\n */\n@Stable\nopen class FloatingActionButtonElevation\ninternal constructor(\n    private val defaultElevation: Dp,\n    private val pressedElevation: Dp,\n    private val focusedElevation: Dp,\n    private val hoveredElevation: Dp,\n) {\n    @Composable\n    internal fun shadowElevation(interactionSource: InteractionSource): State<Dp> {\n        return animateElevation(interactionSource = interactionSource)\n    }\n\n    internal fun tonalElevation(): Dp {\n        return defaultElevation\n    }\n\n    @Composable\n    private fun animateElevation(interactionSource: InteractionSource): State<Dp> {\n        val animatable =\n            remember(interactionSource) {\n                FloatingActionButtonElevationAnimatable(\n                    defaultElevation = defaultElevation,\n                    pressedElevation = pressedElevation,\n                    hoveredElevation = hoveredElevation,\n                    focusedElevation = focusedElevation,\n                )\n            }\n\n        LaunchedEffect(this) {\n            animatable.updateElevation(\n                defaultElevation = defaultElevation,\n                pressedElevation = pressedElevation,\n                hoveredElevation = hoveredElevation,\n                focusedElevation = focusedElevation,\n            )\n        }\n\n        LaunchedEffect(interactionSource) {\n            val interactions = mutableListOf<Interaction>()\n            interactionSource.interactions.collect { interaction ->\n                when (interaction) {\n                    is HoverInteraction.Enter -> {\n                        interactions.add(interaction)\n                    }\n                    is HoverInteraction.Exit -> {\n                        interactions.remove(interaction.enter)\n                    }\n                    is FocusInteraction.Focus -> {\n                        interactions.add(interaction)\n                    }\n                    is FocusInteraction.Unfocus -> {\n                        interactions.remove(interaction.focus)\n                    }\n                    is PressInteraction.Press -> {\n                        interactions.add(interaction)\n                    }\n                    is PressInteraction.Release -> {\n                        interactions.remove(interaction.press)\n                    }\n                    is PressInteraction.Cancel -> {\n                        interactions.remove(interaction.press)\n                    }\n                }\n                val targetInteraction = interactions.lastOrNull()\n                launch { animatable.animateElevation(to = targetInteraction) }\n            }\n        }\n\n        return animatable.asState()\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is FloatingActionButtonElevation) return false\n\n        if (defaultElevation != other.defaultElevation) return false\n        if (pressedElevation != other.pressedElevation) return false\n        if (focusedElevation != other.focusedElevation) return false\n        return hoveredElevation == other.hoveredElevation\n    }\n\n    override fun hashCode(): Int {\n        var result = defaultElevation.hashCode()\n        result = 31 * result + pressedElevation.hashCode()\n        result = 31 * result + focusedElevation.hashCode()\n        result = 31 * result + hoveredElevation.hashCode()\n        return result\n    }\n}\n\nprivate class FloatingActionButtonElevationAnimatable(\n    private var defaultElevation: Dp,\n    private var pressedElevation: Dp,\n    private var hoveredElevation: Dp,\n    private var focusedElevation: Dp,\n) {\n    private val animatable = Animatable(defaultElevation, Dp.VectorConverter)\n\n    private var lastTargetInteraction: Interaction? = null\n    private var targetInteraction: Interaction? = null\n\n    private fun Interaction?.calculateTarget(): Dp {\n        return when (this) {\n            is PressInteraction.Press -> pressedElevation\n            is HoverInteraction.Enter -> hoveredElevation\n            is FocusInteraction.Focus -> focusedElevation\n            else -> defaultElevation\n        }\n    }\n\n    suspend fun updateElevation(\n        defaultElevation: Dp,\n        pressedElevation: Dp,\n        hoveredElevation: Dp,\n        focusedElevation: Dp,\n    ) {\n        this.defaultElevation = defaultElevation\n        this.pressedElevation = pressedElevation\n        this.hoveredElevation = hoveredElevation\n        this.focusedElevation = focusedElevation\n        snapElevation()\n    }\n\n    private suspend fun snapElevation() {\n        val target = targetInteraction.calculateTarget()\n        if (animatable.targetValue != target) {\n            try {\n                animatable.snapTo(target)\n            } finally {\n                lastTargetInteraction = targetInteraction\n            }\n        }\n    }\n\n    suspend fun animateElevation(to: Interaction?) {\n        val target = to.calculateTarget()\n        // Update the interaction even if the values are the same, for when we change to another\n        // interaction later\n        targetInteraction = to\n        try {\n            if (animatable.targetValue != target) {\n                animatable.animateElevation(target = target, from = lastTargetInteraction, to = to)\n            }\n        } finally {\n            lastTargetInteraction = to\n        }\n    }\n\n    fun asState(): State<Dp> = animatable.asState()\n}\n\nprivate val SmallExtendedFabMinimumWidth = ExtendedFabSmallTokens.ContainerHeight\nprivate val SmallExtendedFabMinimumHeight = ExtendedFabSmallTokens.ContainerHeight\nprivate val SmallExtendedFabPaddingStart = ExtendedFabSmallTokens.LeadingSpace\nprivate val SmallExtendedFabPaddingEnd = ExtendedFabSmallTokens.TrailingSpace\nprivate val SmallExtendedFabIconPadding = ExtendedFabSmallTokens.IconLabelSpace\nprivate val SmallExtendedFabTextStyle = TypographyKeyTokens.TitleMedium\n\nprivate val MediumExtendedFabMinimumWidth = ExtendedFabMediumTokens.ContainerHeight\nprivate val MediumExtendedFabMinimumHeight = ExtendedFabMediumTokens.ContainerHeight\nprivate val MediumExtendedFabPaddingStart = ExtendedFabMediumTokens.LeadingSpace\nprivate val MediumExtendedFabPaddingEnd = ExtendedFabMediumTokens.TrailingSpace\n// TODO: ExtendedFabMediumTokens.IconLabelSpace is incorrect\nprivate val MediumExtendedFabIconPadding = 12.dp\nprivate val MediumExtendedFabTextStyle = TypographyKeyTokens.TitleLarge\n\nprivate val LargeExtendedFabMinimumWidth = ExtendedFabLargeTokens.ContainerHeight\nprivate val LargeExtendedFabMinimumHeight = ExtendedFabLargeTokens.ContainerHeight\nprivate val LargeExtendedFabPaddingStart = ExtendedFabLargeTokens.LeadingSpace\nprivate val LargeExtendedFabPaddingEnd = ExtendedFabLargeTokens.TrailingSpace\n// TODO: ExtendedFabLargeTokens.IconLabelSpace is incorrect\nprivate val LargeExtendedFabIconPadding = 16.dp\nprivate val LargeExtendedFabTextStyle = TypographyKeyTokens.HeadlineSmall\n\nprivate val ExtendedFabStartIconPadding = 16.dp\n\nprivate val ExtendedFabEndIconPadding = 12.dp\n\nprivate val ExtendedFabTextPadding = 20.dp\n\nprivate val ExtendedFabMinimumWidth = 80.dp\n\n@Composable\nprivate fun extendedFabCollapseAnimation() =\n    fadeOut(\n        // TODO Load the motionScheme tokens from the component tokens file\n        animationSpec = MotionSchemeKeyTokens.FastEffects.value()\n    ) +\n        shrinkHorizontally(\n            animationSpec = MotionSchemeKeyTokens.DefaultSpatial.value(),\n            shrinkTowards = Alignment.Start,\n        )\n\n@Composable\nprivate fun extendedFabExpandAnimation() =\n    fadeIn(\n        // TODO Load the motionScheme tokens from the component tokens file\n        animationSpec = MotionSchemeKeyTokens.DefaultEffects.value()\n    ) +\n        expandHorizontally(\n            animationSpec = MotionSchemeKeyTokens.FastSpatial.value(),\n            expandFrom = Alignment.Start,\n        )\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Checkbox.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.animation.animateColorAsState\nimport androidx.compose.animation.core.AnimationSpec\nimport androidx.compose.animation.core.animateFloat\nimport androidx.compose.animation.core.snap\nimport androidx.compose.animation.core.updateTransition\nimport androidx.compose.foundation.Canvas\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.requiredSize\nimport androidx.compose.foundation.layout.wrapContentSize\nimport androidx.compose.foundation.selection.triStateToggleable\nimport androidx.compose.material3.tokens.CheckboxTokens\nimport androidx.compose.material3.tokens.MotionSchemeKeyTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberUpdatedState\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.CornerRadius\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Path\nimport androidx.compose.ui.graphics.PathMeasure\nimport androidx.compose.ui.graphics.StrokeCap\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.drawscope.Fill\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.state.ToggleableState\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.lerp\nimport kotlin.math.floor\nimport kotlin.math.max\n\n/**\n * [Material Design checkbox](https://m3.material.io/components/checkbox/overview)\n *\n * Checkboxes allow users to select one or more items from a set. Checkboxes can turn an option on\n * or off.\n *\n * ![Checkbox\n * image](https://developer.android.com/images/reference/androidx/compose/material3/checkbox.png)\n *\n * Simple Checkbox sample:\n *\n * @sample androidx.compose.material3.samples.CheckboxSample\n *\n * Combined Checkbox with Text sample:\n *\n * @sample androidx.compose.material3.samples.CheckboxWithTextSample\n * @param checked whether this checkbox is checked or unchecked\n * @param onCheckedChange called when this checkbox is clicked. If `null`, then this checkbox will\n *   not be interactable, unless something else handles its input events and updates its state.\n * @param modifier the [Modifier] to be applied to this checkbox\n * @param enabled controls the enabled state of this checkbox. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param colors [CheckboxColors] that will be used to resolve the colors used for this checkbox in\n *   different states. See [CheckboxDefaults.colors].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this checkbox. You can use this to change the checkbox's appearance\n *   or preview the checkbox in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @see [TriStateCheckbox] if you require support for an indeterminate state.\n */\n@Composable\nfun Checkbox(\n    checked: Boolean,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: CheckboxColors = CheckboxDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    val strokeWidthPx = with(LocalDensity.current) { floor(CheckboxDefaults.StrokeWidth.toPx()) }\n    TriStateCheckbox(\n        state = ToggleableState(checked),\n        onClick =\n            if (onCheckedChange != null) {\n                { onCheckedChange(!checked) }\n            } else {\n                null\n            },\n        checkmarkStroke = Stroke(width = strokeWidthPx, cap = StrokeCap.Square),\n        outlineStroke = Stroke(width = strokeWidthPx),\n        modifier = modifier,\n        enabled = enabled,\n        colors = colors,\n        interactionSource = interactionSource,\n    )\n}\n\n/**\n * [Material Design checkbox](https://m3.material.io/components/checkbox/overview)\n *\n * Checkboxes allow users to select one or more items from a set. Checkboxes can turn an option on\n * or off.\n *\n * ![Checkbox\n * image](https://developer.android.com/images/reference/androidx/compose/material3/checkbox.png)\n *\n * This Checkbox function offers greater flexibility in visual customization. Using the [Stroke]\n * parameters, you can control the appearance of both the checkmark and the box that surrounds it.\n *\n * A sample of a `Checkbox` that uses a [Stroke] with rounded [StrokeCap] and\n * [androidx.compose.ui.graphics.StrokeJoin]:\n *\n * @sample androidx.compose.material3.samples.CheckboxRoundedStrokesSample\n * @param checked whether this checkbox is checked or unchecked\n * @param onCheckedChange called when this checkbox is clicked. If `null`, then this checkbox will\n *   not be interactable, unless something else handles its input events and updates its state.\n * @param checkmarkStroke stroke for the checkmark.\n * @param outlineStroke stroke for the checkmark's box outline. Note that this stroke is applied\n *   when drawing the outline's rounded rectangle, so attributions such as\n *   [androidx.compose.ui.graphics.StrokeJoin] will be ignored.\n * @param modifier the [Modifier] to be applied to this checkbox\n * @param enabled controls the enabled state of this checkbox. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param colors [CheckboxColors] that will be used to resolve the colors used for this checkbox in\n *   different states. See [CheckboxDefaults.colors].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this checkbox. You can use this to change the checkbox's appearance\n *   or preview the checkbox in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @see [TriStateCheckbox] if you require support for an indeterminate state.\n */\n@Composable\nfun Checkbox(\n    checked: Boolean,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    checkmarkStroke: Stroke,\n    outlineStroke: Stroke,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: CheckboxColors = CheckboxDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    TriStateCheckbox(\n        state = ToggleableState(checked),\n        onClick =\n            if (onCheckedChange != null) {\n                { onCheckedChange(!checked) }\n            } else {\n                null\n            },\n        checkmarkStroke = checkmarkStroke,\n        outlineStroke = outlineStroke,\n        modifier = modifier,\n        enabled = enabled,\n        colors = colors,\n        interactionSource = interactionSource,\n    )\n}\n\n/**\n * [Material Design checkbox](https://m3.material.io/components/checkbox/guidelines)\n *\n * Checkboxes can have a parent-child relationship with other checkboxes. When the parent checkbox\n * is checked, all child checkboxes are checked. If a parent checkbox is unchecked, all child\n * checkboxes are unchecked. If some, but not all, child checkboxes are checked, the parent checkbox\n * becomes an indeterminate checkbox.\n *\n * ![Checkbox\n * image](https://developer.android.com/images/reference/androidx/compose/material3/indeterminate-checkbox.png)\n *\n * @sample androidx.compose.material3.samples.TriStateCheckboxSample\n * @param state whether this checkbox is checked, unchecked, or in an indeterminate state\n * @param onClick called when this checkbox is clicked. If `null`, then this checkbox will not be\n *   interactable, unless something else handles its input events and updates its [state].\n * @param modifier the [Modifier] to be applied to this checkbox\n * @param enabled controls the enabled state of this checkbox. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param colors [CheckboxColors] that will be used to resolve the colors used for this checkbox in\n *   different states. See [CheckboxDefaults.colors].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this checkbox. You can use this to change the checkbox's appearance\n *   or preview the checkbox in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @see [Checkbox] if you want a simple component that represents Boolean state\n */\n@Composable\nfun TriStateCheckbox(\n    state: ToggleableState,\n    onClick: (() -> Unit)?,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: CheckboxColors = CheckboxDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    val strokeWidthPx = with(LocalDensity.current) { floor(CheckboxDefaults.StrokeWidth.toPx()) }\n    TriStateCheckbox(\n        state = state,\n        onClick = onClick,\n        checkmarkStroke = Stroke(width = strokeWidthPx, cap = StrokeCap.Square),\n        outlineStroke = Stroke(width = strokeWidthPx),\n        modifier = modifier,\n        enabled = enabled,\n        colors = colors,\n        interactionSource = interactionSource,\n    )\n}\n\n/**\n * [Material Design checkbox](https://m3.material.io/components/checkbox/guidelines)\n *\n * Checkboxes can have a parent-child relationship with other checkboxes. When the parent checkbox\n * is checked, all child checkboxes are checked. If a parent checkbox is unchecked, all child\n * checkboxes are unchecked. If some, but not all, child checkboxes are checked, the parent checkbox\n * becomes an indeterminate checkbox.\n *\n * ![Checkbox\n * image](https://developer.android.com/images/reference/androidx/compose/material3/indeterminate-checkbox.png)\n *\n * This Checkbox function offers greater flexibility in visual customization. Using the [Stroke]\n * parameters, you can control the appearance of both the checkmark and the box that surrounds it.\n *\n * A sample of a `TriStateCheckbox` that uses a [Stroke] with rounded [StrokeCap] and\n * [androidx.compose.ui.graphics.StrokeJoin]:\n *\n * @sample androidx.compose.material3.samples.TriStateCheckboxRoundedStrokesSample\n * @param state whether this checkbox is checked, unchecked, or in an indeterminate state\n * @param onClick called when this checkbox is clicked. If `null`, then this checkbox will not be\n *   interactable, unless something else handles its input events and updates its [state].\n * @param checkmarkStroke stroke for the checkmark.\n * @param outlineStroke stroke for the checkmark's box outline. Note that this stroke is applied\n *   when drawing the outline's rounded rectangle, so attributions such as\n *   [androidx.compose.ui.graphics.StrokeJoin] will be ignored.\n * @param modifier the [Modifier] to be applied to this checkbox\n * @param enabled controls the enabled state of this checkbox. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param colors [CheckboxColors] that will be used to resolve the colors used for this checkbox in\n *   different states. See [CheckboxDefaults.colors].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this checkbox. You can use this to change the checkbox's appearance\n *   or preview the checkbox in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n * @see [Checkbox] if you want a simple component that represents Boolean state\n */\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun TriStateCheckbox(\n    state: ToggleableState,\n    onClick: (() -> Unit)?,\n    checkmarkStroke: Stroke,\n    outlineStroke: Stroke,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    colors: CheckboxColors = CheckboxDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    val isCheckboxStylingFixEnabled = ComposeMaterial3Flags.isCheckboxStylingFixEnabled\n    val indication =\n        if (isCheckboxStylingFixEnabled)\n            ripple(\n                bounded = false,\n                radius = CheckboxTokens.StateLayerSize / 2,\n                color = colors.indicatorColor(state),\n            )\n        else {\n            ripple(bounded = false, radius = CheckboxTokens.StateLayerSize / 2)\n        }\n    val toggleableModifier =\n        if (onClick != null) {\n            Modifier.triStateToggleable(\n                state = state,\n                onClick = onClick,\n                enabled = enabled,\n                role = Role.Checkbox,\n                interactionSource = interactionSource,\n                indication = indication,\n            )\n        } else {\n            Modifier\n        }\n    CheckboxImpl(\n        enabled = enabled,\n        value = state,\n        modifier =\n            modifier\n                .then(\n                    if (onClick != null) {\n                        Modifier.minimumInteractiveComponentSize()\n                    } else {\n                        Modifier\n                    }\n                )\n                .then(toggleableModifier)\n                .then(\n                    if (isCheckboxStylingFixEnabled) {\n                        Modifier\n                    } else {\n                        Modifier.padding(CheckboxDefaultPadding)\n                    }\n                ),\n        colors = colors,\n        checkmarkStroke = checkmarkStroke,\n        outlineStroke = outlineStroke,\n    )\n}\n\n/** Defaults used in [Checkbox] and [TriStateCheckbox]. */\nobject CheckboxDefaults {\n    /**\n     * Creates a [CheckboxColors] that will animate between the provided colors according to the\n     * Material specification.\n     */\n    @Composable fun colors() = MaterialTheme.colorScheme.defaultCheckboxColors\n\n    /**\n     * Creates a [CheckboxColors] that will animate between the provided colors according to the\n     * Material specification.\n     *\n     * @param checkedColor the color that will be used for the border and box when checked\n     * @param uncheckedColor color that will be used for the border when unchecked. By default, the\n     *   inner box is transparent when unchecked.\n     * @param checkmarkColor color that will be used for the checkmark when checked\n     * @param disabledCheckedColor color that will be used for the box and border when disabled and\n     *   checked\n     * @param disabledUncheckedColor color that will be used for the border when disabled and\n     *   unchecked. By default, the inner box is transparent when unchecked.\n     * @param disabledIndeterminateColor color that will be used for the box and border in a\n     *   [TriStateCheckbox] when disabled AND in an [ToggleableState.Indeterminate] state\n     */\n    @Composable\n    fun colors(\n        checkedColor: Color = Color.Unspecified,\n        uncheckedColor: Color = Color.Unspecified,\n        checkmarkColor: Color = Color.Unspecified,\n        disabledCheckedColor: Color = Color.Unspecified,\n        disabledUncheckedColor: Color = Color.Unspecified,\n        disabledIndeterminateColor: Color = Color.Unspecified,\n    ): CheckboxColors =\n        MaterialTheme.colorScheme.defaultCheckboxColors.copy(\n            checkedCheckmarkColor = checkmarkColor,\n            uncheckedCheckmarkColor = Color.Transparent,\n            disabledCheckmarkColor = checkmarkColor,\n            checkedBoxColor = checkedColor,\n            uncheckedBoxColor = Color.Transparent,\n            disabledCheckedBoxColor = disabledCheckedColor,\n            disabledUncheckedBoxColor = Color.Transparent,\n            disabledIndeterminateBoxColor = disabledIndeterminateColor,\n            checkedBorderColor = checkedColor,\n            uncheckedBorderColor = uncheckedColor,\n            disabledBorderColor = disabledCheckedColor,\n            disabledUncheckedBorderColor = disabledUncheckedColor,\n            disabledIndeterminateBorderColor = disabledIndeterminateColor,\n        )\n\n    /**\n     * Creates a [CheckboxColors] that will animate between the provided colors according to the\n     * Material specification.\n     *\n     * @param checkedCheckmarkColor color that will be used for the checkmark when checked\n     * @param uncheckedCheckmarkColor color that will be used for the checkmark when unchecked\n     * @param disabledCheckmarkColor color that will be used for the checkmark when disabled\n     * @param checkedBoxColor the color that will be used for the box when checked\n     * @param uncheckedBoxColor color that will be used for the box when unchecked\n     * @param disabledCheckedBoxColor color that will be used for the box when disabled and checked\n     * @param disabledUncheckedBoxColor color that will be used for the box when disabled and\n     *   unchecked\n     * @param disabledIndeterminateBoxColor color that will be used for the box and border in a\n     *   [TriStateCheckbox] when disabled AND in an [ToggleableState.Indeterminate] state.\n     * @param checkedBorderColor color that will be used for the border when checked\n     * @param uncheckedBorderColor color that will be used for the border when unchecked\n     * @param disabledBorderColor color that will be used for the border when disabled and checked\n     * @param disabledUncheckedBorderColor color that will be used for the border when disabled and\n     *   unchecked\n     * @param disabledIndeterminateBorderColor color that will be used for the border when disabled\n     *   and in an [ToggleableState.Indeterminate] state.\n     */\n    @Composable\n    fun colors(\n        checkedCheckmarkColor: Color = Color.Unspecified,\n        uncheckedCheckmarkColor: Color = Color.Unspecified,\n        disabledCheckmarkColor: Color = Color.Unspecified,\n        checkedBoxColor: Color = Color.Unspecified,\n        uncheckedBoxColor: Color = Color.Unspecified,\n        disabledCheckedBoxColor: Color = Color.Unspecified,\n        disabledUncheckedBoxColor: Color = Color.Unspecified,\n        disabledIndeterminateBoxColor: Color = Color.Unspecified,\n        checkedBorderColor: Color = Color.Unspecified,\n        uncheckedBorderColor: Color = Color.Unspecified,\n        disabledBorderColor: Color = Color.Unspecified,\n        disabledUncheckedBorderColor: Color = Color.Unspecified,\n        disabledIndeterminateBorderColor: Color = Color.Unspecified,\n    ): CheckboxColors =\n        MaterialTheme.colorScheme.defaultCheckboxColors.copy(\n            checkedCheckmarkColor = checkedCheckmarkColor,\n            uncheckedCheckmarkColor = uncheckedCheckmarkColor,\n            disabledCheckmarkColor = disabledCheckmarkColor,\n            checkedBoxColor = checkedBoxColor,\n            uncheckedBoxColor = uncheckedBoxColor,\n            disabledCheckedBoxColor = disabledCheckedBoxColor,\n            disabledUncheckedBoxColor = disabledUncheckedBoxColor,\n            disabledIndeterminateBoxColor = disabledIndeterminateBoxColor,\n            checkedBorderColor = checkedBorderColor,\n            uncheckedBorderColor = uncheckedBorderColor,\n            disabledBorderColor = disabledBorderColor,\n            disabledUncheckedBorderColor = disabledUncheckedBorderColor,\n            disabledIndeterminateBorderColor = disabledIndeterminateBorderColor,\n        )\n\n    internal val ColorScheme.defaultCheckboxColors: CheckboxColors\n        get() {\n            return defaultCheckboxColorsCached\n                ?: CheckboxColors(\n                        checkedCheckmarkColor = fromToken(CheckboxTokens.SelectedIconColor),\n                        uncheckedCheckmarkColor = Color.Transparent,\n                        disabledCheckmarkColor =\n                            fromToken(CheckboxTokens.SelectedDisabledIconColor),\n                        checkedBoxColor = fromToken(CheckboxTokens.SelectedContainerColor),\n                        uncheckedBoxColor = Color.Transparent,\n                        disabledCheckedBoxColor =\n                            fromToken(CheckboxTokens.SelectedDisabledContainerColor)\n                                .copy(alpha = CheckboxTokens.SelectedDisabledContainerOpacity),\n                        disabledUncheckedBoxColor = Color.Transparent,\n                        disabledIndeterminateBoxColor =\n                            fromToken(CheckboxTokens.SelectedDisabledContainerColor)\n                                .copy(alpha = CheckboxTokens.SelectedDisabledContainerOpacity),\n                        checkedBorderColor = fromToken(CheckboxTokens.SelectedContainerColor),\n                        uncheckedBorderColor = fromToken(CheckboxTokens.UnselectedOutlineColor),\n                        disabledBorderColor =\n                            fromToken(CheckboxTokens.SelectedDisabledContainerColor)\n                                .copy(alpha = CheckboxTokens.SelectedDisabledContainerOpacity),\n                        disabledUncheckedBorderColor =\n                            fromToken(CheckboxTokens.UnselectedDisabledOutlineColor)\n                                .copy(alpha = CheckboxTokens.UnselectedDisabledContainerOpacity),\n                        disabledIndeterminateBorderColor =\n                            fromToken(CheckboxTokens.SelectedDisabledContainerColor)\n                                .copy(alpha = CheckboxTokens.SelectedDisabledContainerOpacity),\n                    )\n                    .also { defaultCheckboxColorsCached = it }\n        }\n\n    /**\n     * The default stroke width for a [Checkbox]. This width will be used for the checkmark when the\n     * `Checkbox` is in a checked or indeterminate states, or for the outline when it's unchecked.\n     */\n    val StrokeWidth = 2.dp\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nprivate fun CheckboxImpl(\n    enabled: Boolean,\n    value: ToggleableState,\n    modifier: Modifier,\n    colors: CheckboxColors,\n    checkmarkStroke: Stroke,\n    outlineStroke: Stroke,\n) {\n    val isCheckboxStylingFixEnabled = ComposeMaterial3Flags.isCheckboxStylingFixEnabled\n    val transition = updateTransition(value)\n    val defaultAnimationSpec = MotionSchemeKeyTokens.DefaultSpatial.value<Float>()\n    val checkDrawFraction =\n        transition.animateFloat(\n            transitionSpec = {\n                when {\n                    // TODO Load the motionScheme tokens from the component tokens file\n                    initialState == ToggleableState.Off -> defaultAnimationSpec\n                    targetState == ToggleableState.Off -> snap(delayMillis = SnapAnimationDelay)\n                    else -> defaultAnimationSpec\n                }\n            }\n        ) {\n            when (it) {\n                ToggleableState.On -> 1f\n                ToggleableState.Off -> 0f\n                ToggleableState.Indeterminate -> 1f\n            }\n        }\n\n    val checkCenterGravitationShiftFraction =\n        transition.animateFloat(\n            transitionSpec = {\n                when {\n                    // TODO Load the motionScheme tokens from the component tokens file\n                    initialState == ToggleableState.Off -> snap()\n                    targetState == ToggleableState.Off -> snap(delayMillis = SnapAnimationDelay)\n                    else -> defaultAnimationSpec\n                }\n            }\n        ) {\n            when (it) {\n                ToggleableState.On -> 0f\n                ToggleableState.Off -> 0f\n                ToggleableState.Indeterminate -> 1f\n            }\n        }\n    val checkCache = remember { CheckDrawingCache() }\n    val checkColor =\n        if (isCheckboxStylingFixEnabled) {\n            colors.checkmarkColor(enabled, value)\n        } else {\n            colors.checkmarkColor(value)\n        }\n    val boxColor = colors.boxColor(enabled, value)\n    val borderColor = colors.borderColor(enabled, value)\n    val containerSize =\n        if (isCheckboxStylingFixEnabled) {\n            CheckboxTokens.ContainerSize\n        } else {\n            CheckboxSize\n        }\n    Canvas(modifier.wrapContentSize(Alignment.Center).requiredSize(containerSize)) {\n        drawBox(\n            boxColor = boxColor.value,\n            borderColor = borderColor.value,\n            radius = RadiusSize.toPx(),\n            stroke = outlineStroke,\n        )\n        drawCheck(\n            checkColor = checkColor.value,\n            checkFraction = checkDrawFraction.value,\n            crossCenterGravitation = checkCenterGravitationShiftFraction.value,\n            stroke = checkmarkStroke,\n            drawingCache = checkCache,\n        )\n    }\n}\n\nprivate fun DrawScope.drawBox(boxColor: Color, borderColor: Color, radius: Float, stroke: Stroke) {\n    val halfStrokeWidth = stroke.width / 2.0f\n    val checkboxSize = size.width\n    if (boxColor == borderColor) {\n        drawRoundRect(\n            boxColor,\n            size = Size(checkboxSize, checkboxSize),\n            cornerRadius = CornerRadius(radius),\n            style = Fill,\n        )\n    } else {\n        drawRoundRect(\n            boxColor,\n            topLeft = Offset(stroke.width, stroke.width),\n            size = Size(checkboxSize - stroke.width * 2, checkboxSize - stroke.width * 2),\n            cornerRadius = CornerRadius(max(0f, radius - stroke.width)),\n            style = Fill,\n        )\n        drawRoundRect(\n            borderColor,\n            topLeft = Offset(halfStrokeWidth, halfStrokeWidth),\n            size = Size(checkboxSize - stroke.width, checkboxSize - stroke.width),\n            cornerRadius = CornerRadius(radius - halfStrokeWidth),\n            style = stroke,\n        )\n    }\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\nprivate fun DrawScope.drawCheck(\n    checkColor: Color,\n    checkFraction: Float,\n    crossCenterGravitation: Float,\n    stroke: Stroke,\n    drawingCache: CheckDrawingCache,\n) {\n    val isCheckboxStylingFixEnabled = ComposeMaterial3Flags.isCheckboxStylingFixEnabled\n    val width = size.width\n    val checkCrossX = 0.4f\n    val checkCrossY = if (isCheckboxStylingFixEnabled) 0.65f else 0.7f\n    val leftX = if (isCheckboxStylingFixEnabled) 0.25f else 0.2f\n    val leftY = 0.5f\n    val rightX = if (isCheckboxStylingFixEnabled) 0.75f else 0.8f\n    val rightY = 0.3f\n\n    val gravitatedCrossX = lerp(checkCrossX, 0.5f, crossCenterGravitation)\n    val gravitatedCrossY = lerp(checkCrossY, 0.5f, crossCenterGravitation)\n    // gravitate only Y for end to achieve center line\n    val gravitatedLeftY = lerp(leftY, 0.5f, crossCenterGravitation)\n    val gravitatedRightY = lerp(rightY, 0.5f, crossCenterGravitation)\n\n    with(drawingCache) {\n        checkPath.rewind()\n        checkPath.moveTo(width * leftX, width * gravitatedLeftY)\n        checkPath.lineTo(width * gravitatedCrossX, width * gravitatedCrossY)\n        checkPath.lineTo(width * rightX, width * gravitatedRightY)\n        // TODO: replace with proper declarative non-android alternative when ready (b/158188351)\n        pathMeasure.setPath(checkPath, false)\n        pathToDraw.rewind()\n        pathMeasure.getSegment(0f, pathMeasure.length * checkFraction, pathToDraw, true)\n    }\n    drawPath(drawingCache.pathToDraw, checkColor, style = stroke)\n}\n\n@Immutable\nprivate class CheckDrawingCache(\n    val checkPath: Path = Path(),\n    val pathMeasure: PathMeasure = PathMeasure(),\n    val pathToDraw: Path = Path(),\n)\n\n/**\n * Represents the colors used by the three different sections (checkmark, box, and border) of a\n * [Checkbox] or [TriStateCheckbox] in different states.\n *\n * @param checkedCheckmarkColor color that will be used for the checkmark when checked\n * @param uncheckedCheckmarkColor color that will be used for the checkmark when unchecked\n * @param checkedBoxColor the color that will be used for the box when checked\n * @param uncheckedBoxColor color that will be used for the box when unchecked\n * @param disabledCheckedBoxColor color that will be used for the box when disabled and checked\n * @param disabledUncheckedBoxColor color that will be used for the box when disabled and unchecked\n * @param disabledIndeterminateBoxColor color that will be used for the box and border in a\n *   [TriStateCheckbox] when disabled AND in an [ToggleableState.Indeterminate] state.\n * @param checkedBorderColor color that will be used for the border when checked\n * @param uncheckedBorderColor color that will be used for the border when unchecked\n * @param disabledBorderColor color that will be used for the border when disabled and checked\n * @param disabledUncheckedBorderColor color that will be used for the border when disabled and\n *   unchecked\n * @param disabledIndeterminateBorderColor color that will be used for the border when disabled and\n *   in an [ToggleableState.Indeterminate] state.\n * @param disabledCheckmarkColor color that will be used for the checkmark when disabled\n * @constructor create an instance with arbitrary colors, see [CheckboxDefaults.colors] for the\n *   default implementation that follows Material specifications.\n */\n@Immutable\nclass CheckboxColors\nconstructor(\n    val checkedCheckmarkColor: Color,\n    val uncheckedCheckmarkColor: Color,\n    val checkedBoxColor: Color,\n    val uncheckedBoxColor: Color,\n    val disabledCheckedBoxColor: Color,\n    val disabledUncheckedBoxColor: Color,\n    val disabledIndeterminateBoxColor: Color,\n    val checkedBorderColor: Color,\n    val uncheckedBorderColor: Color,\n    val disabledBorderColor: Color,\n    val disabledUncheckedBorderColor: Color,\n    val disabledIndeterminateBorderColor: Color,\n    val disabledCheckmarkColor: Color,\n) {\n    @Deprecated(\n        message =\n            \"This constructor is deprecated. Use the primary constructor that includes 'disabledCheckmarkColor'\",\n        level = DeprecationLevel.WARNING,\n    )\n    constructor(\n        checkedCheckmarkColor: Color,\n        uncheckedCheckmarkColor: Color,\n        checkedBoxColor: Color,\n        uncheckedBoxColor: Color,\n        disabledCheckedBoxColor: Color,\n        disabledUncheckedBoxColor: Color,\n        disabledIndeterminateBoxColor: Color,\n        checkedBorderColor: Color,\n        uncheckedBorderColor: Color,\n        disabledBorderColor: Color,\n        disabledUncheckedBorderColor: Color,\n        disabledIndeterminateBorderColor: Color,\n    ) : this(\n        checkedCheckmarkColor = checkedCheckmarkColor,\n        uncheckedCheckmarkColor = uncheckedCheckmarkColor,\n        checkedBoxColor = checkedBoxColor,\n        uncheckedBoxColor = uncheckedBoxColor,\n        disabledCheckedBoxColor = disabledCheckedBoxColor,\n        disabledUncheckedBoxColor = disabledUncheckedBoxColor,\n        disabledIndeterminateBoxColor = disabledIndeterminateBoxColor,\n        checkedBorderColor = checkedBorderColor,\n        uncheckedBorderColor = uncheckedBorderColor,\n        disabledBorderColor = disabledBorderColor,\n        disabledUncheckedBorderColor = disabledUncheckedBorderColor,\n        disabledIndeterminateBorderColor = disabledIndeterminateBorderColor,\n        disabledCheckmarkColor = checkedCheckmarkColor,\n    )\n\n    /**\n     * Returns a copy of this CheckboxColors, optionally overriding some of the values. This uses\n     * the Color.Unspecified to mean “use the value from the source”\n     */\n    @Deprecated(\n        message =\n            \"This function is deprecated. Use 'copy' that includes 'disabledCheckmarkColor' instead\",\n        level = DeprecationLevel.HIDDEN,\n    )\n    fun copy(\n        checkedCheckmarkColor: Color = this.checkedCheckmarkColor,\n        uncheckedCheckmarkColor: Color = this.uncheckedCheckmarkColor,\n        checkedBoxColor: Color = this.checkedBoxColor,\n        uncheckedBoxColor: Color = this.uncheckedBoxColor,\n        disabledCheckedBoxColor: Color = this.disabledCheckedBoxColor,\n        disabledUncheckedBoxColor: Color = this.disabledUncheckedBoxColor,\n        disabledIndeterminateBoxColor: Color = this.disabledIndeterminateBoxColor,\n        checkedBorderColor: Color = this.checkedBorderColor,\n        uncheckedBorderColor: Color = this.uncheckedBorderColor,\n        disabledBorderColor: Color = this.disabledBorderColor,\n        disabledUncheckedBorderColor: Color = this.disabledUncheckedBorderColor,\n        disabledIndeterminateBorderColor: Color = this.disabledIndeterminateBorderColor,\n    ) =\n        CheckboxColors(\n            checkedCheckmarkColor = checkedCheckmarkColor.takeOrElse { this.checkedCheckmarkColor },\n            uncheckedCheckmarkColor =\n                uncheckedCheckmarkColor.takeOrElse { this.uncheckedCheckmarkColor },\n            checkedBoxColor = checkedBoxColor.takeOrElse { this.checkedBoxColor },\n            uncheckedBoxColor = uncheckedBoxColor.takeOrElse { this.uncheckedBoxColor },\n            disabledCheckedBoxColor =\n                disabledCheckedBoxColor.takeOrElse { this.disabledCheckedBoxColor },\n            disabledUncheckedBoxColor =\n                disabledUncheckedBoxColor.takeOrElse { this.disabledUncheckedBoxColor },\n            disabledIndeterminateBoxColor =\n                disabledIndeterminateBoxColor.takeOrElse { this.disabledIndeterminateBoxColor },\n            checkedBorderColor = checkedBorderColor.takeOrElse { this.checkedBorderColor },\n            uncheckedBorderColor = uncheckedBorderColor.takeOrElse { this.uncheckedBorderColor },\n            disabledBorderColor = disabledBorderColor.takeOrElse { this.disabledBorderColor },\n            disabledUncheckedBorderColor =\n                disabledUncheckedBorderColor.takeOrElse { this.disabledUncheckedBorderColor },\n            disabledIndeterminateBorderColor =\n                disabledIndeterminateBorderColor.takeOrElse {\n                    this.disabledIndeterminateBorderColor\n                },\n            disabledCheckmarkColor = checkedCheckmarkColor.takeOrElse { this.checkedCheckmarkColor },\n        )\n\n    /**\n     * Returns a copy of this CheckboxColors, optionally overriding some of the values. This uses\n     * the Color.Unspecified to mean “use the value from the source”\n     */\n    fun copy(\n        checkedCheckmarkColor: Color = this.checkedCheckmarkColor,\n        uncheckedCheckmarkColor: Color = this.uncheckedCheckmarkColor,\n        checkedBoxColor: Color = this.checkedBoxColor,\n        uncheckedBoxColor: Color = this.uncheckedBoxColor,\n        disabledCheckedBoxColor: Color = this.disabledCheckedBoxColor,\n        disabledUncheckedBoxColor: Color = this.disabledUncheckedBoxColor,\n        disabledIndeterminateBoxColor: Color = this.disabledIndeterminateBoxColor,\n        checkedBorderColor: Color = this.checkedBorderColor,\n        uncheckedBorderColor: Color = this.uncheckedBorderColor,\n        disabledBorderColor: Color = this.disabledBorderColor,\n        disabledUncheckedBorderColor: Color = this.disabledUncheckedBorderColor,\n        disabledIndeterminateBorderColor: Color = this.disabledIndeterminateBorderColor,\n        disabledCheckmarkColor: Color = this.disabledCheckmarkColor,\n    ) =\n        CheckboxColors(\n            checkedCheckmarkColor = checkedCheckmarkColor.takeOrElse { this.checkedCheckmarkColor },\n            uncheckedCheckmarkColor =\n                uncheckedCheckmarkColor.takeOrElse { this.uncheckedCheckmarkColor },\n            checkedBoxColor = checkedBoxColor.takeOrElse { this.checkedBoxColor },\n            uncheckedBoxColor = uncheckedBoxColor.takeOrElse { this.uncheckedBoxColor },\n            disabledCheckedBoxColor =\n                disabledCheckedBoxColor.takeOrElse { this.disabledCheckedBoxColor },\n            disabledUncheckedBoxColor =\n                disabledUncheckedBoxColor.takeOrElse { this.disabledUncheckedBoxColor },\n            disabledIndeterminateBoxColor =\n                disabledIndeterminateBoxColor.takeOrElse { this.disabledIndeterminateBoxColor },\n            checkedBorderColor = checkedBorderColor.takeOrElse { this.checkedBorderColor },\n            uncheckedBorderColor = uncheckedBorderColor.takeOrElse { this.uncheckedBorderColor },\n            disabledBorderColor = disabledBorderColor.takeOrElse { this.disabledBorderColor },\n            disabledUncheckedBorderColor =\n                disabledUncheckedBorderColor.takeOrElse { this.disabledUncheckedBorderColor },\n            disabledIndeterminateBorderColor =\n                disabledIndeterminateBorderColor.takeOrElse {\n                    this.disabledIndeterminateBorderColor\n                },\n            disabledCheckmarkColor =\n                disabledCheckmarkColor.takeOrElse { this.disabledCheckmarkColor },\n        )\n\n    /**\n     * Represents the color used for the checkbox container's background indication, depending on\n     * [state].\n     *\n     * @param state the [ToggleableState] of the checkbox\n     */\n    internal fun indicatorColor(state: ToggleableState): Color {\n        return if (state == ToggleableState.Off) {\n            uncheckedBoxColor\n        } else {\n            checkedBoxColor\n        }\n    }\n\n    /**\n     * Represents the color used for the checkmark inside the checkbox, depending on [enabled] and\n     * [state].\n     *\n     * @param enabled whether the checkbox is enabled or not\n     * @param state the [ToggleableState] of the checkbox\n     */\n    @Composable\n    internal fun checkmarkColor(enabled: Boolean, state: ToggleableState): State<Color> {\n        val target =\n            if (enabled) {\n                if (state == ToggleableState.Off) {\n                    uncheckedCheckmarkColor\n                } else {\n                    checkedCheckmarkColor\n                }\n            } else {\n                disabledCheckmarkColor\n            }\n        return animateColorAsState(target, colorAnimationSpecForState(state))\n    }\n\n    /**\n     * Represents the color used for the checkmark inside the checkbox, depending on [state].\n     *\n     * @param state the [ToggleableState] of the checkbox\n     */\n    @Composable\n    internal fun checkmarkColor(state: ToggleableState): State<Color> {\n        val target =\n            if (state == ToggleableState.Off) {\n                uncheckedCheckmarkColor\n            } else {\n                checkedCheckmarkColor\n            }\n\n        return animateColorAsState(target, colorAnimationSpecForState(state))\n    }\n\n    /**\n     * Represents the color used for the box (background) of the checkbox, depending on [enabled]\n     * and [state].\n     *\n     * @param enabled whether the checkbox is enabled or not\n     * @param state the [ToggleableState] of the checkbox\n     */\n    @Composable\n    internal fun boxColor(enabled: Boolean, state: ToggleableState): State<Color> {\n        val target =\n            if (enabled) {\n                when (state) {\n                    ToggleableState.On,\n                    ToggleableState.Indeterminate -> checkedBoxColor\n                    ToggleableState.Off -> uncheckedBoxColor\n                }\n            } else {\n                when (state) {\n                    ToggleableState.On -> disabledCheckedBoxColor\n                    ToggleableState.Indeterminate -> disabledIndeterminateBoxColor\n                    ToggleableState.Off -> disabledUncheckedBoxColor\n                }\n            }\n\n        // If not enabled 'snap' to the disabled state, as there should be no animations between\n        // enabled / disabled.\n        return if (enabled) {\n            animateColorAsState(target, colorAnimationSpecForState(state))\n        } else {\n            rememberUpdatedState(target)\n        }\n    }\n\n    /**\n     * Represents the color used for the border of the checkbox, depending on [enabled] and [state].\n     *\n     * @param enabled whether the checkbox is enabled or not\n     * @param state the [ToggleableState] of the checkbox\n     */\n    @Composable\n    internal fun borderColor(enabled: Boolean, state: ToggleableState): State<Color> {\n        val target =\n            if (enabled) {\n                when (state) {\n                    ToggleableState.On,\n                    ToggleableState.Indeterminate -> checkedBorderColor\n                    ToggleableState.Off -> uncheckedBorderColor\n                }\n            } else {\n                when (state) {\n                    ToggleableState.Indeterminate -> disabledIndeterminateBorderColor\n                    ToggleableState.On -> disabledBorderColor\n                    ToggleableState.Off -> disabledUncheckedBorderColor\n                }\n            }\n\n        // If not enabled 'snap' to the disabled state, as there should be no animations between\n        // enabled / disabled.\n        return if (enabled) {\n            animateColorAsState(target, colorAnimationSpecForState(state))\n        } else {\n            rememberUpdatedState(target)\n        }\n    }\n\n    /** Returns the color [AnimationSpec] for the given state. */\n    @Composable\n    private fun colorAnimationSpecForState(state: ToggleableState): AnimationSpec<Color> {\n        // TODO Load the motionScheme tokens from the component tokens file\n        return if (state == ToggleableState.Off) {\n            // Box out\n            MotionSchemeKeyTokens.FastEffects.value()\n        } else {\n            // Box in\n            MotionSchemeKeyTokens.DefaultEffects.value()\n        }\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is CheckboxColors) return false\n\n        if (checkedCheckmarkColor != other.checkedCheckmarkColor) return false\n        if (uncheckedCheckmarkColor != other.uncheckedCheckmarkColor) return false\n        if (disabledCheckmarkColor != other.disabledCheckmarkColor) return false\n        if (checkedBoxColor != other.checkedBoxColor) return false\n        if (uncheckedBoxColor != other.uncheckedBoxColor) return false\n        if (disabledCheckedBoxColor != other.disabledCheckedBoxColor) return false\n        if (disabledUncheckedBoxColor != other.disabledUncheckedBoxColor) return false\n        if (disabledIndeterminateBoxColor != other.disabledIndeterminateBoxColor) return false\n        if (checkedBorderColor != other.checkedBorderColor) return false\n        if (uncheckedBorderColor != other.uncheckedBorderColor) return false\n        if (disabledBorderColor != other.disabledBorderColor) return false\n        if (disabledUncheckedBorderColor != other.disabledUncheckedBorderColor) return false\n        if (disabledIndeterminateBorderColor != other.disabledIndeterminateBorderColor) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = checkedCheckmarkColor.hashCode()\n        result = 31 * result + uncheckedCheckmarkColor.hashCode()\n        result = 31 * result + disabledCheckmarkColor.hashCode()\n        result = 31 * result + checkedBoxColor.hashCode()\n        result = 31 * result + uncheckedBoxColor.hashCode()\n        result = 31 * result + disabledCheckedBoxColor.hashCode()\n        result = 31 * result + disabledUncheckedBoxColor.hashCode()\n        result = 31 * result + disabledIndeterminateBoxColor.hashCode()\n        result = 31 * result + checkedBorderColor.hashCode()\n        result = 31 * result + uncheckedBorderColor.hashCode()\n        result = 31 * result + disabledBorderColor.hashCode()\n        result = 31 * result + disabledUncheckedBorderColor.hashCode()\n        result = 31 * result + disabledIndeterminateBorderColor.hashCode()\n        return result\n    }\n}\n\nprivate const val SnapAnimationDelay = 100\n\n// TODO(b/188529841): Update the padding and size when the Checkbox spec is finalized.\nprivate val CheckboxDefaultPadding = 2.dp\nprivate val CheckboxSize = 20.dp\nprivate val RadiusSize = 2.dp\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Switch.kt\n```kotlin\n/*\n * Copyright 2022 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.AnimationVector1D\nimport androidx.compose.animation.core.FiniteAnimationSpec\nimport androidx.compose.animation.core.SnapSpec\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.border\nimport androidx.compose.foundation.indication\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.InteractionSource\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.interaction.PressInteraction\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.requiredSize\nimport androidx.compose.foundation.layout.wrapContentSize\nimport androidx.compose.foundation.selection.toggleable\nimport androidx.compose.material3.tokens.MotionSchemeKeyTokens\nimport androidx.compose.material3.tokens.SwitchTokens\nimport androidx.compose.material3.tokens.SwitchTokens.TrackOutlineWidth\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.graphics.compositeOver\nimport androidx.compose.ui.graphics.takeOrElse\nimport androidx.compose.ui.layout.Measurable\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.node.LayoutModifierNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.node.invalidateMeasurement\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.dp\nimport kotlinx.coroutines.launch\n\n/**\n * [Material Design switch](https://m3.material.io/components/switch)\n *\n * Switches toggle the state of a single item on or off.\n *\n * ![Switch\n * image](https://developer.android.com/images/reference/androidx/compose/material3/switch.png)\n *\n * @sample androidx.compose.material3.samples.SwitchSample\n *\n * Switch can be used with a custom icon via [thumbContent] parameter\n *\n * @sample androidx.compose.material3.samples.SwitchWithThumbIconSample\n * @param checked whether or not this switch is checked\n * @param onCheckedChange called when this switch is clicked. If `null`, then this switch will not\n *   be interactable, unless something else handles its input events and updates its state.\n * @param modifier the [Modifier] to be applied to this switch\n * @param thumbContent content that will be drawn inside the thumb, expected to measure\n *   [SwitchDefaults.IconSize]\n * @param enabled controls the enabled state of this switch. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param colors [SwitchColors] that will be used to resolve the colors used for this switch in\n *   different states. See [SwitchDefaults.colors].\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this switch. You can use this to change the switch's appearance or\n *   preview the switch in different states. Note that if `null` is provided, interactions will\n *   still happen internally.\n */\n@Composable\n@Suppress(\"ComposableLambdaParameterNaming\", \"ComposableLambdaParameterPosition\")\nfun Switch(\n    checked: Boolean,\n    onCheckedChange: ((Boolean) -> Unit)?,\n    modifier: Modifier = Modifier,\n    thumbContent: (@Composable () -> Unit)? = null,\n    enabled: Boolean = true,\n    colors: SwitchColors = SwitchDefaults.colors(),\n    interactionSource: MutableInteractionSource? = null,\n) {\n    @Suppress(\"NAME_SHADOWING\")\n    val interactionSource = interactionSource ?: remember { MutableInteractionSource() }\n\n    // TODO: Add Swipeable modifier b/223797571\n    val toggleableModifier =\n        if (onCheckedChange != null) {\n            Modifier.minimumInteractiveComponentSize()\n                .toggleable(\n                    value = checked,\n                    onValueChange = onCheckedChange,\n                    enabled = enabled,\n                    role = Role.Switch,\n                    interactionSource = interactionSource,\n                    indication = null,\n                )\n        } else {\n            Modifier\n        }\n\n    SwitchImpl(\n        modifier =\n            modifier\n                .then(toggleableModifier)\n                .wrapContentSize(Alignment.Center)\n                .requiredSize(SwitchWidth, SwitchHeight),\n        checked = checked,\n        enabled = enabled,\n        colors = colors,\n        interactionSource = interactionSource,\n        thumbShape = SwitchTokens.HandleShape.value,\n        thumbContent = thumbContent,\n    )\n}\n\n@Composable\n@Suppress(\"ComposableLambdaParameterNaming\", \"ComposableLambdaParameterPosition\")\nprivate fun SwitchImpl(\n    modifier: Modifier,\n    checked: Boolean,\n    enabled: Boolean,\n    colors: SwitchColors,\n    thumbContent: (@Composable () -> Unit)?,\n    interactionSource: InteractionSource,\n    thumbShape: Shape,\n) {\n    val trackColor = colors.trackColor(enabled, checked)\n    val resolvedThumbColor = colors.thumbColor(enabled, checked)\n    val trackShape = SwitchTokens.TrackShape.value\n\n    Box(\n        modifier\n            .border(TrackOutlineWidth, colors.borderColor(enabled, checked), trackShape)\n            .background(trackColor, trackShape)\n    ) {\n        Box(\n            modifier =\n                Modifier.align(Alignment.CenterStart)\n                    .then(\n                        ThumbElement(\n                            interactionSource = interactionSource,\n                            checked = checked,\n                            // TODO Load the motionScheme tokens from the component tokens file\n                            animationSpec = MotionSchemeKeyTokens.FastSpatial.value(),\n                        )\n                    )\n                    .indication(\n                        interactionSource = interactionSource,\n                        indication =\n                            ripple(bounded = false, radius = SwitchTokens.StateLayerSize / 2),\n                    )\n                    .background(resolvedThumbColor, thumbShape),\n            contentAlignment = Alignment.Center,\n        ) {\n            if (thumbContent != null) {\n                val iconColor = colors.iconColor(enabled, checked)\n                CompositionLocalProvider(\n                    LocalContentColor provides iconColor,\n                    content = thumbContent,\n                )\n            }\n        }\n    }\n}\n\nprivate data class ThumbElement(\n    val interactionSource: InteractionSource,\n    val checked: Boolean,\n    val animationSpec: FiniteAnimationSpec<Float>,\n) : ModifierNodeElement<ThumbNode>() {\n    override fun create() = ThumbNode(interactionSource, checked, animationSpec)\n\n    override fun update(node: ThumbNode) {\n        node.interactionSource = interactionSource\n        if (node.checked != checked) {\n            node.invalidateMeasurement()\n        }\n        node.checked = checked\n        node.animationSpec = animationSpec\n        node.update()\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"switchThumb\"\n        properties[\"interactionSource\"] = interactionSource\n        properties[\"checked\"] = checked\n        properties[\"animationSpec\"] = animationSpec\n    }\n}\n\nprivate class ThumbNode(\n    var interactionSource: InteractionSource,\n    var checked: Boolean,\n    var animationSpec: FiniteAnimationSpec<Float>,\n) : Modifier.Node(), LayoutModifierNode {\n\n    override val shouldAutoInvalidate: Boolean\n        get() = false\n\n    private var isPressed = false\n    private var offsetAnim: Animatable<Float, AnimationVector1D>? = null\n    private var sizeAnim: Animatable<Float, AnimationVector1D>? = null\n    private var initialOffset: Float = Float.NaN\n    private var initialSize: Float = Float.NaN\n\n    override fun onAttach() {\n        coroutineScope.launch {\n            var pressCount = 0\n            interactionSource.interactions.collect { interaction ->\n                when (interaction) {\n                    is PressInteraction.Press -> pressCount++\n                    is PressInteraction.Release -> pressCount--\n                    is PressInteraction.Cancel -> pressCount--\n                }\n                val pressed = pressCount > 0\n                if (isPressed != pressed) {\n                    isPressed = pressed\n                    invalidateMeasurement()\n                }\n            }\n        }\n    }\n\n    override fun onReset() {\n        super.onReset()\n        offsetAnim = null\n        sizeAnim = null\n        initialSize = Float.NaN\n        initialOffset = Float.NaN\n    }\n\n    override fun MeasureScope.measure(\n        measurable: Measurable,\n        constraints: Constraints,\n    ): MeasureResult {\n        val hasContent =\n            measurable.maxIntrinsicHeight(constraints.maxWidth) != 0 &&\n                measurable.maxIntrinsicWidth(constraints.maxHeight) != 0\n        val size =\n            when {\n                isPressed -> SwitchTokens.PressedHandleWidth\n                hasContent || checked -> ThumbDiameter\n                else -> UncheckedThumbDiameter\n            }.toPx()\n\n        val actualSize = (sizeAnim?.value ?: size).toInt()\n        val placeable = measurable.measure(Constraints.fixed(actualSize, actualSize))\n        val thumbPaddingStart = (SwitchHeight - size.toDp()) / 2f\n        val minBound = thumbPaddingStart.toPx()\n        val thumbPathLength = (SwitchWidth - ThumbDiameter) - ThumbPadding\n        val maxBound = thumbPathLength.toPx()\n        val offset =\n            when {\n                isPressed && checked -> maxBound - TrackOutlineWidth.toPx()\n                isPressed && !checked -> TrackOutlineWidth.toPx()\n                checked -> maxBound\n                else -> minBound\n            }\n\n        if (sizeAnim?.targetValue != size) {\n            coroutineScope.launch {\n                sizeAnim?.animateTo(size, if (isPressed) SnapSpec else animationSpec)\n            }\n        }\n\n        if (offsetAnim?.targetValue != offset) {\n            coroutineScope.launch {\n                offsetAnim?.animateTo(offset, if (isPressed) SnapSpec else animationSpec)\n            }\n        }\n\n        if (initialSize.isNaN() && initialOffset.isNaN()) {\n            initialSize = size\n            initialOffset = offset\n        }\n\n        return layout(actualSize, actualSize) {\n            placeable.placeRelative(offsetAnim?.value?.toInt() ?: offset.toInt(), 0)\n        }\n    }\n\n    fun update() {\n        if (sizeAnim == null && !initialSize.isNaN()) {\n            sizeAnim = Animatable(initialSize)\n        }\n\n        if (offsetAnim == null && !initialOffset.isNaN()) offsetAnim = Animatable(initialOffset)\n    }\n}\n\n/** Contains the default values used by [Switch] */\nobject SwitchDefaults {\n    /**\n     * Creates a [SwitchColors] that represents the different colors used in a [Switch] in different\n     * states.\n     */\n    @Composable fun colors() = MaterialTheme.colorScheme.defaultSwitchColors\n\n    /**\n     * Creates a [SwitchColors] that represents the different colors used in a [Switch] in different\n     * states.\n     *\n     * @param checkedThumbColor the color used for the thumb when enabled and checked\n     * @param checkedTrackColor the color used for the track when enabled and checked\n     * @param checkedBorderColor the color used for the border when enabled and checked\n     * @param checkedIconColor the color used for the icon when enabled and checked\n     * @param uncheckedThumbColor the color used for the thumb when enabled and unchecked\n     * @param uncheckedTrackColor the color used for the track when enabled and unchecked\n     * @param uncheckedBorderColor the color used for the border when enabled and unchecked\n     * @param uncheckedIconColor the color used for the icon when enabled and unchecked\n     * @param disabledCheckedThumbColor the color used for the thumb when disabled and checked\n     * @param disabledCheckedTrackColor the color used for the track when disabled and checked\n     * @param disabledCheckedBorderColor the color used for the border when disabled and checked\n     * @param disabledCheckedIconColor the color used for the icon when disabled and checked\n     * @param disabledUncheckedThumbColor the color used for the thumb when disabled and unchecked\n     * @param disabledUncheckedTrackColor the color used for the track when disabled and unchecked\n     * @param disabledUncheckedBorderColor the color used for the border when disabled and unchecked\n     * @param disabledUncheckedIconColor the color used for the icon when disabled and unchecked\n     */\n    @Composable\n    fun colors(\n        checkedThumbColor: Color = SwitchTokens.SelectedHandleColor.value,\n        checkedTrackColor: Color = SwitchTokens.SelectedTrackColor.value,\n        checkedBorderColor: Color = Color.Transparent,\n        checkedIconColor: Color = SwitchTokens.SelectedIconColor.value,\n        uncheckedThumbColor: Color = SwitchTokens.UnselectedHandleColor.value,\n        uncheckedTrackColor: Color = SwitchTokens.UnselectedTrackColor.value,\n        uncheckedBorderColor: Color = SwitchTokens.UnselectedFocusTrackOutlineColor.value,\n        uncheckedIconColor: Color = SwitchTokens.UnselectedIconColor.value,\n        disabledCheckedThumbColor: Color =\n            SwitchTokens.DisabledSelectedHandleColor.value\n                .copy(alpha = SwitchTokens.DisabledSelectedHandleOpacity)\n                .compositeOver(MaterialTheme.colorScheme.surface),\n        disabledCheckedTrackColor: Color =\n            SwitchTokens.DisabledSelectedTrackColor.value\n                .copy(alpha = SwitchTokens.DisabledTrackOpacity)\n                .compositeOver(MaterialTheme.colorScheme.surface),\n        disabledCheckedBorderColor: Color = Color.Transparent,\n        disabledCheckedIconColor: Color =\n            SwitchTokens.DisabledSelectedIconColor.value\n                .copy(alpha = SwitchTokens.DisabledSelectedIconOpacity)\n                .compositeOver(MaterialTheme.colorScheme.surface),\n        disabledUncheckedThumbColor: Color =\n            SwitchTokens.DisabledUnselectedHandleColor.value\n                .copy(alpha = SwitchTokens.DisabledUnselectedHandleOpacity)\n                .compositeOver(MaterialTheme.colorScheme.surface),\n        disabledUncheckedTrackColor: Color =\n            SwitchTokens.DisabledUnselectedTrackColor.value\n                .copy(alpha = SwitchTokens.DisabledTrackOpacity)\n                .compositeOver(MaterialTheme.colorScheme.surface),\n        disabledUncheckedBorderColor: Color =\n            SwitchTokens.DisabledUnselectedTrackOutlineColor.value\n                .copy(alpha = SwitchTokens.DisabledTrackOpacity)\n                .compositeOver(MaterialTheme.colorScheme.surface),\n        disabledUncheckedIconColor: Color =\n            SwitchTokens.DisabledUnselectedIconColor.value\n                .copy(alpha = SwitchTokens.DisabledUnselectedIconOpacity)\n                .compositeOver(MaterialTheme.colorScheme.surface),\n    ): SwitchColors =\n        SwitchColors(\n            checkedThumbColor = checkedThumbColor,\n            checkedTrackColor = checkedTrackColor,\n            checkedBorderColor = checkedBorderColor,\n            checkedIconColor = checkedIconColor,\n            uncheckedThumbColor = uncheckedThumbColor,\n            uncheckedTrackColor = uncheckedTrackColor,\n            uncheckedBorderColor = uncheckedBorderColor,\n            uncheckedIconColor = uncheckedIconColor,\n            disabledCheckedThumbColor = disabledCheckedThumbColor,\n            disabledCheckedTrackColor = disabledCheckedTrackColor,\n            disabledCheckedBorderColor = disabledCheckedBorderColor,\n            disabledCheckedIconColor = disabledCheckedIconColor,\n            disabledUncheckedThumbColor = disabledUncheckedThumbColor,\n            disabledUncheckedTrackColor = disabledUncheckedTrackColor,\n            disabledUncheckedBorderColor = disabledUncheckedBorderColor,\n            disabledUncheckedIconColor = disabledUncheckedIconColor,\n        )\n\n    internal val ColorScheme.defaultSwitchColors: SwitchColors\n        get() {\n            return defaultSwitchColorsCached\n                ?: SwitchColors(\n                        checkedThumbColor = fromToken(SwitchTokens.SelectedHandleColor),\n                        checkedTrackColor = fromToken(SwitchTokens.SelectedTrackColor),\n                        checkedBorderColor = Color.Transparent,\n                        checkedIconColor = fromToken(SwitchTokens.SelectedIconColor),\n                        uncheckedThumbColor = fromToken(SwitchTokens.UnselectedHandleColor),\n                        uncheckedTrackColor = fromToken(SwitchTokens.UnselectedTrackColor),\n                        uncheckedBorderColor =\n                            fromToken(SwitchTokens.UnselectedFocusTrackOutlineColor),\n                        uncheckedIconColor = fromToken(SwitchTokens.UnselectedIconColor),\n                        disabledCheckedThumbColor =\n                            fromToken(SwitchTokens.DisabledSelectedHandleColor)\n                                .copy(alpha = SwitchTokens.DisabledSelectedHandleOpacity)\n                                .compositeOver(surface),\n                        disabledCheckedTrackColor =\n                            fromToken(SwitchTokens.DisabledSelectedTrackColor)\n                                .copy(alpha = SwitchTokens.DisabledTrackOpacity)\n                                .compositeOver(surface),\n                        disabledCheckedBorderColor = Color.Transparent,\n                        disabledCheckedIconColor =\n                            fromToken(SwitchTokens.DisabledSelectedIconColor)\n                                .copy(alpha = SwitchTokens.DisabledSelectedIconOpacity)\n                                .compositeOver(surface),\n                        disabledUncheckedThumbColor =\n                            fromToken(SwitchTokens.DisabledUnselectedHandleColor)\n                                .copy(alpha = SwitchTokens.DisabledUnselectedHandleOpacity)\n                                .compositeOver(surface),\n                        disabledUncheckedTrackColor =\n                            fromToken(SwitchTokens.DisabledUnselectedTrackColor)\n                                .copy(alpha = SwitchTokens.DisabledTrackOpacity)\n                                .compositeOver(surface),\n                        disabledUncheckedBorderColor =\n                            fromToken(SwitchTokens.DisabledUnselectedTrackOutlineColor)\n                                .copy(alpha = SwitchTokens.DisabledTrackOpacity)\n                                .compositeOver(surface),\n                        disabledUncheckedIconColor =\n                            fromToken(SwitchTokens.DisabledUnselectedIconColor)\n                                .copy(alpha = SwitchTokens.DisabledUnselectedIconOpacity)\n                                .compositeOver(surface),\n                    )\n                    .also { defaultSwitchColorsCached = it }\n        }\n\n    /** Icon size to use for `thumbContent` */\n    val IconSize = 16.dp\n}\n\n/**\n * Represents the colors used by a [Switch] in different states\n *\n * @param checkedThumbColor the color used for the thumb when enabled and checked\n * @param checkedTrackColor the color used for the track when enabled and checked\n * @param checkedBorderColor the color used for the border when enabled and checked\n * @param checkedIconColor the color used for the icon when enabled and checked\n * @param uncheckedThumbColor the color used for the thumb when enabled and unchecked\n * @param uncheckedTrackColor the color used for the track when enabled and unchecked\n * @param uncheckedBorderColor the color used for the border when enabled and unchecked\n * @param uncheckedIconColor the color used for the icon when enabled and unchecked\n * @param disabledCheckedThumbColor the color used for the thumb when disabled and checked\n * @param disabledCheckedTrackColor the color used for the track when disabled and checked\n * @param disabledCheckedBorderColor the color used for the border when disabled and checked\n * @param disabledCheckedIconColor the color used for the icon when disabled and checked\n * @param disabledUncheckedThumbColor the color used for the thumb when disabled and unchecked\n * @param disabledUncheckedTrackColor the color used for the track when disabled and unchecked\n * @param disabledUncheckedBorderColor the color used for the border when disabled and unchecked\n * @param disabledUncheckedIconColor the color used for the icon when disabled and unchecked\n * @constructor create an instance with arbitrary colors. See [SwitchDefaults.colors] for the\n *   default implementation that follows Material specifications.\n */\n@Immutable\nclass SwitchColors\nconstructor(\n    val checkedThumbColor: Color,\n    val checkedTrackColor: Color,\n    val checkedBorderColor: Color,\n    val checkedIconColor: Color,\n    val uncheckedThumbColor: Color,\n    val uncheckedTrackColor: Color,\n    val uncheckedBorderColor: Color,\n    val uncheckedIconColor: Color,\n    val disabledCheckedThumbColor: Color,\n    val disabledCheckedTrackColor: Color,\n    val disabledCheckedBorderColor: Color,\n    val disabledCheckedIconColor: Color,\n    val disabledUncheckedThumbColor: Color,\n    val disabledUncheckedTrackColor: Color,\n    val disabledUncheckedBorderColor: Color,\n    val disabledUncheckedIconColor: Color,\n) {\n    /**\n     * Returns a copy of this SwitchColors, optionally overriding some of the values. This uses the\n     * Color.Unspecified to mean “use the value from the source”\n     */\n    fun copy(\n        checkedThumbColor: Color = this.checkedThumbColor,\n        checkedTrackColor: Color = this.checkedTrackColor,\n        checkedBorderColor: Color = this.checkedBorderColor,\n        checkedIconColor: Color = this.checkedIconColor,\n        uncheckedThumbColor: Color = this.uncheckedThumbColor,\n        uncheckedTrackColor: Color = this.uncheckedTrackColor,\n        uncheckedBorderColor: Color = this.uncheckedBorderColor,\n        uncheckedIconColor: Color = this.uncheckedIconColor,\n        disabledCheckedThumbColor: Color = this.disabledCheckedThumbColor,\n        disabledCheckedTrackColor: Color = this.disabledCheckedTrackColor,\n        disabledCheckedBorderColor: Color = this.disabledCheckedBorderColor,\n        disabledCheckedIconColor: Color = this.disabledCheckedIconColor,\n        disabledUncheckedThumbColor: Color = this.disabledUncheckedThumbColor,\n        disabledUncheckedTrackColor: Color = this.disabledUncheckedTrackColor,\n        disabledUncheckedBorderColor: Color = this.disabledUncheckedBorderColor,\n        disabledUncheckedIconColor: Color = this.disabledUncheckedIconColor,\n    ) =\n        SwitchColors(\n            checkedThumbColor.takeOrElse { this.checkedThumbColor },\n            checkedTrackColor.takeOrElse { this.checkedTrackColor },\n            checkedBorderColor.takeOrElse { this.checkedBorderColor },\n            checkedIconColor.takeOrElse { this.checkedIconColor },\n            uncheckedThumbColor.takeOrElse { this.uncheckedThumbColor },\n            uncheckedTrackColor.takeOrElse { this.uncheckedTrackColor },\n            uncheckedBorderColor.takeOrElse { this.uncheckedBorderColor },\n            uncheckedIconColor.takeOrElse { this.uncheckedIconColor },\n            disabledCheckedThumbColor.takeOrElse { this.disabledCheckedThumbColor },\n            disabledCheckedTrackColor.takeOrElse { this.disabledCheckedTrackColor },\n            disabledCheckedBorderColor.takeOrElse { this.disabledCheckedBorderColor },\n            disabledCheckedIconColor.takeOrElse { this.disabledCheckedIconColor },\n            disabledUncheckedThumbColor.takeOrElse { this.disabledUncheckedThumbColor },\n            disabledUncheckedTrackColor.takeOrElse { this.disabledUncheckedTrackColor },\n            disabledUncheckedBorderColor.takeOrElse { this.disabledUncheckedBorderColor },\n            disabledUncheckedIconColor.takeOrElse { this.disabledUncheckedIconColor },\n        )\n\n    /**\n     * Represents the color used for the switch's thumb, depending on [enabled] and [checked].\n     *\n     * @param enabled whether the [Switch] is enabled or not\n     * @param checked whether the [Switch] is checked or not\n     */\n    @Stable\n    internal fun thumbColor(enabled: Boolean, checked: Boolean): Color =\n        if (enabled) {\n            if (checked) checkedThumbColor else uncheckedThumbColor\n        } else {\n            if (checked) disabledCheckedThumbColor else disabledUncheckedThumbColor\n        }\n\n    /**\n     * Represents the color used for the switch's track, depending on [enabled] and [checked].\n     *\n     * @param enabled whether the [Switch] is enabled or not\n     * @param checked whether the [Switch] is checked or not\n     */\n    @Stable\n    internal fun trackColor(enabled: Boolean, checked: Boolean): Color =\n        if (enabled) {\n            if (checked) checkedTrackColor else uncheckedTrackColor\n        } else {\n            if (checked) disabledCheckedTrackColor else disabledUncheckedTrackColor\n        }\n\n    /**\n     * Represents the color used for the switch's border, depending on [enabled] and [checked].\n     *\n     * @param enabled whether the [Switch] is enabled or not\n     * @param checked whether the [Switch] is checked or not\n     */\n    @Stable\n    internal fun borderColor(enabled: Boolean, checked: Boolean): Color =\n        if (enabled) {\n            if (checked) checkedBorderColor else uncheckedBorderColor\n        } else {\n            if (checked) disabledCheckedBorderColor else disabledUncheckedBorderColor\n        }\n\n    /**\n     * Represents the content color passed to the icon if used\n     *\n     * @param enabled whether the [Switch] is enabled or not\n     * @param checked whether the [Switch] is checked or not\n     */\n    @Stable\n    internal fun iconColor(enabled: Boolean, checked: Boolean): Color =\n        if (enabled) {\n            if (checked) checkedIconColor else uncheckedIconColor\n        } else {\n            if (checked) disabledCheckedIconColor else disabledUncheckedIconColor\n        }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other == null || other !is SwitchColors) return false\n\n        if (checkedThumbColor != other.checkedThumbColor) return false\n        if (checkedTrackColor != other.checkedTrackColor) return false\n        if (checkedBorderColor != other.checkedBorderColor) return false\n        if (checkedIconColor != other.checkedIconColor) return false\n        if (uncheckedThumbColor != other.uncheckedThumbColor) return false\n        if (uncheckedTrackColor != other.uncheckedTrackColor) return false\n        if (uncheckedBorderColor != other.uncheckedBorderColor) return false\n        if (uncheckedIconColor != other.uncheckedIconColor) return false\n        if (disabledCheckedThumbColor != other.disabledCheckedThumbColor) return false\n        if (disabledCheckedTrackColor != other.disabledCheckedTrackColor) return false\n        if (disabledCheckedBorderColor != other.disabledCheckedBorderColor) return false\n        if (disabledCheckedIconColor != other.disabledCheckedIconColor) return false\n        if (disabledUncheckedThumbColor != other.disabledUncheckedThumbColor) return false\n        if (disabledUncheckedTrackColor != other.disabledUncheckedTrackColor) return false\n        if (disabledUncheckedBorderColor != other.disabledUncheckedBorderColor) return false\n        if (disabledUncheckedIconColor != other.disabledUncheckedIconColor) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = checkedThumbColor.hashCode()\n        result = 31 * result + checkedTrackColor.hashCode()\n        result = 31 * result + checkedBorderColor.hashCode()\n        result = 31 * result + checkedIconColor.hashCode()\n        result = 31 * result + uncheckedThumbColor.hashCode()\n        result = 31 * result + uncheckedTrackColor.hashCode()\n        result = 31 * result + uncheckedBorderColor.hashCode()\n        result = 31 * result + uncheckedIconColor.hashCode()\n        result = 31 * result + disabledCheckedThumbColor.hashCode()\n        result = 31 * result + disabledCheckedTrackColor.hashCode()\n        result = 31 * result + disabledCheckedBorderColor.hashCode()\n        result = 31 * result + disabledCheckedIconColor.hashCode()\n        result = 31 * result + disabledUncheckedThumbColor.hashCode()\n        result = 31 * result + disabledUncheckedTrackColor.hashCode()\n        result = 31 * result + disabledUncheckedBorderColor.hashCode()\n        result = 31 * result + disabledUncheckedIconColor.hashCode()\n        return result\n    }\n}\n\n/* @VisibleForTesting */\ninternal val ThumbDiameter = SwitchTokens.SelectedHandleWidth\ninternal val UncheckedThumbDiameter = SwitchTokens.UnselectedHandleWidth\n\nprivate val SwitchWidth = SwitchTokens.TrackWidth\nprivate val SwitchHeight = SwitchTokens.TrackHeight\nprivate val ThumbPadding = (SwitchHeight - ThumbDiameter) / 2\nprivate val SnapSpec = SnapSpec<Float>()\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/Tab.kt\n```kotlin\n/*\n * Copyright 2022 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.compose.animation.animateColor\nimport androidx.compose.animation.core.updateTransition\nimport androidx.compose.foundation.interaction.Interaction\nimport androidx.compose.foundation.interaction.MutableInteractionSource\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.ColumnScope\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.requiredWidth\nimport androidx.compose.foundation.selection.selectable\nimport androidx.compose.material3.tokens.MotionSchemeKeyTokens\nimport androidx.compose.material3.tokens.PrimaryNavigationTabTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.getValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.layout.FirstBaseline\nimport androidx.compose.ui.layout.LastBaseline\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.layout.layoutId\nimport androidx.compose.ui.semantics.Role\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport androidx.compose.ui.util.fastFirst\nimport kotlin.math.max\n\n/**\n * [Material Design tab](https://m3.material.io/components/tabs/overview)\n *\n * A default Tab, also known as a Primary Navigation Tab. Tabs organize content across different\n * screens, data sets, and other interactions.\n *\n * ![Tabs\n * image](https://developer.android.com/images/reference/androidx/compose/material3/secondary-tabs.png)\n *\n * A Tab represents a single page of content using a text label and/or icon. It represents its\n * selected state by tinting the text label and/or image with [selectedContentColor].\n *\n * This should typically be used inside of a [TabRow], see the corresponding documentation for\n * example usage.\n *\n * This Tab has slots for [text] and/or [icon] - see the other Tab overload for a generic Tab that\n * is not opinionated about its content.\n *\n * @param selected whether this tab is selected or not\n * @param onClick called when this tab is clicked\n * @param modifier the [Modifier] to be applied to this tab\n * @param enabled controls the enabled state of this tab. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param text the text label displayed in this tab\n * @param icon the icon displayed in this tab\n * @param selectedContentColor the color for the content of this tab when selected, and the color of\n *   the ripple.\n * @param unselectedContentColor the color for the content of this tab when not selected\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this tab. You can use this to change the tab's appearance or\n *   preview the tab in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @see LeadingIconTab\n */\n@Composable\nfun Tab(\n    selected: Boolean,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    text: @Composable (() -> Unit)? = null,\n    icon: @Composable (() -> Unit)? = null,\n    selectedContentColor: Color = LocalContentColor.current,\n    unselectedContentColor: Color = selectedContentColor,\n    interactionSource: MutableInteractionSource? = null,\n) {\n    val styledText: @Composable (() -> Unit)? =\n        text?.let {\n            @Composable {\n                val style =\n                    PrimaryNavigationTabTokens.LabelTextFont.value.copy(\n                        textAlign = TextAlign.Center\n                    )\n                ProvideTextStyle(style, content = text)\n            }\n        }\n    Tab(\n        modifier = modifier.badgeBounds(),\n        selected = selected,\n        onClick = onClick,\n        enabled = enabled,\n        selectedContentColor = selectedContentColor,\n        unselectedContentColor = unselectedContentColor,\n        interactionSource = interactionSource,\n    ) {\n        TabBaselineLayout(icon = icon, text = styledText)\n    }\n}\n\n/**\n * [Material Design tab](https://m3.material.io/components/tabs/overview)\n *\n * Tabs organize content across different screens, data sets, and other interactions.\n *\n * A LeadingIconTab represents a single page of content using a text label and an icon in front of\n * the label. It represents its selected state by tinting the text label and icon with\n * [selectedContentColor].\n *\n * This should typically be used inside of a [TabRow], see the corresponding documentation for\n * example usage.\n *\n * @param selected whether this tab is selected or not\n * @param onClick called when this tab is clicked\n * @param text the text label displayed in this tab\n * @param icon the icon displayed in this tab. Should be 24.dp.\n * @param modifier the [Modifier] to be applied to this tab\n * @param enabled controls the enabled state of this tab. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param selectedContentColor the color for the content of this tab when selected, and the color of\n *   the ripple.\n * @param unselectedContentColor the color for the content of this tab when not selected\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this tab. You can use this to change the tab's appearance or\n *   preview the tab in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @see Tab\n */\n@Composable\nfun LeadingIconTab(\n    selected: Boolean,\n    onClick: () -> Unit,\n    text: @Composable () -> Unit,\n    icon: @Composable () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    selectedContentColor: Color = LocalContentColor.current,\n    unselectedContentColor: Color = selectedContentColor,\n    interactionSource: MutableInteractionSource? = null,\n) {\n    // The color of the Ripple should always the be selected color, as we want to show the color\n    // before the item is considered selected, and hence before the new contentColor is\n    // provided by TabTransition.\n    val ripple = ripple(bounded = true, color = selectedContentColor)\n\n    TabTransition(selectedContentColor, unselectedContentColor, selected) {\n        Row(\n            modifier =\n                modifier\n                    .height(SmallTabHeight)\n                    .selectable(\n                        selected = selected,\n                        onClick = onClick,\n                        enabled = enabled,\n                        role = Role.Tab,\n                        interactionSource = interactionSource,\n                        indication = ripple,\n                    )\n                    .padding(horizontal = HorizontalTextPadding)\n                    .fillMaxWidth(),\n            horizontalArrangement = Arrangement.Center,\n            verticalAlignment = Alignment.CenterVertically,\n        ) {\n            icon()\n            Spacer(Modifier.requiredWidth(TextDistanceFromLeadingIcon))\n            val style =\n                PrimaryNavigationTabTokens.LabelTextFont.value.copy(textAlign = TextAlign.Center)\n            ProvideTextStyle(style, content = text)\n        }\n    }\n}\n\n/**\n * [Material Design tab](https://m3.material.io/components/tabs/overview)\n *\n * Tabs organize content across different screens, data sets, and other interactions.\n *\n * ![Tabs\n * image](https://developer.android.com/images/reference/androidx/compose/material3/secondary-tabs.png)\n *\n * Generic [Tab] overload that is not opinionated about content / color. See the other overload for\n * a Tab that has specific slots for text and / or an icon, as well as providing the correct colors\n * for selected / unselected states.\n *\n * A custom tab using this API may look like:\n *\n * @sample androidx.compose.material3.samples.FancyTab\n * @param selected whether this tab is selected or not\n * @param onClick called when this tab is clicked\n * @param modifier the [Modifier] to be applied to this tab\n * @param enabled controls the enabled state of this tab. When `false`, this component will not\n *   respond to user input, and it will appear visually disabled and disabled to accessibility\n *   services.\n * @param selectedContentColor the color for the content of this tab when selected, and the color of\n *   the ripple.\n * @param unselectedContentColor the color for the content of this tab when not selected\n * @param interactionSource an optional hoisted [MutableInteractionSource] for observing and\n *   emitting [Interaction]s for this tab. You can use this to change the tab's appearance or\n *   preview the tab in different states. Note that if `null` is provided, interactions will still\n *   happen internally.\n * @param content the content of this tab\n */\n@Composable\nfun Tab(\n    selected: Boolean,\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    selectedContentColor: Color = LocalContentColor.current,\n    unselectedContentColor: Color = selectedContentColor,\n    interactionSource: MutableInteractionSource? = null,\n    content: @Composable ColumnScope.() -> Unit,\n) {\n    // The color of the Ripple should always the selected color, as we want to show the color\n    // before the item is considered selected, and hence before the new contentColor is\n    // provided by TabTransition.\n    val ripple = ripple(bounded = true, color = selectedContentColor)\n\n    TabTransition(selectedContentColor, unselectedContentColor, selected) {\n        Column(\n            modifier =\n                modifier\n                    .selectable(\n                        selected = selected,\n                        onClick = onClick,\n                        enabled = enabled,\n                        role = Role.Tab,\n                        interactionSource = interactionSource,\n                        indication = ripple,\n                    )\n                    .fillMaxWidth(),\n            horizontalAlignment = Alignment.CenterHorizontally,\n            verticalArrangement = Arrangement.Center,\n            content = content,\n        )\n    }\n}\n\n/**\n * Transition defining how the tint color for a tab animates, when a new tab is selected. This\n * component uses [LocalContentColor] to provide an interpolated value between [activeColor] and\n * [inactiveColor] depending on the animation status.\n */\n@Composable\nprivate fun TabTransition(\n    activeColor: Color,\n    inactiveColor: Color,\n    selected: Boolean,\n    content: @Composable () -> Unit,\n) {\n    val transition = updateTransition(selected)\n    // TODO Load the motionScheme tokens from the component tokens file\n    val color by\n        transition.animateColor(\n            transitionSpec = {\n                if (false isTransitioningTo true) {\n                    // Fade-in\n                    MotionSchemeKeyTokens.DefaultEffects.value()\n                } else {\n                    // Fade-out\n                    MotionSchemeKeyTokens.FastEffects.value()\n                }\n            }\n        ) {\n            if (it) activeColor else inactiveColor\n        }\n    CompositionLocalProvider(LocalContentColor provides color, content = content)\n}\n\n/**\n * A [Layout] that positions [text] and an optional [icon] with the correct baseline distances. This\n * Layout will either be [SmallTabHeight] or [LargeTabHeight] depending on its content, and then\n * place the text and/or icon inside with the correct baseline alignment.\n */\n@Composable\nprivate fun TabBaselineLayout(text: @Composable (() -> Unit)?, icon: @Composable (() -> Unit)?) {\n    Layout({\n        if (text != null) {\n            Box(Modifier.layoutId(\"text\").padding(horizontal = HorizontalTextPadding)) { text() }\n        }\n        if (icon != null) {\n            Box(Modifier.layoutId(\"icon\")) { icon() }\n        }\n    }) { measurables, constraints ->\n        val textPlaceable =\n            text?.let {\n                measurables\n                    .fastFirst { it.layoutId == \"text\" }\n                    .measure(\n                        // Measure with loose constraints for height as we don't want the text to\n                        // take up more\n                        // space than it needs\n                        constraints.copy(minHeight = 0)\n                    )\n            }\n\n        val iconPlaceable =\n            icon?.let { measurables.fastFirst { it.layoutId == \"icon\" }.measure(constraints) }\n\n        val tabWidth = max(textPlaceable?.width ?: 0, iconPlaceable?.width ?: 0)\n\n        val specHeight =\n            if (textPlaceable != null && iconPlaceable != null) {\n                    LargeTabHeight\n                } else {\n                    SmallTabHeight\n                }\n                .roundToPx()\n\n        val tabHeight =\n            max(\n                specHeight,\n                (iconPlaceable?.height ?: 0) +\n                    (textPlaceable?.height ?: 0) +\n                    IconDistanceFromBaseline.roundToPx(),\n            )\n\n        val firstBaseline = textPlaceable?.get(FirstBaseline)\n        val lastBaseline = textPlaceable?.get(LastBaseline)\n\n        layout(tabWidth, tabHeight) {\n            when {\n                textPlaceable != null && iconPlaceable != null ->\n                    placeTextAndIcon(\n                        density = this@Layout,\n                        textPlaceable = textPlaceable,\n                        iconPlaceable = iconPlaceable,\n                        tabWidth = tabWidth,\n                        tabHeight = tabHeight,\n                        firstBaseline = firstBaseline!!,\n                        lastBaseline = lastBaseline!!,\n                    )\n                textPlaceable != null -> placeTextOrIcon(textPlaceable, tabHeight)\n                iconPlaceable != null -> placeTextOrIcon(iconPlaceable, tabHeight)\n                else -> {}\n            }\n        }\n    }\n}\n\n/** Places the provided [textOrIconPlaceable] in the vertical center of the provided [tabHeight]. */\nprivate fun Placeable.PlacementScope.placeTextOrIcon(\n    textOrIconPlaceable: Placeable,\n    tabHeight: Int,\n) {\n    val contentY = (tabHeight - textOrIconPlaceable.height) / 2\n    textOrIconPlaceable.placeRelative(0, contentY)\n}\n\n/**\n * Places the provided [textPlaceable] offset from the bottom of the tab using the correct baseline\n * offset, with the provided [iconPlaceable] placed above the text using the correct baseline\n * offset.\n */\nprivate fun Placeable.PlacementScope.placeTextAndIcon(\n    density: Density,\n    textPlaceable: Placeable,\n    iconPlaceable: Placeable,\n    tabWidth: Int,\n    tabHeight: Int,\n    firstBaseline: Int,\n    lastBaseline: Int,\n) {\n    val baselineOffset =\n        if (firstBaseline == lastBaseline) {\n            SingleLineTextBaselineWithIcon\n        } else {\n            DoubleLineTextBaselineWithIcon\n        }\n\n    // Total offset between the last text baseline and the bottom of the Tab layout\n    val textOffset =\n        with(density) {\n            baselineOffset.roundToPx() +\n                PrimaryNavigationTabTokens.ActiveIndicatorHeight.roundToPx()\n        }\n\n    // How much space there is between the top of the icon (essentially the top of this layout)\n    // and the top of the text layout's bounding box (not baseline)\n    val iconOffset =\n        with(density) {\n            iconPlaceable.height + IconDistanceFromBaseline.roundToPx() - firstBaseline\n        }\n\n    val textPlaceableX = (tabWidth - textPlaceable.width) / 2\n    val textPlaceableY = tabHeight - lastBaseline - textOffset\n    textPlaceable.placeRelative(textPlaceableX, textPlaceableY)\n\n    val iconPlaceableX = (tabWidth - iconPlaceable.width) / 2\n    val iconPlaceableY = textPlaceableY - iconOffset\n    iconPlaceable.placeRelative(iconPlaceableX, iconPlaceableY)\n}\n\n// Tab specifications\nprivate val SmallTabHeight = PrimaryNavigationTabTokens.ContainerHeight\nprivate val LargeTabHeight = 72.dp\n\n// The horizontal padding on the left and right of text\ninternal val HorizontalTextPadding = 16.dp\n\n// Distance from the top of the indicator to the text baseline when there is one line of text and an\n// icon\nprivate val SingleLineTextBaselineWithIcon = 14.dp\n\n// Distance from the top of the indicator to the last text baseline when there are two lines of text\n// and an icon\nprivate val DoubleLineTextBaselineWithIcon = 6.dp\n\n// Distance from the first text baseline to the bottom of the icon in a combined tab\nprivate val IconDistanceFromBaseline = 20.sp\n\n// Distance from the end of the leading icon to the start of the text\nprivate val TextDistanceFromLeadingIcon = 8.dp\n```\n\n## File: compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TabRow.kt\n```kotlin\n/*\n * Copyright 2022 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.material3\n\nimport androidx.collection.mutableIntListOf\nimport androidx.compose.animation.core.Animatable\nimport androidx.compose.animation.core.AnimationVector1D\nimport androidx.compose.animation.core.FiniteAnimationSpec\nimport androidx.compose.animation.core.VectorConverter\nimport androidx.compose.animation.core.animateDpAsState\nimport androidx.compose.foundation.ScrollState\nimport androidx.compose.foundation.background\nimport androidx.compose.foundation.horizontalScroll\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.offset\nimport androidx.compose.foundation.layout.requiredHeight\nimport androidx.compose.foundation.layout.requiredWidth\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.wrapContentSize\nimport androidx.compose.foundation.rememberScrollState\nimport androidx.compose.foundation.selection.selectableGroup\nimport androidx.compose.material3.TabRowDefaults.tabIndicatorOffset\nimport androidx.compose.material3.tokens.MotionSchemeKeyTokens\nimport androidx.compose.material3.tokens.PrimaryNavigationTabTokens\nimport androidx.compose.material3.tokens.SecondaryNavigationTabTokens\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.composed\nimport androidx.compose.ui.draw.clipToBounds\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.layout.Measurable\nimport androidx.compose.ui.layout.MeasureResult\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.layout.SubcomposeLayout\nimport androidx.compose.ui.layout.layout\nimport androidx.compose.ui.node.LayoutModifierNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.platform.debugInspectorInfo\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.util.fastFold\nimport androidx.compose.ui.util.fastForEach\nimport androidx.compose.ui.util.fastForEachIndexed\nimport androidx.compose.ui.util.fastMap\nimport kotlin.math.max\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.launch\n\n/**\n * [Material Design fixed primary tabs](https://m3.material.io/components/tabs/overview)\n *\n * Primary tabs are placed at the top of the content pane under a top app bar. They display the main\n * content destinations. Fixed tabs display all tabs in a set simultaneously. They are best for\n * switching between related content quickly, such as between transportation methods in a map. To\n * navigate between fixed tabs, tap an individual tab, or swipe left or right in the content area.\n *\n * A TabRow contains a row of [Tab]s, and displays an indicator underneath the currently selected\n * tab. A TabRow places its tabs evenly spaced along the entire row, with each tab taking up an\n * equal amount of space. See [PrimaryScrollableTabRow] for a tab row that does not enforce equal\n * size, and allows scrolling to tabs that do not fit on screen.\n *\n * A simple example with text tabs looks like:\n *\n * @sample androidx.compose.material3.samples.PrimaryTextTabs\n *\n * You can also provide your own custom tab, such as:\n *\n * @sample androidx.compose.material3.samples.FancyTabs\n *\n * Where the custom tab itself could look like:\n *\n * @sample androidx.compose.material3.samples.FancyTab\n *\n * As well as customizing the tab, you can also provide a custom [indicator], to customize the\n * indicator displayed for a tab. [indicator] will be placed to fill the entire TabRow, so it should\n * internally take care of sizing and positioning the indicator to match changes to\n * [selectedTabIndex].\n *\n * For example, given an indicator that draws a rounded rectangle near the edges of the [Tab]:\n *\n * @sample androidx.compose.material3.samples.FancyIndicator\n *\n * We can reuse [TabRowDefaults.tabIndicatorOffset] and just provide this indicator, as we aren't\n * changing how the size and position of the indicator changes between tabs:\n *\n * @sample androidx.compose.material3.samples.FancyIndicatorTabs\n *\n * You may also want to use a custom transition, to allow you to dynamically change the appearance\n * of the indicator as it animates between tabs, such as changing its color or size. [indicator] is\n * stacked on top of the entire TabRow, so you just need to provide a custom transition that\n * animates the offset of the indicator from the start of the TabRow. For example, take the\n * following example that uses a transition to animate the offset, width, and color of the same\n * FancyIndicator from before, also adding a physics based 'spring' effect to the indicator in the\n * direction of motion:\n *\n * @sample androidx.compose.material3.samples.FancyAnimatedIndicatorWithModifier\n *\n * We can now just pass this indicator directly to TabRow:\n *\n * @sample androidx.compose.material3.samples.FancyIndicatorContainerTabs\n * @param selectedTabIndex the index of the currently selected tab\n * @param modifier the [Modifier] to be applied to this tab row\n * @param containerColor the color used for the background of this tab row. Use [Color.Transparent]\n *   to have no color.\n * @param contentColor the preferred color for content inside this tab row. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param indicator the indicator that represents which tab is currently selected. By default this\n *   will be a [TabRowDefaults.PrimaryIndicator], using a [TabRowDefaults.tabIndicatorOffset]\n *   modifier to animate its position.\n * @param divider the divider displayed at the bottom of the tab row. This provides a layer of\n *   separation between the tab row and the content displayed underneath.\n * @param tabs the tabs inside this tab row. Typically this will be multiple [Tab]s. Each element\n *   inside this lambda will be measured and placed evenly across the row, each taking up equal\n *   space.\n */\n@Composable\nfun PrimaryTabRow(\n    selectedTabIndex: Int,\n    modifier: Modifier = Modifier,\n    containerColor: Color = TabRowDefaults.primaryContainerColor,\n    contentColor: Color = TabRowDefaults.primaryContentColor,\n    indicator: @Composable TabIndicatorScope.() -> Unit = {\n        TabRowDefaults.PrimaryIndicator(\n            modifier = Modifier.tabIndicatorOffset(selectedTabIndex, matchContentSize = true),\n            width = Dp.Unspecified,\n        )\n    },\n    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },\n    tabs: @Composable () -> Unit,\n) {\n    TabRowImpl(modifier, containerColor, contentColor, indicator, divider, tabs)\n}\n\n/**\n * [Material Design fixed secondary tabs](https://m3.material.io/components/tabs/overview)\n *\n * Secondary tabs are used within a content area to further separate related content and establish\n * hierarchy. Fixed tabs display all tabs in a set simultaneously. To navigate between fixed tabs,\n * tap an individual tab, or swipe left or right in the content area.\n *\n * A TabRow contains a row of [Tab]s, and displays an indicator underneath the currently selected\n * tab. A Fixed TabRow places its tabs evenly spaced along the entire row, with each tab taking up\n * an equal amount of space. See [SecondaryScrollableTabRow] for a tab row that does not enforce\n * equal size, and allows scrolling to tabs that do not fit on screen.\n *\n * A simple example with text tabs looks like:\n *\n * @sample androidx.compose.material3.samples.SecondaryTextTabs\n * @param selectedTabIndex the index of the currently selected tab\n * @param modifier the [Modifier] to be applied to this tab row\n * @param containerColor the color used for the background of this tab row. Use [Color.Transparent]\n *   to have no color.\n * @param contentColor the preferred color for content inside this tab row. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param indicator the indicator that represents which tab is currently selected. By default this\n *   will be a [TabRowDefaults.SecondaryIndicator], using a [TabRowDefaults.tabIndicatorOffset]\n *   modifier to animate its position. Note that this indicator will be forced to fill up the entire\n *   tab row, so you should use [TabRowDefaults.tabIndicatorOffset] or similar to animate the actual\n *   drawn indicator inside this space, and provide an offset from the start.\n * @param divider the divider displayed at the bottom of the tab row. This provides a layer of\n *   separation between the tab row and the content displayed underneath.\n * @param tabs the tabs inside this tab row. Typically this will be multiple [Tab]s. Each element\n *   inside this lambda will be measured and placed evenly across the row, each taking up equal\n *   space.\n */\n@Composable\nfun SecondaryTabRow(\n    selectedTabIndex: Int,\n    modifier: Modifier = Modifier,\n    containerColor: Color = TabRowDefaults.secondaryContainerColor,\n    contentColor: Color = TabRowDefaults.secondaryContentColor,\n    indicator: @Composable TabIndicatorScope.() -> Unit =\n        @Composable {\n            TabRowDefaults.SecondaryIndicator(\n                Modifier.tabIndicatorOffset(selectedTabIndex, matchContentSize = false)\n            )\n        },\n    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },\n    tabs: @Composable () -> Unit,\n) {\n    TabRowImpl(modifier, containerColor, contentColor, indicator, divider, tabs)\n}\n\n/**\n * [Material Design scrollable primary tabs](https://m3.material.io/components/tabs/overview)\n *\n * Primary tabs are placed at the top of the content pane under a top app bar. They display the main\n * content destinations. When a set of tabs cannot fit on screen, use scrollable tabs. Scrollable\n * tabs can use longer text labels and a larger number of tabs. They are best used for browsing on\n * touch interfaces.\n *\n * A scrollable tab row contains a row of [Tab]s, and displays an indicator underneath the currently\n * selected tab. A scrollable tab row places its tabs offset from the starting edge, and allows\n * scrolling to tabs that are placed off screen. For a fixed tab row that does not allow scrolling,\n * and evenly places its tabs, see [PrimaryTabRow].\n *\n * @param selectedTabIndex the index of the currently selected tab\n * @param modifier the [Modifier] to be applied to this tab row\n * @param scrollState the [ScrollState] of this tab row\n * @param containerColor the color used for the background of this tab row. Use [Color.Transparent]\n *   to have no color.\n * @param contentColor the preferred color for content inside this tab row. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param edgePadding the padding between the starting and ending edge of the scrollable tab row,\n *   and the tabs inside the row. This padding helps inform the user that this tab row can be\n *   scrolled, unlike a [TabRow].\n * @param indicator the indicator that represents which tab is currently selected. By default this\n *   will be a [TabRowDefaults.PrimaryIndicator], using a [TabRowDefaults.tabIndicatorOffset]\n *   modifier to animate its position.\n * @param divider the divider displayed at the bottom of the tab row. This provides a layer of\n *   separation between the tab row and the content displayed underneath.\n * @param minTabWidth the minimum width for a [Tab] in this tab row regardless of content size.\n * @param tabs the tabs inside this tab row. Typically this will be multiple [Tab]s. Each element\n *   inside this lambda will be measured and placed evenly across the row, each taking up equal\n *   space.\n */\n@Composable\nfun PrimaryScrollableTabRow(\n    selectedTabIndex: Int,\n    modifier: Modifier = Modifier,\n    scrollState: ScrollState = rememberScrollState(),\n    containerColor: Color = TabRowDefaults.primaryContainerColor,\n    contentColor: Color = TabRowDefaults.primaryContentColor,\n    edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding,\n    indicator: @Composable TabIndicatorScope.() -> Unit =\n        @Composable {\n            TabRowDefaults.PrimaryIndicator(\n                Modifier.tabIndicatorOffset(selectedTabIndex, matchContentSize = true),\n                width = Dp.Unspecified,\n            )\n        },\n    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },\n    minTabWidth: Dp = TabRowDefaults.ScrollableTabRowMinTabWidth,\n    tabs: @Composable () -> Unit,\n) {\n    ScrollableTabRowImpl(\n        selectedTabIndex = selectedTabIndex,\n        indicator = indicator,\n        modifier = modifier,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        edgePadding = edgePadding,\n        minTabWidth = minTabWidth,\n        divider = divider,\n        tabs = tabs,\n        scrollState = scrollState,\n    )\n}\n\n/**\n * [Material Design scrollable secondary tabs](https://m3.material.io/components/tabs/overview)\n *\n * Material Design scrollable tabs.\n *\n * Secondary tabs are used within a content area to further separate related content and establish\n * hierarchy. When a set of tabs cannot fit on screen, use scrollable tabs. Scrollable tabs can use\n * longer text labels and a larger number of tabs. They are best used for browsing on touch\n * interfaces.\n *\n * A scrollable tab row contains a row of [Tab]s, and displays an indicator underneath the currently\n * selected tab. A scrollable tab row places its tabs offset from the starting edge, and allows\n * scrolling to tabs that are placed off screen. For a fixed tab row that does not allow scrolling,\n * and evenly places its tabs, see [SecondaryTabRow].\n *\n * @param selectedTabIndex the index of the currently selected tab\n * @param modifier the [Modifier] to be applied to this tab row\n * @param scrollState the [ScrollState] of this tab row\n * @param containerColor the color used for the background of this tab row. Use [Color.Transparent]\n *   to have no color.\n * @param contentColor the preferred color for content inside this tab row. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param edgePadding the padding between the starting and ending edge of the scrollable tab row,\n *   and the tabs inside the row. This padding helps inform the user that this tab row can be\n *   scrolled, unlike a [TabRow].\n * @param indicator the indicator that represents which tab is currently selected. By default this\n *   will be a [TabRowDefaults.SecondaryIndicator], using a [TabRowDefaults.tabIndicatorOffset]\n *   modifier to animate its position. Note that this indicator will be forced to fill up the entire\n *   tab row, so you should use [TabRowDefaults.tabIndicatorOffset] or similar to animate the actual\n *   drawn indicator inside this space, and provide an offset from the start.\n * @param divider the divider displayed at the bottom of the tab row. This provides a layer of\n *   separation between the tab row and the content displayed underneath.\n * @param minTabWidth the minimum width for a [Tab] in this tab row regardless of content size.\n * @param tabs the tabs inside this tab row. Typically this will be multiple [Tab]s. Each element\n *   inside this lambda will be measured and placed evenly across the row, each taking up equal\n *   space.\n */\n@Composable\nfun SecondaryScrollableTabRow(\n    selectedTabIndex: Int,\n    modifier: Modifier = Modifier,\n    scrollState: ScrollState = rememberScrollState(),\n    containerColor: Color = TabRowDefaults.secondaryContainerColor,\n    contentColor: Color = TabRowDefaults.secondaryContentColor,\n    edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding,\n    indicator: @Composable TabIndicatorScope.() -> Unit =\n        @Composable {\n            TabRowDefaults.SecondaryIndicator(\n                Modifier.tabIndicatorOffset(selectedTabIndex, matchContentSize = false)\n            )\n        },\n    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },\n    minTabWidth: Dp = TabRowDefaults.ScrollableTabRowMinTabWidth,\n    tabs: @Composable () -> Unit,\n) {\n    ScrollableTabRowImpl(\n        selectedTabIndex = selectedTabIndex,\n        indicator = indicator,\n        modifier = modifier,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        edgePadding = edgePadding,\n        minTabWidth = minTabWidth,\n        divider = divider,\n        tabs = tabs,\n        scrollState = scrollState,\n    )\n}\n\n/**\n * Scope for the composable used to render a Tab indicator, this can be used for more complex\n * indicators requiring layout information about the tabs like [TabRowDefaults.PrimaryIndicator] and\n * [TabRowDefaults.SecondaryIndicator]\n */\ninterface TabIndicatorScope {\n\n    /**\n     * A layout modifier that provides tab positions, this can be used to animate and layout a\n     * TabIndicator depending on size, position, and content size of each Tab.\n     *\n     * @sample androidx.compose.material3.samples.FancyAnimatedIndicatorWithModifier\n     */\n    fun Modifier.tabIndicatorLayout(\n        measure: MeasureScope.(Measurable, Constraints, List<TabPosition>) -> MeasureResult\n    ): Modifier\n\n    /**\n     * A Modifier that follows the default offset and animation\n     *\n     * @param selectedTabIndex the index of the current selected tab\n     * @param matchContentSize this modifier can also animate the width of the indicator to match\n     *   the content size of the tab.\n     */\n    fun Modifier.tabIndicatorOffset(\n        selectedTabIndex: Int,\n        matchContentSize: Boolean = false,\n    ): Modifier\n}\n\ninternal interface TabPositionsHolder {\n\n    fun setTabPositions(positions: List<TabPosition>)\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nprivate fun TabRowImpl(\n    modifier: Modifier,\n    containerColor: Color,\n    contentColor: Color,\n    indicator: @Composable TabIndicatorScope.() -> Unit,\n    divider: @Composable () -> Unit,\n    tabs: @Composable () -> Unit,\n) {\n    Surface(\n        modifier = modifier.selectableGroup(),\n        color = containerColor,\n        contentColor = contentColor,\n    ) {\n        // TODO Load the motionScheme tokens from the component tokens file\n        val tabIndicatorAnimationSpec = MotionSchemeKeyTokens.DefaultSpatial.value<Dp>()\n        val scope = remember {\n            object : TabIndicatorScope, TabPositionsHolder {\n\n                val tabPositions = mutableStateOf<(List<TabPosition>)>(listOf())\n\n                override fun Modifier.tabIndicatorLayout(\n                    measure:\n                        MeasureScope.(Measurable, Constraints, List<TabPosition>) -> MeasureResult\n                ): Modifier =\n                    this.layout { measurable: Measurable, constraints: Constraints ->\n                        measure(measurable, constraints, tabPositions.value)\n                    }\n\n                override fun Modifier.tabIndicatorOffset(\n                    selectedTabIndex: Int,\n                    matchContentSize: Boolean,\n                ): Modifier =\n                    this.then(\n                        TabIndicatorModifier(\n                            tabPositions,\n                            selectedTabIndex,\n                            matchContentSize,\n                            tabIndicatorAnimationSpec,\n                        )\n                    )\n\n                override fun setTabPositions(positions: List<TabPosition>) {\n                    tabPositions.value = positions\n                }\n            }\n        }\n\n        Layout(\n            modifier = Modifier.fillMaxWidth(),\n            contents = listOf(tabs, divider, { scope.indicator() }),\n        ) { (tabMeasurables, dividerMeasurables, indicatorMeasurables), constraints ->\n            val tabRowWidth = constraints.maxWidth\n            val tabCount = tabMeasurables.size\n            var tabWidth = 0\n            if (tabCount > 0) {\n                tabWidth = (tabRowWidth / tabCount)\n            }\n            val tabRowHeight =\n                tabMeasurables.fastFold(initial = 0) { max, curr ->\n                    maxOf(curr.maxIntrinsicHeight(tabWidth), max)\n                }\n\n            scope.setTabPositions(\n                List(tabCount) { index ->\n                    var contentWidth =\n                        minOf(tabMeasurables[index].maxIntrinsicWidth(tabRowHeight), tabWidth)\n                            .toDp()\n                    contentWidth -= HorizontalTextPadding * 2\n                    // Enforce minimum touch target of 24.dp\n                    val indicatorWidth = maxOf(contentWidth, 24.dp)\n\n                    TabPosition(tabWidth.toDp() * index, tabWidth.toDp(), indicatorWidth)\n                }\n            )\n\n            val tabPlaceables =\n                tabMeasurables.fastMap {\n                    it.measure(\n                        constraints.copy(\n                            minWidth = tabWidth,\n                            maxWidth = tabWidth,\n                            minHeight = tabRowHeight,\n                            maxHeight = tabRowHeight,\n                        )\n                    )\n                }\n\n            val dividerPlaceables =\n                dividerMeasurables.fastMap { it.measure(constraints.copy(minHeight = 0)) }\n\n            val indicatorPlaceables =\n                indicatorMeasurables.fastMap {\n                    it.measure(\n                        constraints.copy(\n                            minWidth = tabWidth,\n                            maxWidth = tabWidth,\n                            minHeight = 0,\n                            maxHeight = tabRowHeight,\n                        )\n                    )\n                }\n\n            layout(tabRowWidth, tabRowHeight) {\n                tabPlaceables.fastForEachIndexed { index, placeable ->\n                    placeable.placeRelative(index * tabWidth, 0)\n                }\n\n                dividerPlaceables.fastForEach { placeable ->\n                    placeable.placeRelative(0, tabRowHeight - placeable.height)\n                }\n\n                indicatorPlaceables.fastForEach { it.placeRelative(0, tabRowHeight - it.height) }\n            }\n        }\n    }\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nprivate fun ScrollableTabRowImpl(\n    selectedTabIndex: Int,\n    modifier: Modifier,\n    containerColor: Color,\n    contentColor: Color,\n    edgePadding: Dp,\n    minTabWidth: Dp,\n    scrollState: ScrollState,\n    indicator: @Composable TabIndicatorScope.() -> Unit,\n    divider: @Composable () -> Unit,\n    tabs: @Composable () -> Unit,\n) {\n    Surface(modifier = modifier, color = containerColor, contentColor = contentColor) {\n        val coroutineScope = rememberCoroutineScope()\n        // TODO Load the motionScheme tokens from the component tokens file\n        val scrollAnimationSpec = MotionSchemeKeyTokens.DefaultSpatial.value<Float>()\n        val tabIndicatorAnimationSpec: FiniteAnimationSpec<Dp> =\n            MotionSchemeKeyTokens.DefaultSpatial.value()\n        val scrollableTabData =\n            remember(scrollState, coroutineScope) {\n                ScrollableTabData(\n                    scrollState = scrollState,\n                    coroutineScope = coroutineScope,\n                    animationSpec = scrollAnimationSpec,\n                )\n            }\n\n        val scope = remember {\n            object : TabIndicatorScope, TabPositionsHolder {\n\n                val tabPositions = mutableStateOf<(List<TabPosition>)>(listOf())\n\n                override fun Modifier.tabIndicatorLayout(\n                    measure:\n                        MeasureScope.(Measurable, Constraints, List<TabPosition>) -> MeasureResult\n                ): Modifier =\n                    this.layout { measurable: Measurable, constraints: Constraints ->\n                        measure(measurable, constraints, tabPositions.value)\n                    }\n\n                override fun Modifier.tabIndicatorOffset(\n                    selectedTabIndex: Int,\n                    matchContentSize: Boolean,\n                ): Modifier =\n                    this.then(\n                        TabIndicatorModifier(\n                            tabPositions,\n                            selectedTabIndex,\n                            matchContentSize,\n                            tabIndicatorAnimationSpec,\n                        )\n                    )\n\n                override fun setTabPositions(positions: List<TabPosition>) {\n                    tabPositions.value = positions\n                }\n            }\n        }\n        Box(contentAlignment = Alignment.BottomStart) {\n            divider()\n            Layout(\n                contents = listOf(tabs, { scope.indicator() }),\n                modifier =\n                    Modifier.fillMaxWidth()\n                        .wrapContentSize(align = Alignment.CenterStart)\n                        .horizontalScroll(scrollState)\n                        .selectableGroup()\n                        .clipToBounds(),\n            ) { (tabMeasurables, indicatorMeasurables), constraints ->\n                val padding = edgePadding.roundToPx()\n                val tabCount = tabMeasurables.size\n                val layoutHeight =\n                    tabMeasurables.fastFold(initial = 0) { curr, measurable ->\n                        maxOf(curr, measurable.maxIntrinsicHeight(Constraints.Infinity))\n                    }\n                var layoutWidth = padding * 2\n                val tabConstraints =\n                    constraints.copy(\n                        minWidth = minTabWidth.roundToPx(),\n                        minHeight = layoutHeight,\n                        maxHeight = layoutHeight,\n                    )\n\n                var left = edgePadding\n                val tabPlaceables = tabMeasurables.fastMap { it.measure(tabConstraints) }\n                // Get indicator widths based on incoming content size, not based on forced minimum\n                // width applied below.\n                val indicatorWidth = mutableIntListOf()\n                tabMeasurables.fastForEach {\n                    indicatorWidth.add(it.maxIntrinsicWidth(Constraints.Infinity))\n                }\n\n                val positions =\n                    List(tabCount) { index ->\n                        val tabWidth = maxOf(minTabWidth, tabPlaceables[index].width.toDp())\n                        layoutWidth += tabWidth.roundToPx()\n                        // Enforce minimum touch target of 24.dp\n                        val contentWidth =\n                            maxOf(indicatorWidth[index].toDp() - (HorizontalTextPadding * 2), 24.dp)\n                        val tabPosition =\n                            TabPosition(left = left, width = tabWidth, contentWidth = contentWidth)\n                        left += tabWidth\n                        tabPosition\n                    }\n                scope.setTabPositions(positions)\n\n                val indicatorPlaceables =\n                    indicatorMeasurables.fastMap {\n                        it.measure(\n                            constraints.copy(\n                                minWidth = 0,\n                                maxWidth = positions[selectedTabIndex].contentWidth.roundToPx(),\n                                minHeight = 0,\n                                maxHeight = layoutHeight,\n                            )\n                        )\n                    }\n\n                layout(layoutWidth, layoutHeight) {\n                    left = edgePadding\n                    tabPlaceables.fastForEachIndexed { index, placeable ->\n                        placeable.placeRelative(left.roundToPx(), 0)\n                        left += positions[index].width\n                    }\n\n                    indicatorPlaceables.fastForEach {\n                        val relativeOffset =\n                            max(0, (positions[selectedTabIndex].width.roundToPx() - it.width) / 2)\n                        it.placeRelative(relativeOffset, layoutHeight - it.height)\n                    }\n\n                    scrollableTabData.onLaidOut(\n                        density = this@Layout,\n                        edgeOffset = padding,\n                        tabPositions = positions,\n                        selectedTab = selectedTabIndex,\n                    )\n                }\n            }\n        }\n    }\n}\n\ninternal data class TabIndicatorModifier(\n    val tabPositionsState: State<List<TabPosition>>,\n    val selectedTabIndex: Int,\n    val followContentSize: Boolean,\n    val animationSpec: FiniteAnimationSpec<Dp>,\n) : ModifierNodeElement<TabIndicatorOffsetNode>() {\n\n    override fun create(): TabIndicatorOffsetNode {\n        return TabIndicatorOffsetNode(\n            tabPositionsState = tabPositionsState,\n            selectedTabIndex = selectedTabIndex,\n            followContentSize = followContentSize,\n            animationSpec = animationSpec,\n        )\n    }\n\n    override fun update(node: TabIndicatorOffsetNode) {\n        node.tabPositionsState = tabPositionsState\n        node.selectedTabIndex = selectedTabIndex\n        node.followContentSize = followContentSize\n        node.animationSpec = animationSpec\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        // Show nothing in the inspector.\n    }\n}\n\ninternal class TabIndicatorOffsetNode(\n    var tabPositionsState: State<List<TabPosition>>,\n    var selectedTabIndex: Int,\n    var followContentSize: Boolean,\n    var animationSpec: FiniteAnimationSpec<Dp>,\n) : Modifier.Node(), LayoutModifierNode {\n\n    private var offsetAnimatable: Animatable<Dp, AnimationVector1D>? = null\n    private var widthAnimatable: Animatable<Dp, AnimationVector1D>? = null\n    private var initialOffset: Dp? = null\n    private var initialWidth: Dp? = null\n\n    override fun MeasureScope.measure(\n        measurable: Measurable,\n        constraints: Constraints,\n    ): MeasureResult {\n        if (tabPositionsState.value.isEmpty()) {\n            return layout(0, 0) {}\n        }\n\n        val currentTabWidth =\n            if (followContentSize) {\n                tabPositionsState.value[selectedTabIndex].contentWidth\n            } else {\n                tabPositionsState.value[selectedTabIndex].width\n            }\n\n        if (initialWidth != null) {\n            val widthAnim =\n                widthAnimatable\n                    ?: Animatable(initialWidth!!, Dp.VectorConverter).also { widthAnimatable = it }\n\n            if (currentTabWidth != widthAnim.targetValue) {\n                coroutineScope.launch { widthAnim.animateTo(currentTabWidth, animationSpec) }\n            }\n        } else {\n            initialWidth = currentTabWidth\n        }\n\n        val indicatorOffset = tabPositionsState.value[selectedTabIndex].left\n\n        if (initialOffset != null) {\n            val offsetAnim =\n                offsetAnimatable\n                    ?: Animatable(initialOffset!!, Dp.VectorConverter).also {\n                        offsetAnimatable = it\n                    }\n\n            if (indicatorOffset != offsetAnim.targetValue) {\n                coroutineScope.launch { offsetAnim.animateTo(indicatorOffset, animationSpec) }\n            }\n        } else {\n            initialOffset = indicatorOffset\n        }\n\n        val offset =\n            if (layoutDirection == LayoutDirection.Ltr) {\n                offsetAnimatable?.value ?: indicatorOffset\n            } else {\n                -(offsetAnimatable?.value ?: indicatorOffset)\n            }\n\n        val width = widthAnimatable?.value ?: currentTabWidth\n\n        val placeable =\n            measurable.measure(\n                constraints.copy(minWidth = width.roundToPx(), maxWidth = width.roundToPx())\n            )\n\n        return layout(placeable.width, placeable.height) { placeable.place(offset.roundToPx(), 0) }\n    }\n}\n\n@Suppress(\"ComposableLambdaInMeasurePolicy\")\n@Composable\nprivate fun TabRowWithSubcomposeImpl(\n    modifier: Modifier,\n    containerColor: Color,\n    contentColor: Color,\n    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit,\n    divider: @Composable () -> Unit,\n    tabs: @Composable () -> Unit,\n) {\n    Surface(\n        modifier = modifier.selectableGroup(),\n        color = containerColor,\n        contentColor = contentColor,\n    ) {\n        SubcomposeLayout(Modifier.fillMaxWidth()) { constraints ->\n            val tabRowWidth = constraints.maxWidth\n            val tabMeasurables = subcompose(TabSlots.Tabs, tabs)\n            val tabCount = tabMeasurables.size\n            var tabWidth = 0\n            if (tabCount > 0) {\n                tabWidth = (tabRowWidth / tabCount)\n            }\n            val tabRowHeight =\n                tabMeasurables.fastFold(initial = 0) { max, curr ->\n                    maxOf(curr.maxIntrinsicHeight(tabWidth), max)\n                }\n\n            val tabPlaceables =\n                tabMeasurables.fastMap {\n                    it.measure(\n                        constraints.copy(\n                            minWidth = tabWidth,\n                            maxWidth = tabWidth,\n                            minHeight = tabRowHeight,\n                            maxHeight = tabRowHeight,\n                        )\n                    )\n                }\n\n            val tabPositions =\n                List(tabCount) { index ->\n                    var contentWidth =\n                        minOf(tabMeasurables[index].maxIntrinsicWidth(tabRowHeight), tabWidth)\n                            .toDp()\n                    contentWidth -= HorizontalTextPadding * 2\n                    // Enforce minimum touch target of 24.dp\n                    val indicatorWidth = maxOf(contentWidth, 24.dp)\n                    TabPosition(tabWidth.toDp() * index, tabWidth.toDp(), indicatorWidth)\n                }\n\n            layout(tabRowWidth, tabRowHeight) {\n                tabPlaceables.fastForEachIndexed { index, placeable ->\n                    placeable.placeRelative(index * tabWidth, 0)\n                }\n\n                subcompose(TabSlots.Divider, divider).fastForEach {\n                    val placeable = it.measure(constraints.copy(minHeight = 0))\n                    placeable.placeRelative(0, tabRowHeight - placeable.height)\n                }\n\n                subcompose(TabSlots.Indicator) { indicator(tabPositions) }\n                    .fastForEach {\n                        it.measure(Constraints.fixed(tabRowWidth, tabRowHeight)).placeRelative(0, 0)\n                    }\n            }\n        }\n    }\n}\n\n@Suppress(\"ComposableLambdaInMeasurePolicy\")\n@Composable\nprivate fun ScrollableTabRowWithSubcomposeImpl(\n    selectedTabIndex: Int,\n    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit,\n    modifier: Modifier = Modifier,\n    containerColor: Color = TabRowDefaults.primaryContainerColor,\n    contentColor: Color = TabRowDefaults.primaryContentColor,\n    edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding,\n    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },\n    tabs: @Composable () -> Unit,\n    scrollState: ScrollState,\n) {\n    Surface(modifier = modifier, color = containerColor, contentColor = contentColor) {\n        val coroutineScope = rememberCoroutineScope()\n        // TODO Load the motionScheme tokens from the component tokens file\n        val scrollAnimationSpec = MotionSchemeKeyTokens.DefaultSpatial.value<Float>()\n        val scrollableTabData =\n            remember(scrollState, coroutineScope) {\n                ScrollableTabData(\n                    scrollState = scrollState,\n                    coroutineScope = coroutineScope,\n                    animationSpec = scrollAnimationSpec,\n                )\n            }\n        SubcomposeLayout(\n            Modifier.fillMaxWidth()\n                .wrapContentSize(align = Alignment.CenterStart)\n                .horizontalScroll(scrollState)\n                .selectableGroup()\n                .clipToBounds()\n        ) { constraints ->\n            val minTabWidth = TabRowDefaults.ScrollableTabRowMinTabWidth.roundToPx()\n            val padding = edgePadding.roundToPx()\n\n            val tabMeasurables = subcompose(TabSlots.Tabs, tabs)\n\n            val layoutHeight =\n                tabMeasurables.fastFold(initial = 0) { curr, measurable ->\n                    maxOf(curr, measurable.maxIntrinsicHeight(Constraints.Infinity))\n                }\n\n            val tabConstraints =\n                constraints.copy(\n                    minWidth = minTabWidth,\n                    minHeight = layoutHeight,\n                    maxHeight = layoutHeight,\n                )\n\n            val tabPlaceables = mutableListOf<Placeable>()\n            val tabContentWidths = mutableListOf<Dp>()\n            tabMeasurables.fastForEach {\n                val placeable = it.measure(tabConstraints)\n                var contentWidth =\n                    minOf(it.maxIntrinsicWidth(placeable.height), placeable.width).toDp()\n                contentWidth -= HorizontalTextPadding * 2\n                tabPlaceables.add(placeable)\n                tabContentWidths.add(contentWidth)\n            }\n\n            val layoutWidth =\n                tabPlaceables.fastFold(initial = padding * 2) { curr, measurable ->\n                    curr + measurable.width\n                }\n\n            // Position the children.\n            layout(layoutWidth, layoutHeight) {\n                // Place the tabs\n                val tabPositions = mutableListOf<TabPosition>()\n                var left = padding\n                tabPlaceables.fastForEachIndexed { index, placeable ->\n                    placeable.placeRelative(left, 0)\n                    tabPositions.add(\n                        TabPosition(\n                            left = left.toDp(),\n                            width = placeable.width.toDp(),\n                            contentWidth = tabContentWidths[index],\n                        )\n                    )\n                    left += placeable.width\n                }\n\n                // The divider is measured with its own height, and width equal to the total width\n                // of the tab row, and then placed on top of the tabs.\n                subcompose(TabSlots.Divider, divider).fastForEach {\n                    val placeable =\n                        it.measure(\n                            constraints.copy(\n                                minHeight = 0,\n                                minWidth = layoutWidth,\n                                maxWidth = layoutWidth,\n                            )\n                        )\n                    placeable.placeRelative(0, layoutHeight - placeable.height)\n                }\n\n                // The indicator container is measured to fill the entire space occupied by the tab\n                // row, and then placed on top of the divider.\n                subcompose(TabSlots.Indicator) { indicator(tabPositions) }\n                    .fastForEach {\n                        it.measure(Constraints.fixed(layoutWidth, layoutHeight)).placeRelative(0, 0)\n                    }\n\n                scrollableTabData.onLaidOut(\n                    density = this@SubcomposeLayout,\n                    edgeOffset = padding,\n                    tabPositions = tabPositions,\n                    selectedTab = selectedTabIndex,\n                )\n            }\n        }\n    }\n}\n\n/**\n * Data class that contains information about a tab's position on screen, used for calculating where\n * to place the indicator that shows which tab is selected.\n *\n * @property left the left edge's x position from the start of the [TabRow]\n * @property right the right edge's x position from the start of the [TabRow]\n * @property width the width of this tab\n * @property contentWidth the content width of this tab. Should be a minimum of 24.dp\n */\n@Immutable\nclass TabPosition internal constructor(val left: Dp, val width: Dp, val contentWidth: Dp) {\n\n    val right: Dp\n        get() = left + width\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is TabPosition) return false\n\n        if (left != other.left) return false\n        if (width != other.width) return false\n        if (contentWidth != other.contentWidth) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = left.hashCode()\n        result = 31 * result + width.hashCode()\n        result = 31 * result + contentWidth.hashCode()\n        return result\n    }\n\n    override fun toString(): String {\n        return \"TabPosition(left=$left, right=$right, width=$width, contentWidth=$contentWidth)\"\n    }\n}\n\n/** Contains default implementations and values used for TabRow. */\nobject TabRowDefaults {\n    /**\n     * The default minimum width for a tab in a [PrimaryScrollableTabRow] or\n     * [SecondaryScrollableTabRow].\n     */\n    val ScrollableTabRowMinTabWidth = 90.dp\n\n    /**\n     * The default padding from the starting edge before a tab in a [PrimaryScrollableTabRow] or\n     * [SecondaryScrollableTabRow].\n     */\n    val ScrollableTabRowEdgeStartPadding = 52.dp\n\n    /** Default container color of a tab row. */\n    @Deprecated(\n        message = \"Use TabRowDefaults.primaryContainerColor instead\",\n        replaceWith = ReplaceWith(\"primaryContainerColor\"),\n    )\n    val containerColor: Color\n        @Composable get() = PrimaryNavigationTabTokens.ContainerColor.value\n\n    /** Default container color of a [PrimaryTabRow]. */\n    val primaryContainerColor: Color\n        @Composable get() = PrimaryNavigationTabTokens.ContainerColor.value\n\n    /** Default container color of a [SecondaryTabRow]. */\n    val secondaryContainerColor: Color\n        @Composable get() = SecondaryNavigationTabTokens.ContainerColor.value\n\n    /** Default content color of a tab row. */\n    @Deprecated(\n        message = \"Use TabRowDefaults.primaryContentColor instead\",\n        replaceWith = ReplaceWith(\"primaryContentColor\"),\n    )\n    val contentColor: Color\n        @Composable get() = PrimaryNavigationTabTokens.ActiveLabelTextColor.value\n\n    /** Default content color of a [PrimaryTabRow]. */\n    val primaryContentColor: Color\n        @Composable get() = PrimaryNavigationTabTokens.ActiveLabelTextColor.value\n\n    /** Default content color of a [SecondaryTabRow]. */\n    val secondaryContentColor: Color\n        @Composable get() = SecondaryNavigationTabTokens.ActiveLabelTextColor.value\n\n    /**\n     * Default indicator, which will be positioned at the bottom of the [TabRow], on top of the\n     * divider.\n     *\n     * @param modifier modifier for the indicator's layout\n     * @param height height of the indicator\n     * @param color color of the indicator\n     */\n    @Composable\n    @Deprecated(\n        message = \"Use SecondaryIndicator instead.\",\n        replaceWith = ReplaceWith(\"SecondaryIndicator(modifier, height, color)\"),\n    )\n    fun Indicator(\n        modifier: Modifier = Modifier,\n        height: Dp = PrimaryNavigationTabTokens.ActiveIndicatorHeight,\n        color: Color =\n            MaterialTheme.colorScheme.fromToken(PrimaryNavigationTabTokens.ActiveIndicatorColor),\n    ) {\n        Box(modifier.fillMaxWidth().height(height).background(color = color))\n    }\n\n    /**\n     * Primary indicator, which will be positioned at the bottom of the [TabRow], on top of the\n     * divider.\n     *\n     * @param modifier modifier for the indicator's layout\n     * @param width width of the indicator\n     * @param height height of the indicator\n     * @param color color of the indicator\n     * @param shape shape of the indicator\n     */\n    @Composable\n    fun PrimaryIndicator(\n        modifier: Modifier = Modifier,\n        width: Dp = 24.dp,\n        height: Dp = PrimaryNavigationTabTokens.ActiveIndicatorHeight,\n        color: Color = PrimaryNavigationTabTokens.ActiveIndicatorColor.value,\n        shape: Shape = PrimaryNavigationTabTokens.ActiveIndicatorShape,\n    ) {\n        Spacer(\n            modifier\n                .requiredHeight(height)\n                .requiredWidth(width)\n                .background(color = color, shape = shape)\n        )\n    }\n\n    /**\n     * Secondary indicator, which will be positioned at the bottom of the [TabRow], on top of the\n     * divider.\n     *\n     * @param modifier modifier for the indicator's layout\n     * @param height height of the indicator\n     * @param color color of the indicator\n     */\n    @Composable\n    fun SecondaryIndicator(\n        modifier: Modifier = Modifier,\n        height: Dp = PrimaryNavigationTabTokens.ActiveIndicatorHeight,\n        color: Color = PrimaryNavigationTabTokens.ActiveIndicatorColor.value,\n    ) {\n        Box(modifier.fillMaxWidth().height(height).background(color = color))\n    }\n\n    /**\n     * [Modifier] that takes up all the available width inside the [TabRow], and then animates the\n     * offset of the indicator it is applied to, depending on the [currentTabPosition].\n     *\n     * @param currentTabPosition [TabPosition] of the currently selected tab. This is used to\n     *   calculate the offset of the indicator this modifier is applied to, as well as its width.\n     */\n    @Deprecated(\n        level = DeprecationLevel.WARNING,\n        message =\n            \"Solely for use alongside deprecated TabRowDefaults.Indicator method. For \" +\n                \"recommended PrimaryIndicator and SecondaryIndicator methods, please use \" +\n                \"TabIndicatorScope.tabIndicatorOffset method.\",\n    )\n    fun Modifier.tabIndicatorOffset(currentTabPosition: TabPosition): Modifier =\n        composed(\n            inspectorInfo =\n                debugInspectorInfo {\n                    name = \"tabIndicatorOffset\"\n                    value = currentTabPosition\n                }\n        ) {\n            // TODO Load the motionScheme tokens from the component tokens file\n            val currentTabWidth by\n                animateDpAsState(\n                    targetValue = currentTabPosition.width,\n                    animationSpec = MotionSchemeKeyTokens.DefaultSpatial.value(),\n                )\n            val indicatorOffset by\n                animateDpAsState(\n                    targetValue = currentTabPosition.left,\n                    animationSpec = MotionSchemeKeyTokens.DefaultSpatial.value(),\n                )\n            fillMaxWidth()\n                .wrapContentSize(Alignment.BottomStart)\n                .offset { IntOffset(x = indicatorOffset.roundToPx(), y = 0) }\n                .width(currentTabWidth)\n        }\n}\n\nprivate enum class TabSlots {\n    Tabs,\n    Divider,\n    Indicator,\n}\n\n/** Class holding onto state needed for [ScrollableTabRow] */\nprivate class ScrollableTabData(\n    private val scrollState: ScrollState,\n    private val coroutineScope: CoroutineScope,\n    private val animationSpec: FiniteAnimationSpec<Float>,\n) {\n    private var selectedTab: Int? = null\n\n    fun onLaidOut(\n        density: Density,\n        edgeOffset: Int,\n        tabPositions: List<TabPosition>,\n        selectedTab: Int,\n    ) {\n        // Animate if the new tab is different from the old tab, or this is called for the first\n        // time (i.e selectedTab is `null`).\n        if (this.selectedTab != selectedTab) {\n            this.selectedTab = selectedTab\n            tabPositions.getOrNull(selectedTab)?.let {\n                // Scrolls to the tab with [tabPosition], trying to place it in the center of the\n                // screen or as close to the center as possible.\n                val calculatedOffset = it.calculateTabOffset(density, edgeOffset, tabPositions)\n                if (scrollState.value != calculatedOffset) {\n                    coroutineScope.launch {\n                        scrollState.animateScrollTo(calculatedOffset, animationSpec = animationSpec)\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * @return the offset required to horizontally center the tab inside this TabRow. If the tab is\n     *   at the start / end, and there is not enough space to fully centre the tab, this will just\n     *   clamp to the min / max position given the max width.\n     */\n    private fun TabPosition.calculateTabOffset(\n        density: Density,\n        edgeOffset: Int,\n        tabPositions: List<TabPosition>,\n    ): Int =\n        with(density) {\n            val totalTabRowWidth = tabPositions.last().right.roundToPx() + edgeOffset\n            val visibleWidth = totalTabRowWidth - scrollState.maxValue\n            val tabOffset = left.roundToPx()\n            val scrollerCenter = visibleWidth / 2\n            val tabWidth = width.roundToPx()\n            val centeredTabOffset = tabOffset - (scrollerCenter - tabWidth / 2)\n            // How much space we have to scroll. If the visible width is <= to the total width, then\n            // we have no space to scroll as everything is always visible.\n            val availableSpace = (totalTabRowWidth - visibleWidth).coerceAtLeast(0)\n            return centeredTabOffset.coerceIn(0, availableSpace)\n        }\n}\n\n@Deprecated(level = DeprecationLevel.HIDDEN, message = \"Maintained for Binary Compatibility.\")\n@Composable\nfun PrimaryScrollableTabRow(\n    selectedTabIndex: Int,\n    modifier: Modifier = Modifier,\n    scrollState: ScrollState = rememberScrollState(),\n    containerColor: Color = TabRowDefaults.primaryContainerColor,\n    contentColor: Color = TabRowDefaults.primaryContentColor,\n    edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding,\n    indicator: @Composable TabIndicatorScope.() -> Unit =\n        @Composable {\n            TabRowDefaults.PrimaryIndicator(\n                Modifier.tabIndicatorOffset(selectedTabIndex, matchContentSize = true),\n                width = Dp.Unspecified,\n            )\n        },\n    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },\n    tabs: @Composable () -> Unit,\n) =\n    PrimaryScrollableTabRow(\n        selectedTabIndex = selectedTabIndex,\n        modifier = modifier,\n        scrollState = scrollState,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        edgePadding = edgePadding,\n        indicator = indicator,\n        divider = divider,\n        minTabWidth = TabRowDefaults.ScrollableTabRowMinTabWidth,\n        tabs = tabs,\n    )\n\n@Deprecated(level = DeprecationLevel.HIDDEN, message = \"Maintained for Binary Compatibility.\")\n@Composable\nfun SecondaryScrollableTabRow(\n    selectedTabIndex: Int,\n    modifier: Modifier = Modifier,\n    scrollState: ScrollState = rememberScrollState(),\n    containerColor: Color = TabRowDefaults.secondaryContainerColor,\n    contentColor: Color = TabRowDefaults.secondaryContentColor,\n    edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding,\n    indicator: @Composable TabIndicatorScope.() -> Unit =\n        @Composable {\n            TabRowDefaults.SecondaryIndicator(\n                Modifier.tabIndicatorOffset(selectedTabIndex, matchContentSize = false)\n            )\n        },\n    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },\n    tabs: @Composable () -> Unit,\n) =\n    SecondaryScrollableTabRow(\n        selectedTabIndex = selectedTabIndex,\n        modifier = modifier,\n        scrollState = scrollState,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        edgePadding = edgePadding,\n        indicator = indicator,\n        divider = divider,\n        minTabWidth = TabRowDefaults.ScrollableTabRowMinTabWidth,\n        tabs = tabs,\n    )\n\n/**\n * [Material Design tabs](https://m3.material.io/components/tabs/overview)\n *\n * Material Design fixed tabs.\n *\n * For primary indicator tabs, use [PrimaryTabRow]. For secondary indicator tabs, use\n * [SecondaryTabRow].\n *\n * Fixed tabs display all tabs in a set simultaneously. They are best for switching between related\n * content quickly, such as between transportation methods in a map. To navigate between fixed tabs,\n * tap an individual tab, or swipe left or right in the content area.\n *\n * A TabRow contains a row of [Tab]s, and displays an indicator underneath the currently selected\n * tab. A TabRow places its tabs evenly spaced along the entire row, with each tab taking up an\n * equal amount of space. See [ScrollableTabRow] for a tab row that does not enforce equal size, and\n * allows scrolling to tabs that do not fit on screen.\n *\n * A simple example with text tabs looks like:\n *\n * @sample androidx.compose.material3.samples.TextTabs\n *\n * You can also provide your own custom tab, such as:\n *\n * @sample androidx.compose.material3.samples.FancyTabs\n *\n * Where the custom tab itself could look like:\n *\n * @sample androidx.compose.material3.samples.FancyTab\n *\n * As well as customizing the tab, you can also provide a custom [indicator], to customize the\n * indicator displayed for a tab. [indicator] will be placed to fill the entire TabRow, so it should\n * internally take care of sizing and positioning the indicator to match changes to\n * [selectedTabIndex].\n *\n * For example, given an indicator that draws a rounded rectangle near the edges of the [Tab]:\n *\n * @sample androidx.compose.material3.samples.FancyIndicator\n *\n * We can reuse [TabRowDefaults.tabIndicatorOffset] and just provide this indicator, as we aren't\n * changing how the size and position of the indicator changes between tabs:\n *\n * @sample androidx.compose.material3.samples.FancyIndicatorTabs\n *\n * You may also want to use a custom transition, to allow you to dynamically change the appearance\n * of the indicator as it animates between tabs, such as changing its color or size. [indicator] is\n * stacked on top of the entire TabRow, so you just need to provide a custom transition that\n * animates the offset of the indicator from the start of the TabRow. For example, take the\n * following example that uses a transition to animate the offset, width, and color of the same\n * FancyIndicator from before, also adding a physics based 'spring' effect to the indicator in the\n * direction of motion:\n *\n * @sample androidx.compose.material3.samples.FancyAnimatedIndicatorWithModifier\n *\n * We can now just pass this indicator directly to TabRow:\n *\n * @sample androidx.compose.material3.samples.FancyIndicatorContainerTabs\n * @param selectedTabIndex the index of the currently selected tab\n * @param modifier the [Modifier] to be applied to this tab row\n * @param containerColor the color used for the background of this tab row. Use [Color.Transparent]\n *   to have no color.\n * @param contentColor the preferred color for content inside this tab row. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param indicator the indicator that represents which tab is currently selected. By default this\n *   will be a [TabRowDefaults.SecondaryIndicator], using a [TabRowDefaults.tabIndicatorOffset]\n *   modifier to animate its position. Note that this indicator will be forced to fill up the entire\n *   tab row, so you should use [TabRowDefaults.tabIndicatorOffset] or similar to animate the actual\n *   drawn indicator inside this space, and provide an offset from the start.\n * @param divider the divider displayed at the bottom of the tab row. This provides a layer of\n *   separation between the tab row and the content displayed underneath.\n * @param tabs the tabs inside this tab row. Typically this will be multiple [Tab]s. Each element\n *   inside this lambda will be measured and placed evenly across the row, each taking up equal\n *   space.\n */\n@Composable\n@Deprecated(\n    level = DeprecationLevel.WARNING,\n    message = \"Replaced with PrimaryTabRow and SecondaryTabRow.\",\n    replaceWith =\n        ReplaceWith(\n            \"SecondaryTabRow(selectedTabIndex, modifier, containerColor, contentColor, indicator, divider, tabs)\"\n        ),\n)\n@Suppress(\"DEPRECATION\")\nfun TabRow(\n    selectedTabIndex: Int,\n    modifier: Modifier = Modifier,\n    containerColor: Color = TabRowDefaults.primaryContainerColor,\n    contentColor: Color = TabRowDefaults.primaryContentColor,\n    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit =\n        @Composable { tabPositions ->\n            if (selectedTabIndex < tabPositions.size) {\n                TabRowDefaults.SecondaryIndicator(\n                    Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex])\n                )\n            }\n        },\n    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },\n    tabs: @Composable () -> Unit,\n) {\n    TabRowWithSubcomposeImpl(modifier, containerColor, contentColor, indicator, divider, tabs)\n}\n\n/**\n * [Material Design tabs](https://m3.material.io/components/tabs/overview)\n *\n * Material Design scrollable tabs.\n *\n * For primary indicator tabs, use [PrimaryScrollableTabRow]. For secondary indicator tabs, use\n * [SecondaryScrollableTabRow].\n *\n * When a set of tabs cannot fit on screen, use scrollable tabs. Scrollable tabs can use longer text\n * labels and a larger number of tabs. They are best used for browsing on touch interfaces.\n *\n * A ScrollableTabRow contains a row of [Tab]s, and displays an indicator underneath the currently\n * selected tab. A ScrollableTabRow places its tabs offset from the starting edge, and allows\n * scrolling to tabs that are placed off screen. For a fixed tab row that does not allow scrolling,\n * and evenly places its tabs, see [TabRow].\n *\n * @param selectedTabIndex the index of the currently selected tab\n * @param modifier the [Modifier] to be applied to this tab row\n * @param containerColor the color used for the background of this tab row. Use [Color.Transparent]\n *   to have no color.\n * @param contentColor the preferred color for content inside this tab row. Defaults to either the\n *   matching content color for [containerColor], or to the current [LocalContentColor] if\n *   [containerColor] is not a color from the theme.\n * @param edgePadding the padding between the starting and ending edge of the scrollable tab row,\n *   and the tabs inside the row. This padding helps inform the user that this tab row can be\n *   scrolled, unlike a [TabRow].\n * @param indicator the indicator that represents which tab is currently selected. By default this\n *   will be a [TabRowDefaults.SecondaryIndicator], using a [TabRowDefaults.tabIndicatorOffset]\n *   modifier to animate its position. Note that this indicator will be forced to fill up the entire\n *   tab row, so you should use [TabRowDefaults.tabIndicatorOffset] or similar to animate the actual\n *   drawn indicator inside this space, and provide an offset from the start.\n * @param divider the divider displayed at the bottom of the tab row. This provides a layer of\n *   separation between the tab row and the content displayed underneath.\n * @param tabs the tabs inside this tab row. Typically this will be multiple [Tab]s. Each element\n *   inside this lambda will be measured and placed evenly across the row, each taking up equal\n *   space.\n */\n@Composable\n@Deprecated(\n    level = DeprecationLevel.WARNING,\n    message = \"Replaced with PrimaryScrollableTabRow and SecondaryScrollableTabRow tab variants.\",\n    replaceWith =\n        ReplaceWith(\n            \"SecondaryScrollableTabRow(selectedTabIndex, modifier, containerColor, contentColor, edgePadding, indicator, divider, tabs)\"\n        ),\n)\n@Suppress(\"DEPRECATION\")\nfun ScrollableTabRow(\n    selectedTabIndex: Int,\n    modifier: Modifier = Modifier,\n    containerColor: Color = TabRowDefaults.primaryContainerColor,\n    contentColor: Color = TabRowDefaults.primaryContentColor,\n    edgePadding: Dp = TabRowDefaults.ScrollableTabRowEdgeStartPadding,\n    indicator: @Composable (tabPositions: List<TabPosition>) -> Unit =\n        @Composable { tabPositions ->\n            TabRowDefaults.SecondaryIndicator(\n                Modifier.tabIndicatorOffset(tabPositions[selectedTabIndex])\n            )\n        },\n    divider: @Composable () -> Unit = @Composable { HorizontalDivider() },\n    tabs: @Composable () -> Unit,\n) {\n    ScrollableTabRowWithSubcomposeImpl(\n        selectedTabIndex = selectedTabIndex,\n        indicator = indicator,\n        modifier = modifier,\n        containerColor = containerColor,\n        contentColor = contentColor,\n        edgePadding = edgePadding,\n        divider = divider,\n        tabs = tabs,\n        scrollState = rememberScrollState(),\n    )\n}\n```\n\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/source-code/navigation-source.md",
    "content": "# Navigation Compose Source Reference\n\n## File: navigation/navigation-compose/src/androidMain/kotlin/androidx/navigation/compose/NavHostController.android.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@file:JvmName(\"NavHostControllerKt\")\n@file:JvmMultifileClass\n\npackage androidx.navigation.compose\n\nimport android.content.Context\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.saveable.Saver\nimport androidx.compose.runtime.saveable.rememberSaveable\nimport androidx.compose.ui.platform.LocalContext\nimport androidx.navigation.NavDestination\nimport androidx.navigation.NavHostController\nimport androidx.navigation.Navigator\n\n@Composable\npublic actual fun rememberNavController(\n    vararg navigators: Navigator<out NavDestination>\n): NavHostController {\n    val context = LocalContext.current\n    return rememberSaveable(inputs = navigators, saver = NavControllerSaver(context)) {\n            createNavController(context)\n        }\n        .apply {\n            for (navigator in navigators) {\n                navigatorProvider.addNavigator(navigator)\n            }\n        }\n}\n\nprivate fun createNavController(context: Context) =\n    NavHostController(context).apply {\n        navigatorProvider.addNavigator(ComposeNavGraphNavigator(navigatorProvider))\n        navigatorProvider.addNavigator(ComposeNavigator())\n        navigatorProvider.addNavigator(DialogNavigator())\n    }\n\n/** Saver to save and restore the NavController across config change and process death. */\nprivate fun NavControllerSaver(context: Context): Saver<NavHostController, *> =\n    Saver(\n        save = { it.saveState() },\n        restore = { createNavController(context).apply { restoreState(it) } },\n    )\n```\n\n## File: navigation/navigation-compose/src/androidMain/kotlin/androidx/navigation/compose/internal/NavComposeUtils.android.kt\n```kotlin\n/*\n * Copyright 2025 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.navigation.compose.internal\n\nimport androidx.activity.compose.PredictiveBackHandler\nimport androidx.compose.runtime.Composable\nimport java.lang.ref.WeakReference\nimport java.util.UUID\nimport kotlinx.coroutines.flow.Flow\n\ninternal actual typealias BackEventCompat = androidx.activity.BackEventCompat\n\n@Composable\ninternal actual fun PredictiveBackHandler(\n    enabled: Boolean,\n    onBack: suspend (progress: Flow<BackEventCompat>) -> Unit,\n) {\n    PredictiveBackHandler(enabled, onBack)\n}\n\ninternal actual fun randomUUID(): String = UUID.randomUUID().toString()\n\n/**\n * Class WeakReference encapsulates weak reference to an object, which could be used to either\n * retrieve a strong reference to an object, or return null, if object was already destroyed by the\n * memory manager.\n */\ninternal actual class WeakReference<T : Any> actual constructor(reference: T) {\n    private val weakReference = WeakReference(reference)\n\n    actual fun get(): T? = weakReference.get()\n\n    actual fun clear() = weakReference.clear()\n}\n\ninternal actual typealias DefaultNavTransitions = StandardDefaultNavTransitions\n```\n\n## File: navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/ComposeNavGraphNavigator.kt\n```kotlin\n/*\n * Copyright 2023 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.navigation.compose\n\nimport androidx.compose.animation.AnimatedContentTransitionScope\nimport androidx.compose.animation.EnterTransition\nimport androidx.compose.animation.ExitTransition\nimport androidx.compose.animation.SizeTransform\nimport androidx.navigation.NavBackStackEntry\nimport androidx.navigation.NavGraph\nimport androidx.navigation.NavGraphNavigator\nimport androidx.navigation.Navigator\nimport androidx.navigation.NavigatorProvider\nimport kotlin.jvm.JvmSuppressWildcards\n\n/**\n * Custom subclass of [NavGraphNavigator] that adds support for defining transitions at the\n * navigation graph level.\n */\n@Navigator.Name(\"navigation\")\ninternal class ComposeNavGraphNavigator(navigatorProvider: NavigatorProvider) :\n    NavGraphNavigator(navigatorProvider) {\n    override fun createDestination(): NavGraph {\n        return ComposeNavGraph(this)\n    }\n\n    internal class ComposeNavGraph(navGraphNavigator: Navigator<out NavGraph>) :\n        NavGraph(navGraphNavigator) {\n        internal var enterTransition:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n            null\n\n        internal var exitTransition:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n            null\n\n        internal var popEnterTransition:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n            null\n\n        internal var popExitTransition:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n            null\n\n        internal var predictivePopEnterTransition:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> EnterTransition?)? =\n            null\n\n        internal var predictivePopExitTransition:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> ExitTransition?)? =\n            null\n\n        internal var sizeTransform:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n            null\n    }\n}\n```\n\n## File: navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/ComposeNavigator.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.navigation.compose\n\nimport androidx.compose.animation.AnimatedContentScope\nimport androidx.compose.animation.AnimatedContentTransitionScope\nimport androidx.compose.animation.EnterTransition\nimport androidx.compose.animation.ExitTransition\nimport androidx.compose.animation.SizeTransform\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.navigation.NavBackStackEntry\nimport androidx.navigation.NavDestination\nimport androidx.navigation.NavOptions\nimport androidx.navigation.Navigator\nimport androidx.navigation.compose.ComposeNavigator.Destination\nimport kotlin.jvm.JvmSuppressWildcards\nimport kotlinx.coroutines.flow.StateFlow\n\n/**\n * Navigator that navigates through [Composable]s. Every destination using this Navigator must set a\n * valid [Composable] by setting it directly on an instantiated [Destination] or calling\n * [composable].\n */\n@Navigator.Name(\"composable\")\npublic class ComposeNavigator constructor() : Navigator<Destination>(NAME) {\n\n    /** Get the map of transitions currently in progress from the [state]. */\n    internal val transitionsInProgress\n        get() = state.transitionsInProgress\n\n    /** Get the back stack from the [state]. */\n    public val backStack: StateFlow<List<NavBackStackEntry>>\n        get() = state.backStack\n\n    internal val isPop = mutableStateOf(false)\n\n    override fun navigate(\n        entries: List<NavBackStackEntry>,\n        navOptions: NavOptions?,\n        navigatorExtras: Extras?,\n    ) {\n        entries.forEach { entry -> state.pushWithTransition(entry) }\n        isPop.value = false\n    }\n\n    override fun createDestination(): Destination {\n        return Destination(this) {}\n    }\n\n    override fun popBackStack(popUpTo: NavBackStackEntry, savedState: Boolean) {\n        state.popWithTransition(popUpTo, savedState)\n        isPop.value = true\n    }\n\n    /**\n     * Function to prepare the entry for transition.\n     *\n     * This should be called when the entry needs to move the [androidx.lifecycle.Lifecycle.State]\n     * in preparation for a transition such as when using predictive back.\n     */\n    public fun prepareForTransition(entry: NavBackStackEntry) {\n        state.prepareForTransition(entry)\n    }\n\n    /**\n     * Callback to mark a navigation in transition as complete.\n     *\n     * This should be called in conjunction with [navigate] and [popBackStack] as those calls merely\n     * start a transition to the target destination, and requires manually marking the transition as\n     * complete by calling this method.\n     *\n     * Failing to call this method could result in entries being prevented from reaching their final\n     * [androidx.lifecycle.Lifecycle.State].\n     */\n    public fun onTransitionComplete(entry: NavBackStackEntry) {\n        state.markTransitionComplete(entry)\n    }\n\n    /** NavDestination specific to [ComposeNavigator] */\n    @NavDestination.ClassType(Composable::class)\n    public class Destination(\n        navigator: ComposeNavigator,\n        internal val content:\n            @Composable\n            AnimatedContentScope.(@JvmSuppressWildcards NavBackStackEntry) -> Unit,\n    ) : NavDestination(navigator) {\n\n        @Deprecated(\n            message = \"Deprecated in favor of Destination that supports AnimatedContent\",\n            level = DeprecationLevel.HIDDEN,\n        )\n        public constructor(\n            navigator: ComposeNavigator,\n            content: @Composable (NavBackStackEntry) -> @JvmSuppressWildcards Unit,\n        ) : this(navigator, content = { entry -> content(entry) })\n\n        internal var enterTransition:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n            null\n\n        internal var exitTransition:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n            null\n\n        internal var popEnterTransition:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n            null\n\n        internal var popExitTransition:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n            null\n\n        internal var predictivePopEnterTransition:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> EnterTransition?)? =\n            null\n\n        internal var predictivePopExitTransition:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> ExitTransition?)? =\n            null\n\n        internal var sizeTransform:\n            (@JvmSuppressWildcards\n            AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n            null\n    }\n\n    internal companion object {\n        internal const val NAME = \"composable\"\n    }\n}\n```\n\n## File: navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/ComposeNavigatorDestinationBuilder.kt\n```kotlin\n/*\n * Copyright 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.navigation.compose\n\nimport androidx.compose.animation.AnimatedContentScope\nimport androidx.compose.animation.AnimatedContentTransitionScope\nimport androidx.compose.animation.EnterTransition\nimport androidx.compose.animation.ExitTransition\nimport androidx.compose.animation.SizeTransform\nimport androidx.compose.runtime.Composable\nimport androidx.navigation.NavBackStackEntry\nimport androidx.navigation.NavDestinationBuilder\nimport androidx.navigation.NavDestinationDsl\nimport androidx.navigation.NavType\nimport kotlin.jvm.JvmSuppressWildcards\nimport kotlin.reflect.KClass\nimport kotlin.reflect.KType\n\n/** DSL for constructing a new [ComposeNavigator.Destination] */\n@NavDestinationDsl\npublic class ComposeNavigatorDestinationBuilder :\n    NavDestinationBuilder<ComposeNavigator.Destination> {\n\n    private val composeNavigator: ComposeNavigator\n    private val content: @Composable (AnimatedContentScope.(NavBackStackEntry) -> Unit)\n\n    public var enterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n        null\n\n    public var exitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n        null\n\n    public var popEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n        null\n\n    public var popExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n        null\n\n    public var sizeTransform:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n        null\n\n    /**\n     * DSL for constructing a new [ComposeNavigator.Destination]\n     *\n     * @param navigator navigator used to create the destination\n     * @param route the destination's unique route\n     * @param content composable for the destination\n     */\n    public constructor(\n        navigator: ComposeNavigator,\n        route: String,\n        content: @Composable AnimatedContentScope.(NavBackStackEntry) -> Unit,\n    ) : super(navigator, route) {\n        this.composeNavigator = navigator\n        this.content = content\n    }\n\n    /**\n     * DSL for constructing a new [ComposeNavigator.Destination]\n     *\n     * @param navigator navigator used to create the destination\n     * @param route the destination's unique route from a [KClass]\n     * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n     *   [NavType]. May be empty if [route] does not use custom NavTypes.\n     * @param content composable for the destination\n     */\n    public constructor(\n        navigator: ComposeNavigator,\n        route: KClass<*>,\n        typeMap: Map<KType, @JvmSuppressWildcards NavType<*>>,\n        content: @Composable AnimatedContentScope.(NavBackStackEntry) -> Unit,\n    ) : super(navigator, route, typeMap) {\n        this.composeNavigator = navigator\n        this.content = content\n    }\n\n    override fun instantiateDestination(): ComposeNavigator.Destination {\n        return ComposeNavigator.Destination(composeNavigator, content)\n    }\n\n    override fun build(): ComposeNavigator.Destination {\n        return super.build().also { destination ->\n            destination.enterTransition = enterTransition\n            destination.exitTransition = exitTransition\n            destination.popEnterTransition = popEnterTransition\n            destination.popExitTransition = popExitTransition\n            destination.sizeTransform = sizeTransform\n        }\n    }\n}\n```\n\n## File: navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/DialogHost.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.navigation.compose\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveableStateHolder\nimport androidx.compose.runtime.snapshots.SnapshotStateList\nimport androidx.compose.ui.platform.LocalInspectionMode\nimport androidx.compose.ui.window.Dialog\nimport androidx.lifecycle.Lifecycle\nimport androidx.lifecycle.LifecycleEventObserver\nimport androidx.navigation.NavBackStackEntry\nimport androidx.navigation.compose.DialogNavigator.Destination\n\n/**\n * Show each [Destination] on the [DialogNavigator]'s back stack as a [Dialog].\n *\n * Note that [NavHost] will call this for you; you do not need to call it manually.\n */\n@Composable\npublic fun DialogHost(dialogNavigator: DialogNavigator) {\n    val saveableStateHolder = rememberSaveableStateHolder()\n    val dialogBackStack by dialogNavigator.backStack.collectAsState()\n    val visibleBackStack = rememberVisibleList(dialogBackStack)\n    visibleBackStack.PopulateVisibleList(dialogBackStack)\n\n    val transitionInProgress by dialogNavigator.transitionInProgress.collectAsState()\n    val dialogsToDispose = remember { mutableStateListOf<NavBackStackEntry>() }\n\n    visibleBackStack.forEach { backStackEntry ->\n        val destination = backStackEntry.destination as Destination\n        Dialog(\n            onDismissRequest = { dialogNavigator.dismiss(backStackEntry) },\n            properties = destination.dialogProperties,\n        ) {\n            DisposableEffect(backStackEntry) {\n                dialogsToDispose.add(backStackEntry)\n                onDispose {\n                    dialogNavigator.onTransitionComplete(backStackEntry)\n                    dialogsToDispose.remove(backStackEntry)\n                }\n            }\n\n            // while in the scope of the composable, we provide the navBackStackEntry as the\n            // ViewModelStoreOwner and LifecycleOwner\n            backStackEntry.LocalOwnersProvider(saveableStateHolder) {\n                destination.content(backStackEntry)\n            }\n        }\n    }\n    // Dialogs may have been popped before it was composed. To prevent leakage, we need to\n    // mark popped entries as complete here. Check that we don't accidentally complete popped\n    // entries that were composed, unless they were disposed of already.\n    LaunchedEffect(transitionInProgress, dialogsToDispose) {\n        transitionInProgress.forEach { entry ->\n            if (\n                !dialogNavigator.backStack.value.contains(entry) &&\n                    !dialogsToDispose.contains(entry)\n            ) {\n                dialogNavigator.onTransitionComplete(entry)\n            }\n        }\n    }\n}\n\n@Composable\ninternal fun MutableList<NavBackStackEntry>.PopulateVisibleList(\n    backStack: Collection<NavBackStackEntry>\n) {\n    val isInspecting = LocalInspectionMode.current\n    backStack.forEach { entry ->\n        DisposableEffect(entry.lifecycle) {\n            val observer = LifecycleEventObserver { _, event ->\n                // show dialog in preview\n                if (isInspecting && !contains(entry)) {\n                    add(entry)\n                }\n                // ON_START -> add to visibleBackStack, ON_STOP -> remove from visibleBackStack\n                if (event == Lifecycle.Event.ON_START) {\n                    // We want to treat the visible lists as Sets but we want to keep\n                    // the functionality of mutableStateListOf() so that we recompose in response\n                    // to adds and removes.\n                    if (!contains(entry)) {\n                        add(entry)\n                    }\n                }\n                if (event == Lifecycle.Event.ON_STOP) {\n                    remove(entry)\n                }\n            }\n            entry.lifecycle.addObserver(observer)\n            onDispose { entry.lifecycle.removeObserver(observer) }\n        }\n    }\n}\n\n@Composable\ninternal fun rememberVisibleList(\n    backStack: Collection<NavBackStackEntry>\n): SnapshotStateList<NavBackStackEntry> {\n    // show dialog in preview\n    val isInspecting = LocalInspectionMode.current\n    return remember(backStack) {\n        mutableStateListOf<NavBackStackEntry>().also {\n            it.addAll(\n                backStack.filter { entry ->\n                    if (isInspecting) {\n                        true\n                    } else {\n                        entry.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)\n                    }\n                }\n            )\n        }\n    }\n}\n```\n\n## File: navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/DialogNavigator.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.navigation.compose\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.window.Dialog\nimport androidx.compose.ui.window.DialogProperties\nimport androidx.navigation.FloatingWindow\nimport androidx.navigation.NavBackStackEntry\nimport androidx.navigation.NavDestination\nimport androidx.navigation.NavOptions\nimport androidx.navigation.Navigator\nimport androidx.navigation.compose.DialogNavigator.Destination\n\n/**\n * Navigator that navigates through [Composable]s that will be hosted within a [Dialog]. Every\n * destination using this Navigator must set a valid [Composable] by setting it directly on an\n * instantiated [Destination] or calling [dialog].\n */\n@Navigator.Name(\"dialog\")\npublic class DialogNavigator() : Navigator<Destination>(NAME) {\n\n    /** Get the back stack from the [state]. */\n    internal val backStack\n        get() = state.backStack\n\n    /** Get the transitioning dialogs from the [state]. */\n    internal val transitionInProgress\n        get() = state.transitionsInProgress\n\n    /** Dismiss the dialog destination associated with the given [backStackEntry]. */\n    internal fun dismiss(backStackEntry: NavBackStackEntry) {\n        popBackStack(backStackEntry, false)\n    }\n\n    override fun navigate(\n        entries: List<NavBackStackEntry>,\n        navOptions: NavOptions?,\n        navigatorExtras: Extras?,\n    ) {\n        entries.forEach { entry -> state.push(entry) }\n    }\n\n    override fun createDestination(): Destination {\n        return Destination(this) {}\n    }\n\n    override fun popBackStack(popUpTo: NavBackStackEntry, savedState: Boolean) {\n        state.popWithTransition(popUpTo, savedState)\n        // When popping, the incoming dialog is marked transitioning to hold it in\n        // STARTED. With pop complete, we can remove it from transition so it can move to RESUMED.\n        val popIndex = state.transitionsInProgress.value.indexOf(popUpTo)\n        // do not mark complete for entries up to and including popUpTo\n        state.transitionsInProgress.value.forEachIndexed { index, entry ->\n            if (index > popIndex) onTransitionComplete(entry)\n        }\n    }\n\n    internal fun onTransitionComplete(entry: NavBackStackEntry) {\n        state.markTransitionComplete(entry)\n    }\n\n    /** NavDestination specific to [DialogNavigator] */\n    @NavDestination.ClassType(Composable::class)\n    public class Destination(\n        navigator: DialogNavigator,\n        internal val dialogProperties: DialogProperties = DialogProperties(),\n        internal val content: @Composable (NavBackStackEntry) -> Unit,\n    ) : NavDestination(navigator), FloatingWindow\n\n    internal companion object {\n        internal const val NAME = \"dialog\"\n    }\n}\n```\n\n## File: navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/DialogNavigatorDestinationBuilder.kt\n```kotlin\n/*\n * Copyright 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.navigation.compose\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.window.DialogProperties\nimport androidx.navigation.NavBackStackEntry\nimport androidx.navigation.NavDestinationBuilder\nimport androidx.navigation.NavDestinationDsl\nimport androidx.navigation.NavType\nimport kotlin.jvm.JvmSuppressWildcards\nimport kotlin.reflect.KClass\nimport kotlin.reflect.KType\n\n/** DSL for constructing a new [DialogNavigator.Destination] */\n@NavDestinationDsl\npublic class DialogNavigatorDestinationBuilder :\n    NavDestinationBuilder<DialogNavigator.Destination> {\n\n    private val dialogNavigator: DialogNavigator\n    private val dialogProperties: DialogProperties\n    private val content: @Composable (NavBackStackEntry) -> Unit\n\n    /**\n     * DSL for constructing a new [DialogNavigator.Destination]\n     *\n     * @param navigator navigator used to create the destination\n     * @param route the destination's unique route\n     * @param dialogProperties properties that should be passed to\n     *   [androidx.compose.ui.window.Dialog].\n     * @param content composable for the destination\n     */\n    public constructor(\n        navigator: DialogNavigator,\n        route: String,\n        dialogProperties: DialogProperties,\n        content: @Composable (NavBackStackEntry) -> Unit,\n    ) : super(navigator, route) {\n        this.dialogNavigator = navigator\n        this.dialogProperties = dialogProperties\n        this.content = content\n    }\n\n    /**\n     * DSL for constructing a new [DialogNavigator.Destination]\n     *\n     * @param navigator navigator used to create the destination\n     * @param route the destination's unique route from a [KClass]\n     * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n     *   [NavType]. May be empty if [route] does not use custom NavTypes.\n     * @param dialogProperties properties that should be passed to\n     *   [androidx.compose.ui.window.Dialog].\n     * @param content composable for the destination\n     */\n    public constructor(\n        navigator: DialogNavigator,\n        route: KClass<*>,\n        typeMap: Map<KType, @JvmSuppressWildcards NavType<*>>,\n        dialogProperties: DialogProperties,\n        content: @Composable (NavBackStackEntry) -> Unit,\n    ) : super(navigator, route, typeMap) {\n        this.dialogNavigator = navigator\n        this.dialogProperties = dialogProperties\n        this.content = content\n    }\n\n    override fun instantiateDestination(): DialogNavigator.Destination {\n        return DialogNavigator.Destination(dialogNavigator, dialogProperties, content)\n    }\n}\n```\n\n## File: navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/NavBackStackEntryProvider.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@file:JvmName(\"NavBackStackEntryProviderKt\")\n\npackage androidx.navigation.compose\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.saveable.SaveableStateHolder\nimport androidx.lifecycle.SavedStateHandle\nimport androidx.lifecycle.ViewModel\nimport androidx.lifecycle.compose.LocalLifecycleOwner\nimport androidx.lifecycle.createSavedStateHandle\nimport androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner\nimport androidx.lifecycle.viewmodel.compose.viewModel\nimport androidx.navigation.NavBackStackEntry\nimport androidx.navigation.compose.internal.WeakReference\nimport androidx.navigation.compose.internal.randomUUID\nimport androidx.savedstate.compose.LocalSavedStateRegistryOwner\nimport kotlin.jvm.JvmName\n\n/**\n * Provides [this] [NavBackStackEntry] as [LocalViewModelStoreOwner], [LocalLifecycleOwner] and\n * [LocalSavedStateRegistryOwner] to the [content] and saves the [content]'s saveable states with\n * the given [saveableStateHolder].\n *\n * @param saveableStateHolder The [SaveableStateHolder] that holds the saved states. The same holder\n *   should be used for all [NavBackStackEntry]s in the encapsulating [Composable] and the holder\n *   should be hoisted.\n * @param content The content [Composable]\n */\n@Composable\npublic fun NavBackStackEntry.LocalOwnersProvider(\n    saveableStateHolder: SaveableStateHolder,\n    content: @Composable () -> Unit,\n) {\n    // This outer `CompositionLocalProvider` explicitly provides the owners from this\n    // `NavBackStackEntry` directly to the `SaveableStateProvider`. This prevents potential issues,\n    // such as in testing scenarios, where these owners might not be set.\n    CompositionLocalProvider(\n        LocalViewModelStoreOwner provides this,\n        LocalLifecycleOwner provides this,\n        LocalSavedStateRegistryOwner provides this,\n    ) {\n        saveableStateHolder.SaveableStateProvider {\n            // This inner `CompositionLocalProvider`, located inside the `SaveableStateProvider`\n            // lambda, ensures that the `content` composable receives the correct owners\n            // from this `NavBackStackEntry`. This layering prevents unintended owner overrides\n            // by `SaveableStateProvider` and ensures the destination content correctly interacts\n            // with its navigation-scoped owners.\n            CompositionLocalProvider(\n                LocalViewModelStoreOwner provides this,\n                LocalLifecycleOwner provides this,\n                LocalSavedStateRegistryOwner provides this,\n                content = content,\n            )\n        }\n    }\n}\n\n@Composable\nprivate fun SaveableStateHolder.SaveableStateProvider(content: @Composable () -> Unit) {\n    val viewModel = viewModel { BackStackEntryIdViewModel(createSavedStateHandle()) }\n    // Stash a reference to the SaveableStateHolder in the ViewModel so that\n    // it is available when the ViewModel is cleared, marking the permanent removal of this\n    // NavBackStackEntry from the back stack. Which, because of animations,\n    // only happens after this leaves composition. Which means we can't rely on\n    // DisposableEffect to clean up this reference (as it'll be cleaned up too early)\n    viewModel.saveableStateHolderRef = WeakReference(this)\n    SaveableStateProvider(viewModel.id, content)\n}\n\ninternal class BackStackEntryIdViewModel(handle: SavedStateHandle) : ViewModel() {\n\n    private val IdKey = \"SaveableStateHolder_BackStackEntryKey\"\n\n    // we create our own id for each back stack entry to support multiple entries of the same\n    // destination. this id will be restored by SavedStateHandle\n    val id: String = (handle.get<String>(IdKey) ?: randomUUID().also { handle.set(IdKey, it) })\n\n    lateinit var saveableStateHolderRef: WeakReference<SaveableStateHolder>\n\n    // onCleared will be called on the entries removed from the back stack. here we notify\n    // SaveableStateProvider that we should remove any state is had associated with this\n    // destination as it is no longer needed.\n    override fun onCleared() {\n        super.onCleared()\n        saveableStateHolderRef.get()?.removeState(id)\n        saveableStateHolderRef.clear()\n    }\n}\n```\n\n## File: navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/NavGraphBuilder.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.navigation.compose\n\nimport androidx.compose.animation.AnimatedContentScope\nimport androidx.compose.animation.AnimatedContentTransitionScope\nimport androidx.compose.animation.EnterTransition\nimport androidx.compose.animation.ExitTransition\nimport androidx.compose.animation.SizeTransform\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.window.DialogProperties\nimport androidx.navigation.NamedNavArgument\nimport androidx.navigation.NavBackStackEntry\nimport androidx.navigation.NavDeepLink\nimport androidx.navigation.NavGraph\nimport androidx.navigation.NavGraphBuilder\nimport androidx.navigation.NavType\nimport androidx.navigation.get\nimport kotlin.jvm.JvmSuppressWildcards\nimport kotlin.reflect.KClass\nimport kotlin.reflect.KType\n\n/**\n * Add the [Composable] to the [NavGraphBuilder]\n *\n * @param route route for the destination\n * @param arguments list of arguments to associate with destination\n * @param deepLinks list of deep links to associate with the destinations\n * @param content composable for the destination\n */\n@Deprecated(\n    message = \"Deprecated in favor of composable builder that supports AnimatedContent\",\n    level = DeprecationLevel.HIDDEN,\n)\npublic fun NavGraphBuilder.composable(\n    route: String,\n    arguments: List<NamedNavArgument> = emptyList(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    content: @Composable (NavBackStackEntry) -> Unit,\n) {\n    addDestination(\n        ComposeNavigator.Destination(provider[ComposeNavigator::class]) { entry -> content(entry) }\n            .apply {\n                this.route = route\n                arguments.forEach { (argumentName, argument) ->\n                    addArgument(argumentName, argument)\n                }\n                deepLinks.forEach { deepLink -> addDeepLink(deepLink) }\n            }\n    )\n}\n\n/**\n * Add the [Composable] to the [NavGraphBuilder]\n *\n * @param route route for the destination\n * @param arguments list of arguments to associate with destination\n * @param deepLinks list of deep links to associate with the destinations\n * @param enterTransition callback to determine the destination's enter transition\n * @param exitTransition callback to determine the destination's exit transition\n * @param popEnterTransition callback to determine the destination's popEnter transition\n * @param popExitTransition callback to determine the destination's popExit transition\n * @param content composable for the destination\n */\n@Deprecated(\n    message = \"Deprecated in favor of composable builder that supports sizeTransform\",\n    level = DeprecationLevel.HIDDEN,\n)\npublic fun NavGraphBuilder.composable(\n    route: String,\n    arguments: List<NamedNavArgument> = emptyList(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    enterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n        null,\n    exitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n        null,\n    popEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n        enterTransition,\n    popExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n        exitTransition,\n    content: @Composable AnimatedContentScope.(NavBackStackEntry) -> Unit,\n) {\n    destination(\n        ComposeNavigatorDestinationBuilder(provider[ComposeNavigator::class], route, content)\n            .apply {\n                arguments.forEach { (argumentName, argument) -> argument(argumentName, argument) }\n                deepLinks.forEach { deepLink -> deepLink(deepLink) }\n                this.enterTransition = enterTransition\n                this.exitTransition = exitTransition\n                this.popEnterTransition = popEnterTransition\n                this.popExitTransition = popExitTransition\n            }\n    )\n}\n\n/**\n * Add the [Composable] to the [NavGraphBuilder]\n *\n * @param route route for the destination\n * @param arguments list of arguments to associate with destination\n * @param deepLinks list of deep links to associate with the destinations\n * @param enterTransition callback to determine the destination's enter transition\n * @param exitTransition callback to determine the destination's exit transition\n * @param popEnterTransition callback to determine the destination's popEnter transition\n * @param popExitTransition callback to determine the destination's popExit transition\n * @param sizeTransform callback to determine the destination's sizeTransform.\n * @param content composable for the destination\n * @sample androidx.navigation.compose.samples.SizeTransformComposable\n */\npublic fun NavGraphBuilder.composable(\n    route: String,\n    arguments: List<NamedNavArgument> = emptyList(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    enterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n        null,\n    exitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n        null,\n    popEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n        enterTransition,\n    popExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n        exitTransition,\n    sizeTransform:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n        null,\n    content: @Composable AnimatedContentScope.(NavBackStackEntry) -> Unit,\n) {\n    destination(\n        ComposeNavigatorDestinationBuilder(provider[ComposeNavigator::class], route, content)\n            .apply {\n                arguments.forEach { (argumentName, argument) -> argument(argumentName, argument) }\n                deepLinks.forEach { deepLink -> deepLink(deepLink) }\n                this.enterTransition = enterTransition\n                this.exitTransition = exitTransition\n                this.popEnterTransition = popEnterTransition\n                this.popExitTransition = popExitTransition\n                this.sizeTransform = sizeTransform\n            }\n    )\n}\n\n/**\n * Add the [Composable] to the [NavGraphBuilder]\n *\n * @param T route from a [KClass] for the destination\n * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n *   [NavType]. May be empty if [T] does not use custom NavTypes.\n * @param deepLinks list of deep links to associate with the destinations\n * @param enterTransition callback to determine the destination's enter transition\n * @param exitTransition callback to determine the destination's exit transition\n * @param popEnterTransition callback to determine the destination's popEnter transition\n * @param popExitTransition callback to determine the destination's popExit transition\n * @param sizeTransform callback to determine the destination's sizeTransform.\n * @param content composable for the destination\n */\npublic inline fun <reified T : Any> NavGraphBuilder.composable(\n    typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    noinline enterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            EnterTransition?)? =\n        null,\n    noinline exitTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            ExitTransition?)? =\n        null,\n    noinline popEnterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            EnterTransition?)? =\n        enterTransition,\n    noinline popExitTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            ExitTransition?)? =\n        exitTransition,\n    noinline sizeTransform:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            SizeTransform?)? =\n        null,\n    noinline content: @Composable AnimatedContentScope.(NavBackStackEntry) -> Unit,\n) {\n    composable(\n        T::class,\n        typeMap,\n        deepLinks,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n        sizeTransform,\n        content,\n    )\n}\n\n/**\n * Add the [Composable] to the [NavGraphBuilder]\n *\n * @param route route from a [KClass] for the destination\n * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n *   [NavType]. May be empty if [route] does not use custom NavTypes.\n * @param deepLinks list of deep links to associate with the destinations\n * @param enterTransition callback to determine the destination's enter transition\n * @param exitTransition callback to determine the destination's exit transition\n * @param popEnterTransition callback to determine the destination's popEnter transition\n * @param popExitTransition callback to determine the destination's popExit transition\n * @param sizeTransform callback to determine the destination's sizeTransform.\n * @param content composable for the destination\n */\npublic fun <T : Any> NavGraphBuilder.composable(\n    route: KClass<T>,\n    typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    enterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            EnterTransition?)? =\n        null,\n    exitTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            ExitTransition?)? =\n        null,\n    popEnterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            EnterTransition?)? =\n        enterTransition,\n    popExitTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            ExitTransition?)? =\n        exitTransition,\n    sizeTransform:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            SizeTransform?)? =\n        null,\n    content: @Composable AnimatedContentScope.(NavBackStackEntry) -> Unit,\n) {\n    destination(\n        ComposeNavigatorDestinationBuilder(\n                provider[ComposeNavigator::class],\n                route,\n                typeMap,\n                content,\n            )\n            .apply {\n                deepLinks.forEach { deepLink -> deepLink(deepLink) }\n                this.enterTransition = enterTransition\n                this.exitTransition = exitTransition\n                this.popEnterTransition = popEnterTransition\n                this.popExitTransition = popExitTransition\n                this.sizeTransform = sizeTransform\n            }\n    )\n}\n\n/**\n * Construct a nested [NavGraph]\n *\n * @sample androidx.navigation.compose.samples.NavWithArgsInNestedGraph\n * @param startDestination the starting destination's route for this NavGraph\n * @param route the destination's unique route\n * @param arguments list of arguments to associate with destination\n * @param deepLinks list of deep links to associate with the destinations\n * @param builder the builder used to construct the graph\n */\n@Deprecated(\n    message = \"Deprecated in favor of navigation builder that supports AnimatedContent\",\n    level = DeprecationLevel.HIDDEN,\n)\npublic fun NavGraphBuilder.navigation(\n    startDestination: String,\n    route: String,\n    arguments: List<NamedNavArgument> = emptyList(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    navigation(startDestination, route, arguments, deepLinks, null, null, null, null, null, builder)\n}\n\n/**\n * Construct a nested [NavGraph]\n *\n * @param startDestination the starting destination's route for this NavGraph\n * @param route the destination's unique route\n * @param arguments list of arguments to associate with destination\n * @param deepLinks list of deep links to associate with the destinations\n * @param enterTransition callback to define enter transitions for destination in this NavGraph\n * @param exitTransition callback to define exit transitions for destination in this NavGraph\n * @param popEnterTransition callback to define pop enter transitions for destination in this\n *   NavGraph\n * @param popExitTransition callback to define pop exit transitions for destination in this NavGraph\n * @param builder the builder used to construct the graph\n * @return the newly constructed nested NavGraph\n */\n@Deprecated(\n    message = \"Deprecated in favor of navigation builder that supports sizeTransform\",\n    level = DeprecationLevel.HIDDEN,\n)\npublic fun NavGraphBuilder.navigation(\n    startDestination: String,\n    route: String,\n    arguments: List<NamedNavArgument> = emptyList(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    enterTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n        null,\n    exitTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n        null,\n    popEnterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n        enterTransition,\n    popExitTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n        exitTransition,\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    navigation(\n        startDestination,\n        route,\n        arguments,\n        deepLinks,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n        null,\n        builder,\n    )\n}\n\n/**\n * Construct a nested [NavGraph]\n *\n * @param startDestination the starting destination's route for this NavGraph\n * @param route the destination's unique route\n * @param arguments list of arguments to associate with destination\n * @param deepLinks list of deep links to associate with the destinations\n * @param enterTransition callback to define enter transitions for destination in this NavGraph\n * @param exitTransition callback to define exit transitions for destination in this NavGraph\n * @param popEnterTransition callback to define pop enter transitions for destination in this\n *   NavGraph\n * @param popExitTransition callback to define pop exit transitions for destination in this NavGraph\n * @param sizeTransform callback to define the size transform for destinations in this NavGraph\n * @param builder the builder used to construct the graph\n * @return the newly constructed nested NavGraph\n */\npublic fun NavGraphBuilder.navigation(\n    startDestination: String,\n    route: String,\n    arguments: List<NamedNavArgument> = emptyList(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    enterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n        null,\n    exitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n        null,\n    popEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition?)? =\n        enterTransition,\n    popExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition?)? =\n        exitTransition,\n    sizeTransform:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n        null,\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    addDestination(\n        NavGraphBuilder(provider, startDestination, route).apply(builder).build().apply {\n            arguments.forEach { (argumentName, argument) -> addArgument(argumentName, argument) }\n            deepLinks.forEach { deepLink -> addDeepLink(deepLink) }\n            if (this is ComposeNavGraphNavigator.ComposeNavGraph) {\n                this.enterTransition = enterTransition\n                this.exitTransition = exitTransition\n                this.popEnterTransition = popEnterTransition\n                this.popExitTransition = popExitTransition\n                this.sizeTransform = sizeTransform\n            }\n        }\n    )\n}\n\n/**\n * Construct a nested [NavGraph]\n *\n * @param T the destination's unique route from a KClass\n * @param startDestination the starting destination's route from [KClass] for this NavGraph\n * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n *   [NavType]. May be empty if [T] does not use custom NavTypes.\n * @param deepLinks list of deep links to associate with the destinations\n * @param enterTransition callback to define enter transitions for destination in this NavGraph\n * @param exitTransition callback to define exit transitions for destination in this NavGraph\n * @param popEnterTransition callback to define pop enter transitions for destination in this\n *   NavGraph\n * @param popExitTransition callback to define pop exit transitions for destination in this NavGraph\n * @param sizeTransform callback to define the size transform for destinations in this NavGraph\n * @param builder the builder used to construct the graph\n * @return the newly constructed nested NavGraph\n * @sample androidx.navigation.compose.samples.SizeTransformNav\n */\npublic inline fun <reified T : Any> NavGraphBuilder.navigation(\n    startDestination: KClass<*>,\n    typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    noinline enterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            EnterTransition?)? =\n        null,\n    noinline exitTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            ExitTransition?)? =\n        null,\n    noinline popEnterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            EnterTransition?)? =\n        enterTransition,\n    noinline popExitTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            ExitTransition?)? =\n        exitTransition,\n    noinline sizeTransform:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            SizeTransform?)? =\n        null,\n    noinline builder: NavGraphBuilder.() -> Unit,\n) {\n    navigation(\n        startDestination,\n        T::class,\n        typeMap,\n        deepLinks,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n        sizeTransform,\n        builder,\n    )\n}\n\n/**\n * Construct a nested [NavGraph]\n *\n * @param route the destination's unique route from a KClass\n * @param startDestination the starting destination's route from [KClass] for this NavGraph\n * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n *   [NavType]. May be empty if [route] does not use custom NavTypes.\n * @param deepLinks list of deep links to associate with the destinations\n * @param enterTransition callback to define enter transitions for destination in this NavGraph\n * @param exitTransition callback to define exit transitions for destination in this NavGraph\n * @param popEnterTransition callback to define pop enter transitions for destination in this\n *   NavGraph\n * @param popExitTransition callback to define pop exit transitions for destination in this NavGraph\n * @param sizeTransform callback to define the size transform for destinations in this NavGraph\n * @param builder the builder used to construct the graph\n * @return the newly constructed nested NavGraph\n */\npublic fun <T : Any> NavGraphBuilder.navigation(\n    startDestination: KClass<*>,\n    route: KClass<T>,\n    typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    enterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            EnterTransition?)? =\n        null,\n    exitTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            ExitTransition?)? =\n        null,\n    popEnterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            EnterTransition?)? =\n        enterTransition,\n    popExitTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            ExitTransition?)? =\n        exitTransition,\n    sizeTransform:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            SizeTransform?)? =\n        null,\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    addDestination(\n        NavGraphBuilder(provider, startDestination, route, typeMap).apply(builder).build().apply {\n            deepLinks.forEach { deepLink -> addDeepLink(deepLink) }\n            if (this is ComposeNavGraphNavigator.ComposeNavGraph) {\n                this.enterTransition = enterTransition\n                this.exitTransition = exitTransition\n                this.popEnterTransition = popEnterTransition\n                this.popExitTransition = popExitTransition\n                this.sizeTransform = sizeTransform\n            }\n        }\n    )\n}\n\n/**\n * Construct a nested [NavGraph]\n *\n * @param T the destination's unique route from a KClass\n * @param startDestination the starting destination's route from an Object for this NavGraph\n * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n *   [NavType]. May be empty if [T] does not use custom NavTypes.\n * @param deepLinks list of deep links to associate with the destinations\n * @param enterTransition callback to define enter transitions for destination in this NavGraph\n * @param exitTransition callback to define exit transitions for destination in this NavGraph\n * @param popEnterTransition callback to define pop enter transitions for destination in this\n *   NavGraph\n * @param popExitTransition callback to define pop exit transitions for destination in this NavGraph\n * @param sizeTransform callback to define the size transform for destinations in this NavGraph\n * @param builder the builder used to construct the graph\n * @return the newly constructed nested NavGraph\n */\npublic inline fun <reified T : Any> NavGraphBuilder.navigation(\n    startDestination: Any,\n    typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    noinline enterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            EnterTransition?)? =\n        null,\n    noinline exitTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            ExitTransition?)? =\n        null,\n    noinline popEnterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            EnterTransition?)? =\n        enterTransition,\n    noinline popExitTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            ExitTransition?)? =\n        exitTransition,\n    noinline sizeTransform:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            SizeTransform?)? =\n        null,\n    noinline builder: NavGraphBuilder.() -> Unit,\n) {\n    navigation(\n        startDestination,\n        T::class,\n        typeMap,\n        deepLinks,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n        sizeTransform,\n        builder,\n    )\n}\n\n/**\n * Construct a nested [NavGraph]\n *\n * @param route the destination's unique route from a KClass\n * @param startDestination the starting destination's route from an Object for this NavGraph\n * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n *   [NavType]. May be empty if [route] does not use custom NavTypes.\n * @param deepLinks list of deep links to associate with the destinations\n * @param enterTransition callback to define enter transitions for destination in this NavGraph\n * @param exitTransition callback to define exit transitions for destination in this NavGraph\n * @param popEnterTransition callback to define pop enter transitions for destination in this\n *   NavGraph\n * @param popExitTransition callback to define pop exit transitions for destination in this NavGraph\n * @param sizeTransform callback to define the size transform for destinations in this NavGraph\n * @param builder the builder used to construct the graph\n * @return the newly constructed nested NavGraph\n */\npublic fun <T : Any> NavGraphBuilder.navigation(\n    startDestination: Any,\n    route: KClass<T>,\n    typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    enterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            EnterTransition?)? =\n        null,\n    exitTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            ExitTransition?)? =\n        null,\n    popEnterTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            EnterTransition?)? =\n        enterTransition,\n    popExitTransition:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            ExitTransition?)? =\n        exitTransition,\n    sizeTransform:\n        (AnimatedContentTransitionScope<NavBackStackEntry>.() -> @JvmSuppressWildcards\n            SizeTransform?)? =\n        null,\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    addDestination(\n        NavGraphBuilder(provider, startDestination, route, typeMap).apply(builder).build().apply {\n            deepLinks.forEach { deepLink -> addDeepLink(deepLink) }\n            if (this is ComposeNavGraphNavigator.ComposeNavGraph) {\n                this.enterTransition = enterTransition\n                this.exitTransition = exitTransition\n                this.popEnterTransition = popEnterTransition\n                this.popExitTransition = popExitTransition\n                this.sizeTransform = sizeTransform\n            }\n        }\n    )\n}\n\n/**\n * Add the [Composable] to the [NavGraphBuilder] that will be hosted within a\n * [androidx.compose.ui.window.Dialog]. This is suitable only when this dialog represents a separate\n * screen in your app that needs its own lifecycle and saved state, independent of any other\n * destination in your navigation graph. For use cases such as `AlertDialog`, you should use those\n * APIs directly in the [composable] destination that wants to show that dialog.\n *\n * @param route route for the destination\n * @param arguments list of arguments to associate with destination\n * @param deepLinks list of deep links to associate with the destinations\n * @param dialogProperties properties that should be passed to [androidx.compose.ui.window.Dialog].\n * @param content composable content for the destination that will be hosted within the Dialog\n */\npublic fun NavGraphBuilder.dialog(\n    route: String,\n    arguments: List<NamedNavArgument> = emptyList(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    dialogProperties: DialogProperties = DialogProperties(),\n    content: @Composable (NavBackStackEntry) -> Unit,\n) {\n    destination(\n        DialogNavigatorDestinationBuilder(\n                provider[DialogNavigator::class],\n                route,\n                dialogProperties,\n                content,\n            )\n            .apply {\n                arguments.forEach { (argumentName, argument) -> argument(argumentName, argument) }\n                deepLinks.forEach { deepLink -> deepLink(deepLink) }\n            }\n    )\n}\n\n/**\n * Add the [Composable] to the [NavGraphBuilder] that will be hosted within a\n * [androidx.compose.ui.window.Dialog]. This is suitable only when this dialog represents a separate\n * screen in your app that needs its own lifecycle and saved state, independent of any other\n * destination in your navigation graph. For use cases such as `AlertDialog`, you should use those\n * APIs directly in the [composable] destination that wants to show that dialog.\n *\n * @param T route from a KClass for the destination\n * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n *   [NavType]. May be empty if [T] does not use custom NavTypes.\n * @param deepLinks list of deep links to associate with the destinations\n * @param dialogProperties properties that should be passed to [androidx.compose.ui.window.Dialog].\n * @param content composable content for the destination that will be hosted within the Dialog\n */\npublic inline fun <reified T : Any> NavGraphBuilder.dialog(\n    typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    dialogProperties: DialogProperties = DialogProperties(),\n    noinline content: @Composable (NavBackStackEntry) -> Unit,\n) {\n    dialog(T::class, typeMap, deepLinks, dialogProperties, content)\n}\n\n/**\n * Add the [Composable] to the [NavGraphBuilder] that will be hosted within a\n * [androidx.compose.ui.window.Dialog]. This is suitable only when this dialog represents a separate\n * screen in your app that needs its own lifecycle and saved state, independent of any other\n * destination in your navigation graph. For use cases such as `AlertDialog`, you should use those\n * APIs directly in the [composable] destination that wants to show that dialog.\n *\n * @param route route from [KClass] of [T] for the destination\n * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n *   [NavType]. May be empty if [route] does not use custom NavTypes.\n * @param deepLinks list of deep links to associate with the destinations\n * @param dialogProperties properties that should be passed to [androidx.compose.ui.window.Dialog].\n * @param content composable content for the destination that will be hosted within the Dialog\n */\npublic fun <T : Any> NavGraphBuilder.dialog(\n    route: KClass<T>,\n    typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap(),\n    deepLinks: List<NavDeepLink> = emptyList(),\n    dialogProperties: DialogProperties = DialogProperties(),\n    content: @Composable (NavBackStackEntry) -> Unit,\n) {\n    destination(\n        DialogNavigatorDestinationBuilder(\n                provider[DialogNavigator::class],\n                route,\n                typeMap,\n                dialogProperties,\n                content,\n            )\n            .apply { deepLinks.forEach { deepLink -> deepLink(deepLink) } }\n    )\n}\n```\n\n## File: navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/NavHost.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.navigation.compose\n\nimport androidx.collection.mutableObjectFloatMapOf\nimport androidx.compose.animation.AnimatedContent\nimport androidx.compose.animation.AnimatedContentTransitionScope\nimport androidx.compose.animation.ContentTransform\nimport androidx.compose.animation.EnterTransition\nimport androidx.compose.animation.ExitTransition\nimport androidx.compose.animation.SizeTransform\nimport androidx.compose.animation.core.SeekableTransitionState\nimport androidx.compose.animation.core.animate\nimport androidx.compose.animation.core.rememberTransition\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.togetherWith\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisposableEffect\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.collectAsState\nimport androidx.compose.runtime.derivedStateOf\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.saveable.rememberSaveableStateHolder\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.lifecycle.compose.LocalLifecycleOwner\nimport androidx.lifecycle.viewmodel.compose.LocalViewModelStoreOwner\nimport androidx.navigation.NavBackStackEntry\nimport androidx.navigation.NavDestination\nimport androidx.navigation.NavDestination.Companion.hierarchy\nimport androidx.navigation.NavGraph\nimport androidx.navigation.NavGraphBuilder\nimport androidx.navigation.NavHostController\nimport androidx.navigation.NavType\nimport androidx.navigation.Navigator\nimport androidx.navigation.compose.internal.DefaultNavTransitions\nimport androidx.navigation.compose.internal.PredictiveBackHandler\nimport androidx.navigation.createGraph\nimport androidx.navigation.get\nimport kotlin.coroutines.cancellation.CancellationException\nimport kotlin.jvm.JvmSuppressWildcards\nimport kotlin.reflect.KClass\nimport kotlin.reflect.KType\nimport kotlinx.coroutines.launch\n\n/**\n * Provides a place in the Compose hierarchy for self contained navigation to occur.\n *\n * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from\n * the provided [navController].\n *\n * The builder passed into this method is [remember]ed. This means that for this NavHost, the\n * contents of the builder cannot be changed.\n *\n * @sample androidx.navigation.compose.samples.NavScaffold\n * @param navController the navController for this host\n * @param startDestination the route for the start destination\n * @param modifier The modifier to be applied to the layout.\n * @param route the route for the graph\n * @param builder the builder used to construct the graph\n */\n@Deprecated(\n    message = \"Deprecated in favor of NavHost that supports AnimatedContent\",\n    level = DeprecationLevel.HIDDEN,\n)\n@Composable\npublic fun NavHost(\n    navController: NavHostController,\n    startDestination: String,\n    modifier: Modifier = Modifier,\n    route: String? = null,\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    NavHost(\n        navController,\n        remember(route, startDestination, builder) {\n            navController.createGraph(startDestination, route, builder)\n        },\n        modifier,\n    )\n}\n\n/**\n * Provides a place in the Compose hierarchy for self contained navigation to occur.\n *\n * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from\n * the provided [navController].\n *\n * The builder passed into this method is [remember]ed. This means that for this NavHost, the\n * contents of the builder cannot be changed.\n *\n * @param navController the navController for this host\n * @param startDestination the route for the start destination\n * @param modifier The modifier to be applied to the layout.\n * @param contentAlignment The [Alignment] of the [AnimatedContent]\n * @param route the route for the graph\n * @param enterTransition callback to define enter transitions for destination in this host\n * @param exitTransition callback to define exit transitions for destination in this host\n * @param popEnterTransition callback to define popEnter transitions for destination in this host\n * @param popExitTransition callback to define popExit transitions for destination in this host\n * @param builder the builder used to construct the graph\n */\n@Deprecated(\n    message = \"Deprecated in favor of NavHost that supports sizeTransform\",\n    level = DeprecationLevel.HIDDEN,\n)\n@Composable\npublic fun NavHost(\n    navController: NavHostController,\n    startDestination: String,\n    modifier: Modifier = Modifier,\n    contentAlignment: Alignment = Alignment.TopStart,\n    route: String? = null,\n    enterTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        DefaultNavTransitions.enterTransition,\n    exitTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        DefaultNavTransitions.exitTransition,\n    popEnterTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        enterTransition,\n    popExitTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        exitTransition,\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    NavHost(\n        navController,\n        remember(route, startDestination, builder) {\n            navController.createGraph(startDestination, route, builder)\n        },\n        modifier,\n        contentAlignment,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n    )\n}\n\n/**\n * Provides a place in the Compose hierarchy for self contained navigation to occur.\n *\n * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from\n * the provided [navController].\n *\n * The builder passed into this method is [remember]ed. This means that for this NavHost, the\n * contents of the builder cannot be changed.\n *\n * @param navController the navController for this host\n * @param startDestination the route for the start destination\n * @param modifier The modifier to be applied to the layout.\n * @param contentAlignment The [Alignment] of the [AnimatedContent]\n * @param route the route for the graph\n * @param enterTransition callback to define enter transitions for destination in this host\n * @param exitTransition callback to define exit transitions for destination in this host\n * @param popEnterTransition callback to define popEnter transitions for destination in this host\n * @param popExitTransition callback to define popExit transitions for destination in this host\n * @param sizeTransform callback to define the size transform for destinations in this host\n * @param builder the builder used to construct the graph\n */\n@Deprecated(\n    message =\n        \"Deprecated in favor of NavHost that supports predictivePopEnterTransition and predictivePopExitTransition\",\n    level = DeprecationLevel.HIDDEN,\n)\n@Composable\npublic fun NavHost(\n    navController: NavHostController,\n    startDestination: String,\n    modifier: Modifier = Modifier,\n    contentAlignment: Alignment = Alignment.TopStart,\n    route: String? = null,\n    enterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        DefaultNavTransitions.enterTransition,\n    exitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        DefaultNavTransitions.exitTransition,\n    popEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        enterTransition,\n    popExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        exitTransition,\n    sizeTransform:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n        DefaultNavTransitions.sizeTransform,\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    NavHost(\n        navController,\n        startDestination,\n        modifier,\n        contentAlignment,\n        route,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n        sizeTransform = sizeTransform,\n        builder = builder,\n    )\n}\n\n/**\n * Provides a place in the Compose hierarchy for self contained navigation to occur.\n *\n * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from\n * the provided [navController].\n *\n * The builder passed into this method is [remember]ed. This means that for this NavHost, the\n * contents of the builder cannot be changed.\n *\n * @param navController the navController for this host\n * @param startDestination the route for the start destination\n * @param modifier The modifier to be applied to the layout.\n * @param contentAlignment The [Alignment] of the [AnimatedContent]\n * @param route the route for the graph\n * @param enterTransition callback to define enter transitions for destination in this host\n * @param exitTransition callback to define exit transitions for destination in this host\n * @param popEnterTransition callback to define popEnter transitions for destination in this host\n * @param popExitTransition callback to define popExit transitions for destination in this host\n * @param predictivePopEnterTransition callback to define predictivePopEnter transitions for\n *   destination in this host\n * @param predictivePopExitTransition callback to define predictivePopExit transitions for\n *   destination in this host\n * @param sizeTransform callback to define the size transform for destinations in this host\n * @param builder the builder used to construct the graph\n */\n@Composable\npublic fun NavHost(\n    navController: NavHostController,\n    startDestination: String,\n    modifier: Modifier = Modifier,\n    contentAlignment: Alignment = Alignment.TopStart,\n    route: String? = null,\n    enterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        DefaultNavTransitions.enterTransition,\n    exitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        DefaultNavTransitions.exitTransition,\n    popEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        enterTransition,\n    popExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        exitTransition,\n    predictivePopEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> EnterTransition) =\n        DefaultNavTransitions.predictivePopEnterTransition,\n    predictivePopExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> ExitTransition) =\n        DefaultNavTransitions.predictivePopExitTransition,\n    sizeTransform:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n        DefaultNavTransitions.sizeTransform,\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    NavHost(\n        navController,\n        remember(route, startDestination, builder) {\n            navController.createGraph(startDestination, route, builder)\n        },\n        modifier,\n        contentAlignment,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n        predictivePopEnterTransition,\n        predictivePopExitTransition,\n        sizeTransform,\n    )\n}\n\n/**\n * Provides a place in the Compose hierarchy for self contained navigation to occur.\n *\n * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from\n * the provided [navController].\n *\n * The builder passed into this method is [remember]ed. This means that for this NavHost, the\n * contents of the builder cannot be changed.\n *\n * @param navController the navController for this host\n * @param startDestination the route from a [KClass] for the start destination\n * @param modifier The modifier to be applied to the layout.\n * @param contentAlignment The [Alignment] of the [AnimatedContent]\n * @param route the route from a [KClass] for the graph\n * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n *   [NavType]. May be empty if [route] does not use custom NavTypes.\n * @param enterTransition callback to define enter transitions for destination in this host\n * @param exitTransition callback to define exit transitions for destination in this host\n * @param popEnterTransition callback to define popEnter transitions for destination in this host\n * @param popExitTransition callback to define popExit transitions for destination in this host\n * @param sizeTransform callback to define the size transform for destinations in this host\n * @param builder the builder used to construct the graph\n */\n@Deprecated(\n    message =\n        \"Deprecated in favor of NavHost that supports predictivePopEnterTransition and predictivePopExitTransition\",\n    level = DeprecationLevel.HIDDEN,\n)\n@Composable\npublic fun NavHost(\n    navController: NavHostController,\n    startDestination: KClass<*>,\n    modifier: Modifier = Modifier,\n    contentAlignment: Alignment = Alignment.TopStart,\n    route: KClass<*>? = null,\n    typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap(),\n    enterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        DefaultNavTransitions.enterTransition,\n    exitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        DefaultNavTransitions.exitTransition,\n    popEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        enterTransition,\n    popExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        exitTransition,\n    sizeTransform:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n        DefaultNavTransitions.sizeTransform,\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    NavHost(\n        navController,\n        startDestination,\n        modifier,\n        contentAlignment,\n        route,\n        typeMap,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n        DefaultNavTransitions.predictivePopEnterTransition,\n        DefaultNavTransitions.predictivePopExitTransition,\n        sizeTransform,\n        builder,\n    )\n}\n\n/**\n * Provides a place in the Compose hierarchy for self contained navigation to occur.\n *\n * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from\n * the provided [navController].\n *\n * The builder passed into this method is [remember]ed. This means that for this NavHost, the\n * contents of the builder cannot be changed.\n *\n * @param navController the navController for this host\n * @param startDestination the route from a [KClass] for the start destination\n * @param modifier The modifier to be applied to the layout.\n * @param contentAlignment The [Alignment] of the [AnimatedContent]\n * @param route the route from a [KClass] for the graph\n * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n *   [NavType]. May be empty if [route] does not use custom NavTypes.\n * @param enterTransition callback to define enter transitions for destination in this host\n * @param exitTransition callback to define exit transitions for destination in this host\n * @param popEnterTransition callback to define popEnter transitions for destination in this host\n * @param popExitTransition callback to define popExit transitions for destination in this host\n * @param predictivePopEnterTransition callback to define predictivePopEnter transitions for\n *   destination in this host\n * @param predictivePopExitTransition callback to define predictivePopExit transitions for\n *   destination in this host\n * @param sizeTransform callback to define the size transform for destinations in this host\n * @param builder the builder used to construct the graph\n */\n@Composable\npublic fun NavHost(\n    navController: NavHostController,\n    startDestination: KClass<*>,\n    modifier: Modifier = Modifier,\n    contentAlignment: Alignment = Alignment.TopStart,\n    route: KClass<*>? = null,\n    typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap(),\n    enterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        DefaultNavTransitions.enterTransition,\n    exitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        DefaultNavTransitions.exitTransition,\n    popEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        enterTransition,\n    popExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        exitTransition,\n    predictivePopEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> EnterTransition) =\n        DefaultNavTransitions.predictivePopEnterTransition,\n    predictivePopExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> ExitTransition) =\n        DefaultNavTransitions.predictivePopExitTransition,\n    sizeTransform:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n        DefaultNavTransitions.sizeTransform,\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    NavHost(\n        navController,\n        remember(route, startDestination, builder) {\n            navController.createGraph(startDestination, route, typeMap, builder)\n        },\n        modifier,\n        contentAlignment,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n        predictivePopEnterTransition,\n        predictivePopExitTransition,\n        sizeTransform,\n    )\n}\n\n/**\n * Provides in place in the Compose hierarchy for self contained navigation to occur.\n *\n * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from\n * the provided [navController].\n *\n * The builder passed into this method is [remember]ed. This means that for this NavHost, the\n * contents of the builder cannot be changed.\n *\n * @param navController the navController for this host\n * @param startDestination the route from a an Object for the start destination\n * @param modifier The modifier to be applied to the layout.\n * @param contentAlignment The [Alignment] of the [AnimatedContent]\n * @param route the route from a [KClass] for the graph\n * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n *   [NavType]. May be empty if [route] does not use custom NavTypes.\n * @param enterTransition callback to define enter transitions for destination in this host\n * @param exitTransition callback to define exit transitions for destination in this host\n * @param popEnterTransition callback to define popEnter transitions for destination in this host\n * @param popExitTransition callback to define popExit transitions for destination in this host\n * @param sizeTransform callback to define the size transform for destinations in this host\n * @param builder the builder used to construct the graph\n */\n@Deprecated(\n    message =\n        \"Deprecated in favor of NavHost that supports predictivePopEnterTransition and predictivePopExitTransition\",\n    level = DeprecationLevel.HIDDEN,\n)\n@Composable\npublic fun NavHost(\n    navController: NavHostController,\n    startDestination: Any,\n    modifier: Modifier = Modifier,\n    contentAlignment: Alignment = Alignment.TopStart,\n    route: KClass<*>? = null,\n    typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap(),\n    enterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        DefaultNavTransitions.enterTransition,\n    exitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        DefaultNavTransitions.exitTransition,\n    popEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        enterTransition,\n    popExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        exitTransition,\n    sizeTransform:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n        DefaultNavTransitions.sizeTransform,\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    NavHost(\n        navController,\n        startDestination,\n        modifier,\n        contentAlignment,\n        route,\n        typeMap,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n        DefaultNavTransitions.predictivePopEnterTransition,\n        DefaultNavTransitions.predictivePopExitTransition,\n        sizeTransform,\n        builder,\n    )\n}\n\n/**\n * Provides in place in the Compose hierarchy for self contained navigation to occur.\n *\n * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from\n * the provided [navController].\n *\n * The builder passed into this method is [remember]ed. This means that for this NavHost, the\n * contents of the builder cannot be changed.\n *\n * @param navController the navController for this host\n * @param startDestination the route from a an Object for the start destination\n * @param modifier The modifier to be applied to the layout.\n * @param contentAlignment The [Alignment] of the [AnimatedContent]\n * @param route the route from a [KClass] for the graph\n * @param typeMap map of destination arguments' kotlin type [KType] to its respective custom\n *   [NavType]. May be empty if [route] does not use custom NavTypes.\n * @param enterTransition callback to define enter transitions for destination in this host\n * @param exitTransition callback to define exit transitions for destination in this host\n * @param popEnterTransition callback to define popEnter transitions for destination in this host\n * @param popExitTransition callback to define popExit transitions for destination in this host\n * @param predictivePopEnterTransition callback to define predictivePopEnter transitions for\n *   destination in this host\n * @param predictivePopExitTransition callback to define predictivePopExit transitions for\n *   destination in this host\n * @param sizeTransform callback to define the size transform for destinations in this host\n * @param builder the builder used to construct the graph\n */\n@Composable\npublic fun NavHost(\n    navController: NavHostController,\n    startDestination: Any,\n    modifier: Modifier = Modifier,\n    contentAlignment: Alignment = Alignment.TopStart,\n    route: KClass<*>? = null,\n    typeMap: Map<KType, @JvmSuppressWildcards NavType<*>> = emptyMap(),\n    enterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        DefaultNavTransitions.enterTransition,\n    exitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        DefaultNavTransitions.exitTransition,\n    popEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        enterTransition,\n    popExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        exitTransition,\n    predictivePopEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> EnterTransition) =\n        DefaultNavTransitions.predictivePopEnterTransition,\n    predictivePopExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> ExitTransition) =\n        DefaultNavTransitions.predictivePopExitTransition,\n    sizeTransform:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n        DefaultNavTransitions.sizeTransform,\n    builder: NavGraphBuilder.() -> Unit,\n) {\n    NavHost(\n        navController,\n        remember(route, startDestination, builder) {\n            navController.createGraph(startDestination, route, typeMap, builder)\n        },\n        modifier,\n        contentAlignment,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n        predictivePopEnterTransition,\n        predictivePopExitTransition,\n        sizeTransform,\n    )\n}\n\n/**\n * Provides in place in the Compose hierarchy for self contained navigation to occur.\n *\n * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from\n * the provided [navController].\n *\n * The graph passed into this method is [remember]ed. This means that for this NavHost, the graph\n * cannot be changed.\n *\n * @param navController the navController for this host\n * @param graph the graph for this host\n * @param modifier The modifier to be applied to the layout.\n */\n@Deprecated(\n    message = \"Deprecated in favor of NavHost that supports AnimatedContent\",\n    level = DeprecationLevel.HIDDEN,\n)\n@Composable\npublic fun NavHost(\n    navController: NavHostController,\n    graph: NavGraph,\n    modifier: Modifier = Modifier,\n): Unit = NavHost(navController, graph, modifier)\n\n/**\n * Provides a place in the Compose hierarchy for self contained navigation to occur.\n *\n * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from\n * the provided [navController].\n *\n * @param navController the navController for this host\n * @param graph the graph for this host\n * @param modifier The modifier to be applied to the layout.\n * @param contentAlignment The [Alignment] of the [AnimatedContent]\n * @param enterTransition callback to define enter transitions for destination in this host\n * @param exitTransition callback to define exit transitions for destination in this host\n * @param popEnterTransition callback to define popEnter transitions for destination in this host\n * @param popExitTransition callback to define popExit transitions for destination in this host\n */\n@Deprecated(\n    message = \"Deprecated in favor of NavHost that supports sizeTransform\",\n    level = DeprecationLevel.HIDDEN,\n)\n@Composable\npublic fun NavHost(\n    navController: NavHostController,\n    graph: NavGraph,\n    modifier: Modifier = Modifier,\n    contentAlignment: Alignment = Alignment.TopStart,\n    enterTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        DefaultNavTransitions.enterTransition,\n    exitTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        DefaultNavTransitions.exitTransition,\n    popEnterTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        enterTransition,\n    popExitTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        exitTransition,\n) {\n    NavHost(\n        navController,\n        graph,\n        modifier,\n        contentAlignment,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n        sizeTransform = null, // sizeTransform\n    )\n}\n\n/**\n * Provides a place in the Compose hierarchy for self contained navigation to occur.\n *\n * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from\n * the provided [navController].\n *\n * @param navController the navController for this host\n * @param graph the graph for this host\n * @param modifier The modifier to be applied to the layout.\n * @param contentAlignment The [Alignment] of the [AnimatedContent]\n * @param enterTransition callback to define enter transitions for destination in this host\n * @param exitTransition callback to define exit transitions for destination in this host\n * @param popEnterTransition callback to define popEnter transitions for destination in this host\n * @param popExitTransition callback to define popExit transitions for destination in this host\n * @param sizeTransform callback to define the size transform for destinations in this host\n */\n@Deprecated(\n    message =\n        \"Deprecated in favor of NavHost that supports predictivePopEnterTransition and predictivePopExitTransition\",\n    level = DeprecationLevel.HIDDEN,\n)\n@Composable\npublic fun NavHost(\n    navController: NavHostController,\n    graph: NavGraph,\n    modifier: Modifier = Modifier,\n    contentAlignment: Alignment = Alignment.TopStart,\n    enterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        DefaultNavTransitions.enterTransition,\n    exitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        DefaultNavTransitions.exitTransition,\n    popEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        enterTransition,\n    popExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        exitTransition,\n    sizeTransform:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n        DefaultNavTransitions.sizeTransform,\n) {\n    NavHost(\n        navController,\n        graph,\n        modifier,\n        contentAlignment,\n        enterTransition,\n        exitTransition,\n        popEnterTransition,\n        popExitTransition,\n        DefaultNavTransitions.predictivePopEnterTransition,\n        DefaultNavTransitions.predictivePopExitTransition,\n        sizeTransform,\n    )\n}\n\n/**\n * Provides a place in the Compose hierarchy for self contained navigation to occur.\n *\n * Once this is called, any Composable within the given [NavGraphBuilder] can be navigated to from\n * the provided [navController].\n *\n * @param navController the navController for this host\n * @param graph the graph for this host\n * @param modifier The modifier to be applied to the layout.\n * @param contentAlignment The [Alignment] of the [AnimatedContent]\n * @param enterTransition callback to define enter transitions for destination in this host\n * @param exitTransition callback to define exit transitions for destination in this host\n * @param popEnterTransition callback to define popEnter transitions for destination in this host\n * @param popExitTransition callback to define popExit transitions for destination in this host\n * @param predictivePopEnterTransition callback to define predictivePopEnter transitions for\n *   destination in this host\n * @param predictivePopExitTransition callback to define predictivePopExit transitions for\n *   destination in this host\n * @param sizeTransform callback to define the size transform for destinations in this host\n */\n@Composable\npublic fun NavHost(\n    navController: NavHostController,\n    graph: NavGraph,\n    modifier: Modifier = Modifier,\n    contentAlignment: Alignment = Alignment.TopStart,\n    enterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        DefaultNavTransitions.enterTransition,\n    exitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        DefaultNavTransitions.exitTransition,\n    popEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) =\n        enterTransition,\n    popExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) =\n        exitTransition,\n    predictivePopEnterTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> EnterTransition) =\n        DefaultNavTransitions.predictivePopEnterTransition,\n    predictivePopExitTransition:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> ExitTransition) =\n        DefaultNavTransitions.predictivePopExitTransition,\n    sizeTransform:\n        (@JvmSuppressWildcards\n        AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n        DefaultNavTransitions.sizeTransform,\n) {\n\n    val lifecycleOwner = LocalLifecycleOwner.current\n    val viewModelStoreOwner =\n        checkNotNull(LocalViewModelStoreOwner.current) {\n            \"NavHost requires a ViewModelStoreOwner to be provided via LocalViewModelStoreOwner\"\n        }\n\n    navController.setViewModelStore(viewModelStoreOwner.viewModelStore)\n\n    // Then set the graph\n    navController.graph = graph\n\n    // Find the ComposeNavigator, returning early if it isn't found\n    // (such as is the case when using TestNavHostController)\n    val composeNavigator =\n        navController.navigatorProvider.get<Navigator<out NavDestination>>(ComposeNavigator.NAME)\n            as? ComposeNavigator ?: return\n\n    val currentBackStack by composeNavigator.backStack.collectAsState()\n\n    var progress by remember { mutableFloatStateOf(0f) }\n    var inPredictiveBack by remember { mutableStateOf(false) }\n    var swipeEdge by remember { mutableIntStateOf(0) }\n    PredictiveBackHandler(currentBackStack.size > 1) { backEvent ->\n        // This block handles the three phases of a predictive back gesture:\n        // 1. OnStarted: When the gesture begins.\n        // 2. OnProgressed: As the user drags their finger.\n        // 3. OnCompleted or OnCancelled: When the gesture finishes or is cancelled.\n        //\n        // Always guard with `currentBackStack.size > 1`:\n        // If `enabled` becomes stale (set false mid-frame while a gesture is in-flight),\n        // these checks prevent IndexOutOfBounds when accessing the stack.\n\n        var currentBackStackEntry: NavBackStackEntry? = null\n\n        // --- OnStarted ---\n        if (currentBackStack.size > 1) {\n            progress = 0f\n            currentBackStackEntry = currentBackStack.lastOrNull()\n            composeNavigator.prepareForTransition(currentBackStackEntry!!)\n            val previousEntry = currentBackStack[currentBackStack.size - 2]\n            composeNavigator.prepareForTransition(previousEntry)\n        }\n        try {\n            backEvent.collect {\n                // --- OnProgressed ---\n                if (currentBackStack.size > 1) {\n                    inPredictiveBack = true\n                    progress = it.progress\n                    swipeEdge = it.swipeEdge\n                }\n            }\n            // --- OnCompleted ---\n            if (currentBackStack.size > 1) {\n                inPredictiveBack = false\n                composeNavigator.popBackStack(currentBackStackEntry!!, false)\n            }\n        } catch (_: CancellationException) {\n            // --- OnCancelled ---\n            if (currentBackStack.size > 1) {\n                inPredictiveBack = false\n            }\n        }\n    }\n\n    DisposableEffect(lifecycleOwner) {\n        // Setup the navController with proper owners\n        navController.setLifecycleOwner(lifecycleOwner)\n        onDispose {}\n    }\n\n    val saveableStateHolder = rememberSaveableStateHolder()\n\n    val allVisibleEntries by navController.visibleEntries.collectAsState()\n\n    // Intercept back only when there's a destination to pop\n    val visibleEntries by remember {\n        derivedStateOf {\n            allVisibleEntries.filter { entry ->\n                entry.destination.navigatorName == ComposeNavigator.NAME\n            }\n        }\n    }\n\n    val backStackEntry: NavBackStackEntry? = visibleEntries.lastOrNull()\n\n    val zIndices = remember { mutableObjectFloatMapOf<String>() }\n\n    if (backStackEntry != null) {\n        val finalEnter: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = {\n            val targetDestination = targetState.destination as ComposeNavigator.Destination\n\n            if (inPredictiveBack) {\n                targetDestination.hierarchy.firstNotNullOfOrNull { destination ->\n                    destination.createPredictivePopEnterTransition(this, swipeEdge)\n                } ?: predictivePopEnterTransition.invoke(this, swipeEdge)\n            } else if (composeNavigator.isPop.value) {\n                targetDestination.hierarchy.firstNotNullOfOrNull { destination ->\n                    destination.createPopEnterTransition(this)\n                } ?: popEnterTransition.invoke(this)\n            } else {\n                targetDestination.hierarchy.firstNotNullOfOrNull { destination ->\n                    destination.createEnterTransition(this)\n                } ?: enterTransition.invoke(this)\n            }\n        }\n\n        val finalExit: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = {\n            val initialDestination = initialState.destination as ComposeNavigator.Destination\n\n            if (inPredictiveBack) {\n                initialDestination.hierarchy.firstNotNullOfOrNull { destination ->\n                    destination.createPredictivePopExitTransition(this, swipeEdge)\n                } ?: predictivePopExitTransition.invoke(this, swipeEdge)\n            } else if (composeNavigator.isPop.value) {\n                initialDestination.hierarchy.firstNotNullOfOrNull { destination ->\n                    destination.createPopExitTransition(this)\n                } ?: popExitTransition.invoke(this)\n            } else {\n                initialDestination.hierarchy.firstNotNullOfOrNull { destination ->\n                    destination.createExitTransition(this)\n                } ?: exitTransition.invoke(this)\n            }\n        }\n\n        val finalSizeTransform:\n            AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform? =\n            {\n                val targetDestination = targetState.destination as ComposeNavigator.Destination\n\n                targetDestination.hierarchy.firstNotNullOfOrNull { destination ->\n                    destination.createSizeTransform(this)\n                } ?: sizeTransform?.invoke(this)\n            }\n\n        DisposableEffect(true) {\n            onDispose {\n                visibleEntries.forEach { entry -> composeNavigator.onTransitionComplete(entry) }\n            }\n        }\n\n        val transitionState = remember {\n            // The state returned here cannot be nullable cause it produces the input of the\n            // transitionSpec passed into the AnimatedContent and that must match the non-nullable\n            // scope exposed by the transitions on the NavHost and composable APIs.\n            SeekableTransitionState(backStackEntry)\n        }\n\n        val transition = rememberTransition(transitionState, label = \"entry\")\n\n        if (inPredictiveBack) {\n            LaunchedEffect(progress) {\n                // Update transition progress safely (same guard against stale enabled state).\n                if (currentBackStack.size > 1) {\n                    val previousEntry = currentBackStack[currentBackStack.size - 2]\n                    transitionState.seekTo(progress, previousEntry)\n                }\n            }\n        } else {\n            LaunchedEffect(backStackEntry) {\n                // This ensures we don't animate after the back gesture is cancelled and we\n                // are already on the current state\n                if (transitionState.currentState != backStackEntry) {\n                    transitionState.animateTo(backStackEntry)\n                } else {\n                    // convert from nanoseconds to milliseconds\n                    val totalDuration = transition.totalDurationNanos / 1000000\n                    // When the predictive back gesture is cancel, we need to manually animate\n                    // the SeekableTransitionState from where it left off, to zero and then\n                    // snapTo the final position.\n                    animate(\n                        transitionState.fraction,\n                        0f,\n                        animationSpec = tween((transitionState.fraction * totalDuration).toInt()),\n                    ) { value, _ ->\n                        this@LaunchedEffect.launch {\n                            if (value > 0) {\n                                // Seek the original transition back to the currentState\n                                transitionState.seekTo(value)\n                            }\n                            if (value == 0f) {\n                                // Once we animate to the start, we need to snap to the right state.\n                                transitionState.snapTo(backStackEntry)\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        transition.AnimatedContent(\n            modifier,\n            transitionSpec = {\n                // If the initialState of the AnimatedContent is not in visibleEntries, we are in\n                // a case where visible has cleared the old state for some reason, so instead of\n                // attempting to animate away from the initialState, we skip the animation.\n                if (initialState in visibleEntries) {\n                    val initialZIndex = zIndices.getOrPut(initialState.id) { 0f }\n                    val targetZIndex =\n                        when {\n                            targetState.id == initialState.id -> initialZIndex\n                            composeNavigator.isPop.value || inPredictiveBack -> initialZIndex - 1f\n                            else -> initialZIndex + 1f\n                        }\n                    zIndices[targetState.id] = targetZIndex\n\n                    ContentTransform(\n                        finalEnter(this),\n                        finalExit(this),\n                        targetZIndex,\n                        finalSizeTransform(this),\n                    )\n                } else {\n                    EnterTransition.None togetherWith ExitTransition.None\n                }\n            },\n            contentAlignment,\n            contentKey = { it.id },\n        ) {\n            // In some specific cases, such as clearing your back stack by changing your\n            // start destination, AnimatedContent can contain an entry that is no longer\n            // part of visible entries since it was cleared from the back stack and is not\n            // animating. In these cases the currentEntry will be null, and in those cases,\n            // AnimatedContent will just skip attempting to transition the old entry.\n            // See https://issuetracker.google.com/238686802\n            val isPredictiveBackCancelAnimation = transitionState.currentState == backStackEntry\n            val currentEntry =\n                if (inPredictiveBack || isPredictiveBackCancelAnimation) {\n                    // We have to do this because the previous entry does not show up in\n                    // visibleEntries\n                    // even if we prepare it above as part of onBackStackChangeStarted\n                    it\n                } else {\n                    visibleEntries.lastOrNull { entry -> it == entry }\n                }\n\n            // while in the scope of the composable, we provide the navBackStackEntry as the\n            // ViewModelStoreOwner and LifecycleOwner\n            currentEntry?.LocalOwnersProvider(saveableStateHolder) {\n                (currentEntry.destination as ComposeNavigator.Destination).content(\n                    this,\n                    currentEntry,\n                )\n            }\n        }\n        LaunchedEffect(transition.currentState, transition.targetState) {\n            if (\n                transition.currentState == transition.targetState &&\n                    // There is a race condition where previous animation has completed the new\n                    // animation has yet to start and there is a navigate call before this effect.\n                    // We need to make sure we are completing only when the start is settled on the\n                    // actual entry.\n                    (navController.currentBackStackEntry == null ||\n                        transition.targetState == backStackEntry)\n            ) {\n                visibleEntries.forEach { entry -> composeNavigator.onTransitionComplete(entry) }\n                zIndices.removeIf { key, _ -> key != transition.targetState.id }\n            }\n        }\n    }\n\n    val dialogNavigator =\n        navController.navigatorProvider.get<Navigator<out NavDestination>>(DialogNavigator.NAME)\n            as? DialogNavigator ?: return\n\n    // Show any dialog destinations\n    DialogHost(dialogNavigator)\n}\n\nprivate fun NavDestination.createEnterTransition(\n    scope: AnimatedContentTransitionScope<NavBackStackEntry>\n): EnterTransition? =\n    when (this) {\n        is ComposeNavigator.Destination -> this.enterTransition?.invoke(scope)\n        is ComposeNavGraphNavigator.ComposeNavGraph -> this.enterTransition?.invoke(scope)\n        else -> null\n    }\n\nprivate fun NavDestination.createExitTransition(\n    scope: AnimatedContentTransitionScope<NavBackStackEntry>\n): ExitTransition? =\n    when (this) {\n        is ComposeNavigator.Destination -> this.exitTransition?.invoke(scope)\n        is ComposeNavGraphNavigator.ComposeNavGraph -> this.exitTransition?.invoke(scope)\n        else -> null\n    }\n\nprivate fun NavDestination.createPopEnterTransition(\n    scope: AnimatedContentTransitionScope<NavBackStackEntry>\n): EnterTransition? =\n    when (this) {\n        is ComposeNavigator.Destination -> this.popEnterTransition?.invoke(scope)\n        is ComposeNavGraphNavigator.ComposeNavGraph -> this.popEnterTransition?.invoke(scope)\n        else -> null\n    }\n\nprivate fun NavDestination.createPopExitTransition(\n    scope: AnimatedContentTransitionScope<NavBackStackEntry>\n): ExitTransition? =\n    when (this) {\n        is ComposeNavigator.Destination -> this.popExitTransition?.invoke(scope)\n        is ComposeNavGraphNavigator.ComposeNavGraph -> this.popExitTransition?.invoke(scope)\n        else -> null\n    }\n\nprivate fun NavDestination.createPredictivePopEnterTransition(\n    scope: AnimatedContentTransitionScope<NavBackStackEntry>,\n    swipeEdge: Int,\n): EnterTransition? =\n    when (this) {\n        is ComposeNavigator.Destination ->\n            this.predictivePopEnterTransition?.invoke(scope, swipeEdge)\n        is ComposeNavGraphNavigator.ComposeNavGraph ->\n            this.predictivePopEnterTransition?.invoke(scope, swipeEdge)\n        else -> null\n    }\n\nprivate fun NavDestination.createPredictivePopExitTransition(\n    scope: AnimatedContentTransitionScope<NavBackStackEntry>,\n    swipeEdge: Int,\n): ExitTransition? =\n    when (this) {\n        is ComposeNavigator.Destination ->\n            this.predictivePopExitTransition?.invoke(scope, swipeEdge)\n        is ComposeNavGraphNavigator.ComposeNavGraph ->\n            this.predictivePopExitTransition?.invoke(scope, swipeEdge)\n        else -> null\n    }\n\nprivate fun NavDestination.createSizeTransform(\n    scope: AnimatedContentTransitionScope<NavBackStackEntry>\n): SizeTransform? =\n    when (this) {\n        is ComposeNavigator.Destination -> this.sizeTransform?.invoke(scope)\n        is ComposeNavGraphNavigator.ComposeNavGraph -> this.sizeTransform?.invoke(scope)\n        else -> null\n    }\n```\n\n## File: navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/NavHostController.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@file:JvmName(\"NavHostControllerKt\")\n@file:JvmMultifileClass\n\npackage androidx.navigation.compose\n\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.MutableState\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.collectAsState\nimport androidx.navigation.NavBackStackEntry\nimport androidx.navigation.NavController\nimport androidx.navigation.NavDestination\nimport androidx.navigation.NavHostController\nimport androidx.navigation.Navigator\nimport kotlin.jvm.JvmMultifileClass\nimport kotlin.jvm.JvmName\n\n/**\n * Gets the current navigation back stack entry as a [MutableState]. When the given navController\n * changes the back stack due to a [NavController.navigate] or [NavController.popBackStack] this\n * will trigger a recompose and return the top entry on the back stack.\n *\n * @return a mutable state of the current back stack entry\n */\n@Composable\npublic fun NavController.currentBackStackEntryAsState(): State<NavBackStackEntry?> {\n    return currentBackStackEntryFlow.collectAsState(null)\n}\n\n/**\n * Creates a NavHostController that handles the adding of the [ComposeNavigator] and\n * [DialogNavigator]. Additional [Navigator] instances can be passed through [navigators] to be\n * applied to the returned NavController. Note that each [Navigator] must be separately remembered\n * before being passed in here: any changes to those inputs will cause the NavController to be\n * recreated.\n *\n * @see NavHost\n */\n@Composable\npublic expect fun rememberNavController(\n    vararg navigators: Navigator<out NavDestination>\n): NavHostController\n```\n\n## File: navigation/navigation-compose/src/commonMain/kotlin/androidx/navigation/compose/internal/NavComposeUtils.kt\n```kotlin\n/*\n * Copyright 2025 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.navigation.compose.internal\n\nimport androidx.compose.animation.AnimatedContentTransitionScope\nimport androidx.compose.animation.EnterTransition\nimport androidx.compose.animation.ExitTransition\nimport androidx.compose.animation.SizeTransform\nimport androidx.compose.animation.core.spring\nimport androidx.compose.animation.core.tween\nimport androidx.compose.animation.fadeIn\nimport androidx.compose.animation.fadeOut\nimport androidx.compose.animation.scaleOut\nimport androidx.compose.runtime.Composable\nimport androidx.navigation.NavBackStackEntry\nimport kotlinx.coroutines.flow.Flow\n\ninternal expect class BackEventCompat {\n    val touchX: Float\n    val touchY: Float\n    val progress: Float\n    val swipeEdge: Int\n}\n\n@Composable\ninternal expect fun PredictiveBackHandler(\n    enabled: Boolean = true,\n    onBack: suspend (progress: Flow<BackEventCompat>) -> Unit,\n)\n\ninternal expect fun randomUUID(): String\n\n/**\n * Class WeakReference encapsulates weak reference to an object, which could be used to either\n * retrieve a strong reference to an object, or return null, if object was already destroyed by the\n * memory manager.\n */\ninternal expect class WeakReference<T : Any>(reference: T) {\n    fun get(): T?\n\n    fun clear()\n}\n\ninternal expect object DefaultNavTransitions {\n    val enterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition\n    val exitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition\n    val predictivePopEnterTransition:\n        AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> EnterTransition\n    val predictivePopExitTransition:\n        AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> ExitTransition\n    val sizeTransform: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)?\n}\n\ninternal object StandardDefaultNavTransitions {\n    val enterTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition = {\n        fadeIn(animationSpec = tween(700))\n    }\n    val exitTransition: AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition = {\n        fadeOut(animationSpec = tween(700))\n    }\n    val predictivePopEnterTransition:\n        AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> EnterTransition =\n        {\n            fadeIn(\n                spring(\n                    dampingRatio = 1.0f, // reflects material3 motionScheme.defaultEffectsSpec()\n                    stiffness = 1600.0f, // reflects material3 motionScheme.defaultEffectsSpec()\n                )\n            )\n        }\n    val predictivePopExitTransition:\n        AnimatedContentTransitionScope<NavBackStackEntry>.(Int) -> ExitTransition =\n        {\n            scaleOut(targetScale = 0.7f) // reflects material3 motionScheme.defaultEffectsSpec()\n        }\n    val sizeTransform: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> SizeTransform?)? =\n        null\n}\n```\n\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/source-code/runtime-source.md",
    "content": "# Compose Runtime Source Reference\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composable.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.runtime\n\n/**\n * [Composable] functions are the fundamental building blocks of an application built with Compose.\n *\n * [Composable] can be applied to a function or lambda to indicate that the function/lambda can be\n * used as part of a composition to describe a transformation from application data into a tree or\n * hierarchy.\n *\n * Annotating a function or expression with [Composable] changes the type of that function or\n * expression. For example, [Composable] functions can only ever be called from within another\n * [Composable] function. A useful mental model for [Composable] functions is that an implicit\n * \"composable context\" is passed into a [Composable] function, and is done so implicitly when it is\n * called from within another [Composable] function. This \"context\" can be used to store information\n * from previous executions of the function that happened at the same logical point of the tree.\n */\n@MustBeDocumented\n@Retention(AnnotationRetention.BINARY)\n@Target(\n    // function declarations\n    // @Composable fun Foo() { ... }\n    // lambda expressions\n    // val foo = @Composable { ... }\n    AnnotationTarget.FUNCTION,\n\n    // type declarations\n    // var foo: @Composable () -> Unit = { ... }\n    // parameter types\n    // foo: @Composable () -> Unit\n    AnnotationTarget.TYPE,\n\n    // composable types inside of type signatures\n    // foo: (@Composable () -> Unit) -> Unit\n    AnnotationTarget.TYPE_PARAMETER,\n\n    // composable property getters and setters\n    // val foo: Int @Composable get() { ... }\n    // var bar: Int\n    //   @Composable get() { ... }\n    AnnotationTarget.PROPERTY_GETTER,\n)\npublic annotation class Composable\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composition.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@file:OptIn(InternalComposeApi::class)\n\npackage androidx.compose.runtime\n\nimport androidx.collection.MutableScatterSet\nimport androidx.collection.ObjectList\nimport androidx.collection.ScatterMap\nimport androidx.collection.ScatterSet\nimport androidx.compose.runtime.collection.ScopeMap\nimport androidx.compose.runtime.collection.fastForEach\nimport androidx.compose.runtime.composer.DebugStringFormattable\nimport androidx.compose.runtime.composer.RememberManager\nimport androidx.compose.runtime.composer.gapbuffer.SlotTable\nimport androidx.compose.runtime.composer.gapbuffer.asGapBufferSlotTable\nimport androidx.compose.runtime.composer.gapbuffer.changelist.ChangeList\nimport androidx.compose.runtime.composer.linkbuffer.asLinkBufferSlotTable\nimport androidx.compose.runtime.internal.AtomicReference\nimport androidx.compose.runtime.internal.RememberEventDispatcher\nimport androidx.compose.runtime.internal.trace\nimport androidx.compose.runtime.platform.makeSynchronizedObject\nimport androidx.compose.runtime.platform.synchronized\nimport androidx.compose.runtime.snapshots.ReaderKind\nimport androidx.compose.runtime.snapshots.StateObjectImpl\nimport androidx.compose.runtime.snapshots.fastAll\nimport androidx.compose.runtime.snapshots.fastAny\nimport androidx.compose.runtime.tooling.CompositionErrorContextImpl\nimport androidx.compose.runtime.tooling.CompositionObserver\nimport androidx.compose.runtime.tooling.CompositionObserverHandle\nimport androidx.compose.runtime.tooling.ObservableComposition\n\n/**\n * A composition object is usually constructed for you, and returned from an API that is used to\n * initially compose a UI. For instance, [setContent] returns a Composition.\n *\n * The [dispose] method should be used when you would like to dispose of the UI and the Composition.\n */\npublic interface Composition {\n    /**\n     * Returns true if any pending invalidations have been scheduled. An invalidation is schedule if\n     * [RecomposeScope.invalidate] has been called on any composition scopes create for the\n     * composition.\n     *\n     * Modifying [MutableState.value] of a value produced by [mutableStateOf] will automatically\n     * call [RecomposeScope.invalidate] for any scope that read [State.value] of the mutable state\n     * instance during composition.\n     *\n     * @see RecomposeScope\n     * @see mutableStateOf\n     */\n    public val hasInvalidations: Boolean\n\n    /** True if [dispose] has been called. */\n    public val isDisposed: Boolean\n\n    /**\n     * Clear the hierarchy that was created from the composition and release resources allocated for\n     * composition. After calling [dispose] the composition will no longer be recomposed and calling\n     * [setContent] will throw an [IllegalStateException]. Calling [dispose] is idempotent, all\n     * calls after the first are a no-op.\n     */\n    public fun dispose()\n\n    /**\n     * Update the composition with the content described by the [content] composable. After this has\n     * been called the changes to produce the initial composition has been calculated and applied to\n     * the composition.\n     *\n     * Will throw an [IllegalStateException] if the composition has been disposed.\n     *\n     * @param content A composable function that describes the content of the composition.\n     * @exception IllegalStateException thrown in the composition has been [dispose]d.\n     */\n    public fun setContent(content: @Composable () -> Unit)\n}\n\n/**\n * A [ReusableComposition] is a [Composition] that can be reused for different composable content.\n *\n * This interface is used by components that have to synchronize lifecycle of parent and child\n * compositions and efficiently reuse the nodes emitted by [ReusableComposeNode].\n */\npublic sealed interface ReusableComposition : Composition {\n    /**\n     * Update the composition with the content described by the [content] composable. After this has\n     * been called the changes to produce the initial composition has been calculated and applied to\n     * the composition.\n     *\n     * This method forces this composition into \"reusing\" state before setting content. In reusing\n     * state, all remembered content is discarded, and nodes emitted by [ReusableComposeNode] are\n     * re-used for the new content. The nodes are only reused if the group structure containing the\n     * node matches new content.\n     *\n     * Will throw an [IllegalStateException] if the composition has been disposed.\n     *\n     * @param content A composable function that describes the content of the composition.\n     * @exception IllegalStateException thrown in the composition has been [dispose]d.\n     */\n    public fun setContentWithReuse(content: @Composable () -> Unit)\n\n    /**\n     * Deactivate all observation scopes in composition and remove all remembered slots while\n     * preserving nodes in place. The composition can be re-activated by calling [setContent] with a\n     * new content.\n     */\n    public fun deactivate()\n}\n\n/**\n * A key to locate a service using the [CompositionServices] interface optionally implemented by\n * implementations of [Composition].\n */\npublic interface CompositionServiceKey<T>\n\n/**\n * Allows finding composition services from the runtime. The services requested through this\n * interface are internal to the runtime and cannot be provided directly.\n *\n * The [CompositionServices] interface is used by the runtime to provide optional and/or\n * experimental services through public extension functions.\n *\n * Implementation of [Composition] that delegate to another [Composition] instance should implement\n * this interface and delegate calls to [getCompositionService] to the original [Composition].\n */\npublic interface CompositionServices {\n    /** Find a service of class [T]. */\n    public fun <T> getCompositionService(key: CompositionServiceKey<T>): T?\n}\n\n/**\n * Find a Composition service.\n *\n * Find services that implement optional and/or experimental services provided through public or\n * experimental extension functions.\n */\ninternal fun <T> Composition.getCompositionService(key: CompositionServiceKey<T>) =\n    (this as? CompositionServices)?.getCompositionService(key)\n\n/**\n * A controlled composition is a [Composition] that can be directly controlled by the caller.\n *\n * This is the interface used by the [Recomposer] to control how and when a composition is\n * invalidated and subsequently recomposed.\n *\n * Normally a composition is controlled by the [Recomposer] but it is often more efficient for tests\n * to take direct control over a composition by calling [ControlledComposition] instead of\n * [Composition].\n *\n * @see ControlledComposition\n */\npublic sealed interface ControlledComposition : Composition {\n    /**\n     * True if the composition is actively compositing such as when actively in a call to\n     * [composeContent] or [recompose].\n     */\n    public val isComposing: Boolean\n\n    /**\n     * True after [composeContent] or [recompose] has been called and [applyChanges] is expected as\n     * the next call. An exception will be throw in [composeContent] or [recompose] is called while\n     * there are pending from the previous composition pending to be applied.\n     */\n    public val hasPendingChanges: Boolean\n\n    /**\n     * Called by the parent composition in response to calling [setContent]. After this method the\n     * changes should be calculated but not yet applied. DO NOT call this method directly if this is\n     * interface is controlled by a [Recomposer], either use [setContent] or\n     * [Recomposer.composeInitial] instead.\n     *\n     * @param content A composable function that describes the tree.\n     */\n    public fun composeContent(content: @Composable () -> Unit)\n\n    /**\n     * Record the values that were modified after the last call to [recompose] or from the initial\n     * call to [composeContent]. This should be called before [recompose] is called to record which\n     * parts of the composition need to be recomposed.\n     *\n     * @param values the set of values that have changed since the last composition.\n     */\n    public fun recordModificationsOf(values: Set<Any>)\n\n    /**\n     * Returns true if any of the object instances in [values] is observed by this composition. This\n     * allows detecting if values changed by a previous composition will potentially affect this\n     * composition.\n     */\n    public fun observesAnyOf(values: Set<Any>): Boolean\n\n    /**\n     * Execute [block] with [isComposing] set temporarily to `true`. This allows treating\n     * invalidations reported during [prepareCompose] as if they happened while composing to avoid\n     * double invalidations when propagating changes from a parent composition while before\n     * composing the child composition.\n     */\n    public fun prepareCompose(block: () -> Unit)\n\n    /**\n     * Record that [value] has been read. This is used primarily by the [Recomposer] to inform the\n     * composer when the a [MutableState] instance has been read implying it should be observed for\n     * changes.\n     *\n     * @param value the instance from which a property was read\n     */\n    public fun recordReadOf(value: Any)\n\n    /**\n     * Record that [value] has been modified. This is used primarily by the [Recomposer] to inform\n     * the composer when the a [MutableState] instance been change by a composable function.\n     */\n    public fun recordWriteOf(value: Any)\n\n    /**\n     * Recompose the composition to calculate any changes necessary to the composition state and the\n     * tree maintained by the applier. No changes have been made yet. Changes calculated will be\n     * applied when [applyChanges] is called.\n     *\n     * @return returns `true` if any changes are pending and [applyChanges] should be called.\n     */\n    public fun recompose(): Boolean\n\n    /**\n     * Insert the given list of movable content with their paired state in potentially a different\n     * composition. If the second part of the pair is null then the movable content should be\n     * inserted as new. If second part of the pair has a value then the state should be moved into\n     * the referenced location and then recomposed there.\n     */\n    @InternalComposeApi\n    public fun insertMovableContent(\n        references: List<Pair<MovableContentStateReference, MovableContentStateReference?>>\n    )\n\n    /** Dispose the value state that is no longer needed. */\n    @InternalComposeApi public fun disposeUnusedMovableContent(state: MovableContentState)\n\n    /**\n     * Apply the changes calculated during [setContent] or [recompose]. If an exception is thrown by\n     * [applyChanges] the composition is irreparably damaged and should be [dispose]d.\n     */\n    public fun applyChanges()\n\n    /**\n     * Apply change that must occur after the main bulk of changes have been applied. Late changes\n     * are the result of inserting movable content and it must be performed after [applyChanges]\n     * because, for content that have moved must be inserted only after it has been removed from the\n     * previous location. All deletes must be executed before inserts. To ensure this, all deletes\n     * are performed in [applyChanges] and all inserts are performed in [applyLateChanges].\n     */\n    public fun applyLateChanges()\n\n    /**\n     * Call when all changes, including late changes, have been applied. This signals to the\n     * composition that any transitory composition state can now be discarded. This is advisory only\n     * and a controlled composition will execute correctly when this is not called.\n     */\n    public fun changesApplied()\n\n    /**\n     * Abandon current changes and reset composition state. Called when recomposer cannot proceed\n     * with current recomposition loop and needs to reset composition.\n     */\n    public fun abandonChanges()\n\n    /**\n     * Invalidate all invalidation scopes. This is called, for example, by [Recomposer] when the\n     * Recomposer becomes active after a previous period of inactivity, potentially missing more\n     * granular invalidations.\n     */\n    public fun invalidateAll()\n\n    /**\n     * Throws an exception if the internal state of the composer has been corrupted and is no longer\n     * consistent. Used in testing the composer itself.\n     */\n    @InternalComposeApi public fun verifyConsistent()\n\n    /**\n     * Temporarily delegate all invalidations sent to this composition to the [to] composition. This\n     * is used when movable content moves between compositions. The recompose scopes are not\n     * redirected until after the move occurs during [applyChanges] and [applyLateChanges]. This is\n     * used to compose as if the scopes have already been changed.\n     */\n    public fun <R> delegateInvalidations(\n        to: ControlledComposition?,\n        groupIndex: Int,\n        block: () -> R,\n    ): R\n\n    /**\n     * Sets the [shouldPause] callback allowing a composition to be pausable if it is not `null`.\n     * Setting the callback to `null` disables pausing.\n     *\n     * @return the previous value of the callback which will be restored once the callback is no\n     *   longer needed.\n     * @see PausableComposition\n     */\n    @Suppress(\"ExecutorRegistration\")\n    public fun getAndSetShouldPauseCallback(shouldPause: ShouldPauseCallback?): ShouldPauseCallback?\n}\n\n/** Utility function to set and restore a should pause callback. */\ninternal inline fun <R> ControlledComposition.pausable(\n    shouldPause: ShouldPauseCallback,\n    block: () -> R,\n): R {\n    val previous = getAndSetShouldPauseCallback(shouldPause)\n    return try {\n        block()\n    } finally {\n        getAndSetShouldPauseCallback(previous)\n    }\n}\n\n/**\n * This method is the way to initiate a composition. [parent] [CompositionContext] can be\n * * provided to make the composition behave as a sub-composition of the parent. If composition does\n * * not have a parent, [Recomposer] instance should be provided.\n *\n * It is important to call [Composition.dispose] when composition is no longer needed in order to\n * release resources.\n *\n * @sample androidx.compose.runtime.samples.CustomTreeComposition\n * @param applier The [Applier] instance to be used in the composition.\n * @param parent The parent [CompositionContext].\n * @see Applier\n * @see Composition\n * @see Recomposer\n */\npublic fun Composition(applier: Applier<*>, parent: CompositionContext): Composition =\n    CompositionImpl(parent, applier)\n\n/**\n * This method is the way to initiate a reusable composition. [parent] [CompositionContext] can be\n * provided to make the composition behave as a sub-composition of the parent. If composition does\n * not have a parent, [Recomposer] instance should be provided.\n *\n * It is important to call [Composition.dispose] when composition is no longer needed in order to\n * release resources.\n *\n * @param applier The [Applier] instance to be used in the composition.\n * @param parent The parent [CompositionContext].\n * @see Applier\n * @see ReusableComposition\n * @see rememberCompositionContext\n */\npublic fun ReusableComposition(\n    applier: Applier<*>,\n    parent: CompositionContext,\n): ReusableComposition = CompositionImpl(parent, applier)\n\n/**\n * This method is a way to initiate a composition. Optionally, a [parent] [CompositionContext] can\n * be provided to make the composition behave as a sub-composition of the parent or a [Recomposer]\n * can be provided.\n *\n * A controlled composition allows direct control of the composition instead of it being controlled\n * by the [Recomposer] passed ot the root composition.\n *\n * It is important to call [Composition.dispose] this composer is no longer needed in order to\n * release resources.\n *\n * @sample androidx.compose.runtime.samples.CustomTreeComposition\n * @param applier The [Applier] instance to be used in the composition.\n * @param parent The parent [CompositionContext].\n * @see Applier\n * @see Composition\n * @see Recomposer\n */\n@TestOnly\npublic fun ControlledComposition(\n    applier: Applier<*>,\n    parent: CompositionContext,\n): ControlledComposition = CompositionImpl(parent, applier)\n\nprivate val PendingApplyNoModifications = Any()\n\n@OptIn(ExperimentalComposeRuntimeApi::class)\ninternal val ObservableCompositionServiceKey =\n    object : CompositionServiceKey<ObservableComposition> {}\n\nprivate const val RUNNING = 0\nprivate const val DEACTIVATED = 1\nprivate const val INCONSISTENT = 2\nprivate const val DISPOSED = 3\n\ninternal abstract class SlotStorage {\n    abstract val isEmpty: Boolean\n\n    /** Clear the content of the slot table. Report removes to the remember manager */\n    abstract fun clear(rememberManager: RememberManager)\n\n    /** Tell the slot storage to collect call-by information (used by live-edit) */\n    abstract fun collectCalledByInformation()\n\n    /** Tell the slot storage to collect source information (used by tooling) */\n    abstract fun collectSourceInformation()\n\n    /** Deactivate all nodes in the storage (used by lazy) */\n    abstract fun deactivateAll(rememberManager: RememberManager)\n\n    abstract fun dispose()\n\n    /** Extract one or more states of movable content that is nested in the slot storage */\n    abstract fun extractNestedStates(\n        applier: Applier<*>,\n        references: ObjectList<MovableContentStateReference>,\n    ): ScatterMap<MovableContentStateReference, MovableContentState>\n\n    abstract fun disposeUnusedMovableContent(\n        rememberManager: RememberManager,\n        state: MovableContentState,\n    )\n\n    /** Invalidate all scopes in the storage (used by live-edit) */\n    abstract fun invalidateAll()\n\n    /** Invalidates all groups with the [target] group key (used by live-edit) */\n    abstract fun invalidateGroupsWithKey(target: Int): List<RecomposeScopeImpl>?\n\n    /** Returns true if the recompose scope is in the slot storage */\n    abstract fun ownsRecomposeScope(scope: RecomposeScopeImpl): Boolean\n\n    /** Returns true if the group indicated by group owns the recompose scope */\n    abstract fun groupContainsAnchor(group: Int, anchor: Anchor): Boolean\n\n    /** Returns true if the [parent] group contains the [child] group */\n    abstract fun inGroup(parent: Anchor, child: Anchor): Boolean\n\n    /** Debugging */\n    abstract fun toDebugString(): String\n\n    /**\n     * Testing. Throws an exception if the slot table is not well-formed. A well-formed slot storage\n     * is a slot storage where all the internal invariants hold.\n     */\n    @TestOnly abstract fun verifyWellFormed()\n\n    @TestOnly abstract fun getSlots(): Iterable<Any?>\n}\n\ninternal abstract class Changes : DebugStringFormattable() {\n    abstract fun clear()\n\n    abstract fun execute(\n        slotStorage: SlotStorage,\n        applier: Applier<*>,\n        rememberManager: RememberManager,\n        errorContext: CompositionErrorContextImpl?,\n    )\n\n    abstract fun isEmpty(): Boolean\n\n    fun isNotEmpty() = !isEmpty()\n}\n\n/**\n * The implementation of the [Composition] interface.\n *\n * @param parent An optional reference to the parent composition.\n * @param applier The applier to use to manage the tree built by the composer.\n */\n@OptIn(ExperimentalComposeRuntimeApi::class)\ninternal class CompositionImpl(\n    /**\n     * The parent composition from [rememberCompositionContext], for sub-compositions, or the an\n     * instance of [Recomposer] for root compositions.\n     */\n    @get:TestOnly val parent: CompositionContext,\n\n    /** The applier to use to update the tree managed by the composition. */\n    private val applier: Applier<*>,\n) :\n    ControlledComposition,\n    ReusableComposition,\n    RecomposeScopeOwner,\n    CompositionServices,\n    PausableComposition,\n    ObservableComposition {\n\n    /**\n     * `null` if a composition isn't pending to apply. `Set<Any>` or `Array<Set<Any>>` if there are\n     * modifications to record [PendingApplyNoModifications] if a composition is pending to apply,\n     * no modifications. any set contents will be sent to [recordModificationsOf] after applying\n     * changes before releasing [lock]\n     */\n    private val pendingModifications = AtomicReference<Any?>(null)\n\n    // Held when making changes to self or composer\n    private val lock = makeSynchronizedObject()\n\n    /**\n     * A set of remember observers that were potentially abandoned between [composeContent] or\n     * [recompose] and [applyChanges]. When inserting new content any newly remembered\n     * [RememberObserver]s are added to this set and then removed as [RememberObserver.onRemembered]\n     * is dispatched. If any are left in this when exiting [applyChanges] they have been abandoned\n     * and are sent an [RememberObserver.onAbandoned] notification.\n     */\n    @Suppress(\"AsCollectionCall\") // Requires iterator API when dispatching abandons\n    private val abandonSet = MutableScatterSet<RememberObserver>().asMutableSet()\n\n    /** The slot table is used to store the composition information required for recomposition. */\n    @Suppress(\"MemberVisibilityCanBePrivate\") // published as internal\n    internal val slotStorage: SlotStorage =\n        createSlotStorage().also {\n            if (parent.collectingCallByInformation) it.collectCalledByInformation()\n            if (parent.collectingSourceInformation) it.collectSourceInformation()\n        }\n\n    @OptIn(ExperimentalComposeApi::class)\n    private fun createSlotStorage(): SlotStorage =\n        if (ComposeRuntimeFlags.isLinkBufferComposerEnabled) {\n            androidx.compose.runtime.composer.linkbuffer.SlotTable()\n        } else {\n            androidx.compose.runtime.composer.gapbuffer.SlotTable()\n        }\n\n    /**\n     * A map of observable objects to the [RecomposeScope]s that observe the object. If the key\n     * object is modified the associated scopes should be invalidated.\n     */\n    private val observations = ScopeMap<Any, RecomposeScopeImpl>()\n\n    /** Used for testing. Returns the objects that are observed */\n    internal val observedObjects\n        @TestOnly @Suppress(\"AsCollectionCall\") get() = observations.map.asMap().keys\n\n    /**\n     * A set of scopes that were invalidated by a call from [recordModificationsOf]. This set is\n     * only used in [addPendingInvalidationsLocked], and is reused between invocations.\n     */\n    private val invalidatedScopes = MutableScatterSet<RecomposeScopeImpl>()\n\n    /**\n     * A set of scopes that were invalidated conditionally (that is they were invalidated by a\n     * [derivedStateOf] object) by a call from [recordModificationsOf]. They need to be held in the\n     * [observations] map until invalidations are drained for composition as a later call to\n     * [recordModificationsOf] might later cause them to be unconditionally invalidated.\n     */\n    private val conditionallyInvalidatedScopes = MutableScatterSet<RecomposeScopeImpl>()\n\n    /** A map of object read during derived states to the corresponding derived state. */\n    private val derivedStates = ScopeMap<Any, DerivedState<*>>()\n\n    /** Used for testing. Returns dependencies of derived states that are currently observed. */\n    internal val derivedStateDependencies\n        @TestOnly @Suppress(\"AsCollectionCall\") get() = derivedStates.map.asMap().keys\n\n    /** Used for testing. Returns the conditional scopes being tracked by the composer */\n    internal val conditionalScopes: List<RecomposeScopeImpl>\n        @TestOnly\n        @Suppress(\"AsCollectionCall\")\n        get() = conditionallyInvalidatedScopes.asSet().toList()\n\n    /**\n     * A list of changes calculated by [Composer] to be applied to the [Applier] and the [SlotTable]\n     * to reflect the result of composition. This is a list of lambdas that need to be invoked in\n     * order to produce the desired effects.\n     */\n    private val changes = createChangeList()\n\n    /**\n     * A list of changes calculated by [Composer] to be applied after all other compositions have\n     * had [applyChanges] called. These changes move [MovableContent] state from one composition to\n     * another and must be applied after [applyChanges] because [applyChanges] copies and removes\n     * the state out of the previous composition so it can be inserted into the new location. As\n     * inserts might be earlier in the composition than the position it is deleted, this move must\n     * be done in two phases.\n     */\n    private val lateChanges = createChangeList()\n\n    /**\n     * When an observable object is modified during composition any recompose scopes that are\n     * observing that object are invalidated immediately. Since they have already been processed\n     * there is no need to process them again, so this set maintains a set of the recompose scopes\n     * that were already dismissed by composition and should be ignored in the next call to\n     * [recordModificationsOf].\n     */\n    private val observationsProcessed = ScopeMap<Any, RecomposeScopeImpl>()\n\n    /**\n     * A map of the invalid [RecomposeScope]s. If this map is non-empty the current state of the\n     * composition does not reflect the current state of the objects it observes and should be\n     * recomposed by calling [recompose]. Tbe value is a map of values that invalidated the scope.\n     * The scope is checked with these instances to ensure the value has changed. This is used to\n     * only invalidate the scope if a [derivedStateOf] object changes.\n     */\n    private var invalidations = ScopeMap<RecomposeScopeImpl, Any>()\n\n    /**\n     * As [RecomposeScope]s are removed the corresponding entries in the observations set must be\n     * removed as well. This process is expensive so should only be done if it is certain the\n     * [observations] set contains [RecomposeScope] that is no longer needed. [pendingInvalidScopes]\n     * is set to true whenever a [RecomposeScope] is removed from the [slotStorage].\n     */\n    @Suppress(\"MemberVisibilityCanBePrivate\") // published as internal\n    internal var pendingInvalidScopes = false\n\n    /**\n     * If the [shouldPause] callback is set the composition is pausable and should pause whenever\n     * the [shouldPause] callback returns `true`.\n     */\n    private var shouldPause: ShouldPauseCallback? = null\n\n    private var pendingPausedComposition: PausedCompositionImpl? = null\n\n    private var invalidationDelegate: CompositionImpl? = null\n\n    private var invalidationDelegateGroup: Int = 0\n\n    internal val observerHolder = CompositionObserverHolder(parent = parent)\n\n    private val rememberManager = RememberEventDispatcher()\n\n    /** The [Composer] to use to create and update the tree managed by this composition. */\n    internal val composer: InternalComposer = createComposer().also { parent.registerComposer(it) }\n\n    @OptIn(ExperimentalComposeApi::class)\n    private fun createComposer(): InternalComposer =\n        if (ComposeRuntimeFlags.isLinkBufferComposerEnabled) {\n            LinkComposer(\n                applier = applier,\n                parentContext = parent,\n                slotTable = slotStorage.asLinkBufferSlotTable(),\n                abandonSet = abandonSet,\n                changes = changes,\n                lateChanges = lateChanges,\n                composition = this,\n                observerHolder = observerHolder,\n            )\n        } else {\n            GapComposer(\n                applier = applier,\n                parentContext = parent,\n                slotTable = slotStorage.asGapBufferSlotTable(),\n                abandonSet = abandonSet,\n                changes = changes,\n                lateChanges = lateChanges,\n                composition = this,\n                observerHolder = observerHolder,\n            )\n        }\n\n    @OptIn(ExperimentalComposeApi::class)\n    private fun createChangeList(): Changes =\n        if (ComposeRuntimeFlags.isLinkBufferComposerEnabled) {\n            androidx.compose.runtime.composer.linkbuffer.changelist.ChangeList()\n        } else {\n            androidx.compose.runtime.composer.gapbuffer.changelist.ChangeList()\n        }\n\n    /** Return true if this is a root (non-sub-) composition. */\n    val isRoot: Boolean = parent is Recomposer\n\n    /** True if [dispose] has been called. */\n    private var state = RUNNING\n\n    /** True if a sub-composition of this composition is current composing. */\n    private val areChildrenComposing\n        get() = composer.areChildrenComposing\n\n    /**\n     * The [Composable] function used to define the tree managed by this composition. This is set by\n     * [setContent].\n     */\n    var composable: @Composable () -> Unit = {}\n\n    override val isComposing: Boolean\n        get() = composer.isComposing\n\n    override val isDisposed: Boolean\n        get() = state == DISPOSED\n\n    override val hasPendingChanges: Boolean\n        get() = synchronized(lock) { composer.hasPendingChanges }\n\n    override fun setContent(content: @Composable () -> Unit) {\n        val wasDeactivated = clearDeactivated()\n        ensureRunning()\n\n        if (wasDeactivated) {\n            composeInitialWithReuse(content)\n        } else {\n            composeInitial(content)\n        }\n    }\n\n    override fun setContentWithReuse(content: @Composable () -> Unit) {\n        clearDeactivated()\n        ensureRunning()\n\n        composeInitialWithReuse(content)\n    }\n\n    override fun setPausableContent(content: @Composable () -> Unit): PausedComposition {\n        val wasDeactivated = clearDeactivated()\n        return composeInitialPaused(reusable = wasDeactivated, content)\n    }\n\n    override fun setPausableContentWithReuse(content: @Composable () -> Unit): PausedComposition {\n        clearDeactivated()\n        ensureRunning()\n\n        return composeInitialPaused(reusable = true, content)\n    }\n\n    internal fun pausedCompositionFinished(ignoreSet: ScatterSet<RememberObserverHolder>?) {\n        pendingPausedComposition = null\n        if (ignoreSet != null) {\n            rememberManager.ignoreForgotten(ignoreSet)\n            state = INCONSISTENT\n        }\n    }\n\n    private fun composeInitial(content: @Composable () -> Unit) {\n        this.composable = content\n        parent.composeInitial(this, composable)\n    }\n\n    private fun composeInitialPaused(\n        reusable: Boolean,\n        content: @Composable () -> Unit,\n    ): PausedComposition {\n        checkPrecondition(pendingPausedComposition == null) {\n            \"A pausable composition is in progress\"\n        }\n        val pausedComposition =\n            PausedCompositionImpl(\n                composition = this,\n                context = parent,\n                composer = composer,\n                content = content,\n                reusable = reusable,\n                abandonSet = abandonSet,\n                applier = applier,\n                lock = lock,\n            )\n        pendingPausedComposition = pausedComposition\n        return pausedComposition\n    }\n\n    private fun composeInitialWithReuse(content: @Composable () -> Unit) {\n        composer.startReuseFromRoot()\n        composeInitial(content)\n        composer.endReuseFromRoot()\n    }\n\n    private fun ensureRunning() {\n        checkPrecondition(state == RUNNING) {\n            when (state) {\n                INCONSISTENT ->\n                    \"A previous pausable composition for this composition was cancelled. This \" +\n                        \"composition must be disposed.\"\n                DISPOSED -> \"The composition is disposed\"\n                DEACTIVATED -> \"The composition should be activated before setting content.\"\n                else -> \"\" // Excluded by the precondition check\n            }\n        }\n        checkPrecondition(pendingPausedComposition == null) {\n            \"A pausable composition is in progress\"\n        }\n    }\n\n    private fun clearDeactivated(): Boolean =\n        synchronized(lock) {\n            val isDeactivated = state == DEACTIVATED\n            if (isDeactivated) {\n                state = RUNNING\n            }\n            isDeactivated\n        }\n\n    @OptIn(ExperimentalComposeRuntimeApi::class)\n    override fun setObserver(observer: CompositionObserver): CompositionObserverHandle {\n        synchronized(lock) {\n            observerHolder.observer = observer\n            observerHolder.root = true\n        }\n        return object : CompositionObserverHandle {\n            override fun dispose() {\n                synchronized(lock) {\n                    if (observerHolder.observer == observer) {\n                        observerHolder.observer = null\n                        observerHolder.root = false\n                    }\n                }\n            }\n        }\n    }\n\n    fun invalidateGroupsWithKey(key: Int) {\n        val scopesToInvalidate = synchronized(lock) { slotStorage.invalidateGroupsWithKey(key) }\n        // Calls to invalidate must be performed without the lock as the they may cause the\n        // recomposer to take its lock to respond to the invalidation and that takes the locks\n        // in the opposite order of composition so if composition begins in another thread taking\n        // the recomposer lock with the composer lock held will deadlock.\n        val forceComposition =\n            scopesToInvalidate == null ||\n                scopesToInvalidate.fastAny {\n                    it.invalidateForResult(null) == InvalidationResult.IGNORED\n                }\n        if (forceComposition && composer.forceRecomposeScopes()) {\n            parent.invalidate(this)\n        }\n    }\n\n    @Suppress(\"UNCHECKED_CAST\")\n    private fun drainPendingModificationsForCompositionLocked() {\n        // Recording modifications may race for lock. If there are pending modifications\n        // and we won the lock race, drain them before composing.\n        when (val toRecord = pendingModifications.getAndSet(PendingApplyNoModifications)) {\n            null -> {\n                // Do nothing, just start composing.\n            }\n            PendingApplyNoModifications -> {\n                composeRuntimeError(\"pending composition has not been applied\")\n            }\n            is Set<*> -> {\n                addPendingInvalidationsLocked(toRecord as Set<Any>, forgetConditionalScopes = true)\n            }\n            is Array<*> ->\n                for (changed in toRecord as Array<Set<Any>>) {\n                    addPendingInvalidationsLocked(changed, forgetConditionalScopes = true)\n                }\n            else -> composeRuntimeError(\"corrupt pendingModifications drain: $pendingModifications\")\n        }\n    }\n\n    @Suppress(\"UNCHECKED_CAST\")\n    private fun drainPendingModificationsLocked() {\n        when (val toRecord = pendingModifications.getAndSet(null)) {\n            PendingApplyNoModifications -> {\n                // No work to do\n            }\n            is Set<*> -> {\n                addPendingInvalidationsLocked(toRecord as Set<Any>, forgetConditionalScopes = false)\n            }\n            is Array<*> ->\n                for (changed in toRecord as Array<Set<Any>>) {\n                    addPendingInvalidationsLocked(changed, forgetConditionalScopes = false)\n                }\n            null -> {\n                if (pendingPausedComposition == null)\n                    composeImmediateRuntimeError(\n                        \"calling recordModificationsOf and applyChanges concurrently is not supported\"\n                    )\n                // otherwise, the paused composition may be being resumed concurrently.\n            }\n            else -> composeRuntimeError(\"corrupt pendingModifications drain: $pendingModifications\")\n        }\n    }\n\n    // Drain the modification out of the normal recordModificationsOf(), composition() cycle.\n    // This avoids the checks to make sure the two calls are called in order.\n    @Suppress(\"UNCHECKED_CAST\")\n    private fun drainPendingModificationsOutOfBandLocked() {\n        when (val toRecord = pendingModifications.getAndSet(emptySet<Any>())) {\n            PendingApplyNoModifications,\n            null -> {\n                // No work to do\n            }\n            is Set<*> -> {\n                addPendingInvalidationsLocked(toRecord as Set<Any>, forgetConditionalScopes = false)\n            }\n            is Array<*> ->\n                for (changed in toRecord as Array<Set<Any>>) {\n                    addPendingInvalidationsLocked(changed, forgetConditionalScopes = false)\n                }\n            else -> composeRuntimeError(\"corrupt pendingModifications drain: $pendingModifications\")\n        }\n    }\n\n    override fun composeContent(content: @Composable () -> Unit) {\n        // TODO: This should raise a signal to any currently running recompose calls\n        //   to halt and return\n        guardChanges {\n            synchronized(lock) {\n                drainPendingModificationsForCompositionLocked()\n                guardInvalidationsLocked { invalidations ->\n                    composer.composeContent(invalidations, content, shouldPause)\n                }\n            }\n        }\n    }\n\n    internal fun updateMovingInvalidations() {\n        synchronized(lock) {\n            drainPendingModificationsOutOfBandLocked()\n            guardInvalidationsLocked { invalidations ->\n                composer.updateComposerInvalidations(invalidations)\n            }\n        }\n    }\n\n    override fun dispose() {\n        synchronized(lock) {\n            checkPrecondition(!composer.isComposing) {\n                \"Composition is disposed while composing. If dispose is triggered by a call in \" +\n                    \"@Composable function, consider wrapping it with SideEffect block.\"\n            }\n            if (state != DISPOSED) {\n                state = DISPOSED\n                composable = {}\n\n                // Changes are deferred if the composition contains movable content that needs\n                // to be released. NOTE: Applying these changes leaves the slot table in\n                // potentially invalid state. The routine use to produce this change list reuses\n                // code that extracts movable content from groups that are being deleted. This code\n                // does not bother to correctly maintain the node counts of a group nested groups\n                // that are going to be removed anyway so the node counts of the groups affected\n                // are might be incorrect after the changes have been applied.\n                val deferredChanges = composer.deferredChanges\n                if (deferredChanges != null) {\n                    applyChangesInLocked(deferredChanges)\n                }\n\n                // Dispatch all the `onForgotten` events for object that are no longer part of a\n                // composition because this composition is being discarded. It is important that\n                // this is done after applying deferred changes above to avoid sending `\n                // onForgotten` notification to objects that are still part of movable content that\n                // will be moved to a new location.\n                val nonEmptySlotTable = !slotStorage.isEmpty\n                if (nonEmptySlotTable || abandonSet.isNotEmpty()) {\n                    rememberManager.use(abandonSet, composer.errorContext) {\n                        if (nonEmptySlotTable) {\n                            applier.onBeginChanges()\n                            slotStorage.clear(rememberManager)\n                            applier.clear()\n                            applier.onEndChanges()\n                            dispatchRememberObservers()\n                        }\n                        dispatchAbandons()\n                    }\n                }\n                composer.dispose()\n            }\n        }\n        parent.unregisterComposition(this)\n    }\n\n    override val hasInvalidations\n        get() = synchronized(lock) { invalidations.size > 0 }\n\n    /**\n     * To bootstrap multithreading handling, recording modifications is now deferred between\n     * recomposition with changes to apply and the application of those changes.\n     * [pendingModifications] will contain a queue of changes to apply once all current changes have\n     * been successfully processed. Draining this queue is the responsibility of [recompose] if it\n     * would return `false` (changes do not need to be applied) or [applyChanges].\n     */\n    @Suppress(\"UNCHECKED_CAST\")\n    override fun recordModificationsOf(values: Set<Any>) {\n        while (true) {\n            val old = pendingModifications.get()\n            val new: Any =\n                when (old) {\n                    null,\n                    PendingApplyNoModifications -> values\n                    is Set<*> -> arrayOf(old, values)\n                    is Array<*> -> (old as Array<Set<Any>>) + values\n                    else -> error(\"corrupt pendingModifications: $pendingModifications\")\n                }\n            if (pendingModifications.compareAndSet(old, new)) {\n                if (old == null) {\n                    synchronized(lock) { drainPendingModificationsLocked() }\n                }\n                break\n            }\n        }\n    }\n\n    override fun observesAnyOf(values: Set<Any>): Boolean {\n        values.fastForEach { value ->\n            if (value in observations || value in derivedStates) return true\n        }\n        return false\n    }\n\n    override fun prepareCompose(block: () -> Unit) = composer.prepareCompose(block)\n\n    /**\n     * Extract the invalidations that are in the group with the given marker. This is used when\n     * movable content is moved between tables and the content was invalidated. This is used to move\n     * the invalidations with the content.\n     */\n    internal fun extractInvalidationsOf(anchor: Anchor): List<Pair<RecomposeScopeImpl, Any>> {\n        return if (invalidations.size > 0) {\n            val result = mutableListOf<Pair<RecomposeScopeImpl, Any>>()\n            val slotStorage = slotStorage\n            invalidations.removeIf { scope, value ->\n                val scopeAnchor = scope.anchor\n                if (scopeAnchor != null && slotStorage.inGroup(anchor, scopeAnchor)) {\n                    result.add(scope to value)\n                    // Remove the invalidation\n                    true\n                } else {\n                    // Keep the invalidation\n                    false\n                }\n            }\n            result\n        } else emptyList()\n    }\n\n    /**\n     * Extract the invalidations that are in the group with the given marker. This is used when\n     * movable content is moved between tables and the content was invalidated. This is used to move\n     * the invalidations with the content.\n     */\n    internal inline fun extractInvalidationsOfGroup(\n        inGroup: (Anchor) -> Boolean\n    ): List<Pair<RecomposeScopeImpl, Any>> {\n        return if (invalidations.size > 0) {\n            val result = mutableListOf<Pair<RecomposeScopeImpl, Any>>()\n            invalidations.removeIf { scope, value ->\n                val scopeAnchor = scope.anchor\n                if (scopeAnchor != null && inGroup(scopeAnchor)) {\n                    result.add(scope to value)\n\n                    // Remove the invalidation\n                    true\n                } else {\n                    // Keep the invalidation\n                    false\n                }\n            }\n            result\n        } else emptyList()\n    }\n\n    private fun addPendingInvalidationsLocked(value: Any, forgetConditionalScopes: Boolean) {\n        observations.forEachScopeOf(value) { scope ->\n            if (\n                !observationsProcessed.remove(value, scope) &&\n                    scope.invalidateForResult(value) != InvalidationResult.IGNORED\n            ) {\n                if (scope.isConditional && !forgetConditionalScopes) {\n                    conditionallyInvalidatedScopes.add(scope)\n                } else {\n                    invalidatedScopes.add(scope)\n                }\n            }\n        }\n    }\n\n    private fun addPendingInvalidationsLocked(values: Set<Any>, forgetConditionalScopes: Boolean) {\n        values.fastForEach { value ->\n            if (value is RecomposeScopeImpl) {\n                value.invalidateForResult(null)\n            } else {\n                addPendingInvalidationsLocked(value, forgetConditionalScopes)\n                derivedStates.forEachScopeOf(value) {\n                    addPendingInvalidationsLocked(it, forgetConditionalScopes)\n                }\n            }\n        }\n\n        val conditionallyInvalidatedScopes = conditionallyInvalidatedScopes\n        val invalidatedScopes = invalidatedScopes\n        if (forgetConditionalScopes && conditionallyInvalidatedScopes.isNotEmpty()) {\n            observations.removeScopeIf { scope ->\n                scope in conditionallyInvalidatedScopes || scope in invalidatedScopes\n            }\n            conditionallyInvalidatedScopes.clear()\n            cleanUpDerivedStateObservations()\n        } else if (invalidatedScopes.isNotEmpty()) {\n            observations.removeScopeIf { scope -> scope in invalidatedScopes }\n            cleanUpDerivedStateObservations()\n            invalidatedScopes.clear()\n        }\n    }\n\n    private fun cleanUpDerivedStateObservations() {\n        derivedStates.removeScopeIf { derivedState -> derivedState !in observations }\n        if (conditionallyInvalidatedScopes.isNotEmpty()) {\n            conditionallyInvalidatedScopes.removeIf { scope -> !scope.isConditional }\n        }\n    }\n\n    override fun recordReadOf(value: Any) {\n        // Not acquiring lock since this happens during composition with it already held\n        if (!areChildrenComposing) {\n            composer.currentRecomposeScope?.let { scope ->\n                scope.used = true\n\n                val alreadyRead = scope.recordRead(value)\n\n                observer()?.onReadInScope(scope, value)\n\n                if (!alreadyRead) {\n                    if (value is StateObjectImpl) {\n                        value.recordReadIn(ReaderKind.Composition)\n                    }\n\n                    observations.add(value, scope)\n\n                    // Record derived state dependency mapping\n                    if (value is DerivedState<*>) {\n                        val record = value.currentRecord\n                        derivedStates.removeScope(value)\n                        record.dependencies.forEachKey { dependency ->\n                            if (dependency is StateObjectImpl) {\n                                dependency.recordReadIn(ReaderKind.Composition)\n                            }\n                            derivedStates.add(dependency, value)\n                        }\n                        scope.recordDerivedStateValue(value, record.currentValue)\n                    }\n                }\n            }\n        }\n    }\n\n    private fun invalidateScopeOfLocked(value: Any) {\n        // Invalidate any recompose scopes that read this value.\n        observations.forEachScopeOf(value) { scope ->\n            if (scope.invalidateForResult(value) == InvalidationResult.IMMINENT) {\n                // If we process this during recordWriteOf, ignore it when recording modifications\n                observationsProcessed.add(value, scope)\n            }\n        }\n    }\n\n    override fun recordWriteOf(value: Any) =\n        synchronized(lock) {\n            invalidateScopeOfLocked(value)\n\n            // If writing to dependency of a derived value and the value is changed, invalidate the\n            // scopes that read the derived value.\n            derivedStates.forEachScopeOf(value) { invalidateScopeOfLocked(it) }\n        }\n\n    override fun recompose(): Boolean =\n        synchronized(lock) {\n            val pendingPausedComposition = pendingPausedComposition\n            if (pendingPausedComposition != null && !pendingPausedComposition.isRecomposing) {\n                // If the composition is pending do not recompose it now as the recomposition\n                // is in the control of the pausable composition and is supposed to happen when\n                // the resume is called. However, this may cause the pausable composition to go\n                // revert to an incomplete state. If isRecomposing is true then this is being\n                // called in resume()\n                pendingPausedComposition.markIncomplete()\n                pendingPausedComposition.pausableApplier.markRecomposePending()\n                return false\n            }\n            drainPendingModificationsForCompositionLocked()\n            guardChanges {\n                guardInvalidationsLocked { invalidations ->\n                    composer.recompose(invalidations, shouldPause).also { shouldDrain ->\n                        // Apply would normally do this for us; do it now if apply shouldn't happen.\n                        if (!shouldDrain) drainPendingModificationsLocked()\n                    }\n                }\n            }\n        }\n\n    override fun insertMovableContent(\n        references: List<Pair<MovableContentStateReference, MovableContentStateReference?>>\n    ) {\n        runtimeCheck(references.fastAll { it.first.composition == this })\n        guardChanges { composer.insertMovableContentReferences(references) }\n    }\n\n    override fun disposeUnusedMovableContent(state: MovableContentState) {\n        rememberManager.use(abandonSet, composer.errorContext) {\n            state.slotStorage.disposeUnusedMovableContent(rememberManager, state)\n            dispatchRememberObservers()\n        }\n    }\n\n    private fun applyChangesInLocked(changes: Changes) {\n        rememberManager.prepare(abandonSet, composer.errorContext)\n        try {\n            if (changes.isEmpty()) return\n            val applier = pendingPausedComposition?.pausableApplier ?: applier\n            val traceName =\n                if (applier == pendingPausedComposition?.pausableApplier) {\n                    \"Compose:recordChanges\"\n                } else {\n                    \"Compose:applyChanges\"\n                }\n            trace(traceName) {\n                val rememberManager = pendingPausedComposition?.rememberManager ?: rememberManager\n                applier.onBeginChanges()\n\n                changes.execute(slotStorage, applier, rememberManager, composer.errorContext)\n\n                applier.onEndChanges()\n            }\n\n            // Side effects run after lifecycle observers so that any remembered objects\n            // that implement RememberObserver receive onRemembered before a side effect\n            // that captured it and operates on it can run.\n            rememberManager.dispatchRememberObservers()\n            rememberManager.dispatchSideEffects()\n\n            if (pendingInvalidScopes) {\n                trace(\"Compose:unobserve\") {\n                    pendingInvalidScopes = false\n                    observations.removeScopeIf { scope -> !scope.valid }\n                    cleanUpDerivedStateObservations()\n                }\n            }\n        } finally {\n            // Only dispatch abandons if we do not have any late changes or pending paused\n            // compositions. The instances in the abandon set can be remembered in the late changes\n            // or when the paused composition is applied.\n            try {\n                if (this.lateChanges.isEmpty() && pendingPausedComposition == null) {\n                    rememberManager.dispatchAbandons()\n                }\n            } finally {\n                rememberManager.clear()\n            }\n        }\n    }\n\n    override fun applyChanges() {\n        synchronized(lock) {\n            guardChanges {\n                applyChangesInLocked(changes)\n                drainPendingModificationsLocked()\n            }\n        }\n    }\n\n    override fun applyLateChanges() {\n        synchronized(lock) {\n            guardChanges {\n                if (lateChanges.isNotEmpty()) {\n                    applyChangesInLocked(lateChanges)\n                }\n            }\n        }\n    }\n\n    override fun changesApplied() {\n        synchronized(lock) {\n            guardChanges {\n                composer.changesApplied()\n\n                // By this time all abandon objects should be notified that they have been\n                // abandoned.\n                if (this.abandonSet.isNotEmpty()) {\n                    rememberManager.use(abandonSet, traceContext = composer.errorContext) {\n                        dispatchAbandons()\n                    }\n                }\n            }\n        }\n    }\n\n    private inline fun <T> guardInvalidationsLocked(\n        block: (changes: ScopeMap<RecomposeScopeImpl, Any>) -> T\n    ): T {\n        val invalidations = takeInvalidations()\n        return try {\n            block(invalidations)\n        } catch (e: Throwable) {\n            this.invalidations = invalidations\n            throw e\n        }\n    }\n\n    private inline fun <T> guardChanges(block: () -> T): T =\n        try {\n            trackAbandonedValues(block)\n        } catch (e: Throwable) {\n            abandonChanges()\n            throw e\n        }\n\n    override fun abandonChanges() {\n        pendingModifications.set(null)\n        changes.clear()\n        lateChanges.clear()\n\n        if (abandonSet.isNotEmpty()) {\n            rememberManager.use(abandonSet, composer.errorContext) { dispatchAbandons() }\n        }\n    }\n\n    override fun invalidateAll() {\n        slotStorage.invalidateAll()\n    }\n\n    override fun verifyConsistent() {\n        synchronized(lock) {\n            if (!isComposing) {\n                composer.verifyConsistent()\n                slotStorage.verifyWellFormed()\n            }\n        }\n    }\n\n    override fun <R> delegateInvalidations(\n        to: ControlledComposition?,\n        groupIndex: Int,\n        block: () -> R,\n    ): R {\n        return if (to != null && to != this && groupIndex >= 0) {\n            invalidationDelegate = to as CompositionImpl\n            invalidationDelegateGroup = groupIndex\n            try {\n                block()\n            } finally {\n                invalidationDelegate = null\n                invalidationDelegateGroup = 0\n            }\n        } else block()\n    }\n\n    override fun getAndSetShouldPauseCallback(\n        shouldPause: ShouldPauseCallback?\n    ): ShouldPauseCallback? {\n        val previous = this.shouldPause\n        this.shouldPause = shouldPause\n        return previous\n    }\n\n    override fun invalidate(scope: RecomposeScopeImpl, instance: Any?): InvalidationResult {\n        if (scope.defaultsInScope) {\n            scope.defaultsInvalid = true\n        }\n        val anchor = scope.anchor\n        if (anchor == null || !anchor.valid)\n            return InvalidationResult.IGNORED // The scope was removed from the composition\n        if (!slotStorage.ownsRecomposeScope(scope)) {\n            // The scope might be owned by the delegate\n            val delegate = synchronized(lock) { invalidationDelegate }\n            if (delegate?.tryImminentInvalidation(scope, instance) == true)\n                return InvalidationResult.IMMINENT // The scope was owned by the delegate\n\n            return InvalidationResult.IGNORED // The scope has not yet entered the composition\n        }\n        if (!scope.canRecompose)\n            return InvalidationResult.IGNORED // The scope isn't able to be recomposed/invalidated\n        return invalidateChecked(scope, anchor, instance).also {\n            if (it != InvalidationResult.IGNORED) {\n                observer()?.onScopeInvalidated(scope, instance)\n            }\n        }\n    }\n\n    override fun recomposeScopeReleased(scope: RecomposeScopeImpl) {\n        pendingInvalidScopes = true\n\n        observer()?.onScopeDisposed(scope)\n    }\n\n    @Suppress(\"UNCHECKED_CAST\")\n    override fun <T> getCompositionService(key: CompositionServiceKey<T>): T? =\n        if (key == ObservableCompositionServiceKey) this as T else null\n\n    private fun tryImminentInvalidation(scope: RecomposeScopeImpl, instance: Any?): Boolean =\n        isComposing && composer.tryImminentInvalidation(scope, instance)\n\n    private fun invalidateChecked(\n        scope: RecomposeScopeImpl,\n        anchor: Anchor,\n        instance: Any?,\n    ): InvalidationResult {\n        val delegate =\n            synchronized(lock) {\n                val delegate =\n                    invalidationDelegate?.let { changeDelegate ->\n                        // Invalidations are delegated when recomposing changes to movable content\n                        // that is destined to be moved. The movable content is composed in the\n                        // destination composer but all the recompose scopes point the current\n                        // composer and will arrive here. this redirects the invalidations that\n                        // will be moved to the destination composer instead of recording an\n                        // invalid invalidation in the from composer.\n                        if (slotStorage.groupContainsAnchor(invalidationDelegateGroup, anchor)) {\n                            changeDelegate\n                        } else null\n                    }\n                if (delegate == null) {\n                    if (tryImminentInvalidation(scope, instance)) {\n                        // The invalidation was redirected to the composer.\n                        return InvalidationResult.IMMINENT\n                    }\n\n                    // Observer requires a map of scope -> states, so we have to fill it if observer\n                    // is set.\n                    if (instance == null) {\n                        // invalidations[scope] containing ScopeInvalidated means it was invalidated\n                        // unconditionally.\n                        invalidations.set(scope, ScopeInvalidated)\n                    } else if (instance !is DerivedState<*>) {\n                        // If observer is not set, we only need to add derived states to\n                        // invalidation, as regular states are always going to invalidate.\n                        invalidations.set(scope, ScopeInvalidated)\n                    } else {\n                        if (!invalidations.anyScopeOf(scope) { it === ScopeInvalidated }) {\n                            invalidations.add(scope, instance)\n                        }\n                    }\n                }\n                delegate\n            }\n\n        // We call through the delegate here to ensure we don't nest synchronization scopes.\n        if (delegate != null) {\n            return delegate.invalidateChecked(scope, anchor, instance)\n        }\n        parent.invalidate(this)\n        return if (isComposing) InvalidationResult.DEFERRED else InvalidationResult.SCHEDULED\n    }\n\n    internal fun removeObservation(instance: Any, scope: RecomposeScopeImpl) {\n        observations.remove(instance, scope)\n    }\n\n    internal fun removeDerivedStateObservation(state: DerivedState<*>) {\n        // remove derived state if it is not observed in other scopes\n        if (state !in observations) {\n            derivedStates.removeScope(state)\n        }\n    }\n\n    /**\n     * This takes ownership of the current invalidations and sets up a new array map to hold the new\n     * invalidations.\n     */\n    private fun takeInvalidations(): ScopeMap<RecomposeScopeImpl, Any> {\n        val invalidations = invalidations\n        this.invalidations = ScopeMap()\n        return invalidations\n    }\n\n    private inline fun <T> trackAbandonedValues(block: () -> T): T {\n        var success = false\n        return try {\n            block().also { success = true }\n        } finally {\n            if (!success && abandonSet.isNotEmpty()) {\n                rememberManager.use(abandonSet, composer.errorContext) { dispatchAbandons() }\n            }\n        }\n    }\n\n    private fun observer(): CompositionObserver? = observerHolder.current()\n\n    override fun deactivate() {\n        synchronized(lock) {\n            checkPrecondition(pendingPausedComposition == null) {\n                \"Deactivate is not supported while pausable composition is in progress\"\n            }\n            val nonEmptySlotTable = !slotStorage.isEmpty\n            if (nonEmptySlotTable || abandonSet.isNotEmpty()) {\n                trace(\"Compose:deactivate\") {\n                    rememberManager.use(abandonSet, composer.errorContext) {\n                        if (nonEmptySlotTable) {\n                            applier.onBeginChanges()\n                            slotStorage.deactivateAll(rememberManager)\n                            applier.onEndChanges()\n                            dispatchRememberObservers()\n                        }\n                        dispatchAbandons()\n                    }\n                }\n            }\n            observations.clear()\n            derivedStates.clear()\n            invalidations.clear()\n            changes.clear()\n            lateChanges.clear()\n            composer.deactivate()\n\n            state = DEACTIVATED\n        }\n    }\n\n    // This is only used in tests to ensure the stacks do not silently leak.\n    internal fun composerStacksSizes(): Int = composer.stacksSize()\n}\n\ninternal object ScopeInvalidated\n\n@OptIn(ExperimentalComposeRuntimeApi::class)\ninternal class CompositionObserverHolder(\n    var observer: CompositionObserver? = null,\n    var root: Boolean = false,\n    private val parent: CompositionContext,\n) {\n    fun current(): CompositionObserver? {\n        return if (root) {\n            observer\n        } else {\n            val parentHolder = parent.observerHolder\n            val parentObserver = parentHolder?.observer\n            if (parentObserver != observer) {\n                observer = parentObserver\n            }\n            parentObserver\n        }\n    }\n}\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionLocal.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.runtime\n\n/**\n * Compose passes data through the composition tree explicitly through means of parameters to\n * composable functions. This is often times the simplest and best way to have data flow through the\n * tree.\n *\n * Sometimes this model can be cumbersome or break down for data that is needed by lots of\n * components, or when components need to pass data between one another but keep that implementation\n * detail private. For these cases, [CompositionLocal]s can be used as an implicit way to have data\n * flow through a composition.\n *\n * [CompositionLocal]s by their nature are hierarchical. They make sense when the value of the\n * [CompositionLocal] needs to be scoped to a particular sub-hierarchy of the composition.\n *\n * One must create a [CompositionLocal] instance, which can be referenced by the consumers\n * statically. [CompositionLocal] instances themselves hold no data, and can be thought of as a\n * type-safe identifier for the data being passed down a tree. [CompositionLocal] factory functions\n * take a single parameter: a factory to create a default value in cases where a [CompositionLocal]\n * is used without a Provider. If this is a situation you would rather not handle, you can throw an\n * error in this factory.\n *\n * @sample androidx.compose.runtime.samples.createCompositionLocal\n *\n * Somewhere up the tree, a [CompositionLocalProvider] component can be used, which provides a value\n * for the [CompositionLocal]. This would often be at the \"root\" of a tree, but could be anywhere,\n * and can also be used in multiple places to override the provided value for a sub-tree.\n *\n * @sample androidx.compose.runtime.samples.compositionLocalProvider\n *\n * Intermediate components do not need to know about the [CompositionLocal] value, and can have zero\n * dependencies on it. For example, `SomeScreen` might look like this:\n *\n * @sample androidx.compose.runtime.samples.someScreenSample\n *\n * Finally, a component that wishes to consume the [CompositionLocal] value can use the [current]\n * property of the [CompositionLocal] key which returns the current value of the [CompositionLocal],\n * and subscribes the component to changes of it.\n *\n * @sample androidx.compose.runtime.samples.consumeCompositionLocal\n */\n@Stable\npublic sealed class CompositionLocal<T>(defaultFactory: () -> T) {\n    internal open val defaultValueHolder: ValueHolder<T> = LazyValueHolder(defaultFactory)\n\n    internal abstract fun updatedStateOf(\n        value: ProvidedValue<T>,\n        previous: ValueHolder<T>?,\n    ): ValueHolder<T>\n\n    /**\n     * Return the value provided by the nearest [CompositionLocalProvider] component that invokes,\n     * directly or indirectly, the composable function that uses this property.\n     *\n     * @sample androidx.compose.runtime.samples.consumeCompositionLocal\n     */\n    @OptIn(InternalComposeApi::class)\n    public inline val current: T\n        @ReadOnlyComposable @Composable get() = currentComposer.consume(this)\n}\n\n/**\n * A [ProvidableCompositionLocal] can be used in [CompositionLocalProvider] to provide values.\n *\n * @see compositionLocalOf\n * @see staticCompositionLocalOf\n * @see CompositionLocal\n * @see CompositionLocalProvider\n */\n@Stable\npublic abstract class ProvidableCompositionLocal<T> internal constructor(defaultFactory: () -> T) :\n    CompositionLocal<T>(defaultFactory) {\n    internal abstract fun defaultProvidedValue(value: T): ProvidedValue<T>\n\n    /**\n     * Associates a [CompositionLocal] key to a value in a call to [CompositionLocalProvider].\n     *\n     * @see CompositionLocal\n     * @see ProvidableCompositionLocal\n     */\n    public infix fun provides(value: T): ProvidedValue<T> = defaultProvidedValue(value)\n\n    /**\n     * Associates a [CompositionLocal] key to a value in a call to [CompositionLocalProvider] if the\n     * key does not already have an associated value.\n     *\n     * @see CompositionLocal\n     * @see ProvidableCompositionLocal\n     */\n    public infix fun providesDefault(value: T): ProvidedValue<T> =\n        defaultProvidedValue(value).ifNotAlreadyProvided()\n\n    /**\n     * Associates a [CompositionLocal] key to a lambda, [compute], in a call to [CompositionLocal].\n     * The [compute] lambda is invoked whenever the key is retrieved. The lambda is executed in the\n     * context of a [CompositionLocalContext] which allow retrieving the current values of other\n     * composition locals by calling [CompositionLocalAccessorScope.currentValue], which is an\n     * extension function provided by the context for a [CompositionLocal] key.\n     *\n     * The lambda passed to [providesComputed] will be invoked every time the\n     * [CompositionLocal.current] is evaluated for the composition local and computes its value\n     * based on the current value of the locals referenced in the lambda at the time\n     * [CompositionLocal.current] is evaluated. This allows providing values that can be derived\n     * from other locals. For example, if accent colors can be calculated from a single base color,\n     * the accent colors can be provided as computed composition locals. Providing a new base color\n     * would automatically update all the accent colors.\n     *\n     * @sample androidx.compose.runtime.samples.compositionLocalProvidedComputed\n     * @sample androidx.compose.runtime.samples.compositionLocalComputedAfterProvidingLocal\n     * @see CompositionLocal\n     * @see CompositionLocalContext\n     * @see ProvidableCompositionLocal\n     */\n    public infix fun providesComputed(\n        compute: CompositionLocalAccessorScope.() -> T\n    ): ProvidedValue<T> =\n        ProvidedValue(\n            compositionLocal = this,\n            value = null,\n            explicitNull = false,\n            mutationPolicy = null,\n            state = null,\n            compute = compute,\n            isDynamic = false,\n        )\n\n    override fun updatedStateOf(\n        value: ProvidedValue<T>,\n        previous: ValueHolder<T>?,\n    ): ValueHolder<T> {\n        return when (previous) {\n            is DynamicValueHolder ->\n                if (value.isDynamic) {\n                    previous.state.value = value.effectiveValue\n                    previous\n                } else null\n            is StaticValueHolder ->\n                if (value.isStatic && value.effectiveValue == previous.value) previous else null\n            is ComputedValueHolder -> if (value.compute === previous.compute) previous else null\n            else -> null\n        } ?: valueHolderOf(value)\n    }\n\n    private fun valueHolderOf(value: ProvidedValue<T>): ValueHolder<T> =\n        when {\n            value.isDynamic ->\n                DynamicValueHolder(\n                    value.state\n                        ?: mutableStateOf(\n                            value.value,\n                            value.mutationPolicy ?: structuralEqualityPolicy(),\n                        )\n                )\n            value.compute != null -> ComputedValueHolder(value.compute)\n            value.state != null -> DynamicValueHolder(value.state)\n            else -> StaticValueHolder(value.effectiveValue)\n        }\n}\n\n/**\n * A [DynamicProvidableCompositionLocal] is a [CompositionLocal] backed by [mutableStateOf].\n * Providing new values using a [DynamicProvidableCompositionLocal] will provide the same [State]\n * with a different value. Reading the [CompositionLocal] value of a\n * [DynamicProvidableCompositionLocal] will record a read in the [RecomposeScope] of the\n * composition. Changing the provided value will invalidate the [RecomposeScope]s.\n *\n * @see compositionLocalOf\n */\ninternal class DynamicProvidableCompositionLocal<T>(\n    private val policy: SnapshotMutationPolicy<T>,\n    defaultFactory: () -> T,\n) : ProvidableCompositionLocal<T>(defaultFactory) {\n\n    override fun defaultProvidedValue(value: T) =\n        ProvidedValue(\n            compositionLocal = this,\n            value = value,\n            explicitNull = value === null,\n            mutationPolicy = policy,\n            state = null,\n            compute = null,\n            isDynamic = true,\n        )\n}\n\n/**\n * A [StaticProvidableCompositionLocal] is a value that is expected to rarely change.\n *\n * @see staticCompositionLocalOf\n */\ninternal class StaticProvidableCompositionLocal<T>(defaultFactory: () -> T) :\n    ProvidableCompositionLocal<T>(defaultFactory) {\n\n    override fun defaultProvidedValue(value: T) =\n        ProvidedValue(\n            compositionLocal = this,\n            value = value,\n            explicitNull = value === null,\n            mutationPolicy = null,\n            state = null,\n            compute = null,\n            isDynamic = false,\n        )\n}\n\n/**\n * Create a [CompositionLocal] key that can be provided using [CompositionLocalProvider]. Changing\n * the value provided during recomposition will invalidate the content of [CompositionLocalProvider]\n * that read the value using [CompositionLocal.current].\n *\n * [compositionLocalOf] creates a [ProvidableCompositionLocal] which can be used in a a call to\n * [CompositionLocalProvider]. Similar to [MutableList] vs. [List], if the key is made public as\n * [CompositionLocal] instead of [ProvidableCompositionLocal], it can be read using\n * [CompositionLocal.current] but not re-provided.\n *\n * @param policy a policy to determine when a [CompositionLocal] is considered changed. See\n *   [SnapshotMutationPolicy] for details.\n * @param defaultFactory a value factory to supply a value when a value is not provided. This\n *   factory is called when no value is provided through a [CompositionLocalProvider] of the caller\n *   of the component using [CompositionLocal.current]. If no reasonable default can be provided\n *   then consider throwing an exception.\n * @see CompositionLocal\n * @see staticCompositionLocalOf\n * @see mutableStateOf\n */\npublic fun <T> compositionLocalOf(\n    policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy(),\n    defaultFactory: () -> T,\n): ProvidableCompositionLocal<T> = DynamicProvidableCompositionLocal(policy, defaultFactory)\n\n/**\n * Create a [CompositionLocal] key that can be provided using [CompositionLocalProvider].\n *\n * Unlike [compositionLocalOf], reads of a [staticCompositionLocalOf] are not tracked by the\n * composer and changing the value provided in the [CompositionLocalProvider] call will cause the\n * entirety of the content to be recomposed instead of just the places where in the composition the\n * local value is used. This lack of tracking, however, makes a [staticCompositionLocalOf] more\n * efficient when the value provided is highly unlikely to or will never change. For example, the\n * android context, font loaders, or similar shared values, are unlikely to change for the\n * components in the content of a the [CompositionLocalProvider] and should consider using a\n * [staticCompositionLocalOf]. A color, or other theme like value, might change or even be animated\n * therefore a [compositionLocalOf] should be used.\n *\n * [staticCompositionLocalOf] creates a [ProvidableCompositionLocal] which can be used in a a call\n * to [CompositionLocalProvider]. Similar to [MutableList] vs. [List], if the key is made public as\n * [CompositionLocal] instead of [ProvidableCompositionLocal], it can be read using\n * [CompositionLocal.current] but not re-provided.\n *\n * @param defaultFactory a value factory to supply a value when a value is not provided. This\n *   factory is called when no value is provided through a [CompositionLocalProvider] of the caller\n *   of the component using [CompositionLocal.current]. If no reasonable default can be provided\n *   then consider throwing an exception.\n * @see CompositionLocal\n * @see compositionLocalOf\n */\npublic fun <T> staticCompositionLocalOf(defaultFactory: () -> T): ProvidableCompositionLocal<T> =\n    StaticProvidableCompositionLocal(defaultFactory)\n\n/**\n * Create a [CompositionLocal] that behaves like it was provided using\n * [ProvidableCompositionLocal.providesComputed] by default. If a value is provided using\n * [ProvidableCompositionLocal.provides] it behaves as if the [CompositionLocal] was produced by\n * calling [compositionLocalOf].\n *\n * In other words, a [CompositionLocal] produced by can be provided identically to\n * [CompositionLocal] created with [compositionLocalOf] with the only difference is how it behaves\n * when the value is not provided. For a [compositionLocalOf] the default value is returned. If no\n * default value has be computed for [CompositionLocal] the default computation is called.\n *\n * The lambda passed to [compositionLocalWithComputedDefaultOf] will be invoked every time the\n * [CompositionLocal.current] is evaluated for the composition local and computes its value based on\n * the current value of the locals referenced in the lambda at the time [CompositionLocal.current]\n * is evaluated. This allows providing values that can be derived from other locals. For example, if\n * accent colors can be calculated from a single base color, the accent colors can be provided as\n * computed composition locals. Providing a new base color would automatically update all the accent\n * colors.\n *\n * @sample androidx.compose.runtime.samples.compositionLocalComputedByDefault\n * @sample androidx.compose.runtime.samples.compositionLocalComputedAfterProvidingLocal\n * @param defaultComputation the default computation to use when this [CompositionLocal] is not\n *   provided.\n * @see CompositionLocal\n * @see ProvidableCompositionLocal\n */\npublic fun <T> compositionLocalWithComputedDefaultOf(\n    defaultComputation: CompositionLocalAccessorScope.() -> T\n): ProvidableCompositionLocal<T> = ComputedProvidableCompositionLocal(defaultComputation)\n\ninternal class ComputedProvidableCompositionLocal<T>(\n    defaultComputation: CompositionLocalAccessorScope.() -> T\n) : ProvidableCompositionLocal<T>({ composeRuntimeError(\"Unexpected call to default provider\") }) {\n    override val defaultValueHolder = ComputedValueHolder(defaultComputation)\n\n    override fun defaultProvidedValue(value: T): ProvidedValue<T> =\n        ProvidedValue(\n            compositionLocal = this,\n            value = value,\n            explicitNull = value === null,\n            mutationPolicy = null,\n            state = null,\n            compute = null,\n            isDynamic = true,\n        )\n}\n\n/**\n * Creates a [ProvidableCompositionLocal] where the default value is resolved by querying the\n * [LocalHostDefaultProvider] with the given [key].\n *\n * If a value is provided using [ProvidableCompositionLocal.provides], this behaves identically to a\n * [CompositionLocal] created with [compositionLocalOf].\n *\n * When no value is provided, the default value is resolved by querying the\n * [LocalHostDefaultProvider] currently present in the composition. This mechanism allows the\n * default value to be determined dynamically by the hosting environment (such as an Android View)\n * rather than being hardcoded or requiring an explicit provider at the root of the composition.\n *\n * This effectively acts as a bridge, decoupling the definition of the [CompositionLocal] from the\n * platform-specific logic required to resolve its default. For example, a\n * `LocalViewModelStoreOwner` can use this to ask the host for the owner without having a direct\n * dependency on the Android View system.\n *\n * @param key An opaque key used to identify the requested value within the host's context. The type\n *   and meaning of the key are defined by the [HostDefaultProvider] implementation (e.g., on\n *   Android, this is typically a Resource ID).\n * @throws NullPointerException If the host cannot find a value for [key], it returns `null`. If [T]\n *   is a non-nullable type (e.g., `compositionLocalWithHostDefaultOf<String>`), a missing key will\n *   result in a [NullPointerException] when the value is accessed.\n */\npublic fun <T> compositionLocalWithHostDefaultOf(\n    key: HostDefaultKey<T>\n): ProvidableCompositionLocal<T> = compositionLocalWithComputedDefaultOf {\n    LocalHostDefaultProvider.currentValue.getHostDefault(key)\n}\n\npublic interface CompositionLocalAccessorScope {\n    /**\n     * An extension property that allows accessing the current value of a composition local in the\n     * context of this scope. This scope is the type of the `this` parameter when in a computed\n     * composition. Computed composition locals can be provided by either using\n     * [compositionLocalWithComputedDefaultOf] or by using the\n     * [ProvidableCompositionLocal.providesComputed] infix operator.\n     *\n     * @sample androidx.compose.runtime.samples.compositionLocalProvidedComputed\n     * @see ProvidableCompositionLocal\n     * @see ProvidableCompositionLocal.providesComputed\n     * @see ProvidableCompositionLocal.provides\n     * @see CompositionLocalProvider\n     */\n    public val <T> CompositionLocal<T>.currentValue: T\n}\n\n/**\n * Stores [CompositionLocal]'s and their values.\n *\n * Can be obtained via [currentCompositionLocalContext] and passed to another composition via\n * [CompositionLocalProvider].\n *\n * [CompositionLocalContext] is immutable and won't be changed after its obtaining.\n */\n@Stable\npublic class CompositionLocalContext\ninternal constructor(internal val compositionLocals: PersistentCompositionLocalMap) {\n    override fun equals(other: Any?): Boolean {\n        return other is CompositionLocalContext && other.compositionLocals == this.compositionLocals\n    }\n\n    override fun hashCode(): Int {\n        return compositionLocals.hashCode()\n    }\n}\n\n/**\n * [CompositionLocalProvider] binds values to [ProvidableCompositionLocal] keys. Reading the\n * [CompositionLocal] using [CompositionLocal.current] will return the value provided in\n * [CompositionLocalProvider]'s [values] parameter for all composable functions called directly or\n * indirectly in the [content] lambda.\n *\n * @sample androidx.compose.runtime.samples.compositionLocalProvider\n * @see CompositionLocal\n * @see compositionLocalOf\n * @see staticCompositionLocalOf\n */\n@Composable\n@OptIn(InternalComposeApi::class)\n@NonSkippableComposable\npublic fun CompositionLocalProvider(\n    vararg values: ProvidedValue<*>,\n    content: @Composable () -> Unit,\n) {\n    currentComposer.startProviders(values)\n    content()\n    currentComposer.endProviders()\n}\n\n/**\n * [CompositionLocalProvider] binds value to [ProvidableCompositionLocal] key. Reading the\n * [CompositionLocal] using [CompositionLocal.current] will return the value provided in\n * [CompositionLocalProvider]'s [value] parameter for all composable functions called directly or\n * indirectly in the [content] lambda.\n *\n * @sample androidx.compose.runtime.samples.compositionLocalProvider\n * @see CompositionLocal\n * @see compositionLocalOf\n * @see staticCompositionLocalOf\n */\n@Composable\n@OptIn(InternalComposeApi::class)\n@NonSkippableComposable\npublic fun CompositionLocalProvider(value: ProvidedValue<*>, content: @Composable () -> Unit) {\n    currentComposer.startProvider(value)\n    content()\n    currentComposer.endProvider()\n}\n\n/**\n * [CompositionLocalProvider] binds values to [CompositionLocal]'s, provided by [context]. Reading\n * the [CompositionLocal] using [CompositionLocal.current] will return the value provided in values\n * stored inside [context] for all composable functions called directly or indirectly in the\n * [content] lambda.\n *\n * @sample androidx.compose.runtime.samples.compositionLocalProvider\n * @see CompositionLocal\n * @see compositionLocalOf\n * @see staticCompositionLocalOf\n */\n@Composable\npublic fun CompositionLocalProvider(\n    context: CompositionLocalContext,\n    content: @Composable () -> Unit,\n) {\n    CompositionLocalProvider(\n        *context.compositionLocals.map { it.value.toProvided(it.key) }.toTypedArray(),\n        content = content,\n    )\n}\n\n/**\n * [withCompositionLocal] binds value to [ProvidableCompositionLocal] key and returns the result\n * produced by the [content] lambda. Use with non-unit returning [content] lambdas or else use\n * [CompositionLocalProvider]. Reading the [CompositionLocal] using [CompositionLocal.current] will\n * return the value provided in [CompositionLocalProvider]'s [value] parameter for all composable\n * functions called directly or indirectly in the [content] lambda.\n *\n * @see CompositionLocalProvider\n * @see CompositionLocal\n * @see compositionLocalOf\n * @see staticCompositionLocalOf\n */\n@Suppress(\"BanInlineOptIn\") // b/430604046 - These APIs are stable so are ok to inline\n@OptIn(InternalComposeApi::class)\n@Composable\npublic inline fun <T> withCompositionLocal(\n    value: ProvidedValue<*>,\n    content: @Composable () -> T,\n): T {\n    currentComposer.startProvider(value)\n    return content().also { currentComposer.endProvider() }\n}\n\n/**\n * [withCompositionLocals] binds values to [ProvidableCompositionLocal] key and returns the result\n * produced by the [content] lambda. Use with non-unit returning [content] lambdas or else use\n * [CompositionLocalProvider]. Reading the [CompositionLocal] using [CompositionLocal.current] will\n * return the values provided in [CompositionLocalProvider]'s [values] parameter for all composable\n * functions called directly or indirectly in the [content] lambda.\n *\n * @see CompositionLocalProvider\n * @see CompositionLocal\n * @see compositionLocalOf\n * @see staticCompositionLocalOf\n */\n@Suppress(\"BanInlineOptIn\") // b/430604046 - These APIs are stable so are ok to inline\n@OptIn(InternalComposeApi::class)\n@Composable\npublic inline fun <T> withCompositionLocals(\n    vararg values: ProvidedValue<*>,\n    content: @Composable () -> T,\n): T {\n    currentComposer.startProviders(values)\n    return content().also { currentComposer.endProvider() }\n}\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/CompositionContext.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.runtime\n\nimport androidx.collection.ScatterSet\nimport androidx.compose.runtime.internal.persistentCompositionLocalHashMapOf\nimport androidx.compose.runtime.tooling.CompositionData\nimport kotlin.coroutines.CoroutineContext\n\nprivate val EmptyPersistentCompositionLocalMap: PersistentCompositionLocalMap =\n    persistentCompositionLocalHashMapOf()\n\n/**\n * A [CompositionContext] is an opaque type that is used to logically \"link\" two compositions\n * together. The [CompositionContext] instance represents a reference to the \"parent\" composition in\n * a specific position of that composition's tree, and the instance can then be given to a new\n * \"child\" composition. This reference ensures that invalidations and [CompositionLocal]s flow\n * logically through the two compositions as if they were not separate.\n *\n * The \"parent\" of a root composition is a [Recomposer].\n *\n * @see rememberCompositionContext\n */\n@OptIn(InternalComposeApi::class, ExperimentalComposeRuntimeApi::class)\npublic abstract class CompositionContext internal constructor() {\n    internal abstract val compositeKeyHashCode: CompositeKeyHashCode\n    internal abstract val collectingParameterInformation: Boolean\n    internal abstract val collectingSourceInformation: Boolean\n    internal abstract val collectingCallByInformation: Boolean\n    internal abstract val stackTraceEnabled: Boolean\n    internal open val observerHolder: CompositionObserverHolder?\n        get() = null\n\n    /** The [CoroutineContext] with which effects for the composition will be executed in. */\n    public abstract val effectCoroutineContext: CoroutineContext\n\n    /** Associated composition if one exists. */\n    internal abstract val composition: Composition?\n\n    internal abstract fun composeInitial(\n        composition: ControlledComposition,\n        content: @Composable () -> Unit,\n    )\n\n    internal abstract fun composeInitialPaused(\n        composition: ControlledComposition,\n        shouldPause: ShouldPauseCallback,\n        content: @Composable () -> Unit,\n    ): ScatterSet<RecomposeScopeImpl>\n\n    internal abstract fun recomposePaused(\n        composition: ControlledComposition,\n        shouldPause: ShouldPauseCallback,\n        invalidScopes: ScatterSet<RecomposeScopeImpl>,\n    ): ScatterSet<RecomposeScopeImpl>\n\n    internal abstract fun reportPausedScope(scope: RecomposeScopeImpl)\n\n    internal abstract fun invalidate(composition: ControlledComposition)\n\n    internal abstract fun invalidateScope(scope: RecomposeScopeImpl)\n\n    internal open fun recordInspectionTable(table: MutableSet<CompositionData>) {}\n\n    internal open fun registerComposer(composer: Composer) {}\n\n    internal open fun unregisterComposer(composer: Composer) {}\n\n    internal abstract fun registerComposition(composition: ControlledComposition)\n\n    internal abstract fun unregisterComposition(composition: ControlledComposition)\n\n    internal open fun getCompositionLocalScope(): PersistentCompositionLocalMap =\n        EmptyPersistentCompositionLocalMap\n\n    internal open fun startComposing() {}\n\n    internal open fun doneComposing() {}\n\n    internal abstract fun insertMovableContent(reference: MovableContentStateReference)\n\n    internal abstract fun deletedMovableContent(reference: MovableContentStateReference)\n\n    internal abstract fun movableContentStateReleased(\n        reference: MovableContentStateReference,\n        data: MovableContentState,\n        applier: Applier<*>,\n    )\n\n    internal open fun movableContentStateResolve(\n        reference: MovableContentStateReference\n    ): MovableContentState? = null\n\n    internal abstract fun reportRemovedComposition(composition: ControlledComposition)\n\n    public abstract fun scheduleFrameEndCallback(action: () -> Unit): CancellationHandle\n}\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Composer.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@file:OptIn(InternalComposeApi::class)\n@file:Suppress(\"NOTHING_TO_INLINE\", \"KotlinRedundantDiagnosticSuppress\")\n\npackage androidx.compose.runtime\n\nimport androidx.compose.runtime.Composer.Companion.Empty\nimport androidx.compose.runtime.collection.ScopeMap\nimport androidx.compose.runtime.composer.RememberManager\nimport androidx.compose.runtime.composer.gapbuffer.SlotReader\nimport androidx.compose.runtime.composer.gapbuffer.SlotTable\nimport androidx.compose.runtime.composer.gapbuffer.SlotWriter\nimport androidx.compose.runtime.composer.gapbuffer.asGapAnchor\nimport androidx.compose.runtime.tooling.ComposeStackTrace\nimport androidx.compose.runtime.tooling.ComposeStackTraceFrame\nimport androidx.compose.runtime.tooling.ComposeStackTraceMode\nimport androidx.compose.runtime.tooling.CompositionData\nimport androidx.compose.runtime.tooling.CompositionErrorContextImpl\nimport kotlin.contracts.ExperimentalContracts\nimport kotlin.contracts.contract\nimport kotlin.coroutines.CoroutineContext\nimport kotlin.jvm.JvmInline\nimport kotlin.jvm.JvmName\n\n/**\n * Internal compose compiler plugin API that is used to update the function the composer will call\n * to recompose a recomposition scope. This should not be used or called directly.\n */\n@ComposeCompilerApi\npublic interface ScopeUpdateScope {\n    /**\n     * Called by generated code to update the recomposition scope with the function to call\n     * recompose the scope. This is called by code generated by the compose compiler plugin and\n     * should not be called directly.\n     */\n    public fun updateScope(block: (Composer, Int) -> Unit)\n}\n\ninternal enum class InvalidationResult {\n    /**\n     * The invalidation was ignored because the associated recompose scope is no longer part of the\n     * composition or has yet to be entered in the composition. This could occur for invalidations\n     * called on scopes that are no longer part of composition or if the scope was invalidated\n     * before [ControlledComposition.applyChanges] was called that will enter the scope into the\n     * composition.\n     */\n    IGNORED,\n\n    /**\n     * The composition is not currently composing and the invalidation was recorded for a future\n     * composition. A recomposition requested to be scheduled.\n     */\n    SCHEDULED,\n\n    /**\n     * The composition that owns the recompose scope is actively composing but the scope has already\n     * been composed or is in the process of composing. The invalidation is treated as SCHEDULED\n     * above.\n     */\n    DEFERRED,\n\n    /**\n     * The composition that owns the recompose scope is actively composing and the invalidated scope\n     * has not been composed yet but will be recomposed before the composition completes. A new\n     * recomposition was not scheduled for this invalidation.\n     */\n    IMMINENT,\n}\n\n/**\n * An instance to hold a value provided by [CompositionLocalProvider] and is created by the\n * [ProvidableCompositionLocal.provides] infix operator. If [canOverride] is `false`, the provided\n * value will not overwrite a potentially already existing value in the scope.\n *\n * This value cannot be created directly. It can only be created by using one of the `provides`\n * operators of [ProvidableCompositionLocal].\n *\n * @see ProvidableCompositionLocal.provides\n * @see ProvidableCompositionLocal.providesDefault\n * @see ProvidableCompositionLocal.providesComputed\n */\npublic class ProvidedValue<T>\ninternal constructor(\n    /**\n     * The composition local that is provided by this value. This is the left-hand side of the\n     * [ProvidableCompositionLocal.provides] infix operator.\n     */\n    public val compositionLocal: CompositionLocal<T>,\n    value: T?,\n    private val explicitNull: Boolean,\n    internal val mutationPolicy: SnapshotMutationPolicy<T>?,\n    internal val state: MutableState<T>?,\n    internal val compute: (CompositionLocalAccessorScope.() -> T)?,\n    internal val isDynamic: Boolean,\n) {\n    private val providedValue: T? = value\n\n    /**\n     * The value provided by the [ProvidableCompositionLocal.provides] infix operator. This is the\n     * right-hand side of the operator.\n     */\n    @Suppress(\"UNCHECKED_CAST\")\n    public val value: T\n        get() = providedValue as T\n\n    /**\n     * This value is `true` if the provided value will override any value provided above it. This\n     * value is `true` when using [ProvidableCompositionLocal.provides] but `false` when using\n     * [ProvidableCompositionLocal.providesDefault].\n     *\n     * @see ProvidableCompositionLocal.provides\n     * @see ProvidableCompositionLocal.providesDefault\n     */\n    @get:JvmName(\"getCanOverride\")\n    public var canOverride: Boolean = true\n        private set\n\n    @Suppress(\"UNCHECKED_CAST\")\n    internal val effectiveValue: T\n        get() =\n            when {\n                explicitNull -> null as T\n                state != null -> state.value\n                providedValue != null -> providedValue\n                else -> composeRuntimeError(\"Unexpected form of a provided value\")\n            }\n\n    internal val isStatic\n        get() = (explicitNull || value != null) && !isDynamic\n\n    internal fun ifNotAlreadyProvided() = this.also { canOverride = false }\n}\n\nprivate val SlotWriter.nextGroup\n    get() = currentGroup + groupSize(currentGroup)\n\n/**\n * Composer is the interface that is targeted by the Compose Kotlin compiler plugin and used by code\n * generation helpers. It is highly recommended that direct calls these be avoided as the runtime\n * assumes that the calls are generated by the compiler and contain only a minimum amount of state\n * validation.\n */\npublic sealed interface Composer {\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Changes calculated and recorded during composition and are sent to [applier] which makes the\n     * physical changes to the node tree implied by a composition.\n     *\n     * Composition has two discrete phases, 1) calculate and record changes and 2) making the\n     * changes via the [applier]. While a [Composable] functions is executing, none of the [applier]\n     * methods are called. The recorded changes are sent to the [applier] all at once after all\n     * [Composable] functions have completed.\n     */\n    @ComposeCompilerApi public val applier: Applier<*>\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Reflects that a new part of the composition is being created, that is, the composition will\n     * insert new nodes into the resulting tree.\n     */\n    @ComposeCompilerApi public val inserting: Boolean\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Reflects whether the [Composable] function can skip. Even if a [Composable] function is\n     * called with the same parameters it might still need to run because, for example, a new value\n     * was provided for a [CompositionLocal] created by [staticCompositionLocalOf].\n     */\n    @ComposeCompilerApi public val skipping: Boolean\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Reflects whether the default parameter block of a [Composable] function is valid. This is\n     * `false` if a [State] object read in the [startDefaults] group was modified since the last\n     * time the [Composable] function was run.\n     */\n    @ComposeCompilerApi public val defaultsInvalid: Boolean\n\n    /**\n     * A Compose internal property. DO NOT call directly. Use [currentRecomposeScope] instead.\n     *\n     * The invalidation current invalidation scope. An new invalidation scope is created whenever\n     * [startRestartGroup] is called. when this scope's [RecomposeScope.invalidate] is called then\n     * lambda supplied to [endRestartGroup]'s [ScopeUpdateScope] will be scheduled to be run.\n     */\n    @InternalComposeApi public val recomposeScope: RecomposeScope?\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Return an object that can be used to uniquely identity of the current recomposition scope.\n     * This identity will be the same even if the recompose scope instance changes.\n     *\n     * This is used internally by tooling track composable function invocations.\n     */\n    @ComposeCompilerApi public val recomposeScopeIdentity: Any?\n\n    /**\n     * A Compose internal property. DO NOT call directly. Use [currentCompositeKeyHash] instead.\n     *\n     * This a hash value used to map externally stored state to the composition. For example, this\n     * is used by saved instance state to preserve state across activity lifetime boundaries.\n     *\n     * This value is likely but not guaranteed to be unique. There are known cases, such as for\n     * loops without a unique [key], where the runtime does not have enough information to make the\n     * compound key hash unique.\n     */\n    @Deprecated(\n        \"Prefer the higher-precision compositeKeyHashCode instead\",\n        ReplaceWith(\"compositeKeyHashCode\"),\n    )\n    @InternalComposeApi\n    public val compoundKeyHash: Int\n        get() = compositeKeyHashCode.hashCode()\n\n    /**\n     * A Compose internal property. DO NOT call directly. Use [currentCompositeKeyHashCode] instead.\n     *\n     * This a hash value used to map externally stored state to the composition. For example, this\n     * is used by saved instance state to preserve state across activity lifetime boundaries.\n     *\n     * This value is likely but not guaranteed to be unique. There are known cases, such as for\n     * loops without a unique [key], where the runtime does not have enough information to make the\n     * compound key hash unique.\n     */\n    @InternalComposeApi public val compositeKeyHashCode: CompositeKeyHashCode\n\n    // Groups\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Start a replaceable group. A replaceable group is a group that cannot be moved during\n     * execution and can only either inserted, removed, or replaced. For example, the group created\n     * by most control flow constructs such as an `if` statement are replaceable groups.\n     *\n     * Warning: Versions of the compiler that generate calls to this function also contain subtle\n     * bug that does not generate a group around a loop containing code that just creates composable\n     * lambdas (AnimatedContent from androidx.compose.animation, for example) which makes replacing\n     * the group unsafe and the this must treat this like a movable group. [startReplaceGroup] was\n     * added that will replace the group as described above and is only called by versions of the\n     * compiler that correctly generate code around loops that create lambdas. This method is kept\n     * to maintain compatibility with code generated by older versions of the compose compiler\n     * plugin.\n     *\n     * @param key A compiler generated key based on the source location of the call.\n     */\n    @ComposeCompilerApi public fun startReplaceableGroup(key: Int)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Called at the end of a replaceable group.\n     *\n     * @see startRestartGroup\n     */\n    @ComposeCompilerApi public fun endReplaceableGroup()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Start a replace group. A replace group is a group that cannot be moved during must only\n     * either be inserted, removed, or replaced. For example, the group created by most control flow\n     * constructs such as an `if` statement are replaceable groups.\n     *\n     * Note: This method replaces [startReplaceableGroup] which is only generated by older versions\n     * of the compose compiler plugin that predate the addition of this method. The runtime is now\n     * required to replace the group if a different group is detected instead of treating it like a\n     * movable group.\n     *\n     * @param key A compiler generated key based on the source location of the call.\n     * @see endReplaceGroup\n     */\n    @ComposeCompilerApi public fun startReplaceGroup(key: Int)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Called at the end of a replace group.\n     *\n     * @see startReplaceGroup\n     */\n    @ComposeCompilerApi public fun endReplaceGroup()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Start a movable group. A movable group is one that can be moved based on the value of\n     * [dataKey] which is typically supplied by the [key][androidx.compose.runtime.key] pseudo\n     * compiler function.\n     *\n     * A movable group implements the semantics of [key][androidx.compose.runtime.key] which allows\n     * the state and nodes generated by a loop to move with the composition implied by the key\n     * passed to [key][androidx.compose.runtime.key].\n     *\n     * @param key a compiler generated key based on the source location of the call.\n     * @param dataKey an additional object that is used as a second part of the key. This key\n     *   produced from the `keys` parameter supplied to the [key][androidx.compose.runtime.key]\n     *   pseudo compiler function.\n     */\n    @ComposeCompilerApi public fun startMovableGroup(key: Int, dataKey: Any?)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Called at the end of a movable group.\n     *\n     * @see startMovableGroup\n     */\n    @ComposeCompilerApi public fun endMovableGroup()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Called to start the group that calculates the default parameters of a [Composable] function.\n     *\n     * This method is called near the beginning of a [Composable] function with default parameters\n     * and surrounds the remembered values or [Composable] calls necessary to produce the default\n     * parameters. For example, for `model: Model = remember { DefaultModel() }` the call to\n     * [remember] is called inside a [startDefaults] group.\n     */\n    @ComposeCompilerApi public fun startDefaults()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Called at the end of defaults group.\n     *\n     * @see startDefaults\n     */\n    @ComposeCompilerApi public fun endDefaults()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Called to record a group for a [Composable] function and starts a group that can be\n     * recomposed on demand based on the lambda passed to\n     * [updateScope][ScopeUpdateScope.updateScope] when [endRestartGroup] is called\n     *\n     * @param key A compiler generated key based on the source location of the call.\n     * @return the instance of the composer to use for the rest of the function.\n     */\n    @ComposeCompilerApi public fun startRestartGroup(key: Int): Composer\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Called to end a restart group.\n     */\n    @ComposeCompilerApi public fun endRestartGroup(): ScopeUpdateScope?\n\n    /**\n     * A Compose internal API. DO NOT call directly.\n     *\n     * Request movable content be inserted at the current location. This will schedule with the root\n     * composition parent a call to [insertMovableContent] with the correct [MovableContentState] if\n     * one was released in another part of composition.\n     */\n    @InternalComposeApi public fun insertMovableContent(value: MovableContent<*>, parameter: Any?)\n\n    /**\n     * A Compose internal API. DO NOT call directly.\n     *\n     * Perform a late composition that adds to the current late apply that will insert the given\n     * references to [MovableContent] into the composition. If a [MovableContent] is paired then\n     * this is a request to move a released [MovableContent] from a different location or from a\n     * different composition. If it is not paired (i.e. the `second` [MovableContentStateReference]\n     * is `null`) then new state for the [MovableContent] is inserted into the composition.\n     */\n    @InternalComposeApi\n    public fun insertMovableContentReferences(\n        references: List<Pair<MovableContentStateReference, MovableContentStateReference?>>\n    )\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Record the source information string for a group. This must be immediately called after the\n     * start of a group.\n     *\n     * @param sourceInformation An string value to that provides the compose tools enough\n     *   information to calculate the source location of calls to composable functions.\n     */\n    public fun sourceInformation(sourceInformation: String)\n\n    /**\n     * A compose compiler plugin API. DO NOT call directly.\n     *\n     * Record a source information marker. This marker can be used in place of a group that would\n     * have contained the information but was elided as the compiler plugin determined the group was\n     * not necessary such as when a function is marked with [ReadOnlyComposable].\n     *\n     * @param key A compiler generated key based on the source location of the call.\n     * @param sourceInformation An string value to that provides the compose tools enough\n     *   information to calculate the source location of calls to composable functions.\n     */\n    public fun sourceInformationMarkerStart(key: Int, sourceInformation: String)\n\n    /**\n     * A compose compiler plugin API. DO NOT call directly.\n     *\n     * Record the end of the marked source information range.\n     */\n    public fun sourceInformationMarkerEnd()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Skips the composer to the end of the current group. This generated by the compiler to when\n     * the body of a [Composable] function can be skipped typically because the parameters to the\n     * function are equal to the values passed to it in the previous composition.\n     */\n    @ComposeCompilerApi public fun skipToGroupEnd()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Deactivates the content to the end of the group by treating content as if it was deleted and\n     * replaces all slot table entries for calls to [cache] to be [Empty]. This must be called as\n     * the first call for a group.\n     */\n    @ComposeCompilerApi public fun deactivateToEndGroup(changed: Boolean)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Skips the current group. This called by the compiler to indicate that the current group can\n     * be skipped, for example, this is generated to skip the [startDefaults] group the default\n     * group is was not invalidated.\n     */\n    @ComposeCompilerApi public fun skipCurrentGroup()\n\n    // Nodes\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Start a group that tracks a the code that will create or update a node that is generated as\n     * part of the tree implied by the composition.\n     */\n    @ComposeCompilerApi public fun startNode()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Start a group that tracks a the code that will create or update a node that is generated as\n     * part of the tree implied by the composition. A reusable node can be reused in a reusable\n     * group even if the group key is changed.\n     */\n    @ComposeCompilerApi public fun startReusableNode()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Report the [factory] that will be used to create the node that will be generated into the\n     * tree implied by the composition. This will only be called if [inserting] is is `true`.\n     *\n     * @param factory a factory function that will generate a node that will eventually be supplied\n     *   to [applier] though [Applier.insertBottomUp] and [Applier.insertTopDown].\n     */\n    @ComposeCompilerApi public fun <T> createNode(factory: () -> T)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Report that the node is still being used. This will be called in the same location as the\n     * corresponding [createNode] when [inserting] is `false`.\n     */\n    @ComposeCompilerApi public fun useNode()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Called at the end of a node group.\n     */\n    @ComposeCompilerApi public fun endNode()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Start a reuse group. Unlike a movable group, in a reuse group if the [dataKey] changes the\n     * composition shifts into a reusing state cause the composer to act like it is inserting (e.g.\n     * [cache] acts as if all values are invalid, [changed] always returns true, etc.) even though\n     * it is recomposing until it encounters a reusable node. If the node is reusable it temporarily\n     * shifts into recomposition for the node and then shifts back to reusing for the children. If a\n     * non-reusable node is generated the composer shifts to inserting for the node and all of its\n     * children.\n     *\n     * @param key An compiler generated key based on the source location of the call.\n     * @param dataKey A key provided by the [ReusableContent] composable function that is used to\n     *   determine if the composition shifts into a reusing state for this group.\n     */\n    @ComposeCompilerApi public fun startReusableGroup(key: Int, dataKey: Any?)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Called at the end of a reusable group.\n     */\n    @ComposeCompilerApi public fun endReusableGroup()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Temporarily disable reusing if it is enabled.\n     */\n    @ComposeCompilerApi public fun disableReusing()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Reenable reusing if it was previously enabled before the last call to [disableReusing].\n     */\n    @ComposeCompilerApi public fun enableReusing()\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Return a marker for the current group that can be used in a call to [endToMarker].\n     */\n    @ComposeCompilerApi public val currentMarker: Int\n\n    /**\n     * Compose compiler plugin API. DO NOT call directly.\n     *\n     * Ends all the groups up to but not including the group that is the parent group when\n     * [currentMarker] was called to produce [marker]. All groups ended must have been started with\n     * either [startReplaceableGroup] or [startMovableGroup]. Ending other groups can cause the\n     * state of the composer to become inconsistent.\n     */\n    @ComposeCompilerApi public fun endToMarker(marker: Int)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Schedule [block] to called with [value]. This is intended to update the node generated by\n     * [createNode] to changes discovered by composition.\n     *\n     * @param value the new value to be set into some property of the node.\n     * @param block the block that sets the some property of the node to [value].\n     */\n    @ComposeCompilerApi public fun <V, T> apply(value: V, block: T.(V) -> Unit)\n\n    // State\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Produce an object that will compare equal an iff [left] and [right] compare equal to some\n     * [left] and [right] of a previous call to [joinKey]. This is used by [key] to handle multiple\n     * parameters. Since the previous composition stored [left] and [right] in a \"join key\" object\n     * this call is used to return the previous value without an allocation instead of blindly\n     * creating a new value that will be immediately discarded.\n     *\n     * @param left the first part of a a joined key.\n     * @param right the second part of a joined key.\n     * @return an object that will compare equal to a value previously returned by [joinKey] iff\n     *   [left] and [right] compare equal to the [left] and [right] passed to the previous call.\n     */\n    @ComposeCompilerApi public fun joinKey(left: Any?, right: Any?): Any\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Remember a value into the composition state. This is a primitive method used to implement\n     * [remember].\n     *\n     * @return [Composer.Empty] when [inserting] is `true` or the value passed to\n     *   [updateRememberedValue] from the previous composition.\n     * @see cache\n     */\n    @ComposeCompilerApi public fun rememberedValue(): Any?\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Update the remembered value correspond to the previous call to [rememberedValue]. The [value]\n     * will be returned by [rememberedValue] for the next composition.\n     */\n    @ComposeCompilerApi public fun updateRememberedValue(value: Any?)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Check [value] is different than the value used in the previous composition. This is used, for\n     * example, to check parameter values to determine if they have changed.\n     *\n     * @param value the value to check\n     * @return `true` if the value if [equals] of the previous value returns `false` when passed\n     *   [value].\n     */\n    @ComposeCompilerApi public fun changed(value: Any?): Boolean\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Check [value] is different than the value used in the previous composition. This is used, for\n     * example, to check parameter values to determine if they have changed.\n     *\n     * This overload is provided to avoid boxing [value] to compare with a potentially boxed version\n     * of [value] in the composition state.\n     *\n     * @param value the value to check\n     * @return `true` if the value if [equals] of the previous value returns `false` when passed\n     *   [value].\n     */\n    @ComposeCompilerApi public fun changed(value: Boolean): Boolean = changed(value)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Check [value] is different than the value used in the previous composition. This is used, for\n     * example, to check parameter values to determine if they have changed.\n     *\n     * This overload is provided to avoid boxing [value] to compare with a potentially boxed version\n     * of [value] in the composition state.\n     *\n     * @param value the value to check\n     * @return `true` if the value if [equals] of the previous value returns `false` when passed\n     *   [value].\n     */\n    @ComposeCompilerApi public fun changed(value: Char): Boolean = changed(value)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Check [value] is different than the value used in the previous composition. This is used, for\n     * example, to check parameter values to determine if they have changed.\n     *\n     * This overload is provided to avoid boxing [value] to compare with a potentially boxed version\n     * of [value] in the composition state.\n     *\n     * @param value the value to check\n     * @return `true` if the value if [equals] of the previous value returns `false` when passed\n     *   [value].\n     */\n    @ComposeCompilerApi public fun changed(value: Byte): Boolean = changed(value)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Check [value] is different than the value used in the previous composition. This is used, for\n     * example, to check parameter values to determine if they have changed.\n     *\n     * This overload is provided to avoid boxing [value] to compare with a potentially boxed version\n     * of [value] in the composition state.\n     *\n     * @param value the value to check\n     * @return `true` if the value if [equals] of the previous value returns `false` when passed\n     *   [value].\n     */\n    @ComposeCompilerApi public fun changed(value: Short): Boolean = changed(value)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Check [value] is different than the value used in the previous composition. This is used, for\n     * example, to check parameter values to determine if they have changed.\n     *\n     * This overload is provided to avoid boxing [value] to compare with a potentially boxed version\n     * of [value] in the composition state.\n     *\n     * @param value the value to check\n     * @return `true` if the value if [equals] of the previous value returns `false` when passed\n     *   [value].\n     */\n    @ComposeCompilerApi public fun changed(value: Int): Boolean = changed(value)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Check [value] is different than the value used in the previous composition. This is used, for\n     * example, to check parameter values to determine if they have changed.\n     *\n     * This overload is provided to avoid boxing [value] to compare with a potentially boxed version\n     * of [value] in the composition state.\n     *\n     * @param value the value to check\n     * @return `true` if the value if [equals] of the previous value returns `false` when passed\n     *   [value].\n     */\n    @ComposeCompilerApi public fun changed(value: Float): Boolean = changed(value)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Check [value] is different than the value used in the previous composition. This is used, for\n     * example, to check parameter values to determine if they have changed.\n     *\n     * This overload is provided to avoid boxing [value] to compare with a potentially boxed version\n     * of [value] in the composition state.\n     *\n     * @param value the value to check\n     * @return `true` if the value if [equals] of the previous value returns `false` when passed\n     *   [value].\n     */\n    @ComposeCompilerApi public fun changed(value: Long): Boolean = changed(value)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Check [value] is different than the value used in the previous composition. This is used, for\n     * example, to check parameter values to determine if they have changed.\n     *\n     * This overload is provided to avoid boxing [value] to compare with a potentially boxed version\n     * of [value] in the composition state.\n     *\n     * @param value the value to check\n     * @return `true` if the value if [equals] of the previous value returns `false` when passed\n     *   [value].\n     */\n    @ComposeCompilerApi public fun changed(value: Double): Boolean = changed(value)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Check [value] is different than the value used in the previous composition using `===`\n     * instead of `==` equality. This is used, for example, to check parameter values to determine\n     * if they have changed for values that use value equality but, for correct behavior, the\n     * composer needs reference equality.\n     *\n     * @param value the value to check\n     * @return `true` if the value is === equal to the previous value and returns `false` when\n     *   [value] is different.\n     */\n    @ComposeCompilerApi public fun changedInstance(value: Any?): Boolean = changed(value)\n\n    // Scopes\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Mark [scope] as used. [endReplaceableGroup] will return `null` unless [recordUsed] is called\n     * on the corresponding [scope]. This is called implicitly when [State] objects are read during\n     * composition is called when [currentRecomposeScope] is called in the [Composable] function.\n     */\n    @InternalComposeApi public fun recordUsed(scope: RecomposeScope)\n\n    /**\n     * A Compose compiler plugin API. DO NOT call directly.\n     *\n     * Generated by the compile to determine if the composable function should be executed. It may\n     * not execute if parameter has not changed and the nothing else is forcing the function to\n     * execute (such as its scope was invalidated or a static composition local it was changed) or\n     * the composition is pausable and the composition is pausing.\n     *\n     * @param parametersChanged `true` if the parameters to the composable function have changed.\n     *   This is also `true` if the composition is [inserting] or if content is being reused.\n     * @param flags The `$changed` parameter that contains the forced recompose bit to allow the\n     *   composer to disambiguate when the parameters changed due the execution being forced or if\n     *   the parameters actually changed. This is only ambiguous in a [PausableComposition] and is\n     *   necessary to determine if the function can be paused. The bits, other than 0, are reserved\n     *   for future use (which would required the bit 31, which is unused in `$changed` values, to\n     *   be set to indicate that the flags carry additional information). Passing the `$changed`\n     *   flags directly, instead of masking the 0 bit, is more efficient as it allows less code to\n     *   be generated per call to `shouldExecute` which is every called in every restartable\n     *   function, as well as allowing for the API to be extended without a breaking changed.\n     */\n    @InternalComposeApi public fun shouldExecute(parametersChanged: Boolean, flags: Int): Boolean\n\n    // Internal API\n\n    /**\n     * A Compose internal function. DO NOT call directly.\n     *\n     * Record a function to call when changes to the corresponding tree are applied to the\n     * [applier]. This is used to implement [SideEffect].\n     *\n     * @param effect a lambda to invoke after the changes calculated up to this point have been\n     *   applied.\n     */\n    @InternalComposeApi public fun recordSideEffect(effect: () -> Unit)\n\n    /**\n     * Returns the active set of CompositionLocals at the current position in the composition\n     * hierarchy. This is a lower level API that can be used to export and access CompositionLocal\n     * values outside of Composition.\n     *\n     * This API does not track reads of CompositionLocals and does not automatically dispatch new\n     * values to previous readers when the value of a CompositionLocal changes. To use this API as\n     * intended, you must set up observation manually. This means:\n     * - For [non-static CompositionLocals][compositionLocalOf], composables reading this map need\n     *   to observe the snapshot state for CompositionLocals being read to be notified when their\n     *   values in this map change.\n     * - For [static CompositionLocals][staticCompositionLocalOf], all composables including the\n     *   composable reading this map will be recomposed and you will need to re-obtain this map to\n     *   get the latest values.\n     *\n     * Most applications shouldn't use this API directly, and should instead use\n     * [CompositionLocal.current].\n     */\n    public val currentCompositionLocalMap: CompositionLocalMap\n\n    /**\n     * A Compose internal function. DO NOT call directly.\n     *\n     * Return the [CompositionLocal] value associated with [key]. This is the primitive function\n     * used to implement [CompositionLocal.current].\n     *\n     * @param key the [CompositionLocal] value to be retrieved.\n     */\n    @InternalComposeApi public fun <T> consume(key: CompositionLocal<T>): T\n\n    /**\n     * A Compose internal function. DO NOT call directly.\n     *\n     * Provide the given values for the associated [CompositionLocal] keys. This is the primitive\n     * function used to implement [CompositionLocalProvider].\n     *\n     * @param values an array of value to provider key pairs.\n     */\n    @InternalComposeApi public fun startProviders(values: Array<out ProvidedValue<*>>)\n\n    /**\n     * A Compose internal function. DO NOT call directly.\n     *\n     * End the provider group.\n     *\n     * @see startProviders\n     */\n    @InternalComposeApi public fun endProviders()\n\n    /**\n     * A Compose internal function. DO NOT call directly.\n     *\n     * Provide the given value for the associated [CompositionLocal] key. This is the primitive\n     * function used to implement [CompositionLocalProvider].\n     *\n     * @param value a value to provider key pairs.\n     */\n    @InternalComposeApi public fun startProvider(value: ProvidedValue<*>)\n\n    /**\n     * A Compose internal function. DO NOT call directly.\n     *\n     * End the provider group.\n     *\n     * @see startProvider\n     */\n    @InternalComposeApi public fun endProvider()\n\n    /**\n     * A tooling API function. DO NOT call directly.\n     *\n     * The data stored for the composition. This is used by Compose tools, such as the preview and\n     * the inspector, to display or interpret the result of composition.\n     */\n    public val compositionData: CompositionData\n\n    /**\n     * A tooling API function. DO NOT call directly.\n     *\n     * Called by the inspector to inform the composer that it should collect additional information\n     * about call parameters. By default, only collect parameter information for scopes that are\n     * [recordUsed] has been called on. If [collectParameterInformation] is called it will attempt\n     * to collect all calls even if the runtime doesn't need them.\n     *\n     * WARNING: calling this will result in a significant number of additional allocations that are\n     * typically avoided.\n     */\n    public fun collectParameterInformation()\n\n    /**\n     * Schedules an [action] to be invoked when the recomposer finishes the next composition of a\n     * frame (including the completion of subcompositions). If a frame is currently in-progress,\n     * [action] will be invoked when the current frame fully finishes composing. If a frame isn't\n     * currently in-progress, a new frame will be scheduled (if one hasn't been already) and\n     * [action] will execute at the completion of the next frame's composition. If a new frame is\n     * scheduled and there is no other work to execute, [action] will still execute.\n     *\n     * [action] will always execute on the applier thread.\n     *\n     * Note that [action] runs at the end of a frame scheduled by the recomposer. If a callback is\n     * scheduled via this method during the initial composition, it will not execute until the\n     * _next_ frame.\n     *\n     * @return A [CancellationHandle] that can be used to unregister the [action]. The returned\n     *   handle is thread-safe and may be cancelled from any thread. Cancelling the handle only\n     *   removes the callback from the queue. If [action] is currently executing, it will not be\n     *   cancelled by this handle.\n     */\n    public fun scheduleFrameEndCallback(action: () -> Unit): CancellationHandle\n\n    /**\n     * A Compose internal function. DO NOT call directly.\n     *\n     * Build a composition context that can be used to created a subcomposition. A composition\n     * reference is used to communicate information from this composition to the subcompositions\n     * such as the all the [CompositionLocal]s provided at the point the reference is created.\n     */\n    @InternalComposeApi public fun buildContext(): CompositionContext\n\n    /**\n     * A Compose internal function. DO NOT call directly.\n     *\n     * The coroutine context for the composition. This is used, for example, to implement\n     * [LaunchedEffect]. This context is managed by the [Recomposer].\n     */\n    @InternalComposeApi\n    public val applyCoroutineContext: CoroutineContext\n        @TestOnly get\n\n    /** The composition that is used to control this composer. */\n    public val composition: ControlledComposition\n        @TestOnly get\n\n    /**\n     * Disable the collection of source information, that may introduce groups to store the source\n     * information, in order to be able to more accurately calculate the actual number of groups a\n     * composable function generates in a release build.\n     *\n     * This function is only safe to call in a test and will produce incorrect composition results\n     * if called on a composer not under test.\n     */\n    @TestOnly public fun disableSourceInformation()\n\n    public companion object {\n        /**\n         * A special value used to represent no value was stored (e.g. an empty slot). This is\n         * returned, for example by [Composer.rememberedValue] while it is [Composer.inserting] is\n         * `true`.\n         */\n        public val Empty: Any =\n            object {\n                override fun toString() = \"Empty\"\n            }\n\n        /**\n         * Internal API for specifying a tracer used for instrumenting frequent operations, e.g.\n         * recompositions.\n         */\n        @InternalComposeTracingApi\n        public fun setTracer(tracer: CompositionTracer?) {\n            compositionTracer = tracer\n        }\n\n        /**\n         * Set the mode for collecting composition stack traces. See [ComposeStackTraceMode] for\n         * more information about available modes. The stack traces are disabled by default.\n         *\n         * Note: changing stack trace collection mode will not affect already running compositions.\n         */\n        public fun setDiagnosticStackTraceMode(mode: ComposeStackTraceMode) {\n            composeStackTraceMode = mode\n        }\n\n        /**\n         * Enable composition stack traces based on the source information. When this flag is\n         * enabled, composition will record source information at runtime. When crash occurs,\n         * Compose will append a suppressed exception that contains a stack trace pointing to the\n         * place in composition closest to the crash.\n         *\n         * @see [ComposeStackTraceMode.SourceInformation] for more information.\n         */\n        @Deprecated(message = \"Use setDiagnosticStackTraceMode instead\")\n        @ExperimentalComposeRuntimeApi\n        public fun setDiagnosticStackTraceEnabled(enabled: Boolean) {\n            composeStackTraceMode =\n                if (enabled) ComposeStackTraceMode.SourceInformation else ComposeStackTraceMode.None\n        }\n    }\n}\n\ninternal abstract class InternalComposer : Composer {\n    internal abstract val areChildrenComposing: Boolean\n    internal abstract val isComposing: Boolean\n    internal abstract val hasPendingChanges: Boolean\n    internal abstract val currentRecomposeScope: RecomposeScopeImpl?\n    internal abstract val errorContext: CompositionErrorContextImpl?\n    internal abstract val deferredChanges: Changes?\n    internal abstract val sourceMarkersEnabled: Boolean\n\n    internal abstract fun startReuseFromRoot()\n\n    internal abstract fun endReuseFromRoot()\n\n    internal abstract fun changesApplied()\n\n    internal abstract fun forceRecomposeScopes(): Boolean\n\n    internal abstract fun dispose()\n\n    internal abstract fun deactivate()\n\n    internal abstract fun verifyConsistent()\n\n    internal abstract fun stacksSize(): Int\n\n    internal abstract fun stackTraceForValue(value: Any?): ComposeStackTrace\n\n    internal abstract fun parentStackTrace(): List<ComposeStackTraceFrame>\n\n    internal abstract fun prepareCompose(block: () -> Unit)\n\n    internal abstract fun composeContent(\n        invalidationsRequested: ScopeMap<RecomposeScopeImpl, Any>,\n        content: @Composable () -> Unit,\n        shouldPause: ShouldPauseCallback?,\n    )\n\n    internal abstract fun recompose(\n        invalidationsRequested: ScopeMap<RecomposeScopeImpl, Any>,\n        shouldPause: ShouldPauseCallback?,\n    ): Boolean\n\n    internal abstract fun tryImminentInvalidation(\n        scope: RecomposeScopeImpl,\n        instance: Any?,\n    ): Boolean\n\n    internal abstract fun updateComposerInvalidations(\n        invalidationsRequested: ScopeMap<RecomposeScopeImpl, Any>\n    )\n\n    @TestOnly internal abstract fun parentKey(): Int\n}\n\n/**\n * A Compose compiler plugin API. DO NOT call directly.\n *\n * Cache, that is remember, a value in the composition data of a composition. This is used to\n * implement [remember] and used by the compiler plugin to generate more efficient calls to\n * [remember] when it determines these optimizations are safe.\n */\n@ComposeCompilerApi\npublic inline fun <T> Composer.cache(invalid: Boolean, block: @DisallowComposableCalls () -> T): T {\n    @Suppress(\"UNCHECKED_CAST\")\n    return rememberedValue().let {\n        if (invalid || it === Composer.Empty) {\n            val value = block()\n            updateRememberedValue(value)\n            value\n        } else it\n    } as T\n}\n\n/**\n * A Compose internal function. DO NOT call directly.\n *\n * Records source information that can be used for tooling to determine the source location of the\n * corresponding composable function. By default, this function is declared as having no\n * side-effects. It is safe for code shrinking tools (such as R8 or ProGuard) to remove it.\n */\n@ComposeCompilerApi\npublic fun sourceInformation(composer: Composer, sourceInformation: String) {\n    composer.sourceInformation(sourceInformation)\n}\n\n/**\n * A Compose internal function. DO NOT call directly.\n *\n * Records the start of a source information marker that can be used for tooling to determine the\n * source location of the corresponding composable function that otherwise don't require tracking\n * information such as [ReadOnlyComposable] functions. By default, this function is declared as\n * having no side-effects. It is safe for code shrinking tools (such as R8 or ProGuard) to remove\n * it.\n *\n * Important that both [sourceInformationMarkerStart] and [sourceInformationMarkerEnd] are removed\n * together or both kept. Removing only one will cause incorrect runtime behavior.\n */\n@ComposeCompilerApi\npublic fun sourceInformationMarkerStart(composer: Composer, key: Int, sourceInformation: String) {\n    composer.sourceInformationMarkerStart(key, sourceInformation)\n}\n\n/**\n * Internal tracing API.\n *\n * Should be called without thread synchronization with occasional information loss.\n */\n@InternalComposeTracingApi\npublic interface CompositionTracer {\n    public fun traceEventStart(key: Int, dirty1: Int, dirty2: Int, info: String): Unit\n\n    public fun traceEventEnd(): Unit\n\n    public fun isTraceInProgress(): Boolean\n}\n\n@OptIn(InternalComposeTracingApi::class) private var compositionTracer: CompositionTracer? = null\n\ninternal var composeStackTraceMode = ComposeStackTraceMode.None\n\n/**\n * Internal tracing API.\n *\n * Should be called without thread synchronization with occasional information loss.\n */\n@OptIn(InternalComposeTracingApi::class)\n@ComposeCompilerApi\npublic fun isTraceInProgress(): Boolean =\n    compositionTracer.let { it != null && it.isTraceInProgress() }\n\n@OptIn(InternalComposeTracingApi::class)\n@ComposeCompilerApi\n@Deprecated(\n    message = \"Use the overload with \\$dirty metadata instead\",\n    ReplaceWith(\"traceEventStart(key, dirty1, dirty2, info)\"),\n    DeprecationLevel.HIDDEN,\n)\npublic fun traceEventStart(key: Int, info: String): Unit = traceEventStart(key, -1, -1, info)\n\n/**\n * Internal tracing API.\n *\n * Should be called without thread synchronization with occasional information loss.\n *\n * @param key is a group key generated by the compiler plugin for the function being traced. This\n *   key is unique the function.\n * @param dirty1 $dirty metadata: forced-recomposition and function parameters 1..10 if present\n * @param dirty2 $dirty2 metadata: forced-recomposition and function parameters 11..20 if present\n * @param info is a user displayable string that describes the function for which this is the start\n *   event.\n */\n@OptIn(InternalComposeTracingApi::class)\n@ComposeCompilerApi\npublic fun traceEventStart(key: Int, dirty1: Int, dirty2: Int, info: String) {\n    compositionTracer?.traceEventStart(key, dirty1, dirty2, info)\n}\n\n/**\n * Internal tracing API.\n *\n * Should be called without thread synchronization with occasional information loss.\n */\n@OptIn(InternalComposeTracingApi::class)\n@ComposeCompilerApi\npublic fun traceEventEnd() {\n    compositionTracer?.traceEventEnd()\n}\n\n/**\n * A Compose internal function. DO NOT call directly.\n *\n * Records the end of a source information marker that can be used for tooling to determine the\n * source location of the corresponding composable function that otherwise don't require tracking\n * information such as [ReadOnlyComposable] functions. By default, this function is declared as\n * having no side-effects. It is safe for code shrinking tools (such as R8 or ProGuard) to remove\n * it.\n *\n * Important that both [sourceInformationMarkerStart] and [sourceInformationMarkerEnd] are removed\n * together or both kept. Removing only one will cause incorrect runtime behavior.\n */\n@ComposeCompilerApi\npublic fun sourceInformationMarkerEnd(composer: Composer) {\n    composer.sourceInformationMarkerEnd()\n}\n\n/**\n * A helper receiver scope class used by [ComposeNode] to help write code to initialized and update\n * a node.\n *\n * @see ComposeNode\n */\n@JvmInline\npublic value class Updater<T> constructor(@PublishedApi internal val composer: Composer) {\n    /**\n     * Set the value property of the emitted node.\n     *\n     * Schedules [block] to be run when the node is first created or when [value] is different than\n     * the previous composition.\n     *\n     * @see update\n     */\n    @Deprecated(\"Boxes more than than the generic overload\", level = DeprecationLevel.HIDDEN)\n    @Suppress(\"NOTHING_TO_INLINE\")\n    public inline fun set(value: Int, noinline block: T.(value: Int) -> Unit): Unit =\n        with(composer) {\n            if (inserting || rememberedValue() != value) {\n                updateRememberedValue(value)\n                composer.apply(value, block)\n            }\n        }\n\n    /**\n     * Set the value property of the emitted node.\n     *\n     * Schedules [block] to be run when the node is first created or when [value] is different than\n     * the previous composition.\n     *\n     * @see update\n     */\n    public fun <V> set(value: V, block: T.(value: V) -> Unit): Unit =\n        with(composer) {\n            if (inserting || rememberedValue() != value) {\n                updateRememberedValue(value)\n                composer.apply(value, block)\n            }\n        }\n\n    /**\n     * Update the value of a property of the emitted node.\n     *\n     * Schedules [block] to be run when [value] is different than the previous composition. It is\n     * different than [set] in that it does not run when the node is created. This is used when\n     * initial value set by the [ComposeNode] in the constructor callback already has the correct\n     * value. For example, use [update} when [value] is passed into of the classes constructor\n     * parameters.\n     *\n     * @see set\n     */\n    @Deprecated(\"Boxes more than the generic overload\", level = DeprecationLevel.HIDDEN)\n    @Suppress(\"NOTHING_TO_INLINE\")\n    public inline fun update(value: Int, noinline block: T.(value: Int) -> Unit): Unit =\n        with(composer) {\n            val inserting = inserting\n            if (inserting || rememberedValue() != value) {\n                updateRememberedValue(value)\n                if (!inserting) apply(value, block)\n            }\n        }\n\n    /**\n     * Update the value of a property of the emitted node.\n     *\n     * Schedules [block] to be run when [value] is different than the previous composition. It is\n     * different than [set] in that it does not run when the node is created. This is used when\n     * initial value set by the [ComposeNode] in the constructor callback already has the correct\n     * value. For example, use [update} when [value] is passed into of the classes constructor\n     * parameters.\n     *\n     * @see set\n     */\n    public fun <V> update(value: V, block: T.(value: V) -> Unit): Unit =\n        with(composer) {\n            val inserting = inserting\n            if (inserting || rememberedValue() != value) {\n                updateRememberedValue(value)\n                if (!inserting) apply(value, block)\n            }\n        }\n\n    /**\n     * Initialize emitted node.\n     *\n     * Schedule [block] to be executed after the node is created.\n     *\n     * This is only executed once. The can be used to call a method or set a value on a node\n     * instance that is required to be set after one or more other properties have been set.\n     *\n     * @see reconcile\n     */\n    public fun init(block: T.() -> Unit) {\n        if (composer.inserting) composer.apply<Unit, T>(Unit) { block() }\n    }\n\n    /**\n     * Initialize emitted node.\n     *\n     * Schedule [block] to be executed after the node is created.\n     *\n     * This is only executed once. The can be used to call a method or set a value on a node\n     * instance that is required to be set after one or more other properties have been set.\n     *\n     * This is different from the other [init] overload in that it does not force creating a lambda\n     * to capture [value].\n     */\n    public fun <V> init(value: V, block: T.(V) -> Unit) {\n        if (composer.inserting) composer.apply(value, block)\n    }\n\n    /**\n     * Reconcile the node to the current state.\n     *\n     * This is used when [set] and [update] are insufficient to update the state of the node based\n     * on changes passed to the function calling [ComposeNode].\n     *\n     * Schedules [block] to execute. As this unconditionally schedules [block] to executed it might\n     * be executed unnecessarily as no effort is taken to ensure it only executes when the values\n     * [block] captures have changed. It is highly recommended that [set] and [update] be used\n     * instead as they will only schedule their blocks to executed when the value passed to them has\n     * changed.\n     */\n    @Suppress(\"MemberVisibilityCanBePrivate\")\n    public fun reconcile(block: T.() -> Unit) {\n        composer.apply<Unit, T>(Unit) { this.block() }\n    }\n}\n\n@JvmInline\npublic value class SkippableUpdater<T> constructor(@PublishedApi internal val composer: Composer) {\n    public inline fun update(block: Updater<T>.() -> Unit) {\n        composer.startReplaceableGroup(0x1e65194f)\n        Updater<T>(composer).block()\n        composer.endReplaceableGroup()\n    }\n}\n\ninternal fun SlotWriter.removeCurrentGroup(rememberManager: RememberManager) {\n    // Notify the lifecycle manager of any observers leaving the slot table\n    // The notification order should ensure that listeners are notified of leaving\n    // in opposite order that they are notified of entering.\n\n    // To ensure this order, we call `enters` as a pre-order traversal\n    // of the group tree, and then call `leaves` in the inverse order.\n\n    forAllDataInRememberOrder(currentGroup) { _, slot ->\n        // even that in the documentation we claim ComposeNodeLifecycleCallback should be only\n        // implemented on the nodes we do not really enforce it here as doing so will be expensive.\n        if (slot is ComposeNodeLifecycleCallback) {\n            rememberManager.releasing(slot)\n        }\n        if (slot is RememberObserverHolder) {\n            rememberManager.forgetting(slot)\n        }\n        if (slot is RecomposeScopeImpl) {\n            slot.release()\n        }\n    }\n\n    removeGroup()\n}\n\ninternal inline fun <R> SlotWriter.withAfterAnchorInfo(anchor: Anchor?, cb: (Int, Int) -> R) {\n    var priority = -1\n    var endRelativeAfter = -1\n    if (anchor != null && anchor.valid) {\n        priority = anchorIndex(anchor.asGapAnchor())\n        endRelativeAfter = slotsSize - slotsEndAllIndex(priority)\n    }\n    cb(priority, endRelativeAfter)\n}\n\ninternal val SlotWriter.isAfterFirstChild\n    get() = currentGroup > parent + 1\ninternal val SlotReader.isAfterFirstChild\n    get() = currentGroup > parent + 1\n\n/**\n * Remember observer which is not removed during reuse/deactivate of the group. It is used to\n * preserve composition locals between group deactivation.\n */\ninternal interface ReusableRememberObserverHolder : RememberObserverHolder\n\ninternal interface RememberObserverHolder {\n    var wrapped: RememberObserver\n}\n\n// An arbitrary key value that marks the default parameter group\ninternal const val defaultsKey = -127\n\n@PublishedApi internal const val invocationKey: Int = 200\n\n@PublishedApi internal val invocation: Any = OpaqueKey(\"provider\")\n\n@PublishedApi internal const val providerKey: Int = 201\n\n@PublishedApi internal val provider: Any = OpaqueKey(\"provider\")\n\n@PublishedApi internal const val compositionLocalMapKey: Int = 202\n\n@PublishedApi internal val compositionLocalMap: Any = OpaqueKey(\"compositionLocalMap\")\n\n@PublishedApi internal const val providerValuesKey: Int = 203\n\n@PublishedApi internal val providerValues: Any = OpaqueKey(\"providerValues\")\n\n@PublishedApi internal const val providerMapsKey: Int = 204\n\n@PublishedApi internal val providerMaps: Any = OpaqueKey(\"providers\")\n\n@PublishedApi internal const val referenceKey: Int = 206\n\n@PublishedApi internal val reference: Any = OpaqueKey(\"reference\")\n\n@PublishedApi internal const val reuseKey: Int = 207\n\nprivate const val invalidGroupLocation = -2\n\ninternal class ComposeRuntimeError(override val message: String) : IllegalStateException()\n\n@Suppress(\"BanInlineOptIn\")\n@OptIn(ExperimentalContracts::class)\ninternal inline fun runtimeCheck(value: Boolean, lazyMessage: () -> String) {\n    contract { returns() implies value }\n    if (!value) {\n        composeImmediateRuntimeError(lazyMessage())\n    }\n}\n\ninternal const val EnableDebugRuntimeChecks = false\n\n/**\n * A variation of [composeRuntimeError] that gets stripped from R8-minified builds. Use this for\n * more expensive checks or assertions along a hotpath that, if failed, would still lead to an\n * application crash that could be traced back to this assertion if removed from the final program\n * binary.\n */\ninternal inline fun debugRuntimeCheck(value: Boolean, lazyMessage: () -> String) {\n    if (EnableDebugRuntimeChecks && !value) {\n        composeImmediateRuntimeError(lazyMessage())\n    }\n}\n\ninternal inline fun debugRuntimeCheck(value: Boolean) = debugRuntimeCheck(value) { \"Check failed\" }\n\ninternal inline fun runtimeCheck(value: Boolean) = runtimeCheck(value) { \"Check failed\" }\n\ninternal fun composeRuntimeError(message: String): Nothing {\n    throw ComposeRuntimeError(\n        \"Compose Runtime internal error. Unexpected or incorrect use of the Compose \" +\n            \"internal runtime API ($message). Please report to Google or use \" +\n            \"https://goo.gle/compose-feedback\"\n    )\n}\n\n// Unit variant of composeRuntimeError() so the call site doesn't add 3 extra\n// instructions to throw a KotlinNothingValueException\ninternal fun composeImmediateRuntimeError(message: String) {\n    throw ComposeRuntimeError(\n        \"Compose Runtime internal error. Unexpected or incorrect use of the Compose \" +\n            \"internal runtime API ($message). Please report to Google or use \" +\n            \"https://goo.gle/compose-feedback\"\n    )\n}\n\n/**\n * Extract the state of movable content from the given writer. A new slot table is created and the\n * content is removed from [slots] (leaving a movable content group that, if composed over, will\n * create new content) and added to this new slot table. The invalidations that occur to recompose\n * scopes in the movable content state will be collected and forwarded to the new composition if the\n * state is used.\n */\ninternal fun extractMovableContentAtCurrent(\n    composition: ControlledComposition,\n    reference: MovableContentStateReference,\n    slots: SlotWriter,\n    applier: Applier<*>?,\n): MovableContentState {\n    val slotTable = SlotTable()\n    if (slots.collectingSourceInformation) {\n        slotTable.collectSourceInformation()\n    }\n    if (slots.collectingCalledInformation) {\n        slotTable.collectCalledByInformation()\n    }\n\n    // If an applier is provided then we are extracting a state from the middle of an\n    // already extracted state. If the group has nodes then the nodes need to be removed\n    // from their parent so they can potentially be inserted into a destination.\n    val currentGroup = slots.currentGroup\n    if (applier != null && slots.nodeCount(currentGroup) > 0) {\n        @Suppress(\"UNCHECKED_CAST\")\n        applier as Applier<Any?>\n\n        // Find the parent node by going up until the first node group\n        var parentNodeGroup = slots.parent\n        while (parentNodeGroup > 0 && !slots.isNode(parentNodeGroup)) {\n            parentNodeGroup = slots.parent(parentNodeGroup)\n        }\n\n        // If we don't find a node group the nodes in the state have already been removed\n        // as they are the nodes that were removed when the state was removed from the original\n        // table.\n        if (parentNodeGroup >= 0 && slots.isNode(parentNodeGroup)) {\n            val node = slots.node(parentNodeGroup)\n            var currentChild = parentNodeGroup + 1\n            val end = parentNodeGroup + slots.groupSize(parentNodeGroup)\n\n            // Find the node index\n            var nodeIndex = 0\n            while (currentChild < end) {\n                val size = slots.groupSize(currentChild)\n                if (currentChild + size > currentGroup) {\n                    break\n                }\n                nodeIndex += if (slots.isNode(currentChild)) 1 else slots.nodeCount(currentChild)\n                currentChild += size\n            }\n\n            // Remove the nodes\n            val count = if (slots.isNode(currentGroup)) 1 else slots.nodeCount(currentGroup)\n            applier.down(node)\n            applier.remove(nodeIndex, count)\n            applier.up()\n        }\n    }\n\n    // Transfer invalidations before moving the scopes, since we could have accumulated more after\n    // creating the state.\n    val anchor = reference.anchor\n    if (anchor.valid) {\n        val extracted =\n            (composition as CompositionImpl).extractInvalidationsOfGroup {\n                slots.inGroup(anchor.asGapAnchor(), it.asGapAnchor())\n            }\n        reference.invalidations += extracted\n    }\n\n    // Write a table that as if it was written by a calling invokeMovableContentLambda because this\n    // might be removed from the composition before the new composition can be composed to receive\n    // it. When the new composition receives the state it must recompose over the state by calling\n    // invokeMovableContentLambda.\n    val anchors =\n        slotTable.write { writer ->\n            writer.beginInsert()\n\n            // This is the prefix created by invokeMovableContentLambda\n            writer.startGroup(movableContentKey, reference.content)\n            writer.markGroup()\n            writer.update(reference.parameter)\n\n            // Move the content into current location\n            val anchors = slots.moveTo(reference.anchor.asGapAnchor(), 1, writer)\n\n            // skip the group that was just inserted.\n            writer.skipGroup()\n\n            // End the group that represents the call to invokeMovableContentLambda\n            writer.endGroup()\n\n            writer.endInsert()\n\n            anchors\n        }\n\n    val state = MovableContentState(slotTable)\n    if (RecomposeScopeImpl.hasAnchoredRecomposeScopes(slotTable, anchors)) {\n        // If any recompose scopes are invalidated while the movable content is outside a\n        // composition, ensure the reference is updated to contain the invalidation.\n        val movableContentRecomposeScopeOwner =\n            object : RecomposeScopeOwner {\n                override fun invalidate(\n                    scope: RecomposeScopeImpl,\n                    instance: Any?,\n                ): InvalidationResult {\n                    // Try sending this to the original owner first.\n                    val result =\n                        (composition as? RecomposeScopeOwner)?.invalidate(scope, instance)\n                            ?: InvalidationResult.IGNORED\n\n                    // If the original owner ignores this then we need to record it in the\n                    // reference\n                    if (result == InvalidationResult.IGNORED) {\n                        reference.invalidations += scope to instance\n                        return InvalidationResult.SCHEDULED\n                    }\n                    return result\n                }\n\n                // The only reason [recomposeScopeReleased] is called is when the recompose scope is\n                // removed from the table. First, this never happens for content that is moving, and\n                // 2) even if it did the only reason we tell the composer is to clear tracking\n                // tables that contain this information which is not relevant here.\n                override fun recomposeScopeReleased(scope: RecomposeScopeImpl) {\n                    // Nothing to do\n                }\n\n                // [recordReadOf] this is also something that would happen only during active\n                // recomposition which doesn't happened to a slot table that is moving.\n                override fun recordReadOf(value: Any) {\n                    // Nothing to do\n                }\n            }\n        slotTable.write { writer ->\n            RecomposeScopeImpl.adoptAnchoredScopes(\n                slots = writer,\n                anchors = anchors,\n                newOwner = movableContentRecomposeScopeOwner,\n            )\n        }\n    }\n    return state\n}\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Recomposer.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.runtime\n\nimport androidx.collection.MutableObjectList\nimport androidx.collection.MutableScatterSet\nimport androidx.collection.ScatterSet\nimport androidx.collection.emptyObjectList\nimport androidx.collection.emptyScatterSet\nimport androidx.collection.mutableScatterMapOf\nimport androidx.collection.mutableScatterSetOf\nimport androidx.compose.runtime.collection.MultiValueMap\nimport androidx.compose.runtime.collection.fastForEach\nimport androidx.compose.runtime.collection.fastMap\nimport androidx.compose.runtime.collection.mutableVectorOf\nimport androidx.compose.runtime.collection.wrapIntoSet\nimport androidx.compose.runtime.external.kotlinx.collections.immutable.persistentSetOf\nimport androidx.compose.runtime.internal.AtomicReference\nimport androidx.compose.runtime.internal.SnapshotThreadLocal\nimport androidx.compose.runtime.internal.logError\nimport androidx.compose.runtime.internal.trace\nimport androidx.compose.runtime.platform.SynchronizedObject\nimport androidx.compose.runtime.platform.makeSynchronizedObject\nimport androidx.compose.runtime.platform.synchronized\nimport androidx.compose.runtime.snapshots.MutableSnapshot\nimport androidx.compose.runtime.snapshots.ReaderKind\nimport androidx.compose.runtime.snapshots.Snapshot\nimport androidx.compose.runtime.snapshots.SnapshotApplyResult\nimport androidx.compose.runtime.snapshots.StateObjectImpl\nimport androidx.compose.runtime.snapshots.TransparentObserverMutableSnapshot\nimport androidx.compose.runtime.snapshots.TransparentObserverSnapshot\nimport androidx.compose.runtime.snapshots.fastAll\nimport androidx.compose.runtime.snapshots.fastAny\nimport androidx.compose.runtime.snapshots.fastFilterIndexed\nimport androidx.compose.runtime.snapshots.fastForEach\nimport androidx.compose.runtime.snapshots.fastGroupBy\nimport androidx.compose.runtime.snapshots.fastMap\nimport androidx.compose.runtime.snapshots.fastMapNotNull\nimport androidx.compose.runtime.tooling.ComposeStackTraceMode\nimport androidx.compose.runtime.tooling.ComposeToolingApi\nimport androidx.compose.runtime.tooling.CompositionData\nimport androidx.compose.runtime.tooling.CompositionObserverHandle\nimport androidx.compose.runtime.tooling.CompositionRegistrationObserver\nimport androidx.compose.runtime.tooling.ObservableComposition\nimport androidx.compose.runtime.tooling.observe\nimport kotlin.collections.removeLast as removeLastKt\nimport kotlin.coroutines.Continuation\nimport kotlin.coroutines.CoroutineContext\nimport kotlin.coroutines.coroutineContext\nimport kotlin.coroutines.resume\nimport kotlin.native.concurrent.ThreadLocal\nimport kotlinx.coroutines.CancellableContinuation\nimport kotlinx.coroutines.CancellationException\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.coroutineScope\nimport kotlinx.coroutines.flow.Flow\nimport kotlinx.coroutines.flow.MutableStateFlow\nimport kotlinx.coroutines.flow.StateFlow\nimport kotlinx.coroutines.flow.collect\nimport kotlinx.coroutines.flow.first\nimport kotlinx.coroutines.flow.takeWhile\nimport kotlinx.coroutines.job\nimport kotlinx.coroutines.launch\nimport kotlinx.coroutines.suspendCancellableCoroutine\nimport kotlinx.coroutines.withContext\n\ninternal const val recomposerKey = 1000\n\n// TODO: Can we use rootKey for this since all compositions will have an eventual Recomposer parent?\nprivate inline val RecomposerCompoundHashKey\n    get() = CompositeKeyHashCode(recomposerKey)\n\n/**\n * Runs [block] with a new, active [Recomposer] applying changes in the calling [CoroutineContext].\n * The [Recomposer] will be [closed][Recomposer.close] after [block] returns.\n * [withRunningRecomposer] will return once the [Recomposer] is [Recomposer.State.ShutDown] and all\n * child jobs launched by [block] have [joined][Job.join].\n */\npublic suspend fun <R> withRunningRecomposer(\n    block: suspend CoroutineScope.(recomposer: Recomposer) -> R\n): R = coroutineScope {\n    val recomposer = Recomposer(coroutineContext)\n    // Will be cancelled when recomposerJob cancels\n    launch { recomposer.runRecomposeAndApplyChanges() }\n    block(recomposer).also {\n        recomposer.close()\n        recomposer.join()\n    }\n}\n\n/**\n * Read-only information about a [Recomposer]. Used when code should only monitor the activity of a\n * [Recomposer], and not attempt to alter its state or create new compositions from it.\n */\npublic interface RecomposerInfo {\n    /** The current [State] of the [Recomposer]. See each [State] value for its meaning. */\n    // TODO: Mirror the currentState/StateFlow API change here once we can safely add\n    // default interface methods. https://youtrack.jetbrains.com/issue/KT-47000\n    public val state: Flow<Recomposer.State>\n\n    /**\n     * `true` if the [Recomposer] has been assigned work to do and it is currently performing that\n     * work or awaiting an opportunity to do so.\n     */\n    public val hasPendingWork: Boolean\n\n    /**\n     * The running count of the number of times the [Recomposer] awoke and applied changes to one or\n     * more [Composer]s. This count is unaffected if the composer awakes and recomposed but\n     * composition did not produce changes to apply.\n     */\n    public val changeCount: Long\n\n    /**\n     * Get flow of error states captured in composition. This flow is only available when recomposer\n     * is in hot reload mode.\n     *\n     * @return a flow of error states captured during composition\n     */\n    @ComposeToolingApi\n    public val errorState: StateFlow<RecomposerErrorInformation?>\n        get() = DefaultErrorStateFlow\n\n    /**\n     * Register an observer to be notified when a composition is added to or removed from the given\n     * [Recomposer]. When this method is called, the observer will be notified of all currently\n     * registered compositions per the documentation in\n     * [CompositionRegistrationObserver.onCompositionRegistered].\n     */\n    @ExperimentalComposeRuntimeApi\n    public fun observe(observer: CompositionRegistrationObserver): CompositionObserverHandle? = null\n\n    private companion object {\n        @ComposeToolingApi\n        private val DefaultErrorStateFlow: StateFlow<RecomposerErrorInformation?> =\n            MutableStateFlow(null)\n    }\n}\n\n/** Read only information about [Recomposer] error state. */\n@ComposeToolingApi\npublic interface RecomposerErrorInformation {\n    /** Exception which forced recomposition to halt. */\n    public val cause: Throwable\n\n    /**\n     * Whether composition can recover from the error by itself. If the error is not recoverable,\n     * recomposer will not react to invalidate calls until state is reloaded.\n     */\n    public val isRecoverable: Boolean\n}\n\n/**\n * Read only information about [Recomposer] error state. This is an internal API only kept for\n * backward compatibility.\n */\n// TODO(b/469471141): Remove when Live Edit no longer depends on this API.\n@InternalComposeApi\ninternal interface RecomposerErrorInfo {\n    /** Exception which forced recomposition to halt. */\n    val cause: Throwable\n\n    /**\n     * Whether composition can recover from the error by itself. If the error is not recoverable,\n     * recomposer will not react to invalidate calls until state is reloaded.\n     */\n    val recoverable: Boolean\n}\n\n/**\n * The scheduler for performing recomposition and applying updates to one or more [Composition]s.\n */\n// RedundantVisibilityModifier suppressed because metalava picks up internal function overrides\n// if 'internal' is not explicitly specified - b/171342041\n// NotCloseable suppressed because this is Kotlin-only common code; [Auto]Closeable not available.\n@Suppress(\"RedundantVisibilityModifier\", \"NotCloseable\")\n@OptIn(InternalComposeApi::class)\npublic class Recomposer(effectCoroutineContext: CoroutineContext) : CompositionContext() {\n    /**\n     * This is a running count of the number of times the recomposer awoke and applied changes to\n     * one or more composers. This count is unaffected if the composer awakes and recomposed but\n     * composition did not produce changes to apply.\n     */\n    public var changeCount: Long = 0L\n        private set\n\n    private val broadcastFrameClock = BroadcastFrameClock { onNewFrameAwaiter() }\n    private val nextFrameEndCallbackQueue = NextFrameEndCallbackQueue { onNewFrameAwaiter() }\n\n    /** Valid operational states of a [Recomposer]. */\n    public enum class State {\n        /**\n         * [cancel] was called on the [Recomposer] and all cleanup work has completed. The\n         * [Recomposer] is no longer available for use.\n         */\n        ShutDown,\n\n        /**\n         * [cancel] was called on the [Recomposer] and it is no longer available for use. Cleanup\n         * work has not yet been fully completed and composition effect coroutines may still be\n         * running.\n         */\n        ShuttingDown,\n\n        /**\n         * The [Recomposer] is not tracking invalidations for known composers and it will not\n         * recompose them in response to changes. Call [runRecomposeAndApplyChanges] to await and\n         * perform work. This is the initial state of a newly constructed [Recomposer].\n         */\n        Inactive,\n\n        /**\n         * The [Recomposer] is [Inactive] but at least one effect associated with a managed\n         * composition is awaiting a frame. This frame will not be produced until the [Recomposer]\n         * is [running][runRecomposeAndApplyChanges].\n         */\n        InactivePendingWork,\n\n        /**\n         * The [Recomposer] is tracking composition and snapshot invalidations but there is\n         * currently no work to do.\n         */\n        Idle,\n\n        /**\n         * The [Recomposer] has been notified of pending work it must perform and is either actively\n         * performing it or awaiting the appropriate opportunity to perform it. This work may\n         * include invalidated composers that must be recomposed, snapshot state changes that must\n         * be presented to known composers to check for invalidated compositions, or coroutines\n         * awaiting a frame using the Recomposer's [MonotonicFrameClock].\n         */\n        PendingWork,\n    }\n\n    private val stateLock = makeSynchronizedObject()\n\n    // Begin properties guarded by stateLock\n    private var runnerJob: Job? = null\n    private var closeCause: Throwable? = null\n    private val _knownCompositions = mutableListOf<ControlledComposition>()\n    private var _knownCompositionsCache: List<ControlledComposition>? = null\n    private var snapshotInvalidations = MutableScatterSet<Any>()\n    private val compositionInvalidations = mutableVectorOf<ControlledComposition>()\n    private val compositionsAwaitingApply = mutableListOf<ControlledComposition>()\n    private val movableContentAwaitingInsert = mutableListOf<MovableContentStateReference>()\n    private val movableContentRemoved =\n        MultiValueMap<MovableContent<Any?>, MovableContentStateReference>()\n    private val movableContentNestedStatesAvailable = NestedContentMap()\n    private val movableContentStatesAvailable =\n        mutableScatterMapOf<MovableContentStateReference, MovableContentState>()\n    private val movableContentNestedExtractionsPending =\n        MultiValueMap<MovableContentStateReference, MovableContentStateReference>()\n    private var failedCompositions: MutableList<ControlledComposition>? = null\n    private var compositionsRemoved: MutableScatterSet<ControlledComposition>? = null\n    private var workContinuation: CancellableContinuation<Unit>? = null\n    private var concurrentCompositionsOutstanding = 0\n    private var isClosed: Boolean = false\n    private var errorState = MutableStateFlow<RecomposerErrorState?>(null)\n\n    private var frameClockPaused: Boolean = false\n    // End properties guarded by stateLock\n\n    private val _state = MutableStateFlow(State.Inactive)\n    private val pausedScopes = SnapshotThreadLocal<MutableScatterSet<RecomposeScopeImpl>?>()\n\n    /**\n     * A [Job] used as a parent of any effects created by this [Recomposer]'s compositions. Its\n     * cleanup is used to advance to [State.ShuttingDown] or [State.ShutDown].\n     *\n     * Initialized after other state above, since it is possible for [Job.invokeOnCompletion] to run\n     * synchronously during construction if the [Recomposer] is constructed with a completed or\n     * cancelled [Job].\n     */\n    private val effectJob =\n        Job(effectCoroutineContext[Job]).apply {\n            invokeOnCompletion { throwable ->\n                // Since the running recompose job is operating in a disjoint job if present,\n                // kick it out and make sure no new ones start if we have one.\n                val cancellation =\n                    CancellationException(\"Recomposer effect job completed\", throwable)\n\n                var continuationToResume: CancellableContinuation<Unit>? = null\n                synchronized(stateLock) {\n                    val runnerJob = runnerJob\n                    if (runnerJob != null) {\n                        _state.value = State.ShuttingDown\n                        // If the recomposer is closed we will let the runnerJob return from\n                        // runRecomposeAndApplyChanges normally and consider ourselves shut down\n                        // immediately.\n                        if (!isClosed) {\n                            // This is the job hosting frameContinuation; no need to resume it\n                            // otherwise\n                            runnerJob.cancel(cancellation)\n                        } else if (workContinuation != null) {\n                            continuationToResume = workContinuation\n                        }\n                        workContinuation = null\n                        runnerJob.invokeOnCompletion { runnerJobCause ->\n                            synchronized(stateLock) {\n                                closeCause =\n                                    throwable?.apply {\n                                        runnerJobCause\n                                            ?.takeIf { it !is CancellationException }\n                                            ?.let { addSuppressed(it) }\n                                    }\n                                _state.value = State.ShutDown\n                            }\n                        }\n                    } else {\n                        closeCause = cancellation\n                        _state.value = State.ShutDown\n                    }\n                }\n                continuationToResume?.resume(Unit)\n            }\n        }\n\n    /** The [effectCoroutineContext] is derived from the parameter of the same name. */\n    override val effectCoroutineContext: CoroutineContext =\n        effectCoroutineContext + broadcastFrameClock + effectJob\n\n    private val hasBroadcastFrameClockAwaitersLocked: Boolean\n        get() = !frameClockPaused && broadcastFrameClock.hasAwaiters\n\n    private val hasNextFrameEndAwaitersLocked: Boolean\n        get() = !frameClockPaused && nextFrameEndCallbackQueue.hasAwaiters\n\n    private val hasBroadcastFrameClockAwaiters: Boolean\n        get() = synchronized(stateLock) { hasBroadcastFrameClockAwaitersLocked }\n\n    @OptIn(ExperimentalComposeRuntimeApi::class)\n    private var registrationObservers: MutableObjectList<CompositionRegistrationObserver>? = null\n\n    /**\n     * Determine the new value of [_state]. Call only while locked on [stateLock]. If it returns a\n     * continuation, that continuation should be resumed after releasing the lock.\n     */\n    private fun deriveStateLocked(): CancellableContinuation<Unit>? {\n        if (_state.value <= State.ShuttingDown) {\n            clearKnownCompositionsLocked()\n            snapshotInvalidations = MutableScatterSet()\n            compositionInvalidations.clear()\n            compositionsAwaitingApply.clear()\n            movableContentAwaitingInsert.clear()\n            failedCompositions = null\n            workContinuation?.cancel()\n            workContinuation = null\n            errorState.value = null\n            return null\n        }\n\n        val newState =\n            when {\n                errorState.value != null -> {\n                    State.Inactive\n                }\n                runnerJob == null -> {\n                    snapshotInvalidations = MutableScatterSet()\n                    compositionInvalidations.clear()\n                    if (hasBroadcastFrameClockAwaitersLocked || hasNextFrameEndAwaitersLocked)\n                        State.InactivePendingWork\n                    else State.Inactive\n                }\n                compositionInvalidations.isNotEmpty() ||\n                    snapshotInvalidations.isNotEmpty() ||\n                    compositionsAwaitingApply.isNotEmpty() ||\n                    movableContentAwaitingInsert.isNotEmpty() ||\n                    concurrentCompositionsOutstanding > 0 ||\n                    hasBroadcastFrameClockAwaitersLocked ||\n                    hasNextFrameEndAwaitersLocked ||\n                    movableContentRemoved.isNotEmpty() -> State.PendingWork\n                else -> State.Idle\n            }\n\n        _state.value = newState\n        return if (newState == State.PendingWork) {\n            workContinuation.also { workContinuation = null }\n        } else null\n    }\n\n    private fun onNewFrameAwaiter() {\n        synchronized(stateLock) {\n                deriveStateLocked().also {\n                    if (_state.value <= State.ShuttingDown)\n                        throw CancellationException(\n                            \"Recomposer shutdown; frame clock awaiter will never resume\",\n                            closeCause,\n                        )\n                }\n            }\n            ?.resume(Unit)\n    }\n\n    /** `true` if there is still work to do for an active caller of [runRecomposeAndApplyChanges] */\n    private val shouldKeepRecomposing: Boolean\n        get() = synchronized(stateLock) { !isClosed } || effectJob.children.any { it.isActive }\n\n    /** The current [State] of this [Recomposer]. See each [State] value for its meaning. */\n    @Deprecated(\"Replaced by currentState as a StateFlow\", ReplaceWith(\"currentState\"))\n    public val state: Flow<State>\n        get() = currentState\n\n    /** The current [State] of this [Recomposer], available synchronously. */\n    public val currentState: StateFlow<State>\n        get() = _state\n\n    // A separate private object to avoid the temptation of casting a RecomposerInfo\n    // to a Recomposer if Recomposer itself were to implement RecomposerInfo.\n    private inner class RecomposerInfoImpl : RecomposerInfo {\n        override val state: Flow<State>\n            get() = this@Recomposer.currentState\n\n        override val hasPendingWork: Boolean\n            get() = this@Recomposer.hasPendingWork\n\n        override val changeCount: Long\n            get() = this@Recomposer.changeCount\n\n        @ComposeToolingApi\n        override val errorState: StateFlow<RecomposerErrorInformation?>\n            get() = this@Recomposer.errorState\n\n        @ComposeToolingApi\n        val currentError: RecomposerErrorInformation?\n            get() = synchronized(stateLock) { this@Recomposer.errorState.value }\n\n        @OptIn(ExperimentalComposeRuntimeApi::class)\n        override fun observe(observer: CompositionRegistrationObserver): CompositionObserverHandle =\n            this@Recomposer.observe(observer)\n\n        fun invalidateGroupsWithKey(key: Int) {\n            val compositions: List<ControlledComposition> = knownCompositions()\n            compositions\n                .fastMapNotNull { it as? CompositionImpl }\n                .fastForEach { it.invalidateGroupsWithKey(key) }\n        }\n\n        fun saveStateAndDisposeForHotReload(): List<HotReloadable> {\n            val compositions: List<ControlledComposition> = knownCompositions()\n            return compositions\n                .fastMapNotNull { it as? CompositionImpl }\n                .fastMap { HotReloadable(it).apply { clearContent() } }\n        }\n\n        fun resetErrorState(): RecomposerErrorState? = this@Recomposer.resetErrorState()\n\n        fun retryFailedCompositions() = this@Recomposer.retryFailedCompositions()\n    }\n\n    private class HotReloadable(private val composition: CompositionImpl) {\n        private var composable: @Composable () -> Unit = composition.composable\n\n        fun clearContent() {\n            if (composition.isRoot) {\n                composition.setContent {}\n            }\n        }\n\n        fun resetContent() {\n            composition.composable = composable\n        }\n\n        fun recompose() {\n            if (composition.isRoot) {\n                composition.setContent(composable)\n            }\n        }\n    }\n\n    @OptIn(ComposeToolingApi::class)\n    private class RecomposerErrorState(\n        override val cause: Throwable,\n        override val isRecoverable: Boolean,\n    ) : RecomposerErrorInfo, RecomposerErrorInformation {\n        override val recoverable: Boolean\n            get() = isRecoverable\n    }\n\n    private val recomposerInfo = RecomposerInfoImpl()\n\n    /** Obtain a read-only [RecomposerInfo] for this [Recomposer]. */\n    public fun asRecomposerInfo(): RecomposerInfo = recomposerInfo\n\n    /**\n     * Propagate all invalidations from `snapshotInvalidations` to all the known compositions.\n     *\n     * @return `true` if the frame has work to do (e.g. [hasFrameWorkLocked])\n     */\n    private fun recordComposerModifications(): Boolean {\n        var compositions: List<ControlledComposition> = emptyList()\n        val changes =\n            synchronized(stateLock) {\n                if (snapshotInvalidations.isEmpty()) return hasFrameWorkLocked\n                compositions = knownCompositionsLocked()\n                snapshotInvalidations.wrapIntoSet().also {\n                    snapshotInvalidations = MutableScatterSet()\n                }\n            }\n        var complete = false\n        try {\n            run {\n                compositions.fastForEach { composition ->\n                    composition.recordModificationsOf(changes)\n\n                    // Stop dispatching if the recomposer if we detect the recomposer\n                    // is shutdown.\n                    if (_state.value <= State.ShuttingDown) return@run\n                }\n            }\n            complete = true\n        } finally {\n            if (!complete) {\n                // If the previous loop was not complete, we have not sent all of theses\n                // changes to all the composers so try again after the exception that caused\n                // the early exit is handled and we can then retry sending the changes.\n                synchronized(stateLock) { snapshotInvalidations.addAll(changes) }\n            }\n        }\n        return synchronized(stateLock) {\n            if (deriveStateLocked() != null) {\n                error(\"called outside of runRecomposeAndApplyChanges\")\n            }\n            hasFrameWorkLocked\n        }\n    }\n\n    private fun registerRunnerJob(callingJob: Job) {\n        synchronized(stateLock) {\n            closeCause?.let { throw it }\n            if (_state.value <= State.ShuttingDown) error(\"Recomposer shut down\")\n            if (runnerJob != null) error(\"Recomposer already running\")\n            runnerJob = callingJob\n            if (deriveStateLocked() != null) {\n                composeImmediateRuntimeError(\"called outside of runRecomposeAndApplyChanges\")\n            }\n        }\n    }\n\n    /**\n     * Await the invalidation of any associated [Composer]s, recompose them, and apply their changes\n     * to their associated [Composition]s if recomposition is successful.\n     *\n     * While [runRecomposeAndApplyChanges] is running, [awaitIdle] will suspend until there are no\n     * more invalid composers awaiting recomposition.\n     *\n     * This method will not return unless the [Recomposer] is [close]d and all effects in managed\n     * compositions complete. Unhandled failure exceptions from child coroutines will be thrown by\n     * this method.\n     */\n    public suspend fun runRecomposeAndApplyChanges(): Unit =\n        recompositionRunner { parentFrameClock ->\n            val toRecompose = mutableListOf<ControlledComposition>()\n            val toInsert = mutableListOf<MovableContentStateReference>()\n            val toApply = mutableListOf<ControlledComposition>()\n            val toLateApply = mutableScatterSetOf<ControlledComposition>()\n            val toComplete = mutableScatterSetOf<ControlledComposition>()\n            val modifiedValues = MutableScatterSet<Any>()\n            val modifiedValuesSet = modifiedValues.wrapIntoSet()\n            val alreadyComposed = mutableScatterSetOf<ControlledComposition>()\n\n            fun clearRecompositionState() {\n                synchronized(stateLock) {\n                    toRecompose.clear()\n                    toInsert.clear()\n\n                    toApply.fastForEach {\n                        it.abandonChanges()\n                        recordFailedCompositionLocked(it)\n                    }\n                    toApply.clear()\n\n                    toLateApply.forEach {\n                        it.abandonChanges()\n                        recordFailedCompositionLocked(it)\n                    }\n                    toLateApply.clear()\n\n                    toComplete.forEach { it.changesApplied() }\n                    toComplete.clear()\n\n                    modifiedValues.clear()\n\n                    alreadyComposed.forEach {\n                        it.abandonChanges()\n                        recordFailedCompositionLocked(it)\n                    }\n                    alreadyComposed.clear()\n                }\n            }\n\n            fun fillToInsert() {\n                toInsert.clear()\n                synchronized(stateLock) {\n                    movableContentAwaitingInsert.fastForEach { toInsert += it }\n                    movableContentAwaitingInsert.clear()\n                }\n            }\n\n            while (shouldKeepRecomposing) {\n                awaitWorkAvailable()\n\n                // Don't await a new frame if we don't have frame-scoped work\n                if (!recordComposerModifications()) continue\n\n                // Align work with the next frame to coalesce changes.\n                // Note: it is possible to resume from the above with no recompositions pending,\n                // instead someone might be awaiting our frame clock dispatch below.\n                // We use the cached frame clock from above not just so that we don't locate it\n                // each time, but because we've installed the broadcastFrameClock as the scope\n                // clock above for user code to locate.\n                parentFrameClock.withFrameNanos { frameTime ->\n                    // Dispatch MonotonicFrameClock frames first; this may produce new\n                    // composer invalidations that we must handle during the same frame.\n                    if (hasBroadcastFrameClockAwaiters) {\n                        trace(\"Recomposer:animation\") {\n                            // Propagate the frame time to anyone who is awaiting from the\n                            // recomposer clock.\n                            broadcastFrameClock.sendFrame(frameTime)\n\n                            // Ensure any global changes are observed\n                            Snapshot.sendApplyNotifications()\n                        }\n                    }\n\n                    trace(\"Recomposer:recompose\") {\n                        // Drain any composer invalidations from snapshot changes and record\n                        // composers to work on\n                        recordComposerModifications()\n                        synchronized(stateLock) {\n                            compositionInvalidations.forEach { toRecompose += it }\n                            compositionInvalidations.clear()\n                        }\n\n                        // Perform recomposition for any invalidated composers\n                        modifiedValues.clear()\n                        alreadyComposed.clear()\n                        while (toRecompose.isNotEmpty() || toInsert.isNotEmpty()) {\n                            try {\n                                toRecompose.fastForEach { composition ->\n                                    performRecompose(composition, modifiedValues)?.let {\n                                        toApply += it\n                                    }\n                                    alreadyComposed.add(composition)\n                                }\n                            } catch (e: Throwable) {\n                                processCompositionError(e, recoverable = true)\n                                clearRecompositionState()\n                                return@withFrameNanos\n                            } finally {\n                                toRecompose.clear()\n                            }\n\n                            // Find any trailing recompositions that need to be composed because\n                            // of a value change by a composition. This can happen, for example, if\n                            // a CompositionLocal changes in a parent and was read in a child\n                            // composition that was otherwise valid.\n                            if (\n                                modifiedValues.isNotEmpty() || compositionInvalidations.isNotEmpty()\n                            ) {\n                                synchronized(stateLock) {\n                                    knownCompositionsLocked().fastForEach { value ->\n                                        if (\n                                            value !in alreadyComposed &&\n                                                value.observesAnyOf(modifiedValuesSet)\n                                        ) {\n                                            toRecompose += value\n                                        }\n                                    }\n\n                                    // Composable lambda is a special kind of value that is not\n                                    // observed\n                                    // by the snapshot system, but invalidates composition scope\n                                    // directly instead.\n                                    compositionInvalidations.removeIf { value ->\n                                        if (value !in alreadyComposed && value !in toRecompose) {\n                                            toRecompose += value\n                                            true\n                                        } else {\n                                            false\n                                        }\n                                    }\n                                }\n                            }\n\n                            if (toRecompose.isEmpty()) {\n                                try {\n                                    fillToInsert()\n                                    while (toInsert.isNotEmpty()) {\n                                        toLateApply += performInsertValues(toInsert, modifiedValues)\n                                        fillToInsert()\n                                    }\n                                } catch (e: Throwable) {\n                                    processCompositionError(e, recoverable = true)\n                                    clearRecompositionState()\n                                    return@withFrameNanos\n                                }\n                            }\n                        }\n\n                        // This is an optimization to avoid reallocating TransparentSnapshot for\n                        // each observeChanges within `apply`. Many modifiers use observation in\n                        // `onAttach` and other lifecycle methods, and allocations can be mitigated\n                        // by updating read observer in the snapshot allocated here.\n                        withTransparentSnapshot {\n                            if (toApply.isNotEmpty()) {\n                                changeCount++\n\n                                // Perform apply changes\n                                try {\n                                    // We could do toComplete += toApply but doing it like below\n                                    // avoids unnecessary allocations since toApply is a mutable\n                                    // list\n                                    // toComplete += toApply\n                                    toApply.fastForEach { composition ->\n                                        toComplete.add(composition)\n                                    }\n                                    toApply.fastForEach { composition ->\n                                        composition.applyChanges()\n                                    }\n                                } catch (e: Throwable) {\n                                    processCompositionError(e)\n                                    clearRecompositionState()\n                                    return@withFrameNanos\n                                } finally {\n                                    toApply.clear()\n                                }\n                            }\n\n                            if (toLateApply.isNotEmpty()) {\n                                try {\n                                    toComplete += toLateApply\n                                    toLateApply.forEach { composition ->\n                                        composition.applyLateChanges()\n                                    }\n                                } catch (e: Throwable) {\n                                    processCompositionError(e)\n                                    clearRecompositionState()\n                                    return@withFrameNanos\n                                } finally {\n                                    toLateApply.clear()\n                                }\n                            }\n\n                            if (toComplete.isNotEmpty()) {\n                                try {\n                                    toComplete.forEach { composition ->\n                                        composition.changesApplied()\n                                    }\n                                } catch (e: Throwable) {\n                                    processCompositionError(e)\n                                    clearRecompositionState()\n                                    return@withFrameNanos\n                                } finally {\n                                    toComplete.clear()\n                                }\n                            }\n                        }\n\n                        synchronized(stateLock) {\n                            runtimeCheck(deriveStateLocked() == null) {\n                                \"unexpected to get continuation here\"\n                            }\n                        }\n\n                        // Ensure any state objects that were written during apply changes, e.g.\n                        // nodes with state-backed properties, get sent apply notifications to\n                        // invalidate anything observing the nodes. Call this method instead of\n                        // sendApplyNotifications to ensure that objects that were _created_ in this\n                        // snapshot are also considered changed after this point.\n                        Snapshot.notifyObjectsInitialized()\n                        alreadyComposed.clear()\n                        modifiedValues.clear()\n                        compositionsRemoved = null\n                    }\n                }\n\n                discardUnusedMovableContentState()\n                nextFrameEndCallbackQueue.markFrameComplete()\n            }\n        }\n\n    private fun processCompositionError(\n        e: Throwable,\n        failedInitialComposition: ControlledComposition? = null,\n        recoverable: Boolean = false,\n    ) {\n        if (_hotReloadEnabled.get() && e !is ComposeRuntimeError) {\n            synchronized(stateLock) {\n                logError(\"Error was captured in composition while live edit was enabled.\", e)\n\n                compositionsAwaitingApply.clear()\n                compositionInvalidations.clear()\n                snapshotInvalidations = MutableScatterSet()\n\n                movableContentAwaitingInsert.clear()\n                movableContentRemoved.clear()\n                movableContentStatesAvailable.clear()\n\n                errorState.value = RecomposerErrorState(isRecoverable = recoverable, cause = e)\n\n                if (failedInitialComposition != null) {\n                    recordFailedCompositionLocked(failedInitialComposition)\n                }\n\n                if (deriveStateLocked() != null) {\n                    composeImmediateRuntimeError(\n                        \"expected to go to inactive state due to composition error\"\n                    )\n                }\n            }\n        } else {\n            // withFrameNanos uses `runCatching` to ensure that crashes are not propagated to\n            // AndroidUiDispatcher. This means that errors that happen during recomposition might\n            // be delayed by a frame and swallowed if composed into inconsistent state caused by\n            // the error.\n            // Common case is subcomposition: if measure occurs after recomposition has thrown,\n            // composeInitial will throw because of corrupted composition while original exception\n            // won't be recorded.\n            synchronized(stateLock) {\n                logError(\"Error was captured in composition.\", e)\n                val errorState = errorState.value\n                if (errorState == null) {\n                    // Record exception if current error state is empty.\n                    this.errorState.value = RecomposerErrorState(isRecoverable = false, cause = e)\n                } else {\n                    // Re-throw original cause if we recorded it previously.\n                    throw errorState.cause\n                }\n            }\n\n            throw e\n        }\n    }\n\n    private inline fun withTransparentSnapshot(block: () -> Unit) {\n        val currentSnapshot = Snapshot.current\n\n        val snapshot =\n            if (currentSnapshot is MutableSnapshot) {\n                TransparentObserverMutableSnapshot(\n                    currentSnapshot,\n                    null,\n                    null,\n                    mergeParentObservers = true,\n                    ownsParentSnapshot = false,\n                )\n            } else {\n                TransparentObserverSnapshot(\n                    currentSnapshot,\n                    null,\n                    mergeParentObservers = true,\n                    ownsParentSnapshot = false,\n                )\n            }\n        try {\n            snapshot.enter(block)\n        } finally {\n            snapshot.dispose()\n        }\n    }\n\n    /**\n     * Returns a cached copy of the list of known compositions that can be iterated safely without\n     * holding the `stateLock`.\n     */\n    private fun knownCompositions(): List<ControlledComposition> {\n        return synchronized(stateLock) { knownCompositionsLocked() }\n    }\n\n    private fun knownCompositionsLocked(): List<ControlledComposition> {\n        val cache = _knownCompositionsCache\n        if (cache != null) return cache\n\n        val compositions = _knownCompositions\n        val newCache = if (compositions.isEmpty()) emptyList() else ArrayList(compositions)\n        _knownCompositionsCache = newCache\n        return newCache\n    }\n\n    @OptIn(ExperimentalComposeRuntimeApi::class)\n    private fun clearKnownCompositionsLocked() {\n        knownCompositionsLocked().fastForEach { composition ->\n            unregisterCompositionLocked(composition)\n        }\n        _knownCompositions.clear()\n        _knownCompositionsCache = emptyList()\n    }\n\n    private fun removeKnownCompositionLocked(composition: ControlledComposition) {\n        if (_knownCompositions.remove(composition)) {\n            _knownCompositionsCache = null\n            unregisterCompositionLocked(composition)\n        }\n    }\n\n    private fun addKnownCompositionLocked(composition: ControlledComposition) {\n        _knownCompositions += composition\n        _knownCompositionsCache = null\n    }\n\n    @OptIn(ExperimentalComposeRuntimeApi::class)\n    private fun registerCompositionLocked(composition: ControlledComposition) {\n        registrationObservers?.forEach {\n            if (composition is ObservableComposition) {\n                it.onCompositionRegistered(composition)\n            }\n        }\n    }\n\n    @OptIn(ExperimentalComposeRuntimeApi::class)\n    private fun unregisterCompositionLocked(composition: ControlledComposition) {\n        registrationObservers?.forEach {\n            if (composition is ObservableComposition) {\n                it.onCompositionUnregistered(composition)\n            }\n        }\n    }\n\n    @OptIn(ExperimentalComposeRuntimeApi::class)\n    internal fun addCompositionRegistrationObserver(\n        observer: CompositionRegistrationObserver\n    ): CompositionObserverHandle {\n        synchronized(stateLock) {\n            val observers =\n                registrationObservers\n                    ?: MutableObjectList<CompositionRegistrationObserver>().also {\n                        registrationObservers = it\n                    }\n\n            observers += observer\n            _knownCompositions.fastForEach { composition ->\n                if (composition is ObservableComposition) {\n                    observer.onCompositionRegistered(composition)\n                }\n            }\n        }\n\n        return object : CompositionObserverHandle {\n            override fun dispose() {\n                synchronized(stateLock) { registrationObservers?.remove(observer) }\n            }\n        }\n    }\n\n    private fun resetErrorState(): RecomposerErrorState? {\n        var error: RecomposerErrorState? = null\n        synchronized(stateLock) {\n                error = errorState.value\n                if (error != null) {\n                    errorState.value = null\n                    deriveStateLocked()\n                } else {\n                    null\n                }\n            }\n            ?.resume(Unit)\n        return error\n    }\n\n    private fun retryFailedCompositions() {\n        val compositionsToRetry =\n            synchronized(stateLock) { failedCompositions.also { failedCompositions = null } }\n                ?: return\n        try {\n            while (compositionsToRetry.isNotEmpty()) {\n                val composition = compositionsToRetry.removeLastKt()\n                if (composition !is CompositionImpl) continue\n\n                composition.invalidateAll()\n                composition.setContent(composition.composable)\n\n                if (errorState.value != null) break\n            }\n        } finally {\n            if (compositionsToRetry.isNotEmpty()) {\n                // If we did not complete the last list then add the remaining compositions back\n                // into the failedCompositions list\n                synchronized(stateLock) {\n                    compositionsToRetry.fastForEach { recordFailedCompositionLocked(it) }\n                }\n            }\n        }\n    }\n\n    private fun recordFailedCompositionLocked(composition: ControlledComposition) {\n        val failedCompositions =\n            failedCompositions\n                ?: mutableListOf<ControlledComposition>().also { failedCompositions = it }\n\n        if (composition !in failedCompositions) {\n            failedCompositions += composition\n        }\n        removeKnownCompositionLocked(composition)\n    }\n\n    private val hasSchedulingWork: Boolean\n        get() =\n            synchronized(stateLock) {\n                snapshotInvalidations.isNotEmpty() ||\n                    compositionInvalidations.isNotEmpty() ||\n                    hasBroadcastFrameClockAwaitersLocked ||\n                    hasNextFrameEndAwaitersLocked\n            }\n\n    private suspend fun awaitWorkAvailable() {\n        if (!hasSchedulingWork) {\n            // NOTE: Do not remove the `<Unit>` from the next line even if the IDE reports it as\n            // redundant. Removing this causes reports it cannot infer the type. (KT-79553)\n            @Suppress(\"RemoveExplicitTypeArguments\") // See note above\n            suspendCancellableCoroutine<Unit> { co ->\n                synchronized(stateLock) {\n                        if (hasSchedulingWork) {\n                            co\n                        } else {\n                            workContinuation = co\n                            null\n                        }\n                    }\n                    ?.resume(Unit)\n            }\n        }\n    }\n\n    @OptIn(ExperimentalComposeApi::class)\n    private suspend fun recompositionRunner(\n        block: suspend CoroutineScope.(parentFrameClock: MonotonicFrameClock) -> Unit\n    ) {\n        val parentFrameClock = coroutineContext.monotonicFrameClock\n        withContext(broadcastFrameClock) {\n            // Enforce mutual exclusion of callers; register self as current runner\n            val callingJob = coroutineContext.job\n            registerRunnerJob(callingJob)\n\n            // Observe snapshot changes and propagate them to known composers only from\n            // this caller's dispatcher, never working with the same composer in parallel.\n            // unregisterApplyObserver is called as part of the big finally below\n            val unregisterApplyObserver =\n                Snapshot.registerApplyObserver { changed, _ ->\n                    synchronized(stateLock) {\n                            if (_state.value >= State.Idle) {\n                                val snapshotInvalidations = snapshotInvalidations\n                                changed.fastForEach {\n                                    if (\n                                        it is StateObjectImpl &&\n                                            !it.isReadIn(ReaderKind.Composition)\n                                    ) {\n                                        // continue if we know that state is never read in\n                                        // composition\n                                        return@fastForEach\n                                    }\n                                    snapshotInvalidations.add(it)\n                                }\n                                deriveStateLocked()\n                            } else null\n                        }\n                        ?.resume(Unit)\n                }\n\n            addRunning(recomposerInfo)\n\n            try {\n                // Invalidate all registered composers when we start since we weren't observing\n                // snapshot changes on their behalf. Assume anything could have changed.\n                knownCompositions().fastForEach { it.invalidateAll() }\n\n                coroutineScope { block(parentFrameClock) }\n            } finally {\n                unregisterApplyObserver.dispose()\n                synchronized(stateLock) {\n                    if (runnerJob === callingJob) {\n                        runnerJob = null\n                    }\n                    if (deriveStateLocked() != null) {\n                        composeImmediateRuntimeError(\n                            \"called outside of runRecomposeAndApplyChanges\"\n                        )\n                    }\n                }\n                removeRunning(recomposerInfo)\n            }\n        }\n    }\n\n    /**\n     * Permanently shut down this [Recomposer] for future use. [currentState] will immediately\n     * reflect [State.ShuttingDown] (or a lower state) before this call returns. All ongoing\n     * recompositions will stop, new composer invalidations with this [Recomposer] at the root will\n     * no longer occur, and any [LaunchedEffect]s currently running in compositions managed by this\n     * [Recomposer] will be cancelled. Any [rememberCoroutineScope] scopes from compositions managed\n     * by this [Recomposer] will also be cancelled. See [join] to await the completion of all of\n     * these outstanding tasks.\n     */\n    public fun cancel() {\n        // Move to State.ShuttingDown immediately rather than waiting for effectJob to join\n        // if we're cancelling to shut down the Recomposer. This permits other client code\n        // to use `state.first { it < State.Idle }` or similar to reliably and immediately detect\n        // that the recomposer can no longer be used.\n        // It looks like a CAS loop would be more appropriate here, but other occurrences\n        // of taking stateLock assume that the state cannot change without holding it.\n        synchronized(stateLock) {\n            if (_state.value >= State.Idle) {\n                _state.value = State.ShuttingDown\n            }\n        }\n        effectJob.cancel()\n    }\n\n    /**\n     * Close this [Recomposer]. Once all effects launched by managed compositions complete, any\n     * active call to [runRecomposeAndApplyChanges] will return normally and this [Recomposer] will\n     * be [State.ShutDown]. See [join] to await the completion of all of these outstanding tasks.\n     */\n    public fun close() {\n        if (effectJob.complete()) {\n            synchronized(stateLock) { isClosed = true }\n        }\n    }\n\n    /** Await the completion of a [cancel] operation. */\n    public suspend fun join() {\n        currentState.first { it == State.ShutDown }\n    }\n\n    /**\n     * Schedules an [action] to be invoked when the recomposer finishes the next composition of a\n     * frame (including the completion of subcompositions). If a frame is currently in-progress,\n     * [action] will be invoked when the current frame fully finishes composing. If a frame isn't\n     * currently in-progress, a new frame will be scheduled (if one hasn't been already) and\n     * [action] will execute at the completion of the next frame's composition. If a new frame is\n     * scheduled and there is no other work to execute, [action] will still execute.\n     *\n     * [action] will always execute on the applier thread.\n     *\n     * @return A [CancellationHandle] that can be used to unregister the [action]. The returned\n     *   handle is thread-safe and may be cancelled from any thread. Cancelling the handle only\n     *   removes the callback from the queue. If [action] is currently executing, it will not be\n     *   cancelled by this handle.\n     */\n    public override fun scheduleFrameEndCallback(action: () -> Unit): CancellationHandle {\n        return nextFrameEndCallbackQueue.scheduleFrameEndCallback(action)\n    }\n\n    internal override fun composeInitial(\n        composition: ControlledComposition,\n        content: @Composable () -> Unit,\n    ) {\n        val composerWasComposing = composition.isComposing\n\n        val newComposition =\n            synchronized(stateLock) {\n                if (_state.value > State.ShuttingDown) {\n                    val new = composition !in knownCompositionsLocked()\n                    if (new) {\n                        registerCompositionLocked(composition)\n                    }\n                    new\n                } else {\n                    true\n                }\n            }\n\n        try {\n            composing(composition, null) { composition.composeContent(content) }\n        } catch (e: Throwable) {\n            if (newComposition) {\n                synchronized(stateLock) { unregisterCompositionLocked(composition) }\n            }\n\n            processCompositionError(e, composition, recoverable = true)\n            return\n        }\n\n        synchronized(stateLock) {\n            if (_state.value > State.ShuttingDown) {\n                if (composition !in knownCompositionsLocked()) {\n                    addKnownCompositionLocked(composition)\n                }\n            } else {\n                unregisterCompositionLocked(composition)\n            }\n        }\n\n        // TODO(b/143755743)\n        if (!composerWasComposing) {\n            Snapshot.notifyObjectsInitialized()\n        }\n\n        try {\n            performInitialMovableContentInserts(composition)\n        } catch (e: Throwable) {\n            processCompositionError(e, composition, recoverable = true)\n            return\n        }\n\n        try {\n            composition.applyChanges()\n            composition.applyLateChanges()\n        } catch (e: Throwable) {\n            processCompositionError(e)\n            return\n        }\n\n        if (!composerWasComposing) {\n            // Ensure that any state objects created during applyChanges are seen as changed\n            // if modified after this call.\n            Snapshot.notifyObjectsInitialized()\n        }\n    }\n\n    internal override fun composeInitialPaused(\n        composition: ControlledComposition,\n        shouldPause: ShouldPauseCallback,\n        content: @Composable () -> Unit,\n    ): ScatterSet<RecomposeScopeImpl> {\n        return try {\n            composition.pausable(shouldPause) {\n                composeInitial(composition, content)\n                pausedScopes.get() ?: emptyScatterSet()\n            }\n        } finally {\n            pausedScopes.set(null)\n        }\n    }\n\n    internal override fun recomposePaused(\n        composition: ControlledComposition,\n        shouldPause: ShouldPauseCallback,\n        invalidScopes: ScatterSet<RecomposeScopeImpl>,\n    ): ScatterSet<RecomposeScopeImpl> {\n        return try {\n            recordComposerModifications()\n            composition.recordModificationsOf(invalidScopes.wrapIntoSet())\n            composition.pausable(shouldPause) {\n                val needsApply = performRecompose(composition, null)\n                if (needsApply != null) {\n                    performInitialMovableContentInserts(composition)\n                    needsApply.applyChanges()\n                    needsApply.applyLateChanges()\n                }\n                pausedScopes.get() ?: emptyScatterSet()\n            }\n        } finally {\n            pausedScopes.set(null)\n        }\n    }\n\n    override fun reportPausedScope(scope: RecomposeScopeImpl) {\n        val scopes =\n            pausedScopes.get()\n                ?: run {\n                    val newScopes = mutableScatterSetOf<RecomposeScopeImpl>()\n                    pausedScopes.set(newScopes)\n                    newScopes\n                }\n        scopes.add(scope)\n    }\n\n    private fun performInitialMovableContentInserts(composition: ControlledComposition) {\n        synchronized(stateLock) {\n            if (!movableContentAwaitingInsert.fastAny { it.composition == composition }) return\n        }\n        val toInsert = mutableListOf<MovableContentStateReference>()\n        fun fillToInsert() {\n            toInsert.clear()\n            synchronized(stateLock) {\n                val iterator = movableContentAwaitingInsert.iterator()\n                while (iterator.hasNext()) {\n                    val value = iterator.next()\n                    if (value.composition == composition) {\n                        toInsert.add(value)\n                        iterator.remove()\n                    }\n                }\n            }\n        }\n        fillToInsert()\n        while (toInsert.isNotEmpty()) {\n            performInsertValues(toInsert, null)\n            fillToInsert()\n        }\n    }\n\n    private fun performRecompose(\n        composition: ControlledComposition,\n        modifiedValues: MutableScatterSet<Any>?,\n    ): ControlledComposition? {\n        if (\n            composition.isComposing ||\n                composition.isDisposed ||\n                compositionsRemoved?.contains(composition) == true\n        )\n            return null\n\n        return if (\n            composing(composition, modifiedValues) {\n                if (modifiedValues?.isNotEmpty() == true) {\n                    // Record write performed by a previous composition as if they happened during\n                    // composition.\n                    composition.prepareCompose {\n                        modifiedValues.forEach { composition.recordWriteOf(it) }\n                    }\n                }\n                composition.recompose()\n            }\n        )\n            composition\n        else null\n    }\n\n    @OptIn(ExperimentalComposeApi::class)\n    private fun performInsertValues(\n        references: List<MovableContentStateReference>,\n        modifiedValues: MutableScatterSet<Any>?,\n    ): List<ControlledComposition> {\n        val tasks = references.fastGroupBy { it.composition }\n        for ((composition, refs) in tasks) {\n            runtimeCheck(!composition.isComposing)\n            composing(composition, modifiedValues) {\n                // Map insert movable content to movable content states that have been released\n                // during `performRecompose`.\n                val pairs =\n                    synchronized(stateLock) {\n                        refs\n                            .fastMap { reference ->\n                                reference to\n                                    movableContentRemoved.removeLast(reference.content).also {\n                                        if (it != null) {\n                                            movableContentNestedStatesAvailable.usedContainer(it)\n                                        }\n                                    }\n                            }\n                            .let { pairs ->\n                                // Check for any nested states\n                                if (\n                                    pairs.fastAny {\n                                        it.second == null &&\n                                            it.first.content in movableContentNestedStatesAvailable\n                                    }\n                                ) {\n                                    // We have at least one nested state we could use, if a state\n                                    // is available for the container then schedule the state to be\n                                    // removed from the container when it is released.\n                                    pairs.fastMap { pair ->\n                                        if (pair.second == null) {\n                                            val nestedContentReference =\n                                                movableContentNestedStatesAvailable.removeLast(\n                                                    pair.first.content\n                                                )\n                                            if (nestedContentReference == null) return@fastMap pair\n                                            val content = nestedContentReference.content\n                                            val container = nestedContentReference.container\n                                            movableContentNestedExtractionsPending.add(\n                                                container,\n                                                content,\n                                            )\n                                            pair.first to content\n                                        } else pair\n                                    }\n                                } else pairs\n                            }\n                    }\n\n                // Avoid mixing creating new content with moving content as the moved content\n                // may release content when it is moved as it is recomposed when move.\n                val toInsert =\n                    if (\n                        pairs.fastAll { it.second == null } || pairs.fastAll { it.second != null }\n                    ) {\n                        pairs\n                    } else {\n                        // Return the content not moving to the awaiting list. These will come back\n                        // here in the next iteration of the caller's loop and either have content\n                        // to move or by still needing to create the content.\n                        val toReturn =\n                            pairs.fastMapNotNull { item ->\n                                if (item.second == null) item.first else null\n                            }\n                        synchronized(stateLock) { movableContentAwaitingInsert += toReturn }\n\n                        // Only insert the moving content this time\n                        pairs.fastFilterIndexed { _, item -> item.second != null }\n                    }\n\n                // toInsert is guaranteed to be not empty as,\n                // 1) refs is guaranteed to be not empty as a condition of groupBy\n                // 2) pairs is guaranteed to be not empty as it is a map of refs\n                // 3) toInsert is guaranteed to not be empty because the toReturn and toInsert\n                //    lists have at least one item by the condition of the guard in the if\n                //    expression. If one would be empty the condition is true and the filter is not\n                //    performed. As both have at least one item toInsert has at least one item. If\n                //    the filter is not performed the list is pairs which has at least one item.\n                composition.insertMovableContent(toInsert)\n            }\n        }\n        return tasks.keys.toList()\n    }\n\n    private fun discardUnusedMovableContentState() {\n        val unusedValues =\n            synchronized(stateLock) {\n                if (movableContentRemoved.isNotEmpty()) {\n                    val references = movableContentRemoved.values()\n                    movableContentRemoved.clear()\n                    movableContentNestedStatesAvailable.clear()\n                    movableContentNestedExtractionsPending.clear()\n                    val unusedValues =\n                        references.fastMap { it to movableContentStatesAvailable[it] }\n                    movableContentStatesAvailable.clear()\n                    unusedValues\n                } else emptyObjectList()\n            }\n        unusedValues.forEach { (reference, state) ->\n            if (state != null) {\n                reference.composition.disposeUnusedMovableContent(state)\n            }\n        }\n    }\n\n    private fun readObserverOf(composition: ControlledComposition): (Any) -> Unit {\n        return { value -> composition.recordReadOf(value) }\n    }\n\n    private fun writeObserverOf(\n        composition: ControlledComposition,\n        modifiedValues: MutableScatterSet<Any>?,\n    ): (Any) -> Unit {\n        return { value ->\n            composition.recordWriteOf(value)\n            modifiedValues?.add(value)\n        }\n    }\n\n    private inline fun <T> composing(\n        composition: ControlledComposition,\n        modifiedValues: MutableScatterSet<Any>?,\n        block: () -> T,\n    ): T {\n        val snapshot =\n            Snapshot.takeMutableSnapshot(\n                readObserverOf(composition),\n                writeObserverOf(composition, modifiedValues),\n            )\n        try {\n            return snapshot.enter(block)\n        } finally {\n            applyAndCheck(snapshot)\n        }\n    }\n\n    private fun applyAndCheck(snapshot: MutableSnapshot) {\n        try {\n            val applyResult = snapshot.apply()\n            if (applyResult is SnapshotApplyResult.Failure) {\n                error(\n                    \"Unsupported concurrent change during composition. A state object was \" +\n                        \"modified by composition as well as being modified outside composition.\"\n                )\n            }\n        } finally {\n            snapshot.dispose()\n        }\n    }\n\n    /**\n     * `true` if this [Recomposer] has any pending work scheduled, regardless of whether or not it\n     * is currently [running][runRecomposeAndApplyChanges].\n     */\n    public val hasPendingWork: Boolean\n        get() =\n            synchronized(stateLock) {\n                snapshotInvalidations.isNotEmpty() ||\n                    compositionInvalidations.isNotEmpty() ||\n                    concurrentCompositionsOutstanding > 0 ||\n                    compositionsAwaitingApply.isNotEmpty() ||\n                    hasBroadcastFrameClockAwaitersLocked ||\n                    hasNextFrameEndAwaitersLocked ||\n                    movableContentRemoved.isNotEmpty()\n            }\n\n    private val hasFrameWorkLocked: Boolean\n        get() =\n            compositionInvalidations.isNotEmpty() ||\n                hasBroadcastFrameClockAwaitersLocked ||\n                hasNextFrameEndAwaitersLocked ||\n                movableContentRemoved.isNotEmpty()\n\n    /**\n     * Suspends until the currently pending recomposition frame is complete. Any recomposition for\n     * this recomposer triggered by actions before this call begins will be complete and applied (if\n     * recomposition was successful) when this call returns.\n     *\n     * If [runRecomposeAndApplyChanges] is not currently running the [Recomposer] is considered idle\n     * and this method will not suspend.\n     */\n    public suspend fun awaitIdle() {\n        currentState.takeWhile { it > State.Idle }.collect()\n    }\n\n    /**\n     * Pause broadcasting the frame clock while recomposing. This effectively pauses animations, or\n     * any other use of the [withFrameNanos], while the frame clock is paused.\n     *\n     * [pauseCompositionFrameClock] should be called when the recomposer is not being displayed for\n     * some reason such as not being the current activity in Android, for example.\n     *\n     * Calls to [pauseCompositionFrameClock] are thread-safe and idempotent (calling it when the\n     * frame clock is already paused is a no-op).\n     */\n    public fun pauseCompositionFrameClock() {\n        synchronized(stateLock) { frameClockPaused = true }\n    }\n\n    /**\n     * Resume broadcasting the frame clock after is has been paused. Pending calls to\n     * [withFrameNanos] will start receiving frame clock broadcasts at the beginning of the frame\n     * and a frame will be requested if there are pending calls to [withFrameNanos] if a frame has\n     * not already been scheduled.\n     *\n     * Calls to [resumeCompositionFrameClock] are thread-safe and idempotent (calling it when the\n     * frame clock is running is a no-op).\n     */\n    public fun resumeCompositionFrameClock() {\n        synchronized(stateLock) {\n                if (frameClockPaused) {\n                    frameClockPaused = false\n                    deriveStateLocked()\n                } else null\n            }\n            ?.resume(Unit)\n    }\n\n    // Recomposer always starts with a constant compound hash\n    internal override val compositeKeyHashCode: CompositeKeyHashCode\n        get() = RecomposerCompoundHashKey\n\n    internal override val collectingCallByInformation: Boolean\n        get() = _hotReloadEnabled.get()\n\n    // Collecting parameter happens at the level of a composer; starts as false\n    internal override val collectingParameterInformation: Boolean\n        get() = false\n\n    internal override val collectingSourceInformation: Boolean\n        get() = composeStackTraceMode == ComposeStackTraceMode.SourceInformation\n\n    internal override val stackTraceEnabled: Boolean\n        get() = composeStackTraceMode != ComposeStackTraceMode.None\n\n    internal override fun recordInspectionTable(table: MutableSet<CompositionData>) {\n        // TODO: The root recomposer might be a better place to set up inspection\n        // than the current configuration with an CompositionLocal\n    }\n\n    internal override fun registerComposition(composition: ControlledComposition) {\n        // Do nothing.\n    }\n\n    internal override fun unregisterComposition(composition: ControlledComposition) {\n        synchronized(stateLock) {\n            removeKnownCompositionLocked(composition)\n            compositionInvalidations -= composition\n            compositionsAwaitingApply -= composition\n        }\n    }\n\n    internal override fun invalidate(composition: ControlledComposition) {\n        synchronized(stateLock) {\n                if (composition !in compositionInvalidations) {\n                    compositionInvalidations += composition\n                    deriveStateLocked()\n                } else null\n            }\n            ?.resume(Unit)\n    }\n\n    internal override fun invalidateScope(scope: RecomposeScopeImpl) {\n        synchronized(stateLock) {\n                snapshotInvalidations.add(scope)\n                deriveStateLocked()\n            }\n            ?.resume(Unit)\n    }\n\n    internal override fun insertMovableContent(reference: MovableContentStateReference) {\n        synchronized(stateLock) {\n                movableContentAwaitingInsert += reference\n                deriveStateLocked()\n            }\n            ?.resume(Unit)\n    }\n\n    internal override fun deletedMovableContent(reference: MovableContentStateReference) {\n        synchronized(stateLock) {\n                movableContentRemoved.add(reference.content, reference)\n                if (reference.nestedReferences != null) {\n                    val container = reference\n                    fun recordNestedStatesOf(reference: MovableContentStateReference) {\n                        reference.nestedReferences?.fastForEach { nestedReference ->\n                            movableContentNestedStatesAvailable.add(\n                                nestedReference.content,\n                                NestedMovableContent(nestedReference, container),\n                            )\n                            recordNestedStatesOf(nestedReference)\n                        }\n                    }\n                    recordNestedStatesOf(reference)\n                }\n                deriveStateLocked()\n            }\n            ?.resume(Unit)\n    }\n\n    internal override fun movableContentStateReleased(\n        reference: MovableContentStateReference,\n        data: MovableContentState,\n        applier: Applier<*>,\n    ) {\n        synchronized(stateLock) {\n            movableContentStatesAvailable[reference] = data\n            val extractions = movableContentNestedExtractionsPending[reference]\n            if (extractions.isNotEmpty()) {\n                val states = data.slotStorage.extractNestedStates(applier, extractions)\n                states.forEach { reference, state ->\n                    movableContentStatesAvailable[reference] = state\n                }\n            }\n        }\n    }\n\n    internal override fun reportRemovedComposition(composition: ControlledComposition) {\n        synchronized(stateLock) {\n            val compositionsRemoved =\n                compositionsRemoved\n                    ?: mutableScatterSetOf<ControlledComposition>().also {\n                        compositionsRemoved = it\n                    }\n            compositionsRemoved.add(composition)\n        }\n    }\n\n    override fun movableContentStateResolve(\n        reference: MovableContentStateReference\n    ): MovableContentState? =\n        synchronized(stateLock) { movableContentStatesAvailable.remove(reference) }\n\n    override val composition: Composition?\n        get() = null\n\n    /**\n     * hack: the companion object is thread local in Kotlin/Native to avoid freezing\n     * [_runningRecomposers] with the current memory model. As a side effect, recomposers are now\n     * forced to be single threaded in Kotlin/Native targets.\n     *\n     * This annotation WILL BE REMOVED with the new memory model of Kotlin/Native.\n     */\n    @ThreadLocal\n    public companion object {\n\n        private val _runningRecomposers = MutableStateFlow(persistentSetOf<RecomposerInfoImpl>())\n\n        private val _hotReloadEnabled = AtomicReference(false)\n\n        /**\n         * An observable [Set] of [RecomposerInfo]s for currently\n         * [running][runRecomposeAndApplyChanges] [Recomposer]s. Emitted sets are immutable.\n         */\n        public val runningRecomposers: StateFlow<Set<RecomposerInfo>>\n            get() = _runningRecomposers\n\n        internal fun setHotReloadEnabled(value: Boolean) {\n            _hotReloadEnabled.set(value)\n        }\n\n        private fun addRunning(info: RecomposerInfoImpl) {\n            while (true) {\n                val old = _runningRecomposers.value\n                val new = old.add(info)\n                if (old === new || _runningRecomposers.compareAndSet(old, new)) break\n            }\n        }\n\n        private fun removeRunning(info: RecomposerInfoImpl) {\n            while (true) {\n                val old = _runningRecomposers.value\n                val new = old.remove(info)\n                if (old === new || _runningRecomposers.compareAndSet(old, new)) break\n            }\n        }\n\n        internal fun saveStateAndDisposeForHotReload(): Any {\n            // NOTE: when we move composition/recomposition onto multiple threads, we will want\n            // to ensure that we pause recompositions before this call.\n            _hotReloadEnabled.set(true)\n            return _runningRecomposers.value.flatMap { it.saveStateAndDisposeForHotReload() }\n        }\n\n        internal fun loadStateAndComposeForHotReload(token: Any) {\n            // NOTE: when we move composition/recomposition onto multiple threads, we will want\n            // to ensure that we pause recompositions before this call.\n            _hotReloadEnabled.set(true)\n\n            _runningRecomposers.value.forEach { it.resetErrorState() }\n\n            @Suppress(\"UNCHECKED_CAST\") val holders = token as List<HotReloadable>\n            holders.fastForEach { it.resetContent() }\n            holders.fastForEach { it.recompose() }\n\n            _runningRecomposers.value.forEach { it.retryFailedCompositions() }\n        }\n\n        @OptIn(ComposeToolingApi::class)\n        internal fun invalidateGroupsWithKey(key: Int) {\n            _hotReloadEnabled.set(true)\n            _runningRecomposers.value.forEach {\n                if (it.currentError?.isRecoverable == false) {\n                    return@forEach\n                }\n\n                it.resetErrorState()\n\n                it.invalidateGroupsWithKey(key)\n\n                it.retryFailedCompositions()\n            }\n        }\n\n        /** This is an internal API only kept for backward compatibility. */\n        @OptIn(ComposeToolingApi::class)\n        internal fun getCurrentErrors(): List<RecomposerErrorInfo> =\n            _runningRecomposers.value.mapNotNull { it.currentError as? RecomposerErrorInfo }\n\n        @OptIn(ComposeToolingApi::class)\n        internal fun getRecomposerErrors(): List<RecomposerErrorInformation> =\n            _runningRecomposers.value.mapNotNull { it.currentError }\n\n        internal fun clearErrors() {\n            _runningRecomposers.value.mapNotNull { it.resetErrorState() }\n        }\n    }\n}\n\n/** Sentinel used by [ProduceFrameSignal] */\nprivate val ProduceAnotherFrame = Any()\nprivate val FramePending = Any()\n\n/**\n * Multiple producer, single consumer conflated signal that tells concurrent composition when it\n * should try to produce another frame. This class is intended to be used along with a lock shared\n * between producers and consumer.\n */\nprivate class ProduceFrameSignal {\n    private var pendingFrameContinuation: Any? = null\n\n    /**\n     * Suspend until a frame is requested. After this method returns the signal is in a\n     * [FramePending] state which must be acknowledged by a call to [takeFrameRequestLocked] once\n     * all data that will be used to produce the frame has been claimed.\n     */\n    suspend fun awaitFrameRequest(lock: SynchronizedObject) {\n        synchronized(lock) {\n            if (pendingFrameContinuation === ProduceAnotherFrame) {\n                pendingFrameContinuation = FramePending\n                return\n            }\n        }\n        suspendCancellableCoroutine<Unit> { co ->\n            synchronized(lock) {\n                    if (pendingFrameContinuation === ProduceAnotherFrame) {\n                        pendingFrameContinuation = FramePending\n                        co\n                    } else {\n                        pendingFrameContinuation = co\n                        null\n                    }\n                }\n                ?.resume(Unit)\n        }\n    }\n\n    /**\n     * Signal from the frame request consumer that the frame is beginning with data that was\n     * available up until this point. (Synchronizing access to that data is up to the caller.)\n     */\n    fun takeFrameRequestLocked() {\n        checkPrecondition(pendingFrameContinuation === FramePending) { \"frame not pending\" }\n        pendingFrameContinuation = null\n    }\n\n    fun requestFrameLocked(): Continuation<Unit>? =\n        when (val co = pendingFrameContinuation) {\n            is Continuation<*> -> {\n                pendingFrameContinuation = FramePending\n                @Suppress(\"UNCHECKED_CAST\")\n                co as Continuation<Unit>\n            }\n            ProduceAnotherFrame,\n            FramePending -> null\n            null -> {\n                pendingFrameContinuation = ProduceAnotherFrame\n                null\n            }\n            else -> error(\"invalid pendingFrameContinuation $co\")\n        }\n}\n\n@OptIn(InternalComposeApi::class)\nprivate class NestedContentMap {\n    private val contentMap = MultiValueMap<MovableContent<Any?>, NestedMovableContent>()\n    private val containerMap = MultiValueMap<MovableContentStateReference, MovableContent<Any?>>()\n\n    fun add(content: MovableContent<Any?>, nestedContent: NestedMovableContent) {\n        contentMap.add(content, nestedContent)\n        containerMap.add(nestedContent.container, content)\n    }\n\n    fun clear() {\n        contentMap.clear()\n        containerMap.clear()\n    }\n\n    fun removeLast(key: MovableContent<Any?>) =\n        contentMap.removeLast(key).also { if (contentMap.isEmpty()) containerMap.clear() }\n\n    operator fun contains(key: MovableContent<Any?>) = key in contentMap\n\n    fun usedContainer(reference: MovableContentStateReference) {\n        containerMap.forEachValue(reference) { value ->\n            contentMap.removeValueIf(value) { it.container == reference }\n        }\n    }\n}\n\n@InternalComposeApi\nprivate class NestedMovableContent(\n    val content: MovableContentStateReference,\n    val container: MovableContentStateReference,\n)\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/SnapshotState.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@file:JvmName(\"SnapshotStateKt\")\n@file:JvmMultifileClass\n\npackage androidx.compose.runtime\n\nimport androidx.compose.runtime.snapshots.GlobalSnapshot\nimport androidx.compose.runtime.snapshots.Snapshot\nimport androidx.compose.runtime.snapshots.SnapshotId\nimport androidx.compose.runtime.snapshots.SnapshotMutableState\nimport androidx.compose.runtime.snapshots.SnapshotStateList\nimport androidx.compose.runtime.snapshots.SnapshotStateMap\nimport androidx.compose.runtime.snapshots.SnapshotStateSet\nimport androidx.compose.runtime.snapshots.StateFactoryMarker\nimport androidx.compose.runtime.snapshots.StateObjectImpl\nimport androidx.compose.runtime.snapshots.StateRecord\nimport androidx.compose.runtime.snapshots.currentSnapshot\nimport androidx.compose.runtime.snapshots.overwritable\nimport androidx.compose.runtime.snapshots.readable\nimport androidx.compose.runtime.snapshots.toSnapshotId\nimport androidx.compose.runtime.snapshots.withCurrent\nimport kotlin.jvm.JvmMultifileClass\nimport kotlin.jvm.JvmName\nimport kotlin.reflect.KProperty\n\n/**\n * Return a new [MutableState] initialized with the passed in [value]\n *\n * The MutableState class is a single value holder whose reads and writes are observed by Compose.\n * Additionally, writes to it are transacted as part of the [Snapshot] system.\n *\n * @param value the initial value for the [MutableState]\n * @param policy a policy to controls how changes are handled in mutable snapshots.\n * @sample androidx.compose.runtime.samples.SimpleStateSample\n * @sample androidx.compose.runtime.samples.DestructuredStateSample\n * @sample androidx.compose.runtime.samples.observeUserSample\n * @sample androidx.compose.runtime.samples.stateSample\n * @see State\n * @see MutableState\n * @see SnapshotMutationPolicy\n * @see mutableIntStateOf\n * @see mutableLongStateOf\n * @see mutableFloatStateOf\n * @see mutableDoubleStateOf\n */\n@StateFactoryMarker\npublic fun <T> mutableStateOf(\n    value: T,\n    policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy(),\n): MutableState<T> = createSnapshotMutableState(value, policy)\n\n/**\n * A value holder where reads to the [value] property during the execution of a [Composable]\n * function, the current [RecomposeScope] will be subscribed to changes of that value.\n *\n * @see [MutableState]\n * @see [mutableStateOf]\n */\n@Stable\npublic interface State<out T> {\n    public val value: T\n}\n\n/**\n * Permits property delegation of `val`s using `by` for [State].\n *\n * @sample androidx.compose.runtime.samples.DelegatedReadOnlyStateSample\n */\n@Suppress(\"NOTHING_TO_INLINE\")\npublic inline operator fun <T> State<T>.getValue(thisObj: Any?, property: KProperty<*>): T = value\n\n/**\n * A mutable value holder where reads to the [value] property during the execution of a [Composable]\n * function, the current [RecomposeScope] will be subscribed to changes of that value. When the\n * [value] property is written to and changed, a recomposition of any subscribed [RecomposeScope]s\n * will be scheduled. If [value] is written to with the same value, no recompositions will be\n * scheduled.\n *\n * @see [State]\n * @see [mutableStateOf]\n */\n@Stable\npublic interface MutableState<T> : State<T> {\n    override var value: T\n\n    public operator fun component1(): T\n\n    public operator fun component2(): (T) -> Unit\n}\n\n/**\n * Permits property delegation of `var`s using `by` for [MutableState].\n *\n * @sample androidx.compose.runtime.samples.DelegatedStateSample\n */\n@Suppress(\"NOTHING_TO_INLINE\")\npublic inline operator fun <T> MutableState<T>.setValue(\n    thisObj: Any?,\n    property: KProperty<*>,\n    value: T,\n) {\n    this.value = value\n}\n\n/** Returns platform specific implementation based on [SnapshotMutableStateImpl]. */\ninternal expect fun <T> createSnapshotMutableState(\n    value: T,\n    policy: SnapshotMutationPolicy<T>,\n): SnapshotMutableState<T>\n\n/**\n * A single value holder whose reads and writes are observed by Compose.\n *\n * Additionally, writes to it are transacted as part of the [Snapshot] system.\n *\n * @param value the wrapped value\n * @param policy a policy to control how changes are handled in a mutable snapshot.\n * @see mutableStateOf\n * @see SnapshotMutationPolicy\n */\ninternal open class SnapshotMutableStateImpl<T>(\n    value: T,\n    override val policy: SnapshotMutationPolicy<T>,\n) : StateObjectImpl(), SnapshotMutableState<T> {\n    @Suppress(\"UNCHECKED_CAST\")\n    override var value: T\n        get() = next.readable(this).value\n        set(value) =\n            next.withCurrent {\n                if (!policy.equivalent(it.value, value)) {\n                    next.overwritable(this, it) { this.value = value }\n                }\n            }\n\n    private var next: StateStateRecord<T> =\n        currentSnapshot().let { snapshot ->\n            StateStateRecord(snapshot.snapshotId, value).also {\n                if (snapshot !is GlobalSnapshot) {\n                    it.next = StateStateRecord(Snapshot.PreexistingSnapshotId.toSnapshotId(), value)\n                }\n            }\n        }\n\n    override val firstStateRecord: StateRecord\n        get() = next\n\n    override fun prependStateRecord(value: StateRecord) {\n        @Suppress(\"UNCHECKED_CAST\")\n        next = value as StateStateRecord<T>\n    }\n\n    @Suppress(\"UNCHECKED_CAST\")\n    override fun mergeRecords(\n        previous: StateRecord,\n        current: StateRecord,\n        applied: StateRecord,\n    ): StateRecord? {\n        val previousRecord = previous as StateStateRecord<T>\n        val currentRecord = current as StateStateRecord<T>\n        val appliedRecord = applied as StateStateRecord<T>\n        return if (policy.equivalent(currentRecord.value, appliedRecord.value)) current\n        else {\n            val merged =\n                policy.merge(previousRecord.value, currentRecord.value, appliedRecord.value)\n            if (merged != null) {\n                appliedRecord.create(appliedRecord.snapshotId).also { it.value = merged }\n            } else {\n                null\n            }\n        }\n    }\n\n    override fun toString(): String =\n        next.withCurrent { \"MutableState(value=${it.value})@${hashCode()}\" }\n\n    private class StateStateRecord<T>(snapshotId: SnapshotId, myValue: T) :\n        StateRecord(snapshotId) {\n        override fun assign(value: StateRecord) {\n            @Suppress(\"UNCHECKED_CAST\")\n            this.value = (value as StateStateRecord<T>).value\n        }\n\n        override fun create() = StateStateRecord(currentSnapshot().snapshotId, value)\n\n        override fun create(snapshotId: SnapshotId) =\n            StateStateRecord(currentSnapshot().snapshotId, value)\n\n        var value: T = myValue\n    }\n\n    /**\n     * The componentN() operators allow state objects to be used with the property destructuring\n     * syntax\n     *\n     * ```\n     * var (foo, setFoo) = remember { mutableStateOf(0) }\n     * setFoo(123) // set\n     * foo == 123 // get\n     * ```\n     */\n    override operator fun component1(): T = value\n\n    override operator fun component2(): (T) -> Unit = { value = it }\n\n    /**\n     * A function used by the debugger to display the value of the current value of the mutable\n     * state object without triggering read observers.\n     */\n    @Suppress(\"unused\")\n    val debuggerDisplayValue: T\n        @JvmName(\"getDebuggerDisplayValue\") get() = next.withCurrent { it }.value\n}\n\n/**\n * Create a instance of [MutableList]<T> that is observable and can be snapshot.\n *\n * @sample androidx.compose.runtime.samples.stateListSample\n * @see mutableStateOf\n * @see mutableListOf\n * @see MutableList\n * @see Snapshot.takeSnapshot\n */\n@StateFactoryMarker\npublic fun <T> mutableStateListOf(): SnapshotStateList<T> = SnapshotStateList<T>()\n\n/**\n * Create an instance of [MutableList]<T> that is observable and can be snapshot.\n *\n * @see mutableStateOf\n * @see mutableListOf\n * @see MutableList\n * @see Snapshot.takeSnapshot\n */\n@StateFactoryMarker\npublic fun <T> mutableStateListOf(vararg elements: T): SnapshotStateList<T> =\n    SnapshotStateList<T>().also { it.addAll(elements.toList()) }\n\n/**\n * Create an instance of [MutableList]<T> from a collection that is observable and can be snapshot.\n */\npublic fun <T> Collection<T>.toMutableStateList(): SnapshotStateList<T> =\n    SnapshotStateList<T>().also { it.addAll(this) }\n\n/**\n * Create a instance of [MutableMap]<K, V> that is observable and can be snapshot.\n *\n * @sample androidx.compose.runtime.samples.stateMapSample\n * @see mutableStateOf\n * @see mutableMapOf\n * @see MutableMap\n * @see Snapshot.takeSnapshot\n */\n@StateFactoryMarker\npublic fun <K, V> mutableStateMapOf(): SnapshotStateMap<K, V> = SnapshotStateMap<K, V>()\n\n/**\n * Create a instance of [MutableMap]<K, V> that is observable and can be snapshot.\n *\n * @see mutableStateOf\n * @see mutableMapOf\n * @see MutableMap\n * @see Snapshot.takeSnapshot\n */\n@StateFactoryMarker\npublic fun <K, V> mutableStateMapOf(vararg pairs: Pair<K, V>): SnapshotStateMap<K, V> =\n    SnapshotStateMap<K, V>().apply { putAll(pairs.toMap()) }\n\n/**\n * Create an instance of [MutableMap]<K, V> from a collection of pairs that is observable and can be\n * snapshot.\n */\n@Suppress(\"unused\")\npublic fun <K, V> Iterable<Pair<K, V>>.toMutableStateMap(): SnapshotStateMap<K, V> =\n    SnapshotStateMap<K, V>().also { it.putAll(this.toMap()) }\n\n/**\n * Create a instance of [MutableSet]<T> that is observable and can be snapshot.\n *\n * The returned set iteration order is in the order the items were inserted into the set.\n *\n * @sample androidx.compose.runtime.samples.stateSetSample\n * @see mutableStateOf\n * @see mutableSetOf\n * @see MutableSet\n * @see Snapshot.takeSnapshot\n */\n@StateFactoryMarker public fun <T> mutableStateSetOf(): SnapshotStateSet<T> = SnapshotStateSet<T>()\n\n/**\n * Create an instance of [MutableSet]<T> that is observable and can be snapshot.\n *\n * The returned set iteration order is in the order the items were inserted into the set.\n *\n * @see mutableStateOf\n * @see mutableSetOf\n * @see MutableSet\n * @see Snapshot.takeSnapshot\n */\n@StateFactoryMarker\npublic fun <T> mutableStateSetOf(vararg elements: T): SnapshotStateSet<T> =\n    SnapshotStateSet<T>().also { it.addAll(elements.toSet()) }\n\n/**\n * [remember] a [mutableStateOf] [newValue] and update its value to [newValue] on each recomposition\n * of the [rememberUpdatedState] call.\n *\n * [rememberUpdatedState] should be used when parameters or values computed during composition are\n * referenced by a long-lived lambda or object expression. Recomposition will update the resulting\n * [State] without recreating the long-lived lambda or object, allowing that object to persist\n * without cancelling and resubscribing, or relaunching a long-lived operation that may be expensive\n * or prohibitive to recreate and restart. This may be common when working with [DisposableEffect]\n * or [LaunchedEffect], for example:\n *\n * @sample androidx.compose.runtime.samples.rememberUpdatedStateSampleWithDisposableEffect\n *\n * [LaunchedEffect]s often describe state machines that should not be reset and restarted if a\n * parameter or event callback changes, but they should have the current value available when\n * needed. For example:\n *\n * @sample androidx.compose.runtime.samples.rememberUpdatedStateSampleWithLaunchedEffect\n *\n * By using [rememberUpdatedState] a composable function can update these operations in progress.\n */\n@Composable\npublic fun <T> rememberUpdatedState(newValue: T): State<T> =\n    remember { mutableStateOf(newValue) }.apply { value = newValue }\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Effects.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.runtime\n\nimport androidx.compose.runtime.internal.PlatformOptimizedCancellationException\nimport androidx.compose.runtime.platform.makeSynchronizedObject\nimport androidx.compose.runtime.platform.synchronized\nimport androidx.compose.runtime.tooling.ComposeToolingApi\nimport androidx.compose.runtime.tooling.ComposeToolingFlags\nimport androidx.compose.runtime.tooling.CompositionErrorContextImpl\nimport kotlin.concurrent.Volatile\nimport kotlin.coroutines.CoroutineContext\nimport kotlin.coroutines.EmptyCoroutineContext\nimport kotlin.jvm.JvmField\nimport kotlinx.coroutines.CoroutineExceptionHandler\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.cancel\nimport kotlinx.coroutines.launch\n\n/**\n * Schedule [effect] to run when the current composition completes successfully and applies changes.\n * [SideEffect] can be used to apply side effects to objects managed by the composition that are not\n * backed by [snapshots][androidx.compose.runtime.snapshots.Snapshot] so as not to leave those\n * objects in an inconsistent state if the current composition operation fails.\n *\n * [effect] will always be run on the composition's apply dispatcher and appliers are never run\n * concurrent with themselves, one another, applying changes to the composition tree, or running\n * [RememberObserver] event callbacks. [SideEffect]s are always run after [RememberObserver] event\n * callbacks.\n *\n * A [SideEffect] runs after **every** recomposition. To launch an ongoing task spanning potentially\n * many recompositions, see [LaunchedEffect]. To manage an event subscription or other object\n * lifecycle, see [DisposableEffect].\n */\n@Composable\n@NonRestartableComposable\n@ExplicitGroupsComposable\n@OptIn(InternalComposeApi::class)\npublic fun SideEffect(effect: () -> Unit) {\n    currentComposer.recordSideEffect(effect)\n}\n\n/**\n * Receiver scope for [DisposableEffect] that offers the [onDispose] clause that should be the last\n * statement in any call to [DisposableEffect].\n */\npublic class DisposableEffectScope {\n    /**\n     * Provide [onDisposeEffect] to the [DisposableEffect] to run when it leaves the composition or\n     * its key changes.\n     */\n    public inline fun onDispose(crossinline onDisposeEffect: () -> Unit): DisposableEffectResult =\n        object : DisposableEffectResult {\n            override fun dispose() {\n                onDisposeEffect()\n            }\n        }\n}\n\npublic interface DisposableEffectResult {\n    public fun dispose()\n}\n\nprivate val InternalDisposableEffectScope = DisposableEffectScope()\n\nprivate class DisposableEffectImpl(\n    private val effect: DisposableEffectScope.() -> DisposableEffectResult\n) : RememberObserver {\n    private var onDispose: DisposableEffectResult? = null\n\n    override fun onRemembered() {\n        onDispose = InternalDisposableEffectScope.effect()\n    }\n\n    override fun onForgotten() {\n        onDispose?.dispose()\n        onDispose = null\n    }\n\n    override fun onAbandoned() {\n        // Nothing to do as [onRemembered] was not called.\n    }\n}\n\nprivate const val DisposableEffectNoParamError =\n    \"DisposableEffect must provide one or more 'key' parameters that define the identity of \" +\n        \"the DisposableEffect and determine when its previous effect should be disposed and \" +\n        \"a new effect started for the new key.\"\n\nprivate const val LaunchedEffectNoParamError =\n    \"LaunchedEffect must provide one or more 'key' parameters that define the identity of \" +\n        \"the LaunchedEffect and determine when its previous effect coroutine should be cancelled \" +\n        \"and a new effect launched for the new key.\"\n\n/**\n * A side effect of composition that must be reversed or cleaned up if the [DisposableEffect] leaves\n * the composition.\n *\n * It is an error to call [DisposableEffect] without at least one `key` parameter.\n */\n// This deprecated-error function shadows the varargs overload so that the varargs version\n// is not used without key parameters.\n@Composable\n@NonRestartableComposable\n@Suppress(\"DeprecatedCallableAddReplaceWith\", \"UNUSED_PARAMETER\")\n@Deprecated(DisposableEffectNoParamError, level = DeprecationLevel.ERROR)\npublic fun DisposableEffect(effect: DisposableEffectScope.() -> DisposableEffectResult): Unit =\n    error(DisposableEffectNoParamError)\n\n/**\n * A side effect of composition that must run for any new unique value of [key1] and must be\n * reversed or cleaned up if [key1] changes or if the [DisposableEffect] leaves the composition.\n *\n * A [DisposableEffect]'s _key_ is a value that defines the identity of the [DisposableEffect]. If a\n * key changes, the [DisposableEffect] must [dispose][DisposableEffectScope.onDispose] its current\n * [effect] and reset by calling [effect] again. Examples of keys include:\n * * Observable objects that the effect subscribes to\n * * Unique request parameters to an operation that must cancel and retry if those parameters change\n *\n * [DisposableEffect] may be used to initialize or subscribe to a key and reinitialize when a\n * different key is provided, performing cleanup for the old operation before initializing the new.\n * For example:\n *\n * @sample androidx.compose.runtime.samples.disposableEffectSample\n *\n * A [DisposableEffect] **must** include an [onDispose][DisposableEffectScope.onDispose] clause as\n * the final statement in its [effect] block. If your operation does not require disposal it might\n * be a [SideEffect] instead, or a [LaunchedEffect] if it launches a coroutine that should be\n * managed by the composition.\n *\n * There is guaranteed to be one call to [dispose][DisposableEffectScope.onDispose] for every call\n * to [effect]. Both [effect] and [dispose][DisposableEffectScope.onDispose] will always be run on\n * the composition's apply dispatcher and appliers are never run concurrent with themselves, one\n * another, applying changes to the composition tree, or running [RememberObserver] event callbacks.\n */\n@Composable\n@NonRestartableComposable\npublic fun DisposableEffect(\n    key1: Any?,\n    effect: DisposableEffectScope.() -> DisposableEffectResult,\n) {\n    remember(key1) { DisposableEffectImpl(effect) }\n}\n\n/**\n * A side effect of composition that must run for any new unique value of [key1] or [key2] and must\n * be reversed or cleaned up if [key1] or [key2] changes, or if the [DisposableEffect] leaves the\n * composition.\n *\n * A [DisposableEffect]'s _key_ is a value that defines the identity of the [DisposableEffect]. If a\n * key changes, the [DisposableEffect] must [dispose][DisposableEffectScope.onDispose] its current\n * [effect] and reset by calling [effect] again. Examples of keys include:\n * * Observable objects that the effect subscribes to\n * * Unique request parameters to an operation that must cancel and retry if those parameters change\n *\n * [DisposableEffect] may be used to initialize or subscribe to a key and reinitialize when a\n * different key is provided, performing cleanup for the old operation before initializing the new.\n * For example:\n *\n * @sample androidx.compose.runtime.samples.disposableEffectSample\n *\n * A [DisposableEffect] **must** include an [onDispose][DisposableEffectScope.onDispose] clause as\n * the final statement in its [effect] block. If your operation does not require disposal it might\n * be a [SideEffect] instead, or a [LaunchedEffect] if it launches a coroutine that should be\n * managed by the composition.\n *\n * There is guaranteed to be one call to [dispose][DisposableEffectScope.onDispose] for every call\n * to [effect]. Both [effect] and [dispose][DisposableEffectScope.onDispose] will always be run on\n * the composition's apply dispatcher and appliers are never run concurrent with themselves, one\n * another, applying changes to the composition tree, or running [RememberObserver] event callbacks.\n */\n@Composable\n@NonRestartableComposable\npublic fun DisposableEffect(\n    key1: Any?,\n    key2: Any?,\n    effect: DisposableEffectScope.() -> DisposableEffectResult,\n) {\n    remember(key1, key2) { DisposableEffectImpl(effect) }\n}\n\n/**\n * A side effect of composition that must run for any new unique value of [key1], [key2] or [key3]\n * and must be reversed or cleaned up if [key1], [key2] or [key3] changes, or if the\n * [DisposableEffect] leaves the composition.\n *\n * A [DisposableEffect]'s _key_ is a value that defines the identity of the [DisposableEffect]. If a\n * key changes, the [DisposableEffect] must [dispose][DisposableEffectScope.onDispose] its current\n * [effect] and reset by calling [effect] again. Examples of keys include:\n * * Observable objects that the effect subscribes to\n * * Unique request parameters to an operation that must cancel and retry if those parameters change\n *\n * [DisposableEffect] may be used to initialize or subscribe to a key and reinitialize when a\n * different key is provided, performing cleanup for the old operation before initializing the new.\n * For example:\n *\n * @sample androidx.compose.runtime.samples.disposableEffectSample\n *\n * A [DisposableEffect] **must** include an [onDispose][DisposableEffectScope.onDispose] clause as\n * the final statement in its [effect] block. If your operation does not require disposal it might\n * be a [SideEffect] instead, or a [LaunchedEffect] if it launches a coroutine that should be\n * managed by the composition.\n *\n * There is guaranteed to be one call to [dispose][DisposableEffectScope.onDispose] for every call\n * to [effect]. Both [effect] and [dispose][DisposableEffectScope.onDispose] will always be run on\n * the composition's apply dispatcher and appliers are never run concurrent with themselves, one\n * another, applying changes to the composition tree, or running [RememberObserver] event callbacks.\n */\n@Composable\n@NonRestartableComposable\npublic fun DisposableEffect(\n    key1: Any?,\n    key2: Any?,\n    key3: Any?,\n    effect: DisposableEffectScope.() -> DisposableEffectResult,\n) {\n    remember(key1, key2, key3) { DisposableEffectImpl(effect) }\n}\n\n/**\n * A side effect of composition that must run for any new unique value of [keys] and must be\n * reversed or cleaned up if any [keys] change or if the [DisposableEffect] leaves the composition.\n *\n * A [DisposableEffect]'s _key_ is a value that defines the identity of the [DisposableEffect]. If a\n * key changes, the [DisposableEffect] must [dispose][DisposableEffectScope.onDispose] its current\n * [effect] and reset by calling [effect] again. Examples of keys include:\n * * Observable objects that the effect subscribes to\n * * Unique request parameters to an operation that must cancel and retry if those parameters change\n *\n * [DisposableEffect] may be used to initialize or subscribe to a key and reinitialize when a\n * different key is provided, performing cleanup for the old operation before initializing the new.\n * For example:\n *\n * @sample androidx.compose.runtime.samples.disposableEffectSample\n *\n * A [DisposableEffect] **must** include an [onDispose][DisposableEffectScope.onDispose] clause as\n * the final statement in its [effect] block. If your operation does not require disposal it might\n * be a [SideEffect] instead, or a [LaunchedEffect] if it launches a coroutine that should be\n * managed by the composition.\n *\n * There is guaranteed to be one call to [dispose][DisposableEffectScope.onDispose] for every call\n * to [effect]. Both [effect] and [dispose][DisposableEffectScope.onDispose] will always be run on\n * the composition's apply dispatcher and appliers are never run concurrent with themselves, one\n * another, applying changes to the composition tree, or running [RememberObserver] event callbacks.\n */\n@Composable\n@NonRestartableComposable\n@Suppress(\"ArrayReturn\")\npublic fun DisposableEffect(\n    vararg keys: Any?,\n    effect: DisposableEffectScope.() -> DisposableEffectResult,\n) {\n    remember(*keys) { DisposableEffectImpl(effect) }\n}\n\ninternal class LaunchedEffectImpl(\n    private val parentCoroutineContext: CoroutineContext,\n    private val task: suspend CoroutineScope.() -> Unit,\n) : RememberObserver, CoroutineExceptionHandler {\n    private val scope: CoroutineScope\n    private var job: Job? = null\n\n    init {\n        var context = parentCoroutineContext + this\n        @OptIn(ComposeToolingApi::class)\n        if (ComposeToolingFlags.isVerboseTracingEnabled) {\n            context += LaunchedEffectTracingContext\n        }\n        scope = CoroutineScope(context)\n    }\n\n    override fun onRemembered() {\n        // This should never happen but is left here for safety\n        job?.cancel(\"Old job was still running!\")\n        job = scope.launch(block = task)\n    }\n\n    override fun onForgotten() {\n        job?.cancel(LeftCompositionCancellationException())\n        job = null\n    }\n\n    override fun onAbandoned() {\n        job?.cancel(LeftCompositionCancellationException())\n        job = null\n    }\n\n    // CoroutineExceptionHandler implementation to save on allocations\n    override val key: CoroutineContext.Key<*>\n        get() = CoroutineExceptionHandler.Key\n\n    override fun handleException(context: CoroutineContext, exception: Throwable) {\n        context[CompositionErrorContextImpl]?.apply {\n            exception.attachComposeStackTrace(this@LaunchedEffectImpl)\n        }\n        parentCoroutineContext[CoroutineExceptionHandler]?.handleException(context, exception)\n            ?: throw exception\n    }\n}\n\n/**\n * When [LaunchedEffect] enters the composition it will launch [block] into the composition's\n * [CoroutineContext]. The coroutine will be [cancelled][Job.cancel] when the [LaunchedEffect]\n * leaves the composition.\n *\n * It is an error to call [LaunchedEffect] without at least one `key` parameter.\n */\n// This deprecated-error function shadows the varargs overload so that the varargs version\n// is not used without key parameters.\n@Deprecated(LaunchedEffectNoParamError, level = DeprecationLevel.ERROR)\n@Suppress(\"DeprecatedCallableAddReplaceWith\", \"UNUSED_PARAMETER\")\n@Composable\npublic fun LaunchedEffect(block: suspend CoroutineScope.() -> Unit): Unit =\n    error(LaunchedEffectNoParamError)\n\n/**\n * When [LaunchedEffect] enters the composition it will launch [block] into the composition's\n * [CoroutineContext]. The coroutine will be [cancelled][Job.cancel] and **re-launched** when\n * [LaunchedEffect] is recomposed with a different [key1]. The coroutine will be\n * [cancelled][Job.cancel] when the [LaunchedEffect] leaves the composition.\n *\n * This function should **not** be used to (re-)launch ongoing tasks in response to callback events\n * by way of storing callback data in [MutableState] passed to [key1]. Instead, see\n * [rememberCoroutineScope] to obtain a [CoroutineScope] that may be used to launch ongoing jobs\n * scoped to the composition in response to event callbacks.\n */\n@Composable\n@NonRestartableComposable\n@OptIn(InternalComposeApi::class)\npublic fun LaunchedEffect(key1: Any?, block: suspend CoroutineScope.() -> Unit) {\n    val applyContext = currentComposer.applyCoroutineContext\n    remember(key1) { LaunchedEffectImpl(applyContext, block) }\n}\n\n/**\n * When [LaunchedEffect] enters the composition it will launch [block] into the composition's\n * [CoroutineContext]. The coroutine will be [cancelled][Job.cancel] and **re-launched** when\n * [LaunchedEffect] is recomposed with a different [key1] or [key2]. The coroutine will be\n * [cancelled][Job.cancel] when the [LaunchedEffect] leaves the composition.\n *\n * This function should **not** be used to (re-)launch ongoing tasks in response to callback events\n * by way of storing callback data in [MutableState] passed to [key]. Instead, see\n * [rememberCoroutineScope] to obtain a [CoroutineScope] that may be used to launch ongoing jobs\n * scoped to the composition in response to event callbacks.\n */\n@Composable\n@NonRestartableComposable\n@OptIn(InternalComposeApi::class)\npublic fun LaunchedEffect(key1: Any?, key2: Any?, block: suspend CoroutineScope.() -> Unit) {\n    val applyContext = currentComposer.applyCoroutineContext\n    remember(key1, key2) { LaunchedEffectImpl(applyContext, block) }\n}\n\n/**\n * When [LaunchedEffect] enters the composition it will launch [block] into the composition's\n * [CoroutineContext]. The coroutine will be [cancelled][Job.cancel] and **re-launched** when\n * [LaunchedEffect] is recomposed with a different [key1], [key2] or [key3]. The coroutine will be\n * [cancelled][Job.cancel] when the [LaunchedEffect] leaves the composition.\n *\n * This function should **not** be used to (re-)launch ongoing tasks in response to callback events\n * by way of storing callback data in [MutableState] passed to [key]. Instead, see\n * [rememberCoroutineScope] to obtain a [CoroutineScope] that may be used to launch ongoing jobs\n * scoped to the composition in response to event callbacks.\n */\n@Composable\n@NonRestartableComposable\n@OptIn(InternalComposeApi::class)\npublic fun LaunchedEffect(\n    key1: Any?,\n    key2: Any?,\n    key3: Any?,\n    block: suspend CoroutineScope.() -> Unit,\n) {\n    val applyContext = currentComposer.applyCoroutineContext\n    remember(key1, key2, key3) { LaunchedEffectImpl(applyContext, block) }\n}\n\nprivate class LeftCompositionCancellationException :\n    PlatformOptimizedCancellationException(\"The coroutine scope left the composition\")\n\n/**\n * When [LaunchedEffect] enters the composition it will launch [block] into the composition's\n * [CoroutineContext]. The coroutine will be [cancelled][Job.cancel] and **re-launched** when\n * [LaunchedEffect] is recomposed with any different [keys]. The coroutine will be\n * [cancelled][Job.cancel] when the [LaunchedEffect] leaves the composition.\n *\n * This function should **not** be used to (re-)launch ongoing tasks in response to callback events\n * by way of storing callback data in [MutableState] passed to [key]. Instead, see\n * [rememberCoroutineScope] to obtain a [CoroutineScope] that may be used to launch ongoing jobs\n * scoped to the composition in response to event callbacks.\n */\n@Composable\n@NonRestartableComposable\n@Suppress(\"ArrayReturn\")\n@OptIn(InternalComposeApi::class)\npublic fun LaunchedEffect(vararg keys: Any?, block: suspend CoroutineScope.() -> Unit) {\n    val applyContext = currentComposer.applyCoroutineContext\n    remember(*keys) { LaunchedEffectImpl(applyContext, block) }\n}\n\n// Maintenance note: this class once was used by the inlined implementation of\n// rememberCoroutineScope and must be maintained for binary compatibility. The new implementation\n// of RememberedCoroutineScope implements RememberObserver directly, since as of this writing the\n// compose runtime no longer implicitly treats objects incidentally stored in the slot table (e.g.\n// previous parameter values from a skippable invocation, remember keys, etc.) as eligible\n// RememberObservers. This dramatically reduces the risk of receiving unexpected RememberObserver\n// lifecycle callbacks when a reference to a RememberObserver is leaked into user code and we can\n// omit wrapper RememberObservers such as this one.\n@PublishedApi\ninternal class CompositionScopedCoroutineScopeCanceller(val coroutineScope: CoroutineScope) :\n    RememberObserver {\n    override fun onRemembered() {\n        // Nothing to do\n    }\n\n    override fun onForgotten() {\n        val coroutineScope = coroutineScope\n        if (coroutineScope is RememberedCoroutineScope) {\n            coroutineScope.cancelIfCreated()\n        } else {\n            coroutineScope.cancel(LeftCompositionCancellationException())\n        }\n    }\n\n    override fun onAbandoned() {\n        val coroutineScope = coroutineScope\n        if (coroutineScope is RememberedCoroutineScope) {\n            coroutineScope.cancelIfCreated()\n        } else {\n            coroutineScope.cancel(LeftCompositionCancellationException())\n        }\n    }\n}\n\nprivate class CancelledCoroutineContext : CoroutineContext.Element {\n    override val key: CoroutineContext.Key<*>\n        get() = Key\n\n    companion object Key : CoroutineContext.Key<CancelledCoroutineContext>\n}\n\nprivate class ForgottenCoroutineScopeException :\n    PlatformOptimizedCancellationException(\"rememberCoroutineScope left the composition\")\n\ninternal class RememberedCoroutineScope(\n    private val parentContext: CoroutineContext,\n    private val overlayContext: CoroutineContext,\n) : CoroutineScope, RememberObserver {\n    private val lock = makeSynchronizedObject(this)\n\n    // The goal of this implementation is to make cancellation as cheap as possible if the\n    // coroutineContext property was never accessed, consisting only of taking a monitor lock and\n    // setting a volatile field.\n\n    @Volatile private var _coroutineContext: CoroutineContext? = null\n\n    override val coroutineContext: CoroutineContext\n        get() {\n            var localCoroutineContext = _coroutineContext\n            if (\n                localCoroutineContext == null || localCoroutineContext === CancelledCoroutineContext\n            ) {\n                val traceContext = parentContext[CompositionErrorContextImpl]\n                val exceptionHandler =\n                    if (traceContext != null) {\n                        // If trace context is present, override exception handler, so all child\n                        // jobs would have the composable trace appended.\n                        // On exception, call overlay -> parent and throw if neither are present.\n                        CoroutineExceptionHandler { c, e ->\n                            traceContext.apply {\n                                e.attachComposeStackTrace(this@RememberedCoroutineScope)\n                            }\n                            overlayContext[CoroutineExceptionHandler]?.handleException(c, e)\n                                ?: parentContext[CoroutineExceptionHandler]?.handleException(c, e)\n                                ?: throw e\n                        }\n                    } else {\n                        EmptyCoroutineContext\n                    }\n\n                // Yes, we're leaking our lock here by using the instance of the object\n                // that also gets handled by user code as a CoroutineScope as an intentional\n                // tradeoff for avoiding the allocation of a dedicated lock object.\n                // Since we only use it here for this lazy initialization and control flow\n                // does not escape the creation of the CoroutineContext while holding the lock,\n                // the splash damage should be acceptable.\n                synchronized(lock) {\n                    localCoroutineContext = _coroutineContext\n                    if (localCoroutineContext == null) {\n                        val parentContext = parentContext\n                        val childJob = Job(parentContext[Job])\n                        localCoroutineContext =\n                            parentContext + childJob + overlayContext + exceptionHandler\n                    } else if (localCoroutineContext === CancelledCoroutineContext) {\n                        // Lazily initialize the child job here, already cancelled.\n                        // Assemble the CoroutineContext exactly as otherwise expected.\n                        val parentContext = parentContext\n                        val cancelledChildJob =\n                            Job(parentContext[Job]).apply {\n                                cancel(ForgottenCoroutineScopeException())\n                            }\n                        localCoroutineContext =\n                            parentContext + cancelledChildJob + overlayContext + exceptionHandler\n\n                        @OptIn(ComposeToolingApi::class)\n                        if (ComposeToolingFlags.isVerboseTracingEnabled) {\n                            localCoroutineContext += RememberedCoroutineScopeTracingContext\n                        }\n                    }\n                    _coroutineContext = localCoroutineContext\n                }\n            }\n            return localCoroutineContext!!\n        }\n\n    fun cancelIfCreated() {\n        // Take the lock unconditionally; this is internal API only used by internal\n        // RememberObserver implementations that are not leaked to user code; we can assume\n        // this won't be called repeatedly. If this assumption is violated we'll simply create a\n        // redundant exception.\n        synchronized(lock) {\n            val context = _coroutineContext\n            if (context == null) {\n                _coroutineContext = CancelledCoroutineContext\n            } else {\n                // Ignore optimizing the case where we might be cancelling an already cancelled job;\n                // only internal callers such as RememberObservers will invoke this method.\n                context.cancel(ForgottenCoroutineScopeException())\n            }\n        }\n    }\n\n    override fun onRemembered() {\n        // Do nothing\n    }\n\n    override fun onForgotten() {\n        cancelIfCreated()\n    }\n\n    override fun onAbandoned() {\n        cancelIfCreated()\n    }\n\n    companion object {\n        @JvmField val CancelledCoroutineContext: CoroutineContext = CancelledCoroutineContext()\n    }\n}\n\n@PublishedApi\n@OptIn(InternalComposeApi::class)\ninternal fun createCompositionCoroutineScope(\n    coroutineContext: CoroutineContext,\n    composer: Composer,\n): CoroutineScope =\n    if (coroutineContext[Job] != null) {\n        CoroutineScope(\n            Job().apply {\n                completeExceptionally(\n                    IllegalArgumentException(\n                        \"CoroutineContext supplied to \" +\n                            \"rememberCoroutineScope may not include a parent job\"\n                    )\n                )\n            }\n        )\n    } else {\n        val applyContext = composer.applyCoroutineContext\n        RememberedCoroutineScope(applyContext, coroutineContext)\n    }\n\n/**\n * Return a [CoroutineScope] bound to this point in the composition using the optional\n * [CoroutineContext] provided by [getContext]. [getContext] will only be called once and the same\n * [CoroutineScope] instance will be returned across recompositions.\n *\n * This scope will be [cancelled][CoroutineScope.cancel] when this call leaves the composition. The\n * [CoroutineContext] returned by [getContext] may not contain a [Job] as this scope is considered\n * to be a child of the composition.\n *\n * The default dispatcher of this scope if one is not provided by the context returned by\n * [getContext] will be the applying dispatcher of the composition's [Recomposer].\n *\n * Use this scope to launch jobs in response to callback events such as clicks or other user\n * interaction where the response to that event needs to unfold over time and be cancelled if the\n * composable managing that process leaves the composition. Jobs should never be launched into\n * **any** coroutine scope as a side effect of composition itself. For scoped ongoing jobs initiated\n * by composition, see [LaunchedEffect].\n *\n * This function will not throw if preconditions are not met, as composable functions do not yet\n * fully support exceptions. Instead the returned scope's [CoroutineScope.coroutineContext] will\n * contain a failed [Job] with the associated exception and will not be capable of launching child\n * jobs.\n */\n@Composable\npublic inline fun rememberCoroutineScope(\n    crossinline getContext: @DisallowComposableCalls () -> CoroutineContext = {\n        EmptyCoroutineContext\n    }\n): CoroutineScope {\n    val composer = currentComposer\n    return remember { createCompositionCoroutineScope(getContext(), composer) }\n}\n\nprivate object LaunchedEffectTracingContext : TracingContext(\"Compose:LaunchedEffect\")\n\nprivate object RememberedCoroutineScopeTracingContext : TracingContext(\"Compose:coroutineScope\")\n\ninternal expect abstract class TracingContext(name: String) : CoroutineContext.Element {\n    override val key: CoroutineContext.Key<*>\n\n    companion object Key : CoroutineContext.Key<TracingContext>\n}\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/DerivedState.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@file:JvmName(\"SnapshotStateKt\")\n@file:JvmMultifileClass\n\npackage androidx.compose.runtime\n\nimport androidx.collection.MutableObjectIntMap\nimport androidx.collection.ObjectIntMap\nimport androidx.collection.emptyObjectIntMap\nimport androidx.compose.runtime.collection.MutableVector\nimport androidx.compose.runtime.internal.IntRef\nimport androidx.compose.runtime.internal.SnapshotThreadLocal\nimport androidx.compose.runtime.internal.identityHashCode\nimport androidx.compose.runtime.snapshots.Snapshot\nimport androidx.compose.runtime.snapshots.SnapshotId\nimport androidx.compose.runtime.snapshots.SnapshotIdZero\nimport androidx.compose.runtime.snapshots.StateFactoryMarker\nimport androidx.compose.runtime.snapshots.StateObject\nimport androidx.compose.runtime.snapshots.StateObjectImpl\nimport androidx.compose.runtime.snapshots.StateRecord\nimport androidx.compose.runtime.snapshots.current\nimport androidx.compose.runtime.snapshots.currentSnapshot\nimport androidx.compose.runtime.snapshots.newWritableRecord\nimport androidx.compose.runtime.snapshots.sync\nimport androidx.compose.runtime.snapshots.withCurrent\nimport kotlin.jvm.JvmMultifileClass\nimport kotlin.jvm.JvmName\nimport kotlin.math.min\n\n/**\n * A [State] that is derived from one or more other states.\n *\n * @see derivedStateOf\n */\ninternal interface DerivedState<T> : State<T> {\n    /** Provides a current [Record]. */\n    val currentRecord: Record<T>\n\n    /**\n     * Mutation policy that controls how changes are handled after state dependencies update. If the\n     * policy is `null`, the derived state update is triggered regardless of the value produced and\n     * it is up to observer to invalidate it correctly.\n     */\n    val policy: SnapshotMutationPolicy<T>?\n\n    interface Record<T> {\n        /**\n         * The value of the derived state retrieved without triggering a notification to read\n         * observers.\n         */\n        val currentValue: T\n\n        /**\n         * Map of the dependencies used to produce [value] or [currentValue] to nested read level.\n         *\n         * This map can be used to determine if the state could affect value of this derived state,\n         * when a [StateObject] appears in the apply observer set.\n         */\n        val dependencies: ObjectIntMap<StateObject>\n    }\n}\n\nprivate val calculationBlockNestedLevel = SnapshotThreadLocal<IntRef>()\n\nprivate inline fun <T> withCalculationNestedLevel(block: (IntRef) -> T): T {\n    val ref =\n        calculationBlockNestedLevel.get() ?: IntRef(0).also { calculationBlockNestedLevel.set(it) }\n    return block(ref)\n}\n\nprivate class DerivedSnapshotState<T>(\n    private val calculation: () -> T,\n    override val policy: SnapshotMutationPolicy<T>?,\n) : StateObjectImpl(), DerivedState<T> {\n    private var first: ResultRecord<T> = ResultRecord(currentSnapshot().snapshotId)\n\n    class ResultRecord<T>(snapshotId: SnapshotId) :\n        StateRecord(snapshotId), DerivedState.Record<T> {\n        companion object {\n            val Unset = Any()\n        }\n\n        var validSnapshotId: SnapshotId = SnapshotIdZero\n        var validSnapshotWriteCount: Int = 0\n\n        override var dependencies: ObjectIntMap<StateObject> = emptyObjectIntMap()\n        var result: Any? = Unset\n        var resultHash: Int = 0\n\n        override fun assign(value: StateRecord) {\n            @Suppress(\"UNCHECKED_CAST\") val other = value as ResultRecord<T>\n            dependencies = other.dependencies\n            result = other.result\n            resultHash = other.resultHash\n        }\n\n        override fun create(): StateRecord = create(currentSnapshot().snapshotId)\n\n        override fun create(snapshotId: SnapshotId): StateRecord = ResultRecord<T>(snapshotId)\n\n        fun isValid(derivedState: DerivedState<*>, snapshot: Snapshot): Boolean {\n            val snapshotChanged = sync {\n                validSnapshotId != snapshot.snapshotId ||\n                    validSnapshotWriteCount != snapshot.writeCount\n            }\n            val isValid =\n                result !== Unset &&\n                    (!snapshotChanged || resultHash == readableHash(derivedState, snapshot))\n\n            if (isValid && snapshotChanged) {\n                sync {\n                    validSnapshotId = snapshot.snapshotId\n                    validSnapshotWriteCount = snapshot.writeCount\n                }\n            }\n\n            return isValid\n        }\n\n        fun readableHash(derivedState: DerivedState<*>, snapshot: Snapshot): Int {\n            var hash = 7\n            val dependencies = sync { dependencies }\n            if (dependencies.isNotEmpty()) {\n                notifyObservers(derivedState) {\n                    dependencies.forEach { stateObject, readLevel ->\n                        if (readLevel != 1) {\n                            return@forEach\n                        }\n\n                        // Find the first record without triggering an observer read.\n                        val record =\n                            if (stateObject is DerivedSnapshotState<*>) {\n                                // eagerly access the parent derived states without recording the\n                                // read\n                                // that way we can be sure derived states in deps were recalculated,\n                                // and are updated to the last values\n                                stateObject.current(snapshot)\n                            } else {\n                                current(stateObject.firstStateRecord, snapshot)\n                            }\n\n                        hash = 31 * hash + identityHashCode(record)\n                        hash = 31 * hash + record.snapshotId.hashCode()\n                    }\n                }\n            }\n            return hash\n        }\n\n        override val currentValue: T\n            @Suppress(\"UNCHECKED_CAST\") get() = result as T\n    }\n\n    /**\n     * Get current record in snapshot. Forces recalculation if record is invalid to refresh state\n     * value.\n     *\n     * @return latest state record for the derived state.\n     */\n    fun current(snapshot: Snapshot): StateRecord =\n        currentRecord(current(first, snapshot), snapshot, false, calculation)\n\n    private fun currentRecord(\n        readable: ResultRecord<T>,\n        snapshot: Snapshot,\n        forceDependencyReads: Boolean,\n        calculation: () -> T,\n    ): ResultRecord<T> {\n        if (readable.isValid(this, snapshot)) {\n            // If the dependency is not recalculated, emulate nested state reads\n            // for correct invalidation later\n            if (forceDependencyReads) {\n                notifyObservers(this) {\n                    val dependencies = readable.dependencies\n                    withCalculationNestedLevel { calculationLevelRef ->\n                        val invalidationNestedLevel = calculationLevelRef.element\n                        dependencies.forEach { dependency, nestedLevel ->\n                            calculationLevelRef.element = invalidationNestedLevel + nestedLevel\n                            snapshot.readObserver?.invoke(dependency)\n                        }\n                        calculationLevelRef.element = invalidationNestedLevel\n                    }\n                }\n            }\n            return readable\n        }\n\n        val newDependencies = MutableObjectIntMap<StateObject>()\n        val result = withCalculationNestedLevel { calculationLevelRef ->\n            val nestedCalculationLevel = calculationLevelRef.element\n            notifyObservers(this) {\n                calculationLevelRef.element = nestedCalculationLevel + 1\n\n                val result =\n                    Snapshot.observe(\n                        {\n                            if (it === this) error(\"A derived state calculation cannot read itself\")\n                            if (it is StateObject) {\n                                val readNestedLevel = calculationLevelRef.element\n                                newDependencies[it] =\n                                    min(\n                                        readNestedLevel - nestedCalculationLevel,\n                                        newDependencies.getOrDefault(it, Int.MAX_VALUE),\n                                    )\n                            }\n                        },\n                        null,\n                        calculation,\n                    )\n\n                calculationLevelRef.element = nestedCalculationLevel\n                result\n            }\n        }\n\n        val record = sync {\n            val currentSnapshot = Snapshot.current\n\n            if (\n                readable.result !== ResultRecord.Unset &&\n                    @Suppress(\"UNCHECKED_CAST\") policy?.equivalent(result, readable.result as T) ==\n                        true\n            ) {\n                readable.dependencies = newDependencies\n                readable.resultHash = readable.readableHash(this, currentSnapshot)\n                readable\n            } else {\n                val writable = first.newWritableRecord(this, currentSnapshot)\n                writable.dependencies = newDependencies\n                writable.resultHash = writable.readableHash(this, currentSnapshot)\n                writable.result = result\n                writable\n            }\n        }\n\n        if (calculationBlockNestedLevel.get()?.element == 0) {\n            Snapshot.notifyObjectsInitialized()\n\n            sync {\n                val currentSnapshot = Snapshot.current\n                record.validSnapshotId = currentSnapshot.snapshotId\n                record.validSnapshotWriteCount = currentSnapshot.writeCount\n            }\n        }\n\n        return record\n    }\n\n    override val firstStateRecord: StateRecord\n        get() = first\n\n    override fun prependStateRecord(value: StateRecord) {\n        @Suppress(\"UNCHECKED_CAST\")\n        first = value as ResultRecord<T>\n    }\n\n    override val value: T\n        get() {\n            // Unlike most state objects, the record list of a derived state can change during a\n            // read\n            // because reading updates the cache. To account for this, instead of calling readable,\n            // which sends the read notification, the read observer is notified directly and current\n            // value is used instead which doesn't notify. This allow the read observer to read the\n            // value and only update the cache once.\n            Snapshot.current.readObserver?.invoke(this)\n            // Read observer could advance the snapshot, so get current snapshot again\n            val snapshot = Snapshot.current\n            val record = current(first, snapshot)\n            @Suppress(\"UNCHECKED_CAST\")\n            return currentRecord(record, snapshot, true, calculation).result as T\n        }\n\n    override val currentRecord: DerivedState.Record<T>\n        get() {\n            val snapshot = Snapshot.current\n            val record = current(first, snapshot)\n            return currentRecord(record, snapshot, false, calculation)\n        }\n\n    override fun toString(): String =\n        first.withCurrent { \"DerivedState(value=${displayValue()})@${hashCode()}\" }\n\n    /**\n     * A function used by the debugger to display the value of the current value of the mutable\n     * state object without triggering read observers.\n     */\n    @Suppress(\"unused\")\n    val debuggerDisplayValue: T?\n        @JvmName(\"getDebuggerDisplayValue\")\n        get() =\n            first.withCurrent {\n                @Suppress(\"UNCHECKED_CAST\")\n                if (it.isValid(this, Snapshot.current)) it.result as T else null\n            }\n\n    private fun displayValue(): String {\n        first.withCurrent {\n            if (it.isValid(this, Snapshot.current)) {\n                return it.result.toString()\n            }\n            return \"<Not calculated>\"\n        }\n    }\n}\n\n/**\n * Creates a [State] object whose [State.value] is the result of [calculation]. The result of\n * calculation will be cached in such a way that calling [State.value] repeatedly will not cause\n * [calculation] to be executed multiple times, but reading [State.value] will cause all [State]\n * objects that got read during the [calculation] to be read in the current [Snapshot], meaning that\n * this will correctly subscribe to the derived state objects if the value is being read in an\n * observed context such as a [Composable] function. Derived states without mutation policy trigger\n * updates on each dependency change. To avoid invalidation on update, provide suitable\n * [SnapshotMutationPolicy] through [derivedStateOf] overload.\n *\n * @sample androidx.compose.runtime.samples.DerivedStateSample\n * @param calculation the calculation to create the value this state object represents.\n */\n@StateFactoryMarker\npublic fun <T> derivedStateOf(calculation: () -> T): State<T> =\n    DerivedSnapshotState(calculation, null)\n\n/**\n * Creates a [State] object whose [State.value] is the result of [calculation]. The result of\n * calculation will be cached in such a way that calling [State.value] repeatedly will not cause\n * [calculation] to be executed multiple times, but reading [State.value] will cause all [State]\n * objects that got read during the [calculation] to be read in the current [Snapshot], meaning that\n * this will correctly subscribe to the derived state objects if the value is being read in an\n * observed context such as a [Composable] function.\n *\n * @sample androidx.compose.runtime.samples.DerivedStateSample\n * @param policy mutation policy to control when changes to the [calculation] result trigger update.\n * @param calculation the calculation to create the value this state object represents.\n */\n@StateFactoryMarker\npublic fun <T> derivedStateOf(policy: SnapshotMutationPolicy<T>, calculation: () -> T): State<T> =\n    DerivedSnapshotState(calculation, policy)\n\n/** Observe the recalculations performed by derived states. */\ninternal interface DerivedStateObserver {\n    /** Called before a calculation starts. */\n    fun start(derivedState: DerivedState<*>)\n\n    /** Called after the started calculation is complete. */\n    fun done(derivedState: DerivedState<*>)\n}\n\nprivate val derivedStateObservers = SnapshotThreadLocal<MutableVector<DerivedStateObserver>>()\n\ninternal fun derivedStateObservers(): MutableVector<DerivedStateObserver> =\n    derivedStateObservers.get()\n        ?: MutableVector<DerivedStateObserver>(0).also { derivedStateObservers.set(it) }\n\nprivate inline fun <R> notifyObservers(derivedState: DerivedState<*>, block: () -> R): R {\n    val observers = derivedStateObservers()\n    observers.forEach { it.start(derivedState) }\n    return try {\n        block()\n    } finally {\n        observers.forEach { it.done(derivedState) }\n    }\n}\n\n/**\n * Observe the recalculations performed by any derived state that is recalculated during the\n * execution of [block].\n *\n * @param observer called for every calculation of a derived state in the [block].\n * @param block the block of code to observe.\n */\ninternal inline fun <R> observeDerivedStateRecalculations(\n    observer: DerivedStateObserver,\n    block: () -> R,\n) {\n    val observers = derivedStateObservers()\n    try {\n        observers.add(observer)\n        block()\n    } finally {\n        observers.removeAt(observers.lastIndex)\n    }\n}\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/Snapshot.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.runtime.snapshots\n\nimport androidx.collection.MutableScatterSet\nimport androidx.collection.mutableScatterSetOf\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.DisallowComposableCalls\nimport androidx.compose.runtime.ExperimentalComposeRuntimeApi\nimport androidx.compose.runtime.InternalComposeApi\nimport androidx.compose.runtime.checkPrecondition\nimport androidx.compose.runtime.collection.wrapIntoSet\nimport androidx.compose.runtime.internal.AtomicInt\nimport androidx.compose.runtime.internal.JvmDefaultWithCompatibility\nimport androidx.compose.runtime.internal.SnapshotThreadLocal\nimport androidx.compose.runtime.internal.currentThreadId\nimport androidx.compose.runtime.platform.SynchronizedObject\nimport androidx.compose.runtime.platform.makeSynchronizedObject\nimport androidx.compose.runtime.platform.synchronized\nimport androidx.compose.runtime.requirePrecondition\nimport androidx.compose.runtime.snapshots.Snapshot.Companion.takeMutableSnapshot\nimport androidx.compose.runtime.snapshots.Snapshot.Companion.takeSnapshot\nimport androidx.compose.runtime.snapshots.tooling.creatingSnapshot\nimport androidx.compose.runtime.snapshots.tooling.dispatchObserverOnApplied\nimport androidx.compose.runtime.snapshots.tooling.dispatchObserverOnPreDispose\nimport androidx.compose.runtime.tooling.verboseTrace\nimport kotlin.contracts.ExperimentalContracts\nimport kotlin.contracts.InvocationKind\nimport kotlin.contracts.contract\n\n/**\n * A snapshot of the values return by mutable states and other state objects. All state object will\n * have the same value in the snapshot as they had when the snapshot was created unless they are\n * explicitly changed in the snapshot.\n *\n * To enter a snapshot call [enter]. The snapshot is the current snapshot as returned by\n * [currentSnapshot] until the control returns from the lambda (or until a nested [enter] is\n * called). All state objects will return the values associated with this snapshot, locally in the\n * thread, until [enter] returns. All other threads are unaffected.\n *\n * Snapshots can be nested by calling [takeNestedSnapshot].\n *\n * @see takeSnapshot\n * @see takeMutableSnapshot\n * @see androidx.compose.runtime.mutableStateOf\n * @see androidx.compose.runtime.mutableStateListOf\n * @see androidx.compose.runtime.mutableStateMapOf\n */\npublic sealed class Snapshot(\n    snapshotId: SnapshotId,\n\n    /** A set of all the snapshots that should be treated as invalid. */\n    internal open var invalid: SnapshotIdSet,\n) {\n    @Deprecated(\"Use id: Long constructor instead\", level = DeprecationLevel.HIDDEN)\n    protected constructor(id: Int, invalid: SnapshotIdSet) : this(id.toSnapshotId(), invalid)\n\n    /**\n     * The snapshot id of the snapshot. This is a unique number from a monotonically increasing\n     * value for each snapshot taken.\n     *\n     * [id] will is identical to [snapshotId] if the value of [snapshotId] is less than or equal to\n     * [Int.MAX_VALUE]. For [snapshotId] value greater than [Int.MAX_VALUE], this value will return\n     * a negative value.\n     */\n    @Deprecated(\"Use snapshotId instead\", replaceWith = ReplaceWith(\"snapshotId\"))\n    public open val id: Int\n        get() = snapshotId.toInt()\n\n    /**\n     * The snapshot id of the snapshot. This is a unique number from a monotonically increasing\n     * value for each snapshot taken.\n     */\n    public open var snapshotId: SnapshotId = snapshotId\n        internal set\n\n    internal open var writeCount: Int\n        get() = 0\n        @Suppress(\"UNUSED_PARAMETER\")\n        set(value) {\n            error(\"Updating write count is not supported for this snapshot\")\n        }\n\n    /**\n     * The root snapshot for this snapshot. For non-nested snapshots this is always `this`. For\n     * nested snapshot it is the parent's [root].\n     */\n    public abstract val root: Snapshot\n\n    /** True if any change to a state object in this snapshot will throw. */\n    public abstract val readOnly: Boolean\n\n    /**\n     * Dispose the snapshot. Neglecting to dispose a snapshot will result in difficult to diagnose\n     * memory leaks as it indirectly causes all state objects to maintain its value for the\n     * un-disposed snapshot.\n     */\n    public open fun dispose() {\n        disposed = true\n        sync { releasePinnedSnapshotLocked() }\n    }\n\n    /**\n     * Take a snapshot of the state values in this snapshot. The resulting [Snapshot] is read-only.\n     * All nested snapshots need to be disposed by calling [dispose] before resources associated\n     * with this snapshot can be collected. Nested snapshots are still valid after the parent has\n     * been disposed.\n     */\n    public abstract fun takeNestedSnapshot(readObserver: ((Any) -> Unit)? = null): Snapshot\n\n    /**\n     * Whether there are any pending changes in this snapshot. These changes are not visible until\n     * the snapshot is applied.\n     */\n    public abstract fun hasPendingChanges(): Boolean\n\n    /**\n     * Enter the snapshot. In [block] all state objects have the value associated with this\n     * snapshot. The value of [currentSnapshot] will be this snapshot until this [block] returns or\n     * a nested call to [enter] is called. When [block] returns, the previous current snapshot is\n     * restored if there was one.\n     *\n     * All changes to state objects inside [block] are isolated to this snapshot and are not visible\n     * to other snapshot or as global state. If this is a [readOnly] snapshot, any changes to state\n     * objects will throw an [IllegalStateException].\n     *\n     * For a [MutableSnapshot], changes made to a snapshot inside [block] can be applied atomically\n     * to the global state (or to its parent snapshot if it is a nested snapshot) by calling\n     * [MutableSnapshot.apply].\n     *\n     * @see androidx.compose.runtime.mutableStateOf\n     * @see androidx.compose.runtime.mutableStateListOf\n     * @see androidx.compose.runtime.mutableStateMapOf\n     */\n    public inline fun <T> enter(block: () -> T): T {\n        val previous = makeCurrent()\n        try {\n            return block()\n        } finally {\n            restoreCurrent(previous)\n        }\n    }\n\n    @PublishedApi\n    internal open fun makeCurrent(): Snapshot? {\n        val previous = threadSnapshot.get()\n        threadSnapshot.set(this)\n        return previous\n    }\n\n    @PublishedApi\n    internal open fun restoreCurrent(snapshot: Snapshot?) {\n        threadSnapshot.set(snapshot)\n    }\n\n    /**\n     * Enter the snapshot, returning the previous [Snapshot] for leaving this snapshot later using\n     * [unsafeLeave]. Prefer [enter] or [asContextElement] instead of using [unsafeEnter] directly\n     * to prevent mismatched [unsafeEnter]/[unsafeLeave] calls.\n     *\n     * After returning all state objects have the value associated with this snapshot. The value of\n     * [currentSnapshot] will be this snapshot until [unsafeLeave] is called with the returned\n     * [Snapshot] or another call to [unsafeEnter] or [enter] is made.\n     *\n     * All changes to state objects until another snapshot is entered or this snapshot is left are\n     * isolated to this snapshot and are not visible to other snapshot or as global state. If this\n     * is a [readOnly] snapshot, any changes to state objects will throw an [IllegalStateException].\n     *\n     * For a [MutableSnapshot], changes made to a snapshot can be applied atomically to the global\n     * state (or to its parent snapshot if it is a nested snapshot) by calling\n     * [MutableSnapshot.apply].\n     */\n    public fun unsafeEnter(): Snapshot? = makeCurrent()\n\n    /** Leave the snapshot, restoring the [oldSnapshot] before returning. See [unsafeEnter]. */\n    public fun unsafeLeave(oldSnapshot: Snapshot?) {\n        checkPrecondition(threadSnapshot.get() === this) {\n            \"Cannot leave snapshot; $this is not the current snapshot\"\n        }\n        restoreCurrent(oldSnapshot)\n    }\n\n    internal var disposed = false\n\n    /*\n     * Handle to use when unpinning this snapshot. -1 if this snapshot has been unpinned.\n     */\n    @Suppress(\"LeakingThis\")\n    private var pinningTrackingHandle =\n        if (snapshotId != INVALID_SNAPSHOT) trackPinning(snapshotId, invalid) else -1\n\n    internal inline val isPinned\n        get() = pinningTrackingHandle >= 0\n\n    /*\n     * The read observer for the snapshot if there is one.\n     */\n    @PublishedApi internal abstract val readObserver: ((Any) -> Unit)?\n\n    /** The write observer for the snapshot if there is one. */\n    internal abstract val writeObserver: ((Any) -> Unit)?\n\n    /** Called when a nested snapshot of this snapshot is activated */\n    internal abstract fun nestedActivated(snapshot: Snapshot)\n\n    /** Called when a nested snapshot of this snapshot is deactivated */\n    internal abstract fun nestedDeactivated(snapshot: Snapshot)\n\n    /** Record that state was modified in the snapshot. */\n    internal abstract fun recordModified(state: StateObject)\n\n    /** The set of state objects that have been modified in this snapshot. */\n    internal abstract val modified: MutableScatterSet<StateObject>?\n\n    /**\n     * Notify the snapshot that all objects created in this snapshot to this point should be\n     * considered initialized. If any state object is modified after this point it will appear as\n     * modified in the snapshot. Any applicable snapshot write observer will be called for the\n     * object and the object will be part of the a set of mutated objects sent to any applicable\n     * snapshot apply observer.\n     *\n     * Unless [notifyObjectsInitialized] is called, state objects created in a snapshot are not\n     * considered modified by the snapshot even if they are modified after construction.\n     */\n    internal abstract fun notifyObjectsInitialized()\n\n    /**\n     * Closes the snapshot by removing the snapshot id (an any previous id's) from the list of open\n     * snapshots and unpinning snapshots that no longer are referenced by this snapshot.\n     */\n    internal fun closeAndReleasePinning() {\n        sync {\n            closeLocked()\n            releasePinnedSnapshotsForCloseLocked()\n        }\n    }\n\n    /**\n     * Closes the snapshot by removing the snapshot id (and any previous ids) from the list of open\n     * snapshots. Does not release pinned snapshots. See [releasePinnedSnapshotsForCloseLocked] for\n     * the second half of [closeAndReleasePinning].\n     *\n     * Call while holding a `sync {}` lock.\n     */\n    internal open fun closeLocked() {\n        openSnapshots = openSnapshots.clear(snapshotId)\n    }\n\n    /**\n     * Releases all pinned snapshots required to perform a clean [closeAndReleasePinning].\n     *\n     * Call while holding a `sync {}` lock.\n     *\n     * See [closeAndReleasePinning], [closeLocked].\n     */\n    internal open fun releasePinnedSnapshotsForCloseLocked() {\n        releasePinnedSnapshotLocked()\n    }\n\n    internal fun validateNotDisposed() {\n        requirePrecondition(!disposed) { \"Cannot use a disposed snapshot\" }\n    }\n\n    internal fun releasePinnedSnapshotLocked() {\n        if (pinningTrackingHandle >= 0) {\n            releasePinningLocked(pinningTrackingHandle)\n            pinningTrackingHandle = -1\n        }\n    }\n\n    internal fun takeoverPinnedSnapshot(): Int =\n        pinningTrackingHandle.also { pinningTrackingHandle = -1 }\n\n    public companion object {\n        /**\n         * Return the thread's active snapshot. If no thread snapshot is active then the current\n         * global snapshot is used.\n         */\n        public val current: Snapshot\n            get() = currentSnapshot()\n\n        /** Return `true` if the thread is currently in the context of a snapshot. */\n        public val isInSnapshot: Boolean\n            get() = threadSnapshot.get() != null\n\n        /**\n         * Returns whether any threads are currently in the process of notifying observers about\n         * changes to the global snapshot.\n         */\n        public val isApplyObserverNotificationPending: Boolean\n            get() = pendingApplyObserverCount.get() > 0\n\n        /**\n         * All new state objects initial state records should be [PreexistingSnapshotId] which then\n         * allows snapshots outside the creating snapshot to access the object with its initial\n         * state.\n         */\n        @Suppress(\"ConstPropertyName\") public const val PreexistingSnapshotId: Int = 1\n\n        /**\n         * Take a snapshot of the current value of all state objects. The values are preserved until\n         * [Snapshot.dispose] is called on the result.\n         *\n         * The [readObserver] parameter can be used to track when all state objects are read when in\n         * [Snapshot.enter]. A snapshot apply observer can be registered using\n         * [Snapshot.registerApplyObserver] to observe modification of state objects.\n         *\n         * An active snapshot (after it is created but before [Snapshot.dispose] is called) requires\n         * resources to track the values in the snapshot. Once a snapshot is no longer needed it\n         * should disposed by calling [Snapshot.dispose].\n         *\n         * Leaving a snapshot active could cause hard to diagnose memory leaks values as are\n         * maintained by state objects for these unneeded snapshots. Take care to always call\n         * [Snapshot.dispose] on all snapshots when they are no longer needed.\n         *\n         * Composition uses both of these to implicitly subscribe to changes to state object and\n         * automatically update the composition when state objects read during composition change.\n         *\n         * A nested snapshot can be taken of a snapshot which is an independent read-only copy of\n         * the snapshot and can be disposed independently. This is used by [takeSnapshot] when in a\n         * read-only snapshot for API consistency allowing the result of [takeSnapshot] to be\n         * disposed leaving the parent snapshot active.\n         *\n         * @param readObserver called when any state object is read in the lambda passed to\n         *   [Snapshot.enter] or in the [Snapshot.enter] of any nested snapshot.\n         * @see Snapshot\n         * @see Snapshot.registerApplyObserver\n         */\n        public fun takeSnapshot(readObserver: ((Any) -> Unit)? = null): Snapshot =\n            currentSnapshot().takeNestedSnapshot(readObserver)\n\n        /**\n         * Take a snapshot of the current value of all state objects that also allows the state to\n         * be changed and later atomically applied when [MutableSnapshot.apply] is called. The\n         * values are preserved until [Snapshot.dispose] is called on the result. The global state\n         * will either see all the changes made as one atomic change, when [MutableSnapshot .apply]\n         * is called, or none of the changes if the mutable state object is disposed before being\n         * applied.\n         *\n         * The values in a snapshot can be modified by calling [Snapshot.enter] and then, in its\n         * lambda, modify any state object. The new values of the state objects will only become\n         * visible to the global state when [MutableSnapshot.apply] is called.\n         *\n         * An active snapshot (after it is created but before [Snapshot.dispose] is called) requires\n         * resources to track the values in the snapshot. Once a snapshot is no longer needed it\n         * should disposed by calling [Snapshot.dispose].\n         *\n         * Leaving a snapshot active could cause hard to diagnose memory leaks as values are\n         * maintained by state objects for these unneeded snapshots. Take care to always call\n         * [Snapshot.dispose] on all snapshots when they are no longer needed.\n         *\n         * A nested snapshot can be taken by calling [Snapshot.takeNestedSnapshot], for a read-only\n         * snapshot, or [MutableSnapshot.takeNestedMutableSnapshot] for a snapshot that can be\n         * changed. Nested mutable snapshots are applied to the this, the parent snapshot, when\n         * their [MutableSnapshot.apply] is called. Their applied changes will be visible to in this\n         * snapshot but will not be visible other snapshots (including other nested snapshots) or\n         * the global state until this snapshot is applied by calling [MutableSnapshot.apply].\n         *\n         * Once [MutableSnapshot.apply] is called on this, the parent snapshot, all calls to\n         * [MutableSnapshot.apply] on an active nested snapshot will fail.\n         *\n         * Changes to a mutable snapshot are isolated, using snapshot isolation, from all other\n         * snapshots. Their changes are only visible as global state or to new snapshots once\n         * [MutableSnapshot.apply] is called.\n         *\n         * Applying a snapshot can fail if currently visible changes to the state object conflicts\n         * with a change made in the snapshot.\n         *\n         * When in a mutable snapshot, [takeMutableSnapshot] creates a nested snapshot of the\n         * current mutable snapshot. If the current snapshot is read-only, an exception is thrown.\n         * The current snapshot is the result of calling [currentSnapshot] which is updated by\n         * calling [Snapshot.enter] which makes the [Snapshot] the current snapshot while in its\n         * lambda.\n         *\n         * Composition uses mutable snapshots to allow changes made in a [Composable] functions to\n         * be temporarily isolated from the global state and is later applied to the global state\n         * when the composition is applied. If [MutableSnapshot.apply] fails applying this snapshot,\n         * the snapshot and the changes calculated during composition are disposed and a new\n         * composition is scheduled to be calculated again.\n         *\n         * @param readObserver called when any state object is read in the lambda passed to\n         *   [Snapshot.enter] or in the [Snapshot.enter] of any nested snapshots.\n         *\n         * Composition, layout and draw use [readObserver] to implicitly subscribe to changes to\n         * state objects to know when to update.\n         *\n         * @param writeObserver called when a state object is created or just before it is written\n         *   to the first time in the snapshot or a nested mutable snapshot. This might be called\n         *   several times for the same object if nested mutable snapshots are created.\n         *\n         * Composition uses [writeObserver] to track when a state object is modified during\n         * composition in order to invalidate the reads that have not yet occurred. This allows a\n         * single pass of composition for state objects that are written to before they are read\n         * (such as modifying the value of a dynamic ambient provider).\n         *\n         * @see Snapshot.takeSnapshot\n         * @see Snapshot\n         * @see MutableSnapshot\n         */\n        public fun takeMutableSnapshot(\n            readObserver: ((Any) -> Unit)? = null,\n            writeObserver: ((Any) -> Unit)? = null,\n        ): MutableSnapshot =\n            (currentSnapshot() as? MutableSnapshot)?.takeNestedMutableSnapshot(\n                readObserver,\n                writeObserver,\n            ) ?: error(\"Cannot create a mutable snapshot of an read-only snapshot\")\n\n        /**\n         * Escape the current snapshot, if there is one. All state objects will have the value\n         * associated with the global while the [block] lambda is executing.\n         *\n         * @return the result of [block]\n         */\n        public inline fun <T> global(block: () -> T): T {\n            val previous = removeCurrent()\n            try {\n                return block()\n            } finally {\n                restoreCurrent(previous)\n            }\n        }\n\n        /**\n         * Take a [MutableSnapshot] and run [block] within it. When [block] returns successfully,\n         * attempt to [MutableSnapshot.apply] the snapshot. Returns the result of [block] or throws\n         * [SnapshotApplyConflictException] if snapshot changes attempted by [block] could not be\n         * applied.\n         *\n         * Prior to returning, any changes made to snapshot state (e.g. state holders returned by\n         * [androidx.compose.runtime.mutableStateOf] are not visible to other threads. When\n         * [withMutableSnapshot] returns successfully those changes will be made visible to other\n         * threads and any snapshot observers (e.g. [androidx.compose.runtime.snapshotFlow]) will be\n         * notified of changes.\n         *\n         * [block] must not suspend if [withMutableSnapshot] is called from a suspend function.\n         */\n        // TODO: determine a good way to prevent/discourage suspending in an inlined [block]\n        public inline fun <R> withMutableSnapshot(block: () -> R): R =\n            takeMutableSnapshot().run {\n                var hasError = false\n                try {\n                    enter(block)\n                } catch (e: Throwable) {\n                    hasError = true\n                    throw e\n                } finally {\n                    if (!hasError) {\n                        apply().check()\n                    }\n                    dispose()\n                }\n            }\n\n        /**\n         * Observe reads and or write of state objects in the current thread.\n         *\n         * This only affects the current snapshot (if any) and any new snapshots create from\n         * [Snapshot.takeSnapshot] and [takeMutableSnapshot]. It will not affect any snapshots\n         * previous created even if [Snapshot.enter] is called in [block].\n         *\n         * @param readObserver called when any state object is read.\n         * @param writeObserver called when a state object is created or just before it is written\n         *   to the first time in the snapshot or a nested mutable snapshot. This might be called\n         *   several times for the same object if nested mutable snapshots are created.\n         * @param block the code the [readObserver] and [writeObserver] will be observing. Once\n         *   [block] returns, the [readObserver] and [writeObserver] will no longer be called.\n         */\n        public fun <T> observe(\n            readObserver: ((Any) -> Unit)? = null,\n            writeObserver: ((Any) -> Unit)? = null,\n            block: () -> T,\n        ): T = observeInternal(readObserver, writeObserver, block)\n\n        @Suppress(\"NOTHING_TO_INLINE\")\n        // marked as inline to use as part of SnapshotStateObserver without adding extra function\n        // call overhead.\n        internal inline fun <T> observeInternal(\n            noinline readObserver: ((Any) -> Unit)? = null,\n            noinline writeObserver: ((Any) -> Unit)? = null,\n            noinline block: () -> T,\n        ): T {\n            if (readObserver == null && writeObserver == null) {\n                // No observer change, just execute the block\n                return block()\n            }\n\n            val previous = threadSnapshot.get()\n            if (previous is TransparentObserverMutableSnapshot && previous.canBeReused) {\n                // Change observers in place without allocating new snapshots.\n                val previousReadObserver = previous.readObserver\n                val previousWriteObserver = previous.writeObserver\n\n                try {\n                    previous.readObserver = mergedReadObserver(readObserver, previousReadObserver)\n                    previous.writeObserver =\n                        mergedWriteObserver(writeObserver, previousWriteObserver)\n                    return block()\n                } finally {\n                    previous.readObserver = previousReadObserver\n                    previous.writeObserver = previousWriteObserver\n                }\n            } else {\n                // The snapshot is not already transparent, observe in a new transparent snapshot\n                val snapshot =\n                    when {\n                        previous == null || previous is MutableSnapshot -> {\n                            TransparentObserverMutableSnapshot(\n                                parentSnapshot = previous as? MutableSnapshot,\n                                specifiedReadObserver = readObserver,\n                                specifiedWriteObserver = writeObserver,\n                                mergeParentObservers = true,\n                                ownsParentSnapshot = false,\n                            )\n                        }\n                        readObserver == null -> {\n                            return block()\n                        }\n                        else -> {\n                            previous.takeNestedSnapshot(readObserver)\n                        }\n                    }\n                try {\n                    return snapshot.enter(block)\n                } finally {\n                    snapshot.dispose()\n                }\n            }\n        }\n\n        @Suppress(\"unused\") // left here for binary compatibility\n        @PublishedApi\n        internal fun createNonObservableSnapshot(): Snapshot =\n            createTransparentSnapshotWithNoParentReadObserver(\n                previousSnapshot = threadSnapshot.get()\n            )\n\n        @PublishedApi\n        internal val currentThreadSnapshot: Snapshot?\n            get() = threadSnapshot.get()\n\n        private inline val TransparentObserverMutableSnapshot.canBeReused: Boolean\n            get() = threadId == currentThreadId()\n\n        private inline val TransparentObserverSnapshot.canBeReused: Boolean\n            get() = threadId == currentThreadId()\n\n        @PublishedApi\n        internal fun makeCurrentNonObservable(previous: Snapshot?): Snapshot =\n            when {\n                previous is TransparentObserverMutableSnapshot && previous.canBeReused -> {\n                    previous.readObserver = null\n                    previous\n                }\n                previous is TransparentObserverSnapshot && previous.canBeReused -> {\n                    previous.readObserver = null\n                    previous\n                }\n                else -> {\n                    val snapshot =\n                        createTransparentSnapshotWithNoParentReadObserver(\n                            previousSnapshot = previous\n                        )\n                    snapshot.makeCurrent()\n                    snapshot\n                }\n            }\n\n        @PublishedApi\n        internal fun restoreNonObservable(\n            previous: Snapshot?,\n            nonObservable: Snapshot,\n            observer: ((Any) -> Unit)?,\n        ) {\n            if (previous === nonObservable) {\n                when (previous) {\n                    is TransparentObserverMutableSnapshot -> {\n                        previous.readObserver = observer\n                    }\n                    is TransparentObserverSnapshot -> {\n                        previous.readObserver = observer\n                    }\n                    else -> {\n                        error(\"Non-transparent snapshot was reused: $previous\")\n                    }\n                }\n            } else {\n                nonObservable.restoreCurrent(previous)\n                nonObservable.dispose()\n            }\n        }\n\n        /**\n         * Passed [block] will be run with all the currently set snapshot read observers disabled.\n         */\n        @Suppress(\"BanInlineOptIn\") // Treat Kotlin Contracts as non-experimental.\n        @OptIn(ExperimentalContracts::class)\n        public inline fun <T> withoutReadObservation(block: @DisallowComposableCalls () -> T): T {\n            contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }\n            val previousSnapshot = currentThreadSnapshot\n            val observer = previousSnapshot?.readObserver\n            val newSnapshot = makeCurrentNonObservable(previousSnapshot)\n            try {\n                return block()\n            } finally {\n                restoreNonObservable(previousSnapshot, newSnapshot, observer)\n            }\n        }\n\n        /**\n         * Register an apply listener that is called back when snapshots are applied to the global\n         * state.\n         *\n         * @return [ObserverHandle] to unregister [observer].\n         */\n        public fun registerApplyObserver(observer: (Set<Any>, Snapshot) -> Unit): ObserverHandle {\n            // Ensure observer does not see changes before this call.\n            advanceGlobalSnapshot(emptyLambda)\n\n            sync { applyObservers += observer }\n            return ObserverHandle { sync { applyObservers -= observer } }\n        }\n\n        /**\n         * Register an observer of the first write to the global state of a global state object\n         * since the last call to [sendApplyNotifications].\n         *\n         * Composition uses this to schedule a new composition whenever a state object that was read\n         * in composition is modified.\n         *\n         * State objects can be sent to the apply observer that have not been sent to global write\n         * observers. This happens for state objects inside [MutableSnapshot] that is later applied\n         * by calling [MutableSnapshot.apply].\n         *\n         * This should only be used to determine if a call to [sendApplyNotifications] should be\n         * scheduled to be called.\n         *\n         * @return [ObserverHandle] to unregister [observer].\n         */\n        public fun registerGlobalWriteObserver(observer: ((Any) -> Unit)): ObserverHandle {\n            sync { globalWriteObservers += observer }\n            advanceGlobalSnapshot()\n            return ObserverHandle {\n                sync { globalWriteObservers -= observer }\n                advanceGlobalSnapshot()\n            }\n        }\n\n        /**\n         * Notify the snapshot that all objects created in this snapshot to this point should be\n         * considered initialized. If any state object is are modified passed this point it will\n         * appear as modified in the snapshot and any applicable snapshot write observer will be\n         * called for the object and the object will be part of the a set of mutated objects sent to\n         * any applicable snapshot apply observer.\n         *\n         * Unless [notifyObjectsInitialized] is called, state objects created in a snapshot are not\n         * considered modified by the snapshot even if they are modified after construction.\n         *\n         * Compose uses this between phases of composition to allow observing changes to state\n         * objects create in a previous phase.\n         */\n        public fun notifyObjectsInitialized(): Unit = currentSnapshot().notifyObjectsInitialized()\n\n        /**\n         * Send any pending apply notifications for state objects changed outside a snapshot.\n         *\n         * Apply notifications for state objects modified outside snapshot are deferred until method\n         * is called. This method is implicitly called whenever a non-nested [MutableSnapshot] is\n         * applied making its changes visible to all new, non-nested snapshots.\n         *\n         * Composition schedules this to be called after changes to state objects are detected an\n         * observer registered with [registerGlobalWriteObserver].\n         */\n        public fun sendApplyNotifications() {\n            val changes = sync { globalSnapshot.hasPendingChanges() }\n            if (changes) advanceGlobalSnapshot()\n        }\n\n        @InternalComposeApi public fun openSnapshotCount(): Int = openSnapshots.toList().size\n\n        @PublishedApi\n        internal fun removeCurrent(): Snapshot? {\n            val previous = threadSnapshot.get()\n            if (previous != null) threadSnapshot.set(null)\n            return previous\n        }\n\n        @PublishedApi\n        internal fun restoreCurrent(previous: Snapshot?) {\n            if (previous != null) threadSnapshot.set(previous)\n        }\n    }\n}\n\n/**\n * Pin the snapshot and invalid set.\n *\n * @return returns a handle that should be passed to [releasePinningLocked] when the snapshot closes\n *   or is disposed.\n */\ninternal fun trackPinning(snapshotId: SnapshotId, invalid: SnapshotIdSet): Int {\n    val pinned = invalid.lowest(snapshotId)\n    return sync { pinningTable.add(pinned) }\n}\n\n/** Release the [handle] returned by [trackPinning] */\ninternal fun releasePinningLocked(handle: Int) {\n    pinningTable.remove(handle)\n}\n\n/**\n * A snapshot of the values return by mutable states and other state objects. All state object will\n * have the same value in the snapshot as they had when the snapshot was created unless they are\n * explicitly changed in the snapshot.\n *\n * To enter a snapshot call [enter]. The snapshot is the current snapshot as returned by\n * [currentSnapshot] until the control returns from the lambda (or until a nested [enter] is called.\n * All state objects will return the values associated with this snapshot, locally in the thread,\n * until [enter] returns. All other threads are unaffected.\n *\n * All changes made in a [MutableSnapshot] are snapshot isolated from all other snapshots and their\n * changes can only be seen globally, or by new shots, after [MutableSnapshot.apply] as been called.\n *\n * Snapshots can be nested by calling [takeNestedSnapshot] or\n * [MutableSnapshot.takeNestedMutableSnapshot].\n *\n * @see Snapshot.takeMutableSnapshot\n * @see androidx.compose.runtime.mutableStateOf\n * @see androidx.compose.runtime.mutableStateListOf\n * @see androidx.compose.runtime.mutableStateMapOf\n */\npublic open class MutableSnapshot\ninternal constructor(\n    snapshotId: SnapshotId,\n    invalid: SnapshotIdSet,\n    override val readObserver: ((Any) -> Unit)?,\n    override val writeObserver: ((Any) -> Unit)?,\n) : Snapshot(snapshotId, invalid) {\n    /**\n     * Whether there are any pending changes in this snapshot. These changes are not visible until\n     * the snapshot is applied.\n     */\n    override fun hasPendingChanges(): Boolean = modified?.isNotEmpty() == true\n\n    /**\n     * Take a mutable snapshot of the state values in this snapshot. Entering this snapshot by\n     * calling [enter] allows state objects to be modified that are not visible to the this, the\n     * parent snapshot, until the [apply] is called.\n     *\n     * Applying a nested snapshot, by calling [apply], applies its change to, this, the parent\n     * snapshot. For a change to be visible globally, all the parent snapshots need to be applied\n     * until the root snapshot is applied to the global state.\n     *\n     * All nested snapshots need to be disposed by calling [dispose] before resources associated\n     * with this snapshot can be collected. Nested active snapshots are still valid after the parent\n     * has been disposed but calling [apply] will fail.\n     */\n    @OptIn(ExperimentalComposeRuntimeApi::class)\n    public open fun takeNestedMutableSnapshot(\n        readObserver: ((Any) -> Unit)? = null,\n        writeObserver: ((Any) -> Unit)? = null,\n    ): MutableSnapshot {\n        validateNotDisposed()\n        validateNotAppliedOrPinned()\n        return creatingSnapshot(this, readObserver, writeObserver, readonly = false) {\n            actualReadObserver,\n            actualWriteObserver ->\n            advance {\n                sync {\n                    val newId = nextSnapshotId\n                    nextSnapshotId += 1\n                    openSnapshots = openSnapshots.set(newId)\n                    val currentInvalid = invalid\n                    this.invalid = currentInvalid.set(newId)\n                    NestedMutableSnapshot(\n                        newId,\n                        currentInvalid.addRange(snapshotId + 1, newId),\n                        mergedReadObserver(actualReadObserver, this.readObserver),\n                        mergedWriteObserver(actualWriteObserver, this.writeObserver),\n                        this,\n                    )\n                }\n            }\n        }\n    }\n\n    /**\n     * Apply the changes made to state objects in this snapshot to the global state, or to the\n     * parent snapshot if this is a nested mutable snapshot.\n     *\n     * Once this method returns all changes made to this snapshot are atomically visible as the\n     * global state of the state object or to the parent snapshot.\n     *\n     * While a snapshot is active (after it is created but before [apply] or [dispose] is called)\n     * requires resources to track the values in the snapshot. Once a snapshot is no longer needed\n     * it should be either applied by calling [apply] or disposed by calling [dispose]. A snapshot\n     * that has been had is [apply] called can also have [dispose] called on it. However, calling\n     * [apply] after calling [dispose] will throw an exception.\n     *\n     * Leaving a snapshot active could cause hard to diagnose memory leaks values are maintained by\n     * state objects for unneeded snapshots. Take care to always call [dispose] on any snapshot.\n     */\n    public open fun apply(): SnapshotApplyResult {\n        // NOTE: the this algorithm is currently does not guarantee serializable snapshots as it\n        // doesn't prevent crossing writes as described here https://arxiv.org/pdf/1412.2324.pdf\n\n        // Just removing the snapshot from the active snapshot set is enough to make it part of the\n        // next snapshot, however, this should only be done after first determining that there are\n        // no\n        // colliding writes are being applied.\n\n        // A write is considered colliding if any write occurred in a state object in a snapshot\n        // applied since the snapshot was taken.\n        val modified = modified\n        val optimisticMerges =\n            if (modified != null) {\n                val globalSnapshot = globalSnapshot\n                optimisticMerges(\n                    globalSnapshot.snapshotId,\n                    this,\n                    openSnapshots.clear(globalSnapshot.snapshotId),\n                )\n            } else null\n\n        var observers = emptyList<(Set<Any>, Snapshot) -> Unit>()\n        var globalModified: MutableScatterSet<StateObject>? = null\n        sync {\n            validateOpen(this)\n            if (modified == null || modified.size == 0) {\n                closeLocked()\n                val globalSnapshot = globalSnapshot\n                val previousModified = globalSnapshot.modified\n                resetGlobalSnapshotLocked(globalSnapshot, emptyLambda)\n                if (previousModified != null && previousModified.isNotEmpty()) {\n                    observers = applyObservers\n                    globalModified = previousModified\n                }\n            } else {\n                val globalSnapshot = globalSnapshot\n                val result =\n                    innerApplyLocked(\n                        nextSnapshotId,\n                        modified,\n                        optimisticMerges,\n                        openSnapshots.clear(globalSnapshot.snapshotId),\n                    )\n                if (result != SnapshotApplyResult.Success) return result\n\n                closeLocked()\n\n                // Take a new global snapshot that includes this one.\n                val previousModified = globalSnapshot.modified\n                resetGlobalSnapshotLocked(globalSnapshot, emptyLambda)\n                this.modified = null\n                globalSnapshot.modified = null\n\n                observers = applyObservers\n                globalModified = previousModified\n            }\n        }\n\n        // Mark as applied\n        applied = true\n\n        // Notify any apply observers that changes applied were seen\n        if (globalModified != null) {\n            val nonNullGlobalModified = globalModified!!.wrapIntoSet()\n            if (nonNullGlobalModified.isNotEmpty()) {\n                verboseTrace(\"Compose:applyObservers\") {\n                    observers.fastForEach { it(nonNullGlobalModified, this) }\n                }\n            }\n        }\n\n        if (modified != null && modified.isNotEmpty()) {\n            val modifiedSet = modified.wrapIntoSet()\n            verboseTrace(\"Compose:applyObservers\") {\n                observers.fastForEach { it(modifiedSet, this) }\n            }\n        }\n\n        dispatchObserverOnApplied(this, modified)\n\n        // Wait to release pinned snapshots until after running observers.\n        // This permits observers to safely take a nested snapshot of the one that was just applied\n        // before unpinning records that need to be retained in this case.\n        sync {\n            releasePinnedSnapshotsForCloseLocked()\n            checkAndOverwriteUnusedRecordsLocked()\n            globalModified?.forEach { processForUnusedRecordsLocked(it) }\n            modified?.forEach { processForUnusedRecordsLocked(it) }\n            merged?.fastForEach { processForUnusedRecordsLocked(it) }\n            merged = null\n        }\n\n        return SnapshotApplyResult.Success\n    }\n\n    override val readOnly: Boolean\n        get() = false\n\n    override val root: Snapshot\n        get() = this\n\n    override fun dispose() {\n        if (!disposed) {\n            super.dispose()\n            nestedDeactivated(this)\n            dispatchObserverOnPreDispose(this)\n        }\n    }\n\n    @OptIn(ExperimentalComposeRuntimeApi::class)\n    override fun takeNestedSnapshot(readObserver: ((Any) -> Unit)?): Snapshot {\n        validateNotDisposed()\n        validateNotAppliedOrPinned()\n        val previousId = snapshotId\n        return creatingSnapshot(\n            if (this is GlobalSnapshot) null else this,\n            readObserver = readObserver,\n            writeObserver = null,\n            readonly = true,\n        ) { actualReadObserver, _ ->\n            advance {\n                sync {\n                    val readonlyId = nextSnapshotId.also { nextSnapshotId += 1 }\n                    openSnapshots = openSnapshots.set(readonlyId)\n                    NestedReadonlySnapshot(\n                        snapshotId = readonlyId,\n                        invalid = invalid.addRange(previousId + 1, readonlyId),\n                        readObserver = mergedReadObserver(actualReadObserver, this.readObserver),\n                        parent = this,\n                    )\n                }\n            }\n        }\n    }\n\n    override fun nestedActivated(snapshot: Snapshot) {\n        snapshots++\n    }\n\n    override fun nestedDeactivated(snapshot: Snapshot) {\n        requirePrecondition(snapshots > 0) { \"no pending nested snapshots\" }\n        if (--snapshots == 0) {\n            if (!applied) {\n                abandon()\n            }\n        }\n    }\n\n    override fun notifyObjectsInitialized() {\n        if (applied || disposed) return\n        advance()\n    }\n\n    override fun closeLocked() {\n        // Remove itself and previous ids from the open set.\n        openSnapshots = openSnapshots.clear(snapshotId).andNot(previousIds)\n    }\n\n    override fun releasePinnedSnapshotsForCloseLocked() {\n        releasePreviouslyPinnedSnapshotsLocked()\n        super.releasePinnedSnapshotsForCloseLocked()\n    }\n\n    private fun validateNotApplied() {\n        checkPrecondition(!applied) { \"Unsupported operation on a snapshot that has been applied\" }\n    }\n\n    private fun validateNotAppliedOrPinned() {\n        checkPrecondition(!applied || isPinned) {\n            \"Unsupported operation on a disposed or applied snapshot\"\n        }\n    }\n\n    /**\n     * Abandon the snapshot. This does NOT [closeAndReleasePinning], which must be done as an\n     * additional step by callers.\n     */\n    private fun abandon() {\n        val modified = modified\n        if (modified != null) {\n            validateNotApplied()\n\n            // Mark all state records created in this snapshot as invalid. This allows the snapshot\n            // id to be forgotten as no state records will refer to it.\n            this.modified = null\n            val id = snapshotId\n            modified.forEach { state ->\n                var current: StateRecord? = state.firstStateRecord\n                while (current != null) {\n                    if (current.snapshotId == id || current.snapshotId in previousIds) {\n                        current.snapshotId = INVALID_SNAPSHOT\n                    }\n                    current = current.next\n                }\n            }\n        }\n\n        // The snapshot can now be closed.\n        closeAndReleasePinning()\n    }\n\n    internal fun innerApplyLocked(\n        nextId: SnapshotId,\n        modified: MutableScatterSet<StateObject>,\n        optimisticMerges: Map<StateRecord, StateRecord>?,\n        invalidSnapshots: SnapshotIdSet,\n    ): SnapshotApplyResult {\n        // This must be called in a synchronized block\n\n        // If there are modifications, we need to ensure none of the them have collisions.\n\n        // A record is guaranteed not to collide if no other write was performed to it since this\n        // snapshot was taken. No writes to a state object occurred if, ignoring this snapshot,\n        // the readable records for the snapshots remain the same. If they are different then\n        // there is a potential collision, and the state object is asked if it can resolve\n        // it. If it can, the updated state record is used for the apply.\n\n        // Determining if there is a collision and resolving it requires finding:\n        //  1) the applying record state (i.e., the record being applied by this snapshot)\n        //  2) the current record state (i.e., the record seen by the global snapshot)\n        //  3) the previous state record (i.e., the record originally copied)\n\n        // The applying record is the readable record this snapshot observes. It is found by calling\n        // readable with this snapshot's ignore set and id (which what the state object also does).\n\n        // The current record can be found by asking what would the next snapshot observes. This is\n        // found by calling readable with the invalidSnapshots (the set of all currently open\n        // snapshots) which is what the next snapshot would have in its invalid, and nextId, which\n        // is the id the next snapshot will have.\n\n        // The previous record can be found by looking for the record that this snapshot would\n        // observe had it not modified it. This is done by excluding the snapshot itself from\n        // invalid (an all previous ids the snapshot had because it advanced) while still using its\n        // id to find the record.\n\n        // Once these records are found, a record is in a merge conflict if both the applying record\n        // and the current record have a different record and neither of them is the previous\n        // record.\n\n        // If the record is not changed outside this snapshot (the most likely scenario), then\n        // there is no conflict, and there is no reason to determine the applying record. For this\n        // reason, the current and previous are determined first the applied record is only\n        // determined if there is a conflict (as it is assumed applied record is different from the\n        // previous record since this code would not execute if they were equal).\n\n        // A state object's mutation policy controls how conflicts are resolved. By default, all\n        // conflicts cannot be resolved and the snapshot will not be applied. However, given the\n        // previous, current, and next records, sometimes conflicts can be resolved (e.g. similar to\n        // merge conflicts in a git commit) and, if so, a new value can be provided by the mutation\n        // policy that merges the changes. If all changed objects can be merged, then the snapshot\n        // will apply but with the new, merged values (e.g., conflict-free data types are an example\n        // of types that can be merged).\n        var mergedRecords: MutableList<Pair<StateObject, StateRecord>>? = null\n        val start = this.invalid.set(this.snapshotId).or(this.previousIds)\n        var statesToRemove: MutableList<StateObject>? = null\n        modified.forEach { state ->\n            val first = state.firstStateRecord\n            // If either current or previous cannot be calculated the object was created\n            // in a nested snapshot that was committed then changed.\n            val current = readable(first, nextId, invalidSnapshots) ?: return@forEach\n            val previous = readable(first, this.snapshotId, start) ?: return@forEach\n            if (previous.snapshotId == PreexistingSnapshotId.toSnapshotId()) {\n                // A previous record might not be found if the state object was created in a\n                // nested snapshot that didn't have any other modifications. The `apply()` for\n                // a nested snapshot considers such snapshots no-op snapshots and just closes them\n                // which allows this object's previous record to be missing or be the record created\n                // during initial construction. In these cases taking applied is the right choice\n                // this indicates there was no conflicting writes.\n                return@forEach\n            }\n            if (current != previous) {\n                val applied = readable(first, this.snapshotId, this.invalid) ?: readError()\n                val merged =\n                    optimisticMerges?.get(current)\n                        ?: run { state.mergeRecords(previous, current, applied) }\n                when (merged) {\n                    null -> return SnapshotApplyResult.Failure(this)\n                    applied -> {\n                        // Nothing to do the merge policy says that the current changes\n                        // obscure the current value so ignore the conflict\n                    }\n                    current -> {\n                        (mergedRecords\n                                ?: mutableListOf<Pair<StateObject, StateRecord>>().also {\n                                    mergedRecords = it\n                                })\n                            .add(state to current.create(snapshotId))\n\n                        // If we revert to current then the state is no longer modified.\n                        (statesToRemove\n                                ?: mutableListOf<StateObject>().also { statesToRemove = it })\n                            .add(state)\n                    }\n                    else -> {\n                        (mergedRecords\n                                ?: mutableListOf<Pair<StateObject, StateRecord>>().also {\n                                    mergedRecords = it\n                                })\n                            .add(\n                                if (merged != previous) state to merged\n                                else state to previous.create(snapshotId)\n                            )\n                    }\n                }\n            }\n        }\n\n        mergedRecords?.let {\n            // Ensure we have a new snapshot id\n            advance()\n\n            // Update all the merged records to have the new id.\n            it.fastForEach { merged ->\n                val (state, stateRecord) = merged\n                stateRecord.snapshotId = nextId\n                sync {\n                    stateRecord.next = state.firstStateRecord\n                    state.prependStateRecord(stateRecord)\n                }\n            }\n        }\n\n        statesToRemove?.let { list ->\n            list.fastForEach { modified.remove(it) }\n            val mergedList = merged\n            merged = if (mergedList == null) list else mergedList + list\n        }\n\n        return SnapshotApplyResult.Success\n    }\n\n    internal inline fun <T> advance(block: () -> T): T {\n        recordPrevious(snapshotId)\n        return block().also {\n            // Only advance this snapshot if it's possible for it to be applied later,\n            // otherwise we don't need to bother.\n            // This simplifies tracking of open snapshots when an apply observer takes\n            // a nested snapshot of the snapshot that was just applied.\n            if (!applied && !disposed) {\n                val previousId = snapshotId\n                sync {\n                    snapshotId = nextSnapshotId.also { nextSnapshotId += 1 }\n                    openSnapshots = openSnapshots.set(snapshotId)\n                }\n                invalid = invalid.addRange(previousId + 1, snapshotId)\n            }\n        }\n    }\n\n    internal fun advance(): Unit = advance {}\n\n    internal fun recordPrevious(id: SnapshotId) {\n        sync { previousIds = previousIds.set(id) }\n    }\n\n    internal fun recordPreviousPinnedSnapshot(id: Int) {\n        if (id >= 0) previousPinnedSnapshots += id\n    }\n\n    internal fun recordPreviousPinnedSnapshots(handles: IntArray) {\n        // Avoid unnecessary copies implied by the `+` below.\n        if (handles.isEmpty()) return\n        val pinned = previousPinnedSnapshots\n        previousPinnedSnapshots = if (pinned.isEmpty()) handles else pinned + handles\n    }\n\n    private fun releasePreviouslyPinnedSnapshotsLocked() {\n        for (index in previousPinnedSnapshots.indices) {\n            releasePinningLocked(previousPinnedSnapshots[index])\n        }\n    }\n\n    internal fun recordPreviousList(snapshots: SnapshotIdSet) {\n        sync { previousIds = previousIds.or(snapshots) }\n    }\n\n    override fun recordModified(state: StateObject) {\n        (modified ?: mutableScatterSetOf<StateObject>().also { modified = it }).add(state)\n    }\n\n    override var writeCount: Int = 0\n\n    override var modified: MutableScatterSet<StateObject>? = null\n\n    internal var merged: List<StateObject>? = null\n\n    /**\n     * A set of the id's previously associated with this snapshot. When this snapshot closes then\n     * these ids must be removed from the global as well.\n     */\n    internal var previousIds: SnapshotIdSet = SnapshotIdSet.EMPTY\n\n    /** A list of the pinned snapshots handles that must be released by this snapshot */\n    internal var previousPinnedSnapshots: IntArray = EmptyIntArray\n\n    /**\n     * The number of pending nested snapshots of this snapshot. To simplify the code, this snapshot\n     * it, itself, counted as its own nested snapshot.\n     */\n    private var snapshots = 1\n\n    /** Tracks whether the snapshot has been applied. */\n    internal var applied = false\n\n    private companion object {\n        private val EmptyIntArray = IntArray(0)\n    }\n}\n\n/**\n * The result of a applying a mutable snapshot. [Success] indicates that the snapshot was\n * successfully applied and is now visible as the global state of the state object (or visible in\n * the parent snapshot for a nested snapshot). [Failure] indicates one or more state objects were\n * modified by both this snapshot and in the global (or parent) snapshot, and the changes from this\n * snapshot are **not** visible in the global or parent snapshot.\n */\npublic sealed class SnapshotApplyResult {\n    /**\n     * Check the result of an apply. If the result is [Success] then this does does nothing. If the\n     * result is [Failure] then a [SnapshotApplyConflictException] exception is thrown. Once [check]\n     * as been called the snapshot is disposed.\n     */\n    public abstract fun check()\n\n    /** True if the result is [Success]. */\n    public abstract val succeeded: Boolean\n\n    public object Success : SnapshotApplyResult() {\n        /**\n         * Check the result of a snapshot apply. Calling [check] on a [Success] result is a noop.\n         */\n        override fun check() {}\n\n        override val succeeded: Boolean\n            get() = true\n    }\n\n    public class Failure(public val snapshot: Snapshot) : SnapshotApplyResult() {\n        /**\n         * Check the result of a snapshot apply. Calling [check] on a [Failure] result throws a\n         * [SnapshotApplyConflictException] exception.\n         */\n        override fun check() {\n            snapshot.dispose()\n            throw SnapshotApplyConflictException(snapshot)\n        }\n\n        override val succeeded: Boolean\n            get() = false\n    }\n}\n\n/**\n * The type returned by observer registration methods that unregisters the observer when it is\n * disposed.\n */\n@Suppress(\"CallbackName\")\npublic fun interface ObserverHandle {\n    /** Dispose the observer causing it to be unregistered from the snapshot system. */\n    public fun dispose()\n}\n\n/**\n * Return the thread's active snapshot. If no thread snapshot is active then the current global\n * snapshot is used.\n */\ninternal fun currentSnapshot(): Snapshot = threadSnapshot.get() ?: globalSnapshot\n\n/**\n * An exception that is thrown when [SnapshotApplyResult.check] is called on a result of a\n * [MutableSnapshot.apply] that fails to apply.\n */\npublic class SnapshotApplyConflictException(@Suppress(\"unused\") public val snapshot: Snapshot) :\n    Exception()\n\n/** Snapshot local value of a state object. */\npublic abstract class StateRecord(\n    /** The snapshot id of the snapshot in which the record was created. */\n    internal var snapshotId: SnapshotId\n) {\n    public constructor() : this(currentSnapshot().snapshotId)\n\n    @Deprecated(\"Use snapshotId: Long constructor instead\")\n    public constructor(id: Int) : this(id.toSnapshotId())\n\n    /**\n     * Reference of the next state record. State records are stored in a linked list.\n     *\n     * Changes to [next] must preserve all existing records to all threads even during\n     * intermediately changes. For example, it is safe to add the beginning or end of the list but\n     * adding to the middle requires care. First the new record must have its [next] updated then\n     * the [next] of its new predecessor can then be set to point to it. This implies that records\n     * that are already in the list cannot be moved in the list as this the change must be atomic to\n     * all threads that cannot happen without a lock which this list cannot afford.\n     *\n     * It is unsafe to remove a record as it might be in the process of being reused (see\n     * [usedLocked]). If a record is removed care must be taken to ensure that it is not being\n     * claimed by some other thread. This would require changes to [usedLocked].\n     */\n    internal var next: StateRecord? = null\n\n    /** Copy the value into this state record from another for the same state object. */\n    public abstract fun assign(value: StateRecord)\n\n    /**\n     * Create a new state record for the same state object. Consider also implementing the [create]\n     * overload that provides snapshotId for faster record construction when snapshot id is known.\n     */\n    public abstract fun create(): StateRecord\n\n    /**\n     * Create a new state record for the same state object and provided [snapshotId]. This allows to\n     * implement an optimized version of [create] to avoid accessing [currentSnapshot] when snapshot\n     * id is known. The default implementation provides a backwards compatible behavior, and should\n     * be overridden if [StateRecord] subclass supports this optimization.\n     */\n    @Deprecated(\"Use snapshotId: Long version instead\", level = DeprecationLevel.HIDDEN)\n    public open fun create(snapshotId: Int): StateRecord =\n        create().also { it.snapshotId = snapshotId.toSnapshotId() }\n\n    /**\n     * Create a new state record for the same state object and provided [snapshotId]. This allows to\n     * implement an optimized version of [create] to avoid accessing [currentSnapshot] when snapshot\n     * id is known. The default implementation provides a backwards compatible behavior, and should\n     * be overridden if [StateRecord] subclass supports this optimization.\n     */\n    public open fun create(snapshotId: SnapshotId): StateRecord =\n        create().also { it.snapshotId = snapshotId }\n}\n\n/**\n * Interface implemented by all snapshot aware state objects. Used by this module to maintain the\n * state records of a state object.\n */\n@JvmDefaultWithCompatibility\npublic interface StateObject {\n    /** The first state record in a linked list of state records. */\n    public val firstStateRecord: StateRecord\n\n    /**\n     * Add a new state record to the beginning of a list. After this call [firstStateRecord] should\n     * be [value].\n     */\n    public fun prependStateRecord(value: StateRecord)\n\n    /**\n     * Produce a merged state based on the conflicting state changes.\n     *\n     * This method must not modify any of the records received and should treat the state records as\n     * immutable, even the [applied] record.\n     *\n     * @param previous the state record that was used to create the [applied] record and is a state\n     *   that also (though indirectly) produced the [current] record.\n     * @param current the state record of the parent snapshot or global state.\n     * @param applied the state record that is being applied of the parent snapshot or global state.\n     * @return the modified state or `null` if the values cannot be merged. If the states cannot be\n     *   merged the current apply will fail. Any of the parameters can be returned as a result. If\n     *   it is not one of the parameter values then it *must* be a new value that is created by\n     *   calling [StateRecord.create] on one of the records passed and then can be modified to have\n     *   the merged value before being returned. If a new record is returned [MutableSnapshot.apply]\n     *   will update the internal snapshot id and call [prependStateRecord] if the record is used.\n     */\n    public fun mergeRecords(\n        previous: StateRecord,\n        current: StateRecord,\n        applied: StateRecord,\n    ): StateRecord? = null\n}\n\n/**\n * A snapshot whose state objects cannot be modified. If a state object is modified when in a\n * read-only snapshot a [IllegalStateException] is thrown.\n */\ninternal class ReadonlySnapshot\ninternal constructor(\n    snapshotId: SnapshotId,\n    invalid: SnapshotIdSet,\n    override val readObserver: ((Any) -> Unit)?,\n) : Snapshot(snapshotId, invalid) {\n    /**\n     * The number of nested snapshots that are active. To simplify the code, this snapshot counts\n     * itself as a nested snapshot.\n     */\n    private var snapshots = 1\n    override val readOnly: Boolean\n        get() = true\n\n    override val root: Snapshot\n        get() = this\n\n    override fun hasPendingChanges(): Boolean = false\n\n    override val writeObserver: ((Any) -> Unit)?\n        get() = null\n\n    override var modified: MutableScatterSet<StateObject>?\n        get() = null\n        @Suppress(\"UNUSED_PARAMETER\") set(value) = unsupported()\n\n    @OptIn(ExperimentalComposeRuntimeApi::class)\n    override fun takeNestedSnapshot(readObserver: ((Any) -> Unit)?): Snapshot {\n        validateOpen(this)\n        return creatingSnapshot(\n            parent = this,\n            readObserver = readObserver,\n            writeObserver = null,\n            readonly = true,\n        ) { actualReadObserver, _ ->\n            NestedReadonlySnapshot(\n                snapshotId = snapshotId,\n                invalid = invalid,\n                readObserver = mergedReadObserver(actualReadObserver, this.readObserver),\n                parent = this,\n            )\n        }\n    }\n\n    override fun notifyObjectsInitialized() {\n        // Nothing to do for read-only snapshots\n    }\n\n    override fun dispose() {\n        if (!disposed) {\n            nestedDeactivated(this)\n            super.dispose()\n            dispatchObserverOnPreDispose(this)\n        }\n    }\n\n    override fun nestedActivated(snapshot: Snapshot) {\n        snapshots++\n    }\n\n    override fun nestedDeactivated(snapshot: Snapshot) {\n        if (--snapshots == 0) {\n            // A read-only snapshot can be just be closed as it has no modifications.\n            closeAndReleasePinning()\n        }\n    }\n\n    override fun recordModified(state: StateObject) {\n        reportReadonlySnapshotWrite()\n    }\n}\n\ninternal class NestedReadonlySnapshot(\n    snapshotId: SnapshotId,\n    invalid: SnapshotIdSet,\n    override val readObserver: ((Any) -> Unit)?,\n    val parent: Snapshot,\n) : Snapshot(snapshotId, invalid) {\n    init {\n        parent.nestedActivated(this)\n    }\n\n    override val readOnly\n        get() = true\n\n    override val root: Snapshot\n        get() = parent.root\n\n    @OptIn(ExperimentalComposeRuntimeApi::class)\n    override fun takeNestedSnapshot(readObserver: ((Any) -> Unit)?) =\n        creatingSnapshot(\n            parent = this,\n            readObserver = readObserver,\n            writeObserver = null,\n            readonly = true,\n        ) { actualReadObserver, _ ->\n            NestedReadonlySnapshot(\n                snapshotId = snapshotId,\n                invalid = invalid,\n                readObserver = mergedReadObserver(actualReadObserver, this.readObserver),\n                parent = parent,\n            )\n        }\n\n    override fun notifyObjectsInitialized() {\n        // Nothing to do for read-only snapshots\n    }\n\n    override fun hasPendingChanges(): Boolean = false\n\n    override fun dispose() {\n        if (!disposed) {\n            if (snapshotId != parent.snapshotId) {\n                closeAndReleasePinning()\n            }\n            parent.nestedDeactivated(this)\n            super.dispose()\n            dispatchObserverOnPreDispose(this)\n        }\n    }\n\n    override val modified: MutableScatterSet<StateObject>?\n        get() = null\n\n    override val writeObserver: ((Any) -> Unit)?\n        get() = null\n\n    override fun recordModified(state: StateObject) = reportReadonlySnapshotWrite()\n\n    override fun nestedDeactivated(snapshot: Snapshot) = unsupported()\n\n    override fun nestedActivated(snapshot: Snapshot) = unsupported()\n}\n\nprivate val emptyLambda: (invalid: SnapshotIdSet) -> Unit = {}\n\n/**\n * A snapshot object that simplifies the code by treating the global state as a mutable snapshot.\n */\ninternal class GlobalSnapshot(snapshotId: SnapshotId, invalid: SnapshotIdSet) :\n    MutableSnapshot(\n        snapshotId,\n        invalid,\n        null,\n        { state -> sync { globalWriteObservers.fastForEach { it(state) } } },\n    ) {\n\n    @OptIn(ExperimentalComposeRuntimeApi::class)\n    override fun takeNestedSnapshot(readObserver: ((Any) -> Unit)?): Snapshot =\n        creatingSnapshot(\n            parent = null,\n            readonly = true,\n            readObserver = readObserver,\n            writeObserver = null,\n        ) { actualReadObserver, _ ->\n            takeNewSnapshot { invalid ->\n                ReadonlySnapshot(\n                    snapshotId = sync { nextSnapshotId.also { nextSnapshotId += 1 } },\n                    invalid = invalid,\n                    readObserver = actualReadObserver,\n                )\n            }\n        }\n\n    @OptIn(ExperimentalComposeRuntimeApi::class)\n    override fun takeNestedMutableSnapshot(\n        readObserver: ((Any) -> Unit)?,\n        writeObserver: ((Any) -> Unit)?,\n    ): MutableSnapshot =\n        creatingSnapshot(\n            parent = null,\n            readonly = false,\n            readObserver = readObserver,\n            writeObserver = writeObserver,\n        ) { actualReadObserver, actualWriteObserver ->\n            takeNewSnapshot { invalid ->\n                MutableSnapshot(\n                    snapshotId = sync { nextSnapshotId.also { nextSnapshotId += 1 } },\n                    invalid = invalid,\n\n                    // It is intentional that the global read observers are not merged with mutable\n                    // snapshots read observers.\n                    readObserver = actualReadObserver,\n\n                    // It is intentional that global write observers are not merged with mutable\n                    // snapshots write observers.\n                    writeObserver = actualWriteObserver,\n                )\n            }\n        }\n\n    override fun notifyObjectsInitialized() {\n        advanceGlobalSnapshot()\n    }\n\n    override fun nestedDeactivated(snapshot: Snapshot) = unsupported()\n\n    override fun nestedActivated(snapshot: Snapshot) = unsupported()\n\n    override fun apply(): SnapshotApplyResult =\n        error(\"Cannot apply the global snapshot directly. Call Snapshot.advanceGlobalSnapshot\")\n\n    override fun dispose() {\n        sync { releasePinnedSnapshotLocked() }\n    }\n}\n\n/** A nested mutable snapshot created by [MutableSnapshot.takeNestedMutableSnapshot]. */\ninternal class NestedMutableSnapshot(\n    snapshotId: SnapshotId,\n    invalid: SnapshotIdSet,\n    readObserver: ((Any) -> Unit)?,\n    writeObserver: ((Any) -> Unit)?,\n    val parent: MutableSnapshot,\n) : MutableSnapshot(snapshotId, invalid, readObserver, writeObserver) {\n    private var deactivated = false\n\n    init {\n        parent.nestedActivated(this)\n    }\n\n    override val root: Snapshot\n        get() = parent.root\n\n    override fun dispose() {\n        if (!disposed) {\n            super.dispose()\n            deactivate()\n        }\n    }\n\n    override fun apply(): SnapshotApplyResult {\n        if (parent.applied || parent.disposed) return SnapshotApplyResult.Failure(this)\n\n        // Applying a nested mutable snapshot applies its changes to the parent snapshot.\n\n        // See MutableSnapshot.apply() for implantation notes.\n\n        // The apply observer notification are for applying to the global scope so it is elided\n        // here making this code a bit simpler than MutableSnapshot.apply.\n\n        val modified = modified\n        val id = snapshotId\n        val optimisticMerges =\n            if (modified != null) optimisticMerges(parent.snapshotId, this, parent.invalid)\n            else null\n        sync {\n            validateOpen(this)\n            if (modified == null || modified.size == 0) {\n                closeAndReleasePinning()\n            } else {\n                val result =\n                    innerApplyLocked(parent.snapshotId, modified, optimisticMerges, parent.invalid)\n                if (result != SnapshotApplyResult.Success) return result\n\n                parent.modified?.apply { addAll(modified) }\n                    ?: modified.also {\n                        // Ensure modified reference is only used by one snapshot\n                        parent.modified = it\n                        this.modified = null\n                    }\n            }\n\n            // Ensure the parent is newer than the current snapshot\n            if (parent.snapshotId < id) {\n                parent.advance()\n            }\n\n            // Make the snapshot visible in the parent snapshot\n            parent.invalid = parent.invalid.clear(id).andNot(previousIds)\n\n            // Ensure the ids associated with this snapshot are also applied by the parent.\n            parent.recordPrevious(id)\n            parent.recordPreviousPinnedSnapshot(takeoverPinnedSnapshot())\n            parent.recordPreviousList(previousIds)\n            parent.recordPreviousPinnedSnapshots(previousPinnedSnapshots)\n        }\n\n        applied = true\n        deactivate()\n        dispatchObserverOnApplied(this, modified)\n        return SnapshotApplyResult.Success\n    }\n\n    private fun deactivate() {\n        if (!deactivated) {\n            deactivated = true\n            parent.nestedDeactivated(this)\n        }\n    }\n}\n\n/** A pseudo snapshot that doesn't introduce isolation but does introduce observers. */\ninternal class TransparentObserverMutableSnapshot(\n    private val parentSnapshot: MutableSnapshot?,\n    specifiedReadObserver: ((Any) -> Unit)?,\n    specifiedWriteObserver: ((Any) -> Unit)?,\n    private val mergeParentObservers: Boolean,\n    private val ownsParentSnapshot: Boolean,\n) :\n    MutableSnapshot(\n        INVALID_SNAPSHOT,\n        SnapshotIdSet.EMPTY,\n        mergedReadObserver(\n            specifiedReadObserver,\n            parentSnapshot?.readObserver ?: globalSnapshot.readObserver,\n            mergeParentObservers,\n        ),\n        mergedWriteObserver(\n            specifiedWriteObserver,\n            parentSnapshot?.writeObserver ?: globalSnapshot.writeObserver,\n        ),\n    ) {\n    override var readObserver: ((Any) -> Unit)? = super.readObserver\n    override var writeObserver: ((Any) -> Unit)? = super.writeObserver\n\n    internal val threadId: Long = currentThreadId()\n\n    private val currentSnapshot: MutableSnapshot\n        get() = parentSnapshot ?: globalSnapshot\n\n    override fun dispose() {\n        // Explicitly don't call super.dispose()\n        disposed = true\n        if (ownsParentSnapshot) {\n            parentSnapshot?.dispose()\n        }\n    }\n\n    override var snapshotId: SnapshotId\n        get() = currentSnapshot.snapshotId\n        @Suppress(\"UNUSED_PARAMETER\")\n        set(value) {\n            unsupported()\n        }\n\n    override var invalid\n        get() = currentSnapshot.invalid\n        @Suppress(\"UNUSED_PARAMETER\") set(value) = unsupported()\n\n    override fun hasPendingChanges(): Boolean = currentSnapshot.hasPendingChanges()\n\n    override var modified: MutableScatterSet<StateObject>?\n        get() = currentSnapshot.modified\n        @Suppress(\"UNUSED_PARAMETER\") set(value) = unsupported()\n\n    override var writeCount: Int\n        get() = currentSnapshot.writeCount\n        set(value) {\n            currentSnapshot.writeCount = value\n        }\n\n    override val readOnly: Boolean\n        get() = currentSnapshot.readOnly\n\n    override fun apply(): SnapshotApplyResult = currentSnapshot.apply()\n\n    override fun recordModified(state: StateObject) = currentSnapshot.recordModified(state)\n\n    override fun takeNestedSnapshot(readObserver: ((Any) -> Unit)?): Snapshot {\n        val mergedReadObserver = mergedReadObserver(readObserver, this.readObserver)\n        return if (!mergeParentObservers) {\n            createTransparentSnapshotWithNoParentReadObserver(\n                previousSnapshot = currentSnapshot.takeNestedSnapshot(null),\n                readObserver = mergedReadObserver,\n                ownsPreviousSnapshot = true,\n            )\n        } else {\n            currentSnapshot.takeNestedSnapshot(mergedReadObserver)\n        }\n    }\n\n    override fun takeNestedMutableSnapshot(\n        readObserver: ((Any) -> Unit)?,\n        writeObserver: ((Any) -> Unit)?,\n    ): MutableSnapshot {\n        val mergedReadObserver = mergedReadObserver(readObserver, this.readObserver)\n        val mergedWriteObserver = mergedWriteObserver(writeObserver, this.writeObserver)\n        return if (!mergeParentObservers) {\n            val nestedSnapshot =\n                currentSnapshot.takeNestedMutableSnapshot(\n                    readObserver = null,\n                    writeObserver = mergedWriteObserver,\n                )\n            TransparentObserverMutableSnapshot(\n                parentSnapshot = nestedSnapshot,\n                specifiedReadObserver = mergedReadObserver,\n                specifiedWriteObserver = mergedWriteObserver,\n                mergeParentObservers = false,\n                ownsParentSnapshot = true,\n            )\n        } else {\n            currentSnapshot.takeNestedMutableSnapshot(mergedReadObserver, mergedWriteObserver)\n        }\n    }\n\n    override fun notifyObjectsInitialized() = currentSnapshot.notifyObjectsInitialized()\n\n    /** Should never be called. */\n    override fun nestedActivated(snapshot: Snapshot) = unsupported()\n\n    override fun nestedDeactivated(snapshot: Snapshot) = unsupported()\n}\n\n/** A pseudo snapshot that doesn't introduce isolation but does introduce observers. */\ninternal class TransparentObserverSnapshot(\n    private val parentSnapshot: Snapshot?,\n    specifiedReadObserver: ((Any) -> Unit)?,\n    private val mergeParentObservers: Boolean,\n    private val ownsParentSnapshot: Boolean,\n) : Snapshot(INVALID_SNAPSHOT, SnapshotIdSet.EMPTY) {\n    override var readObserver: ((Any) -> Unit)? =\n        mergedReadObserver(\n            specifiedReadObserver,\n            parentSnapshot?.readObserver ?: globalSnapshot.readObserver,\n            mergeParentObservers,\n        )\n    override val writeObserver: ((Any) -> Unit)? = null\n\n    internal val threadId: Long = currentThreadId()\n\n    override val root: Snapshot = this\n\n    private val currentSnapshot: Snapshot\n        get() = parentSnapshot ?: globalSnapshot\n\n    override fun dispose() {\n        // Explicitly don't call super.dispose()\n        disposed = true\n        if (ownsParentSnapshot) {\n            parentSnapshot?.dispose()\n        }\n    }\n\n    override var snapshotId: SnapshotId\n        get() = currentSnapshot.snapshotId\n        @Suppress(\"UNUSED_PARAMETER\")\n        set(value) {\n            unsupported()\n        }\n\n    override var invalid\n        get() = currentSnapshot.invalid\n        @Suppress(\"UNUSED_PARAMETER\") set(value) = unsupported()\n\n    override fun hasPendingChanges(): Boolean = currentSnapshot.hasPendingChanges()\n\n    override var modified: MutableScatterSet<StateObject>?\n        get() = currentSnapshot.modified\n        @Suppress(\"UNUSED_PARAMETER\") set(value) = unsupported()\n\n    override val readOnly: Boolean\n        get() = currentSnapshot.readOnly\n\n    override fun recordModified(state: StateObject) = currentSnapshot.recordModified(state)\n\n    override fun takeNestedSnapshot(readObserver: ((Any) -> Unit)?): Snapshot {\n        val mergedReadObserver = mergedReadObserver(readObserver, this.readObserver)\n        return if (!mergeParentObservers) {\n            createTransparentSnapshotWithNoParentReadObserver(\n                currentSnapshot.takeNestedSnapshot(null),\n                mergedReadObserver,\n                ownsPreviousSnapshot = true,\n            )\n        } else {\n            currentSnapshot.takeNestedSnapshot(mergedReadObserver)\n        }\n    }\n\n    override fun notifyObjectsInitialized() = currentSnapshot.notifyObjectsInitialized()\n\n    /** Should never be called. */\n    override fun nestedActivated(snapshot: Snapshot) = unsupported()\n\n    override fun nestedDeactivated(snapshot: Snapshot) = unsupported()\n}\n\nprivate fun createTransparentSnapshotWithNoParentReadObserver(\n    previousSnapshot: Snapshot?,\n    readObserver: ((Any) -> Unit)? = null,\n    ownsPreviousSnapshot: Boolean = false,\n): Snapshot =\n    if (previousSnapshot is MutableSnapshot || previousSnapshot == null) {\n        TransparentObserverMutableSnapshot(\n            parentSnapshot = previousSnapshot as? MutableSnapshot,\n            specifiedReadObserver = readObserver,\n            specifiedWriteObserver = null,\n            mergeParentObservers = false,\n            ownsParentSnapshot = ownsPreviousSnapshot,\n        )\n    } else {\n        TransparentObserverSnapshot(\n            parentSnapshot = previousSnapshot,\n            specifiedReadObserver = readObserver,\n            mergeParentObservers = false,\n            ownsParentSnapshot = ownsPreviousSnapshot,\n        )\n    }\n\ninternal fun mergedReadObserver(\n    readObserver: ((Any) -> Unit)?,\n    parentObserver: ((Any) -> Unit)?,\n    mergeReadObserver: Boolean = true,\n): ((Any) -> Unit)? {\n    @Suppress(\"NAME_SHADOWING\") val parentObserver = if (mergeReadObserver) parentObserver else null\n    return if (readObserver != null && parentObserver != null && readObserver !== parentObserver) {\n        { state: Any ->\n            readObserver(state)\n            parentObserver(state)\n        }\n    } else readObserver ?: parentObserver\n}\n\ninternal fun mergedWriteObserver(\n    writeObserver: ((Any) -> Unit)?,\n    parentObserver: ((Any) -> Unit)?,\n): ((Any) -> Unit)? =\n    if (writeObserver != null && parentObserver != null && writeObserver !== parentObserver) {\n        { state: Any ->\n            writeObserver(state)\n            parentObserver(state)\n        }\n    } else writeObserver ?: parentObserver\n\n/**\n * Snapshot id of `0` is reserved as invalid and no state record with snapshot `0` is considered\n * valid.\n *\n * The value `0` was chosen as it is the default value of the Int snapshot id type and records\n * initially created will naturally have a snapshot id of 0. If this wasn't considered invalid\n * adding such a record to a state object will make the state record immediately visible to the\n * snapshots instead of being born invalid. Using `0` ensures all state records are created invalid\n * and must be explicitly marked as valid in to be visible in a snapshot.\n */\nprivate val INVALID_SNAPSHOT = SnapshotIdZero\n\n/** Current thread snapshot */\nprivate val threadSnapshot = SnapshotThreadLocal<Snapshot>()\n\n/**\n * A global synchronization object. This synchronization object should be taken before modifying any\n * of the fields below.\n */\n@PublishedApi internal val lock: SynchronizedObject = makeSynchronizedObject()\n\n@Suppress(\"BanInlineOptIn\", \"LEAKED_IN_PLACE_LAMBDA\", \"WRONG_INVOCATION_KIND\")\n@OptIn(ExperimentalContracts::class)\n@PublishedApi\ninternal inline fun <T> sync(block: () -> T): T {\n    contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }\n    return synchronized(lock, block)\n}\n\n// The following variables should only be written when sync is taken\n\n/**\n * A set of snapshots that are currently open and should be considered invalid for new snapshots.\n */\nprivate var openSnapshots = SnapshotIdSet.EMPTY\n\n/** The first snapshot created must be at least on more than the [Snapshot.PreexistingSnapshotId] */\nprivate var nextSnapshotId = Snapshot.PreexistingSnapshotId.toSnapshotId() + 1\n\n/**\n * A tracking table for pinned snapshots. A pinned snapshot is the lowest snapshot id that the\n * snapshot is ignoring by considering them invalid. This is used to calculate when a snapshot\n * record can be reused.\n */\nprivate val pinningTable = SnapshotDoubleIndexHeap()\n\n/**\n * The set of objects who have more than one active state record. These are traversed during apply\n * of mutable snapshots and when the global snapshot is advanced to determine if any of the records\n * can be cleared.\n */\nprivate val extraStateObjects = SnapshotWeakSet<StateObject>()\n\n/** A list of apply observers */\nprivate var applyObservers = emptyList<(Set<Any>, Snapshot) -> Unit>()\n\n/** A list of observers of writes to the global state. */\nprivate var globalWriteObservers = emptyList<(Any) -> Unit>()\n\nprivate val globalSnapshot =\n    GlobalSnapshot(\n            snapshotId = nextSnapshotId.also { nextSnapshotId += 1 },\n            invalid = SnapshotIdSet.EMPTY,\n        )\n        .also { openSnapshots = openSnapshots.set(it.snapshotId) }\n\n// Unused, kept for API compat\n@Suppress(\"unused\") @PublishedApi internal val snapshotInitializer: Snapshot = globalSnapshot\n\nprivate fun <T> resetGlobalSnapshotLocked(\n    globalSnapshot: GlobalSnapshot,\n    block: (invalid: SnapshotIdSet) -> T,\n): T {\n    val snapshotId = globalSnapshot.snapshotId\n    val result = block(openSnapshots.clear(snapshotId))\n\n    val nextGlobalSnapshotId = nextSnapshotId\n    nextSnapshotId += 1\n\n    openSnapshots = openSnapshots.clear(snapshotId)\n    globalSnapshot.snapshotId = nextGlobalSnapshotId\n    globalSnapshot.invalid = openSnapshots\n    globalSnapshot.writeCount = 0\n    globalSnapshot.modified = null\n    globalSnapshot.releasePinnedSnapshotLocked()\n    openSnapshots = openSnapshots.set(nextGlobalSnapshotId)\n\n    return result\n}\n\n/**\n * Counts the number of threads currently inside `advanceGlobalSnapshot`, notifying observers of\n * changes to the global snapshot.\n */\nprivate var pendingApplyObserverCount = AtomicInt(0)\n\nprivate fun <T> advanceGlobalSnapshot(block: (invalid: SnapshotIdSet) -> T): T {\n    val globalSnapshot = globalSnapshot\n\n    val modified: MutableScatterSet<StateObject>?\n    val result = sync {\n        modified = globalSnapshot.modified\n        if (modified != null) {\n            pendingApplyObserverCount.add(1)\n        }\n        resetGlobalSnapshotLocked(globalSnapshot, block)\n    }\n\n    // If the previous global snapshot had any modified states then notify the registered apply\n    // observers.\n    modified?.let {\n        try {\n            val observers = applyObservers\n            val modifiedSet = it.wrapIntoSet()\n            verboseTrace(\"Compose:applyObservers\") {\n                observers.fastForEach { observer -> observer(modifiedSet, globalSnapshot) }\n            }\n        } finally {\n            pendingApplyObserverCount.add(-1)\n        }\n    }\n\n    sync {\n        checkAndOverwriteUnusedRecordsLocked()\n        modified?.forEach { processForUnusedRecordsLocked(it) }\n    }\n\n    return result\n}\n\nprivate fun advanceGlobalSnapshot() = advanceGlobalSnapshot(emptyLambda)\n\nprivate fun <T : Snapshot> takeNewSnapshot(block: (invalid: SnapshotIdSet) -> T): T =\n    advanceGlobalSnapshot { invalid ->\n        val result = block(invalid)\n        sync { openSnapshots = openSnapshots.set(result.snapshotId) }\n        result\n    }\n\nprivate fun validateOpen(snapshot: Snapshot) {\n    val openSnapshots = openSnapshots\n    if (!openSnapshots.get(snapshot.snapshotId)) {\n        error(\n            \"Snapshot is not open: snapshotId=${\n                snapshot.snapshotId\n            }, disposed=${\n                snapshot.disposed\n            }, applied=${\n                (snapshot as? MutableSnapshot)?.applied ?: \"read-only\"\n            }, lowestPin=${\n                sync { pinningTable.lowestOrDefault(SnapshotIdInvalidValue) }\n            }\"\n        )\n    }\n}\n\n/**\n * A candidate snapshot is valid if the it is less than or equal to the current snapshot and it\n * wasn't specifically marked as invalid when the snapshot started.\n *\n * All snapshot active at when the snapshot was taken considered invalid for the snapshot (they have\n * not been applied and therefore are considered invalid).\n *\n * All snapshots taken after the current snapshot are considered invalid since they where taken\n * after the current snapshot was taken.\n *\n * INVALID_SNAPSHOT is reserved as an invalid snapshot id.\n */\nprivate fun valid(\n    currentSnapshot: SnapshotId,\n    candidateSnapshot: SnapshotId,\n    invalid: SnapshotIdSet,\n): Boolean {\n    return candidateSnapshot != INVALID_SNAPSHOT &&\n        candidateSnapshot <= currentSnapshot &&\n        !invalid.get(candidateSnapshot)\n}\n\n// Determine if the given data is valid for the snapshot.\nprivate fun valid(data: StateRecord, snapshot: SnapshotId, invalid: SnapshotIdSet): Boolean {\n    return valid(snapshot, data.snapshotId, invalid)\n}\n\nprivate fun <T : StateRecord> readable(r: T, id: SnapshotId, invalid: SnapshotIdSet): T? {\n    // The readable record is the valid record with the highest snapshotId\n    var current: StateRecord? = r\n    var candidate: StateRecord? = null\n    while (current != null) {\n        if (valid(current, id, invalid)) {\n            candidate =\n                if (candidate == null) current\n                else if (candidate.snapshotId < current.snapshotId) current else candidate\n        }\n        current = current.next\n    }\n    if (candidate != null) {\n        @Suppress(\"UNCHECKED_CAST\")\n        return candidate as T\n    }\n    return null\n}\n\n/**\n * Return the current readable state record for the current snapshot. It is assumed that [this] is\n * the first record of [state]\n */\npublic fun <T : StateRecord> T.readable(state: StateObject): T {\n    val snapshot = Snapshot.current\n    snapshot.readObserver?.invoke(state)\n    return readable(this, snapshot.snapshotId, snapshot.invalid)\n        ?: sync {\n            // Readable can return null when the global snapshot has been advanced by another thread\n            // and state written to the object was overwritten while this thread was paused.\n            // Repeating the read is valid here as either this will return the same result as\n            // the previous call or will find a valid record. Being in a sync block prevents other\n            // threads from writing to this state object until the read completes.\n            val syncSnapshot = Snapshot.current\n            @Suppress(\"UNCHECKED_CAST\")\n            readable(state.firstStateRecord as T, syncSnapshot.snapshotId, syncSnapshot.invalid)\n                ?: readError()\n        }\n}\n\n// unused, still here for API compat.\n/**\n * Return the current readable state record for the [snapshot]. It is assumed that [this] is the\n * first record of [state]\n */\npublic fun <T : StateRecord> T.readable(state: StateObject, snapshot: Snapshot): T {\n    // invoke the observer associated with the current snapshot.\n    snapshot.readObserver?.invoke(state)\n    return readable(this, snapshot.snapshotId, snapshot.invalid)\n        ?: sync {\n            // Readable can return null when the global snapshot has been advanced by another thread\n            // See T.readable(state: StateObject) for more info.\n            val syncSnapshot = Snapshot.current\n            @Suppress(\"UNCHECKED_CAST\")\n            readable(state.firstStateRecord as T, syncSnapshot.snapshotId, syncSnapshot.invalid)\n                ?: readError()\n        }\n}\n\nprivate fun readError(): Nothing {\n    error(\n        \"Reading a state that was created after the snapshot was taken or in a snapshot that \" +\n            \"has not yet been applied\"\n    )\n}\n\n/**\n * A record can be reused if no other snapshot will see it as valid. This is always true for a\n * record created in an abandoned snapshot. It is also true if the record is valid in the previous\n * snapshot and is obscured by another record also valid in the previous state record.\n */\nprivate fun usedLocked(state: StateObject): StateRecord? {\n    var current: StateRecord? = state.firstStateRecord\n    var validRecord: StateRecord? = null\n    val reuseLimit = pinningTable.lowestOrDefault(nextSnapshotId) - 1\n    val invalid = SnapshotIdSet.EMPTY\n    while (current != null) {\n        val currentId = current.snapshotId\n        if (currentId == INVALID_SNAPSHOT) {\n            // Any records that were marked invalid by an abandoned snapshot or is marked reachable\n            // can be used immediately.\n            return current\n        }\n        if (valid(current, reuseLimit, invalid)) {\n            if (validRecord == null) {\n                validRecord = current\n            } else {\n                // If we have two valid records one must obscure the other. Return the\n                // record with the lowest id\n                return if (current.snapshotId < validRecord.snapshotId) current else validRecord\n            }\n        }\n        current = current.next\n    }\n    return null\n}\n\n/**\n * Clear records that cannot be selected in any currently open snapshot.\n *\n * This method uses the same technique as [usedLocked] which uses the [pinningTable] to determine\n * lowest id in the invalid set for all snapshots. Only the record with the greatest id of all\n * records less or equal to this lowest id can possibly be selected in any snapshot and all other\n * records below that number can be overwritten.\n *\n * However, this technique doesn't find all records that will not be selected by any open snapshot\n * as a record that has an id above that number could be reusable but will not be found.\n *\n * For example if snapshot 1 is open and 2 is created and modifies [state] then is applied, 3 is\n * open and then 4 is open, and then 1 is applied. When 3 modifies [state] and then applies, as 1 is\n * pinned by 4, it is uncertain whether the record for 2 is needed by 4 so it must be kept even if 4\n * also modified [state] and would not select 2. Accurately determine if a record is selectable\n * would require keeping a list of all open [Snapshot] instances which currently is not kept and\n * traversing that list for each record.\n *\n * If any such records are possible this method returns true. In other words, this method returns\n * true if any records might be reusable but this function could not prove there were or not.\n */\nprivate fun overwriteUnusedRecordsLocked(state: StateObject): Boolean {\n    var current: StateRecord? = state.firstStateRecord\n    var overwriteRecord: StateRecord? = null\n    var validRecord: StateRecord? = null\n    val reuseLimit = pinningTable.lowestOrDefault(nextSnapshotId)\n    var retainedRecords = 0\n\n    while (current != null) {\n        val currentId = current.snapshotId\n        if (currentId != INVALID_SNAPSHOT) {\n            if (currentId < reuseLimit) {\n                if (validRecord == null) {\n                    // If any records are below [reuseLimit] then we must keep the highest one\n                    // so the lowest snapshot can select it.\n                    validRecord = current\n                    retainedRecords++\n                } else {\n                    // If [validRecord] is from an earlier snapshot, overwrite it instead\n                    val recordToOverwrite =\n                        if (current.snapshotId < validRecord.snapshotId) {\n                            current\n                        } else {\n                            // We cannot use `.also { }` here as it prevents smart casting of other\n                            // uses of [validRecord].\n                            val result = validRecord\n                            validRecord = current\n                            result\n                        }\n                    if (overwriteRecord == null) {\n                        // Find a record we will definitely keep\n                        overwriteRecord =\n                            state.firstStateRecord.findYoungestOr { it.snapshotId >= reuseLimit }\n                    }\n                    recordToOverwrite.snapshotId = INVALID_SNAPSHOT\n                    recordToOverwrite.assign(overwriteRecord)\n                }\n            } else {\n                retainedRecords++\n            }\n        }\n        current = current.next\n    }\n\n    return retainedRecords > 1\n}\n\nprivate inline fun StateRecord.findYoungestOr(predicate: (StateRecord) -> Boolean): StateRecord {\n    var current: StateRecord? = this\n    var youngest = this\n    while (current != null) {\n        if (predicate(current)) return current\n        if (youngest.snapshotId < current.snapshotId) youngest = current\n        current = current.next\n    }\n    return youngest\n}\n\nprivate fun checkAndOverwriteUnusedRecordsLocked() {\n    extraStateObjects.removeIf { !overwriteUnusedRecordsLocked(it) }\n}\n\nprivate fun processForUnusedRecordsLocked(state: StateObject) {\n    if (overwriteUnusedRecordsLocked(state)) {\n        extraStateObjects.add(state)\n    }\n}\n\n@PublishedApi\ninternal fun <T : StateRecord> T.writableRecord(state: StateObject, snapshot: Snapshot): T {\n    if (snapshot.readOnly) {\n        // If the snapshot is read-only, use the snapshot recordModified to report it.\n        snapshot.recordModified(state)\n    }\n    val id = snapshot.snapshotId\n    val readData = readable(this, id, snapshot.invalid) ?: readError()\n\n    // If the readable data was born in this snapshot, it is writable.\n    if (readData.snapshotId == snapshot.snapshotId) return readData\n\n    // Otherwise, make a copy of the readable data and mark it as born in this snapshot, making it\n    // writable.\n    @Suppress(\"UNCHECKED_CAST\")\n    val newData =\n        sync {\n            // Verify that some other thread didn't already create this.\n            val newReadData = readable(state.firstStateRecord, id, snapshot.invalid) ?: readError()\n            if (newReadData.snapshotId == id) newReadData\n            else newReadData.newWritableRecordLocked(state, snapshot)\n        }\n            as T\n\n    if (readData.snapshotId != Snapshot.PreexistingSnapshotId.toSnapshotId()) {\n        snapshot.recordModified(state)\n    }\n\n    return newData\n}\n\ninternal fun <T : StateRecord> T.overwritableRecord(\n    state: StateObject,\n    snapshot: Snapshot,\n    candidate: T,\n): T {\n    if (snapshot.readOnly) {\n        // If the snapshot is read-only, use the snapshot recordModified to report it.\n        snapshot.recordModified(state)\n    }\n    val id = snapshot.snapshotId\n\n    if (candidate.snapshotId == id) return candidate\n\n    val newData = sync { newOverwritableRecordLocked(state) }\n    newData.snapshotId = id\n\n    if (candidate.snapshotId != Snapshot.PreexistingSnapshotId.toSnapshotId()) {\n        snapshot.recordModified(state)\n    }\n\n    return newData\n}\n\ninternal fun <T : StateRecord> T.newWritableRecord(state: StateObject, snapshot: Snapshot) = sync {\n    newWritableRecordLocked(state, snapshot)\n}\n\nprivate fun <T : StateRecord> T.newWritableRecordLocked(state: StateObject, snapshot: Snapshot): T {\n    // Calling used() on a state object might return the same record for each thread calling\n    // used() therefore selecting the record to reuse should be guarded.\n\n    // Note: setting the snapshotId to Int.MAX_VALUE will make it invalid for all snapshots.\n    // This means the lock can be released as used() will no longer select it. Using id could\n    // also be used but it puts the object into a state where the reused value appears to be\n    // the current valid value for the snapshot. This is not an issue if the snapshot is only\n    // being read from a single thread but using Int.MAX_VALUE allows multiple readers,\n    // single writer, of a snapshot. Note that threads reading a mutating snapshot should not\n    // cache the result of readable() as the mutating thread calls to writable() can change the\n    // result of readable().\n    val newData = newOverwritableRecordLocked(state)\n    newData.assign(this)\n    newData.snapshotId = snapshot.snapshotId\n    return newData\n}\n\ninternal fun <T : StateRecord> T.newOverwritableRecordLocked(state: StateObject): T {\n    // Calling used() on a state object might return the same record for each thread calling\n    // used() therefore selecting the record to reuse should be guarded.\n\n    // Note: setting the snapshotId to Int.MAX_VALUE will make it invalid for all snapshots.\n    // This means the lock can be released as used() will no longer select it. Using id could\n    // also be used but it puts the object into a state where the reused value appears to be\n    // the current valid value for the snapshot. This is not an issue if the snapshot is only\n    // being read from a single thread but using Int.MAX_VALUE allows multiple readers,\n    // single writer, of a snapshot. Note that threads reading a mutating snapshot should not\n    // cache the result of readable() as the mutating thread calls to writable() can change the\n    // result of readable().\n    @Suppress(\"UNCHECKED_CAST\")\n    return (usedLocked(state) as T?)?.apply { snapshotId = SnapshotIdMax }\n        ?: create(SnapshotIdMax).apply {\n            this.next = state.firstStateRecord\n            state.prependStateRecord(this as T)\n        } as T\n}\n\n@PublishedApi\ninternal fun notifyWrite(snapshot: Snapshot, state: StateObject) {\n    snapshot.writeCount += 1\n    snapshot.writeObserver?.invoke(state)\n}\n\n/**\n * Call [block] with a writable state record for [snapshot] of the given record. It is assumed that\n * this is called for the first state record in a state object. If the snapshot is read-only calling\n * this will throw.\n */\npublic inline fun <T : StateRecord, R> T.writable(\n    state: StateObject,\n    snapshot: Snapshot,\n    block: T.() -> R,\n): R {\n    // A writable record will always be the readable record (as all newer records are invalid it\n    // must be the newest valid record). This means that if the readable record is not from the\n    // current snapshot, a new record must be created. To create a new writable record, a record\n    // can be reused, if possible, and the readable record is applied to it. If a record cannot\n    // be reused, a new record is created and the readable record is applied to it. Once the\n    // values are correct the record is made live by giving it the current snapshot id.\n\n    // Writes need to be in a `sync` block as all writes in flight must be completed before a new\n    // snapshot is take. Writing in a sync block ensures this is the case because new snapshots\n    // are also in a sync block.\n    return sync { this.writableRecord(state, snapshot).block() }\n        .also { notifyWrite(snapshot, state) }\n}\n\n/**\n * Call [block] with a writable state record for the given record. It is assumed that this is called\n * for the first state record in a state object. A record is writable if it was created in the\n * current mutable snapshot.\n */\npublic inline fun <T : StateRecord, R> T.writable(state: StateObject, block: T.() -> R): R {\n    val snapshot: Snapshot\n    return sync {\n            snapshot = Snapshot.current\n            this.writableRecord(state, snapshot).block()\n        }\n        .also { notifyWrite(snapshot, state) }\n}\n\n/**\n * Call [block] with a writable state record for the given record. It is assumed that this is called\n * for the first state record in a state object. A record is writable if it was created in the\n * current mutable snapshot. This should only be used when the record will be overwritten in its\n * entirety (such as having only one field and that field is written to).\n *\n * WARNING: If the caller doesn't overwrite all the fields in the state record the object will be\n * inconsistent and the fields not written are almost guaranteed to be incorrect. If it is possible\n * that [block] will not write to all the fields use [writable] instead.\n *\n * @param state The object that has this record in its record list.\n * @param candidate The current for the snapshot record returned by [withCurrent]\n * @param block The block that will mutate all the field of the record.\n */\ninternal inline fun <T : StateRecord, R> T.overwritable(\n    state: StateObject,\n    candidate: T,\n    block: T.() -> R,\n): R {\n    val snapshot: Snapshot\n    return sync {\n            snapshot = Snapshot.current\n            this.overwritableRecord(state, snapshot, candidate).block()\n        }\n        .also { notifyWrite(snapshot, state) }\n}\n\n/**\n * Produce a set of optimistic merges of the state records, this is performed outside the a\n * synchronization block to reduce the amount of time taken in the synchronization block reducing\n * the thread contention of merging state values.\n *\n * How sets and ids are used to determine a merged record is explained in\n * [MutableSnapshot.innerApplyLocked].\n *\n * @see MutableSnapshot.innerApplyLocked\n */\nprivate fun optimisticMerges(\n    currentSnapshotId: SnapshotId,\n    applyingSnapshot: MutableSnapshot,\n    invalidSnapshots: SnapshotIdSet,\n): Map<StateRecord, StateRecord>? {\n    val modified = applyingSnapshot.modified\n    if (modified == null) return null\n    val applyingSnapshotId = applyingSnapshot.snapshotId\n    val start = applyingSnapshot.invalid.set(applyingSnapshotId).or(applyingSnapshot.previousIds)\n    var result: MutableMap<StateRecord, StateRecord>? = null\n    modified.forEach { state ->\n        val first = state.firstStateRecord\n        val current = readable(first, currentSnapshotId, invalidSnapshots) ?: return@forEach\n        val previous = readable(first, applyingSnapshotId, start) ?: return@forEach\n        if (current != previous) {\n            // Try to produce a merged state record\n            val applied =\n                readable(first, applyingSnapshotId, applyingSnapshot.invalid) ?: readError()\n            val merged = state.mergeRecords(previous, current, applied)\n            if (merged != null) {\n                (result ?: hashMapOf<StateRecord, StateRecord>().also { result = it })[current] =\n                    merged\n            } else {\n                // If one fails don't bother calculating the others as they are likely not going\n                // to be used. There is an unlikely case that a optimistic merge cannot be\n                // produced but the snapshot will apply because, once the synchronization is taken,\n                // the current state can be merge. This routine errors on the side of reduced\n                // overall work by not performing work that is likely to be ignored.\n                return null\n            }\n        }\n    }\n    return result\n}\n\nprivate fun reportReadonlySnapshotWrite(): Nothing {\n    error(\"Cannot modify a state object in a read-only snapshot\")\n}\n\n/** Returns the current record without notifying any read observers. */\n@PublishedApi\ninternal fun <T : StateRecord> current(r: T, snapshot: Snapshot): T =\n    readable(r, snapshot.snapshotId, snapshot.invalid)\n        ?: sync {\n            // Global snapshot could have been advanced\n            // see StateRecord.readable for more details\n            readable(r, snapshot.snapshotId, snapshot.invalid)\n        }\n        ?: readError()\n\n@PublishedApi\ninternal fun <T : StateRecord> current(r: T): T =\n    Snapshot.current.let { snapshot ->\n        readable(r, snapshot.snapshotId, snapshot.invalid)\n            ?: sync {\n                // Global snapshot could have been advanced\n                // see StateRecord.readable for more details\n                Snapshot.current.let { syncSnapshot ->\n                    readable(r, syncSnapshot.snapshotId, syncSnapshot.invalid)\n                }\n            }\n            ?: readError()\n    }\n\n/**\n * Provides a [block] with the current record, without notifying any read observers.\n *\n * @see readable\n */\npublic inline fun <T : StateRecord, R> T.withCurrent(block: (r: T) -> R): R = block(current(this))\n\n/** Helper routine to add a range of values ot a snapshot set */\ninternal fun SnapshotIdSet.addRange(from: SnapshotId, until: SnapshotId): SnapshotIdSet {\n    var result = this\n    var invalidId = from\n    while (invalidId < until) {\n        result = result.set(invalidId)\n        invalidId += 1\n    }\n    return result\n}\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotStateList.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.runtime.snapshots\n\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.external.kotlinx.collections.immutable.PersistentList\nimport androidx.compose.runtime.external.kotlinx.collections.immutable.persistentListOf\nimport androidx.compose.runtime.platform.makeSynchronizedObject\nimport androidx.compose.runtime.platform.synchronized\nimport androidx.compose.runtime.requirePrecondition\n\n/**\n * An implementation of [MutableList] that can be observed and snapshot. This is the result type\n * created by [androidx.compose.runtime.mutableStateListOf].\n *\n * This class closely implements the same semantics as [ArrayList].\n *\n * @see androidx.compose.runtime.mutableStateListOf\n */\n@Stable\npublic expect class SnapshotStateList<T> internal constructor(persistentList: PersistentList<T>) :\n    StateObject, MutableList<T>, RandomAccess {\n    public constructor()\n\n    override var firstStateRecord: StateRecord\n        private set\n\n    override fun prependStateRecord(value: StateRecord)\n\n    /**\n     * Return a list containing all the elements of this list.\n     *\n     * The list returned is immutable and returned will not change even if the content of the list\n     * is changed in the same snapshot. It also will be the same instance until the content is\n     * changed. It is not, however, guaranteed to be the same instance for the same list as adding\n     * and removing the same item from the this list might produce a different instance with the\n     * same content.\n     *\n     * This operation is O(1) and does not involve a physically copying the list. It instead returns\n     * the underlying immutable list used internally to store the content of the list.\n     *\n     * It is recommended to use [toList] when using returning the value of this list from\n     * [androidx.compose.runtime.snapshotFlow].\n     */\n    public fun toList(): List<T>\n\n    override val size: Int\n\n    override fun contains(element: T): Boolean\n\n    override fun containsAll(elements: Collection<T>): Boolean\n\n    override fun get(index: Int): T\n\n    override fun indexOf(element: T): Int\n\n    override fun isEmpty(): Boolean\n\n    override fun iterator(): MutableIterator<T>\n\n    override fun lastIndexOf(element: T): Int\n\n    override fun listIterator(): MutableListIterator<T>\n\n    override fun listIterator(index: Int): MutableListIterator<T>\n\n    override fun subList(fromIndex: Int, toIndex: Int): MutableList<T>\n\n    override fun add(element: T): Boolean\n\n    override fun add(index: Int, element: T)\n\n    override fun addAll(elements: Collection<T>): Boolean\n\n    override fun addAll(index: Int, elements: Collection<T>): Boolean\n\n    override fun clear()\n\n    override fun remove(element: T): Boolean\n\n    override fun removeAll(elements: Collection<T>): Boolean\n\n    override fun removeAt(index: Int): T\n\n    override fun retainAll(elements: Collection<T>): Boolean\n\n    override fun set(index: Int, element: T): T\n\n    public fun removeRange(fromIndex: Int, toIndex: Int)\n\n    internal fun retainAllInRange(elements: Collection<T>, start: Int, end: Int): Int\n}\n\ninternal inline fun <R, T> SnapshotStateList<T>.writable(\n    block: StateListStateRecord<T>.() -> R\n): R =\n    @Suppress(\"UNCHECKED_CAST\") (firstStateRecord as StateListStateRecord<T>).writable(this, block)\n\ninternal inline fun <R, T> SnapshotStateList<T>.withCurrent(\n    block: StateListStateRecord<T>.() -> R\n): R = @Suppress(\"UNCHECKED_CAST\") (firstStateRecord as StateListStateRecord<T>).withCurrent(block)\n\ninternal fun <T> SnapshotStateList<T>.mutateBoolean(block: (MutableList<T>) -> Boolean): Boolean =\n    mutate(block)\n\ninternal inline fun <R, T> SnapshotStateList<T>.mutate(block: (MutableList<T>) -> R): R {\n    var result: R\n    while (true) {\n        var oldList: PersistentList<T>? = null\n        var currentModification = 0\n        synchronized(sync) {\n            val current = withCurrent { this }\n            currentModification = current.modification\n            oldList = current.list\n        }\n        val builder = oldList!!.builder()\n        result = block(builder)\n        val newList = builder.build()\n        if (\n            newList == oldList ||\n                writable { attemptUpdate(currentModification, newList, structural = true) }\n        )\n            break\n    }\n    return result\n}\n\ninternal inline fun <T> SnapshotStateList<T>.update(\n    structural: Boolean = true,\n    block: (PersistentList<T>) -> PersistentList<T>,\n) {\n    conditionalUpdate(structural, block)\n}\n\n@Suppress(\"NOTHING_TO_INLINE\")\ninternal inline fun <T> SnapshotStateList<T>.clearImpl() {\n    writable {\n        synchronized(sync) {\n            list = persistentListOf()\n            modification++\n            structuralChange++\n        }\n    }\n}\n\ninternal inline fun <T> SnapshotStateList<T>.conditionalUpdate(\n    structural: Boolean = true,\n    block: (PersistentList<T>) -> PersistentList<T>,\n) = run {\n    val result: Boolean\n    while (true) {\n        var oldList: PersistentList<T>? = null\n        var currentModification = 0\n        synchronized(sync) {\n            val current = withCurrent { this }\n            currentModification = current.modification\n            oldList = current.list\n        }\n        val newList = block(oldList!!)\n        if (newList == oldList) {\n            result = false\n            break\n        }\n        if (writable { attemptUpdate(currentModification, newList, structural) }) {\n            result = true\n            break\n        }\n    }\n    result\n}\n\n// NOTE: do not inline this method to avoid class verification failures, see b/369909868\ninternal fun <T> StateListStateRecord<T>.attemptUpdate(\n    currentModification: Int,\n    newList: PersistentList<T>,\n    structural: Boolean,\n): Boolean =\n    synchronized(sync) {\n        if (modification == currentModification) {\n            list = newList\n            if (structural) structuralChange++\n            modification++\n            true\n        } else false\n    }\n\ninternal fun <T> SnapshotStateList<T>.stateRecordWith(list: PersistentList<T>): StateRecord {\n    val snapshot = currentSnapshot()\n    return StateListStateRecord(snapshot.snapshotId, list).also {\n        if (snapshot !is GlobalSnapshot) {\n            it.next = StateListStateRecord(Snapshot.PreexistingSnapshotId.toSnapshotId(), list)\n        }\n    }\n}\n\ninternal val <T> SnapshotStateList<T>.structure: Int\n    get() = withCurrent { structuralChange }\n\n@Suppress(\"UNCHECKED_CAST\")\ninternal val <T> SnapshotStateList<T>.readable: StateListStateRecord<T>\n    get() = (firstStateRecord as StateListStateRecord<T>).readable(this)\n\n/**\n * Creates a new snapshot state list with the specified [size], where each element is calculated by\n * calling the specified [init] function.\n *\n * The function [init] is called for each list element sequentially starting from the first one. It\n * should return the value for a list element given its index.\n */\npublic fun <T> SnapshotStateList(size: Int, init: (index: Int) -> T): SnapshotStateList<T> {\n    if (size == 0) {\n        return SnapshotStateList()\n    }\n\n    val builder = persistentListOf<T>().builder()\n    for (i in 0 until size) {\n        builder.add(init(i))\n    }\n    return SnapshotStateList(builder.build())\n}\n\n/** This is an internal implementation class of [SnapshotStateList]. Do not use. */\ninternal class StateListStateRecord<T>\ninternal constructor(snapshotId: SnapshotId, internal var list: PersistentList<T>) :\n    StateRecord(snapshotId) {\n    internal var modification = 0\n    internal var structuralChange = 0\n\n    override fun assign(value: StateRecord) {\n        synchronized(sync) {\n            @Suppress(\"UNCHECKED_CAST\")\n            list = (value as StateListStateRecord<T>).list\n            modification = value.modification\n            structuralChange = value.structuralChange\n        }\n    }\n\n    override fun create(): StateRecord = create(currentSnapshot().snapshotId)\n\n    override fun create(snapshotId: SnapshotId): StateRecord =\n        StateListStateRecord(snapshotId, list)\n}\n\n/**\n * This lock is used to ensure that the value of modification and the list in the state record, when\n * used together, are atomically read and written.\n *\n * A global sync object is used to avoid having to allocate a sync object and initialize a monitor\n * for each instance the list. This avoid additional allocations but introduces some contention\n * between lists. As there is already contention on the global snapshot lock to write so the\n * additional contention introduced by this lock is nominal.\n *\n * In code the requires this lock and calls `writable` (or other operation that acquires the\n * snapshot global lock), this lock *MUST* be acquired last to avoid deadlocks. In other words, the\n * lock must be taken in the `writable` lambda, if `writable` is used.\n */\nprivate val sync = makeSynchronizedObject()\n\nprivate fun modificationError(): Nothing = error(\"Cannot modify a state list through an iterator\")\n\nprivate fun validateRange(index: Int, size: Int) {\n    if (index !in 0 until size) {\n        throw IndexOutOfBoundsException(\"index ($index) is out of bound of [0, $size)\")\n    }\n}\n\nprivate fun invalidIteratorSet(): Nothing =\n    error(\n        \"Cannot call set before the first call to next() or previous() \" +\n            \"or immediately after a call to add() or remove()\"\n    )\n\ninternal class StateListIterator<T>(val list: SnapshotStateList<T>, offset: Int) :\n    MutableListIterator<T> {\n    private var index = offset - 1\n    private var lastRequested = -1\n    private var structure = list.structure\n\n    override fun hasPrevious() = index >= 0\n\n    override fun nextIndex() = index + 1\n\n    override fun previous(): T {\n        validateModification()\n        validateRange(index, list.size)\n        lastRequested = index\n        return list[index].also { index-- }\n    }\n\n    override fun previousIndex(): Int = index\n\n    override fun add(element: T) {\n        validateModification()\n        list.add(index + 1, element)\n        lastRequested = -1\n        index++\n        structure = list.structure\n    }\n\n    override fun hasNext() = index < list.size - 1\n\n    override fun next(): T {\n        validateModification()\n        val newIndex = index + 1\n        lastRequested = newIndex\n        validateRange(newIndex, list.size)\n        return list[newIndex].also { index = newIndex }\n    }\n\n    override fun remove() {\n        validateModification()\n        list.removeAt(lastRequested)\n        index--\n        lastRequested = -1\n        structure = list.structure\n    }\n\n    override fun set(element: T) {\n        validateModification()\n        if (lastRequested < 0) invalidIteratorSet()\n        list.set(lastRequested, element)\n        structure = list.structure\n    }\n\n    private fun validateModification() {\n        if (list.structure != structure) {\n            throw ConcurrentModificationException()\n        }\n    }\n}\n\ninternal class SubList<T>(val parentList: SnapshotStateList<T>, fromIndex: Int, toIndex: Int) :\n    MutableList<T> {\n    private val offset = fromIndex\n    private var structure = parentList.structure\n    override var size = toIndex - fromIndex\n        private set\n\n    override fun contains(element: T): Boolean = indexOf(element) >= 0\n\n    override fun containsAll(elements: Collection<T>): Boolean = elements.all { contains(it) }\n\n    override fun get(index: Int): T {\n        validateModification()\n        validateRange(index, size)\n        return parentList[offset + index]\n    }\n\n    override fun indexOf(element: T): Int {\n        validateModification()\n        (offset until offset + size).forEach { if (element == parentList[it]) return it - offset }\n        return -1\n    }\n\n    override fun isEmpty(): Boolean = size == 0\n\n    override fun iterator(): MutableIterator<T> = listIterator()\n\n    override fun lastIndexOf(element: T): Int {\n        validateModification()\n        var index = offset + size - 1\n        while (index >= offset) {\n            if (element == parentList[index]) return index - offset\n            index--\n        }\n        return -1\n    }\n\n    override fun add(element: T): Boolean {\n        validateModification()\n        parentList.add(offset + size, element)\n        size++\n        structure = parentList.structure\n        return true\n    }\n\n    override fun add(index: Int, element: T) {\n        validateModification()\n        parentList.add(offset + index, element)\n        size++\n        structure = parentList.structure\n    }\n\n    override fun addAll(index: Int, elements: Collection<T>): Boolean {\n        validateModification()\n        val result = parentList.addAll(index + offset, elements)\n        if (result) {\n            size += elements.size\n            structure = parentList.structure\n        }\n        return result\n    }\n\n    override fun addAll(elements: Collection<T>): Boolean = addAll(size, elements)\n\n    override fun clear() {\n        if (size > 0) {\n            validateModification()\n            parentList.removeRange(offset, offset + size)\n            size = 0\n            structure = parentList.structure\n        }\n    }\n\n    override fun listIterator(): MutableListIterator<T> = listIterator(0)\n\n    override fun listIterator(index: Int): MutableListIterator<T> {\n        validateModification()\n        var current = index - 1\n        return object : MutableListIterator<T> {\n            override fun hasPrevious() = current >= 0\n\n            override fun nextIndex(): Int = current + 1\n\n            override fun previous(): T {\n                val oldCurrent = current\n                validateRange(oldCurrent, size)\n                current = oldCurrent - 1\n                return this@SubList[oldCurrent]\n            }\n\n            override fun previousIndex(): Int = current\n\n            override fun add(element: T) = modificationError()\n\n            override fun hasNext(): Boolean = current < size - 1\n\n            override fun next(): T {\n                val newCurrent = current + 1\n                validateRange(newCurrent, size)\n                current = newCurrent\n                return this@SubList[newCurrent]\n            }\n\n            override fun remove() = modificationError()\n\n            override fun set(element: T) = modificationError()\n        }\n    }\n\n    override fun remove(element: T): Boolean {\n        val index = indexOf(element)\n        return if (index >= 0) {\n            removeAt(index)\n            true\n        } else false\n    }\n\n    override fun removeAll(elements: Collection<T>): Boolean {\n        var removed = false\n        for (element in elements) {\n            removed = remove(element) || removed\n        }\n        return removed\n    }\n\n    override fun removeAt(index: Int): T {\n        validateModification()\n        return parentList.removeAt(offset + index).also {\n            size--\n            structure = parentList.structure\n        }\n    }\n\n    override fun retainAll(elements: Collection<T>): Boolean {\n        validateModification()\n        val removed = parentList.retainAllInRange(elements, offset, offset + size)\n        if (removed > 0) {\n            structure = parentList.structure\n            size -= removed\n        }\n        return removed > 0\n    }\n\n    override fun set(index: Int, element: T): T {\n        validateRange(index, size)\n        validateModification()\n        val result = parentList.set(index + offset, element)\n        structure = parentList.structure\n        return result\n    }\n\n    override fun subList(fromIndex: Int, toIndex: Int): MutableList<T> {\n        requirePrecondition(fromIndex in 0..toIndex && toIndex <= size) {\n            \"fromIndex or toIndex are out of bounds\"\n        }\n        validateModification()\n        return SubList(parentList, fromIndex + offset, toIndex + offset)\n    }\n\n    private fun validateModification() {\n        if (parentList.structure != structure) {\n            throw ConcurrentModificationException()\n        }\n    }\n}\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/snapshots/SnapshotStateMap.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.runtime.snapshots\n\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.external.kotlinx.collections.immutable.PersistentMap\nimport androidx.compose.runtime.external.kotlinx.collections.immutable.persistentHashMapOf\nimport androidx.compose.runtime.platform.makeSynchronizedObject\nimport androidx.compose.runtime.platform.synchronized\nimport kotlin.jvm.JvmName\n\n/**\n * An implementation of [MutableMap] that can be observed and snapshot. This is the result type\n * created by [androidx.compose.runtime.mutableStateMapOf].\n *\n * This class closely implements the same semantics as [HashMap].\n *\n * @see androidx.compose.runtime.mutableStateMapOf\n */\n@Stable\npublic class SnapshotStateMap<K, V> : StateObject, MutableMap<K, V> {\n    override var firstStateRecord: StateRecord =\n        persistentHashMapOf<K, V>().let { map ->\n            val snapshot = currentSnapshot()\n            StateMapStateRecord(snapshot.snapshotId, map).also {\n                if (snapshot !is GlobalSnapshot) {\n                    it.next =\n                        StateMapStateRecord(Snapshot.PreexistingSnapshotId.toSnapshotId(), map)\n                }\n            }\n        }\n        private set\n\n    override fun prependStateRecord(value: StateRecord) {\n        @Suppress(\"UNCHECKED_CAST\")\n        firstStateRecord = value as StateMapStateRecord<K, V>\n    }\n\n    /**\n     * Returns an immutable map containing all key-value pairs from the original map.\n     *\n     * The content of the map returned will not change even if the content of the map is changed in\n     * the same snapshot. It also will be the same instance until the content is changed. It is not,\n     * however, guaranteed to be the same instance for the same content as adding and removing the\n     * same item from the this map might produce a different instance with the same content.\n     *\n     * This operation is O(1) and does not involve a physically copying the map. It instead returns\n     * the underlying immutable map used internally to store the content of the map.\n     *\n     * It is recommended to use [toMap] when using returning the value of this map from\n     * [androidx.compose.runtime.snapshotFlow].\n     */\n    public fun toMap(): Map<K, V> = readable.map\n\n    override val size: Int\n        get() = readable.map.size\n\n    override fun containsKey(key: K): Boolean = readable.map.containsKey(key)\n\n    override fun containsValue(value: V): Boolean = readable.map.containsValue(value)\n\n    override fun get(key: K): V? = readable.map[key]\n\n    override fun isEmpty(): Boolean = readable.map.isEmpty()\n\n    override val entries: MutableSet<MutableMap.MutableEntry<K, V>> = SnapshotMapEntrySet(this)\n    override val keys: MutableSet<K> = SnapshotMapKeySet(this)\n    override val values: MutableCollection<V> = SnapshotMapValueSet(this)\n\n    @Suppress(\"UNCHECKED_CAST\")\n    override fun toString(): String =\n        (firstStateRecord as StateMapStateRecord<K, V>).withCurrent {\n            \"SnapshotStateMap(value=${it.map})@${hashCode()}\"\n        }\n\n    override fun clear(): Unit = update { persistentHashMapOf() }\n\n    override fun put(key: K, value: V): V? = mutate { it.put(key, value) }\n\n    override fun putAll(from: Map<out K, V>): Unit = mutate { it.putAll(from) }\n\n    override fun remove(key: K): V? = mutate { it.remove(key) }\n\n    internal val modification\n        get() = readable.modification\n\n    internal fun removeValue(value: V) =\n        entries\n            .firstOrNull { it.value == value }\n            ?.let {\n                remove(it.key)\n                true\n            } == true\n\n    @Suppress(\"UNCHECKED_CAST\")\n    internal val readable: StateMapStateRecord<K, V>\n        get() = (firstStateRecord as StateMapStateRecord<K, V>).readable(this)\n\n    internal inline fun removeIf(predicate: (MutableMap.MutableEntry<K, V>) -> Boolean): Boolean {\n        var removed = false\n        mutate {\n            for (entry in this.entries) {\n                if (predicate(entry)) {\n                    it.remove(entry.key)\n                    removed = true\n                }\n            }\n        }\n        return removed\n    }\n\n    internal inline fun any(predicate: (Map.Entry<K, V>) -> Boolean): Boolean {\n        for (entry in readable.map.entries) {\n            if (predicate(entry)) return true\n        }\n        return false\n    }\n\n    internal inline fun all(predicate: (Map.Entry<K, V>) -> Boolean): Boolean {\n        for (entry in readable.map.entries) {\n            if (!predicate(entry)) return false\n        }\n        return true\n    }\n\n    /**\n     * An internal function used by the debugger to display the value of the current value of the\n     * mutable state object without triggering read observers.\n     */\n    @Suppress(\"unused\")\n    internal val debuggerDisplayValue: Map<K, V>\n        @JvmName(\"getDebuggerDisplayValue\") get() = withCurrent { map }\n\n    private inline fun <R> withCurrent(block: StateMapStateRecord<K, V>.() -> R): R =\n        @Suppress(\"UNCHECKED_CAST\")\n        (firstStateRecord as StateMapStateRecord<K, V>).withCurrent(block)\n\n    private inline fun <R> writable(block: StateMapStateRecord<K, V>.() -> R): R =\n        @Suppress(\"UNCHECKED_CAST\")\n        (firstStateRecord as StateMapStateRecord<K, V>).writable(this, block)\n\n    private inline fun <R> mutate(block: (MutableMap<K, V>) -> R): R {\n        var result: R\n        while (true) {\n            var oldMap: PersistentMap<K, V>? = null\n            var currentModification = 0\n            synchronized(sync) {\n                val current = withCurrent { this }\n                oldMap = current.map\n                currentModification = current.modification\n            }\n            val builder = oldMap!!.builder()\n            result = block(builder)\n            val newMap = builder.build()\n            if (newMap == oldMap || writable { attemptUpdate(currentModification, newMap) }) break\n        }\n        return result\n    }\n\n    private fun StateMapStateRecord<K, V>.attemptUpdate(\n        currentModification: Int,\n        newMap: PersistentMap<K, V>,\n    ) =\n        synchronized(sync) {\n            if (modification == currentModification) {\n                map = newMap\n                modification++\n                true\n            } else false\n        }\n\n    private inline fun update(block: (PersistentMap<K, V>) -> PersistentMap<K, V>) = withCurrent {\n        val newMap = block(map)\n        if (newMap !== map) writable { commitUpdate(newMap) }\n    }\n\n    // NOTE: do not inline this method to avoid class verification failures, see b/369909868\n    private fun StateMapStateRecord<K, V>.commitUpdate(newMap: PersistentMap<K, V>) =\n        synchronized(sync) {\n            map = newMap\n            modification++\n        }\n\n    /** Implementation class of [SnapshotStateMap]. Do not use. */\n    internal class StateMapStateRecord<K, V>\n    internal constructor(snapshotId: SnapshotId, internal var map: PersistentMap<K, V>) :\n        StateRecord(snapshotId) {\n        internal var modification = 0\n\n        override fun assign(value: StateRecord) {\n            @Suppress(\"UNCHECKED_CAST\") val other = (value as StateMapStateRecord<K, V>)\n            synchronized(sync) {\n                map = other.map\n                modification = other.modification\n            }\n        }\n\n        override fun create(): StateRecord = StateMapStateRecord(currentSnapshot().snapshotId, map)\n\n        override fun create(snapshotId: SnapshotId): StateRecord =\n            StateMapStateRecord(snapshotId, map)\n    }\n}\n\nprivate abstract class SnapshotMapSet<K, V, E>(val map: SnapshotStateMap<K, V>) : MutableSet<E> {\n    override val size: Int\n        get() = map.size\n\n    override fun clear() = map.clear()\n\n    override fun isEmpty() = map.isEmpty()\n}\n\nprivate class SnapshotMapEntrySet<K, V>(map: SnapshotStateMap<K, V>) :\n    SnapshotMapSet<K, V, MutableMap.MutableEntry<K, V>>(map) {\n    override fun add(element: MutableMap.MutableEntry<K, V>) = unsupported()\n\n    override fun addAll(elements: Collection<MutableMap.MutableEntry<K, V>>) = unsupported()\n\n    override fun iterator(): MutableIterator<MutableMap.MutableEntry<K, V>> =\n        StateMapMutableEntriesIterator(map, map.readable.map.entries.iterator())\n\n    override fun remove(element: MutableMap.MutableEntry<K, V>) = map.remove(element.key) != null\n\n    override fun removeAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {\n        var removed = false\n        for (element in elements) {\n            removed = map.remove(element.key) != null || removed\n        }\n        return removed\n    }\n\n    override fun retainAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {\n        val entries = elements.associate { it.key to it.value }\n        return map.removeIf { !entries.containsKey(it.key) || entries[it.key] != it.value }\n    }\n\n    override fun contains(element: MutableMap.MutableEntry<K, V>): Boolean {\n        return map[element.key] == element.value\n    }\n\n    override fun containsAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {\n        return elements.all { contains(it) }\n    }\n}\n\nprivate class SnapshotMapKeySet<K, V>(map: SnapshotStateMap<K, V>) : SnapshotMapSet<K, V, K>(map) {\n    override fun add(element: K) = unsupported()\n\n    override fun addAll(elements: Collection<K>) = unsupported()\n\n    override fun iterator() = StateMapMutableKeysIterator(map, map.readable.map.entries.iterator())\n\n    override fun remove(element: K): Boolean = map.remove(element) != null\n\n    override fun removeAll(elements: Collection<K>): Boolean {\n        var removed = false\n        elements.forEach { removed = map.remove(it) != null || removed }\n        return removed\n    }\n\n    override fun retainAll(elements: Collection<K>): Boolean {\n        val set = elements.toSet()\n        return map.removeIf { it.key !in set }\n    }\n\n    override fun contains(element: K) = map.contains(element)\n\n    override fun containsAll(elements: Collection<K>): Boolean = elements.all { map.contains(it) }\n}\n\nprivate class SnapshotMapValueSet<K, V>(map: SnapshotStateMap<K, V>) :\n    SnapshotMapSet<K, V, V>(map) {\n    override fun add(element: V) = unsupported()\n\n    override fun addAll(elements: Collection<V>) = unsupported()\n\n    override fun iterator() =\n        StateMapMutableValuesIterator(map, map.readable.map.entries.iterator())\n\n    override fun remove(element: V): Boolean = map.removeValue(element)\n\n    override fun removeAll(elements: Collection<V>): Boolean {\n        val set = elements.toSet()\n        return map.removeIf { it.value in set }\n    }\n\n    override fun retainAll(elements: Collection<V>): Boolean {\n        val set = elements.toSet()\n        return map.removeIf { it.value !in set }\n    }\n\n    override fun contains(element: V) = map.containsValue(element)\n\n    override fun containsAll(elements: Collection<V>): Boolean {\n        return elements.all { map.containsValue(it) }\n    }\n}\n\n/**\n * This lock is used to ensure that the value of modification and the map in the state record, when\n * used together, are atomically read and written.\n *\n * A global sync object is used to avoid having to allocate a sync object and initialize a monitor\n * for each instance the map. This avoids additional allocations but introduces some contention\n * between maps. As there is already contention on the global snapshot lock to write so the\n * additional contention introduced by this lock is nominal.\n *\n * In code the requires this lock and calls `writable` (or other operation that acquires the\n * snapshot global lock), this lock *MUST* be acquired last to avoid deadlocks. In other words, the\n * lock must be taken in the `writable` lambda, if `writable` is used.\n */\nprivate val sync = makeSynchronizedObject()\n\nprivate abstract class StateMapMutableIterator<K, V>(\n    val map: SnapshotStateMap<K, V>,\n    val iterator: Iterator<Map.Entry<K, V>>,\n) {\n    protected var modification = map.modification\n    protected var current: Map.Entry<K, V>? = null\n    protected var next: Map.Entry<K, V>? = null\n\n    init {\n        advance()\n    }\n\n    fun remove() = modify {\n        val value = current\n\n        if (value != null) {\n            map.remove(value.key)\n            current = null\n        } else {\n            throw IllegalStateException()\n        }\n    }\n\n    fun hasNext() = next != null\n\n    protected fun advance() {\n        current = next\n        next = if (iterator.hasNext()) iterator.next() else null\n    }\n\n    protected inline fun <T> modify(block: () -> T): T {\n        if (map.modification != modification) {\n            throw ConcurrentModificationException()\n        }\n        return block().also { modification = map.modification }\n    }\n}\n\nprivate class StateMapMutableEntriesIterator<K, V>(\n    map: SnapshotStateMap<K, V>,\n    iterator: Iterator<Map.Entry<K, V>>,\n) : StateMapMutableIterator<K, V>(map, iterator), MutableIterator<MutableMap.MutableEntry<K, V>> {\n    override fun next(): MutableMap.MutableEntry<K, V> {\n        advance()\n        if (current != null) {\n            return object : MutableMap.MutableEntry<K, V> {\n                override val key = current!!.key\n                override var value = current!!.value\n\n                override fun setValue(newValue: V): V = modify {\n                    val result = value\n                    map[key] = newValue\n                    value = newValue\n                    return result\n                }\n            }\n        } else {\n            throw IllegalStateException()\n        }\n    }\n}\n\nprivate class StateMapMutableKeysIterator<K, V>(\n    map: SnapshotStateMap<K, V>,\n    iterator: Iterator<Map.Entry<K, V>>,\n) : StateMapMutableIterator<K, V>(map, iterator), MutableIterator<K> {\n    override fun next(): K {\n        val result = next ?: throw IllegalStateException()\n        advance()\n        return result.key\n    }\n}\n\nprivate class StateMapMutableValuesIterator<K, V>(\n    map: SnapshotStateMap<K, V>,\n    iterator: Iterator<Map.Entry<K, V>>,\n) : StateMapMutableIterator<K, V>(map, iterator), MutableIterator<V> {\n    override fun next(): V {\n        val result = next ?: throw IllegalStateException()\n        advance()\n        return result.value\n    }\n}\n\ninternal fun unsupported(): Nothing {\n    throw UnsupportedOperationException()\n}\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/ComposeVersion.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.runtime\n\n@Suppress(\"unused\")\ninternal object ComposeVersion {\n    /**\n     * This version number is used by the compose compiler in order to verify that the compiler and\n     * the runtime are compatible with one another.\n     *\n     * Every release should increase this number to a multiple of 100, which provides for the\n     * opportunity to use the last two digits for releases made out-of-band.\n     *\n     * IMPORTANT: Whenever updating this value, please make sure to also update `versionTable` and\n     * `minimumRuntimeVersionInt` in `VersionChecker.kt` of the compiler.\n     */\n    const val version: Int = 13000\n}\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/Applier.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.runtime\n\nimport androidx.compose.runtime.internal.JvmDefaultWithCompatibility\n\n/**\n * An Applier is responsible for applying the tree-based operations that get emitted during a\n * composition. Every [Composer] has an [Applier] which it uses to emit a [ComposeNode].\n *\n * A custom [Applier] implementation will be needed in order to utilize Compose to build and\n * maintain a tree of a novel type.\n *\n * @sample androidx.compose.runtime.samples.CustomTreeComposition\n * @see AbstractApplier\n * @see Composition\n * @see Composer\n * @see ComposeNode\n */\n@JvmDefaultWithCompatibility\npublic interface Applier<N> {\n    /**\n     * The node that operations will be applied on at any given time. It is expected that the value\n     * of this property will change as [down] and [up] are called.\n     */\n    public val current: N\n\n    /**\n     * Called when the [Composer] is about to begin applying changes using this applier.\n     * [onEndChanges] will be called when changes are complete.\n     */\n    public fun onBeginChanges() {}\n\n    /**\n     * Called when the [Composer] is finished applying changes using this applier. A call to\n     * [onBeginChanges] will always precede a call to [onEndChanges].\n     */\n    public fun onEndChanges() {}\n\n    /**\n     * Indicates that the applier is getting traversed \"down\" the tree. When this gets called,\n     * [node] is expected to be a child of [current], and after this operation, [node] is expected\n     * to be the new [current].\n     */\n    public fun down(node: N)\n\n    /**\n     * Indicates that the applier is getting traversed \"up\" the tree. After this operation\n     * completes, the [current] should return the \"parent\" of the [current] node at the beginning of\n     * this operation.\n     */\n    public fun up()\n\n    /**\n     * Indicates that [instance] should be inserted as a child to [current] at [index]. An applier\n     * should insert the node into the tree either in [insertTopDown] or [insertBottomUp], not both.\n     *\n     * The [insertTopDown] method is called before the children of [instance] have been created and\n     * inserted into it. [insertBottomUp] is called after all children have been created and\n     * inserted.\n     *\n     * Some trees are faster to build top-down, in which case the [insertTopDown] method should be\n     * used to insert the [instance]. Other trees are faster to build bottom-up in which case\n     * [insertBottomUp] should be used.\n     *\n     * To give example of building a tree top-down vs. bottom-up consider the following tree,\n     * ```\n     *      R\n     *      |\n     *      B\n     *     / \\\n     *    A   C\n     *  ```\n     *\n     * where the node `B` is being inserted into the tree at `R`. Top-down building of the tree\n     * first inserts `B` into `R`, then inserts `A` into `B` followed by inserting `C` into B`. For\n     * example,\n     *\n     *  ```\n     *      1           2           3\n     *      R           R           R\n     *      |           |           |\n     *      B           B           B\n     *                 /           / \\\n     *                A           A   C\n     * ```\n     *\n     * A bottom-up building of the tree starts with inserting `A` and `C` into `B` then inserts `B`\n     * tree into `R`.\n     *\n     * ```\n     *    1           2           3\n     *    B           B           R\n     *    |          / \\          |\n     *    A         A   C         B\n     *                           / \\\n     *                          A   C\n     * ```\n     *\n     * To see how building top-down vs. bottom-up can differ significantly in performance consider a\n     * tree where whenever a child is added to the tree all parent nodes, up to the root, are\n     * notified of the new child entering the tree. If the tree is built top-down,\n     * 1. `R` is notified of `B` entering.\n     * 2. `B` is notified of `A` entering, `R` is notified of `A` entering.\n     * 3. `B` is notified of `C` entering, `R` is notified of `C` entering.\n     *\n     * for a total of 5 notifications. The number of notifications grows exponentially with the\n     * number of inserts.\n     *\n     * For bottom-up, the notifications are,\n     * 1. `B` is notified `A` entering.\n     * 2. `B` is notified `C` entering.\n     * 3. `R` is notified `B` entering.\n     *\n     * The notifications are linear to the number of nodes inserted.\n     *\n     * If, on the other hand, all children are notified when the parent enters a tree, then the\n     * notifications are, for top-down,\n     * 1. `B` is notified it is entering `R`.\n     * 2. `A` is notified it is entering `B`.\n     * 3. `C` is notified it is entering `B`.\n     *\n     * which is linear to the number of nodes inserted.\n     *\n     * For bottom-up, the notifications look like,\n     * 1. `A` is notified it is entering `B`.\n     * 2. `C` is notified it is entering `B`.\n     * 3. `B` is notified it is entering `R`, `A` is notified it is entering `R`, `C` is notified it\n     *    is entering `R`.\n     *\n     *    which exponential to the number of nodes inserted.\n     */\n    public fun insertTopDown(index: Int, instance: N)\n\n    /**\n     * Indicates that [instance] should be inserted as a child of [current] at [index]. An applier\n     * should insert the node into the tree either in [insertTopDown] or [insertBottomUp], not both.\n     * See the description of [insertTopDown] to which describes when to implement [insertTopDown]\n     * and when to use [insertBottomUp].\n     */\n    public fun insertBottomUp(index: Int, instance: N)\n\n    /**\n     * Indicates that the children of [current] from [index] to [index] + [count] should be removed.\n     */\n    public fun remove(index: Int, count: Int)\n\n    /**\n     * Indicates that [count] children of [current] should be moved from index [from] to index [to].\n     *\n     * The [to] index is relative to the position before the change, so, for example, to move an\n     * element at position 1 to after the element at position 2, [from] should be `1` and [to]\n     * should be `3`. If the elements were A B C D E, calling `move(1, 3, 1)` would result in the\n     * elements being reordered to A C B D E.\n     */\n    public fun move(from: Int, to: Int, count: Int)\n\n    /**\n     * Move to the root and remove all nodes from the root, preparing both this [Applier] and its\n     * root to be used as the target of a new composition in the future.\n     */\n    public fun clear()\n\n    /** Apply a change to the current node. */\n    public fun apply(block: N.(Any?) -> Unit, value: Any?) {\n        current.block(value)\n    }\n\n    /** Notify [current] is is being reused in reusable content. */\n    public fun reuse() {\n        (current as? ComposeNodeLifecycleCallback)?.onReuse()\n    }\n}\n\n/**\n * An abstract [Applier] implementation.\n *\n * @sample androidx.compose.runtime.samples.CustomTreeComposition\n * @see Applier\n * @see Composition\n * @see Composer\n * @see ComposeNode\n */\npublic abstract class AbstractApplier<T>(public val root: T) : Applier<T> {\n    private val stack = Stack<T>()\n\n    override var current: T = root\n        protected set\n\n    override fun down(node: T) {\n        stack.push(current)\n        current = node\n    }\n\n    override fun up() {\n        current = stack.pop()\n    }\n\n    final override fun clear() {\n        stack.clear()\n        current = root\n        onClear()\n    }\n\n    /** Called to perform clearing of the [root] when [clear] is called. */\n    protected abstract fun onClear()\n\n    protected fun MutableList<T>.remove(index: Int, count: Int) {\n        if (count == 1) {\n            removeAt(index)\n        } else {\n            subList(index, index + count).clear()\n        }\n    }\n\n    protected fun MutableList<T>.move(from: Int, to: Int, count: Int) {\n        val dest = if (from > to) to else to - count\n        if (count == 1) {\n            if (from == to + 1 || from == to - 1) {\n                // Adjacent elements, perform swap to avoid backing array manipulations.\n                val fromEl = get(from)\n                val toEl = set(to, fromEl)\n                set(from, toEl)\n            } else {\n                val fromEl = removeAt(from)\n                add(dest, fromEl)\n            }\n        } else {\n            val subView = subList(from, from + count)\n            val subCopy = subView.toMutableList()\n            subView.clear()\n            addAll(dest, subCopy)\n        }\n    }\n}\n\ninternal class OffsetApplier<N>(private val applier: Applier<N>, private val offset: Int) :\n    Applier<N> {\n    private var nesting = 0\n    override val current: N\n        get() = applier.current\n\n    override fun down(node: N) {\n        nesting++\n        applier.down(node)\n    }\n\n    override fun up() {\n        runtimeCheck(nesting > 0) { \"OffsetApplier up called with no corresponding down\" }\n        nesting--\n        applier.up()\n    }\n\n    override fun insertTopDown(index: Int, instance: N) {\n        applier.insertTopDown(index + if (nesting == 0) offset else 0, instance)\n    }\n\n    override fun insertBottomUp(index: Int, instance: N) {\n        applier.insertBottomUp(index + if (nesting == 0) offset else 0, instance)\n    }\n\n    override fun remove(index: Int, count: Int) {\n        applier.remove(index + if (nesting == 0) offset else 0, count)\n    }\n\n    override fun move(from: Int, to: Int, count: Int) {\n        val effectiveOffset = if (nesting == 0) offset else 0\n        applier.move(from + effectiveOffset, to + effectiveOffset, count)\n    }\n\n    override fun clear() {\n        composeImmediateRuntimeError(\"Clear is not valid on OffsetApplier\")\n    }\n\n    override fun apply(block: N.(Any?) -> Unit, value: Any?) {\n        applier.apply(block, value)\n    }\n\n    override fun reuse() {\n        applier.reuse()\n    }\n}\n\n/**\n * A stub of [Applier] that does not implement any operations and throws when called into. Used to\n * apply pending changes that do not result in a change to the composition hierarchy and therefore\n * do not need a real application phase after completing the composition.\n */\ninternal object ThrowingApplierStub : Applier<Any?> {\n    override val current: Any\n        get() = throwIllegalOperationException()\n\n    override fun up() = throwIllegalOperationException()\n\n    override fun remove(index: Int, count: Int) = throwIllegalOperationException()\n\n    override fun move(from: Int, to: Int, count: Int) = throwIllegalOperationException()\n\n    override fun clear() = throwIllegalOperationException()\n\n    override fun insertBottomUp(index: Int, instance: Any?) = throwIllegalOperationException()\n\n    override fun insertTopDown(index: Int, instance: Any?) = throwIllegalOperationException()\n\n    override fun down(node: Any?) = throwIllegalOperationException()\n\n    private fun throwIllegalOperationException() {\n        composeImmediateRuntimeError(\n            \"ChangeList cannot call the Applier when \" +\n                \"executing pending changes outside of the applier phase.\"\n        )\n    }\n}\n```\n\n## File: compose/runtime/runtime/src/commonMain/kotlin/androidx/compose/runtime/RecomposeScopeImpl.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.runtime\n\nimport androidx.collection.MutableObjectIntMap\nimport androidx.collection.MutableScatterMap\nimport androidx.collection.ScatterSet\nimport androidx.compose.runtime.composer.gapbuffer.GapAnchor\nimport androidx.compose.runtime.composer.gapbuffer.SlotTable\nimport androidx.compose.runtime.composer.gapbuffer.SlotWriter\nimport androidx.compose.runtime.snapshots.fastAny\nimport androidx.compose.runtime.snapshots.fastForEach\nimport androidx.compose.runtime.tooling.ComposeToolingApi\nimport androidx.compose.runtime.tooling.IdentifiableRecomposeScope\n\n/**\n * Represents a recomposable scope or section of the composition hierarchy. Can be used to manually\n * invalidate the scope to schedule it for recomposition.\n */\npublic interface RecomposeScope {\n    /**\n     * Invalidate the corresponding scope, requesting the composer recompose this scope.\n     *\n     * This method is thread safe.\n     */\n    public fun invalidate()\n}\n\nprivate const val changedLowBitMask = 0b001_001_001_001_001_001_001_001_001_001_0\nprivate const val changedHighBitMask = changedLowBitMask shl 1\nprivate const val changedMask = (changedLowBitMask or changedHighBitMask).inv()\n\n/**\n * A compiler plugin utility function to change $changed flags from Different(10) to Same(01) for\n * when captured by restart lambdas. All parameters are passed with the same value as it was\n * previously invoked with and the changed flags should reflect that.\n */\n@PublishedApi\ninternal fun updateChangedFlags(flags: Int): Int {\n    val lowBits = flags and changedLowBitMask\n    val highBits = flags and changedHighBitMask\n    return ((flags and changedMask) or\n        (lowBits or (highBits shr 1)) or\n        ((lowBits shl 1) and highBits))\n}\n\nprivate const val UsedFlag = 0x001\nprivate const val DefaultsInScopeFlag = 0x002\nprivate const val DefaultsInvalidFlag = 0x004\nprivate const val RequiresRecomposeFlag = 0x008\nprivate const val SkippedFlag = 0x010\nprivate const val RereadingFlag = 0x020\nprivate const val ForcedRecomposeFlag = 0x040\nprivate const val ForceReusing = 0x080\nprivate const val Paused = 0x100\nprivate const val Resuming = 0x200\nprivate const val ResetReusing = 0x400\n\ninternal interface RecomposeScopeOwner {\n    fun invalidate(scope: RecomposeScopeImpl, instance: Any?): InvalidationResult\n\n    fun recomposeScopeReleased(scope: RecomposeScopeImpl)\n\n    fun recordReadOf(value: Any)\n}\n\n/**\n * A RecomposeScope is created for a region of the composition that can be recomposed independently\n * of the rest of the composition. The composer will position the slot table to the location stored\n * in [anchor] and call [block] when recomposition is requested. It is created by\n * [Composer.startRestartGroup] and is used to track how to restart the group.\n */\n@OptIn(ComposeToolingApi::class)\ninternal class RecomposeScopeImpl(internal var owner: RecomposeScopeOwner?) :\n    ScopeUpdateScope, RecomposeScope, IdentifiableRecomposeScope {\n\n    /** The backing store for the boolean flags tracked by the recompose scope. */\n    private var flags: Int = 0\n\n    /**\n     * An anchor to the location in the slot table that start the group associated with this\n     * recompose scope.\n     */\n    var anchor: Anchor? = null\n\n    /** Access to anchor from tooling */\n    @ComposeToolingApi\n    override val identity: Any?\n        get() = anchor\n\n    /**\n     * Return whether the scope is valid. A scope becomes invalid when the slots it updates are\n     * removed from the slot table. For example, if the scope is in the then clause of an if\n     * statement that later becomes false.\n     */\n    val valid: Boolean\n        get() = owner != null && anchor?.valid ?: false\n\n    val canRecompose: Boolean\n        get() = block != null\n\n    /**\n     * Used is set when the [RecomposeScopeImpl] is used by, for example, [currentRecomposeScope].\n     * This is used as the result of [Composer.endRestartGroup] and indicates whether the lambda\n     * that is stored in [block] will be used.\n     */\n    var used: Boolean\n        get() = getFlag(UsedFlag)\n        set(value) {\n            setFlag(UsedFlag, value)\n        }\n\n    /**\n     * Used to force a scope to the reusing state when a composition is paused while reusing\n     * content.\n     */\n    var reusing: Boolean\n        get() = getFlag(ForceReusing)\n        set(value) {\n            setFlag(ForceReusing, value)\n        }\n\n    /**\n     * Used to restore the reusing state after unpausing a composition that was paused in a reusing\n     * state.\n     */\n    var resetReusing: Boolean\n        get() = getFlag(ResetReusing)\n        set(value) {\n            setFlag(ResetReusing, value)\n        }\n\n    /** Used to flag a scope as paused for pausable compositions */\n    var paused: Boolean\n        get() = getFlag(Paused)\n        set(value) {\n            setFlag(Paused, value)\n        }\n\n    /** Used to flag a scope as paused for pausable compositions */\n    var resuming: Boolean\n        get() = getFlag(Resuming)\n        set(value) {\n            setFlag(Resuming, value)\n        }\n\n    /**\n     * Set to true when the there are function default calculations in the scope. These are treated\n     * as a special case to avoid having to create a special scope for them. If these change the\n     * this scope needs to be recomposed but the default values can be skipped if they where not\n     * invalidated.\n     */\n    var defaultsInScope: Boolean\n        get() = getFlag(DefaultsInScopeFlag)\n        set(value) {\n            setFlag(DefaultsInScopeFlag, value)\n        }\n\n    /**\n     * Tracks whether any of the calculations in the default values were changed. See\n     * [defaultsInScope] for details.\n     */\n    var defaultsInvalid: Boolean\n        get() = getFlag(DefaultsInvalidFlag)\n        set(value) {\n            setFlag(DefaultsInvalidFlag, value)\n        }\n\n    /**\n     * Tracks whether the scope was invalidated directly but was recomposed because the caller was\n     * recomposed. This ensures that a scope invalidated directly will recompose even if its\n     * parameters are the same as the previous recomposition.\n     */\n    var requiresRecompose: Boolean\n        get() = getFlag(RequiresRecomposeFlag)\n        set(value) {\n            setFlag(RequiresRecomposeFlag, value)\n        }\n\n    /** The lambda to call to restart the scopes composition. */\n    private var block: ((Composer, Int) -> Unit)? = null\n\n    /**\n     * Restart the scope's composition. It is an error if [block] was not updated. The code\n     * generated by the compiler ensures that when the recompose scope is used then [block] will be\n     * set but it might occur if the compiler is out-of-date (or ahead of the runtime) or incorrect\n     * direct calls to [Composer.startRestartGroup] and [Composer.endRestartGroup].\n     */\n    fun compose(composer: Composer) {\n        block?.invoke(composer, 1) ?: error(\"Invalid restart scope\")\n    }\n\n    /**\n     * Invalidate the group which will cause [owner] to request this scope be recomposed, and an\n     * [InvalidationResult] will be returned.\n     */\n    fun invalidateForResult(value: Any?): InvalidationResult =\n        owner?.invalidate(this, value) ?: InvalidationResult.IGNORED\n\n    /**\n     * Release the recompose scope. This is called when the recompose scope has been removed by the\n     * compostion because the part of the composition it was tracking was removed.\n     */\n    fun release() {\n        owner?.recomposeScopeReleased(this)\n        owner = null\n        trackedInstances = null\n        trackedDependencies = null\n        block = null\n    }\n\n    /**\n     * Called when the data tracked by this recompose scope moves to a different composition when\n     * for example, the movable content it is part of has moved.\n     */\n    fun adoptedBy(owner: RecomposeScopeOwner) {\n        this.owner = owner\n    }\n\n    /**\n     * Invalidate the group which will cause [owner] to request this scope be recomposed.\n     *\n     * Unlike [invalidateForResult], this method is thread safe and calls the thread safe invalidate\n     * on the composer.\n     */\n    override fun invalidate() {\n        owner?.invalidate(this, null)\n    }\n\n    /**\n     * Update [block]. The scope is returned by [Composer.endRestartGroup] when [used] is true and\n     * implements [ScopeUpdateScope].\n     */\n    override fun updateScope(block: (Composer, Int) -> Unit) {\n        this.block = block\n    }\n\n    private var currentToken = 0\n    private var trackedInstances: MutableObjectIntMap<Any>? = null\n    private var trackedDependencies: MutableScatterMap<DerivedState<*>, Any?>? = null\n    private var rereading: Boolean\n        get() = getFlag(RereadingFlag)\n        set(value) {\n            setFlag(RereadingFlag, value)\n        }\n\n    /**\n     * Used to explicitly force recomposition. This is used during live edit to force a recompose\n     * scope that doesn't have a restart callback to recompose as its parent (or some parent above\n     * it) was invalidated and the path to this scope has also been forced.\n     */\n    var forcedRecompose: Boolean\n        get() = getFlag(ForcedRecomposeFlag)\n        set(value) {\n            setFlag(ForcedRecomposeFlag, value)\n        }\n\n    /** Indicates whether the scope was skipped (e.g. [scopeSkipped] was called. */\n    internal var skipped: Boolean\n        get() = getFlag(SkippedFlag)\n        private set(value) {\n            setFlag(SkippedFlag, value)\n        }\n\n    /**\n     * Called when composition start composing into this scope. The [token] is a value that is\n     * unique everytime this is called. This is currently the snapshot id but that shouldn't be\n     * relied on.\n     */\n    fun start(token: Int) {\n        currentToken = token\n        skipped = false\n    }\n\n    fun scopeSkipped() {\n        if (!reusing) {\n            skipped = true\n        }\n    }\n\n    /**\n     * Track instances that were read in scope.\n     *\n     * @return whether the value was already read in scope during current pass\n     */\n    fun recordRead(instance: Any): Boolean {\n        if (rereading) return false // Re-reading should force composition to update its tracking\n\n        val trackedInstances =\n            trackedInstances ?: MutableObjectIntMap<Any>().also { trackedInstances = it }\n\n        val token = trackedInstances.put(instance, currentToken, default = -1)\n        if (token == currentToken) {\n            return true\n        }\n\n        return false\n    }\n\n    fun recordDerivedStateValue(instance: DerivedState<*>, value: Any?) {\n        val trackedDependencies =\n            trackedDependencies\n                ?: MutableScatterMap<DerivedState<*>, Any?>().also { trackedDependencies = it }\n\n        trackedDependencies[instance] = value\n    }\n\n    /**\n     * Returns true if the scope is observing derived state which might make this scope\n     * conditionally invalidated.\n     */\n    val isConditional: Boolean\n        get() = trackedDependencies != null\n\n    /**\n     * Determine if the scope should be considered invalid.\n     *\n     * @param instances The set of objects reported as invalidating this scope.\n     */\n    fun isInvalidFor(instances: Any? /* State | ScatterSet<State> | null */): Boolean {\n        // If a non-empty instances exists and contains only derived state objects with their\n        // default values, then the scope should not be considered invalid. Otherwise the scope\n        // should if it was invalidated by any other kind of instance.\n        if (instances == null) return true\n        val trackedDependencies = trackedDependencies ?: return true\n\n        return when (instances) {\n            is DerivedState<*> -> {\n                instances.checkDerivedStateChanged(trackedDependencies)\n            }\n            is ScatterSet<*> -> {\n                instances.isNotEmpty() &&\n                    instances.any {\n                        it !is DerivedState<*> || it.checkDerivedStateChanged(trackedDependencies)\n                    }\n            }\n            else -> true\n        }\n    }\n\n    private fun DerivedState<*>.checkDerivedStateChanged(\n        dependencies: MutableScatterMap<DerivedState<*>, Any?>\n    ): Boolean {\n        @Suppress(\"UNCHECKED_CAST\")\n        this as DerivedState<Any?>\n        val policy = policy ?: structuralEqualityPolicy()\n        return !policy.equivalent(currentRecord.currentValue, dependencies[this])\n    }\n\n    fun rereadTrackedInstances() {\n        owner?.let { owner ->\n            trackedInstances?.let { trackedInstances ->\n                rereading = true\n                try {\n                    trackedInstances.forEach { value, _ -> owner.recordReadOf(value) }\n                } finally {\n                    rereading = false\n                }\n            }\n        }\n    }\n\n    /**\n     * Called when composition is completed for this scope. The [token] is the same token passed in\n     * the previous call to [start]. If [end] returns a non-null value the lambda returned will be\n     * called during [ControlledComposition.applyChanges].\n     */\n    fun end(token: Int): ((Composition) -> Unit)? {\n        return trackedInstances?.let { instances ->\n            // If any value previous observed was not read in this current composition\n            // schedule the value to be removed from the observe scope and removed from the\n            // observations tracked by the composition.\n            // [skipped] is true if the scope was skipped. If the scope was skipped we should\n            // leave the observations unmodified.\n            if (!skipped && instances.any { _, instanceToken -> instanceToken != token })\n                { composition ->\n                    if (\n                        currentToken == token &&\n                            instances == trackedInstances &&\n                            composition is CompositionImpl\n                    ) {\n                        instances.removeIf { instance, instanceToken ->\n                            val shouldRemove = instanceToken != token\n                            if (shouldRemove) {\n                                composition.removeObservation(instance, this)\n                                if (instance is DerivedState<*>) {\n                                    composition.removeDerivedStateObservation(instance)\n                                    trackedDependencies?.remove(instance)\n                                }\n                            }\n                            shouldRemove\n                        }\n                    }\n                }\n            else null\n        }\n    }\n\n    @Suppress(\"NOTHING_TO_INLINE\") private inline fun getFlag(flag: Int) = flags and flag != 0\n\n    @Suppress(\"NOTHING_TO_INLINE\")\n    private inline fun setFlag(flag: Int, value: Boolean) {\n        val existingFlags = flags\n        flags =\n            if (value) {\n                existingFlags or flag\n            } else {\n                existingFlags and flag.inv()\n            }\n    }\n\n    companion object {\n        internal fun adoptAnchoredScopes(\n            slots: SlotWriter,\n            anchors: List<GapAnchor>,\n            newOwner: RecomposeScopeOwner,\n        ) {\n            if (anchors.isNotEmpty()) {\n                anchors.fastForEach { anchor ->\n                    // The recompose scope is always at slot 0 of a restart group.\n                    val recomposeScope = slots.slot(anchor, 0) as? RecomposeScopeImpl\n                    // Check for null as the anchor might not be for a recompose scope\n                    recomposeScope?.adoptedBy(newOwner)\n                }\n            }\n        }\n\n        internal fun hasAnchoredRecomposeScopes(slots: SlotTable, anchors: List<GapAnchor>) =\n            anchors.isNotEmpty() &&\n                anchors.fastAny {\n                    slots.ownsAnchor(it) &&\n                        slots.slot(slots.anchorIndex(it), 0) is RecomposeScopeImpl\n                }\n    }\n}\n```\n\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/source-code/ui-source.md",
    "content": "# Compose UI Source Reference\n\n## File: compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/AndroidCompositionLocals.android.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.ui.platform\n\nimport android.content.Context\nimport android.content.res.Configuration\nimport android.content.res.Resources\nimport android.view.View\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.runtime.compositionLocalWithComputedDefaultOf\nimport androidx.compose.runtime.staticCompositionLocalOf\nimport androidx.compose.ui.res.ImageVectorCache\nimport androidx.compose.ui.res.ResourceIdCache\nimport androidx.lifecycle.compose.LocalLifecycleOwner\nimport androidx.savedstate.SavedStateRegistryOwner\nimport androidx.savedstate.compose.LocalSavedStateRegistryOwner\n\n/**\n * The Android [Configuration]. The [Configuration] is useful for determining how to organize the\n * UI.\n */\nval LocalConfiguration =\n    compositionLocalOf<Configuration> { noLocalProvidedFor(\"LocalConfiguration\") }\n\n/** Provides a [Context] that can be used by Android applications. */\nval LocalContext = staticCompositionLocalOf<Context> { noLocalProvidedFor(\"LocalContext\") }\n\n/**\n * The Android [Resources]. This will be updated when [LocalConfiguration] changes, to ensure that\n * calls to APIs such as [Resources.getString] return updated values.\n */\nval LocalResources =\n    compositionLocalWithComputedDefaultOf<Resources> {\n        // Read LocalConfiguration here to invalidate callers of LocalResources when the\n        // configuration changes. This is preferable to explicitly providing the resources object\n        // because the resources object can still have the same instance, even though the\n        // configuration changed, which would mean that callers would not get invalidated. To\n        // resolve that we would need to use neverEqualPolicy to force an invalidation even though\n        // the Resources didn't change, but then that would cause invalidations every time the\n        // providing Composable is recomposed, regardless of whether a configuration change happened\n        // or not.\n        LocalConfiguration.currentValue\n        LocalContext.currentValue.resources\n    }\n\ninternal val LocalImageVectorCache =\n    staticCompositionLocalOf<ImageVectorCache> { noLocalProvidedFor(\"LocalImageVectorCache\") }\n\ninternal val LocalResourceIdCache =\n    staticCompositionLocalOf<ResourceIdCache> { noLocalProvidedFor(\"LocalResourceIdCache\") }\n\n@Deprecated(\n    \"Moved to lifecycle-runtime-compose library in androidx.lifecycle.compose package.\",\n    ReplaceWith(\"androidx.lifecycle.compose.LocalLifecycleOwner\"),\n)\nactual val LocalLifecycleOwner\n    get() = LocalLifecycleOwner\n\n/** The CompositionLocal containing the current [SavedStateRegistryOwner]. */\n@Deprecated(\n    \"Moved to savedstate-compose library in androidx.savedstate.compose package.\",\n    ReplaceWith(\"androidx.savedstate.compose.LocalSavedStateRegistryOwner\"),\n)\nval LocalSavedStateRegistryOwner\n    get() = LocalSavedStateRegistryOwner\n\n/** The CompositionLocal containing the current Compose [View]. */\nval LocalView = staticCompositionLocalOf<View> { noLocalProvidedFor(\"LocalView\") }\n\nprivate fun noLocalProvidedFor(name: String): Nothing {\n    error(\"CompositionLocal $name not present\")\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/Modifier.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.ui\n\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.internal.JvmDefaultWithCompatibility\nimport androidx.compose.ui.internal.PlatformOptimizedCancellationException\nimport androidx.compose.ui.internal.checkPrecondition\nimport androidx.compose.ui.node.DelegatableNode\nimport androidx.compose.ui.node.DrawModifierNode\nimport androidx.compose.ui.node.NodeCoordinator\nimport androidx.compose.ui.node.NodeKind\nimport androidx.compose.ui.node.ObserverNodeOwnerScope\nimport androidx.compose.ui.node.requireOwner\nimport kotlinx.coroutines.CoroutineScope\nimport kotlinx.coroutines.Job\nimport kotlinx.coroutines.cancel\n\ninternal class ModifierNodeDetachedCancellationException :\n    PlatformOptimizedCancellationException(\"The Modifier.Node was detached\")\n\n/**\n * An ordered, immutable collection of [modifier elements][Modifier.Element] that decorate or add\n * behavior to Compose UI elements. For example, backgrounds, padding and click event listeners\n * decorate or add behavior to rows, text or buttons.\n *\n * @sample androidx.compose.ui.samples.ModifierUsageSample\n *\n * Modifier implementations should offer a fluent factory extension function on [Modifier] for\n * creating combined modifiers by starting from existing modifiers:\n *\n * @sample androidx.compose.ui.samples.ModifierFactorySample\n *\n * Modifier elements may be combined using [then]. Order is significant; modifier elements that\n * appear first will be applied first.\n *\n * Composables that accept a [Modifier] as a parameter to be applied to the whole component\n * represented by the composable function should name the parameter `modifier` and assign the\n * parameter a default value of [Modifier]. It should appear as the first optional parameter in the\n * parameter list; after all required parameters (except for trailing lambda parameters) but before\n * any other parameters with default values. Any default modifiers desired by a composable function\n * should come after the `modifier` parameter's value in the composable function's implementation,\n * keeping [Modifier] as the default parameter value. For example:\n *\n * @sample androidx.compose.ui.samples.ModifierParameterSample\n *\n * The pattern above allows default modifiers to still be applied as part of the chain if a caller\n * also supplies unrelated modifiers.\n *\n * Composables that accept modifiers to be applied to a specific subcomponent `foo` should name the\n * parameter `fooModifier` and follow the same guidelines above for default values and behavior.\n * Subcomponent modifiers should be grouped together and follow the parent composable's modifier.\n * For example:\n *\n * @sample androidx.compose.ui.samples.SubcomponentModifierSample\n */\n@Suppress(\"ModifierFactoryExtensionFunction\")\n@Stable\n@JvmDefaultWithCompatibility\ninterface Modifier {\n\n    /**\n     * Accumulates a value starting with [initial] and applying [operation] to the current value and\n     * each element from outside in.\n     *\n     * Elements wrap one another in a chain from left to right; an [Element] that appears to the\n     * left of another in a `+` expression or in [operation]'s parameter order affects all of the\n     * elements that appear after it. [foldIn] may be used to accumulate a value starting from the\n     * parent or head of the modifier chain to the final wrapped child.\n     */\n    fun <R> foldIn(initial: R, operation: (R, Element) -> R): R\n\n    /**\n     * Accumulates a value starting with [initial] and applying [operation] to the current value and\n     * each element from inside out.\n     *\n     * Elements wrap one another in a chain from left to right; an [Element] that appears to the\n     * left of another in a `+` expression or in [operation]'s parameter order affects all of the\n     * elements that appear after it. [foldOut] may be used to accumulate a value starting from the\n     * child or tail of the modifier chain up to the parent or head of the chain.\n     */\n    fun <R> foldOut(initial: R, operation: (Element, R) -> R): R\n\n    /** Returns `true` if [predicate] returns true for any [Element] in this [Modifier]. */\n    fun any(predicate: (Element) -> Boolean): Boolean\n\n    /**\n     * Returns `true` if [predicate] returns true for all [Element]s in this [Modifier] or if this\n     * [Modifier] contains no [Element]s.\n     */\n    fun all(predicate: (Element) -> Boolean): Boolean\n\n    /**\n     * Concatenates this modifier with another.\n     *\n     * Returns a [Modifier] representing this modifier followed by [other] in sequence.\n     */\n    infix fun then(other: Modifier): Modifier =\n        if (other === Modifier) this else CombinedModifier(this, other)\n\n    /** A single element contained within a [Modifier] chain. */\n    @JvmDefaultWithCompatibility\n    interface Element : Modifier {\n        override fun <R> foldIn(initial: R, operation: (R, Element) -> R): R =\n            operation(initial, this)\n\n        override fun <R> foldOut(initial: R, operation: (Element, R) -> R): R =\n            operation(this, initial)\n\n        override fun any(predicate: (Element) -> Boolean): Boolean = predicate(this)\n\n        override fun all(predicate: (Element) -> Boolean): Boolean = predicate(this)\n    }\n\n    /**\n     * The longer-lived object that is created for each [Modifier.Element] applied to a\n     * [androidx.compose.ui.layout.Layout]. Most [Modifier.Node] implementations will have a\n     * corresponding \"Modifier Factory\" extension method on Modifier that will allow them to be used\n     * indirectly, without ever implementing a [Modifier.Node] subclass directly. In some cases it\n     * may be useful to define a custom [Modifier.Node] subclass in order to efficiently implement\n     * some collection of behaviors that requires maintaining state over time and over many\n     * recompositions where the various provided Modifier factories are not sufficient.\n     *\n     * When a [Modifier] is set on a [androidx.compose.ui.layout.Layout], each [Modifier.Element]\n     * contained in that linked list will result in a corresponding [Modifier.Node] instance in a\n     * matching linked list of [Modifier.Node]s that the [androidx.compose.ui.layout.Layout] will\n     * hold on to. As subsequent [Modifier] chains get set on the\n     * [androidx.compose.ui.layout.Layout], the linked list of [Modifier.Node]s will be diffed and\n     * updated as appropriate, even though the [Modifier] instance might be completely new. As a\n     * result, the lifetime of a [Modifier.Node] is the intersection of the lifetime of the\n     * [androidx.compose.ui.layout.Layout] that it lives on and a corresponding [Modifier.Element]\n     * being present in the [androidx.compose.ui.layout.Layout]'s [Modifier].\n     *\n     * If one creates a subclass of [Modifier.Node], it is expected that it will implement one or\n     * more interfaces that interact with the various Compose UI subsystems. To use the\n     * [Modifier.Node] subclass, it is expected that it will be instantiated by adding a\n     * [androidx.compose.ui.node.ModifierNodeElement] to a [Modifier] chain.\n     *\n     * @see androidx.compose.ui.node.ModifierNodeElement\n     * @see androidx.compose.ui.node.CompositionLocalConsumerModifierNode\n     * @see androidx.compose.ui.node.DelegatableNode\n     * @see androidx.compose.ui.node.DelegatingNode\n     * @see androidx.compose.ui.node.LayoutModifierNode\n     * @see androidx.compose.ui.node.DrawModifierNode\n     * @see androidx.compose.ui.node.SemanticsModifierNode\n     * @see androidx.compose.ui.node.PointerInputModifierNode\n     * @see androidx.compose.ui.modifier.ModifierLocalModifierNode\n     * @see androidx.compose.ui.node.ParentDataModifierNode\n     * @see androidx.compose.ui.node.LayoutAwareModifierNode\n     * @see androidx.compose.ui.node.GlobalPositionAwareModifierNode\n     * @see androidx.compose.ui.node.ApproachLayoutModifierNode\n     */\n    abstract class Node : DelegatableNode {\n        @Suppress(\"LeakingThis\")\n        final override var node: Node = this\n            private set\n\n        private var scope: CoroutineScope? = null\n\n        /**\n         * A [CoroutineScope] that can be used to launch tasks that should run while the node is\n         * attached.\n         *\n         * The scope is accessible between [onAttach] and [onDetach] calls, and will be cancelled\n         * after the node is detached (after [onDetach] returns).\n         *\n         * @sample androidx.compose.ui.samples.ModifierNodeCoroutineScopeSample\n         * @throws IllegalStateException If called while the node is not attached.\n         */\n        val coroutineScope: CoroutineScope\n            get() =\n                scope\n                    ?: CoroutineScope(\n                            requireOwner().coroutineContext +\n                                Job(parent = requireOwner().coroutineContext[Job])\n                        )\n                        .also { scope = it }\n\n        internal var kindSet: Int = 0\n\n        // NOTE: We use an aggregate mask that or's all of the type masks of the children of the\n        // chain so that we can quickly prune a subtree. This INCLUDES the kindSet of this node\n        // as well. Initialize this to \"every node\" so that before it is set it doesn't\n        // accidentally cause a truncated traversal.\n        internal var aggregateChildKindSet: Int = 0.inv()\n        internal var parent: Node? = null\n        internal var child: Node? = null\n        internal var ownerScope: ObserverNodeOwnerScope? = null\n        internal var coordinator: NodeCoordinator? = null\n            private set\n\n        internal var insertedNodeAwaitingAttachForInvalidation = false\n        internal var updatedNodeAwaitingAttachForInvalidation = false\n        private var onAttachRunExpected = false\n        private var onDetachRunExpected = false\n\n        internal var detachedListener: (() -> Unit)? = null\n\n        /**\n         * Indicates that the node is attached to a [androidx.compose.ui.layout.Layout] which is\n         * part of the UI tree. This will get set to true right before [onAttach] is called, and set\n         * to false right after [onDetach] is called.\n         *\n         * @see onAttach\n         * @see onDetach\n         */\n        var isAttached: Boolean = false\n            private set\n\n        /**\n         * If this property returns `true`, then nodes will be automatically invalidated after the\n         * modifier update completes (For example, if the returned Node is a [DrawModifierNode], its\n         * [DrawModifierNode.invalidateDraw] function will be invoked automatically as part of auto\n         * invalidation).\n         *\n         * This is enabled by default, and provides a convenient mechanism to schedule invalidation\n         * and apply changes made to the modifier. You may choose to set this to `false` if your\n         * modifier has auto-invalidatable properties that do not frequently require invalidation to\n         * improve performance by skipping unnecessary invalidation. If `autoInvalidate` is set to\n         * `false`, you must call the appropriate invalidate functions manually when the modifier is\n         * updated or else the updates may not be reflected in the UI appropriately.\n         */\n        @Suppress(\"GetterSetterNames\")\n        @get:Suppress(\"GetterSetterNames\")\n        open val shouldAutoInvalidate: Boolean\n            get() = true\n\n        internal open fun updateCoordinator(coordinator: NodeCoordinator?) {\n            this.coordinator = coordinator\n        }\n\n        @Suppress(\"NOTHING_TO_INLINE\")\n        internal inline fun isKind(kind: NodeKind<*>) = kindSet and kind.mask != 0\n\n        internal open fun markAsAttached() {\n            checkPrecondition(!isAttached) { \"node attached multiple times\" }\n            checkPrecondition(coordinator != null) {\n                \"attach invoked on a node without a coordinator\"\n            }\n            isAttached = true\n            onAttachRunExpected = true\n        }\n\n        internal open fun runAttachLifecycle() {\n            checkPrecondition(isAttached) {\n                \"Must run markAsAttached() prior to runAttachLifecycle\"\n            }\n            checkPrecondition(onAttachRunExpected) {\n                \"Must run runAttachLifecycle() only once \" + \"after markAsAttached()\"\n            }\n            onAttachRunExpected = false\n            onAttach()\n            onDetachRunExpected = true\n        }\n\n        internal open fun runDetachLifecycle() {\n            checkPrecondition(isAttached) { \"node detached multiple times\" }\n            checkPrecondition(coordinator != null) {\n                \"detach invoked on a node without a coordinator\"\n            }\n            checkPrecondition(onDetachRunExpected) {\n                \"Must run runDetachLifecycle() once after runAttachLifecycle() and before \" +\n                    \"markAsDetached()\"\n            }\n            onDetachRunExpected = false\n            detachedListener?.invoke()\n            onDetach()\n        }\n\n        internal open fun markAsDetached() {\n            checkPrecondition(isAttached) { \"Cannot detach a node that is not attached\" }\n            checkPrecondition(!onAttachRunExpected) {\n                \"Must run runAttachLifecycle() before markAsDetached()\"\n            }\n            checkPrecondition(!onDetachRunExpected) {\n                \"Must run runDetachLifecycle() before markAsDetached()\"\n            }\n            isAttached = false\n\n            scope?.let {\n                it.cancel(ModifierNodeDetachedCancellationException())\n                scope = null\n            }\n        }\n\n        internal open fun reset() {\n            checkPrecondition(isAttached) { \"reset() called on an unattached node\" }\n            onReset()\n        }\n\n        /**\n         * Called when the node is attached to a [androidx.compose.ui.layout.Layout] which is part\n         * of the UI tree. When called, `node` is guaranteed to be non-null. You can call\n         * sideEffect, coroutineScope, etc. This is not guaranteed to get called at a time where the\n         * rest of the Modifier.Nodes in the hierarchy are \"up to date\". For instance, at the time\n         * of calling onAttach for this node, another node may be in the tree that will be detached\n         * by the time Compose has finished applying changes. As a result, if you need to guarantee\n         * that the state of the tree is \"final\" for this round of changes, you should use the\n         * [sideEffect] API to schedule the calculation to be done at that time.\n         */\n        open fun onAttach() {}\n\n        /**\n         * Called when the node is not attached to a [androidx.compose.ui.layout.Layout] which is\n         * not a part of the UI tree anymore. Note that the node can be reattached again.\n         *\n         * This should be called right before the node gets removed from the list, so you should\n         * still be able to traverse inside of this method. Ideally we would not allow you to\n         * trigger side effects here.\n         */\n        open fun onDetach() {}\n\n        /**\n         * Called when the node is about to be moved to a pool of layouts ready to be reused. For\n         * example it happens when the node is part of the item of LazyColumn after this item is\n         * scrolled out of the viewport. This means this node could be in future reused for a\n         * [androidx.compose.ui.layout.Layout] displaying a semantically different content when the\n         * list will be populating a new item.\n         *\n         * Use this callback to reset some local item specific state, like \"is my component\n         * focused\".\n         *\n         * This callback is called while the node is attached. Right after this callback the node\n         * will be detached and later reattached when reused.\n         *\n         * @sample androidx.compose.ui.samples.ModifierNodeResetSample\n         */\n        open fun onReset() {}\n\n        /**\n         * This can be called to register [effect] as a function to be executed after all of the\n         * changes to the tree are applied.\n         *\n         * This API can only be called if the node [isAttached].\n         */\n        fun sideEffect(effect: () -> Unit) {\n            requireOwner().registerOnEndApplyChangesListener(effect)\n        }\n\n        internal open fun setAsDelegateTo(owner: Node) {\n            node = owner\n        }\n    }\n\n    /**\n     * The companion object `Modifier` is the empty, default, or starter [Modifier] that contains no\n     * [elements][Element]. Use it to create a new [Modifier] using modifier extension factory\n     * functions:\n     *\n     * @sample androidx.compose.ui.samples.ModifierUsageSample\n     *\n     * or as the default value for [Modifier] parameters:\n     *\n     * @sample androidx.compose.ui.samples.ModifierParameterSample\n     */\n    // The companion object implements `Modifier` so that it may be used as the start of a\n    // modifier extension factory expression.\n    companion object : Modifier {\n        override fun <R> foldIn(initial: R, operation: (R, Element) -> R): R = initial\n\n        override fun <R> foldOut(initial: R, operation: (Element, R) -> R): R = initial\n\n        override fun any(predicate: (Element) -> Boolean): Boolean = false\n\n        override fun all(predicate: (Element) -> Boolean): Boolean = true\n\n        override infix fun then(other: Modifier): Modifier = other\n\n        override fun toString() = \"Modifier\"\n    }\n}\n\n/**\n * A node in a [Modifier] chain. A CombinedModifier always contains at least two elements; a\n * Modifier [outer] that wraps around the Modifier [inner].\n */\nclass CombinedModifier(internal val outer: Modifier, internal val inner: Modifier) : Modifier {\n    override fun <R> foldIn(initial: R, operation: (R, Modifier.Element) -> R): R =\n        inner.foldIn(outer.foldIn(initial, operation), operation)\n\n    override fun <R> foldOut(initial: R, operation: (Modifier.Element, R) -> R): R =\n        outer.foldOut(inner.foldOut(initial, operation), operation)\n\n    override fun any(predicate: (Modifier.Element) -> Boolean): Boolean =\n        outer.any(predicate) || inner.any(predicate)\n\n    override fun all(predicate: (Modifier.Element) -> Boolean): Boolean =\n        outer.all(predicate) && inner.all(predicate)\n\n    override fun equals(other: Any?): Boolean =\n        other is CombinedModifier && outer == other.outer && inner == other.inner\n\n    override fun hashCode(): Int = outer.hashCode() + 31 * inner.hashCode()\n\n    override fun toString() =\n        \"[\" +\n            foldIn(\"\") { acc, element ->\n                if (acc.isEmpty()) element.toString() else \"$acc, $element\"\n            } +\n            \"]\"\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/Layout.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@file:Suppress(\"DEPRECATION\")\n\npackage androidx.compose.ui.layout\n\nimport androidx.compose.runtime.Applier\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.ReusableComposeNode\nimport androidx.compose.runtime.SkippableUpdater\nimport androidx.compose.runtime.currentComposer\nimport androidx.compose.runtime.currentCompositeKeyHash\nimport androidx.compose.runtime.currentCompositeKeyHashCode\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.UiComposable\nimport androidx.compose.ui.graphics.GraphicsLayerScope\nimport androidx.compose.ui.materialize\nimport androidx.compose.ui.materializeWithCompositionLocalInjectionInternal\nimport androidx.compose.ui.node.ComposeUiNode\nimport androidx.compose.ui.node.ComposeUiNode.Companion.ApplyOnDeactivatedNodeAssertion\nimport androidx.compose.ui.node.ComposeUiNode.Companion.SetCompositeKeyHash\nimport androidx.compose.ui.node.ComposeUiNode.Companion.SetMeasurePolicy\nimport androidx.compose.ui.node.ComposeUiNode.Companion.SetModifier\nimport androidx.compose.ui.node.ComposeUiNode.Companion.SetResolvedCompositionLocals\nimport androidx.compose.ui.node.LayoutNode\nimport androidx.compose.ui.node.checkMeasuredSize\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.util.fastCoerceAtLeast\nimport androidx.compose.ui.util.fastForEach\nimport kotlin.jvm.JvmName\n\n/**\n * [Layout] is the main core component for layout. It can be used to measure and position zero or\n * more layout children.\n *\n * The measurement, layout and intrinsic measurement behaviours of this layout will be defined by\n * the [measurePolicy] instance. See [MeasurePolicy] for more details.\n *\n * For a composable able to define its content according to the incoming constraints, see\n * [androidx.compose.foundation.layout.BoxWithConstraints].\n *\n * Example usage:\n *\n * @sample androidx.compose.ui.samples.LayoutUsage\n *\n * Example usage with custom intrinsic measurements:\n *\n * @sample androidx.compose.ui.samples.LayoutWithProvidedIntrinsicsUsage\n * @param content The children composable to be laid out.\n * @param modifier Modifiers to be applied to the layout.\n * @param measurePolicy The policy defining the measurement and positioning of the layout.\n * @see Layout\n * @see MeasurePolicy\n * @see androidx.compose.foundation.layout.BoxWithConstraints\n */\n@Suppress(\"ComposableLambdaParameterPosition\")\n@UiComposable\n@Composable\ninline fun Layout(\n    content: @Composable @UiComposable () -> Unit,\n    modifier: Modifier = Modifier,\n    measurePolicy: MeasurePolicy,\n) {\n    val compositeKeyHash = currentCompositeKeyHashCode.hashCode()\n    val localMap = currentComposer.currentCompositionLocalMap\n    val materialized = currentComposer.materialize(modifier)\n    ReusableComposeNode<ComposeUiNode, Applier<Any>>(\n        factory = ComposeUiNode.Constructor,\n        update = {\n            set(measurePolicy, SetMeasurePolicy)\n            set(localMap, SetResolvedCompositionLocals)\n            set(compositeKeyHash, SetCompositeKeyHash)\n            reconcile(ApplyOnDeactivatedNodeAssertion)\n            set(materialized, SetModifier)\n        },\n        content = content,\n    )\n}\n\n/**\n * [Layout] is the main core component for layout for \"leaf\" nodes. It can be used to measure and\n * position zero children.\n *\n * The measurement, layout and intrinsic measurement behaviours of this layout will be defined by\n * the [measurePolicy] instance. See [MeasurePolicy] for more details.\n *\n * For a composable able to define its content according to the incoming constraints, see\n * [androidx.compose.foundation.layout.BoxWithConstraints].\n *\n * Example usage:\n *\n * @sample androidx.compose.ui.samples.LayoutUsage\n *\n * Example usage with custom intrinsic measurements:\n *\n * @sample androidx.compose.ui.samples.LayoutWithProvidedIntrinsicsUsage\n * @param modifier Modifiers to be applied to the layout.\n * @param measurePolicy The policy defining the measurement and positioning of the layout.\n * @see Layout\n * @see MeasurePolicy\n * @see androidx.compose.foundation.layout.BoxWithConstraints\n */\n@Suppress(\"NOTHING_TO_INLINE\")\n@Composable\n@UiComposable\ninline fun Layout(modifier: Modifier = Modifier, measurePolicy: MeasurePolicy) {\n    val compositeKeyHash = currentCompositeKeyHashCode.hashCode()\n    val materialized = currentComposer.materialize(modifier)\n    val localMap = currentComposer.currentCompositionLocalMap\n    ReusableComposeNode<ComposeUiNode, Applier<Any>>(\n        factory = ComposeUiNode.Constructor,\n        update = {\n            set(measurePolicy, SetMeasurePolicy)\n            set(localMap, SetResolvedCompositionLocals)\n            reconcile(ApplyOnDeactivatedNodeAssertion)\n            set(materialized, SetModifier)\n            set(compositeKeyHash, SetCompositeKeyHash)\n        },\n    )\n}\n\n/**\n * [Layout] is the main core component for layout. It can be used to measure and position zero or\n * more layout children.\n *\n * This overload accepts a list of multiple composable content lambdas, which allows treating\n * measurables put into different content lambdas differently - measure policy will provide a list\n * of lists of Measurables, not just a single list. Such list has the same size as the list of\n * contents passed into [Layout] and contains the list of measurables of the corresponding content\n * lambda in the same order.\n *\n * Note that layouts emitted as part of all [contents] lambdas will be added as a direct children\n * for this [Layout]. This means that if you set a custom z index on some children, the drawing\n * order will be calculated as if they were all provided as part of one lambda.\n *\n * Example usage:\n *\n * @sample androidx.compose.ui.samples.LayoutWithMultipleContentsUsage\n * @param contents The list of children composable contents to be laid out.\n * @param modifier Modifiers to be applied to the layout.\n * @param measurePolicy The policy defining the measurement and positioning of the layout.\n * @see Layout for a simpler use case when you have only one content lambda.\n */\n@Suppress(\"ComposableLambdaParameterPosition\", \"NOTHING_TO_INLINE\")\n@UiComposable\n@Composable\ninline fun Layout(\n    contents: List<@Composable @UiComposable () -> Unit>,\n    modifier: Modifier = Modifier,\n    measurePolicy: MultiContentMeasurePolicy,\n) {\n    Layout(\n        content = combineAsVirtualLayouts(contents),\n        modifier = modifier,\n        measurePolicy = remember(measurePolicy) { createMeasurePolicy(measurePolicy) },\n    )\n}\n\n@PublishedApi\ninternal fun combineAsVirtualLayouts(\n    contents: List<@Composable @UiComposable () -> Unit>\n): @Composable @UiComposable () -> Unit = {\n    contents.fastForEach { content ->\n        val compositeKeyHash = currentCompositeKeyHashCode.hashCode()\n        ReusableComposeNode<ComposeUiNode, Applier<Any>>(\n            factory = ComposeUiNode.VirtualConstructor,\n            update = { set(compositeKeyHash, SetCompositeKeyHash) },\n            content = content,\n        )\n    }\n}\n\n/**\n * This function uses a JVM-Name because the original name now has a different implementation for\n * backwards compatibility [materializerOfWithCompositionLocalInjection]. More details can be found\n * at https://issuetracker.google.com/275067189\n */\n@PublishedApi\n@JvmName(\"modifierMaterializerOf\")\ninternal fun materializerOf(\n    modifier: Modifier\n): @Composable SkippableUpdater<ComposeUiNode>.() -> Unit = {\n    val compositeKeyHash = currentCompositeKeyHashCode.hashCode()\n    val materialized = currentComposer.materialize(modifier)\n    update {\n        set(materialized, SetModifier)\n        set(compositeKeyHash, SetCompositeKeyHash)\n    }\n}\n\n/**\n * This function exists solely for solving a backwards-incompatibility with older compilations that\n * used an older version of the `Layout` composable. New code paths should not call this. More\n * details can be found at https://issuetracker.google.com/275067189\n */\n@JvmName(\"materializerOf\")\n@Deprecated(\n    \"Needed only for backwards compatibility. Do not use.\",\n    level = DeprecationLevel.WARNING,\n)\n@PublishedApi\ninternal fun materializerOfWithCompositionLocalInjection(\n    modifier: Modifier\n): @Composable SkippableUpdater<ComposeUiNode>.() -> Unit = {\n    val compositeKeyHash = currentCompositeKeyHash.hashCode()\n    val materialized = currentComposer.materializeWithCompositionLocalInjectionInternal(modifier)\n    update {\n        set(materialized, SetModifier)\n        set(compositeKeyHash, SetCompositeKeyHash)\n    }\n}\n\n@Suppress(\"ComposableLambdaParameterPosition\")\n@Composable\n@UiComposable\n@Deprecated(\n    \"This API is unsafe for UI performance at scale - using it incorrectly will lead \" +\n        \"to exponential performance issues. This API should be avoided whenever possible.\"\n)\nfun MultiMeasureLayout(\n    modifier: Modifier = Modifier,\n    content: @Composable @UiComposable () -> Unit,\n    measurePolicy: MeasurePolicy,\n) {\n    val compositeKeyHash = currentCompositeKeyHash.hashCode()\n    val materialized = currentComposer.materialize(modifier)\n    val localMap = currentComposer.currentCompositionLocalMap\n\n    ReusableComposeNode<LayoutNode, Applier<Any>>(\n        factory = LayoutNode.Constructor,\n        update = {\n            set(measurePolicy, SetMeasurePolicy)\n            set(localMap, SetResolvedCompositionLocals)\n            @Suppress(\"DEPRECATION\") init { this.canMultiMeasure = true }\n            reconcile(ApplyOnDeactivatedNodeAssertion)\n            set(materialized, SetModifier)\n            set(compositeKeyHash, SetCompositeKeyHash)\n        },\n        content = content,\n    )\n}\n\n/** Used to return a fixed sized item for intrinsics measurements in [Layout] */\nprivate class FixedSizeIntrinsicsPlaceable(width: Int, height: Int) : Placeable() {\n    init {\n        measuredSize = IntSize(width, height)\n    }\n\n    override fun get(alignmentLine: AlignmentLine): Int = AlignmentLine.Unspecified\n\n    override fun placeAt(\n        position: IntOffset,\n        zIndex: Float,\n        layerBlock: (GraphicsLayerScope.() -> Unit)?,\n    ) {}\n}\n\n/** Identifies an [IntrinsicMeasurable] as a min or max intrinsic measurement. */\ninternal enum class IntrinsicMinMax {\n    Min,\n    Max,\n}\n\n/** Identifies an [IntrinsicMeasurable] as a width or height intrinsic measurement. */\ninternal enum class IntrinsicWidthHeight {\n    Width,\n    Height,\n}\n\n// A large value to use as a replacement for Infinity with DefaultIntrinisicMeasurable.\n// A layout likely won't use this dimension as it is opposite from the one being measured in\n// the max/min Intrinsic Width/Height, but it is possible. For example, if the direct child\n// uses normal measurement/layout, we don't want to return Infinity sizes when its parent\n// asks for intrinsic size. 15 bits can fit in a Constraints, so should be safe unless\n// the parent adds to it and the other dimension is also very large (> 2^15).\ninternal const val LargeDimension = (1 shl 15) - 1\n\n/**\n * A wrapper around a [Measurable] for intrinsic measurements in [Layout]. Consumers of [Layout]\n * don't identify intrinsic methods, but we can give a reasonable implementation by using their\n * [measure], substituting the intrinsics gathering method for the [Measurable.measure] call.\n */\ninternal class DefaultIntrinsicMeasurable(\n    val measurable: IntrinsicMeasurable,\n    private val minMax: IntrinsicMinMax,\n    private val widthHeight: IntrinsicWidthHeight,\n) : Measurable {\n    override val parentData: Any?\n        get() = measurable.parentData\n\n    override fun measure(constraints: Constraints): Placeable {\n        if (widthHeight == IntrinsicWidthHeight.Width) {\n            val width =\n                if (minMax == IntrinsicMinMax.Max) {\n                    measurable.maxIntrinsicWidth(constraints.maxHeight)\n                } else {\n                    measurable.minIntrinsicWidth(constraints.maxHeight)\n                }\n            // Can't use infinity for height, so use a large number\n            val height = if (constraints.hasBoundedHeight) constraints.maxHeight else LargeDimension\n            return FixedSizeIntrinsicsPlaceable(width, height)\n        }\n        val height =\n            if (minMax == IntrinsicMinMax.Max) {\n                measurable.maxIntrinsicHeight(constraints.maxWidth)\n            } else {\n                measurable.minIntrinsicHeight(constraints.maxWidth)\n            }\n        // Can't use infinity for width, so use a large number\n        val width = if (constraints.hasBoundedWidth) constraints.maxWidth else LargeDimension\n        return FixedSizeIntrinsicsPlaceable(width, height)\n    }\n\n    override fun minIntrinsicWidth(height: Int): Int {\n        return measurable.minIntrinsicWidth(height)\n    }\n\n    override fun maxIntrinsicWidth(height: Int): Int {\n        return measurable.maxIntrinsicWidth(height)\n    }\n\n    override fun minIntrinsicHeight(width: Int): Int {\n        return measurable.minIntrinsicHeight(width)\n    }\n\n    override fun maxIntrinsicHeight(width: Int): Int {\n        return measurable.maxIntrinsicHeight(width)\n    }\n}\n\n/**\n * Receiver scope for [Layout]'s and [LayoutModifier]'s layout lambda when used in an intrinsics\n * call.\n */\ninternal class IntrinsicsMeasureScope(\n    intrinsicMeasureScope: IntrinsicMeasureScope,\n    override val layoutDirection: LayoutDirection,\n) : MeasureScope, IntrinsicMeasureScope by intrinsicMeasureScope {\n    override fun layout(\n        width: Int,\n        height: Int,\n        alignmentLines: Map<AlignmentLine, Int>,\n        rulers: (RulerScope.() -> Unit)?,\n        placementBlock: Placeable.PlacementScope.() -> Unit,\n    ): MeasureResult {\n        val w = width.fastCoerceAtLeast(0)\n        val h = height.fastCoerceAtLeast(0)\n        checkMeasuredSize(w, h)\n        return object : MeasureResult {\n            override val width: Int\n                get() = w\n\n            override val height: Int\n                get() = h\n\n            override val alignmentLines: Map<AlignmentLine, Int>\n                get() = alignmentLines\n\n            override val rulers: (RulerScope.() -> Unit)?\n                get() = rulers\n\n            override fun placeChildren() {\n                // Intrinsics should never be placed\n            }\n        }\n    }\n}\n\ninternal class ApproachIntrinsicsMeasureScope(\n    intrinsicMeasureScope: ApproachIntrinsicMeasureScope,\n    override val layoutDirection: LayoutDirection,\n) : ApproachMeasureScope, ApproachIntrinsicMeasureScope by intrinsicMeasureScope {\n    override fun layout(\n        width: Int,\n        height: Int,\n        alignmentLines: Map<AlignmentLine, Int>,\n        rulers: (RulerScope.() -> Unit)?,\n        placementBlock: Placeable.PlacementScope.() -> Unit,\n    ): MeasureResult {\n        val w = width.fastCoerceAtLeast(0)\n        val h = height.fastCoerceAtLeast(0)\n        checkMeasuredSize(w, h)\n        return object : MeasureResult {\n            override val width: Int\n                get() = w\n\n            override val height: Int\n                get() = h\n\n            override val alignmentLines: Map<AlignmentLine, Int>\n                get() = alignmentLines\n\n            override val rulers: (RulerScope.() -> Unit)?\n                get() = rulers\n\n            override fun placeChildren() {\n                // Intrinsics should never be placed\n            }\n        }\n    }\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/MeasurePolicy.kt\n```kotlin\n/*\n * Copyright 2021 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.ui.layout\n\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.internal.JvmDefaultWithCompatibility\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.util.fastMap\n\n/**\n * Defines the measure and layout behavior of a [Layout]. [Layout] and [MeasurePolicy] are the way\n * Compose layouts (such as `Box`, `Column`, etc.) are built, and they can also be used to achieve\n * custom layouts.\n *\n * See [Layout] samples for examples of how to use [MeasurePolicy].\n *\n * Intrinsic measurement methods define the intrinsic size of the layout. These can be queried by\n * the layout's parent in order to obtain, in specific cases, more information about the size of the\n * layout in the absence of specific constraints:\n * - [minIntrinsicWidth] defines the minimum width this layout can take, given a specific height,\n *   such that the content of the layout will be painted correctly\n * - [minIntrinsicHeight] defines the minimum height this layout can take, given a specific width,\n *   such that the content of the layout will be painted correctly\n * - [maxIntrinsicWidth] defines the minimum width such that increasing it further will not decrease\n *   the minimum intrinsic height\n * - [maxIntrinsicHeight] defines the minimum height such that increasing it further will not\n *   decrease the minimum intrinsic width\n *\n * Most layout scenarios do not require querying intrinsic measurements. Therefore, when writing a\n * custom layout, it is common to only define the actual measurement, as most of the times the\n * intrinsic measurements of the layout will not be queried. Moreover, intrinsic measurement methods\n * have default implementations that make a best effort attempt to calculate the intrinsic\n * measurements by reusing the [measure] method. Note this will not be correct for all layouts, but\n * can be a convenient approximation.\n *\n * Intrinsic measurements can be useful when the layout system enforcement of no more than one\n * measurement per child is limiting. Layouts that use them are the `preferredWidth(IntrinsicSize)`\n * and `preferredHeight(IntrinsicSize)` modifiers. See their samples for when they can be useful.\n *\n * @see Layout\n */\n@Stable\n@JvmDefaultWithCompatibility\nfun interface MeasurePolicy {\n    /**\n     * The function that defines the measurement and layout. Each [Measurable] in the [measurables]\n     * list corresponds to a layout child of the layout, and children can be measured using the\n     * [Measurable.measure] method. This method takes the [Constraints] which the child should\n     * respect; different children can be measured with different constraints.\n     *\n     * Measuring a child returns a [Placeable], which reveals the size chosen by the child as a\n     * result of its own measurement. According to the children sizes, the parent defines the\n     * position of the children, by [placing][Placeable.PlacementScope.place] the [Placeable]s in\n     * the [MeasureResult.placeChildren] of the returned [MeasureResult]. Therefore the parent needs\n     * to measure its children with appropriate [Constraints], such that whatever valid sizes\n     * children choose, they can be laid out correctly according to the parent's layout algorithm.\n     * This is because there is no measurement negotiation between the parent and children: once a\n     * child chooses its size, the parent needs to handle it correctly.\n     *\n     * Note that a child is allowed to choose a size that does not satisfy its constraints. However,\n     * when this happens, the placeable's [width][Placeable.width] and [height][Placeable.height]\n     * will not represent the real size of the child, but rather the size coerced in the child's\n     * constraints. Therefore, it is common for parents to assume in their layout algorithm that its\n     * children will always respect the constraints. When this does not happen in reality, the\n     * position assigned to the child will be automatically offset to be centered on the space\n     * assigned by the parent under the assumption that constraints were respected. Rarely, when a\n     * parent really needs to know the true size of the child, they can read this from the\n     * placeable's [Placeable.measuredWidth] and [Placeable.measuredHeight].\n     *\n     * [MeasureResult] objects are usually created using the [MeasureScope.layout] factory, which\n     * takes the calculated size of this layout, its alignment lines, and a block defining the\n     * positioning of the children layouts.\n     */\n    fun MeasureScope.measure(measurables: List<Measurable>, constraints: Constraints): MeasureResult\n\n    /**\n     * The function used to calculate [IntrinsicMeasurable.minIntrinsicWidth]. It represents the\n     * minimum width this layout can take, given a specific height, such that the content of the\n     * layout can be painted correctly. There should be no side-effect from implementers of\n     * [minIntrinsicWidth].\n     */\n    fun IntrinsicMeasureScope.minIntrinsicWidth(\n        measurables: List<IntrinsicMeasurable>,\n        height: Int,\n    ): Int {\n        val mapped =\n            measurables.fastMap {\n                DefaultIntrinsicMeasurable(it, IntrinsicMinMax.Min, IntrinsicWidthHeight.Width)\n            }\n        val constraints = Constraints(maxHeight = height)\n        val layoutReceiver = IntrinsicsMeasureScope(this, layoutDirection)\n        val layoutResult = layoutReceiver.measure(mapped, constraints)\n        return layoutResult.width\n    }\n\n    /**\n     * The function used to calculate [IntrinsicMeasurable.minIntrinsicHeight]. It represents the\n     * minimum height this layout can take, given a specific width, such that the content of the\n     * layout will be painted correctly. There should be no side-effect from implementers of\n     * [minIntrinsicHeight].\n     */\n    fun IntrinsicMeasureScope.minIntrinsicHeight(\n        measurables: List<IntrinsicMeasurable>,\n        width: Int,\n    ): Int {\n        val mapped =\n            measurables.fastMap {\n                DefaultIntrinsicMeasurable(it, IntrinsicMinMax.Min, IntrinsicWidthHeight.Height)\n            }\n        val constraints = Constraints(maxWidth = width)\n        val layoutReceiver = IntrinsicsMeasureScope(this, layoutDirection)\n        val layoutResult = layoutReceiver.measure(mapped, constraints)\n        return layoutResult.height\n    }\n\n    /**\n     * The function used to calculate [IntrinsicMeasurable.maxIntrinsicWidth]. It represents the\n     * minimum width such that increasing it further will not decrease the minimum intrinsic height.\n     * There should be no side-effects from implementers of [maxIntrinsicWidth].\n     */\n    fun IntrinsicMeasureScope.maxIntrinsicWidth(\n        measurables: List<IntrinsicMeasurable>,\n        height: Int,\n    ): Int {\n        val mapped =\n            measurables.fastMap {\n                DefaultIntrinsicMeasurable(it, IntrinsicMinMax.Max, IntrinsicWidthHeight.Width)\n            }\n        val constraints = Constraints(maxHeight = height)\n        val layoutReceiver = IntrinsicsMeasureScope(this, layoutDirection)\n        val layoutResult = layoutReceiver.measure(mapped, constraints)\n        return layoutResult.width\n    }\n\n    /**\n     * The function used to calculate [IntrinsicMeasurable.maxIntrinsicHeight]. It represents the\n     * minimum height such that increasing it further will not decrease the minimum intrinsic width.\n     * There should be no side-effects from implementers of [maxIntrinsicHeight].\n     */\n    fun IntrinsicMeasureScope.maxIntrinsicHeight(\n        measurables: List<IntrinsicMeasurable>,\n        width: Int,\n    ): Int {\n        val mapped =\n            measurables.fastMap {\n                DefaultIntrinsicMeasurable(it, IntrinsicMinMax.Max, IntrinsicWidthHeight.Height)\n            }\n        val constraints = Constraints(maxWidth = width)\n        val layoutReceiver = IntrinsicsMeasureScope(this, layoutDirection)\n        val layoutResult = layoutReceiver.measure(mapped, constraints)\n        return layoutResult.height\n    }\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/SubcomposeLayout.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.ui.layout\n\nimport androidx.collection.IntList\nimport androidx.collection.MutableOrderedScatterSet\nimport androidx.collection.mutableIntListOf\nimport androidx.collection.mutableIntSetOf\nimport androidx.collection.mutableOrderedScatterSetOf\nimport androidx.collection.mutableScatterMapOf\nimport androidx.compose.runtime.Applier\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.ComposeNodeLifecycleCallback\nimport androidx.compose.runtime.CompositionContext\nimport androidx.compose.runtime.PausableComposition\nimport androidx.compose.runtime.PausedComposition\nimport androidx.compose.runtime.ReusableComposeNode\nimport androidx.compose.runtime.ReusableComposition\nimport androidx.compose.runtime.ReusableContentHost\nimport androidx.compose.runtime.ShouldPauseCallback\nimport androidx.compose.runtime.SideEffect\nimport androidx.compose.runtime.collection.mutableVectorOf\nimport androidx.compose.runtime.currentComposer\nimport androidx.compose.runtime.currentCompositeKeyHashCode\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCompositionContext\nimport androidx.compose.runtime.snapshots.Snapshot\nimport androidx.compose.ui.ExperimentalComposeUiApi\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.UiComposable\nimport androidx.compose.ui.internal.checkPrecondition\nimport androidx.compose.ui.internal.requirePrecondition\nimport androidx.compose.ui.internal.throwIllegalStateExceptionForNullCheck\nimport androidx.compose.ui.internal.throwIndexOutOfBoundsException\nimport androidx.compose.ui.layout.SubcomposeLayoutState.PausedPrecomposition\nimport androidx.compose.ui.layout.SubcomposeLayoutState.PrecomposedSlotHandle\nimport androidx.compose.ui.materialize\nimport androidx.compose.ui.node.ComposeUiNode.Companion.ApplyOnDeactivatedNodeAssertion\nimport androidx.compose.ui.node.ComposeUiNode.Companion.SetCompositeKeyHash\nimport androidx.compose.ui.node.ComposeUiNode.Companion.SetModifier\nimport androidx.compose.ui.node.ComposeUiNode.Companion.SetResolvedCompositionLocals\nimport androidx.compose.ui.node.LayoutNode\nimport androidx.compose.ui.node.LayoutNode.LayoutState\nimport androidx.compose.ui.node.LayoutNode.UsageByParent\nimport androidx.compose.ui.node.OutOfFrameExecutor\nimport androidx.compose.ui.node.TraversableNode\nimport androidx.compose.ui.node.TraversableNode.Companion.TraverseDescendantsAction\nimport androidx.compose.ui.node.checkMeasuredSize\nimport androidx.compose.ui.node.requireOwner\nimport androidx.compose.ui.node.traverseDescendants\nimport androidx.compose.ui.platform.createPausableSubcomposition\nimport androidx.compose.ui.platform.createSubcomposition\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.util.fastForEach\nimport kotlin.jvm.JvmInline\n\n/**\n * Analogue of [Layout] which allows to subcompose the actual content during the measuring stage for\n * example to use the values calculated during the measurement as params for the composition of the\n * children.\n *\n * Possible use cases:\n * * You need to know the constraints passed by the parent during the composition and can't solve\n *   your use case with just custom [Layout] or [LayoutModifier]. See\n *   [androidx.compose.foundation.layout.BoxWithConstraints].\n * * You want to use the size of one child during the composition of the second child.\n * * You want to compose your items lazily based on the available size. For example you have a list\n *   of 100 items and instead of composing all of them you only compose the ones which are currently\n *   visible(say 5 of them) and compose next items when the component is scrolled.\n *\n * @sample androidx.compose.ui.samples.SubcomposeLayoutSample\n * @param modifier [Modifier] to apply for the layout.\n * @param measurePolicy Measure policy which provides ability to subcompose during the measuring.\n */\n@Composable\nfun SubcomposeLayout(\n    modifier: Modifier = Modifier,\n    measurePolicy: SubcomposeMeasureScope.(Constraints) -> MeasureResult,\n) {\n    SubcomposeLayout(\n        state = remember { SubcomposeLayoutState() },\n        modifier = modifier,\n        measurePolicy = measurePolicy,\n    )\n}\n\n/**\n * Analogue of [Layout] which allows to subcompose the actual content during the measuring stage for\n * example to use the values calculated during the measurement as params for the composition of the\n * children.\n *\n * Possible use cases:\n * * You need to know the constraints passed by the parent during the composition and can't solve\n *   your use case with just custom [Layout] or [LayoutModifier]. See\n *   [androidx.compose.foundation.layout.BoxWithConstraints].\n * * You want to use the size of one child during the composition of the second child.\n * * You want to compose your items lazily based on the available size. For example you have a list\n *   of 100 items and instead of composing all of them you only compose the ones which are currently\n *   visible(say 5 of them) and compose next items when the component is scrolled.\n *\n * @sample androidx.compose.ui.samples.SubcomposeLayoutSample\n * @param state the state object to be used by the layout.\n * @param modifier [Modifier] to apply for the layout.\n * @param measurePolicy Measure policy which provides ability to subcompose during the measuring.\n */\n@Composable\n@UiComposable\nfun SubcomposeLayout(\n    state: SubcomposeLayoutState,\n    modifier: Modifier = Modifier,\n    measurePolicy: SubcomposeMeasureScope.(Constraints) -> MeasureResult,\n) {\n    val compositeKeyHash = currentCompositeKeyHashCode.hashCode()\n    val compositionContext = rememberCompositionContext()\n    val materialized = currentComposer.materialize(modifier)\n    val localMap = currentComposer.currentCompositionLocalMap\n    ReusableComposeNode<LayoutNode, Applier<Any>>(\n        factory = LayoutNode.Constructor,\n        update = {\n            set(state, state.setRoot)\n            set(compositionContext, state.setCompositionContext)\n            set(measurePolicy, state.setMeasurePolicy)\n            set(localMap, SetResolvedCompositionLocals)\n            reconcile(ApplyOnDeactivatedNodeAssertion)\n            set(materialized, SetModifier)\n            set(compositeKeyHash, SetCompositeKeyHash)\n        },\n    )\n    if (!currentComposer.skipping) {\n        SideEffect { state.forceRecomposeChildren() }\n    }\n}\n\n/**\n * The receiver scope of a [SubcomposeLayout]'s measure lambda which adds ability to dynamically\n * subcompose a content during the measuring on top of the features provided by [MeasureScope].\n */\ninterface SubcomposeMeasureScope : MeasureScope {\n    /**\n     * Performs subcomposition of the provided [content] with given [slotId].\n     *\n     * @param slotId unique id which represents the slot we are composing into. If you have fixed\n     *   amount or slots you can use enums as slot ids, or if you have a list of items maybe an\n     *   index in the list or some other unique key can work. To be able to correctly match the\n     *   content between remeasures you should provide the object which is equals to the one you\n     *   used during the previous measuring.\n     * @param content the composable content which defines the slot. It could emit multiple layouts,\n     *   in this case the returned list of [Measurable]s will have multiple elements. **Note:** When\n     *   a [SubcomposeLayout] is in a [LookaheadScope], the subcomposition only happens during the\n     *   lookahead pass. In the post-lookahead/main pass, [subcompose] will return the list of\n     *   [Measurable]s that were subcomposed during the lookahead pass. If the structure of the\n     *   subtree emitted from [content] is dependent on incoming constraints, consider using\n     *   constraints received from the lookahead pass for both passes.\n     */\n    fun subcompose(slotId: Any?, content: @Composable () -> Unit): List<Measurable>\n}\n\n/**\n * State used by [SubcomposeLayout].\n *\n * [slotReusePolicy] the policy defining what slots should be retained to be reused later.\n */\nclass SubcomposeLayoutState(private val slotReusePolicy: SubcomposeSlotReusePolicy) {\n    /** State used by [SubcomposeLayout]. */\n    constructor() : this(NoOpSubcomposeSlotReusePolicy)\n\n    /**\n     * State used by [SubcomposeLayout].\n     *\n     * @param maxSlotsToRetainForReuse when non-zero the layout will keep active up to this count\n     *   slots which we were used but not used anymore instead of disposing them. Later when you try\n     *   to compose a new slot instead of creating a completely new slot the layout would reuse the\n     *   previous slot which allows to do less work especially if the slot contents are similar.\n     */\n    @Deprecated(\n        \"This constructor is deprecated\",\n        ReplaceWith(\n            \"SubcomposeLayoutState(SubcomposeSlotReusePolicy(maxSlotsToRetainForReuse))\",\n            \"androidx.compose.ui.layout.SubcomposeSlotReusePolicy\",\n        ),\n    )\n    constructor(\n        maxSlotsToRetainForReuse: Int\n    ) : this(SubcomposeSlotReusePolicy(maxSlotsToRetainForReuse))\n\n    private var _state: LayoutNodeSubcompositionsState? = null\n    private val state: LayoutNodeSubcompositionsState\n        get() =\n            requireNotNull(_state) { \"SubcomposeLayoutState is not attached to SubcomposeLayout\" }\n\n    // Pre-allocated lambdas to update LayoutNode\n    internal val setRoot: LayoutNode.(SubcomposeLayoutState) -> Unit = {\n        _state =\n            subcompositionsState\n                ?: LayoutNodeSubcompositionsState(this, slotReusePolicy).also {\n                    subcompositionsState = it\n                }\n        state.makeSureStateIsConsistent()\n        state.slotReusePolicy = slotReusePolicy\n    }\n    internal val setCompositionContext: LayoutNode.(CompositionContext) -> Unit = {\n        state.compositionContext = it\n    }\n    internal val setMeasurePolicy:\n        LayoutNode.((SubcomposeMeasureScope.(Constraints) -> MeasureResult)) -> Unit =\n        {\n            measurePolicy = state.createMeasurePolicy(it)\n        }\n\n    /**\n     * Composes the content for the given [slotId]. This makes the next scope.subcompose(slotId)\n     * call during the measure pass faster as the content is already composed.\n     *\n     * If the [slotId] was precomposed already but after the future calculations ended up to not be\n     * needed anymore (meaning this slotId is not going to be used during the measure pass anytime\n     * soon) you can use [PrecomposedSlotHandle.dispose] on a returned object to dispose the\n     * content.\n     *\n     * @param slotId unique id which represents the slot to compose into.\n     * @param content the composable content which defines the slot.\n     * @return [PrecomposedSlotHandle] instance which allows you to dispose the content.\n     */\n    fun precompose(slotId: Any?, content: @Composable () -> Unit): PrecomposedSlotHandle =\n        state.precompose(slotId, content)\n\n    /**\n     * Creates [PausedPrecomposition], which allows to perform the composition in an incremental\n     * manner.\n     *\n     * @param slotId unique id which represents the slot to compose into.\n     * @param content the composable content which defines the slot.]\n     * @return [PausedPrecomposition] for the given [slotId]. It allows to perform the composition\n     *   in an incremental manner. Performing full or partial precomposition makes the next\n     *   scope.subcompose(slotId) call during the measure pass faster as the content is already\n     *   composed.\n     */\n    fun createPausedPrecomposition(\n        slotId: Any?,\n        content: @Composable () -> Unit,\n    ): PausedPrecomposition = state.precomposePaused(slotId, content)\n\n    internal fun forceRecomposeChildren() = state.forceRecomposeChildren()\n\n    /**\n     * A [PausedPrecomposition] is a subcomposition that can be composed incrementally as it\n     * supports being paused and resumed.\n     *\n     * Pausable subcomposition can be used between frames to prepare a subcomposition before it is\n     * required by the main composition. For example, this is used in lazy lists to prepare list\n     * items in between frames to that are likely to be scrolled in. The composition is paused when\n     * the start of the next frame is near, allowing composition to be spread across multiple frames\n     * without delaying the production of the next frame.\n     *\n     * @see [PausedComposition]\n     */\n    sealed interface PausedPrecomposition {\n\n        /**\n         * Returns `true` when the [PausedPrecomposition] is complete. [isComplete] matches the last\n         * value returned from [resume]. Once a [PausedPrecomposition] is [isComplete] the [apply]\n         * method should be called. If the [apply] method is not called synchronously and\n         * immediately after [resume] returns `true` then this [isComplete] can return `false` as\n         * any state changes read by the paused composition while it is paused will cause the\n         * composition to require the paused composition to need to be resumed before it is used.\n         */\n        val isComplete: Boolean\n\n        /**\n         * Resume the composition that has been paused. This method should be called until [resume]\n         * returns `true` or [isComplete] is `true` which has the same result as the last result of\n         * calling [resume]. The [shouldPause] parameter is a lambda that returns whether the\n         * composition should be paused. For example, in lazy lists this returns `false` until just\n         * prior to the next frame starting in which it returns `true`\n         *\n         * Calling [resume] after it returns `true` or when `isComplete` is true will throw an\n         * exception.\n         *\n         * @param shouldPause A lambda that is used to determine if the composition should be\n         *   paused. This lambda is called often so should be a very simple calculation. Returning\n         *   `true` does not guarantee the composition will pause, it should only be considered a\n         *   request to pause the composition. Not all composable functions are pausable and only\n         *   pausable composition functions will pause.\n         * @return `true` if the composition is complete and `false` if one or more calls to\n         *   `resume` are required to complete composition.\n         */\n        @Suppress(\"ExecutorRegistration\") fun resume(shouldPause: ShouldPauseCallback): Boolean\n\n        /**\n         * Apply the composition. This is the last step of a paused composition and is required to\n         * be called prior to the composition is usable.\n         *\n         * Calling [apply] should always be proceeded with a check of [isComplete] before it is\n         * called and potentially calling [resume] in a loop until [isComplete] returns `true`. This\n         * can happen if [resume] returned `true` but [apply] was not synchronously called\n         * immediately afterwords. Any state that was read that changed between when [resume] being\n         * called and [apply] being called may require the paused composition to be resumed before\n         * applied.\n         *\n         * @return [PrecomposedSlotHandle] you can use to premeasure the slot as well, or to dispose\n         *   the composed content.\n         */\n        fun apply(): PrecomposedSlotHandle\n\n        /**\n         * Cancels the paused composition. This should only be used if the composition is going to\n         * be disposed and the entire composition is not going to be used.\n         */\n        fun cancel()\n    }\n\n    /** Instance of this interface is returned by [precompose] function. */\n    interface PrecomposedSlotHandle {\n\n        /**\n         * This function allows to dispose the content for the slot which was precomposed previously\n         * via [precompose].\n         *\n         * If this slot was already used during the regular measure pass via\n         * [SubcomposeMeasureScope.subcompose] this function will do nothing.\n         *\n         * This could be useful if after the future calculations this item is not anymore expected\n         * to be used during the measure pass anytime soon.\n         */\n        fun dispose()\n\n        /** The amount of placeables composed into this slot. */\n        val placeablesCount: Int\n            get() = 0\n\n        /**\n         * Performs synchronous measure of the placeable at the given [index].\n         *\n         * @param index the placeable index. Should be smaller than [placeablesCount].\n         * @param constraints Constraints to measure this placeable with.\n         */\n        fun premeasure(index: Int, constraints: Constraints) {}\n\n        /**\n         * Conditionally executes [block] for each [Modifier.Node] of this Composition that is a\n         * [TraversableNode] with a matching [key].\n         *\n         * See [androidx.compose.ui.node.traverseDescendants] for the complete semantics of this\n         * function.\n         */\n        fun traverseDescendants(key: Any?, block: (TraversableNode) -> TraverseDescendantsAction) {}\n\n        /**\n         * Retrieves the latest measured size for a given placeable [index]. This will return\n         * [IntSize.Zero] if this is called before [premeasure].\n         */\n        fun getSize(index: Int): IntSize = IntSize.Zero\n    }\n}\n\n/**\n * This policy allows [SubcomposeLayout] to retain some of slots which we were used but not used\n * anymore instead of disposing them. Next time when you try to compose a new slot instead of\n * creating a completely new slot the layout would reuse the kept slot. This allows to do less work\n * especially if the slot contents are similar.\n */\ninterface SubcomposeSlotReusePolicy {\n    /**\n     * This function will be called with [slotIds] set populated with the slot ids available to\n     * reuse. In the implementation you can remove slots you don't want to retain.\n     */\n    fun getSlotsToRetain(slotIds: SlotIdsSet)\n\n    /**\n     * Returns true if the content previously composed with [reusableSlotId] is compatible with the\n     * content which is going to be composed for [slotId]. Slots could be considered incompatible if\n     * they display completely different types of the UI.\n     */\n    fun areCompatible(slotId: Any?, reusableSlotId: Any?): Boolean\n\n    /**\n     * Set containing slot ids currently available to reuse. Used by [getSlotsToRetain]. The set\n     * retains the insertion order of its elements, guaranteeing stable iteration order.\n     *\n     * This class works exactly as [MutableSet], but doesn't allow to add new items in it.\n     */\n    class SlotIdsSet\n    internal constructor(\n        @PublishedApi\n        internal val set: MutableOrderedScatterSet<Any?> = mutableOrderedScatterSetOf()\n    ) : Collection<Any?> {\n\n        override val size: Int\n            get() = set.size\n\n        override fun isEmpty(): Boolean = set.isEmpty()\n\n        override fun containsAll(elements: Collection<Any?>): Boolean {\n            elements.forEach { element ->\n                if (element !in set) {\n                    return false\n                }\n            }\n            return true\n        }\n\n        override fun contains(element: Any?): Boolean = set.contains(element)\n\n        internal fun add(slotId: Any?) = set.add(slotId)\n\n        override fun iterator(): MutableIterator<Any?> = set.asMutableSet().iterator()\n\n        /**\n         * Removes a [slotId] from this set, if it is present.\n         *\n         * @return `true` if the slot id was removed, `false` if the set was not modified.\n         */\n        fun remove(slotId: Any?): Boolean = set.remove(slotId)\n\n        /**\n         * Removes all slot ids from [slotIds] that are also contained in this set.\n         *\n         * @return `true` if any slot id was removed, `false` if the set was not modified.\n         */\n        fun removeAll(slotIds: Collection<Any?>): Boolean = set.remove(slotIds)\n\n        /**\n         * Removes all slot ids that match the given [predicate].\n         *\n         * @return `true` if any slot id was removed, `false` if the set was not modified.\n         */\n        fun removeAll(predicate: (Any?) -> Boolean): Boolean {\n            val size = set.size\n            set.removeIf(predicate)\n            return size != set.size\n        }\n\n        /**\n         * Retains only the slot ids that are contained in [slotIds].\n         *\n         * @return `true` if any slot id was removed, `false` if the set was not modified.\n         */\n        fun retainAll(slotIds: Collection<Any?>): Boolean = set.retainAll(slotIds)\n\n        /**\n         * Retains only slotIds that match the given [predicate].\n         *\n         * @return `true` if any slot id was removed, `false` if the set was not modified.\n         */\n        fun retainAll(predicate: (Any?) -> Boolean): Boolean = set.retainAll(predicate)\n\n        /** Removes all slot ids from this set. */\n        fun clear() = set.clear()\n\n        /**\n         * Remove entries until [size] equals [maxSlotsToRetainForReuse]. Entries inserted last are\n         * removed first.\n         */\n        fun trimToSize(maxSlotsToRetainForReuse: Int) = set.trimToSize(maxSlotsToRetainForReuse)\n\n        /**\n         * Iterates over every element stored in this set by invoking the specified [block] lambda.\n         * The iteration order is the same as the insertion order. It is safe to remove the element\n         * passed to [block] during iteration.\n         *\n         * NOTE: This method is obscured by `Collection<T>.forEach` since it is marked with\n         *\n         * @HidesMember, which means in practice this will never get called. Please use\n         *   [fastForEach] instead.\n         */\n        fun forEach(block: (Any?) -> Unit) = set.forEach(block)\n\n        /**\n         * Iterates over every element stored in this set by invoking the specified [block] lambda.\n         * The iteration order is the same as the insertion order. It is safe to remove the element\n         * passed to [block] during iteration.\n         *\n         * NOTE: this method was added in order to allow for a more performant forEach method. It is\n         * necessary because [forEach] is obscured by `Collection<T>.forEach` since it is marked\n         * with @HidesMember.\n         */\n        inline fun fastForEach(block: (Any?) -> Unit) = set.forEach(block)\n    }\n}\n\n/**\n * Creates [SubcomposeSlotReusePolicy] which retains the fixed amount of slots.\n *\n * @param maxSlotsToRetainForReuse the [SubcomposeLayout] will retain up to this amount of slots.\n */\nfun SubcomposeSlotReusePolicy(maxSlotsToRetainForReuse: Int): SubcomposeSlotReusePolicy =\n    FixedCountSubcomposeSlotReusePolicy(maxSlotsToRetainForReuse)\n\n/**\n * The inner state containing all the information about active slots and their compositions. It is\n * stored inside LayoutNode object as in fact we need to keep 1-1 mapping between this state and the\n * node: when we compose a slot we first create a virtual LayoutNode child to this node and then\n * save the extra information inside this state. Keeping this state inside LayoutNode also helps us\n * to retain the pool of reusable slots even when a new SubcomposeLayoutState is applied to\n * SubcomposeLayout and even when the SubcomposeLayout's LayoutNode is reused via the\n * ReusableComposeNode mechanism.\n */\n@OptIn(ExperimentalComposeUiApi::class)\ninternal class LayoutNodeSubcompositionsState(\n    private val root: LayoutNode,\n    slotReusePolicy: SubcomposeSlotReusePolicy,\n) : ComposeNodeLifecycleCallback {\n    var compositionContext: CompositionContext? = null\n\n    var slotReusePolicy: SubcomposeSlotReusePolicy = slotReusePolicy\n        set(value) {\n            if (field !== value) {\n                field = value\n                // the new policy will be applied after measure\n                markActiveNodesAsReused(deactivate = false)\n                root.requestRemeasure()\n            }\n        }\n\n    private var currentIndex = 0\n    private var currentApproachIndex = 0\n    private val nodeToNodeState = mutableScatterMapOf<LayoutNode, NodeState>()\n\n    // this map contains active slotIds (without precomposed or reusable nodes)\n    private val slotIdToNode = mutableScatterMapOf<Any?, LayoutNode>()\n    private val scope = Scope()\n    private val approachMeasureScope = ApproachMeasureScopeImpl()\n\n    private val precomposeMap = mutableScatterMapOf<Any?, LayoutNode>()\n    private val reusableSlotIdsSet = SubcomposeSlotReusePolicy.SlotIdsSet()\n\n    // SlotHandles precomposed in the approach pass. These slot handles are owned by the approach\n    // pass, hence the approach pass is responsible for disposing them when they are no longer\n    // needed. Note: if `precompose` is called on a slot owned by the approach pass, the\n    // approach will yield ownership to the new caller. When the new caller disposes a slot\n    // that is still needed by approach, the approach pass will be triggered to create\n    // and own the slot.\n    private val approachPrecomposeSlotHandleMap = mutableScatterMapOf<Any?, PrecomposedSlotHandle>()\n\n    // Slot ids of compositions needed in the approach pass. These compositions are either owned\n    // by the approach pass, or by the caller of [SubcomposeLayoutState#precompose]. For\n    // compositions not created by the approach pass, if they are disposed while the approach pass\n    // still needs it, the approach pass will be triggered to re-create the composition.\n    // The valid slot ids are stored between 0 and currentApproachIndex - 1, beyond index\n    // currentApproachIndex are [UnspecifiedSlotId]s.\n    private val slotIdsOfCompositionsNeededInApproach = mutableVectorOf<Any?>()\n\n    /**\n     * `root.foldedChildren` list consist of:\n     * 1) all the active children (used during the last measure pass)\n     * 2) `reusableCount` nodes in the middle of the list which were active and stopped being used.\n     *    now we keep them (up to `maxCountOfSlotsToReuse`) in order to reuse next time we will need\n     *    to compose a new item\n     * 4) `precomposedCount` nodes in the end of the list which were precomposed and are waiting to\n     *    be used during the next measure passes.\n     */\n    private var reusableCount = 0\n    private var precomposedCount = 0\n\n    override fun onReuse() {\n        markActiveNodesAsReused(deactivate = false)\n    }\n\n    override fun onDeactivate() {\n        markActiveNodesAsReused(deactivate = true)\n    }\n\n    override fun onRelease() {\n        disposeCurrentNodes()\n    }\n\n    fun subcompose(slotId: Any?, content: @Composable () -> Unit): List<Measurable> {\n        makeSureStateIsConsistent()\n        val layoutState = root.layoutState\n        checkPrecondition(\n            layoutState == LayoutState.Measuring ||\n                layoutState == LayoutState.LayingOut ||\n                layoutState == LayoutState.LookaheadMeasuring ||\n                layoutState == LayoutState.LookaheadLayingOut\n        ) {\n            \"subcompose can only be used inside the measure or layout blocks\"\n        }\n\n        val node =\n            slotIdToNode.getOrPut(slotId) {\n                val precomposed = precomposeMap.remove(slotId)\n                if (precomposed != null) {\n                    val nodeState = nodeToNodeState[precomposed]\n                    if (ExtraLoggingEnabled) {\n                        nodeState?.record(SLOperation.TookFromPrecomposeMap)\n                    }\n                    @Suppress(\"ExceptionMessage\") checkPrecondition(precomposedCount > 0)\n                    precomposedCount--\n                    precomposed\n                } else {\n                    takeNodeFromReusables(slotId) ?: createNodeAt(currentIndex)\n                }\n            }\n\n        if (root.foldedChildren.getOrNull(currentIndex) !== node) {\n            // the node has a new index in the list\n            val itemIndex = root.foldedChildren.indexOf(node)\n            requirePrecondition(itemIndex >= currentIndex) {\n                \"Key \\\"$slotId\\\" was already used. If you are using LazyColumn/Row please make \" +\n                    \"sure you provide a unique key for each item.\"\n            }\n            if (currentIndex != itemIndex) {\n                move(itemIndex, currentIndex)\n            }\n        }\n        currentIndex++\n\n        subcompose(node, slotId, pausable = false, content)\n\n        return if (layoutState == LayoutState.Measuring || layoutState == LayoutState.LayingOut) {\n            node.childMeasurables\n        } else {\n            node.childLookaheadMeasurables\n        }\n    }\n\n    // This may be called in approach pass, if a node is only emitted in the approach pass, but\n    // not in the lookahead pass.\n    private fun subcompose(\n        node: LayoutNode,\n        slotId: Any?,\n        pausable: Boolean,\n        content: @Composable () -> Unit,\n    ) {\n        val nodeState = nodeToNodeState.getOrPut(node) { NodeState(slotId, {}) }\n        val contentChanged = nodeState.content !== content\n        if (nodeState.pausedComposition != null) {\n            if (contentChanged) {\n                // content did change so it is not safe to apply the current paused composition.\n                nodeState.cancelPausedPrecomposition()\n            } else if (pausable) {\n                // the paused composition is initialized and the content didn't change\n                return\n            } else {\n                // we can apply as we are still composing the same content.\n                nodeState.applyPausedPrecomposition(shouldComplete = true)\n            }\n        }\n        val hasPendingChanges = nodeState.composition?.hasInvalidations ?: true\n        if (contentChanged || hasPendingChanges || nodeState.forceRecompose) {\n            nodeState.content = content\n            subcompose(node, nodeState, pausable)\n            nodeState.forceRecompose = false\n        }\n    }\n\n    private val outOfFrameExecutor: OutOfFrameExecutor?\n        get() = root.requireOwner().outOfFrameExecutor\n\n    private fun subcompose(node: LayoutNode, nodeState: NodeState, pausable: Boolean) {\n        requirePrecondition(nodeState.pausedComposition == null) {\n            \"new subcompose call while paused composition is still active\"\n        }\n        Snapshot.withoutReadObservation {\n            ignoreRemeasureRequests {\n                val existing = nodeState.composition\n                val parentComposition =\n                    compositionContext\n                        ?: throwIllegalStateExceptionForNullCheck(\n                            \"parent composition reference not set\"\n                        )\n                if (ExtraLoggingEnabled) {\n                    nodeState.record(\n                        if (existing == null) SLOperation.SubcomposeNew else SLOperation.Subcompose\n                    )\n                    if (pausable) {\n                        nodeState.record(SLOperation.SubcomposePausable)\n                    }\n                    if (nodeState.forceReuse) {\n                        nodeState.record(SLOperation.SubcomposeForceReuse)\n                    }\n                }\n                val composition =\n                    if (existing == null || existing.isDisposed) {\n                        if (pausable) {\n                            createPausableSubcomposition(node, parentComposition)\n                        } else {\n                            createSubcomposition(node, parentComposition)\n                        }\n                    } else {\n                        existing\n                    }\n                nodeState.composition = composition\n                val content = nodeState.content\n                val composable: @Composable () -> Unit =\n                    if (outOfFrameExecutor != null) {\n                        nodeState.composedWithReusableContentHost = false\n                        content\n                    } else {\n                        nodeState.composedWithReusableContentHost = true\n                        { ReusableContentHost(nodeState.active, content) }\n                    }\n                if (pausable) {\n                    composition as PausableComposition\n                    if (nodeState.forceReuse) {\n                        nodeState.pausedComposition =\n                            composition.setPausableContentWithReuse(composable)\n                    } else {\n                        nodeState.pausedComposition = composition.setPausableContent(composable)\n                    }\n                } else {\n                    if (nodeState.forceReuse) {\n                        composition.setContentWithReuse(composable)\n                    } else {\n                        composition.setContent(composable)\n                    }\n                }\n                nodeState.forceReuse = false\n            }\n        }\n    }\n\n    private fun getSlotIdAtIndex(foldedChildren: List<LayoutNode>, index: Int): Any? {\n        val node = foldedChildren[index]\n        return nodeToNodeState[node]!!.slotId\n    }\n\n    fun disposeOrReuseStartingFromIndex(startIndex: Int) {\n        reusableCount = 0\n        val foldedChildren = root.foldedChildren\n        val lastReusableIndex = foldedChildren.size - precomposedCount - 1\n        var needApplyNotification = false\n        if (startIndex <= lastReusableIndex) {\n            // construct the set of available slot ids\n            reusableSlotIdsSet.clear()\n            for (i in startIndex..lastReusableIndex) {\n                val slotId = getSlotIdAtIndex(foldedChildren, i)\n                reusableSlotIdsSet.add(slotId)\n            }\n\n            slotReusePolicy.getSlotsToRetain(reusableSlotIdsSet)\n            // iterating backwards so it is easier to remove items\n            var i = lastReusableIndex\n            Snapshot.withoutReadObservation {\n                while (i >= startIndex) {\n                    val node = foldedChildren[i]\n                    val nodeState = nodeToNodeState[node]!!\n                    val slotId = nodeState.slotId\n                    if (slotId in reusableSlotIdsSet) {\n                        reusableCount++\n                        if (nodeState.active) {\n                            node.resetLayoutState()\n                            nodeState.reuseComposition(forceDeactivate = false)\n\n                            if (nodeState.composedWithReusableContentHost) {\n                                needApplyNotification = true\n                            }\n                        }\n                    } else {\n                        ignoreRemeasureRequests {\n                            nodeToNodeState.remove(node)\n                            nodeState.composition?.dispose()\n                            root.removeAt(i, 1)\n                        }\n                    }\n                    // remove it from slotIdToNode so it is not considered active\n                    slotIdToNode.remove(slotId)\n                    i--\n                }\n            }\n        }\n\n        if (needApplyNotification) {\n            Snapshot.sendApplyNotifications()\n        }\n\n        makeSureStateIsConsistent()\n    }\n\n    private fun NodeState.deactivateOutOfFrame(executor: OutOfFrameExecutor) {\n        executor.schedule {\n            if (!active) {\n                if (ExtraLoggingEnabled) {\n                    record(SLOperation.DeactivateOutOfFrame)\n                }\n                composition?.deactivate()\n            } else {\n                if (ExtraLoggingEnabled) {\n                    record(SLOperation.DeactivateOutOfFrameCancelled)\n                }\n            }\n        }\n    }\n\n    private fun markActiveNodesAsReused(deactivate: Boolean) {\n        precomposedCount = 0\n        precomposeMap.clear()\n\n        val foldedChildren = root.foldedChildren\n        val childCount = foldedChildren.size\n        if (reusableCount != childCount) {\n            reusableCount = childCount\n            Snapshot.withoutReadObservation {\n                for (i in 0 until childCount) {\n                    val node = foldedChildren[i]\n                    val nodeState = nodeToNodeState[node]\n                    if (nodeState != null && nodeState.active) {\n                        node.resetLayoutState()\n                        nodeState.reuseComposition(forceDeactivate = deactivate)\n                        nodeState.slotId = ReusedSlotId\n                        if (ExtraLoggingEnabled) {\n                            if (deactivate) {\n                                nodeState.record(SLOperation.SlotToReusedFromOnDeactivate)\n                            } else {\n                                nodeState.record(SLOperation.SlotToReusedFromOnReuse)\n                            }\n                        }\n                    }\n                }\n            }\n            slotIdToNode.clear()\n        }\n\n        makeSureStateIsConsistent()\n    }\n\n    private fun disposeCurrentNodes() {\n        root.ignoreRemeasureRequests {\n            nodeToNodeState.forEachValue { it.composition?.dispose() }\n            root.removeAll()\n        }\n\n        nodeToNodeState.clear()\n        slotIdToNode.clear()\n        precomposedCount = 0\n        reusableCount = 0\n        precomposeMap.clear()\n\n        makeSureStateIsConsistent()\n    }\n\n    fun makeSureStateIsConsistent() {\n        val childrenCount = root.foldedChildren.size\n        requirePrecondition(nodeToNodeState.size == childrenCount) {\n            \"Inconsistency between the count of nodes tracked by the state \" +\n                \"(${nodeToNodeState.size}) and the children count on the SubcomposeLayout\" +\n                \" ($childrenCount). Are you trying to use the state of the\" +\n                \" disposed SubcomposeLayout?\"\n        }\n        requirePrecondition(childrenCount - reusableCount - precomposedCount >= 0) {\n            \"Incorrect state. Total children $childrenCount. Reusable children \" +\n                \"$reusableCount. Precomposed children $precomposedCount\"\n        }\n        requirePrecondition(precomposeMap.size == precomposedCount) {\n            \"Incorrect state. Precomposed children $precomposedCount. Map size \" +\n                \"${precomposeMap.size}\"\n        }\n    }\n\n    private fun LayoutNode.resetLayoutState() {\n        measurePassDelegate.measuredByParent = UsageByParent.NotUsed\n        lookaheadPassDelegate?.let { it.measuredByParent = UsageByParent.NotUsed }\n    }\n\n    private fun takeNodeFromReusables(slotId: Any?): LayoutNode? {\n        if (reusableCount == 0) {\n            return null\n        }\n        val foldedChildren = root.foldedChildren\n        val reusableNodesSectionEnd = foldedChildren.size - precomposedCount\n        val reusableNodesSectionStart = reusableNodesSectionEnd - reusableCount\n        var index = reusableNodesSectionEnd - 1\n        var chosenIndex = -1\n        // first try to find a node with exactly the same slotId\n        while (index >= reusableNodesSectionStart) {\n            if (getSlotIdAtIndex(foldedChildren, index) == slotId) {\n                // we have a node with the same slotId\n                chosenIndex = index\n                break\n            } else {\n                index--\n            }\n        }\n        if (chosenIndex == -1) {\n            // try to find a first compatible slotId from the end of the section\n            index = reusableNodesSectionEnd - 1\n            while (index >= reusableNodesSectionStart) {\n                val node = foldedChildren[index]\n                val nodeState = nodeToNodeState[node]!!\n                if (\n                    nodeState.slotId === ReusedSlotId ||\n                        slotReusePolicy.areCompatible(slotId, nodeState.slotId)\n                ) {\n                    nodeState.slotId = slotId\n                    chosenIndex = index\n                    break\n                }\n                index--\n            }\n        }\n        return if (chosenIndex == -1) {\n            // no compatible nodes found\n            null\n        } else {\n            if (index != reusableNodesSectionStart) {\n                // we need to rearrange the items\n                move(index, reusableNodesSectionStart, 1)\n            }\n            reusableCount--\n            val node = foldedChildren[reusableNodesSectionStart]\n            val nodeState = nodeToNodeState[node]!!\n            // create a new instance to avoid change notifications\n            if (ExtraLoggingEnabled) {\n                nodeState.record(SLOperation.Reused)\n            }\n            nodeState.activeState = mutableStateOf(true)\n            nodeState.forceReuse = true\n            nodeState.forceRecompose = true\n            node\n        }\n    }\n\n    fun createMeasurePolicy(\n        block: SubcomposeMeasureScope.(Constraints) -> MeasureResult\n    ): MeasurePolicy {\n        return object : LayoutNode.NoIntrinsicsMeasurePolicy(error = NoIntrinsicsMessage) {\n            override fun MeasureScope.measure(\n                measurables: List<Measurable>,\n                constraints: Constraints,\n            ): MeasureResult {\n                scope.layoutDirection = layoutDirection\n                scope.density = density\n                scope.fontScale = fontScale\n                if (!isLookingAhead && root.lookaheadRoot != null) {\n                    // Approach pass\n                    currentApproachIndex = 0\n                    val result = approachMeasureScope.block(constraints)\n                    val indexAfterMeasure = currentApproachIndex\n                    return createMeasureResult(result) {\n                        currentApproachIndex = indexAfterMeasure\n                        result.placeChildren()\n                        // dispose\n                        disposeUnusedSlotsInApproach()\n                        disposeOrReuseStartingFromIndex(currentIndex)\n                    }\n                } else {\n                    // Lookahead pass, or the main pass if not in a lookahead scope.\n                    currentIndex = 0\n                    val result = scope.block(constraints)\n                    val indexAfterMeasure = currentIndex\n                    return createMeasureResult(result) {\n                        currentIndex = indexAfterMeasure\n                        result.placeChildren()\n                        if (root.lookaheadRoot == null) {\n                            // If this is in lookahead scope, we need to dispose *after*\n                            // approach placement, to give approach pass the opportunity to\n                            // transfer the ownership of subcompositions before disposing.\n                            disposeOrReuseStartingFromIndex(currentIndex)\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    private fun disposeUnusedSlotsInApproach() {\n        // Iterate over the slots owned by approach, and dispose slots if neither lookahead\n        // nor approach needs it.\n        approachPrecomposeSlotHandleMap.removeIf { slotId, handle ->\n            val id = slotIdsOfCompositionsNeededInApproach.indexOf(slotId)\n            if (id < 0 || id >= currentApproachIndex) {\n                if (id >= 0) {\n                    // Remove the slotId from the list before disposing\n                    slotIdsOfCompositionsNeededInApproach[id] = UnspecifiedSlotId\n                }\n                if (precomposeMap.contains(slotId)) {\n                    // Node has not been needed by lookahead, or approach.\n                    handle.dispose()\n                }\n                true\n            } else {\n                false\n            }\n        }\n    }\n\n    private inline fun createMeasureResult(\n        result: MeasureResult,\n        crossinline placeChildrenBlock: () -> Unit,\n    ) =\n        object : MeasureResult by result {\n            override fun placeChildren() {\n                placeChildrenBlock()\n            }\n        }\n\n    private val NoIntrinsicsMessage =\n        \"Asking for intrinsic measurements of SubcomposeLayout \" +\n            \"layouts is not supported. This includes components that are built on top of \" +\n            \"SubcomposeLayout, such as lazy lists, BoxWithConstraints, TabRow, etc. To mitigate \" +\n            \"this:\\n\" +\n            \"- if intrinsic measurements are used to achieve 'match parent' sizing, consider \" +\n            \"replacing the parent of the component with a custom layout which controls the order in \" +\n            \"which children are measured, making intrinsic measurement not needed\\n\" +\n            \"- adding a size modifier to the component, in order to fast return the queried \" +\n            \"intrinsic measurement.\"\n\n    fun precompose(slotId: Any?, content: @Composable () -> Unit): PrecomposedSlotHandle {\n        precompose(slotId, content, pausable = false)\n        return createPrecomposedSlotHandle(slotId)\n    }\n\n    private fun precompose(slotId: Any?, content: @Composable () -> Unit, pausable: Boolean) {\n        if (!root.isAttached) {\n            return\n        }\n        makeSureStateIsConsistent()\n        if (!slotIdToNode.containsKey(slotId)) {\n            // Yield ownership of PrecomposedHandle from approach to the caller of precompose\n            approachPrecomposeSlotHandleMap.remove(slotId)\n            val node =\n                precomposeMap.getOrPut(slotId) {\n                    val reusedNode = takeNodeFromReusables(slotId)\n                    if (reusedNode != null) {\n                        // now move this node to the end where we keep precomposed items\n                        val nodeIndex = root.foldedChildren.indexOf(reusedNode)\n                        move(nodeIndex, root.foldedChildren.size, 1)\n                        precomposedCount++\n                        reusedNode\n                    } else {\n                        createNodeAt(root.foldedChildren.size).also { precomposedCount++ }\n                    }\n                }\n            subcompose(node, slotId, pausable = pausable, content)\n        }\n    }\n\n    private fun NodeState.reuseComposition(forceDeactivate: Boolean) {\n        if (!forceDeactivate && composedWithReusableContentHost) {\n            // Deactivation through ReusableContentHost is controlled with the active flag\n            active = false\n        } else {\n            // Otherwise, create a new instance to avoid state change notifications\n            activeState = mutableStateOf(false)\n        }\n\n        if (pausedComposition != null) {\n            // Cancelling disposes composition, so no additional work is needed.\n            cancelPausedPrecomposition()\n        } else if (forceDeactivate) {\n            if (ExtraLoggingEnabled) {\n                record(SLOperation.ReuseForceSyncDeactivation)\n            }\n            composition?.deactivate()\n        } else {\n            val outOfFrameExecutor = outOfFrameExecutor\n            if (outOfFrameExecutor != null) {\n                if (ExtraLoggingEnabled) {\n                    record(SLOperation.ReuseScheduleOutOfFrameDeactivation)\n                }\n                deactivateOutOfFrame(outOfFrameExecutor)\n            } else {\n                if (!composedWithReusableContentHost) {\n                    if (ExtraLoggingEnabled) {\n                        record(SLOperation.ReuseSyncDeactivation)\n                    }\n                    composition?.deactivate()\n                } else if (ExtraLoggingEnabled) {\n                    record(SLOperation.ReuseDeactivationViaHost)\n                }\n            }\n        }\n    }\n\n    private fun NodeState.cancelPausedPrecomposition() {\n        pausedComposition?.let {\n            it.cancel()\n            pausedComposition = null\n            composition?.dispose()\n            composition = null\n            if (ExtraLoggingEnabled) {\n                record(SLOperation.CancelPausedPrecomposition)\n            }\n        }\n    }\n\n    private fun disposePrecomposedSlot(slotId: Any?) {\n        makeSureStateIsConsistent()\n        val node = precomposeMap.remove(slotId)\n        if (node != null) {\n            checkPrecondition(precomposedCount > 0) { \"No pre-composed items to dispose\" }\n            val itemIndex = root.foldedChildren.indexOf(node)\n            checkPrecondition(itemIndex >= root.foldedChildren.size - precomposedCount) {\n                \"Item is not in pre-composed item range\"\n            }\n            // move this item into the reusable section\n            reusableCount++\n            precomposedCount--\n\n            nodeToNodeState[node]?.cancelPausedPrecomposition()\n\n            val reusableStart = root.foldedChildren.size - precomposedCount - reusableCount\n            move(itemIndex, reusableStart, 1)\n            disposeOrReuseStartingFromIndex(reusableStart)\n        }\n        // If the slot is not owned by approach (e.g. created for prefetch) and disposed before\n        // approach finishes using it, the approach pass will be invoked to re-create the\n        // composition if needed.\n        if (slotIdsOfCompositionsNeededInApproach.contains(slotId)) {\n            root.requestRemeasure(true)\n        }\n    }\n\n    private fun createPrecomposedSlotHandle(slotId: Any?): PrecomposedSlotHandle {\n        if (!root.isAttached) {\n            return object : PrecomposedSlotHandle {\n                override fun dispose() {}\n            }\n        }\n        return object : PrecomposedSlotHandle {\n            // Saves indices of placeables that have been premeasured in this handle\n            val hasPremeasured = mutableIntSetOf()\n\n            override fun dispose() {\n                disposePrecomposedSlot(slotId)\n            }\n\n            override val placeablesCount: Int\n                get() = precomposeMap[slotId]?.children?.size ?: 0\n\n            override fun premeasure(index: Int, constraints: Constraints) {\n                val node = precomposeMap[slotId]\n                if (node != null && node.isAttached) {\n                    val size = node.children.size\n                    if (index < 0 || index >= size) {\n                        throwIndexOutOfBoundsException(\n                            \"Index ($index) is out of bound of [0, $size)\"\n                        )\n                    }\n                    requirePrecondition(!node.isPlaced) {\n                        \"Pre-measure called on node that is not placed\"\n                    }\n                    root.ignoreRemeasureRequests {\n                        node.requireOwner().measureAndLayout(node.children[index], constraints)\n                    }\n                    hasPremeasured.add(index)\n                }\n            }\n\n            override fun traverseDescendants(\n                key: Any?,\n                block: (TraversableNode) -> TraverseDescendantsAction,\n            ) {\n                precomposeMap[slotId]?.nodes?.head?.traverseDescendants(key, block)\n            }\n\n            override fun getSize(index: Int): IntSize {\n                val node = precomposeMap[slotId]\n                if (node != null && node.isAttached) {\n                    val size = node.children.size\n                    if (index < 0 || index >= size) {\n                        throwIndexOutOfBoundsException(\n                            \"Index ($index) is out of bound of [0, $size)\"\n                        )\n                    }\n\n                    if (hasPremeasured.contains(index)) {\n                        return IntSize(node.children[index].width, node.children[index].height)\n                    }\n                }\n                return IntSize.Zero\n            }\n        }\n    }\n\n    fun precomposePaused(slotId: Any?, content: @Composable () -> Unit): PausedPrecomposition {\n        if (!root.isAttached) {\n            return object : PausedPrecompositionImpl {\n                override val isComplete: Boolean = true\n\n                override fun resume(shouldPause: ShouldPauseCallback) = true\n\n                override fun apply() = createPrecomposedSlotHandle(slotId)\n\n                override fun cancel() {}\n            }\n        }\n        precompose(slotId, content, pausable = true)\n        return object : PausedPrecompositionImpl {\n            override fun cancel() {\n                if (nodeState?.pausedComposition != null) {\n                    // only dispose if the paused composition is still waiting to be applied\n                    disposePrecomposedSlot(slotId)\n                }\n            }\n\n            private val nodeState: NodeState?\n                get() = precomposeMap[slotId]?.let { nodeToNodeState[it] }\n\n            override val isComplete: Boolean\n                get() = nodeState?.pausedComposition?.isComplete ?: true\n\n            override fun resume(shouldPause: ShouldPauseCallback): Boolean {\n                val nodeState = nodeState\n                val pausedComposition = nodeState?.pausedComposition\n                return if (pausedComposition != null && !pausedComposition.isComplete) {\n                    if (ExtraLoggingEnabled) {\n                        nodeState.record(SLOperation.ResumePaused)\n                    }\n                    val isComplete =\n                        Snapshot.withoutReadObservation {\n                            try {\n                                pausedComposition.resume(shouldPause)\n                            } catch (e: Throwable) {\n                                val operations = nodeState.operations\n                                if (operations != null) {\n                                    throw SubcomposeLayoutPausableCompositionException(\n                                        nodeState.operations,\n                                        slotId,\n                                        e,\n                                    )\n                                } else {\n                                    throw e\n                                }\n                            }\n                        }\n                    if (ExtraLoggingEnabled && !isComplete) {\n                        nodeState.record(SLOperation.PausePaused)\n                    }\n                    isComplete\n                } else {\n                    true\n                }\n            }\n\n            override fun apply(): PrecomposedSlotHandle {\n                nodeState?.applyPausedPrecomposition(shouldComplete = false)\n                return createPrecomposedSlotHandle(slotId)\n            }\n        }\n    }\n\n    fun forceRecomposeChildren() {\n        val childCount = root.foldedChildren.size\n        if (reusableCount != childCount) {\n            // only invalidate children if there are any non-reused ones\n            // in other cases, all of them are going to be invalidated later anyways\n            nodeToNodeState.forEachValue { nodeState -> nodeState.forceRecompose = true }\n\n            if (root.lookaheadRoot != null) {\n                // If the SubcomposeLayout is in a LookaheadScope, request for a lookahead measure\n                // so that lookahead gets triggered again to recompose children.\n                if (!root.lookaheadMeasurePending) {\n                    root.requestLookaheadRemeasure()\n                }\n            } else {\n                if (!root.measurePending) {\n                    root.requestRemeasure()\n                }\n            }\n        }\n    }\n\n    private fun createNodeAt(index: Int) =\n        LayoutNode(isVirtual = true).also { node ->\n            ignoreRemeasureRequests { root.insertAt(index, node) }\n        }\n\n    private fun move(from: Int, to: Int, count: Int = 1) {\n        ignoreRemeasureRequests { root.move(from, to, count) }\n    }\n\n    private inline fun <T> ignoreRemeasureRequests(block: () -> T): T =\n        root.ignoreRemeasureRequests(block)\n\n    private fun NodeState.applyPausedPrecomposition(shouldComplete: Boolean) {\n        val pausedComposition = pausedComposition\n        if (pausedComposition != null) {\n            Snapshot.withoutReadObservation {\n                ignoreRemeasureRequests {\n                    try {\n                        if (shouldComplete) {\n                            while (!pausedComposition.isComplete) {\n                                pausedComposition.resume { false }\n                            }\n                        }\n                        pausedComposition.apply()\n                    } catch (e: Throwable) {\n                        val operations = operations\n                        if (operations != null) {\n                            throw SubcomposeLayoutPausableCompositionException(\n                                operations,\n                                slotId,\n                                e,\n                            )\n                        } else {\n                            throw e\n                        }\n                    }\n                    this.pausedComposition = null\n                }\n            }\n        }\n    }\n\n    private class NodeState(\n        var slotId: Any?,\n        var content: @Composable () -> Unit,\n        var composition: ReusableComposition? = null,\n    ) {\n        var forceRecompose = false\n        var forceReuse = false\n        var pausedComposition: PausedComposition? = null\n        var activeState = mutableStateOf(true)\n        var composedWithReusableContentHost = false\n        var active: Boolean\n            get() = activeState.value\n            set(value) {\n                activeState.value = value\n            }\n\n        val operations = if (ExtraLoggingEnabled) mutableIntListOf() else null\n\n        fun record(op: SLOperation) {\n            val operations = operations ?: return\n            operations.add(op.value)\n            if (operations.size >= 50) {\n                operations.removeRange(0, 10)\n            }\n        }\n    }\n\n    private inner class Scope : SubcomposeMeasureScope {\n        // MeasureScope delegation\n        override var layoutDirection: LayoutDirection = LayoutDirection.Rtl\n        override var density: Float = 0f\n        override var fontScale: Float = 0f\n        override val isLookingAhead: Boolean\n            get() =\n                root.layoutState == LayoutState.LookaheadLayingOut ||\n                    root.layoutState == LayoutState.LookaheadMeasuring\n\n        override fun subcompose(slotId: Any?, content: @Composable () -> Unit) =\n            this@LayoutNodeSubcompositionsState.subcompose(slotId, content)\n\n        override fun layout(\n            width: Int,\n            height: Int,\n            alignmentLines: Map<AlignmentLine, Int>,\n            rulers: (RulerScope.() -> Unit)?,\n            placementBlock: Placeable.PlacementScope.() -> Unit,\n        ): MeasureResult {\n            checkMeasuredSize(width, height)\n            return object : MeasureResult {\n                override val width: Int\n                    get() = width\n\n                override val height: Int\n                    get() = height\n\n                override val alignmentLines: Map<AlignmentLine, Int>\n                    get() = alignmentLines\n\n                override val rulers: (RulerScope.() -> Unit)?\n                    get() = rulers\n\n                override fun placeChildren() {\n                    if (isLookingAhead) {\n                        val delegate = root.innerCoordinator.lookaheadDelegate\n                        if (delegate != null) {\n                            delegate.placementScope.placementBlock()\n                            return\n                        }\n                    }\n                    root.innerCoordinator.placementScope.placementBlock()\n                }\n            }\n        }\n    }\n\n    private inner class ApproachMeasureScopeImpl : SubcomposeMeasureScope, MeasureScope by scope {\n        /**\n         * This function retrieves [Measurable]s created for [slotId] based on the subcomposition\n         * that happened in the lookahead pass. If [slotId] was not subcomposed in the lookahead\n         * pass, [subcompose] will return an [emptyList].\n         */\n        override fun subcompose(slotId: Any?, content: @Composable () -> Unit): List<Measurable> {\n            val nodeInSlot = slotIdToNode[slotId]\n            if (nodeInSlot != null && root.foldedChildren.indexOf(nodeInSlot) < currentIndex) {\n                // Check that the node has been composed in lookahead. Otherwise, we need to\n                // compose the node in approach pass via approachSubcompose.\n                return nodeInSlot.childMeasurables\n            } else {\n                return approachSubcompose(slotId, content)\n            }\n        }\n    }\n\n    private fun approachSubcompose(\n        slotId: Any?,\n        content: @Composable () -> Unit,\n    ): List<Measurable> {\n        requirePrecondition(slotIdsOfCompositionsNeededInApproach.size >= currentApproachIndex) {\n            \"Error: currentApproachIndex cannot be greater than the size of the\" +\n                \"approachComposedSlotIds list.\"\n        }\n        val nodeForSlot = slotIdToNode[slotId]\n        if (slotIdsOfCompositionsNeededInApproach.size == currentApproachIndex) {\n            slotIdsOfCompositionsNeededInApproach.add(slotId)\n        } else {\n            slotIdsOfCompositionsNeededInApproach[currentApproachIndex] = slotId\n        }\n        currentApproachIndex++\n        val precomposed = precomposeMap.contains(slotId)\n        if (!precomposed && nodeForSlot == null) {\n            // The slot was not composed in the lookahead pass. And it has not been pre-composed in\n            // the approach pass. Hence, we will precompose it for the approach pass, and track it\n            // in approachPrecomposeSlotHandleMap so that it can be disposed when no longer needed\n            // in approach.\n            precompose(slotId, content).also { approachPrecomposeSlotHandleMap[slotId] = it }\n        } else {\n            // A non-null `nodeForSlot` here means that the slot was composed in lookahead\n            // initially, but no longer needed && has not been disposed yet.\n            // Move from lookahead composed to pre-composed, so that it can be disposed when\n            // no longer needed in approach.\n            if (!precomposed && nodeForSlot != null) {\n                // Transfer ownership of the subcomposition from lookahead pass to approach pass.\n                // As a result, the composition can be disposed as soon as approach pass no\n                // longer needs it.\n                // First, move this node to the end where we keep precomposed items\n                val nodeIndex = root.foldedChildren.indexOf(nodeForSlot)\n                move(nodeIndex, root.foldedChildren.size, 1)\n                precomposedCount++\n                // Remove the slotId from slotIdToNode so that if lookahead were to subcompose\n                // this item, it'll need to take the node out of precomposeMap.\n                slotIdToNode.remove(slotId)\n                precomposeMap[slotId] = nodeForSlot\n                approachPrecomposeSlotHandleMap[slotId] = createPrecomposedSlotHandle(slotId)\n\n                if (root.isAttached) {\n                    makeSureStateIsConsistent()\n                }\n            }\n\n            // Re-subcompose if needed based on forceRecompose\n            val node = precomposeMap[slotId]\n            val nodeState = node?.let { nodeToNodeState[it] }\n            if (nodeState?.forceRecompose == true) {\n                subcompose(node, slotId, pausable = false, content)\n            }\n\n            // Finish pausable composition if it has not been completed yet\n            if (nodeState?.pausedComposition != null) {\n                nodeState.applyPausedPrecomposition(shouldComplete = true)\n            }\n        }\n\n        return precomposeMap[slotId]?.run {\n            measurePassDelegate.childDelegates.also {\n                it.fastForEach { delegate -> delegate.markDetachedFromParentLookaheadPass() }\n            }\n        } ?: emptyList()\n    }\n}\n\nprivate val ReusedSlotId =\n    object {\n        override fun toString(): String = \"ReusedSlotId\"\n    }\n\nprivate class FixedCountSubcomposeSlotReusePolicy(private val maxSlotsToRetainForReuse: Int) :\n    SubcomposeSlotReusePolicy {\n\n    override fun getSlotsToRetain(slotIds: SubcomposeSlotReusePolicy.SlotIdsSet) {\n        if (slotIds.size > maxSlotsToRetainForReuse) {\n            slotIds.trimToSize(maxSlotsToRetainForReuse)\n        }\n    }\n\n    override fun areCompatible(slotId: Any?, reusableSlotId: Any?): Boolean = true\n}\n\nprivate object NoOpSubcomposeSlotReusePolicy : SubcomposeSlotReusePolicy {\n    override fun getSlotsToRetain(slotIds: SubcomposeSlotReusePolicy.SlotIdsSet) {\n        slotIds.clear()\n    }\n\n    override fun areCompatible(slotId: Any?, reusableSlotId: Any?) = false\n}\n\nprivate interface PausedPrecompositionImpl : PausedPrecomposition\n\nprivate val UnspecifiedSlotId = Any()\n\n@JvmInline\nprivate value class SLOperation(val value: Int) {\n    companion object {\n        val CancelPausedPrecomposition = SLOperation(0)\n        val ReuseForceSyncDeactivation = SLOperation(1)\n        val ReuseScheduleOutOfFrameDeactivation = SLOperation(2)\n        val ReuseSyncDeactivation = SLOperation(3)\n        val ReuseDeactivationViaHost = SLOperation(4)\n        val TookFromPrecomposeMap = SLOperation(5)\n        val Subcompose = SLOperation(6)\n        val SubcomposeNew = SLOperation(7)\n        val SubcomposePausable = SLOperation(8)\n        val SubcomposeForceReuse = SLOperation(9)\n        val DeactivateOutOfFrame = SLOperation(10)\n        val DeactivateOutOfFrameCancelled = SLOperation(11)\n        val SlotToReusedFromOnDeactivate = SLOperation(12)\n        val SlotToReusedFromOnReuse = SLOperation(13)\n        val Reused = SLOperation(14)\n        val ResumePaused = SLOperation(15)\n        val PausePaused = SLOperation(16)\n        val ApplyPaused = SLOperation(17)\n    }\n}\n\nprivate class SubcomposeLayoutPausableCompositionException(\n    private val operations: IntList,\n    private val slotId: Any?,\n    cause: Throwable?,\n) : IllegalStateException(cause) {\n\n    private fun operationsList(): List<String> = buildList {\n        var currentOperation = operations.size - 1\n        while (currentOperation >= 0) {\n            val operation = operations[currentOperation]\n            val stringValue =\n                when (SLOperation(operation)) {\n                    SLOperation.CancelPausedPrecomposition -> \"CancelPausedPrecomposition\"\n                    SLOperation.ReuseForceSyncDeactivation -> \"ReuseForceSyncDeactivation\"\n                    SLOperation.ReuseScheduleOutOfFrameDeactivation ->\n                        \"ReuseScheduleOutOfFrameDeactivation\"\n                    SLOperation.ReuseSyncDeactivation -> \"ReuseSyncDeactivation\"\n                    SLOperation.ReuseDeactivationViaHost -> \"ReuseDeactivationViaHost\"\n                    SLOperation.TookFromPrecomposeMap -> \"TookFromPrecomposeMap\"\n                    SLOperation.Subcompose -> \"Subcompose\"\n                    SLOperation.SubcomposeNew -> \"SubcomposeNew\"\n                    SLOperation.SubcomposePausable -> \"SubcomposePausable\"\n                    SLOperation.SubcomposeForceReuse -> \"SubcomposeForceReuse\"\n                    SLOperation.DeactivateOutOfFrame -> \"DeactivateOutOfFrame\"\n                    SLOperation.DeactivateOutOfFrameCancelled -> \"DeactivateOutOfFrameCancelled\"\n                    SLOperation.SlotToReusedFromOnDeactivate -> \"SlotToReusedFromOnDeactivate\"\n                    SLOperation.SlotToReusedFromOnReuse -> \"SlotToReusedFromOnReuse\"\n                    SLOperation.Reused -> \"Reused\"\n                    SLOperation.ResumePaused -> \"ResumePaused\"\n                    SLOperation.PausePaused -> \"PausePaused\"\n                    SLOperation.ApplyPaused -> \"ApplyPaused\"\n                    else -> \"Unexpected $operation\"\n                }\n            add(\"$currentOperation: $stringValue\")\n            currentOperation--\n        }\n    }\n\n    @Suppress(\"ListIterator\")\n    override val message: String?\n        get() =\n            \"\"\"\n            |slotid=$slotId. Last operations:\n            |${operationsList().joinToString(\"\\n\")}\n            \"\"\"\n                .trimMargin()\n}\n\nprivate const val ExtraLoggingEnabled = false\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/layout/IntrinsicMeasurable.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.ui.layout\n\n/**\n * A part of the composition that can be measured. This represents a layout. The instance should\n * never be stored.\n */\ninterface IntrinsicMeasurable {\n    /** Data provided by the [ParentDataModifier]. */\n    val parentData: Any?\n\n    /**\n     * Calculates the minimum width that the layout can be such that the content of the layout will\n     * be painted correctly. There should be no side-effects from a call to [minIntrinsicWidth].\n     */\n    fun minIntrinsicWidth(height: Int): Int\n\n    /**\n     * Calculates the smallest width beyond which increasing the width never decreases the height.\n     * There should be no side-effects from a call to [maxIntrinsicWidth].\n     */\n    fun maxIntrinsicWidth(height: Int): Int\n\n    /**\n     * Calculates the minimum height that the layout can be such that the content of the layout will\n     * be painted correctly. There should be no side-effects from a call to [minIntrinsicHeight].\n     */\n    fun minIntrinsicHeight(width: Int): Int\n\n    /**\n     * Calculates the smallest height beyond which increasing the height never decreases the width.\n     * There should be no side-effects from a call to [maxIntrinsicHeight].\n     */\n    fun maxIntrinsicHeight(width: Int): Int\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/LayoutNode.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage androidx.compose.ui.node\n\nimport androidx.compose.runtime.ComposeNodeLifecycleCallback\nimport androidx.compose.runtime.CompositionLocalMap\nimport androidx.compose.runtime.collection.MutableVector\nimport androidx.compose.runtime.collection.mutableVectorOf\nimport androidx.compose.runtime.tooling.CompositionErrorContext\nimport androidx.compose.runtime.tooling.LocalCompositionErrorContext\nimport androidx.compose.ui.InternalComposeUiApi\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.layer.GraphicsLayer\nimport androidx.compose.ui.input.pointer.PointerInputFilter\nimport androidx.compose.ui.input.pointer.PointerInputModifier\nimport androidx.compose.ui.input.pointer.PointerType\nimport androidx.compose.ui.internal.checkPrecondition\nimport androidx.compose.ui.internal.checkPreconditionNotNull\nimport androidx.compose.ui.internal.requirePrecondition\nimport androidx.compose.ui.layout.IntrinsicMeasurable\nimport androidx.compose.ui.layout.IntrinsicMeasureScope\nimport androidx.compose.ui.layout.LayoutCoordinates\nimport androidx.compose.ui.layout.LayoutInfo\nimport androidx.compose.ui.layout.LayoutNodeSubcompositionsState\nimport androidx.compose.ui.layout.Measurable\nimport androidx.compose.ui.layout.MeasurePolicy\nimport androidx.compose.ui.layout.MeasureScope\nimport androidx.compose.ui.layout.ModifierInfo\nimport androidx.compose.ui.layout.OnGloballyPositionedModifier\nimport androidx.compose.ui.layout.Placeable\nimport androidx.compose.ui.layout.Remeasurement\nimport androidx.compose.ui.node.LayoutNode.LayoutState.Idle\nimport androidx.compose.ui.node.LayoutNode.LayoutState.LayingOut\nimport androidx.compose.ui.node.LayoutNode.LayoutState.LookaheadLayingOut\nimport androidx.compose.ui.node.LayoutNode.LayoutState.LookaheadMeasuring\nimport androidx.compose.ui.node.LayoutNode.LayoutState.Measuring\nimport androidx.compose.ui.node.Nodes.PointerInput\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.platform.LocalViewConfiguration\nimport androidx.compose.ui.platform.ViewConfiguration\nimport androidx.compose.ui.platform.simpleIdentityToString\nimport androidx.compose.ui.semantics.SemanticsConfiguration\nimport androidx.compose.ui.semantics.SemanticsInfo\nimport androidx.compose.ui.semantics.generateSemanticsId\nimport androidx.compose.ui.unit.Constraints\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.DpSize\nimport androidx.compose.ui.unit.IntOffset\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.viewinterop.InteropView\nimport androidx.compose.ui.viewinterop.InteropViewFactoryHolder\n\n/** Enable to log changes to the LayoutNode tree. This logging is quite chatty. */\nprivate const val DebugChanges = false\n\nprivate val DefaultDensity = Density(1f)\n\n/** An element in the layout hierarchy, built with compose UI. */\n@OptIn(InternalComposeUiApi::class)\ninternal class LayoutNode(\n    // Virtual LayoutNode is the temporary concept allows us to a node which is not a real node,\n    // but just a holder for its children - allows us to combine some children into something we\n    // can subcompose in(LayoutNode) without being required to define it as a real layout - we\n    // don't want to define the layout strategy for such nodes, instead the children of the\n    // virtual nodes will be treated as the direct children of the virtual node parent.\n    // This whole concept will be replaced with a proper subcomposition logic which allows to\n    // subcompose multiple times into the same LayoutNode and define offsets.\n    private val isVirtual: Boolean = false,\n    // The unique semantics ID that is used by all semantics modifiers attached to this LayoutNode.\n    // TODO(b/281907968): Implement this with a getter that returns the compositeKeyHash.\n    override var semanticsId: Int = generateSemanticsId(),\n) :\n    ComposeNodeLifecycleCallback,\n    Remeasurement,\n    OwnerScope,\n    LayoutInfo,\n    SemanticsInfo,\n    ComposeUiNode,\n    InteroperableComposeUiNode,\n    Owner.OnLayoutCompletedListener {\n\n    // Params managed by RectManager start:\n    internal var hasPositionalLayerTransformationsInOffsetFromRoot: Boolean = false\n    // this offset contains the combined offset accumulated by the coordinators attached to\n    // this node, not including the offset of the outer one, as the outer offset is part of the\n    // offsetFromRoot of this node, and the rest of the modifiers are affecting offsetFromRoot\n    // for the children.\n    internal var outerToInnerOffset: IntOffset = IntOffset.Max\n    internal var outerToInnerOffsetDirty: Boolean = true\n    // rect in parent is the sum of transformations for parent's coordinators not including the\n    // outer one, and the transformations on this node's outer coordinator.\n    internal var rectInParentDirty: Boolean = true\n    internal var addedToRectList: Boolean = false\n    // Params managed by RectManager end.\n\n    override var compositeKeyHash: Int = 0\n\n    internal var isVirtualLookaheadRoot: Boolean = false\n\n    /**\n     * This lookaheadRoot references the closest root to the LayoutNode, not the top-level lookahead\n     * root.\n     */\n    internal var lookaheadRoot: LayoutNode? = null\n        private set(newRoot) {\n            if (newRoot != field) {\n                field = newRoot\n                if (newRoot != null) {\n                    layoutDelegate.ensureLookaheadDelegateCreated()\n                    forEachCoordinatorIncludingInner { it.ensureLookaheadDelegateCreated() }\n                } else {\n                    // When lookahead root is set to null, clear the lookahead pass delegate.\n                    // This can happen when lookaheadScope is removed in one of the parents, or\n                    // more likely when movableContent moves from a parent in a LookaheadScope to\n                    // a parent not in a LookaheadScope.\n                    layoutDelegate.onRemovedFromLookaheadScope()\n                }\n                invalidateMeasurements()\n            }\n        }\n\n    val isPlacedInLookahead: Boolean?\n        get() = lookaheadPassDelegate?.isPlaced\n\n    private var virtualChildrenCount = 0\n\n    // the list of nodes containing the virtual children as is\n    private val _foldedChildren =\n        MutableVectorWithMutationTracking(mutableVectorOf<LayoutNode>()) {\n            layoutDelegate.markChildrenDirty()\n        }\n    internal val foldedChildren: List<LayoutNode>\n        get() = _foldedChildren.asList()\n\n    // the list of nodes where the virtual children are unfolded (their children are represented\n    // as our direct children)\n    private var _unfoldedChildren: MutableVector<LayoutNode>? = null\n\n    private fun recreateUnfoldedChildrenIfDirty() {\n        if (unfoldedVirtualChildrenListDirty) {\n            unfoldedVirtualChildrenListDirty = false\n            val unfoldedChildren =\n                _unfoldedChildren ?: mutableVectorOf<LayoutNode>().also { _unfoldedChildren = it }\n            unfoldedChildren.clear()\n            _foldedChildren.forEach {\n                if (it.isVirtual) {\n                    unfoldedChildren.addAll(it._children)\n                } else {\n                    unfoldedChildren.add(it)\n                }\n            }\n            layoutDelegate.markChildrenDirty()\n        }\n    }\n\n    internal val childMeasurables: List<Measurable>\n        get() = measurePassDelegate.childDelegates\n\n    internal val childLookaheadMeasurables: List<Measurable>\n        get() = lookaheadPassDelegate!!.childDelegates\n\n    // when the list of our children is modified it will be set to true if we are a virtual node\n    // or it will be set to true on a parent if the parent is a virtual node\n    private var unfoldedVirtualChildrenListDirty = false\n\n    private fun invalidateUnfoldedVirtualChildren() {\n        if (virtualChildrenCount > 0) {\n            unfoldedVirtualChildrenListDirty = true\n        }\n        if (isVirtual) {\n            // Invalidate all virtual unfolded parent until we reach a non-virtual one\n            this._foldedParent?.invalidateUnfoldedVirtualChildren()\n        }\n    }\n\n    /**\n     * This should **not** be mutated or even accessed directly from outside of [LayoutNode]. Use\n     * [forEachChild]/[forEachChildIndexed] when there's a need to iterate through the vector.\n     */\n    internal val _children: MutableVector<LayoutNode>\n        get() {\n            updateChildrenIfDirty()\n            return if (virtualChildrenCount == 0) {\n                _foldedChildren.vector\n            } else {\n                _unfoldedChildren!!\n            }\n        }\n\n    /** Update children if the list is not up to date. */\n    internal fun updateChildrenIfDirty() {\n        if (virtualChildrenCount > 0) {\n            recreateUnfoldedChildrenIfDirty()\n        }\n    }\n\n    inline fun forEachChild(block: (LayoutNode) -> Unit) = _children.forEach(block)\n\n    inline fun forEachChildIndexed(block: (Int, LayoutNode) -> Unit) =\n        _children.forEachIndexed(block)\n\n    /** The children of this LayoutNode, controlled by [insertAt], [move], and [removeAt]. */\n    internal val children: List<LayoutNode>\n        get() = _children.asMutableList()\n\n    /**\n     * The parent node in the LayoutNode hierarchy. This is `null` when the [LayoutNode] is not\n     * attached to a hierarchy or is the root of the hierarchy.\n     */\n    private var _foldedParent: LayoutNode? = null\n\n    /*\n     * The parent node in the LayoutNode hierarchy, skipping over virtual nodes.\n     */\n    internal val parent: LayoutNode?\n        get() {\n            var parent = _foldedParent\n            while (parent?.isVirtual == true) {\n                parent = parent._foldedParent\n            }\n            return parent\n        }\n\n    /** The view system [Owner]. This `null` until [attach] is called */\n    internal var owner: Owner? = null\n        private set\n\n    /**\n     * The [InteropViewFactoryHolder] associated with this node, which is used to instantiate and\n     * manage platform View instances that are hosted in Compose.\n     */\n    internal var interopViewFactoryHolder: InteropViewFactoryHolder? = null\n\n    @InternalComposeUiApi\n    override fun getInteropView(): InteropView? = interopViewFactoryHolder?.getInteropView()\n\n    /**\n     * Returns true if this [LayoutNode] currently has an [LayoutNode.owner]. Semantically, this\n     * means that the LayoutNode is currently a part of a component tree.\n     */\n    override val isAttached: Boolean\n        get() = owner != null\n\n    /**\n     * The tree depth of the [LayoutNode]. This is valid only when it is attached to a hierarchy.\n     */\n    internal var depth: Int = 0\n\n    /**\n     * The layout state the node is currently in.\n     *\n     * The mutation of [layoutState] is confined to [LayoutNode], and is therefore read-only outside\n     * LayoutNode. This makes the state machine easier to reason about.\n     */\n    internal val layoutState\n        get() = layoutDelegate.layoutState\n\n    /**\n     * The lookahead pass delegate for the [LayoutNode]. This should only be used for measure and\n     * layout related impl during *lookahead*. For the actual measure & layout, use\n     * [measurePassDelegate].\n     */\n    internal val lookaheadPassDelegate\n        get() = layoutDelegate.lookaheadPassDelegate\n\n    /**\n     * The measure pass delegate for the [LayoutNode]. This delegate is responsible for the actual\n     * measure & layout, after lookahead if any.\n     */\n    internal val measurePassDelegate\n        get() = layoutDelegate.measurePassDelegate\n\n    /** [requestRemeasure] calls will be ignored while this flag is true. */\n    private var ignoreRemeasureRequests = false\n\n    /**\n     * Inserts a child [LayoutNode] at a particular index. If this LayoutNode [owner] is not `null`\n     * then [instance] will become [attach]ed also. [instance] must have a `null` [parent].\n     */\n    internal fun insertAt(index: Int, instance: LayoutNode) {\n        checkPrecondition(instance._foldedParent == null || instance.owner == null) {\n            exceptionMessageForParentingOrOwnership(instance)\n        }\n\n        if (DebugChanges) {\n            println(\"$instance added to $this at index $index\")\n        }\n\n        instance._foldedParent = this\n        _foldedChildren.add(index, instance)\n        onZSortedChildrenInvalidated()\n\n        if (instance.isVirtual) {\n            virtualChildrenCount++\n        }\n        invalidateUnfoldedVirtualChildren()\n\n        val owner = this.owner\n        if (owner != null) {\n            instance.attach(owner)\n        }\n\n        if (instance.layoutDelegate.childrenAccessingCoordinatesDuringPlacement > 0) {\n            layoutDelegate.childrenAccessingCoordinatesDuringPlacement++\n        }\n        if (instance.globallyPositionedObservers > 0) {\n            globallyPositionedObservers++\n        }\n    }\n\n    private fun exceptionMessageForParentingOrOwnership(instance: LayoutNode) =\n        \"Cannot insert $instance because it already has a parent or an owner.\" +\n            \" This tree: \" +\n            debugTreeToString() +\n            \" Other tree: \" +\n            instance._foldedParent?.debugTreeToString()\n\n    internal fun onZSortedChildrenInvalidated() {\n        if (isVirtual) {\n            parent?.onZSortedChildrenInvalidated()\n        } else {\n            zSortedChildrenInvalidated = true\n        }\n    }\n\n    /** Removes one or more children, starting at [index]. */\n    internal fun removeAt(index: Int, count: Int) {\n        requirePrecondition(count >= 0) { \"count ($count) must be greater than 0\" }\n        for (i in index + count - 1 downTo index) {\n            // Call detach callbacks before removing from _foldedChildren, so the child is still\n            // visible to parents traversing downwards, such as when clearing focus.\n            onChildRemoved(_foldedChildren[i])\n            val child = _foldedChildren.removeAt(i)\n            if (DebugChanges) {\n                println(\"$child removed from $this at index $i\")\n            }\n        }\n    }\n\n    /** Removes all children. */\n    internal fun removeAll() {\n        for (i in _foldedChildren.size - 1 downTo 0) {\n            onChildRemoved(_foldedChildren[i])\n        }\n        _foldedChildren.clear()\n\n        if (DebugChanges) {\n            println(\"Removed all children from $this\")\n        }\n    }\n\n    private fun onChildRemoved(child: LayoutNode) {\n        if (child.layoutDelegate.childrenAccessingCoordinatesDuringPlacement > 0) {\n            layoutDelegate.childrenAccessingCoordinatesDuringPlacement--\n        }\n        if (owner != null) {\n            child.detach()\n        }\n        child._foldedParent = null\n        if (child.globallyPositionedObservers > 0) {\n            globallyPositionedObservers--\n        }\n\n        child.outerCoordinator.wrappedBy = null\n\n        if (child.isVirtual) {\n            virtualChildrenCount--\n            child._foldedChildren.forEach { it.outerCoordinator.wrappedBy = null }\n        }\n        invalidateUnfoldedVirtualChildren()\n        onZSortedChildrenInvalidated()\n    }\n\n    /**\n     * Moves [count] elements starting at index [from] to index [to]. The [to] index is related to\n     * the position before the change, so, for example, to move an element at position 1 to after\n     * the element at position 2, [from] should be `1` and [to] should be `3`. If the elements were\n     * LayoutNodes A B C D E, calling `move(1, 3, 1)` would result in the LayoutNodes being\n     * reordered to A C B D E.\n     */\n    internal fun move(from: Int, to: Int, count: Int) {\n        if (from == to) {\n            return // nothing to do\n        }\n\n        for (i in 0 until count) {\n            // if \"from\" is after \"to,\" the from index moves because we're inserting before it\n            val fromIndex = if (from > to) from + i else from\n            val toIndex = if (from > to) to + i else to + count - 2\n            val child = _foldedChildren.removeAt(fromIndex)\n\n            if (DebugChanges) {\n                println(\"$child moved in $this from index $fromIndex to $toIndex\")\n            }\n\n            _foldedChildren.add(toIndex, child)\n        }\n        onZSortedChildrenInvalidated()\n\n        invalidateUnfoldedVirtualChildren()\n        invalidateMeasurements()\n    }\n\n    override fun isTransparent(): Boolean = outerCoordinator.isTransparent()\n\n    internal var isSemanticsInvalidated = false\n\n    internal fun requestAutofill() {\n        // Ignore calls while semantics are being applied (b/378114177).\n        if (isCurrentlyCalculatingSemanticsConfiguration) return\n\n        val owner = requireOwner()\n        owner.requestAutofill(this)\n    }\n\n    internal fun invalidateSemantics() {\n        // Ignore calls to invalidate Semantics while semantics are being applied (b/378114177).\n        if (isCurrentlyCalculatingSemanticsConfiguration) return\n\n        if (nodes.isUpdating || applyingModifierOnAttach) {\n            // We are currently updating the modifier, so just schedule an invalidation. After\n            // applying the modifier, we will notify listeners of semantics changes.\n            isSemanticsInvalidated = true\n        } else {\n            // We are not currently updating the modifier, so instead of scheduling invalidation,\n            // we update the semantics configuration and send the notification event right away.\n            val prev = _semanticsConfiguration\n            _semanticsConfiguration = calculateSemanticsConfiguration()\n            isSemanticsInvalidated = false\n\n            val owner = requireOwner()\n            owner.semanticsOwner.notifySemanticsChange(this, prev)\n\n            // This is needed for Accessibility and ContentCapture. Remove after these systems\n            // are migrated to use SemanticsInfo and SemanticListeners.\n            owner.onSemanticsChange()\n        }\n    }\n\n    // This is needed until we completely move to the new world where we always pre-compute the\n    // semantics configuration. At that point, this can just be a property with a private setter.\n    private var _semanticsConfiguration: SemanticsConfiguration? = null\n    override val semanticsConfiguration: SemanticsConfiguration?\n        get() {\n            // TODO: investigate if there's a better way to approach \"half attached\" state and\n            // whether or not deactivated nodes should be considered removed or not.\n            if (!isAttached || isDeactivated || !nodes.has(Nodes.Semantics)) return null\n\n            return _semanticsConfiguration\n        }\n\n    private var isCurrentlyCalculatingSemanticsConfiguration = false\n\n    private fun calculateSemanticsConfiguration(): SemanticsConfiguration {\n        // Ignore calls to invalidate Semantics while semantics are being calculated.\n        isCurrentlyCalculatingSemanticsConfiguration = true\n\n        var config = SemanticsConfiguration()\n        requireOwner().snapshotObserver.observeSemanticsReads(this) {\n            nodes.tailToHead(Nodes.Semantics) {\n                if (it.shouldClearDescendantSemantics) {\n                    config = SemanticsConfiguration()\n                    config.isClearingSemantics = true\n                }\n                if (it.shouldMergeDescendantSemantics) {\n                    config.isMergingSemanticsOfDescendants = true\n                }\n                with(it) { config.applySemantics() }\n            }\n        }\n\n        isCurrentlyCalculatingSemanticsConfiguration = false\n\n        return config\n    }\n\n    /**\n     * Set the [Owner] of this LayoutNode. This LayoutNode must not already be attached. [owner]\n     * must match its [parent].[owner].\n     */\n    internal fun attach(owner: Owner) {\n        checkPrecondition(this.owner == null) {\n            \"Cannot attach $this as it already is attached.  Tree: \" + debugTreeToString()\n        }\n        checkPrecondition(_foldedParent == null || _foldedParent?.owner == owner) {\n            \"Attaching to a different owner($owner) than the parent's owner(${parent?.owner}).\" +\n                \" This tree: \" +\n                debugTreeToString() +\n                \" Parent tree: \" +\n                _foldedParent?.debugTreeToString()\n        }\n        val parent = this.parent\n        if (parent == null) {\n            measurePassDelegate.isPlaced = true\n            // regular nodes go through markNodeAndSubtreeAsPlaced(), from where we call this\n            // function on rectManager. as root marked as placed here, we need to call it.\n            owner.rectManager.recalculateRectIfDirty(this)\n            lookaheadPassDelegate?.onAttachedToNullParent()\n        }\n\n        // Use the inner coordinator of first non-virtual parent\n        outerCoordinator.wrappedBy = parent?.innerCoordinator\n\n        this.owner = owner\n        this.depth = (parent?.depth ?: -1) + 1\n\n        pendingModifier?.let { applyModifier(it) }\n        pendingModifier = null\n\n        owner.onPreAttach(this)\n\n        // Update lookahead root when attached. For nested cases, we'll always use the\n        // closest lookahead root\n        if (isVirtualLookaheadRoot) {\n            lookaheadRoot = this\n        } else {\n            // Favor lookahead root from parent than locally created scope, unless current node\n            // is a virtual lookahead root\n            lookaheadRoot = _foldedParent?.lookaheadRoot ?: lookaheadRoot\n            if (lookaheadRoot == null && nodes.has(Nodes.ApproachMeasure)) {\n                // This could happen when movableContent containing intermediateLayout is moved\n                lookaheadRoot = this\n            }\n        }\n        if (!isDeactivated) {\n            nodes.markAsAttached()\n        }\n        _foldedChildren.forEach { child -> child.attach(owner) }\n        if (!isDeactivated) {\n            nodes.runAttachLifecycle()\n        }\n\n        invalidateMeasurements()\n        parent?.invalidateMeasurements()\n\n        onAttach?.invoke(owner)\n\n        layoutDelegate.updateParentData()\n\n        if (!isDeactivated && nodes.has(Nodes.Semantics)) {\n            invalidateSemantics()\n        }\n\n        owner.onPostAttach(this)\n    }\n\n    /**\n     * Remove the LayoutNode from the [Owner]. The [owner] must not be `null` before this call and\n     * its [parent]'s [owner] must be `null` before calling this. This will also [detach] all\n     * children. After executing, the [owner] will be `null`.\n     */\n    internal fun detach() {\n        val owner = owner\n        checkPreconditionNotNull(owner) {\n            \"Cannot detach node that is already detached!  Tree: \" + parent?.debugTreeToString()\n        }\n        val parent = this.parent\n        if (parent != null) {\n            parent.invalidateLayer()\n            parent.invalidateMeasurements()\n            measurePassDelegate.measuredByParent = UsageByParent.NotUsed\n            lookaheadPassDelegate?.let { it.measuredByParent = UsageByParent.NotUsed }\n        }\n        layoutDelegate.resetAlignmentLines()\n\n        forEachCoordinatorIncludingInner { it.onLayoutNodeDetach() }\n        onDetach?.invoke(owner)\n\n        nodes.runDetachLifecycle()\n        ignoreRemeasureRequests { _foldedChildren.forEach { child -> child.detach() } }\n        nodes.markAsDetached()\n        owner.onDetach(this)\n        owner.rectManager.remove(this)\n        this.owner = null\n\n        lookaheadRoot = null\n        depth = 0\n        measurePassDelegate.onNodeDetached()\n        lookaheadPassDelegate?.onNodeDetached()\n\n        // Note: Don't call invalidateSemantics() from within detach() because the modifier nodes\n        // are detached before the LayoutNode, and invalidateSemantics() can trigger a call to\n        // calculateSemanticsConfiguration() which will encounter unattached nodes. Instead, just\n        // set the semantics configuration to null over here since we know the node is detached.\n        if (nodes.has(Nodes.Semantics)) {\n            val prev = _semanticsConfiguration\n            _semanticsConfiguration = null\n            isSemanticsInvalidated = false\n            owner.semanticsOwner.notifySemanticsChange(this, prev)\n\n            // This is needed for Accessibility and ContentCapture. Remove after these systems\n            // are migrated to use SemanticsInfo and SemanticListeners.\n            owner.onSemanticsChange()\n        }\n    }\n\n    private val _zSortedChildren = mutableVectorOf<LayoutNode>()\n    private var zSortedChildrenInvalidated = true\n\n    /**\n     * Returns the children list sorted by their [LayoutNode.zIndex] first (smaller first) and the\n     * order they were placed via [Placeable.placeAt] by parent (smaller first). Please note that\n     * this list contains not placed items as well, so you have to manually filter them.\n     *\n     * Note that the object is reused so you shouldn't save it for later.\n     */\n    @PublishedApi\n    internal val zSortedChildren: MutableVector<LayoutNode>\n        get() {\n            if (zSortedChildrenInvalidated) {\n                _zSortedChildren.clear()\n                _zSortedChildren.addAll(_children)\n                _zSortedChildren.sortWith(ZComparator)\n                zSortedChildrenInvalidated = false\n            }\n            return _zSortedChildren\n        }\n\n    override val isValidOwnerScope: Boolean\n        get() = isAttached\n\n    override fun toString(): String {\n        return \"${simpleIdentityToString(this, null)} children: ${children.size} \" +\n            \"measurePolicy: $measurePolicy deactivated: $isDeactivated\"\n    }\n\n    internal val hasFixedInnerContentConstraints: Boolean\n        get() {\n            // it is the constraints we have after all the modifiers applied on this node,\n            // the one to be passed into user provided [measurePolicy.measure]. if those\n            // constraints are fixed this means the children size changes can't affect\n            // this LayoutNode size.\n            val innerContentConstraints = innerCoordinator.lastMeasurementConstraints\n            return innerContentConstraints.hasFixedWidth && innerContentConstraints.hasFixedHeight\n        }\n\n    /** Call this method from the debugger to see a dump of the LayoutNode tree structure */\n    @Suppress(\"unused\")\n    private fun debugTreeToString(depth: Int = 0): String {\n        val tree = StringBuilder()\n        for (i in 0 until depth) {\n            tree.append(\"  \")\n        }\n        tree.append(\"|-\")\n        tree.append(toString())\n        tree.append('\\n')\n\n        forEachChild { child -> tree.append(child.debugTreeToString(depth + 1)) }\n\n        var treeString = tree.toString()\n        if (depth == 0) {\n            // Delete trailing newline\n            treeString = treeString.substring(0, treeString.length - 1)\n        }\n\n        return treeString\n    }\n\n    internal abstract class NoIntrinsicsMeasurePolicy(private val error: String) : MeasurePolicy {\n        override fun IntrinsicMeasureScope.minIntrinsicWidth(\n            measurables: List<IntrinsicMeasurable>,\n            height: Int,\n        ) = error(error)\n\n        override fun IntrinsicMeasureScope.minIntrinsicHeight(\n            measurables: List<IntrinsicMeasurable>,\n            width: Int,\n        ) = error(error)\n\n        override fun IntrinsicMeasureScope.maxIntrinsicWidth(\n            measurables: List<IntrinsicMeasurable>,\n            height: Int,\n        ) = error(error)\n\n        override fun IntrinsicMeasureScope.maxIntrinsicHeight(\n            measurables: List<IntrinsicMeasurable>,\n            width: Int,\n        ) = error(error)\n    }\n\n    /** Blocks that define the measurement and intrinsic measurement of the layout. */\n    override var measurePolicy: MeasurePolicy = ErrorMeasurePolicy\n        set(value) {\n            if (field != value) {\n                field = value\n                intrinsicsPolicy?.updateFrom(measurePolicy)\n                invalidateMeasurements()\n            }\n        }\n\n    /**\n     * The intrinsic measurements of this layout, backed up by states to trigger correct\n     * remeasurement for layouts using the intrinsics of this layout when the [measurePolicy] is\n     * changing.\n     */\n    private var intrinsicsPolicy: IntrinsicsPolicy? = null\n\n    private fun getOrCreateIntrinsicsPolicy(): IntrinsicsPolicy {\n        return intrinsicsPolicy\n            ?: IntrinsicsPolicy(this, measurePolicy).also { intrinsicsPolicy = it }\n    }\n\n    fun minLookaheadIntrinsicWidth(height: Int) =\n        getOrCreateIntrinsicsPolicy().minLookaheadIntrinsicWidth(height)\n\n    fun minLookaheadIntrinsicHeight(width: Int) =\n        getOrCreateIntrinsicsPolicy().minLookaheadIntrinsicHeight(width)\n\n    fun maxLookaheadIntrinsicWidth(height: Int) =\n        getOrCreateIntrinsicsPolicy().maxLookaheadIntrinsicWidth(height)\n\n    fun maxLookaheadIntrinsicHeight(width: Int) =\n        getOrCreateIntrinsicsPolicy().maxLookaheadIntrinsicHeight(width)\n\n    fun minIntrinsicWidth(height: Int) = getOrCreateIntrinsicsPolicy().minIntrinsicWidth(height)\n\n    fun minIntrinsicHeight(width: Int) = getOrCreateIntrinsicsPolicy().minIntrinsicHeight(width)\n\n    fun maxIntrinsicWidth(height: Int) = getOrCreateIntrinsicsPolicy().maxIntrinsicWidth(height)\n\n    fun maxIntrinsicHeight(width: Int) = getOrCreateIntrinsicsPolicy().maxIntrinsicHeight(width)\n\n    /** The screen density to be used by this layout. */\n    override var density: Density = DefaultDensity\n        set(value) {\n            if (field != value) {\n                field = value\n                onDensityOrLayoutDirectionChanged()\n\n                nodes.headToTail { it.onDensityChange() }\n            }\n        }\n\n    /** The layout direction of the layout node. */\n    override var layoutDirection: LayoutDirection = LayoutDirection.Ltr\n        set(value) {\n            if (field != value) {\n                field = value\n                onDensityOrLayoutDirectionChanged()\n\n                nodes.headToTail { it.onLayoutDirectionChange() }\n            }\n        }\n\n    override var viewConfiguration: ViewConfiguration = DummyViewConfiguration\n        set(value) {\n            if (field != value) {\n                field = value\n\n                nodes.headToTail(type = PointerInput) { it.onViewConfigurationChange() }\n            }\n        }\n\n    override var compositionLocalMap = CompositionLocalMap.Empty\n        set(value) {\n            field = value\n            density = value[LocalDensity]\n            layoutDirection = value[LocalLayoutDirection]\n            viewConfiguration = value[LocalViewConfiguration]\n            nodes.headToTail(Nodes.CompositionLocalConsumer) { modifierNode ->\n                val delegatedNode = modifierNode.node\n                if (delegatedNode.isAttached) {\n                    autoInvalidateUpdatedNode(delegatedNode)\n                } else {\n                    delegatedNode.updatedNodeAwaitingAttachForInvalidation = true\n                }\n            }\n        }\n\n    private val traceContext: CompositionErrorContext?\n        get() = compositionLocalMap[LocalCompositionErrorContext]\n\n    fun rethrowWithComposeStackTrace(e: Throwable): Nothing =\n        throw e.also { traceContext?.apply { e.attachComposeStackTrace(this@LayoutNode) } }\n\n    private fun onDensityOrLayoutDirectionChanged() {\n        // TODO(b/242120396): it seems like we need to update some densities in the node\n        // coordinators here\n        // measure/layout modifiers on the node\n        invalidateMeasurements()\n        // draw modifiers on the node\n        parent?.invalidateLayer() ?: owner?.invalidateRootLayer()\n        // and draw modifiers after graphics layers on the node\n        invalidateLayers()\n    }\n\n    /** The measured width of this layout and all of its [modifier]s. Shortcut for `size.width`. */\n    override val width: Int\n        get() = layoutDelegate.width\n\n    /**\n     * The measured height of this layout and all of its [modifier]s. Shortcut for `size.height`.\n     */\n    override val height: Int\n        get() = layoutDelegate.height\n\n    internal val alignmentLinesRequired: Boolean\n        get() =\n            layoutDelegate.run {\n                alignmentLinesOwner.alignmentLines.required ||\n                    lookaheadAlignmentLinesOwner?.alignmentLines?.required == true\n            }\n\n    internal val mDrawScope: LayoutNodeDrawScope\n        get() = requireOwner().sharedDrawScope\n\n    /**\n     * Whether or not this [LayoutNode] and all of its parents have been placed in the hierarchy.\n     */\n    override val isPlaced: Boolean\n        get() = measurePassDelegate.isPlaced\n\n    /**\n     * Whether or not this [LayoutNode] was placed by its parent. The node can still be considered\n     * not placed if some of the modifiers on it not placed the placeable.\n     */\n    val isPlacedByParent: Boolean\n        get() = measurePassDelegate.isPlacedByParent\n\n    /**\n     * The order in which this node was placed by its parent during the previous `layoutChildren`.\n     * Before the placement the order is set to [NotPlacedPlaceOrder] to all the children. Then\n     * every placed node assigns this variable to [parent]s MeasurePassDelegate's\n     * nextChildPlaceOrder and increments this counter. Not placed items will still have\n     * [NotPlacedPlaceOrder] set.\n     */\n    internal val placeOrder: Int\n        get() = measurePassDelegate.placeOrder\n\n    /** Remembers how the node was measured by the parent. */\n    internal val measuredByParent: UsageByParent\n        get() = measurePassDelegate.measuredByParent\n\n    /** Remembers how the node was measured by the parent in lookahead. */\n    internal val measuredByParentInLookahead: UsageByParent\n        get() = lookaheadPassDelegate?.measuredByParent ?: UsageByParent.NotUsed\n\n    /** Remembers how the node was measured using intrinsics by an ancestor. */\n    internal var intrinsicsUsageByParent: UsageByParent = UsageByParent.NotUsed\n\n    /**\n     * We must cache a previous value of [intrinsicsUsageByParent] because measurement is sometimes\n     * skipped. When it is skipped, the subtree must be restored to this value.\n     */\n    private var previousIntrinsicsUsageByParent: UsageByParent = UsageByParent.NotUsed\n\n    @Deprecated(\"Temporary API to support ConstraintLayout prototyping.\")\n    internal var canMultiMeasure: Boolean = false\n\n    internal val nodes = NodeChain(this)\n    internal val innerCoordinator: NodeCoordinator\n        get() = nodes.innerCoordinator\n\n    internal val layoutDelegate = LayoutNodeLayoutDelegate(this)\n    internal val outerCoordinator: NodeCoordinator\n        get() = nodes.outerCoordinator\n\n    /**\n     * zIndex defines the drawing order of the LayoutNode. Children with larger zIndex are drawn on\n     * top of others (the original order is used for the nodes with the same zIndex). Default zIndex\n     * is 0. We use sum of the values passed as zIndex to place() by the parent layout and all the\n     * applied modifiers.\n     */\n    private val zIndex: Float\n        get() = measurePassDelegate.zIndex\n\n    /** The inner state associated with [androidx.compose.ui.layout.SubcomposeLayout]. */\n    internal var subcompositionsState: LayoutNodeSubcompositionsState? = null\n\n    /** The inner-most layer coordinator. Used for performance for NodeCoordinator.findLayer(). */\n    private var _innerLayerCoordinator: NodeCoordinator? = null\n    internal var innerLayerCoordinatorIsDirty = true\n    internal val innerLayerCoordinator: NodeCoordinator?\n        get() {\n            if (innerLayerCoordinatorIsDirty) {\n                var coordinator: NodeCoordinator? = innerCoordinator\n                val final = outerCoordinator.wrappedBy\n                _innerLayerCoordinator = null\n                while (coordinator != final) {\n                    if (coordinator?.layer != null) {\n                        _innerLayerCoordinator = coordinator\n                        break\n                    }\n                    coordinator = coordinator?.wrappedBy\n                }\n                innerLayerCoordinatorIsDirty = false\n            }\n            val layerCoordinator = _innerLayerCoordinator\n            if (layerCoordinator != null) {\n                checkPreconditionNotNull(layerCoordinator.layer) { \"layer was not set\" }\n            }\n            return layerCoordinator\n        }\n\n    /**\n     * Invalidates the inner-most layer as part of this LayoutNode or from the containing\n     * LayoutNode. This is added for performance so that NodeCoordinator.invalidateLayer() can be\n     * faster.\n     */\n    internal fun invalidateLayer() {\n        val innerLayerCoordinator = innerLayerCoordinator\n        if (innerLayerCoordinator != null) {\n            innerLayerCoordinator.invalidateLayer()\n        } else {\n            val parent = this.parent\n            parent?.invalidateLayer() ?: owner?.invalidateRootLayer()\n        }\n    }\n\n    private var _modifier: Modifier = Modifier\n    private var pendingModifier: Modifier? = null\n    internal val applyingModifierOnAttach\n        get() = pendingModifier != null\n\n    /** The [Modifier] currently applied to this node. */\n    override var modifier: Modifier\n        get() = _modifier\n        set(value) {\n            requirePrecondition(!isVirtual || modifier === Modifier) {\n                \"Modifiers are not supported on virtual LayoutNodes\"\n            }\n            requirePrecondition(!isDeactivated) { \"modifier is updated when deactivated\" }\n            if (isAttached) {\n                applyModifier(value)\n                if (isSemanticsInvalidated) {\n                    invalidateSemantics()\n                }\n            } else {\n                pendingModifier = value\n            }\n        }\n\n    private fun applyModifier(modifier: Modifier) {\n        val hadPointerInput = nodes.has(Nodes.PointerInput)\n        val hadFocusTarget = nodes.has(Nodes.FocusTarget)\n        _modifier = modifier\n        nodes.updateFrom(modifier)\n        val hasPointerInput = nodes.has(Nodes.PointerInput)\n        val hasFocusTarget = nodes.has(Nodes.FocusTarget)\n        layoutDelegate.updateParentData()\n        if (lookaheadRoot == null && nodes.has(Nodes.ApproachMeasure)) {\n            lookaheadRoot = this\n        }\n\n        if (hadPointerInput != hasPointerInput || hadFocusTarget != hasFocusTarget) {\n            requireOwner().rectManager.updateFlagsFor(this, hasFocusTarget, hasPointerInput)\n        }\n    }\n\n    private fun resetModifierState() {\n        nodes.resetState()\n    }\n\n    internal fun invalidateParentData() {\n        layoutDelegate.invalidateParentData()\n    }\n\n    /**\n     * Coordinates of just the contents of the [LayoutNode], after being affected by all modifiers.\n     */\n    override val coordinates: LayoutCoordinates\n        get() = innerCoordinator\n\n    /** Callback to be executed whenever the [LayoutNode] is attached to a new [Owner]. */\n    internal var onAttach: ((Owner) -> Unit)? = null\n\n    /** Callback to be executed whenever the [LayoutNode] is detached from an [Owner]. */\n    internal var onDetach: ((Owner) -> Unit)? = null\n\n    /**\n     * Flag used by [OnPositionedDispatcher] to identify LayoutNodes that have already had their\n     * [OnGloballyPositionedModifier]'s dispatch called so that they aren't called multiple times.\n     */\n    internal var needsOnGloballyPositionedDispatch = false\n\n    /**\n     * Count of attached [GlobalPositionAwareModifierNode] modifiers or children having such\n     * modifiers in their subtree.\n     */\n    var globallyPositionedObservers: Int = 0\n        set(value) {\n            if (field != value) {\n                if (value > 0 && field == 0) {\n                    parent?.globallyPositionedObservers++\n                }\n                if (value == 0 && field > 0) {\n                    parent?.globallyPositionedObservers--\n                }\n                field = value\n            }\n        }\n\n    internal fun place(x: Int, y: Int) {\n        if (intrinsicsUsageByParent == UsageByParent.NotUsed) {\n            // This LayoutNode may have asked children for intrinsics. If so, we should\n            // clear the intrinsics usage for everything that was requested previously.\n            clearSubtreePlacementIntrinsicsUsage()\n        }\n        with(parent?.innerCoordinator?.placementScope ?: requireOwner().placementScope) {\n            measurePassDelegate.placeRelative(x, y)\n        }\n    }\n\n    /** Place this layout node again on the same position it was placed last time */\n    internal fun replace() {\n        if (intrinsicsUsageByParent == UsageByParent.NotUsed) {\n            // This LayoutNode may have asked children for intrinsics. If so, we should\n            // clear the intrinsics usage for everything that was requested previously.\n            clearSubtreePlacementIntrinsicsUsage()\n        }\n        measurePassDelegate.replace()\n    }\n\n    internal fun lookaheadReplace() {\n        if (intrinsicsUsageByParent == UsageByParent.NotUsed) {\n            // This LayoutNode may have asked children for intrinsics. If so, we should\n            // clear the intrinsics usage for everything that was requested previously.\n            clearSubtreePlacementIntrinsicsUsage()\n        }\n        lookaheadPassDelegate!!.replace()\n    }\n\n    internal fun draw(canvas: Canvas, graphicsLayer: GraphicsLayer?) =\n        withComposeStackTrace(this) { outerCoordinator.draw(canvas, graphicsLayer) }\n\n    /**\n     * Carries out a hit test on the [PointerInputModifier]s associated with this [LayoutNode] and\n     * all [PointerInputModifier]s on all descendant [LayoutNode]s.\n     *\n     * If [pointerPosition] is within the bounds of any tested [PointerInputModifier]s, the\n     * [PointerInputModifier] is added to [hitTestResult] and true is returned.\n     *\n     * @param pointerPosition The tested pointer position, which is relative to the LayoutNode.\n     * @param hitTestResult The collection that the hit [PointerInputFilter]s will be added to if\n     *   hit.\n     */\n    internal fun hitTest(\n        pointerPosition: Offset,\n        hitTestResult: HitTestResult,\n        pointerType: PointerType = PointerType.Unknown,\n        isInLayer: Boolean = true,\n    ) {\n        val positionInWrapped = outerCoordinator.fromParentPosition(pointerPosition)\n        outerCoordinator.hitTest(\n            NodeCoordinator.PointerInputSource,\n            positionInWrapped,\n            hitTestResult,\n            pointerType,\n            isInLayer,\n        )\n    }\n\n    @Suppress(\"UNUSED_PARAMETER\")\n    internal fun hitTestSemantics(\n        pointerPosition: Offset,\n        hitSemanticsEntities: HitTestResult,\n        pointerType: PointerType = PointerType.Touch,\n        isInLayer: Boolean = true,\n    ) {\n        val positionInWrapped = outerCoordinator.fromParentPosition(pointerPosition)\n        outerCoordinator.hitTest(\n            NodeCoordinator.SemanticsSource,\n            positionInWrapped,\n            hitSemanticsEntities,\n            pointerType = PointerType.Touch,\n            isInLayer = isInLayer,\n        )\n    }\n\n    internal fun rescheduleRemeasureOrRelayout(it: LayoutNode) {\n        when (it.layoutState) {\n            Idle -> {\n                // this node was scheduled for remeasure or relayout while it was not\n                // placed. such requests are ignored for non-placed nodes so we have to\n                // re-schedule remeasure or relayout.\n                if (it.lookaheadMeasurePending) {\n                    it.requestLookaheadRemeasure(forceRequest = true)\n                } else {\n                    if (it.lookaheadLayoutPending) {\n                        it.requestLookaheadRelayout(forceRequest = true)\n                    }\n                    if (it.measurePending) {\n                        it.requestRemeasure(forceRequest = true)\n                    } else if (it.layoutPending) {\n                        it.requestRelayout(forceRequest = true)\n                    }\n                }\n            }\n            else -> throw IllegalStateException(\"Unexpected state ${it.layoutState}\")\n        }\n    }\n\n    /** Used to request a new measurement + layout pass from the owner. */\n    internal fun requestRemeasure(\n        forceRequest: Boolean = false,\n        scheduleMeasureAndLayout: Boolean = true,\n        invalidateIntrinsics: Boolean = true,\n    ) {\n        if (!ignoreRemeasureRequests && !isVirtual) {\n            val owner = owner ?: return\n            owner.onRequestMeasure(\n                layoutNode = this,\n                forceRequest = forceRequest,\n                scheduleMeasureAndLayout = scheduleMeasureAndLayout,\n            )\n            if (invalidateIntrinsics) {\n                measurePassDelegate.invalidateIntrinsicsParent(forceRequest)\n            }\n        }\n    }\n\n    /**\n     * Used to request a new lookahead measurement, lookahead layout, and subsequently measure and\n     * layout from the owner.\n     */\n    internal fun requestLookaheadRemeasure(\n        forceRequest: Boolean = false,\n        scheduleMeasureAndLayout: Boolean = true,\n        invalidateIntrinsics: Boolean = true,\n    ) {\n        checkPrecondition(lookaheadRoot != null) {\n            \"Lookahead measure cannot be requested on a node that is not a part of the \" +\n                \"LookaheadScope\"\n        }\n        val owner = owner ?: return\n        if (!ignoreRemeasureRequests && !isVirtual) {\n            owner.onRequestMeasure(\n                layoutNode = this,\n                affectsLookahead = true,\n                forceRequest = forceRequest,\n                scheduleMeasureAndLayout = scheduleMeasureAndLayout,\n            )\n            if (invalidateIntrinsics) {\n                lookaheadPassDelegate!!.invalidateIntrinsicsParent(forceRequest)\n            }\n        }\n    }\n\n    /**\n     * This gets called when both lookahead measurement (if in a LookaheadScope) and actual\n     * measurement need to be re-done. Such events include modifier change, attach/detach, etc.\n     */\n    internal fun invalidateMeasurements() {\n        if (isVirtual) {\n            // If the node is virtual, we need to invalidate the parent node (as it is non-virtual)\n            // instead so that children get properly invalidated.\n            parent?.invalidateMeasurements()\n            return\n        }\n        if (lookaheadRoot != null) {\n            requestLookaheadRemeasure()\n        } else {\n            requestRemeasure()\n        }\n    }\n\n    internal fun invalidateOnPositioned() {\n        // If we've already scheduled a measure, the positioned callbacks will get called anyway\n        if (\n            globallyPositionedObservers == 0 ||\n                layoutPending ||\n                measurePending ||\n                needsOnGloballyPositionedDispatch\n        )\n            return\n        requireOwner().requestOnPositionedCallback(this)\n    }\n\n    internal fun onCoordinatorRectChanged(coordinator: NodeCoordinator) {\n        val rectManager = owner?.rectManager\n        val placementPending = layoutState != Idle || measurePending || layoutPending\n        if (addedToRectList && rectManager != null) {\n            if (coordinator === outerCoordinator) {\n                // transformations on the outer coordinator update the offset from parent\n                rectInParentDirty = true\n                if (!placementPending) {\n                    // during placement we get it called right after\n                    rectManager.recalculateRectIfDirty(this)\n                }\n            } else {\n                // transformations on other coordinators invalidate outerToInnerOffset\n                // and offset from parent for each child\n                outerToInnerOffsetDirty = true\n                forEachChild {\n                    it.rectInParentDirty = true\n                    // during placement it is guaranteed to get recalculateRectIfDirty() call on\n                    // each child after the parent finish its placement. we don't want to call it\n                    // straight away, as there are might be multiple changes on the same layout\n                    // node, and we want to apply them once in batch.\n                    if (!placementPending) {\n                        rectManager.recalculateRectIfDirty(it)\n                    }\n                }\n\n                // Since there has been an update to a coordinator somewhere in the\n                // modifier chain of this layout node, we might have onRectChanged\n                // callbacks that need to be notified of that change. As a result, even\n                // if the outer rect of this layout node hasn't changed, we want to\n                // invalidate the callbacks for them\n                rectManager.invalidateCallbacksFor(this)\n            }\n        }\n\n        layoutDelegate.measurePassDelegate.requestLayoutIfCoordinatesAreUsedAndNotifyChildren()\n    }\n\n    internal inline fun <T> ignoreRemeasureRequests(block: () -> T): T {\n        ignoreRemeasureRequests = true\n        val result = block()\n        ignoreRemeasureRequests = false\n        return result\n    }\n\n    /** Used to request a new layout pass from the owner. */\n    internal fun requestRelayout(forceRequest: Boolean = false) {\n        if (!isVirtual) {\n            owner?.onRequestRelayout(this, forceRequest = forceRequest)\n        }\n    }\n\n    internal fun requestLookaheadRelayout(forceRequest: Boolean = false) {\n        if (!isVirtual) {\n            owner?.onRequestRelayout(this, affectsLookahead = true, forceRequest)\n        }\n    }\n\n    internal fun dispatchOnPositionedCallbacks() {\n        if (layoutState != Idle || layoutPending || measurePending || isDeactivated) {\n            return // it hasn't yet been properly positioned, so don't make a call\n        }\n        if (!isPlaced) {\n            return // it hasn't been placed, so don't make a call\n        }\n        nodes.headToTail(Nodes.GlobalPositionAware) {\n            it.onGloballyPositioned(it.requireCoordinator(Nodes.GlobalPositionAware))\n        }\n    }\n\n    /**\n     * This returns a new List of Modifiers and the coordinates and any extra information that may\n     * be useful. This is used for tooling to retrieve layout modifier and layer information.\n     */\n    override fun getModifierInfo(): List<ModifierInfo> = nodes.getModifierInfo()\n\n    /** Invalidates layers defined on this LayoutNode. */\n    internal fun invalidateLayers() {\n        forEachCoordinator { coordinator -> coordinator.layer?.invalidate() }\n        innerCoordinator.layer?.invalidate()\n    }\n\n    internal fun lookaheadRemeasure(\n        constraints: Constraints? = layoutDelegate.lastLookaheadConstraints\n    ): Boolean {\n        // Only lookahead remeasure when the constraints are valid and the node is in\n        // a LookaheadScope (by checking whether the lookaheadScope is set)\n        return if (constraints != null && lookaheadRoot != null) {\n            lookaheadPassDelegate!!.remeasure(constraints)\n        } else {\n            false\n        }\n    }\n\n    /** Return true if the measured size has been changed */\n    internal fun remeasure(constraints: Constraints? = layoutDelegate.lastConstraints): Boolean {\n        return if (constraints != null) {\n            if (intrinsicsUsageByParent == UsageByParent.NotUsed) {\n                // This LayoutNode may have asked children for intrinsics. If so, we should\n                // clear the intrinsics usage for everything that was requested previously.\n                clearSubtreeIntrinsicsUsage()\n            }\n            measurePassDelegate.remeasure(constraints)\n        } else {\n            false\n        }\n    }\n\n    /**\n     * Tracks whether another measure pass is needed for the LayoutNode. Mutation to\n     * [measurePending] is confined to LayoutNodeLayoutDelegate. It can only be set true from\n     * outside of LayoutNode via [markMeasurePending]. It is cleared (i.e. set false) during the\n     * measure pass ( i.e. in [LayoutNodeLayoutDelegate.performMeasure]).\n     */\n    internal val measurePending: Boolean\n        get() = layoutDelegate.measurePending\n\n    /**\n     * Tracks whether another layout pass is needed for the LayoutNode. Mutation to [layoutPending]\n     * is confined to LayoutNode. It can only be set true from outside of LayoutNode via\n     * [markLayoutPending]. It is cleared (i.e. set false) during the layout pass (i.e. in\n     * layoutChildren).\n     */\n    internal val layoutPending: Boolean\n        get() = layoutDelegate.layoutPending\n\n    internal val lookaheadMeasurePending: Boolean\n        get() = layoutDelegate.lookaheadMeasurePending\n\n    internal val lookaheadLayoutPending: Boolean\n        get() = layoutDelegate.lookaheadLayoutPending\n\n    /** Marks the layoutNode dirty for another layout pass. */\n    internal fun markLayoutPending() = layoutDelegate.markLayoutPending()\n\n    /** Marks the layoutNode dirty for another measure pass. */\n    internal fun markMeasurePending() = layoutDelegate.markMeasurePending()\n\n    /** Marks the layoutNode dirty for another lookahead layout pass. */\n    internal fun markLookaheadLayoutPending() = layoutDelegate.markLookaheadLayoutPending()\n\n    fun invalidateSubtree(isRootOfInvalidation: Boolean = true) {\n        if (isRootOfInvalidation) {\n            parent?.invalidateLayer() ?: owner?.invalidateRootLayer()\n        }\n        invalidateSemantics()\n        requestRemeasure()\n        nodes.headToTail(Nodes.Layout) { it.requireCoordinator(Nodes.Layout).layer?.invalidate() }\n        // TODO: invalidate parent data\n        _children.forEach { it.invalidateSubtree(false) }\n    }\n\n    fun invalidateMeasurementForSubtree() {\n        requestRemeasure()\n        _children.forEach { it.invalidateMeasurementForSubtree() }\n    }\n\n    fun invalidateDrawForSubtree(isRootOfInvalidation: Boolean = true) {\n        if (isRootOfInvalidation) {\n            parent?.invalidateLayer() ?: owner?.invalidateRootLayer()\n        }\n        nodes.headToTail(Nodes.Layout) { it.requireCoordinator(Nodes.Layout).layer?.invalidate() }\n        _children.forEach { it.invalidateDrawForSubtree(false) }\n    }\n\n    /** Marks the layoutNode dirty for another lookahead measure pass. */\n    internal fun markLookaheadMeasurePending() = layoutDelegate.markLookaheadMeasurePending()\n\n    override fun forceRemeasure() {\n        // we do not schedule measure and layout as we are going to call it manually right after\n        if (lookaheadRoot != null) {\n            requestLookaheadRemeasure(scheduleMeasureAndLayout = false)\n        } else {\n            requestRemeasure(scheduleMeasureAndLayout = false)\n        }\n        val lastConstraints = layoutDelegate.lastConstraints\n        if (lastConstraints != null) {\n            owner?.measureAndLayout(this, lastConstraints)\n        } else {\n            owner?.measureAndLayout()\n        }\n    }\n\n    override fun onLayoutComplete() {\n        innerCoordinator.visitNodes(Nodes.OnPlaced) { it.onPlaced(innerCoordinator) }\n    }\n\n    /** Calls [block] on all [LayoutModifierNodeCoordinator]s in the NodeCoordinator chain. */\n    internal inline fun forEachCoordinator(block: (LayoutModifierNodeCoordinator) -> Unit) {\n        var coordinator: NodeCoordinator? = outerCoordinator\n        val inner = innerCoordinator\n        while (coordinator !== inner) {\n            block(coordinator as LayoutModifierNodeCoordinator)\n            coordinator = coordinator.wrapped\n        }\n    }\n\n    /** Calls [block] on all [NodeCoordinator]s in the NodeCoordinator chain. */\n    internal inline fun forEachCoordinatorIncludingInner(block: (NodeCoordinator) -> Unit) {\n        var delegate: NodeCoordinator? = outerCoordinator\n        val final = innerCoordinator.wrapped\n        while (delegate != final && delegate != null) {\n            block(delegate)\n            delegate = delegate.wrapped\n        }\n    }\n\n    /**\n     * Walks the subtree and clears all [intrinsicsUsageByParent] that this LayoutNode's measurement\n     * used intrinsics on.\n     *\n     * The layout that asks for intrinsics of its children is the node to call this to request all\n     * of its subtree to be cleared.\n     *\n     * We can't do clearing as part of measure() because the child's measure() call is normally done\n     * after the intrinsics is requested and we don't want to clear the usage at that point.\n     */\n    internal fun clearSubtreeIntrinsicsUsage() {\n        // save the usage in case we short-circuit the measure call\n        previousIntrinsicsUsageByParent = intrinsicsUsageByParent\n        intrinsicsUsageByParent = UsageByParent.NotUsed\n        forEachChild {\n            if (it.intrinsicsUsageByParent != UsageByParent.NotUsed) {\n                it.clearSubtreeIntrinsicsUsage()\n            }\n        }\n    }\n\n    /**\n     * Walks the subtree and clears all [intrinsicsUsageByParent] that this LayoutNode's layout\n     * block used intrinsics on.\n     *\n     * The layout that asks for intrinsics of its children is the node to call this to request all\n     * of its subtree to be cleared.\n     *\n     * We can't do clearing as part of measure() because the child's measure() call is normally done\n     * after the intrinsics is requested and we don't want to clear the usage at that point.\n     */\n    private fun clearSubtreePlacementIntrinsicsUsage() {\n        // save the usage in case we short-circuit the measure call\n        previousIntrinsicsUsageByParent = intrinsicsUsageByParent\n        intrinsicsUsageByParent = UsageByParent.NotUsed\n        forEachChild {\n            if (it.intrinsicsUsageByParent == UsageByParent.InLayoutBlock) {\n                it.clearSubtreePlacementIntrinsicsUsage()\n            }\n        }\n    }\n\n    /**\n     * For a subtree that skips measurement, this resets the [intrinsicsUsageByParent] to what it\n     * was prior to [clearSubtreeIntrinsicsUsage].\n     */\n    internal fun resetSubtreeIntrinsicsUsage() {\n        forEachChild {\n            it.intrinsicsUsageByParent = it.previousIntrinsicsUsageByParent\n            if (it.intrinsicsUsageByParent != UsageByParent.NotUsed) {\n                it.resetSubtreeIntrinsicsUsage()\n            }\n        }\n    }\n\n    override val parentInfo: SemanticsInfo?\n        get() = parent\n\n    override val childrenInfo: List<SemanticsInfo>\n        get() = children\n\n    override var isDeactivated = false\n        private set\n\n    override fun onReuse() {\n        requirePrecondition(isAttached) { \"onReuse is only expected on attached node\" }\n        interopViewFactoryHolder?.onReuse()\n        subcompositionsState?.onReuse()\n        isCurrentlyCalculatingSemanticsConfiguration = false\n        if (isDeactivated) {\n            isDeactivated = false\n            // we don't need to reset state as it was done when deactivated\n        } else {\n            resetModifierState()\n        }\n        val oldSemanticsId = semanticsId\n        // semanticsId is used as the identity. we need to remove from rectlist before changing it\n        owner?.rectManager?.remove(this)\n        semanticsId = generateSemanticsId()\n        owner?.onPreLayoutNodeReused(this, oldSemanticsId)\n        // resetModifierState detaches all nodes, so we need to re-attach them upon reuse.\n        nodes.markAsAttached()\n        nodes.runAttachLifecycle()\n        if (nodes.has(Nodes.Semantics)) {\n            invalidateSemantics()\n        }\n        rescheduleRemeasureOrRelayout(this)\n        owner?.onPostLayoutNodeReused(this, oldSemanticsId)\n        // Sometimes, while scrolling with reuse, a child LayoutNode, might not\n        // require measure or layout at all, but at a minimum we need to update RectManager with\n        // the correct information.\n        owner?.rectManager?.recalculateRectIfDirty(this)\n    }\n\n    override fun onDeactivate() {\n        interopViewFactoryHolder?.onDeactivate()\n        subcompositionsState?.onDeactivate()\n        isDeactivated = true\n        resetModifierState()\n        // if the node is detached the semantics were already updated without this node.\n        if (isAttached) {\n            _semanticsConfiguration = null\n            isSemanticsInvalidated = false\n        }\n        owner?.onLayoutNodeDeactivated(this)\n    }\n\n    override fun onRelease() {\n        interopViewFactoryHolder?.onRelease()\n        subcompositionsState?.onRelease()\n        forEachCoordinatorIncludingInner { it.onRelease() }\n    }\n\n    internal companion object {\n        private val ErrorMeasurePolicy: NoIntrinsicsMeasurePolicy =\n            object :\n                NoIntrinsicsMeasurePolicy(error = \"Undefined intrinsics block and it is required\") {\n                override fun MeasureScope.measure(\n                    measurables: List<Measurable>,\n                    constraints: Constraints,\n                ) = error(\"Undefined measure and it is required\")\n            }\n\n        /** Constant used by [placeOrder]. */\n        @Suppress(\"ConstPropertyName\") internal const val NotPlacedPlaceOrder = Int.MAX_VALUE\n\n        /** Pre-allocated constructor to be used with ComposeNode */\n        internal val Constructor: () -> LayoutNode = { LayoutNode() }\n\n        /**\n         * All of these values are only used in tests. The real ViewConfiguration should be set in\n         * Layout()\n         */\n        internal val DummyViewConfiguration =\n            object : ViewConfiguration {\n                override val longPressTimeoutMillis: Long\n                    get() = 400L\n\n                override val doubleTapTimeoutMillis: Long\n                    get() = 300L\n\n                override val doubleTapMinTimeMillis: Long\n                    get() = 40L\n\n                override val touchSlop: Float\n                    get() = 16f\n\n                override val minimumTouchTargetSize: DpSize\n                    get() = DpSize.Zero\n            }\n\n        /** Comparator allowing to sort nodes by zIndex and placement order. */\n        internal val ZComparator =\n            Comparator<LayoutNode> { node1, node2 ->\n                if (node1.zIndex == node2.zIndex) {\n                    // if zIndex is the same we use the placement order\n                    node1.placeOrder.compareTo(node2.placeOrder)\n                } else {\n                    node1.zIndex.compareTo(node2.zIndex)\n                }\n            }\n    }\n\n    /**\n     * Describes the current state the [LayoutNode] is in. A [LayoutNode] is expected to be in\n     * [LookaheadMeasuring] first, followed by [LookaheadLayingOut] if it is in a LookaheadScope.\n     * After the lookahead is finished, [Measuring] and then [LayingOut] will happen as needed.\n     */\n    internal enum class LayoutState {\n        /** Node is currently being measured. */\n        Measuring,\n\n        /** Node is being measured in lookahead. */\n        LookaheadMeasuring,\n\n        /** Node is currently being laid out. */\n        LayingOut,\n\n        /** Node is being laid out in lookahead. */\n        LookaheadLayingOut,\n\n        /**\n         * Node is not currently measuring or laying out. It could be pending measure or pending\n         * layout depending on the [measurePending] and [layoutPending] flags.\n         */\n        Idle,\n    }\n\n    internal enum class UsageByParent {\n        InMeasureBlock,\n        InLayoutBlock,\n        NotUsed,\n    }\n}\n\ninternal inline fun <T> withComposeStackTrace(layoutNode: LayoutNode, block: () -> T): T =\n    try {\n        block()\n    } catch (e: Throwable) {\n        layoutNode.rethrowWithComposeStackTrace(e)\n    }\n\n/** Returns [LayoutNode.owner] or throws if it is null. */\ninternal fun LayoutNode.requireOwner(): Owner {\n    val owner = owner\n    checkPreconditionNotNull(owner) { \"LayoutNode should be attached to an owner\" }\n    return owner\n}\n\n/**\n * Inserts a child [LayoutNode] at a last index. If this LayoutNode [LayoutNode.isAttached] then\n * [child] will become [LayoutNode.isAttached] also. [child] must have a `null` [LayoutNode.parent].\n */\ninternal fun LayoutNode.add(child: LayoutNode) {\n    insertAt(children.size, child)\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/node/ModifierNodeElement.kt\n```kotlin\n/*\n * Copyright 2022 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.ui.node\n\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.InspectableValue\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.platform.ValueElement\nimport androidx.compose.ui.tryPopulateReflectively\n\n/**\n * A [Modifier.Element] which manages an instance of a particular [Modifier.Node] implementation. A\n * given [Modifier.Node] implementation can only be used when a [ModifierNodeElement] which creates\n * and updates that implementation is applied to a Layout.\n *\n * A [ModifierNodeElement] should be very lightweight, and do little more than hold the information\n * necessary to create and maintain an instance of the associated [Modifier.Node] type.\n *\n * @sample androidx.compose.ui.samples.ModifierNodeElementSample\n * @sample androidx.compose.ui.samples.SemanticsModifierNodeSample\n * @see Modifier.Node\n * @see Modifier.Element\n */\nabstract class ModifierNodeElement<N : Modifier.Node> : Modifier.Element, InspectableValue {\n\n    private var _inspectorValues: InspectorInfo? = null\n    private val inspectorValues: InspectorInfo\n        get() =\n            _inspectorValues\n                ?: InspectorInfo()\n                    .apply {\n                        name = this@ModifierNodeElement::class.simpleName\n                        inspectableProperties()\n                    }\n                    .also { _inspectorValues = it }\n\n    final override val nameFallback: String?\n        get() = inspectorValues.name\n\n    final override val valueOverride: Any?\n        get() = inspectorValues.value\n\n    final override val inspectableElements: Sequence<ValueElement>\n        get() = inspectorValues.properties\n\n    /**\n     * This will be called the first time the modifier is applied to the Layout and it should\n     * construct and return the corresponding [Modifier.Node] instance.\n     */\n    abstract fun create(): N\n\n    /**\n     * Called when a modifier is applied to a Layout whose inputs have changed from the previous\n     * application. This function will have the current node instance passed in as a parameter, and\n     * it is expected that the node will be brought up to date.\n     */\n    abstract fun update(node: N)\n\n    /**\n     * Populates an [InspectorInfo] object with attributes to display in the layout inspector. This\n     * is called by tooling to resolve the properties of this modifier. By convention, implementors\n     * should set the [name][InspectorInfo.name] to the function name of the modifier.\n     *\n     * The default implementation will attempt to reflectively populate the inspector info with the\n     * properties declared on the subclass. It will also set the [name][InspectorInfo.name] property\n     * to the name of this instance's class by default (not the name of the modifier function).\n     * Modifier property population depends on the kotlin-reflect library. If it is not in the\n     * classpath at runtime, the default implementation of this function will populate the\n     * properties with an error message.\n     *\n     * If you override this function and provide the properties you wish to display, you do not need\n     * to call `super`. Doing so may result in duplicate properties appearing in the layout\n     * inspector.\n     */\n    open fun InspectorInfo.inspectableProperties() {\n        tryPopulateReflectively(this@ModifierNodeElement)\n    }\n\n    /**\n     * Require hashCode() to be implemented. Using a data class is sufficient. Singletons and\n     * modifiers with no parameters may implement this function by returning an arbitrary constant.\n     */\n    abstract override fun hashCode(): Int\n\n    /**\n     * Require equals() to be implemented. Using a data class is sufficient. Singletons may\n     * implement this function with referential equality (`this === other`). Modifiers with no\n     * inputs may implement this function by checking the type of the other object.\n     */\n    abstract override fun equals(other: Any?): Boolean\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/input/pointer/PointerInputEventProcessor.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@file:Suppress(\"NOTHING_TO_INLINE\", \"KotlinRedundantDiagnosticSuppress\")\n\npackage androidx.compose.ui.input.pointer\n\nimport androidx.collection.LongSparseArray\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Matrix\nimport androidx.compose.ui.node.HitTestResult\nimport androidx.compose.ui.node.InternalCoreApi\nimport androidx.compose.ui.node.LayoutNode\nimport androidx.compose.ui.util.fastForEach\n\ninternal interface PositionCalculator {\n    fun screenToLocal(positionOnScreen: Offset): Offset\n\n    fun localToScreen(localPosition: Offset): Offset\n}\n\ninternal interface MatrixPositionCalculator : PositionCalculator {\n\n    /**\n     * Takes a matrix which transforms some coordinate system to local coordinates, and updates the\n     * matrix to transform to screen coordinates instead.\n     */\n    fun localToScreen(localTransform: Matrix)\n}\n\n/** The core element that receives [PointerInputEvent]s and process them in Compose UI. */\ninternal class PointerInputEventProcessor(val root: LayoutNode) {\n\n    private val hitPathTracker = HitPathTracker(root.coordinates)\n    private val pointerInputChangeEventProducer = PointerInputChangeEventProducer()\n    private val hitResult = HitTestResult()\n\n    /**\n     * [process] doesn't currently support reentrancy. This prevents reentrant calls from causing a\n     * crash with an early exit.\n     */\n    private var isProcessing = false\n\n    /**\n     * Receives [PointerInputEvent]s and process them through the tree rooted on [root].\n     *\n     * @param pointerEvent The [PointerInputEvent] to process.\n     * @return the result of processing.\n     * @see ProcessResult\n     * @see PointerInputEvent\n     */\n    fun process(\n        @OptIn(InternalCoreApi::class) pointerEvent: PointerInputEvent,\n        positionCalculator: PositionCalculator,\n        isInBounds: Boolean = true,\n    ): ProcessResult {\n        if (isProcessing) {\n            // Processing currently does not support reentrancy.\n            return ProcessResult(\n                dispatchedToAPointerInputModifier = false,\n                anyMovementConsumed = false,\n                anyChangeConsumed = false,\n            )\n        }\n        try {\n            isProcessing = true\n\n            // Gets a new PointerInputChangeEvent with the PointerInputEvent.\n            @OptIn(InternalCoreApi::class)\n            val internalPointerEvent =\n                pointerInputChangeEventProducer.produce(pointerEvent, positionCalculator)\n\n            var isHover = true\n            for (i in 0 until internalPointerEvent.changes.size()) {\n                val pointerInputChange = internalPointerEvent.changes.valueAt(i)\n                if (pointerInputChange.pressed || pointerInputChange.previousPressed) {\n                    isHover = false\n                    break\n                }\n            }\n\n            // Add new hit paths to the tracker due to down events.\n            for (i in 0 until internalPointerEvent.changes.size()) {\n                val pointerInputChange = internalPointerEvent.changes.valueAt(i)\n                if (isHover || pointerInputChange.changedToDownIgnoreConsumed()) {\n                    root.hitTest(pointerInputChange.position, hitResult, pointerInputChange.type)\n                    if (hitResult.isNotEmpty()) {\n                        hitPathTracker.addHitPath(\n                            pointerId = pointerInputChange.id,\n                            pointerInputNodes = hitResult,\n                            // Prunes PointerIds (and changes) to support dynamically\n                            // adding/removing pointer input modifier nodes.\n                            // Note: We do not do this for hover because hover relies on those\n                            // non hit PointerIds to trigger hover exit events.\n                            prunePointerIdsAndChangesNotInNodesList =\n                                pointerInputChange.changedToDownIgnoreConsumed(),\n                        )\n                        hitResult.clear()\n                    }\n                }\n            }\n\n            // Dispatch to PointerInputFilters\n            val dispatchedToSomething =\n                hitPathTracker.dispatchChanges(internalPointerEvent, isInBounds)\n\n            val anyMovementConsumed =\n                if (internalPointerEvent.suppressMovementConsumption) {\n                    false\n                } else {\n                    var result = false\n                    for (i in 0 until internalPointerEvent.changes.size()) {\n                        val event = internalPointerEvent.changes.valueAt(i)\n                        if (event.positionChangedIgnoreConsumed() && event.isConsumed) {\n                            result = true\n                            break\n                        }\n                    }\n                    result\n                }\n\n            var anyChangeConsumed = false\n            for (i in 0 until internalPointerEvent.changes.size()) {\n                val change = internalPointerEvent.changes.valueAt(i)\n                if (change.isConsumed) {\n                    anyChangeConsumed = true\n                    break\n                }\n            }\n\n            return ProcessResult(\n                dispatchedToAPointerInputModifier = dispatchedToSomething,\n                anyMovementConsumed = anyMovementConsumed,\n                anyChangeConsumed = anyChangeConsumed,\n            )\n        } finally {\n            isProcessing = false\n        }\n    }\n\n    /**\n     * Responds appropriately to Android ACTION_CANCEL events.\n     *\n     * Specifically, [PointerInputFilter.onCancel] is invoked on tracked [PointerInputFilter]s and\n     * and this [PointerInputEventProcessor] is reset such that it is no longer tracking any\n     * [PointerInputFilter]s and expects the next [PointerInputEvent] it processes to represent only\n     * new pointers.\n     */\n    fun processCancel() {\n        if (!isProcessing) {\n            // Processing currently does not support reentrancy.\n            pointerInputChangeEventProducer.clear()\n            hitPathTracker.processCancel()\n        }\n    }\n\n    /**\n     * In some cases we need to clear the HIT Modifier.Node(s) cached from previous events because\n     * they are no longer relevant.\n     */\n    fun clearPreviouslyHitModifierNodes() {\n        hitPathTracker.clearPreviouslyHitModifierNodeCache()\n    }\n}\n\n/** Produces [InternalPointerEvent]s by tracking changes between [PointerInputEvent]s */\n@OptIn(InternalCoreApi::class)\nprivate class PointerInputChangeEventProducer {\n    private val previousPointerInputData: LongSparseArray<PointerInputData> = LongSparseArray()\n\n    /** Produces [InternalPointerEvent]s by tracking changes between [PointerInputEvent]s */\n    fun produce(\n        pointerInputEvent: PointerInputEvent,\n        positionCalculator: PositionCalculator,\n    ): InternalPointerEvent {\n        // Set initial capacity to avoid resizing - we know the size the map will be.\n        val changes: LongSparseArray<PointerInputChange> =\n            LongSparseArray(pointerInputEvent.pointers.size)\n        pointerInputEvent.pointers.fastForEach {\n            val previousTime: Long\n            val previousPosition: Offset\n            val previousDown: Boolean\n\n            val previousData = previousPointerInputData[it.id.value]\n            if (previousData == null) {\n                previousTime = it.uptime\n                previousPosition = it.position\n                previousDown = false\n            } else {\n                previousTime = previousData.uptime\n                previousDown = previousData.down\n                previousPosition = positionCalculator.screenToLocal(previousData.positionOnScreen)\n            }\n\n            changes.put(\n                it.id.value,\n                PointerInputChange(\n                    id = it.id,\n                    uptimeMillis = it.uptime,\n                    position = it.position,\n                    pressed = it.down,\n                    pressure = it.pressure,\n                    previousUptimeMillis = previousTime,\n                    previousPosition = previousPosition,\n                    previousPressed = previousDown,\n                    isInitiallyConsumed = false,\n                    type = it.type,\n                    historical = it.historical,\n                    scrollDelta = it.scrollDelta,\n                    scaleGestureFactor = it.scaleGestureFactor,\n                    panGestureOffset = it.panGestureOffset,\n                    originalEventPosition = it.originalEventPosition,\n                ),\n            )\n            if (it.down) {\n                previousPointerInputData.put(\n                    it.id.value,\n                    PointerInputData(it.uptime, it.positionOnScreen, it.down),\n                )\n            } else {\n                previousPointerInputData.remove(it.id.value)\n            }\n        }\n\n        return InternalPointerEvent(changes, pointerInputEvent)\n    }\n\n    /** Clears all tracked information. */\n    fun clear() {\n        previousPointerInputData.clear()\n    }\n\n    private class PointerInputData(\n        val uptime: Long,\n        val positionOnScreen: Offset,\n        val down: Boolean,\n    )\n}\n\n/** The result of a call to [PointerInputEventProcessor.process]. */\n@kotlin.jvm.JvmInline\ninternal value class ProcessResult(val value: Int) {\n    /** It's true when any [PointerInputFilter] has processed a [PointerInputChange] */\n    val dispatchedToAPointerInputModifier\n        inline get() = (value and 0x1) != 0\n\n    /** It's true when [PointerInputChange] was consumed and Pointer's position was changed */\n    val anyMovementConsumed\n        inline get() = (value and 0x2) != 0\n\n    /** It's true when any [PointerInputChange] was consumed. */\n    val anyChangeConsumed\n        inline get() = (value and 0x4) != 0\n}\n\n/**\n * Constructs a new ProcessResult.\n *\n * @param dispatchedToAPointerInputModifier True if the dispatch resulted in at least 1\n *   [PointerInputModifier] receiving the event.\n * @param anyMovementConsumed True if any movement occurred and was consumed.\n */\ninternal fun ProcessResult(\n    dispatchedToAPointerInputModifier: Boolean,\n    anyMovementConsumed: Boolean,\n    anyChangeConsumed: Boolean,\n): ProcessResult {\n    return ProcessResult(\n        value =\n            dispatchedToAPointerInputModifier.toInt() or\n                (anyMovementConsumed.toInt() shl 1) or\n                (anyChangeConsumed.toInt() shl 2)\n    )\n}\n\nprivate inline fun Boolean.toInt() = if (this) 1 else 0\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/draw/DrawModifier.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.ui.draw\n\nimport androidx.collection.MutableObjectList\nimport androidx.collection.mutableObjectListOf\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.Canvas\nimport androidx.compose.ui.graphics.GraphicsContext\nimport androidx.compose.ui.graphics.drawscope.ContentDrawScope\nimport androidx.compose.ui.graphics.drawscope.DrawScope\nimport androidx.compose.ui.graphics.layer.GraphicsLayer\nimport androidx.compose.ui.graphics.shadow.DropShadowPainter\nimport androidx.compose.ui.graphics.shadow.InnerShadowPainter\nimport androidx.compose.ui.graphics.shadow.ShadowContext\nimport androidx.compose.ui.internal.JvmDefaultWithCompatibility\nimport androidx.compose.ui.internal.checkPrecondition\nimport androidx.compose.ui.internal.checkPreconditionNotNull\nimport androidx.compose.ui.node.DrawModifierNode\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.node.Nodes\nimport androidx.compose.ui.node.ObserverModifierNode\nimport androidx.compose.ui.node.invalidateDraw\nimport androidx.compose.ui.node.observeReads\nimport androidx.compose.ui.node.requireCoordinator\nimport androidx.compose.ui.node.requireDensity\nimport androidx.compose.ui.node.requireGraphicsContext\nimport androidx.compose.ui.node.requireLayoutDirection\nimport androidx.compose.ui.platform.InspectorInfo\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.IntSize\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.toIntSize\nimport androidx.compose.ui.unit.toSize\n\n/** A [Modifier.Element] that draws into the space of the layout. */\n@JvmDefaultWithCompatibility\ninterface DrawModifier : Modifier.Element {\n\n    fun ContentDrawScope.draw()\n}\n\n/**\n * [DrawModifier] implementation that supports building a cache of objects to be referenced across\n * draw calls\n */\n@JvmDefaultWithCompatibility\ninterface DrawCacheModifier : DrawModifier {\n\n    /**\n     * Callback invoked to re-build objects to be re-used across draw calls. This is useful to\n     * conditionally recreate objects only if the size of the drawing environment changes, or if\n     * state parameters that are inputs to objects change. This method is guaranteed to be called\n     * before [DrawModifier.draw].\n     *\n     * @param params The params to be used to build the cache.\n     */\n    fun onBuildCache(params: BuildDrawCacheParams)\n}\n\n/**\n * The set of parameters which could be used to build the drawing cache.\n *\n * @see DrawCacheModifier.onBuildCache\n */\ninterface BuildDrawCacheParams {\n    /** The current size of the drawing environment */\n    val size: Size\n\n    /** The current layout direction. */\n    val layoutDirection: LayoutDirection\n\n    /** The current screen density to provide the ability to convert between */\n    val density: Density\n}\n\n/** Draw into a [Canvas] behind the modified content. */\nfun Modifier.drawBehind(onDraw: DrawScope.() -> Unit) = this then DrawBehindElement(onDraw)\n\nprivate class DrawBehindElement(val onDraw: DrawScope.() -> Unit) :\n    ModifierNodeElement<DrawBackgroundModifier>() {\n    override fun create() = DrawBackgroundModifier(onDraw)\n\n    override fun update(node: DrawBackgroundModifier) {\n        node.onDraw = onDraw\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"drawBehind\"\n        properties[\"onDraw\"] = onDraw\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is DrawBehindElement) return false\n\n        if (onDraw !== other.onDraw) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        return onDraw.hashCode()\n    }\n}\n\ninternal class DrawBackgroundModifier(var onDraw: DrawScope.() -> Unit) :\n    Modifier.Node(), DrawModifierNode {\n\n    override fun ContentDrawScope.draw() {\n        onDraw()\n        drawContent()\n    }\n}\n\n/**\n * Draw into a [DrawScope] with content that is persisted across draw calls as long as the size of\n * the drawing area is the same or any state objects that are read have not changed. In the event\n * that the drawing area changes, or the underlying state values that are being read change, this\n * method is invoked again to recreate objects to be used during drawing\n *\n * For example, a [androidx.compose.ui.graphics.LinearGradient] that is to occupy the full bounds of\n * the drawing area can be created once the size has been defined and referenced for subsequent draw\n * calls without having to re-allocate.\n *\n * @sample androidx.compose.ui.samples.DrawWithCacheModifierSample\n * @sample androidx.compose.ui.samples.DrawWithCacheModifierStateParameterSample\n * @sample androidx.compose.ui.samples.DrawWithCacheContentSample\n */\nfun Modifier.drawWithCache(onBuildDrawCache: CacheDrawScope.() -> DrawResult) =\n    this then DrawWithCacheElement(onBuildDrawCache)\n\nprivate class DrawWithCacheElement(val onBuildDrawCache: CacheDrawScope.() -> DrawResult) :\n    ModifierNodeElement<CacheDrawModifierNodeImpl>() {\n    override fun create(): CacheDrawModifierNodeImpl {\n        return CacheDrawModifierNodeImpl(CacheDrawScope(), onBuildDrawCache)\n    }\n\n    override fun update(node: CacheDrawModifierNodeImpl) {\n        node.block = onBuildDrawCache\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"drawWithCache\"\n        properties[\"onBuildDrawCache\"] = onBuildDrawCache\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is DrawWithCacheElement) return false\n\n        if (onBuildDrawCache !== other.onBuildDrawCache) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        return onBuildDrawCache.hashCode()\n    }\n}\n\nfun CacheDrawModifierNode(\n    onBuildDrawCache: CacheDrawScope.() -> DrawResult\n): CacheDrawModifierNode {\n    return CacheDrawModifierNodeImpl(CacheDrawScope(), onBuildDrawCache)\n}\n\n/**\n * Expands on the [androidx.compose.ui.node.DrawModifierNode] by adding the ability to invalidate\n * the draw cache for changes in things like shapes and bitmaps (see Modifier.border for a usage\n * examples).\n */\nsealed interface CacheDrawModifierNode : DrawModifierNode {\n    fun invalidateDrawCache()\n}\n\n/**\n * Wrapper [GraphicsContext] implementation that maintains a list of the [GraphicsLayer] instances\n * that were created through this instance so it can release only those [GraphicsLayer]s when it is\n * disposed of within the corresponding Modifier is disposed\n */\nprivate class ScopedGraphicsContext : GraphicsContext {\n\n    private var allocatedGraphicsLayers: MutableObjectList<GraphicsLayer>? = null\n\n    var graphicsContext: GraphicsContext? = null\n        set(value) {\n            releaseGraphicsLayers()\n            field = value\n        }\n\n    override fun createGraphicsLayer(): GraphicsLayer {\n        val gContext = graphicsContext\n        checkPrecondition(gContext != null) { \"GraphicsContext not provided\" }\n        val layer = gContext.createGraphicsLayer()\n        val layers = allocatedGraphicsLayers\n        if (layers == null) {\n            mutableObjectListOf(layer).also { allocatedGraphicsLayers = it }\n        } else {\n            layers.add(layer)\n        }\n\n        return layer\n    }\n\n    override fun releaseGraphicsLayer(layer: GraphicsLayer) {\n        graphicsContext?.releaseGraphicsLayer(layer)\n    }\n\n    override val shadowContext: ShadowContext\n        get() {\n            val gContext = graphicsContext\n            checkPrecondition(gContext != null) { \"GraphicsContext not provided\" }\n            return gContext.shadowContext\n        }\n\n    fun releaseGraphicsLayers() {\n        allocatedGraphicsLayers?.let { layers ->\n            layers.forEach { layer -> releaseGraphicsLayer(layer) }\n            layers.clear()\n        }\n    }\n}\n\nprivate class CacheDrawModifierNodeImpl(\n    private val cacheDrawScope: CacheDrawScope,\n    block: CacheDrawScope.() -> DrawResult,\n) : Modifier.Node(), CacheDrawModifierNode, ObserverModifierNode, BuildDrawCacheParams {\n\n    private var isCacheValid = false\n    private var cachedGraphicsContext: ScopedGraphicsContext? = null\n\n    var block: CacheDrawScope.() -> DrawResult = block\n        set(value) {\n            field = value\n            invalidateDrawCache()\n        }\n\n    init {\n        cacheDrawScope.cacheParams = this\n        cacheDrawScope.graphicsContextProvider = { graphicsContext }\n    }\n\n    override val density: Density\n        get() = requireDensity()\n\n    override val layoutDirection: LayoutDirection\n        get() = requireLayoutDirection()\n\n    override val size: Size\n        get() = requireCoordinator(Nodes.Draw).size.toSize()\n\n    val graphicsContext: GraphicsContext\n        get() {\n            var localGraphicsContext = cachedGraphicsContext\n            if (localGraphicsContext == null) {\n                localGraphicsContext = ScopedGraphicsContext().also { cachedGraphicsContext = it }\n            }\n            if (localGraphicsContext.graphicsContext == null) {\n                localGraphicsContext.graphicsContext = requireGraphicsContext()\n            }\n            return localGraphicsContext\n        }\n\n    override fun onDetach() {\n        super.onDetach()\n        cachedGraphicsContext?.releaseGraphicsLayers()\n    }\n\n    override fun onReset() {\n        super.onReset()\n        invalidateDrawCache()\n    }\n\n    override fun onMeasureResultChanged() {\n        invalidateDrawCache()\n    }\n\n    override fun onObservedReadsChanged() {\n        invalidateDrawCache()\n    }\n\n    override fun invalidateDrawCache() {\n        // Release all previously allocated graphics layers to the recycling pool\n        // if a layer is needed in a subsequent draw, it will be obtained from the pool again and\n        // reused\n        cachedGraphicsContext?.releaseGraphicsLayers()\n        isCacheValid = false\n        cacheDrawScope.drawResult = null\n        invalidateDraw()\n    }\n\n    override fun onDensityChange() {\n        invalidateDrawCache()\n    }\n\n    override fun onLayoutDirectionChange() {\n        invalidateDrawCache()\n    }\n\n    private fun getOrBuildCachedDrawBlock(contentDrawScope: ContentDrawScope): DrawResult {\n        if (!isCacheValid) {\n            cacheDrawScope.apply {\n                drawResult = null\n                this.contentDrawScope = contentDrawScope\n                observeReads { block() }\n                checkPreconditionNotNull(drawResult) {\n                    \"DrawResult not defined, did you forget to call onDraw?\"\n                }\n            }\n            isCacheValid = true\n        }\n        return cacheDrawScope.drawResult!!\n    }\n\n    override fun ContentDrawScope.draw() {\n        getOrBuildCachedDrawBlock(this).block(this)\n    }\n}\n\n/**\n * Handle to a drawing environment that enables caching of content based on the resolved size.\n * Consumers define parameters and refer to them in the captured draw callback provided in\n * [onDrawBehind] or [onDrawWithContent].\n *\n * [onDrawBehind] will draw behind the layout's drawing contents however, [onDrawWithContent] will\n * provide the ability to draw before or after the layout's contents\n */\nclass CacheDrawScope internal constructor() : Density {\n    internal var cacheParams: BuildDrawCacheParams = EmptyBuildDrawCacheParams\n    internal var drawResult: DrawResult? = null\n    internal var contentDrawScope: ContentDrawScope? = null\n    internal var graphicsContextProvider: (() -> GraphicsContext)? = null\n\n    /** Provides the dimensions of the current drawing environment */\n    val size: Size\n        get() = cacheParams.size\n\n    /** Provides the [LayoutDirection]. */\n    val layoutDirection: LayoutDirection\n        get() = cacheParams.layoutDirection\n\n    /**\n     * Returns a managed [GraphicsLayer] instance. This [GraphicsLayer] maybe newly created or\n     * return a previously allocated instance. Consumers are not expected to release this instance\n     * as it is automatically recycled upon invalidation of the CacheDrawScope and released when the\n     * [DrawCacheModifier] is detached.\n     */\n    fun obtainGraphicsLayer(): GraphicsLayer =\n        graphicsContextProvider!!.invoke().createGraphicsLayer()\n\n    /**\n     * Returns the [ShadowContext] used to create [InnerShadowPainter] and [DropShadowPainter] to\n     * render inner and drop shadows respectively\n     */\n    fun obtainShadowContext(): ShadowContext = graphicsContextProvider!!.invoke().shadowContext\n\n    /**\n     * Record the drawing commands into the [GraphicsLayer] with the [Density], [LayoutDirection]\n     * and [Size] are given from the provided [CacheDrawScope]\n     */\n    fun GraphicsLayer.record(\n        density: Density = this@CacheDrawScope,\n        layoutDirection: LayoutDirection = this@CacheDrawScope.layoutDirection,\n        size: IntSize = this@CacheDrawScope.size.toIntSize(),\n        block: ContentDrawScope.() -> Unit,\n    ) {\n        val scope = contentDrawScope!!\n        with(scope) {\n            val prevDensity = drawContext.density\n            val prevLayoutDirection = drawContext.layoutDirection\n            record(size) {\n                drawContext.apply {\n                    this.density = density\n                    this.layoutDirection = layoutDirection\n                }\n                try {\n                    block(scope)\n                } finally {\n                    drawContext.apply {\n                        this.density = prevDensity\n                        this.layoutDirection = prevLayoutDirection\n                    }\n                }\n            }\n        }\n    }\n\n    /** Issue drawing commands to be executed before the layout content is drawn */\n    fun onDrawBehind(block: DrawScope.() -> Unit): DrawResult = onDrawWithContent {\n        block()\n        drawContent()\n    }\n\n    /** Issue drawing commands before or after the layout's drawing contents */\n    fun onDrawWithContent(block: ContentDrawScope.() -> Unit): DrawResult {\n        return DrawResult(block).also { drawResult = it }\n    }\n\n    override val density: Float\n        get() = cacheParams.density.density\n\n    override val fontScale: Float\n        get() = cacheParams.density.fontScale\n}\n\nprivate object EmptyBuildDrawCacheParams : BuildDrawCacheParams {\n    override val size: Size = Size.Unspecified\n    override val layoutDirection: LayoutDirection = LayoutDirection.Ltr\n    override val density: Density = Density(1f, 1f)\n}\n\n/**\n * Holder to a callback to be invoked during draw operations. This lambda captures and reuses\n * parameters defined within the CacheDrawScope receiver scope lambda.\n */\nclass DrawResult internal constructor(internal var block: ContentDrawScope.() -> Unit)\n\n/**\n * Creates a [DrawModifier] that allows the developer to draw before or after the layout's contents.\n * It also allows the modifier to adjust the layout's canvas.\n */\nfun Modifier.drawWithContent(onDraw: ContentDrawScope.() -> Unit): Modifier =\n    this then DrawWithContentElement(onDraw)\n\nprivate class DrawWithContentElement(val onDraw: ContentDrawScope.() -> Unit) :\n    ModifierNodeElement<DrawWithContentModifier>() {\n    override fun create() = DrawWithContentModifier(onDraw)\n\n    override fun update(node: DrawWithContentModifier) {\n        node.onDraw = onDraw\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"drawWithContent\"\n        properties[\"onDraw\"] = onDraw\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is DrawWithContentElement) return false\n\n        if (onDraw !== other.onDraw) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        return onDraw.hashCode()\n    }\n}\n\nprivate class DrawWithContentModifier(var onDraw: ContentDrawScope.() -> Unit) :\n    Modifier.Node(), DrawModifierNode {\n\n    override fun ContentDrawScope.draw() {\n        onDraw()\n    }\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsModifier.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.ui.semantics\n\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.internal.JvmDefaultWithCompatibility\nimport androidx.compose.ui.node.ModifierNodeElement\nimport androidx.compose.ui.node.SemanticsModifierNode\nimport androidx.compose.ui.platform.AtomicInt\nimport androidx.compose.ui.platform.InspectorInfo\n\nprivate var lastIdentifier = AtomicInt(0)\n\ninternal fun generateSemanticsId() = lastIdentifier.addAndGet(1)\n\n/**\n * A [Modifier.Element] that adds semantics key/value for use in testing, accessibility, and similar\n * use cases.\n */\n@JvmDefaultWithCompatibility\ninterface SemanticsModifier : Modifier.Element {\n    @Deprecated(\n        message =\n            \"SemanticsModifier.id is now unused and has been set to a fixed value. \" +\n                \"Retrieve the id from LayoutInfo instead.\",\n        replaceWith = ReplaceWith(\"\"),\n    )\n    val id: Int\n        get() = -1\n\n    /**\n     * The SemanticsConfiguration holds substantive data, especially a list of key/value pairs such\n     * as (label -> \"buttonName\").\n     */\n    val semanticsConfiguration: SemanticsConfiguration\n}\n\ninternal class CoreSemanticsModifierNode(\n    var mergeDescendants: Boolean,\n    var isClearingSemantics: Boolean,\n    var properties: SemanticsPropertyReceiver.() -> Unit,\n) : Modifier.Node(), SemanticsModifierNode {\n    override val shouldClearDescendantSemantics: Boolean\n        get() = isClearingSemantics\n\n    override val shouldMergeDescendantSemantics: Boolean\n        get() = mergeDescendants\n\n    override fun SemanticsPropertyReceiver.applySemantics() {\n        properties()\n    }\n}\n\ninternal class EmptySemanticsModifier : Modifier.Node(), SemanticsModifierNode {\n    override fun SemanticsPropertyReceiver.applySemantics() {}\n}\n\n/**\n * Add semantics key/value pairs to the layout node, for use in testing, accessibility, etc.\n *\n * The provided lambda receiver scope provides \"key = value\"-style setters for any\n * [SemanticsPropertyKey]. Additionally, chaining multiple semantics modifiers is also a supported\n * style.\n *\n * The resulting semantics produce two [SemanticsNode] trees:\n *\n * The \"unmerged tree\" rooted at [SemanticsOwner.unmergedRootSemanticsNode] has one [SemanticsNode]\n * per layout node which has any [SemanticsModifier] on it. This [SemanticsNode] contains all the\n * properties set in all the [SemanticsModifier]s on that node.\n *\n * The \"merged tree\" rooted at [SemanticsOwner.rootSemanticsNode] has equal-or-fewer nodes: it\n * simplifies the structure based on [mergeDescendants] and [clearAndSetSemantics]. For most\n * purposes (especially accessibility, or the testing of accessibility), the merged semantics tree\n * should be used.\n *\n * @param mergeDescendants Whether the semantic information provided by the owning component and its\n *   descendants should be treated as one logical entity. Most commonly set on\n *   screen-reader-focusable items such as buttons or form fields. In the merged semantics tree, all\n *   descendant nodes (except those themselves marked [mergeDescendants]) will disappear from the\n *   tree, and their properties will get merged into the parent's configuration (using a merging\n *   algorithm that varies based on the type of property -- for example, text properties will get\n *   concatenated, separated by commas). In the unmerged semantics tree, the node is simply marked\n *   with [SemanticsConfiguration.isMergingSemanticsOfDescendants].\n * @param properties properties to add to the semantics. [SemanticsPropertyReceiver] will be\n *   provided in the scope to allow access for common properties and its values.\n *\n *   Note: The [properties] block should be used to set semantic properties or semantic actions.\n *   Don't call [SemanticsModifierNode.applySemantics] from within the [properties] block. It will\n *   result in an infinite loop.\n */\nfun Modifier.semantics(\n    mergeDescendants: Boolean = false,\n    properties: (SemanticsPropertyReceiver.() -> Unit),\n): Modifier =\n    this then AppendedSemanticsElement(mergeDescendants = mergeDescendants, properties = properties)\n\n// Implement SemanticsModifier to allow tooling to inspect the semantics configuration\ninternal class AppendedSemanticsElement(\n    val mergeDescendants: Boolean,\n    val properties: (SemanticsPropertyReceiver.() -> Unit),\n) : ModifierNodeElement<CoreSemanticsModifierNode>(), SemanticsModifier {\n\n    // This should only ever be called by layout inspector\n    override val semanticsConfiguration: SemanticsConfiguration\n        get() =\n            SemanticsConfiguration().apply {\n                isMergingSemanticsOfDescendants = mergeDescendants\n                properties()\n            }\n\n    override fun create(): CoreSemanticsModifierNode {\n        return CoreSemanticsModifierNode(\n            mergeDescendants = mergeDescendants,\n            isClearingSemantics = false,\n            properties = properties,\n        )\n    }\n\n    override fun update(node: CoreSemanticsModifierNode) {\n        node.mergeDescendants = mergeDescendants\n        node.properties = properties\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"semantics\"\n        properties[\"mergeDescendants\"] = mergeDescendants\n        addSemanticsPropertiesFrom(semanticsConfiguration)\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is AppendedSemanticsElement) return false\n\n        if (mergeDescendants != other.mergeDescendants) return false\n        if (properties !== other.properties) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = mergeDescendants.hashCode()\n        result = 31 * result + properties.hashCode()\n        return result\n    }\n}\n\n/**\n * Clears the semantics of all the descendant nodes and sets new semantics.\n *\n * In the merged semantics tree, this clears the semantic information provided by the node's\n * descendants (but not those of the layout node itself, if any) and sets the provided semantics.\n * (In the unmerged tree, the semantics node is marked with\n * \"[SemanticsConfiguration.isClearingSemantics]\", but nothing is actually cleared.)\n *\n * Compose's default semantics provide baseline usability for screen-readers, but this can be used\n * to provide a more polished screen-reader experience: for example, clearing the semantics of a\n * group of tiny buttons, and setting equivalent actions on the card containing them.\n *\n * @param properties properties to add to the semantics. [SemanticsPropertyReceiver] will be\n *   provided in the scope to allow access for common properties and its values.\n *\n *   Note: The [properties] lambda should be used to set semantic properties or semantic actions.\n *   Don't call [SemanticsModifierNode.applySemantics] from within the [properties] block. It will\n *   result in an infinite loop.\n */\nfun Modifier.clearAndSetSemantics(properties: (SemanticsPropertyReceiver.() -> Unit)): Modifier =\n    this then ClearAndSetSemanticsElement(properties)\n\n// Implement SemanticsModifier to allow tooling to inspect the semantics configuration\ninternal class ClearAndSetSemanticsElement(val properties: SemanticsPropertyReceiver.() -> Unit) :\n    ModifierNodeElement<CoreSemanticsModifierNode>(), SemanticsModifier {\n\n    // This should only ever be called by layout inspector\n    override val semanticsConfiguration: SemanticsConfiguration\n        get() =\n            SemanticsConfiguration().apply {\n                isMergingSemanticsOfDescendants = false\n                isClearingSemantics = true\n                properties()\n            }\n\n    override fun create(): CoreSemanticsModifierNode {\n        return CoreSemanticsModifierNode(\n            mergeDescendants = false,\n            isClearingSemantics = true,\n            properties = properties,\n        )\n    }\n\n    override fun update(node: CoreSemanticsModifierNode) {\n        node.properties = properties\n    }\n\n    override fun InspectorInfo.inspectableProperties() {\n        name = \"clearAndSetSemantics\"\n        addSemanticsPropertiesFrom(semanticsConfiguration)\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is ClearAndSetSemanticsElement) return false\n\n        if (properties !== other.properties) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        return properties.hashCode()\n    }\n}\n\nprivate fun InspectorInfo.addSemanticsPropertiesFrom(\n    semanticsConfiguration: SemanticsConfiguration\n) {\n    properties[\"properties\"] =\n        semanticsConfiguration.associate { (key, value) -> key.name to value }\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/semantics/SemanticsProperties.kt\n```kotlin\n/*\n * Copyright 2019 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.ui.semantics\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.ui.autofill.ContentDataType\nimport androidx.compose.ui.autofill.ContentType\nimport androidx.compose.ui.autofill.FillableData\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Shape\nimport androidx.compose.ui.state.ToggleableState\nimport androidx.compose.ui.text.AnnotatedString\nimport androidx.compose.ui.text.TextLayoutResult\nimport androidx.compose.ui.text.TextRange\nimport androidx.compose.ui.text.input.ImeAction\nimport kotlin.reflect.KProperty\n\n/**\n * General semantics properties, mainly used for accessibility and testing.\n *\n * Each of these is intended to be set by the respective SemanticsPropertyReceiver extension instead\n * of used directly.\n */\n/*@VisibleForTesting*/\nobject SemanticsProperties {\n    /** @see SemanticsPropertyReceiver.contentDescription */\n    val ContentDescription =\n        AccessibilityKey<List<String>>(\n            name = \"ContentDescription\",\n            mergePolicy = { parentValue, childValue ->\n                parentValue?.toMutableList()?.also { it.addAll(childValue) } ?: childValue\n            },\n        )\n\n    /** @see SemanticsPropertyReceiver.stateDescription */\n    val StateDescription = AccessibilityKey<String>(\"StateDescription\")\n\n    /** @see SemanticsPropertyReceiver.progressBarRangeInfo */\n    val ProgressBarRangeInfo = AccessibilityKey<ProgressBarRangeInfo>(\"ProgressBarRangeInfo\")\n\n    /** @see SemanticsPropertyReceiver.paneTitle */\n    val PaneTitle =\n        AccessibilityKey<String>(\n            name = \"PaneTitle\",\n            mergePolicy = { _, _ ->\n                throw IllegalStateException(\n                    \"merge function called on unmergeable property PaneTitle.\"\n                )\n            },\n        )\n\n    /** @see SemanticsPropertyReceiver.selectableGroup */\n    val SelectableGroup = AccessibilityKey<Unit>(\"SelectableGroup\")\n\n    /** @see SemanticsPropertyReceiver.collectionInfo */\n    val CollectionInfo = AccessibilityKey<CollectionInfo>(\"CollectionInfo\")\n\n    /** @see SemanticsPropertyReceiver.collectionItemInfo */\n    val CollectionItemInfo = AccessibilityKey<CollectionItemInfo>(\"CollectionItemInfo\")\n\n    /** @see SemanticsPropertyReceiver.heading */\n    val Heading = AccessibilityKey<Unit>(\"Heading\")\n\n    /** @see SemanticsPropertyReceiver.textEntryKey */\n    val TextEntryKey = AccessibilityKey<Unit>(\"TextEntryKey\")\n\n    /** @see SemanticsPropertyReceiver.disabled */\n    val Disabled = AccessibilityKey<Unit>(\"Disabled\")\n\n    /** @see SemanticsPropertyReceiver.liveRegion */\n    val LiveRegion = AccessibilityKey<LiveRegionMode>(\"LiveRegion\")\n\n    /** @see SemanticsPropertyReceiver.focused */\n    val Focused = AccessibilityKey<Boolean>(\"Focused\")\n\n    /** @see SemanticsPropertyReceiver.isContainer */\n    @Deprecated(\"Use `isTraversalGroup` instead.\", replaceWith = ReplaceWith(\"IsTraversalGroup\"))\n    // TODO(mnuzen): `isContainer` should not need to be an accessibility key after a new\n    //  pruning API is added. See b/347038246 for more details.\n    val IsContainer = AccessibilityKey<Boolean>(\"IsContainer\")\n\n    /** @see SemanticsPropertyReceiver.isTraversalGroup */\n    val IsTraversalGroup = SemanticsPropertyKey<Boolean>(\"IsTraversalGroup\")\n\n    /** @see SemanticsPropertyReceiver.IsSensitiveData */\n    val IsSensitiveData = SemanticsPropertyKey<Boolean>(\"IsSensitiveData\")\n\n    /** @see SemanticsPropertyReceiver.invisibleToUser */\n    @Deprecated(\n        \"Use `hideFromAccessibility` instead.\",\n        replaceWith = ReplaceWith(\"HideFromAccessibility\"),\n    )\n    // Retain for binary compatibility with aosp/3341487 in 1.7\n    val InvisibleToUser =\n        SemanticsPropertyKey<Unit>(\n            name = \"InvisibleToUser\",\n            mergePolicy = { parentValue, _ -> parentValue },\n        )\n\n    /** @see SemanticsPropertyReceiver.hideFromAccessibility */\n    val HideFromAccessibility =\n        SemanticsPropertyKey<Unit>(\n            name = \"HideFromAccessibility\",\n            mergePolicy = { parentValue, _ -> parentValue },\n        )\n\n    /** @see SemanticsPropertyReceiver.contentType */\n    val ContentType =\n        SemanticsPropertyKey<ContentType>(\n            name = \"ContentType\",\n            mergePolicy = { parentValue, _ ->\n                // Never merge autofill types\n                parentValue\n            },\n        )\n\n    /** @see SemanticsPropertyReceiver.contentDataType */\n    val ContentDataType =\n        SemanticsPropertyKey<ContentDataType>(\n            name = \"ContentDataType\",\n            mergePolicy = { parentValue, _ ->\n                // Never merge autofill data types\n                parentValue\n            },\n        )\n\n    /** @see SemanticsPropertyReceiver.fillableData */\n    val FillableData =\n        SemanticsPropertyKey<FillableData>(\n            name = \"FillableData\",\n            mergePolicy = { parentValue, _ ->\n                // Never merge autofill types\n                parentValue\n            },\n        )\n\n    /** @see SemanticsPropertyReceiver.traversalIndex */\n    val TraversalIndex =\n        SemanticsPropertyKey<Float>(\n            name = \"TraversalIndex\",\n            mergePolicy = { parentValue, _ ->\n                // Never merge traversal indices\n                parentValue\n            },\n        )\n\n    /** @see SemanticsPropertyReceiver.horizontalScrollAxisRange */\n    val HorizontalScrollAxisRange = AccessibilityKey<ScrollAxisRange>(\"HorizontalScrollAxisRange\")\n\n    /** @see SemanticsPropertyReceiver.verticalScrollAxisRange */\n    val VerticalScrollAxisRange = AccessibilityKey<ScrollAxisRange>(\"VerticalScrollAxisRange\")\n\n    /** @see SemanticsPropertyReceiver.popup */\n    val IsPopup =\n        AccessibilityKey<Unit>(\n            name = \"IsPopup\",\n            mergePolicy = { _, _ ->\n                throw IllegalStateException(\n                    \"merge function called on unmergeable property IsPopup. \" +\n                        \"A popup should not be a child of a clickable/focusable node.\"\n                )\n            },\n        )\n\n    /** @see SemanticsPropertyReceiver.dialog */\n    val IsDialog =\n        AccessibilityKey<Unit>(\n            name = \"IsDialog\",\n            mergePolicy = { _, _ ->\n                throw IllegalStateException(\n                    \"merge function called on unmergeable property IsDialog. \" +\n                        \"A dialog should not be a child of a clickable/focusable node.\"\n                )\n            },\n        )\n\n    /**\n     * The type of user interface element. Accessibility services might use this to describe the\n     * element or do customizations. Most roles can be automatically resolved by the semantics\n     * properties of this element. But some elements with subtle differences need an exact role. If\n     * an exact role is not listed in [Role], this property should not be set and the framework will\n     * automatically resolve it.\n     *\n     * @see SemanticsPropertyReceiver.role\n     */\n    val Role = AccessibilityKey<Role>(\"Role\") { parentValue, _ -> parentValue }\n\n    /** @see SemanticsPropertyReceiver.testTag */\n    val TestTag =\n        SemanticsPropertyKey<String>(\n            name = \"TestTag\",\n            isImportantForAccessibility = false,\n            mergePolicy = { parentValue, _ ->\n                // Never merge TestTags, to avoid leaking internal test tags to parents.\n                parentValue\n            },\n        )\n\n    /**\n     * Marks a link within a text node (a link is represented by a\n     * [androidx.compose.ui.text.LinkAnnotation]) for identification during automated testing. This\n     * property is for internal use only and not intended for general use by developers.\n     */\n    val LinkTestMarker =\n        SemanticsPropertyKey<Unit>(\n            name = \"LinkTestMarker\",\n            isImportantForAccessibility = false,\n            mergePolicy = { parentValue, _ -> parentValue },\n        )\n\n    /** @see SemanticsPropertyReceiver.text */\n    val Text =\n        AccessibilityKey<List<AnnotatedString>>(\n            name = \"Text\",\n            mergePolicy = { parentValue, childValue ->\n                parentValue?.toMutableList()?.also { it.addAll(childValue) } ?: childValue\n            },\n        )\n\n    /** @see SemanticsPropertyReceiver.textSubstitution */\n    val TextSubstitution = SemanticsPropertyKey<AnnotatedString>(name = \"TextSubstitution\")\n\n    /** @see SemanticsPropertyReceiver.isShowingTextSubstitution */\n    val IsShowingTextSubstitution = SemanticsPropertyKey<Boolean>(\"IsShowingTextSubstitution\")\n\n    /** @see SemanticsPropertyReceiver.inputText */\n    val InputText = AccessibilityKey<AnnotatedString>(name = \"InputText\")\n\n    /** @see SemanticsPropertyReceiver.editableText */\n    val EditableText = AccessibilityKey<AnnotatedString>(name = \"EditableText\")\n\n    /** @see SemanticsPropertyReceiver.textSelectionRange */\n    val TextSelectionRange = AccessibilityKey<TextRange>(\"TextSelectionRange\")\n\n    /** @see SemanticsPropertyReceiver.onImeAction */\n    val ImeAction = AccessibilityKey<ImeAction>(\"ImeAction\")\n\n    /** @see SemanticsPropertyReceiver.selected */\n    val Selected = AccessibilityKey<Boolean>(\"Selected\")\n\n    /** @see SemanticsPropertyReceiver.toggleableState */\n    val ToggleableState = AccessibilityKey<ToggleableState>(\"ToggleableState\")\n\n    /** @see SemanticsPropertyReceiver.password */\n    val Password = AccessibilityKey<Unit>(\"Password\")\n\n    /** @see SemanticsPropertyReceiver.error */\n    val Error = AccessibilityKey<String>(\"Error\")\n\n    /** @see SemanticsPropertyReceiver.indexForKey */\n    val IndexForKey = SemanticsPropertyKey<(Any) -> Int>(\"IndexForKey\")\n\n    /** @see SemanticsPropertyReceiver.isEditable */\n    val IsEditable = SemanticsPropertyKey<Boolean>(\"IsEditable\")\n\n    /** @see SemanticsPropertyReceiver.maxTextLength */\n    val MaxTextLength = SemanticsPropertyKey<Int>(\"MaxTextLength\")\n\n    /** @see SemanticsPropertyReceiver.shape */\n    val Shape =\n        SemanticsPropertyKey<Shape>(\n            name = \"Shape\",\n            isImportantForAccessibility = false,\n            mergePolicy = { parentValue, _ ->\n                // Never merge shapes\n                parentValue\n            },\n        )\n}\n\n/**\n * Ths object defines keys of the actions which can be set in semantics and performed on the\n * semantics node.\n *\n * Each of these is intended to be set by the respective SemanticsPropertyReceiver extension instead\n * of used directly.\n */\n/*@VisibleForTesting*/\nobject SemanticsActions {\n    /** @see SemanticsPropertyReceiver.getTextLayoutResult */\n    val GetTextLayoutResult =\n        ActionPropertyKey<(MutableList<TextLayoutResult>) -> Boolean>(\"GetTextLayoutResult\")\n\n    /** @see SemanticsPropertyReceiver.onClick */\n    val OnClick = ActionPropertyKey<() -> Boolean>(\"OnClick\")\n\n    /** @see SemanticsPropertyReceiver.onLongClick */\n    val OnLongClick = ActionPropertyKey<() -> Boolean>(\"OnLongClick\")\n\n    /** @see SemanticsPropertyReceiver.scrollBy */\n    val ScrollBy = ActionPropertyKey<(x: Float, y: Float) -> Boolean>(\"ScrollBy\")\n\n    /** @see SemanticsPropertyReceiver.scrollByOffset */\n    val ScrollByOffset = SemanticsPropertyKey<suspend (offset: Offset) -> Offset>(\"ScrollByOffset\")\n\n    /** @see SemanticsPropertyReceiver.scrollToIndex */\n    val ScrollToIndex = ActionPropertyKey<(Int) -> Boolean>(\"ScrollToIndex\")\n\n    @Suppress(\"unused\")\n    @Deprecated(\n        message = \"Use `SemanticsActions.OnFillData` instead.\",\n        replaceWith =\n            ReplaceWith(\"OnFillData\", \"androidx.compose.ui.semantics.SemanticsActions.OnFillData\"),\n        level = DeprecationLevel.WARNING,\n    )\n    val OnAutofillText = ActionPropertyKey<(AnnotatedString) -> Boolean>(\"OnAutofillText\")\n\n    /** @see SemanticsPropertyReceiver.onFillData */\n    val OnFillData = ActionPropertyKey<(FillableData) -> Boolean>(\"OnFillData\")\n\n    /** @see SemanticsPropertyReceiver.setProgress */\n    val SetProgress = ActionPropertyKey<(progress: Float) -> Boolean>(\"SetProgress\")\n\n    /** @see SemanticsPropertyReceiver.setSelection */\n    val SetSelection = ActionPropertyKey<(Int, Int, Boolean) -> Boolean>(\"SetSelection\")\n\n    /** @see SemanticsPropertyReceiver.setText */\n    val SetText = ActionPropertyKey<(AnnotatedString) -> Boolean>(\"SetText\")\n\n    /** @see SemanticsPropertyReceiver.setTextSubstitution */\n    val SetTextSubstitution = ActionPropertyKey<(AnnotatedString) -> Boolean>(\"SetTextSubstitution\")\n\n    /** @see SemanticsPropertyReceiver.showTextSubstitution */\n    val ShowTextSubstitution = ActionPropertyKey<(Boolean) -> Boolean>(\"ShowTextSubstitution\")\n\n    /** @see SemanticsPropertyReceiver.clearTextSubstitution */\n    val ClearTextSubstitution = ActionPropertyKey<() -> Boolean>(\"ClearTextSubstitution\")\n\n    /** @see SemanticsPropertyReceiver.insertTextAtCursor */\n    val InsertTextAtCursor = ActionPropertyKey<(AnnotatedString) -> Boolean>(\"InsertTextAtCursor\")\n\n    /** @see SemanticsPropertyReceiver.onImeAction */\n    val OnImeAction = ActionPropertyKey<() -> Boolean>(\"PerformImeAction\")\n\n    // b/322269946\n    @Suppress(\"unused\")\n    @Deprecated(\n        message = \"Use `SemanticsActions.OnImeAction` instead.\",\n        replaceWith =\n            ReplaceWith(\n                \"OnImeAction\",\n                \"androidx.compose.ui.semantics.SemanticsActions.OnImeAction\",\n            ),\n        level = DeprecationLevel.ERROR,\n    )\n    val PerformImeAction = ActionPropertyKey<() -> Boolean>(\"PerformImeAction\")\n\n    /** @see SemanticsPropertyReceiver.copyText */\n    val CopyText = ActionPropertyKey<() -> Boolean>(\"CopyText\")\n\n    /** @see SemanticsPropertyReceiver.cutText */\n    val CutText = ActionPropertyKey<() -> Boolean>(\"CutText\")\n\n    /** @see SemanticsPropertyReceiver.pasteText */\n    val PasteText = ActionPropertyKey<() -> Boolean>(\"PasteText\")\n\n    /** @see SemanticsPropertyReceiver.expand */\n    val Expand = ActionPropertyKey<() -> Boolean>(\"Expand\")\n\n    /** @see SemanticsPropertyReceiver.collapse */\n    val Collapse = ActionPropertyKey<() -> Boolean>(\"Collapse\")\n\n    /** @see SemanticsPropertyReceiver.dismiss */\n    val Dismiss = ActionPropertyKey<() -> Boolean>(\"Dismiss\")\n\n    /** @see SemanticsPropertyReceiver.requestFocus */\n    val RequestFocus = ActionPropertyKey<() -> Boolean>(\"RequestFocus\")\n\n    /** @see SemanticsPropertyReceiver.customActions */\n    val CustomActions =\n        AccessibilityKey<List<CustomAccessibilityAction>>(\n            name = \"CustomActions\",\n            mergePolicy = { parentValue, childValue -> parentValue.orEmpty() + childValue },\n        )\n\n    /** @see SemanticsPropertyReceiver.pageUp */\n    val PageUp = ActionPropertyKey<() -> Boolean>(\"PageUp\")\n\n    /** @see SemanticsPropertyReceiver.pageLeft */\n    val PageLeft = ActionPropertyKey<() -> Boolean>(\"PageLeft\")\n\n    /** @see SemanticsPropertyReceiver.pageDown */\n    val PageDown = ActionPropertyKey<() -> Boolean>(\"PageDown\")\n\n    /** @see SemanticsPropertyReceiver.pageRight */\n    val PageRight = ActionPropertyKey<() -> Boolean>(\"PageRight\")\n\n    /** @see SemanticsPropertyReceiver.getScrollViewportLength */\n    val GetScrollViewportLength =\n        ActionPropertyKey<(MutableList<Float>) -> Boolean>(\"GetScrollViewportLength\")\n}\n\n/**\n * SemanticsPropertyKey is the infrastructure for setting key/value pairs inside semantics blocks in\n * a type-safe way. Each key has one particular statically defined value type T.\n */\nclass SemanticsPropertyKey<T>(\n    /** The name of the property. Should be the same as the constant from which it is accessed. */\n    val name: String,\n    internal val mergePolicy: (T?, T) -> T? = { parentValue, childValue ->\n        parentValue ?: childValue\n    },\n) {\n    /**\n     * Whether this type of property provides information relevant to accessibility services.\n     *\n     * Most built-in semantics properties are relevant to accessibility, but a very common exception\n     * is testTag. Nodes with only a testTag still need to be included in the AccessibilityNodeInfo\n     * tree because UIAutomator tests rely on that, but we mark them `isImportantForAccessibility =\n     * false` on the AccessibilityNodeInfo to inform accessibility services that they are best\n     * ignored.\n     *\n     * The default value is false and it is not exposed as a public API. That's because it is\n     * impossible in the first place for `SemanticsPropertyKey`s defined outside the UI package to\n     * be relevant to accessibility, because for each accessibility-relevant SemanticsProperty type\n     * to get plumbed into the AccessibilityNodeInfo, the private `createNodeInfo` implementation\n     * must also have a line of code.\n     */\n    internal var isImportantForAccessibility = false\n        private set\n\n    /**\n     * If this value is non-null, this semantics property will be exposed as an accessibility extra\n     * via AccessibilityNodeInfo.getExtras with this value used as the key for the extra.\n     */\n    internal var accessibilityExtraKey: String? = null\n\n    internal constructor(name: String, isImportantForAccessibility: Boolean) : this(name) {\n        this.isImportantForAccessibility = isImportantForAccessibility\n    }\n\n    internal constructor(\n        name: String,\n        isImportantForAccessibility: Boolean,\n        mergePolicy: (T?, T) -> T?,\n        accessibilityExtraKey: String? = null,\n    ) : this(name, mergePolicy) {\n        this.isImportantForAccessibility = isImportantForAccessibility\n        this.accessibilityExtraKey = accessibilityExtraKey\n    }\n\n    /**\n     * Method implementing the semantics merge policy of a particular key.\n     *\n     * When mergeDescendants is set on a semantics node, then this function will called for each\n     * descendant node of a given key in depth-first-search order. The parent value accumulates the\n     * result of merging the values seen so far, similar to reduce().\n     *\n     * The default implementation returns the parent value if one exists, otherwise uses the child\n     * element. This means by default, a SemanticsNode with mergeDescendants = true winds up with\n     * the first value found for each key in its subtree in depth-first-search order.\n     */\n    fun merge(parentValue: T?, childValue: T): T? {\n        return mergePolicy(parentValue, childValue)\n    }\n\n    /** Throws [UnsupportedOperationException]. Should not be called. */\n    // TODO(KT-6519): Remove this getter\n    // TODO(KT-32770): Cannot deprecate this either as the getter is considered called by \"by\"\n    final operator fun getValue(thisRef: SemanticsPropertyReceiver, property: KProperty<*>): T {\n        return throwSemanticsGetNotSupported()\n    }\n\n    final operator fun setValue(\n        thisRef: SemanticsPropertyReceiver,\n        property: KProperty<*>,\n        value: T,\n    ) {\n        thisRef[this] = value\n    }\n\n    override fun toString(): String {\n        return \"AccessibilityKey: $name\"\n    }\n}\n\nprivate fun <T> throwSemanticsGetNotSupported(): T {\n    throw UnsupportedOperationException(\n        \"You cannot retrieve a semantics property directly - \" +\n            \"use one of the SemanticsConfiguration.getOr* methods instead\"\n    )\n}\n\n@Suppress(\"NOTHING_TO_INLINE\")\n// inline to avoid different static initialization order on different targets.\n// See https://youtrack.jetbrains.com/issue/KT-65040 for more information.\ninternal inline fun <T> AccessibilityKey(name: String) =\n    SemanticsPropertyKey<T>(name = name, isImportantForAccessibility = true)\n\n@Suppress(\"NOTHING_TO_INLINE\")\n// inline to avoid different static initialization order on different targets\n// See https://youtrack.jetbrains.com/issue/KT-65040 for more information.\ninternal inline fun <T> AccessibilityKey(name: String, noinline mergePolicy: (T?, T) -> T?) =\n    SemanticsPropertyKey(name = name, isImportantForAccessibility = true, mergePolicy = mergePolicy)\n\n/**\n * Standard accessibility action.\n *\n * @param label The description of this action\n * @param action The function to invoke when this action is performed. The function should return a\n *   boolean result indicating whether the action is successfully handled. For example, a scroll\n *   forward action should return false if the widget is not enabled or has reached the end of the\n *   list. If multiple semantics blocks with the same AccessibilityAction are provided, the\n *   resulting AccessibilityAction's label/action will be the label/action of the outermost modifier\n *   with this key and nonnull label/action, or null if no nonnull label/action is found.\n */\nclass AccessibilityAction<T : Function<Boolean>>(val label: String?, val action: T?) {\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is AccessibilityAction<*>) return false\n\n        if (label != other.label) return false\n        if (action != other.action) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = label?.hashCode() ?: 0\n        result = 31 * result + action.hashCode()\n        return result\n    }\n\n    override fun toString(): String {\n        return \"AccessibilityAction(label=$label, action=$action)\"\n    }\n}\n\n@Suppress(\"NOTHING_TO_INLINE\")\n// inline to break static initialization cycle issue\nprivate inline fun <T : Function<Boolean>> ActionPropertyKey(name: String) =\n    AccessibilityKey<AccessibilityAction<T>>(\n        name = name,\n        mergePolicy = { parentValue, childValue ->\n            AccessibilityAction(\n                parentValue?.label ?: childValue.label,\n                parentValue?.action ?: childValue.action,\n            )\n        },\n    )\n\n/**\n * Custom accessibility action.\n *\n * @param label The description of this action\n * @param action The function to invoke when this action is performed. The function should have no\n *   arguments and return a boolean result indicating whether the action is successfully handled.\n */\nclass CustomAccessibilityAction(val label: String, val action: () -> Boolean) {\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is CustomAccessibilityAction) return false\n\n        if (label != other.label) return false\n        if (action !== other.action) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = label.hashCode()\n        result = 31 * result + action.hashCode()\n        return result\n    }\n\n    override fun toString(): String {\n        return \"CustomAccessibilityAction(label=$label, action=$action)\"\n    }\n}\n\n/**\n * Accessibility range information, to represent the status of a progress bar or seekable progress\n * bar.\n *\n * @param current current value in the range. Must not be NaN.\n * @param range range of this node\n * @param steps if greater than `0`, specifies the number of discrete values, evenly distributed\n *   between across the whole value range. If `0`, any value from the range specified can be chosen.\n *   Cannot be less than `0`.\n */\nclass ProgressBarRangeInfo(\n    val current: Float,\n    val range: ClosedFloatingPointRange<Float>,\n    /*@IntRange(from = 0)*/\n    val steps: Int = 0,\n) {\n    init {\n        require(!current.isNaN()) { \"current must not be NaN\" }\n    }\n\n    companion object {\n        /** Accessibility range information to present indeterminate progress bar */\n        val Indeterminate = ProgressBarRangeInfo(0f, 0f..0f)\n    }\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is ProgressBarRangeInfo) return false\n\n        if (current != other.current) return false\n        if (range != other.range) return false\n        if (steps != other.steps) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = current.hashCode()\n        result = 31 * result + range.hashCode()\n        result = 31 * result + steps\n        return result\n    }\n\n    override fun toString(): String {\n        return \"ProgressBarRangeInfo(current=$current, range=$range, steps=$steps)\"\n    }\n}\n\n/**\n * Information about the collection.\n *\n * A collection of items has [rowCount] rows and [columnCount] columns. For example, a vertical list\n * is a collection with one column, as many rows as the list items that are important for\n * accessibility; A table is a collection with several rows and several columns.\n *\n * @param rowCount the number of rows in the collection, or -1 if unknown\n * @param columnCount the number of columns in the collection, or -1 if unknown\n */\nclass CollectionInfo(val rowCount: Int, val columnCount: Int) {\n\n    override fun equals(other: Any?): Boolean {\n        if (this === other) return true\n        if (other !is CollectionInfo) return false\n\n        if (rowCount != other.rowCount) return false\n        if (columnCount != other.columnCount) return false\n\n        return true\n    }\n\n    override fun hashCode(): Int {\n        var result = rowCount.hashCode()\n        result = 31 * result + columnCount.hashCode()\n        return result\n    }\n\n    override fun toString(): String {\n        return \"CollectionInfo(rowCount=$rowCount, columnCount=$columnCount)\"\n    }\n}\n\n/**\n * Information about the item of a collection.\n *\n * A collection item is contained in a collection, it starts at a given [rowIndex] and [columnIndex]\n * in the collection, and spans one or more rows and columns. For example, a header of two related\n * table columns starts at the first row and the first column, spans one row and two columns.\n *\n * @param rowIndex the index of the row at which item is located\n * @param rowSpan the number of rows the item spans\n * @param columnIndex the index of the column at which item is located\n * @param columnSpan the number of columns the item spans\n */\nclass CollectionItemInfo(\n    val rowIndex: Int,\n    val rowSpan: Int,\n    val columnIndex: Int,\n    val columnSpan: Int,\n)\n\n/**\n * The scroll state of one axis if this node is scrollable.\n *\n * @param value current 0-based scroll position value (either in pixels, or lazy-item count)\n * @param maxValue maximum bound for [value], or [Float.POSITIVE_INFINITY] if still unknown\n * @param reverseScrolling for horizontal scroll, when this is `true`, 0 [value] will mean right,\n *   when`false`, 0 [value] will mean left. For vertical scroll, when this is `true`, 0 [value] will\n *   mean bottom, when `false`, 0 [value] will mean top\n */\nclass ScrollAxisRange(\n    val value: () -> Float,\n    val maxValue: () -> Float,\n    val reverseScrolling: Boolean = false,\n) {\n    override fun toString(): String =\n        \"ScrollAxisRange(value=${value()}, maxValue=${maxValue()}, \" +\n            \"reverseScrolling=$reverseScrolling)\"\n}\n\n/**\n * The type of user interface element. Accessibility services might use this to describe the element\n * or do customizations. Most roles can be automatically resolved by the semantics properties of\n * this element. But some elements with subtle differences need an exact role. If an exact role is\n * not listed, [SemanticsPropertyReceiver.role] should not be set and the framework will\n * automatically resolve it.\n */\n@Immutable\n@kotlin.jvm.JvmInline\nvalue class Role private constructor(@Suppress(\"unused\") private val value: Int) {\n    companion object {\n        /**\n         * This element is a button control. Associated semantics properties for accessibility:\n         * [SemanticsProperties.Disabled], [SemanticsActions.OnClick]\n         */\n        val Button = Role(0)\n\n        /**\n         * This element is a Checkbox which is a component that represents two states (checked /\n         * unchecked). Associated semantics properties for accessibility:\n         * [SemanticsProperties.Disabled], [SemanticsProperties.StateDescription],\n         * [SemanticsActions.OnClick]\n         */\n        val Checkbox = Role(1)\n\n        /**\n         * This element is a Switch which is a two state toggleable component that provides on/off\n         * like options. Associated semantics properties for accessibility:\n         * [SemanticsProperties.Disabled], [SemanticsProperties.StateDescription],\n         * [SemanticsActions.OnClick]\n         */\n        val Switch = Role(2)\n\n        /**\n         * This element is a RadioButton which is a component to represent two states, selected and\n         * not selected. Associated semantics properties for accessibility:\n         * [SemanticsProperties.Disabled], [SemanticsProperties.StateDescription],\n         * [SemanticsActions.OnClick]\n         */\n        val RadioButton = Role(3)\n\n        /**\n         * This element is a Tab which represents a single page of content using a text label and/or\n         * icon. A Tab also has two states: selected and not selected. Associated semantics\n         * properties for accessibility: [SemanticsProperties.Disabled],\n         * [SemanticsProperties.StateDescription], [SemanticsActions.OnClick]\n         */\n        val Tab = Role(4)\n\n        /**\n         * This element is an image. Associated semantics properties for accessibility:\n         * [SemanticsProperties.ContentDescription]\n         */\n        val Image = Role(5)\n\n        /**\n         * This element is associated with a drop down menu. Associated semantics properties for\n         * accessibility: [SemanticsActions.OnClick]\n         */\n        val DropdownList = Role(6)\n\n        /**\n         * This element is a value picker. It should support the following accessibility actions to\n         * enable selection of the next and previous values:\n         *\n         * [android.view.accessibility.AccessibilityNodeInfo.ACTION_SCROLL_FORWARD]: Select the next\n         * value.\n         *\n         * [android.view.accessibility.AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD]: Select the\n         * previous value.\n         *\n         * These actions allow accessibility services to interact with this node programmatically on\n         * behalf of users, facilitating navigation within sets of selectable values.\n         */\n        val ValuePicker = Role(7)\n\n        /**\n         * This element is a Carousel. This means that even if Pager actions are added, this element\n         * will behave like a regular List collection.\n         *\n         * Associated semantics properties for Pager accessibility actions:\n         * [SemanticsActions.PageUp],[SemanticsActions.PageDown],[SemanticsActions.PageLeft],\n         * [SemanticsActions.PageRight]\n         */\n        val Carousel = Role(8)\n    }\n\n    override fun toString() =\n        when (this) {\n            Button -> \"Button\"\n            Checkbox -> \"Checkbox\"\n            Switch -> \"Switch\"\n            RadioButton -> \"RadioButton\"\n            Tab -> \"Tab\"\n            Image -> \"Image\"\n            DropdownList -> \"DropdownList\"\n            ValuePicker -> \"Picker\"\n            Carousel -> \"Carousel\"\n            else -> \"Unknown\"\n        }\n}\n\n/**\n * The mode of live region. Live region indicates to accessibility services they should\n * automatically notify the user about changes to the node's content description or text, or to the\n * content descriptions or text of the node's children (where applicable).\n */\n@Immutable\n@kotlin.jvm.JvmInline\nvalue class LiveRegionMode private constructor(@Suppress(\"unused\") private val value: Int) {\n    companion object {\n        /**\n         * Live region mode specifying that accessibility services should announce changes to this\n         * node.\n         */\n        val Polite = LiveRegionMode(0)\n\n        /**\n         * Live region mode specifying that accessibility services should interrupt ongoing speech\n         * to immediately announce changes to this node.\n         */\n        val Assertive = LiveRegionMode(1)\n    }\n\n    override fun toString() =\n        when (this) {\n            Polite -> \"Polite\"\n            Assertive -> \"Assertive\"\n            else -> \"Unknown\"\n        }\n}\n\n/**\n * SemanticsPropertyReceiver is the scope provided by semantics {} blocks, letting you set key/value\n * pairs primarily via extension functions.\n */\ninterface SemanticsPropertyReceiver {\n    operator fun <T> set(key: SemanticsPropertyKey<T>, value: T)\n}\n\n/**\n * Developer-set content description of the semantics node.\n *\n * If this is not set, accessibility services will present the [text][SemanticsProperties.Text] of\n * this node as the content.\n *\n * This typically should not be set directly by applications, because some screen readers will cease\n * presenting other relevant information when this property is present. This is intended to be used\n * via Foundation components which are inherently intractable to automatically describe, such as\n * Image, Icon, and Canvas.\n */\nvar SemanticsPropertyReceiver.contentDescription: String\n    get() = throwSemanticsGetNotSupported()\n    set(value) {\n        set(SemanticsProperties.ContentDescription, listOf(value))\n    }\n\n/**\n * Developer-set state description of the semantics node.\n *\n * For example: on/off. If this not set, accessibility services will derive the state from other\n * semantics properties, like [ProgressBarRangeInfo], but it is not guaranteed and the format will\n * be decided by accessibility services.\n */\nvar SemanticsPropertyReceiver.stateDescription by SemanticsProperties.StateDescription\n\n/**\n * The semantics represents a range of possible values with a current value. For example, when used\n * on a slider control, this will allow screen readers to communicate the slider's state.\n */\nvar SemanticsPropertyReceiver.progressBarRangeInfo by SemanticsProperties.ProgressBarRangeInfo\n\n/**\n * The node is marked as heading for accessibility.\n *\n * @see SemanticsProperties.Heading\n */\nfun SemanticsPropertyReceiver.heading() {\n    this[SemanticsProperties.Heading] = Unit\n}\n\n/**\n * The node is marked as a text entry key for accessibility. This is used to indicate that this\n * composable acts as a key within a text entry interface, such as a custom on-screen keyboard.\n * Accessibility services can use this information to provide a better experience for users\n * interacting with custom text input methods.\n *\n * See\n * [AccessibilityNodeInfo.setTextEntryKey](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo#setTextEntryKey(boolean))\n * for more details.\n *\n * @see SemanticsProperties.TextEntryKey\n */\nfun SemanticsPropertyReceiver.textEntryKey() {\n    this[SemanticsProperties.TextEntryKey] = Unit\n}\n\n/**\n * Accessibility-friendly title for a screen's pane. For accessibility purposes, a pane is a\n * visually distinct portion of a window, such as the contents of a open drawer. In order for\n * accessibility services to understand a pane's window-like behavior, you should give descriptive\n * titles to your app's panes. Accessibility services can then provide more granular information to\n * users when a pane's appearance or content changes.\n *\n * @see SemanticsProperties.PaneTitle\n */\nvar SemanticsPropertyReceiver.paneTitle by SemanticsProperties.PaneTitle\n\n/**\n * Whether this semantics node is disabled. Note that proper [SemanticsActions] should still be\n * added when this property is set.\n *\n * @see SemanticsProperties.Disabled\n */\nfun SemanticsPropertyReceiver.disabled() {\n    this[SemanticsProperties.Disabled] = Unit\n}\n\n/**\n * This node is marked as live region for accessibility. This indicates to accessibility services\n * they should automatically notify the user about changes to the node's content description or\n * text, or to the content descriptions or text of the node's children (where applicable). It should\n * be used with caution, especially with assertive mode which immediately stops the current audio\n * and the user does not hear the rest of the content. An example of proper use is a Snackbar which\n * is marked as [LiveRegionMode.Polite].\n *\n * @see SemanticsProperties.LiveRegion\n * @see LiveRegionMode\n */\nvar SemanticsPropertyReceiver.liveRegion by SemanticsProperties.LiveRegion\n\n/**\n * Whether this semantics node is focused. The presence of this property indicates this node is\n * focusable\n *\n * @see SemanticsProperties.Focused\n */\nvar SemanticsPropertyReceiver.focused by SemanticsProperties.Focused\n\n/**\n * Whether this semantics node is a container. This is defined as a node whose function is to serve\n * as a boundary or border in organizing its children.\n *\n * @see SemanticsProperties.IsContainer\n */\n@Deprecated(\"Use `isTraversalGroup` instead.\", replaceWith = ReplaceWith(\"isTraversalGroup\"))\n@Suppress(\"DEPRECATION\")\nvar SemanticsPropertyReceiver.isContainer by SemanticsProperties.IsContainer\n\n/**\n * Whether this semantics node is a traversal group.\n *\n * See https://developer.android.com/develop/ui/compose/accessibility/traversal\n *\n * @see SemanticsProperties.IsTraversalGroup\n */\nvar SemanticsPropertyReceiver.isTraversalGroup by SemanticsProperties.IsTraversalGroup\n\n/**\n * Whether this semantics node should only allow interactions from\n * [android.accessibilityservice.AccessibilityService]s with the\n * [android.accessibilityservice.AccessibilityServiceInfo.isAccessibilityTool] property set to true.\n *\n * This property allows the node to remain visible and interactive to Accessibility Services\n * declared as accessibility tools that assist users with disabilities, while simultaneously hiding\n * this node and its generated AccessibilityEvents from other Accessibility Services that are not\n * declared as accessibility tools.\n *\n * If looking for a way to hide the node from all Accessibility Services then consider\n * [SemanticsProperties.HideFromAccessibility] instead.\n *\n * @see SemanticsProperties.IsSensitiveData\n */\nvar SemanticsPropertyReceiver.isSensitiveData by SemanticsProperties.IsSensitiveData\n\n/**\n * Whether this node is specially known to be invisible to the user.\n *\n * For example, if the node is currently occluded by a dark semitransparent pane above it, then for\n * all practical purposes the node is invisible to the user, but the system cannot automatically\n * determine that. To make the screen reader linear navigation skip over this type of invisible\n * node, this property can be set.\n *\n * If looking for a way to hide semantics of small items from screen readers because they're\n * redundant with semantics of their parent, consider [SemanticsModifier.clearAndSetSemantics]\n * instead.\n */\n@Deprecated(\n    \"Use `hideFromAccessibility()` instead.\",\n    replaceWith = ReplaceWith(\"hideFromAccessibility()\"),\n)\n@Suppress(\"DEPRECATION\")\n// Retain for binary compatibility with aosp/3341487 in 1.7\nfun SemanticsPropertyReceiver.invisibleToUser() {\n    this[SemanticsProperties.InvisibleToUser] = Unit\n}\n\n/**\n * If present, this node is considered hidden from accessibility services.\n *\n * For example, if the node is currently occluded by a dark semitransparent pane above it, then for\n * all practical purposes the node should not be announced to the user. Since the system cannot\n * automatically determine that, this property can be set to make the screen reader linear\n * navigation skip over this type of node.\n *\n * If looking for a way to clear semantics of small items from the UI tree completely because they\n * are redundant with semantics of their parent, consider [SemanticsModifier.clearAndSetSemantics]\n * instead.\n */\nfun SemanticsPropertyReceiver.hideFromAccessibility() {\n    this[SemanticsProperties.HideFromAccessibility] = Unit\n}\n\n/**\n * Content field type information.\n *\n * This API can be used to indicate to Autofill services what _kind of field_ is associated with\n * this node. Not to be confused with the _data type_ to be entered into the field.\n *\n * @see SemanticsProperties.ContentType\n */\nvar SemanticsPropertyReceiver.contentType by SemanticsProperties.ContentType\n\n/**\n * Content data type information.\n *\n * This API can be used to indicate to Autofill services what _kind of data_ is meant to be\n * suggested for this field. Not to be confused with the _type_ of the field.\n *\n * @see SemanticsProperties.ContentType\n */\nvar SemanticsPropertyReceiver.contentDataType by SemanticsProperties.ContentDataType\n\n/**\n * The current value of a component that can be autofilled.\n *\n * This property is used to expose the component's current data *to* the autofill service. The\n * service can then read this value, for example, to save it for future autofill suggestions.\n *\n * This is the counterpart to the [onFillData] action, which is used to *receive* data from the\n * autofill service.\n *\n * @sample androidx.compose.ui.samples.AutofillableTextFieldWithFillableDataSemantics\n * @see SemanticsProperties.FillableData\n */\nvar SemanticsPropertyReceiver.fillableData by SemanticsProperties.FillableData\n\n/**\n * A value to manually control screenreader traversal order.\n *\n * This API can be used to customize TalkBack traversal order. When the `traversalIndex` property is\n * set on a traversalGroup or on a screenreader-focusable node, then the sorting algorithm will\n * prioritize nodes with smaller `traversalIndex`s earlier. The default traversalIndex value is\n * zero, and traversalIndices are compared at a peer level.\n *\n * For example,` traversalIndex = -1f` can be used to force a top bar to be ordered earlier, and\n * `traversalIndex = 1f` to make a bottom bar ordered last, in the edge cases where this does not\n * happen by default. As another example, if you need to reorder two Buttons within a Row, then you\n * can set `isTraversalGroup = true` on the Row, and set `traversalIndex` on one of the Buttons.\n *\n * Note that if `traversalIndex` seems to have no effect, be sure to set `isTraversalGroup = true`\n * as well.\n */\nvar SemanticsPropertyReceiver.traversalIndex by SemanticsProperties.TraversalIndex\n\n/** The horizontal scroll state of this node if this node is scrollable. */\nvar SemanticsPropertyReceiver.horizontalScrollAxisRange by\n    SemanticsProperties.HorizontalScrollAxisRange\n\n/** The vertical scroll state of this node if this node is scrollable. */\nvar SemanticsPropertyReceiver.verticalScrollAxisRange by SemanticsProperties.VerticalScrollAxisRange\n\n/**\n * Whether this semantics node represents a Popup. Not to be confused with if this node is _part of_\n * a Popup.\n */\nfun SemanticsPropertyReceiver.popup() {\n    this[SemanticsProperties.IsPopup] = Unit\n}\n\n/**\n * Whether this element is a Dialog. Not to be confused with if this element is _part of_ a Dialog.\n */\nfun SemanticsPropertyReceiver.dialog() {\n    this[SemanticsProperties.IsDialog] = Unit\n}\n\n/**\n * The type of user interface element. Accessibility services might use this to describe the element\n * or do customizations. Most roles can be automatically resolved by the semantics properties of\n * this element. But some elements with subtle differences need an exact role. If an exact role is\n * not listed in [Role], this property should not be set and the framework will automatically\n * resolve it.\n */\nvar SemanticsPropertyReceiver.role by SemanticsProperties.Role\n\n/**\n * Test tag attached to this semantics node.\n *\n * This can be used to find nodes in testing frameworks:\n * - In Compose's built-in unit test framework, use with\n *   [onNodeWithTag][androidx.compose.ui.test.onNodeWithTag].\n * - For newer AccessibilityNodeInfo-based integration test frameworks, it can be matched in the\n *   extras with key \"androidx.compose.ui.semantics.testTag\"\n * - For legacy AccessibilityNodeInfo-based integration tests, it's optionally exposed as the\n *   resource id if [testTagsAsResourceId] is true (for matching with 'By.res' in UIAutomator).\n */\nvar SemanticsPropertyReceiver.testTag by SemanticsProperties.TestTag\n\n/**\n * Text of the semantics node. It must be real text instead of developer-set content description.\n *\n * @see SemanticsPropertyReceiver.editableText\n */\nvar SemanticsPropertyReceiver.text: AnnotatedString\n    get() = throwSemanticsGetNotSupported()\n    set(value) {\n        set(SemanticsProperties.Text, listOf(value))\n    }\n\n/**\n * Text substitution of the semantics node. This property is only available after calling\n * [SemanticsActions.SetTextSubstitution].\n */\nvar SemanticsPropertyReceiver.textSubstitution by SemanticsProperties.TextSubstitution\n\n/**\n * Whether this element is showing the text substitution. This property is only available after\n * calling [SemanticsActions.SetTextSubstitution].\n */\nvar SemanticsPropertyReceiver.isShowingTextSubstitution by\n    SemanticsProperties.IsShowingTextSubstitution\n\n/**\n * The raw value of the text field after input transformations have been applied.\n *\n * This is an actual user input of the fields, e.g. a real password, after any input transformations\n * that might change or reject that input have been applied. This value is not affected by visual\n * transformations.\n */\nvar SemanticsPropertyReceiver.inputText by SemanticsProperties.InputText\n\n/**\n * A visual value of the text field after output transformations that change the visual\n * representation of the field's state have been applied.\n *\n * This is the value displayed to the user, for example \"*******\" in a password field.\n */\nvar SemanticsPropertyReceiver.editableText by SemanticsProperties.EditableText\n\n/** Text selection range for the text field. */\nvar SemanticsPropertyReceiver.textSelectionRange by SemanticsProperties.TextSelectionRange\n\n/**\n * Contains the IME action provided by the node.\n *\n * For example, \"go to next form field\" or \"submit\".\n *\n * A node that specifies an action should also specify a callback to perform the action via\n * [onImeAction].\n */\n@Deprecated(\"Pass the ImeAction to onImeAction instead.\")\n@get:Deprecated(\"Pass the ImeAction to onImeAction instead.\")\n@set:Deprecated(\"Pass the ImeAction to onImeAction instead.\")\nvar SemanticsPropertyReceiver.imeAction by SemanticsProperties.ImeAction\n\n/**\n * Whether this element is selected (out of a list of possible selections).\n *\n * The presence of this property indicates that the element is selectable.\n */\nvar SemanticsPropertyReceiver.selected by SemanticsProperties.Selected\n\n/**\n * This semantics marks node as a collection and provides the required information.\n *\n * @see collectionItemInfo\n */\nvar SemanticsPropertyReceiver.collectionInfo by SemanticsProperties.CollectionInfo\n\n/**\n * This semantics marks node as an items of a collection and provides the required information.\n *\n * If you mark items of a collection, you should also be marking the collection with\n * [collectionInfo].\n */\nvar SemanticsPropertyReceiver.collectionItemInfo by SemanticsProperties.CollectionItemInfo\n\n/**\n * The state of a toggleable component.\n *\n * The presence of this property indicates that the element is toggleable.\n */\nvar SemanticsPropertyReceiver.toggleableState by SemanticsProperties.ToggleableState\n\n/** Whether this semantics node is editable, e.g. an editable text field. */\nvar SemanticsPropertyReceiver.isEditable by SemanticsProperties.IsEditable\n\n/** The node is marked as a password. */\nfun SemanticsPropertyReceiver.password() {\n    this[SemanticsProperties.Password] = Unit\n}\n\n/**\n * Mark semantics node that contains invalid input or error.\n *\n * @param [description] a localized description explaining an error to the accessibility user\n */\nfun SemanticsPropertyReceiver.error(description: String) {\n    this[SemanticsProperties.Error] = description\n}\n\n/**\n * The index of an item identified by a given key. The key is usually defined during the creation of\n * the container. If the key did not match any of the items' keys, the [mapping] must return -1.\n */\nfun SemanticsPropertyReceiver.indexForKey(mapping: (Any) -> Int) {\n    this[SemanticsProperties.IndexForKey] = mapping\n}\n\n/**\n * Limits the number of characters that can be entered, e.g. in an editable text field. By default\n * this value is -1, signifying there is no maximum text length limit.\n */\nvar SemanticsPropertyReceiver.maxTextLength by SemanticsProperties.MaxTextLength\n\n/** The shape of the UI element. */\nvar SemanticsPropertyReceiver.shape by SemanticsProperties.Shape\n\n/**\n * The node is marked as a collection of horizontally or vertically stacked selectable elements.\n *\n * Unlike [collectionInfo] which marks a collection of any elements and asks developer to provide\n * all the required information like number of elements etc., this semantics will populate the\n * number of selectable elements automatically. Note that if you use this semantics with lazy\n * collections, it won't get the number of elements in the collection.\n *\n * @see SemanticsPropertyReceiver.selected\n */\nfun SemanticsPropertyReceiver.selectableGroup() {\n    this[SemanticsProperties.SelectableGroup] = Unit\n}\n\n/** Custom actions which are defined by app developers. */\nvar SemanticsPropertyReceiver.customActions by SemanticsActions.CustomActions\n\n/**\n * Action to get a Text/TextField node's [TextLayoutResult]. The result is the first element of\n * layout (the argument of the AccessibilityAction).\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.GetTextLayoutResult] is called.\n */\nfun SemanticsPropertyReceiver.getTextLayoutResult(\n    label: String? = null,\n    action: ((MutableList<TextLayoutResult>) -> Boolean)?,\n) {\n    this[SemanticsActions.GetTextLayoutResult] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to be performed when the node is clicked (single-tapped).\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.OnClick] is called.\n */\nfun SemanticsPropertyReceiver.onClick(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.OnClick] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to be performed when the node is long clicked (long-pressed).\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.OnLongClick] is called.\n */\nfun SemanticsPropertyReceiver.onLongClick(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.OnLongClick] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to asynchronously scroll by a specified amount.\n *\n * [scrollByOffset] should be preferred in most cases, since it is synchronous and returns the\n * amount of scroll that was actually consumed.\n *\n * Expected to be used in conjunction with [verticalScrollAxisRange]/[horizontalScrollAxisRange].\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when [SemanticsActions.ScrollBy] is called.\n */\nfun SemanticsPropertyReceiver.scrollBy(\n    label: String? = null,\n    action: ((x: Float, y: Float) -> Boolean)?,\n) {\n    this[SemanticsActions.ScrollBy] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to scroll by a specified amount and return how much of the offset was actually consumed.\n * E.g. if the node can't scroll at all in the given direction, [Offset.Zero] should be returned.\n * The action should not return until the scroll operation has finished.\n *\n * Expected to be used in conjunction with [verticalScrollAxisRange]/[horizontalScrollAxisRange].\n *\n * Unlike [scrollBy], this action is synchronous, and returns the amount of scroll consumed.\n *\n * @param action Action to be performed when [SemanticsActions.ScrollByOffset] is called.\n */\nfun SemanticsPropertyReceiver.scrollByOffset(action: suspend (offset: Offset) -> Offset) {\n    this[SemanticsActions.ScrollByOffset] = action\n}\n\n/**\n * Action to scroll a container to the index of one of its items.\n *\n * The [action] should throw an [IllegalArgumentException] if the index is out of bounds.\n */\nfun SemanticsPropertyReceiver.scrollToIndex(label: String? = null, action: (Int) -> Boolean) {\n    this[SemanticsActions.ScrollToIndex] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to autofill a TextField.\n *\n * Expected to be used in conjunction with [contentType] and [contentDataType] properties.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.OnAutofillText] is called.\n */\n@Deprecated(\n    message = \"Use onFillData instead\",\n    replaceWith = ReplaceWith(\"onFillData\"),\n    level = DeprecationLevel.WARNING,\n)\nfun SemanticsPropertyReceiver.onAutofillText(\n    label: String? = null,\n    action: ((AnnotatedString) -> Boolean)?,\n) {\n    @Suppress(\"DEPRECATION\")\n    this[SemanticsActions.OnAutofillText] = AccessibilityAction(label, action)\n}\n\n/**\n * Action that an autofill service can invoke to fill the component with data.\n *\n * The [action] will be called by the system, passing the [FillableData] that should be used to\n * update the component's state.\n *\n * This is the counterpart to the [fillableData] property, which is used to *provide* the\n * component's current data to the autofill service.\n *\n * @sample androidx.compose.ui.samples.AutofillableTextFieldWithFillableDataSemantics\n * @param label Optional label for this action.\n * @param action Action to be performed when [SemanticsActions.OnFillData] is called. The lambda\n *   receives the [FillableData] from the autofill service.\n */\nfun SemanticsPropertyReceiver.onFillData(\n    label: String? = null,\n    action: ((FillableData) -> Boolean)?,\n) {\n    this[SemanticsActions.OnFillData] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to set the current value of the progress bar.\n *\n * Expected to be used in conjunction with progressBarRangeInfo.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.SetProgress] is called.\n */\nfun SemanticsPropertyReceiver.setProgress(label: String? = null, action: ((Float) -> Boolean)?) {\n    this[SemanticsActions.SetProgress] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to set the text contents of this node.\n *\n * Expected to be used on editable text fields.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when [SemanticsActions.SetText] is called.\n */\nfun SemanticsPropertyReceiver.setText(\n    label: String? = null,\n    action: ((AnnotatedString) -> Boolean)?,\n) {\n    this[SemanticsActions.SetText] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to set the text substitution of this node.\n *\n * Expected to be used on non-editable text.\n *\n * Note, this action doesn't show the text substitution. Please call\n * [SemanticsPropertyReceiver.showTextSubstitution] to show the text substitution.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when [SemanticsActions.SetTextSubstitution] is called.\n */\nfun SemanticsPropertyReceiver.setTextSubstitution(\n    label: String? = null,\n    action: ((AnnotatedString) -> Boolean)?,\n) {\n    this[SemanticsActions.SetTextSubstitution] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to show or hide the text substitution of this node.\n *\n * Expected to be used on non-editable text.\n *\n * Note, this action only takes effect when the node has the text substitution.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when [SemanticsActions.ShowTextSubstitution] is called.\n */\nfun SemanticsPropertyReceiver.showTextSubstitution(\n    label: String? = null,\n    action: ((Boolean) -> Boolean)?,\n) {\n    this[SemanticsActions.ShowTextSubstitution] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to clear the text substitution of this node.\n *\n * Expected to be used on non-editable text.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when [SemanticsActions.ClearTextSubstitution] is called.\n */\nfun SemanticsPropertyReceiver.clearTextSubstitution(\n    label: String? = null,\n    action: (() -> Boolean)?,\n) {\n    this[SemanticsActions.ClearTextSubstitution] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to insert text into this node at the current cursor position, or replacing the selection\n * if text is selected.\n *\n * Expected to be used on editable text fields.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when [SemanticsActions.InsertTextAtCursor] is called.\n */\nfun SemanticsPropertyReceiver.insertTextAtCursor(\n    label: String? = null,\n    action: ((AnnotatedString) -> Boolean)?,\n) {\n    this[SemanticsActions.InsertTextAtCursor] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to invoke the IME action handler configured on the node, as well as specify the type of\n * IME action provided by the node.\n *\n * Expected to be used on editable text fields.\n *\n * @param imeActionType The IME type, such as [ImeAction.Next] or [ImeAction.Search]\n * @param label Optional label for this action.\n * @param action Action to be performed when [SemanticsActions.OnImeAction] is called.\n * @see SemanticsProperties.ImeAction\n * @see SemanticsActions.OnImeAction\n */\nfun SemanticsPropertyReceiver.onImeAction(\n    imeActionType: ImeAction,\n    label: String? = null,\n    action: (() -> Boolean)?,\n) {\n    this[SemanticsProperties.ImeAction] = imeActionType\n    this[SemanticsActions.OnImeAction] = AccessibilityAction(label, action)\n}\n\n// b/322269946\n@Suppress(\"unused\")\n@Deprecated(\n    message = \"Use `SemanticsPropertyReceiver.onImeAction` instead.\",\n    replaceWith =\n        ReplaceWith(\n            \"onImeAction(imeActionType = ImeAction.Default, label = label, action = action)\",\n            \"androidx.compose.ui.semantics.onImeAction\",\n            \"androidx.compose.ui.text.input.ImeAction\",\n        ),\n    level = DeprecationLevel.ERROR,\n)\nfun SemanticsPropertyReceiver.performImeAction(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.OnImeAction] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to set text selection by character index range.\n *\n * If this action is provided, the selection data must be provided using [textSelectionRange].\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.SetSelection] is called. The\n *   parameters to the action are: `startIndex`, `endIndex`, and whether the indices are relative to\n *   the original text or the transformed text (when a `VisualTransformation` is applied).\n */\nfun SemanticsPropertyReceiver.setSelection(\n    label: String? = null,\n    action: ((startIndex: Int, endIndex: Int, relativeToOriginalText: Boolean) -> Boolean)?,\n) {\n    this[SemanticsActions.SetSelection] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to copy the text to the clipboard.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.CopyText] is called.\n */\nfun SemanticsPropertyReceiver.copyText(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.CopyText] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to cut the text and copy it to the clipboard.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.CutText] is called.\n */\nfun SemanticsPropertyReceiver.cutText(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.CutText] = AccessibilityAction(label, action)\n}\n\n/**\n * This function adds the [SemanticsActions.PasteText] to the [SemanticsPropertyReceiver]. Use it to\n * indicate that element is open for accepting paste data from the clipboard. There is no need to\n * check if the clipboard data available as this is done by the framework. For this action to be\n * triggered, the element must also have the [SemanticsProperties.Focused] property set.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.PasteText] is called.\n * @see focused\n */\nfun SemanticsPropertyReceiver.pasteText(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.PasteText] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to expand an expandable node.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.Expand] is called.\n */\nfun SemanticsPropertyReceiver.expand(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.Expand] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to collapse an expandable node.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.Collapse] is called.\n */\nfun SemanticsPropertyReceiver.collapse(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.Collapse] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to dismiss a dismissible node.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.Dismiss] is called.\n */\nfun SemanticsPropertyReceiver.dismiss(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.Dismiss] = AccessibilityAction(label, action)\n}\n\n/**\n * Action that gives input focus to this node.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.RequestFocus] is called.\n */\nfun SemanticsPropertyReceiver.requestFocus(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.RequestFocus] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to page up.\n *\n * Using [Role.Carousel] will prevent this action from being sent to accessibility services.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.PageUp] is called.\n * @see [Role.Carousel] for more information.\n */\nfun SemanticsPropertyReceiver.pageUp(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.PageUp] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to page down.\n *\n * Using [Role.Carousel] will prevent this action from being sent to accessibility services.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.PageDown] is called.\n * @see [Role.Carousel] for more information.\n */\nfun SemanticsPropertyReceiver.pageDown(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.PageDown] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to page left.\n *\n * Using [Role.Carousel] will prevent this action from being sent to accessibility services.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.PageLeft] is called.\n * @see [Role.Carousel] for more information.\n */\nfun SemanticsPropertyReceiver.pageLeft(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.PageLeft] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to page right.\n *\n * Using [Role.Carousel] will prevent this action from being sent to accessibility services.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.PageRight] is called.\n * @see [Role.Carousel] for more information.\n */\nfun SemanticsPropertyReceiver.pageRight(label: String? = null, action: (() -> Boolean)?) {\n    this[SemanticsActions.PageRight] = AccessibilityAction(label, action)\n}\n\n/**\n * Action to get a scrollable's active view port amount for scrolling actions.\n *\n * @param label Optional label for this action.\n * @param action Action to be performed when the [SemanticsActions.GetScrollViewportLength] is\n *   called.\n */\nfun SemanticsPropertyReceiver.getScrollViewportLength(\n    label: String? = null,\n    action: (() -> Float?),\n) {\n    this[SemanticsActions.GetScrollViewportLength] =\n        AccessibilityAction(label) {\n            val viewport = action.invoke()\n            if (viewport == null) {\n                false\n            } else {\n                it.add(viewport)\n                true\n            }\n        }\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusRequester.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.ui.focus\n\nimport androidx.compose.runtime.Stable\nimport androidx.compose.runtime.annotation.RememberInComposition\nimport androidx.compose.runtime.collection.MutableVector\nimport androidx.compose.runtime.collection.mutableVectorOf\nimport androidx.compose.ui.focus.FocusDirection.Companion.Enter\nimport androidx.compose.ui.node.Nodes\nimport androidx.compose.ui.node.visitChildren\n\nprivate const val FocusRequesterNotInitialized =\n    \"\"\"\n   FocusRequester is not initialized. Here are some possible fixes:\n\n   1. Remember the FocusRequester: val focusRequester = remember { FocusRequester() }\n   2. Did you forget to add a Modifier.focusRequester() ?\n   3. Are you attempting to request focus during composition? Focus requests should be made in\n   response to some event. Eg Modifier.clickable { focusRequester.requestFocus() }\n\"\"\"\n\nprivate const val InvalidFocusRequesterInvocation =\n    \"\"\"\n    Please check whether the focusRequester is FocusRequester.Cancel or FocusRequester.Default\n    before invoking any functions on the focusRequester.\n\"\"\"\n\n/**\n * The [FocusRequester] is used in conjunction with\n * [Modifier.focusRequester][androidx.compose.ui.focus.focusRequester] to send requests to change\n * focus.\n *\n * @sample androidx.compose.ui.samples.RequestFocusSample\n * @see androidx.compose.ui.focus.focusRequester\n */\n@Stable\nclass FocusRequester @RememberInComposition constructor() {\n\n    internal val focusRequesterNodes: MutableVector<FocusRequesterModifierNode> = mutableVectorOf()\n\n    /**\n     * Use this function to request focus. If the system grants focus to a component associated with\n     * this [FocusRequester], its [onFocusChanged] modifiers will receive a [FocusState] object\n     * where [FocusState.isFocused] is true.\n     *\n     * @sample androidx.compose.ui.samples.RequestFocusSample\n     */\n    @Deprecated(\n        message = \"use the version the has a FocusDirection\",\n        replaceWith = ReplaceWith(\"this.requestFocus()\"),\n        level = DeprecationLevel.HIDDEN,\n    )\n    fun requestFocus() {\n        requestFocus(Enter)\n    }\n\n    /**\n     * Use this function to request focus with a specific direction. If the system grants focus to a\n     * component associated with this [FocusRequester], its [onFocusChanged] modifiers will receive\n     * a [FocusState] object where [FocusState.isFocused] is true.\n     *\n     * @param focusDirection The direction passed to the [FocusTargetModifierNode] to indicate the\n     *   direction that the focus request comes from.\n     * @return `true` if the focus was successfully requested or `false` if the focus request was\n     *   canceled.\n     * @sample androidx.compose.ui.samples.RequestFocusSample\n     */\n    fun requestFocus(focusDirection: FocusDirection = Enter): Boolean {\n        return findFocusTarget { it.requestFocus(focusDirection) }\n    }\n\n    /**\n     * Deny requests to clear focus.\n     *\n     * Use this function to send a request to capture focus. If a component captures focus, it will\n     * send a [FocusState] object to its associated [onFocusChanged] modifiers where\n     * [FocusState.isCaptured]() == true.\n     *\n     * When a component is in a Captured state, all focus requests from other components are\n     * declined.\n     *\n     * @return true if the focus was successfully captured by one of the [focus][focusTarget]\n     *   modifiers associated with this [FocusRequester]. False otherwise.\n     * @sample androidx.compose.ui.samples.CaptureFocusSample\n     */\n    fun captureFocus(): Boolean {\n        if (focusRequesterNodes.isEmpty()) {\n            println(\"$FocusWarning: $FocusRequesterNotInitialized\")\n            return false\n        }\n        focusRequesterNodes.forEach {\n            if (it.captureFocus()) {\n                return true\n            }\n        }\n        return false\n    }\n\n    /**\n     * Use this function to send a request to free focus when one of the components associated with\n     * this [FocusRequester] is in a Captured state. If a component frees focus, it will send a\n     * [FocusState] object to its associated [onFocusChanged] modifiers where\n     * [FocusState.isCaptured]() == false.\n     *\n     * When a component is in a Captured state, all focus requests from other components are\n     * declined. .\n     *\n     * @return true if the captured focus was successfully released. i.e. At the end of this\n     *   operation, one of the components associated with this [focusRequester] freed focus.\n     * @sample androidx.compose.ui.samples.CaptureFocusSample\n     */\n    fun freeFocus(): Boolean {\n        if (focusRequesterNodes.isEmpty()) {\n            println(\"$FocusWarning: $FocusRequesterNotInitialized\")\n            return false\n        }\n        focusRequesterNodes.forEach {\n            if (it.freeFocus()) {\n                return true\n            }\n        }\n        return false\n    }\n\n    /**\n     * Use this function to request the focus target to save a reference to the currently focused\n     * child in its saved instance state. After calling this, focus can be restored to the saved\n     * child by making a call to [restoreFocusedChild].\n     *\n     * @return true if the focus target associated with this [FocusRequester] has a focused child\n     *   and we successfully saved a reference to it.\n     * @sample androidx.compose.ui.samples.RestoreFocusSample\n     */\n    // TODO: Deprecate once focus restoration is enabled by default via flags.\n    // @Deprecated(\n    //    message =\n    //        \"The focused child is now saved automatically whenever focus changes. Just call\" +\n    //            \" restoreFocusedChild to restore focus.\",\n    //    level = DeprecationLevel.WARNING,\n    // )\n    fun saveFocusedChild(): Boolean {\n        if (focusRequesterNodes.isEmpty()) {\n            println(\"$FocusWarning: $FocusRequesterNotInitialized\")\n            return false\n        }\n        focusRequesterNodes.forEach { if (it.saveFocusedChild()) return true }\n        return false\n    }\n\n    /**\n     * Use this function to restore focus to one of the children of the node pointed to by this\n     * [FocusRequester]. This restores focus to a previously focused child that was saved by using\n     * [saveFocusedChild].\n     *\n     * @return true if we successfully restored focus to one of the children of the [focusTarget]\n     *   associated with this [FocusRequester]\n     * @sample androidx.compose.ui.samples.RestoreFocusSample\n     */\n    fun restoreFocusedChild(): Boolean {\n        if (focusRequesterNodes.isEmpty()) {\n            println(\"$FocusWarning: $FocusRequesterNotInitialized\")\n            return false\n        }\n        var success = false\n        focusRequesterNodes.forEach { success = it.restoreFocusedChild() || success }\n        return success\n    }\n\n    companion object {\n        /**\n         * Default [focusRequester], which when used in [Modifier.focusProperties][focusProperties]\n         * implies that we want to use the default system focus order, that is based on the position\n         * of the items on the screen.\n         */\n        val Default = FocusRequester()\n\n        /**\n         * Cancelled [focusRequester], which when used in\n         * [Modifier.focusProperties][focusProperties] implies that we want to block focus search\n         * from proceeding in the specified [direction][FocusDirection].\n         *\n         * @sample androidx.compose.ui.samples.CancelFocusMoveSample\n         */\n        val Cancel = FocusRequester()\n\n        /** Used to indicate that the focus has been redirected during an enter/exit lambda. */\n        internal val Redirect = FocusRequester()\n\n        /**\n         * Convenient way to create multiple [FocusRequester] instances.\n         *\n         * @sample androidx.compose.ui.samples.CreateFocusRequesterRefsSample\n         */\n        object FocusRequesterFactory {\n            operator fun component1() = FocusRequester()\n\n            operator fun component2() = FocusRequester()\n\n            operator fun component3() = FocusRequester()\n\n            operator fun component4() = FocusRequester()\n\n            operator fun component5() = FocusRequester()\n\n            operator fun component6() = FocusRequester()\n\n            operator fun component7() = FocusRequester()\n\n            operator fun component8() = FocusRequester()\n\n            operator fun component9() = FocusRequester()\n\n            operator fun component10() = FocusRequester()\n\n            operator fun component11() = FocusRequester()\n\n            operator fun component12() = FocusRequester()\n\n            operator fun component13() = FocusRequester()\n\n            operator fun component14() = FocusRequester()\n\n            operator fun component15() = FocusRequester()\n\n            operator fun component16() = FocusRequester()\n        }\n\n        /**\n         * Convenient way to create multiple [FocusRequester]s, which can to be used to request\n         * focus, or to specify a focus traversal order.\n         *\n         * @sample androidx.compose.ui.samples.CreateFocusRequesterRefsSample\n         */\n        fun createRefs(): FocusRequesterFactory = FocusRequesterFactory\n    }\n\n    /**\n     * This function searches down the hierarchy and calls [onFound] for all focus nodes associated\n     * with this [FocusRequester].\n     *\n     * @param onFound the callback that is run when the child is found.\n     * @return false if no focus nodes were found or if the FocusRequester is\n     *   [FocusRequester.Cancel]. Returns a logical or of the result of calling [onFound] for each\n     *   focus node associated with this [FocusRequester].\n     */\n    internal inline fun findFocusTarget(onFound: (FocusTargetNode) -> Boolean): Boolean {\n        check(this !== Default) { InvalidFocusRequesterInvocation }\n        check(this !== Cancel) { InvalidFocusRequesterInvocation }\n        if (focusRequesterNodes.isEmpty()) {\n            println(\"$FocusWarning: $FocusRequesterNotInitialized\")\n            return false\n        }\n        var success = false\n        focusRequesterNodes.forEach { node ->\n            node.visitChildren(Nodes.FocusTarget) {\n                if (onFound(it)) {\n                    success = true\n                    return@forEach\n                }\n            }\n        }\n        return success\n    }\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/focus/FocusManager.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage androidx.compose.ui.focus\n\nimport androidx.compose.ui.internal.JvmDefaultWithCompatibility\n\n@JvmDefaultWithCompatibility\ninterface FocusManager {\n    /**\n     * Call this function to clear focus from the currently focused component, and set the focus to\n     * the root focus modifier.\n     *\n     * @param force: Whether we should forcefully clear focus regardless of whether we have any\n     *   components that have Captured focus.\n     * @sample androidx.compose.ui.samples.ClearFocusSample\n     */\n    fun clearFocus(force: Boolean = false)\n\n    /**\n     * Moves focus in the specified [direction][FocusDirection].\n     *\n     * If you are not satisfied with the default focus order, consider setting a custom order using\n     * [Modifier.focusProperties()][focusProperties].\n     *\n     * @return true if focus was moved successfully. false if the focused item is unchanged.\n     * @sample androidx.compose.ui.samples.MoveFocusSample\n     */\n    fun moveFocus(focusDirection: FocusDirection): Boolean\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/platform/CompositionLocals.kt\n```kotlin\n/*\n * Copyright 2020 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n@file:Suppress(\"DEPRECATION\")\n\npackage androidx.compose.ui.platform\n\nimport androidx.annotation.RestrictTo\nimport androidx.annotation.VisibleForTesting\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocal\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.ProvidableCompositionLocal\nimport androidx.compose.runtime.compositionLocalOf\nimport androidx.compose.runtime.compositionLocalWithComputedDefaultOf\nimport androidx.compose.runtime.retain.LocalRetainedValuesStore\nimport androidx.compose.runtime.staticCompositionLocalOf\nimport androidx.compose.ui.ExperimentalComposeUiApi\nimport androidx.compose.ui.autofill.Autofill\nimport androidx.compose.ui.autofill.AutofillManager\nimport androidx.compose.ui.autofill.AutofillTree\nimport androidx.compose.ui.draw.DrawModifier\nimport androidx.compose.ui.focus.FocusManager\nimport androidx.compose.ui.graphics.GraphicsContext\nimport androidx.compose.ui.graphics.layer.GraphicsLayer\nimport androidx.compose.ui.hapticfeedback.HapticFeedback\nimport androidx.compose.ui.input.InputModeManager\nimport androidx.compose.ui.input.pointer.PointerIconService\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.node.Owner\nimport androidx.compose.ui.text.font.Font\nimport androidx.compose.ui.text.font.FontFamily\nimport androidx.compose.ui.text.input.TextInputService\nimport androidx.compose.ui.text.intl.Locale\nimport androidx.compose.ui.text.intl.LocaleList\nimport androidx.compose.ui.unit.Density\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.lifecycle.LifecycleOwner\n\n/** The CompositionLocal to provide communication with platform accessibility service. */\nval LocalAccessibilityManager = staticCompositionLocalOf<AccessibilityManager?> { null }\n\n/**\n * The CompositionLocal that can be used to trigger autofill actions. Eg.\n * [Autofill.requestAutofillForNode].\n */\n@Deprecated(\n    \"\"\"\n        Use the new semantics-based Autofill APIs androidx.compose.ui.autofill.ContentType and\n        androidx.compose.ui.autofill.ContentDataType instead.\n        \"\"\"\n)\nval LocalAutofill = staticCompositionLocalOf<Autofill?> { null }\n\n/**\n * The CompositionLocal that can be used to add [AutofillNode][import\n * androidx.compose.ui.autofill.AutofillNode]s to the autofill tree. The [AutofillTree] is a\n * temporary data structure that will be replaced by Autofill Semantics (b/138604305).\n */\n@Deprecated(\n    \"\"\"\n        Use the new semantics-based Autofill APIs androidx.compose.ui.autofill.ContentType and\n        androidx.compose.ui.autofill.ContentDataType instead.\n        \"\"\"\n)\nval LocalAutofillTree =\n    staticCompositionLocalOf<AutofillTree> { noLocalProvidedFor(\"LocalAutofillTree\") }\n\n/**\n * The CompositionLocal that can be used to trigger autofill actions. Eg. [AutofillManager.commit].\n */\nval LocalAutofillManager =\n    staticCompositionLocalOf<AutofillManager?> { noLocalProvidedFor(\"LocalAutofillManager\") }\n\n/** The CompositionLocal to provide communication with platform clipboard service. */\n@Deprecated(\n    \"Use LocalClipboard instead which supports suspend functions\",\n    ReplaceWith(\"LocalClipboard\", \"androidx.compose.ui.platform.LocalClipboard\"),\n)\nval LocalClipboardManager =\n    staticCompositionLocalOf<ClipboardManager> { noLocalProvidedFor(\"LocalClipboardManager\") }\n\n/** The CompositionLocal to provide communication with platform clipboard service. */\nval LocalClipboard = staticCompositionLocalOf<Clipboard> { noLocalProvidedFor(\"LocalClipboard\") }\n\n/**\n * The CompositionLocal to provide access to a [GraphicsContext] instance for creation of\n * [GraphicsLayer]s.\n *\n * Consumers that access this Local directly and call [GraphicsContext.createGraphicsLayer] are\n * responsible for calling [GraphicsContext.releaseGraphicsLayer].\n *\n * It is recommended that consumers invoke [rememberGraphicsLayer][import\n * androidx.compose.ui.graphics.rememberGraphicsLayer] instead to ensure that a [GraphicsLayer] is\n * released when the corresponding composable is disposed.\n */\nval LocalGraphicsContext =\n    staticCompositionLocalOf<GraphicsContext> { noLocalProvidedFor(\"LocalGraphicsContext\") }\n\n/**\n * Provides the [Density] to be used to transform between\n * [density-independent pixel units (DP)][androidx.compose.ui.unit.Dp] and pixel units or\n * [scale-independent pixel units (SP)][androidx.compose.ui.unit.TextUnit] and pixel units. This is\n * typically used when a [DP][androidx.compose.ui.unit.Dp] is provided and it must be converted in\n * the body of [Layout] or [DrawModifier].\n */\nval LocalDensity = staticCompositionLocalOf<Density> { noLocalProvidedFor(\"LocalDensity\") }\n\n/** The CompositionLocal that can be used to control focus within Compose. */\nval LocalFocusManager =\n    staticCompositionLocalOf<FocusManager> { noLocalProvidedFor(\"LocalFocusManager\") }\n\n/** The CompositionLocal to provide platform font loading methods. */\n@Suppress(\"DEPRECATION\")\n@Deprecated(\n    \"LocalFontLoader is replaced with LocalFontFamilyResolver\",\n    replaceWith = ReplaceWith(\"LocalFontFamilyResolver\"),\n)\n@get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)\nval LocalFontLoader =\n    staticCompositionLocalOf<Font.ResourceLoader> { noLocalProvidedFor(\"LocalFontLoader\") }\n\n/** The CompositionLocal for compose font resolution from FontFamily. */\nval LocalFontFamilyResolver =\n    staticCompositionLocalOf<FontFamily.Resolver> { noLocalProvidedFor(\"LocalFontFamilyResolver\") }\n\n/** The CompositionLocal to provide haptic feedback to the user. */\nval LocalHapticFeedback =\n    staticCompositionLocalOf<HapticFeedback> { noLocalProvidedFor(\"LocalHapticFeedback\") }\n\n/**\n * The CompositionLocal to provide an instance of InputModeManager which controls the current input\n * mode.\n */\nval LocalInputModeManager =\n    staticCompositionLocalOf<InputModeManager> { noLocalProvidedFor(\"LocalInputManager\") }\n\n/** The CompositionLocal to provide the layout direction. */\nval LocalLayoutDirection =\n    staticCompositionLocalOf<LayoutDirection> { noLocalProvidedFor(\"LocalLayoutDirection\") }\n\n/** The providable CompositionLocal to provide the locale list. This list can never be empty. */\n@get:VisibleForTesting\n@get:RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)\nval LocalProvidableLocaleList: ProvidableCompositionLocal<LocaleList> = staticCompositionLocalOf {\n    noLocalProvidedFor(\"LocalProvidableLocaleList\")\n}\n\n/** The CompositionLocal to provide the locale list. This list will never be empty. */\nval LocalLocaleList: CompositionLocal<LocaleList>\n    get() = LocalProvidableLocaleList\n\n/** The CompositionLocal to provide the locale. */\nval LocalLocale: CompositionLocal<Locale> = compositionLocalWithComputedDefaultOf {\n    LocalLocaleList.currentValue.first()\n}\n\n/** The CompositionLocal to provide communication with platform text input service. */\n@Deprecated(\"Use PlatformTextInputModifierNode instead.\")\nval LocalTextInputService = staticCompositionLocalOf<TextInputService?> { null }\n\n/**\n * The [CompositionLocal] to provide a [SoftwareKeyboardController] that can control the current\n * software keyboard.\n *\n * Will be null if the software keyboard cannot be controlled.\n */\nval LocalSoftwareKeyboardController = staticCompositionLocalOf<SoftwareKeyboardController?> { null }\n\n/** The CompositionLocal to provide text-related toolbar. */\nval LocalTextToolbar =\n    staticCompositionLocalOf<TextToolbar> { noLocalProvidedFor(\"LocalTextToolbar\") }\n\n/** The CompositionLocal to provide functionality related to URL, e.g. open URI. */\nval LocalUriHandler = staticCompositionLocalOf<UriHandler> { noLocalProvidedFor(\"LocalUriHandler\") }\n\n/** The CompositionLocal that provides the ViewConfiguration. */\nval LocalViewConfiguration =\n    staticCompositionLocalOf<ViewConfiguration> { noLocalProvidedFor(\"LocalViewConfiguration\") }\n\n/**\n * The CompositionLocal that provides information about the window that hosts the current [Owner].\n */\nval LocalWindowInfo = staticCompositionLocalOf<WindowInfo> { noLocalProvidedFor(\"LocalWindowInfo\") }\n\n/** The CompositionLocal containing the current [LifecycleOwner]. */\n@Deprecated(\n    \"Moved to lifecycle-runtime-compose library in androidx.lifecycle.compose package.\",\n    ReplaceWith(\"androidx.lifecycle.compose.LocalLifecycleOwner\"),\n)\nexpect val LocalLifecycleOwner: ProvidableCompositionLocal<LifecycleOwner>\n\ninternal val LocalPointerIconService = staticCompositionLocalOf<PointerIconService?> { null }\n\n/** @see LocalScrollCaptureInProgress */\ninternal val LocalProvidableScrollCaptureInProgress = compositionLocalOf { false }\n\n/**\n * True when the system is currently capturing the contents of a scrollable in this compose view or\n * any parent compose view.\n */\nval LocalScrollCaptureInProgress: CompositionLocal<Boolean>\n    get() = LocalProvidableScrollCaptureInProgress\n\n/**\n * Text cursor blinking\n * - _true_ normal cursor behavior (interactive blink)\n * - _false_ never blink (always on)\n *\n * The default of _true_ is the user-expected system behavior for Text editing.\n *\n * Typically you should not set _false_ outside of screenshot tests without also providing a\n * `cursorBrush` to `BasicTextField` to implement a custom design\n */\nval LocalCursorBlinkEnabled: ProvidableCompositionLocal<Boolean> = staticCompositionLocalOf { true }\n\n@ExperimentalComposeUiApi\n@Composable\ninternal fun ProvideCommonCompositionLocals(\n    owner: Owner,\n    uriHandler: UriHandler,\n    content: @Composable () -> Unit,\n) {\n    CompositionLocalProvider(\n        LocalAccessibilityManager provides owner.accessibilityManager,\n        LocalAutofill provides owner.autofill,\n        LocalAutofillManager provides owner.autofillManager,\n        LocalAutofillTree provides owner.autofillTree,\n        LocalClipboardManager provides owner.clipboardManager,\n        LocalClipboard provides owner.clipboard,\n        LocalDensity provides owner.density,\n        LocalFocusManager provides owner.focusOwner,\n        @Suppress(\"DEPRECATION\") LocalFontLoader providesDefault\n            @Suppress(\"DEPRECATION\") owner.fontLoader,\n        LocalFontFamilyResolver providesDefault owner.fontFamilyResolver,\n        LocalHapticFeedback provides owner.hapticFeedBack,\n        LocalInputModeManager provides owner.inputModeManager,\n        LocalLayoutDirection provides owner.layoutDirection,\n        LocalTextInputService provides owner.textInputService,\n        LocalSoftwareKeyboardController provides owner.softwareKeyboardController,\n        LocalTextToolbar provides owner.textToolbar,\n        LocalUriHandler provides uriHandler,\n        LocalViewConfiguration provides owner.viewConfiguration,\n        LocalWindowInfo provides owner.windowInfo,\n        LocalPointerIconService provides owner.pointerIconService,\n        LocalGraphicsContext provides owner.graphicsContext,\n        LocalRetainedValuesStore provides owner.retainedValuesStore,\n        LocalProvidableLocaleList provides owner.localeList,\n        content = content,\n    )\n}\n\nprivate fun noLocalProvidedFor(name: String): Nothing {\n    error(\"CompositionLocal $name not present\")\n}\n```\n\n## File: compose/ui/ui/src/commonMain/kotlin/androidx/compose/ui/ComposeUiFlags.kt\n```kotlin\n/*\n * Copyright 2024 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n@file:JvmName(\"ComposeRuntimeFlags\")\n\npackage androidx.compose.ui\n\nimport androidx.compose.ui.node.findNearestAncestor\nimport kotlin.jvm.JvmField\nimport kotlin.jvm.JvmName\n\n/**\n * This is a collection of flags which are used to guard against regressions in some of the\n * \"riskier\" refactors or new feature support that is added to this module. These flags are always\n * \"on\" in the published artifact of this module, however these flags allow end consumers of this\n * module to toggle them \"off\" in case this new path is causing a regression.\n *\n * These flags are considered temporary, and there should be no expectation for these flags be\n * around for an extended period of time. If you have a regression that one of these flags fixes, it\n * is strongly encouraged for you to file a bug ASAP.\n *\n * **Usage:**\n *\n * In order to turn a feature off in a debug environment, it is recommended to set this to false in\n * as close to the initial loading of the application as possible. Changing this value after compose\n * library code has already been loaded can result in undefined behavior.\n *\n *      class MyApplication : Application() {\n *          override fun onCreate() {\n *              ComposeUiFlags.SomeFeatureEnabled = false\n *              super.onCreate()\n *          }\n *      }\n *\n * In order to turn this off in a release environment, it is recommended to additionally utilize R8\n * rules which force a single value for the entire build artifact. This can result in the new code\n * paths being completely removed from the artifact, which can often have nontrivial positive\n * performance impact.\n *\n *      -assumevalues class androidx.compose.ui.ComposeUiFlags {\n *          public static int isRectTrackingEnabled return false\n *      }\n */\n@ExperimentalComposeUiApi\nobject ComposeUiFlags {\n    /**\n     * This enables fixes for View focus. The changes are large enough to require a flag to allow\n     * disabling them.\n     */\n    // TODO: b/455588830\n    @field:Suppress(\"MutableBareField\") @JvmField var isViewFocusFixEnabled: Boolean = false\n\n    /**\n     * This flag enables an alternate approach to fixing the issues addressed by the\n     * [isViewFocusFixEnabled] flag.\n     */\n    // TODO: b/455592447\n    @field:Suppress(\"MutableBareField\")\n    @JvmField\n    var isBypassUnfocusableComposeViewEnabled: Boolean = true\n\n    /** Enable initial focus when a focusable is added to a screen with no focusable content. */\n    // TODO: b/455601824\n    @field:Suppress(\"MutableBareField\")\n    @JvmField\n    var isInitialFocusOnFocusableAvailable: Boolean = false\n\n    /**\n     * Enable focus restoration, by always saving focus. This flag depends on\n     * [isInitialFocusOnFocusableAvailable] also being true.\n     */\n    // TODO: b/485962036\n    @field:Suppress(\"MutableBareField\") @JvmField var isFocusRestorationEnabled: Boolean = false\n\n    /** Flag for enabling indirect pointer event navigation gestures in Compose. */\n    // TODO: b/455601135\n    @field:Suppress(\"MutableBareField\")\n    @JvmField\n    var isIndirectPointerNavigationGestureDetectorEnabled: Boolean = true\n\n    /** Flag enables optimized focus change dispatching logic. */\n    // TODO: b/455603009\n    @field:Suppress(\"MutableBareField\")\n    @JvmField\n    var isOptimizedFocusEventDispatchEnabled: Boolean = true\n\n    /** This flag enables setting the shape semantics property in the graphicsLayer modifiers. */\n    // TODO: b/455600081\n    @field:Suppress(\"MutableBareField\")\n    @JvmField\n    var isGraphicsLayerShapeSemanticsEnabled: Boolean = true\n\n    /**\n     * Enables a fix where [TraversableNode] traversal method [findNearestAncestor] will take into\n     * consideration any delegates that might also be traversable.\n     */\n    // TODO: b/485962494\n    @field:Suppress(\"MutableBareField\")\n    @JvmField\n    var isTraversableDelegatesFixEnabled: Boolean = true\n\n    /**\n     * Enables a change where off-screen children of the partially visible merging nodes (e.g. a\n     * Text node of a Button) inside scrollable container are now also reported in the semantics\n     * tree for Accessibility needs.\n     *\n     * Enabled is correct, and it should be enabled in all apps.\n     */\n    // TODO: b/484259656\n    @field:Suppress(\"MutableBareField\")\n    @JvmField\n    var isAccessibilityShouldIncludeOffscreenChildrenEnabled: Boolean = true\n\n    /**\n     * Enables support of trackpad gesture events.\n     *\n     * If enabled, [androidx.compose.ui.input.pointer.PointerEvent]s can have type of\n     * [androidx.compose.ui.input.pointer.PointerEventType.PanMove] and\n     * [androidx.compose.ui.input.pointer.PointerEventType.ScaleChange], corresponding to\n     * system-recognized gestures on a trackpad.\n     *\n     * These trackpad gestures will also generally be treated as mouse, with the exact behavior\n     * depending on platform specifics.\n     */\n    // TODO: b/475634969 remove the temporary flag\n    @field:Suppress(\"MutableBareField\")\n    @JvmField\n    var isTrackpadGestureHandlingEnabled: Boolean = true\n\n    /**\n     * Enable the integration of [LocalUiMediaScope] at the root compose view which provides various\n     * signals for adapting the UI across different devices.\n     *\n     * This feature is experimental and is disabled by default.\n     */\n    // TODO: b/485160699 - Remove once the API goes stable\n    @field:Suppress(\"MutableBareField\")\n    @JvmField\n    var isMediaQueryIntegrationEnabled: Boolean = false\n\n    /**\n     * Enables hit test to continue searching for \"semantic nodes\" if the initial node that is hit\n     * is unimportant from an accessibility semantics node point of view.\n     */\n    // TODO: b/487663967\n    @field:Suppress(\"MutableBareField\")\n    @JvmField\n    var isSkipNonImportantSemanticsNodesHitTestEnabled: Boolean = true\n}\n```\n\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/state-management.md",
    "content": "# Jetpack Compose State Management Reference\n\n## State Fundamentals\n\nState in Compose is observable data that triggers recomposition when changed.\n\n### Creating State\n\nUse type-specific state holders for efficiency:\n\n```kotlin\n// General-purpose state (Any type)\nval name = mutableStateOf(\"Alice\")\n\n// Primitive specializations (avoid boxing)\nval count = mutableIntStateOf(0)\nval progress = mutableFloatStateOf(0.5f)\nval enabled = mutableStateOf(true)  // Boolean has no specialization\n```\n\n**Pitfall:** Using `mutableStateOf<Int>()` instead of `mutableIntStateOf()` causes unnecessary boxing on every read/write. Primitive specializations are located in `androidx.compose.runtime` (source: `State.kt`).\n\n## remember vs rememberSaveable\n\nBoth associate state with a composition key, but differ in persistence scope.\n\n### remember\n- Lives for the composition's lifetime\n- Lost on process death, configuration changes, back navigation\n- Best for UI state: selection, expanded/collapsed, scroll position\n\n```kotlin\n@Composable\nfun Counter() {\n    var count by remember { mutableIntStateOf(0) }\n    Button(onClick = { count++ }) {\n        Text(\"Count: $count\")\n    }\n}\n```\n\n### rememberSaveable\n- Survives process death and configuration changes\n- Uses `Bundle`-compatible types by default (String, Int, Boolean, etc.)\n- For custom types, provide a `Saver` or use `@Parcelize`\n- Best for data that represents user input or navigation state\n\n```kotlin\n@Composable\nfun SearchScreen() {\n    var query by rememberSaveable { mutableStateOf(\"\") }\n    // survives configuration change\n}\n\n// Custom type requires explicit Saver\ndata class User(val id: Int, val name: String)\nval userSaver = Saver<User, String>(\n    save = { \"${it.id}:${it.name}\" },\n    restore = { parts -> User(parts.split(\":\")[0].toInt(), parts.split(\":\")[1]) }\n)\nvar user by rememberSaveable(stateSaver = userSaver) { mutableStateOf(User(1, \"Alice\")) }\n```\n\n**Pitfall:** Assuming `rememberSaveable` works with all types. Custom classes need explicit `Saver` or `@Parcelize`. See `SaveableStateRegistry` in `androidx.compose.runtime.saveable`.\n\n## State Hoisting\n\nMove state up to a parent composable to enable reusability and testing.\n\n### Stateful vs Stateless Pattern\n\n```kotlin\n// ❌ Stateful version (tightly coupled)\n@Composable\nfun Counter() {\n    var count by remember { mutableIntStateOf(0) }\n    Button(onClick = { count++ }) { Text(count.toString()) }\n}\n\n// ✅ Stateless version (reusable, testable)\n@Composable\nfun Counter(\n    count: Int,\n    onCountChange: (Int) -> Unit\n) {\n    Button(onClick = { onCountChange(count + 1) }) { Text(count.toString()) }\n}\n\n// ✅ Wrapper composable (provides state, uses stateless child)\n@Composable\nfun StatefulCounter() {\n    var count by remember { mutableIntStateOf(0) }\n    Counter(count = count, onCountChange = { count = it })\n}\n```\n\n**Rule:** Push state as high as needed, but no higher. If only one child needs state, keep it there. If multiple children or parents need it, hoist up.\n\n## derivedStateOf\n\nComputes a value from existing state, recomputing only when dependencies change.\n\n```kotlin\n// ❌ Wrong: recomputes on every recomposition\nval isEven = count % 2 == 0\n\n// ✅ Correct: recomputes only when count changes\nval isEven = derivedStateOf { count % 2 == 0 }\n```\n\n**When to use:**\n- Expensive computations from state (e.g., filtering, sorting lists)\n- Combining multiple state values\n- Creating intermediate state for conditional logic\n\n```kotlin\n@Composable\nfun UserList(users: List<User>, filterText: String) {\n    val filteredUsers = derivedStateOf {\n        users.filter { it.name.contains(filterText, ignoreCase = true) }\n    }\n\n    LazyColumn {\n        items(filteredUsers.value.size) { index ->\n            UserRow(filteredUsers.value[index])\n        }\n    }\n}\n```\n\n**Pitfall:** Using `derivedStateOf` for cheap operations (String concatenation, simple conditions) adds overhead. Only use when the computation is non-trivial.\n\n**Pitfall:** Accessing `.value` in a lambda passed to a child composable doesn't create a dependency. Use `snapshotFlow` for callbacks.\n\n## snapshotFlow\n\nConverts Compose state to Kotlin Flow for side effects and external APIs.\n\n```kotlin\n@Composable\nfun SearchScreen(viewModel: SearchViewModel) {\n    var query by remember { mutableStateOf(\"\") }\n\n    LaunchedEffect(Unit) {\n        snapshotFlow { query }\n            .debounce(500)\n            .distinctUntilChanged()\n            .collect { viewModel.search(it) }\n    }\n}\n```\n\n**Key behaviors:**\n- Emits initial value, then only on changes\n- Works with derivedStateOf, collections, and nested state\n- Runs in the composition's coroutine scope (launched via `LaunchedEffect`)\n\n**Pitfall:** Accessing state directly in a `LaunchedEffect` doesn't track changes:\n```kotlin\n// ❌ Won't re-run when query changes\nLaunchedEffect(Unit) {\n    viewModel.search(query)  // Capture at launch time only\n}\n\n// ✅ Re-runs when query changes\nLaunchedEffect(query) {\n    viewModel.search(query)\n}\n```\n\n## SnapshotStateList and SnapshotStateMap\n\nObservable collections that trigger recomposition on structural changes.\n\n```kotlin\nval items = remember { mutableStateListOf<Item>() }\nitems.add(Item(1, \"First\"))\nitems[0] = Item(1, \"Updated\")\nitems.removeAt(0)\n\nval map = remember { mutableStateMapOf<String, String>() }\nmap[\"key\"] = \"value\"  // Triggers recomposition\n```\n\n**Important:** Changes to list contents trigger recomposition, but changes to list *elements* (if they're mutable objects) do not.\n\n```kotlin\ndata class Item(val id: Int, var name: String)\n\nval items = remember { mutableStateListOf(Item(1, \"First\")) }\n\n// ✅ Triggers recomposition (list structure changed)\nitems[0] = Item(1, \"Updated\")\n\n// ❌ Does NOT trigger recomposition (object mutated in-place)\nitems[0].name = \"Updated\"  // Mutated but list reference unchanged\n\n// ✅ Correct: use copy() or mutableStateOf for nested state\nitems[0] = items[0].copy(name = \"Updated\")\n```\n\nSee source: `androidx.compose.runtime.snapshots` for collection implementation.\n\n## @Stable and @Immutable Annotations\n\nThese annotations help the compiler optimize recomposition (strong skipping mode).\n\n### @Immutable\n- All public fields are read-only primitives or other `@Immutable` types\n- Instances never change after construction\n- Compiler can skip recomposition if parameter unchanged\n\n```kotlin\n@Immutable\ndata class User(val id: Int, val name: String)\n```\n\n### @Stable\n- Implements structural equality (`equals`)\n- Public properties are read-only or observable\n- Changes are always notified to Compose (through state objects)\n- Weaker guarantee than `@Immutable`, but suitable for types with observable state\n\n```kotlin\n@Stable\nclass UserViewModel {\n    val userName: State<String> = mutableStateOf(\"\")\n    val isLoading: State<Boolean> = mutableStateOf(false)\n\n    // Observable state, not direct properties\n}\n```\n\n**Pitfall:** Not annotating data classes used as parameters. Unannotated types are assumed unstable, triggering unnecessary recompositions.\n\n```kotlin\n// ❌ Treated as unstable, causes recomposition\nclass Config(val title: String, val color: Color)\n\n// ✅ Properly annotated\n@Immutable\nclass Config(val title: String, val color: Color)\n```\n\n## Strong Skipping Mode\n\nIn Compose 1.6+, strong skipping mode applies stricter recomposition logic.\n\n**What changed:**\n- Composables skip recomposition if *all* parameters have unchanged identity and value\n- Unannotated parameter types are treated as unstable (always recompose)\n- `@Stable` and `@Immutable` annotations are now critical for performance\n- Lambda parameters always cause recomposition (they're new instances)\n\n**Enable strong skipping:**\n```gradle\ncomposeOptions {\n    kotlinCompilerExtensionVersion = \"1.5.4+\"  // enables by default\n}\n```\n\n**Practical impact:**\n```kotlin\n// ❌ These create new instances, always recompose child\n@Composable\nfun Parent() {\n    Child(title = buildString { append(\"Title\") })\n    Child(config = Config(...))  // Unstable type\n}\n\n// ✅ Cache instances\n@Composable\nfun Parent() {\n    val title = remember { \"Title\" }\n    val config = remember { Config(...) }\n    Child(title = title)\n    Child(config = config)\n}\n```\n\n## State in ViewModels: StateFlow vs Compose State\n\n### StateFlow (Recommended for ViewModel)\n- Survives composition recomposition and configuration changes\n- Works with lifecycle (`collectAsStateWithLifecycle`)\n- Thread-safe, works across layers\n\n```kotlin\nclass UserViewModel : ViewModel() {\n    private val _uiState = MutableStateFlow<UiState>(UiState.Loading)\n    val uiState: StateFlow<UiState> = _uiState.asStateFlow()\n}\n\n@Composable\nfun UserScreen(viewModel: UserViewModel) {\n    val uiState by viewModel.uiState.collectAsStateWithLifecycle()\n\n    when (uiState) {\n        is UiState.Loading -> LoadingScreen()\n        is UiState.Success -> SuccessScreen((uiState as UiState.Success).data)\n        is UiState.Error -> ErrorScreen((uiState as UiState.Error).message)\n    }\n}\n```\n\n### Compose State (For UI-only state)\n- Use for temporary, UI-local state\n- Don't hoist to ViewModel\n- Lost on back navigation\n\n```kotlin\n@Composable\nfun SearchScreen(viewModel: SearchViewModel) {\n    var showFilters by remember { mutableStateOf(false) }  // UI-only\n    val searchResults by viewModel.searchResults.collectAsStateWithLifecycle()\n\n    SearchUI(\n        results = searchResults,\n        showFilters = showFilters,\n        onToggleFilters = { showFilters = !showFilters }\n    )\n}\n```\n\n**Key difference:** `collectAsStateWithLifecycle()` (in `androidx.lifecycle:lifecycle-runtime-compose`) collects only when the composable is in a STARTED state, avoiding memory leaks.\n\n## Common Anti-Patterns\n\n### State in Local Variables\n```kotlin\n// ❌ Lost on recomposition\n@Composable\nfun Counter() {\n    var count = 0  // Reset to 0 on every recomposition\n    Button(onClick = { count++ }) { Text(count.toString()) }\n}\n\n// ✅ Correct\n@Composable\nfun Counter() {\n    var count by remember { mutableIntStateOf(0) }\n    Button(onClick = { count++ }) { Text(count.toString()) }\n}\n```\n\n### Reading State in Wrong Scope\n```kotlin\n// ❌ Reads happen inside lambda; changes don't re-launch effect\nvar count by remember { mutableIntStateOf(0) }\nLaunchedEffect(Unit) {\n    while (true) {\n        delay(1000)\n        println(count)  // Always prints 0\n    }\n}\n\n// ✅ Pass state to LaunchedEffect key\nLaunchedEffect(count) {\n    println(\"Count changed: $count\")\n}\n```\n\n### Creating State in Lambdas\n```kotlin\n// ❌ Creates new state on every call\nval onButtonClick = {\n    val newValue = remember { mutableStateOf(0) }  // ERROR: Can't call remember in lambda\n}\n\n// ✅ Create state at composition level\nvar value by remember { mutableIntStateOf(0) }\nval onButtonClick = { value++ }\n```\n\n---\n\n**Source references:** `androidx.compose.runtime.State`, `androidx.compose.runtime.saveable`, `androidx.lifecycle.runtime.compose`\n\n---\n\n## produceState\n\nBridge between suspend functions and Compose state:\n\n```kotlin\n@Composable\nfun UserProfile(userId: String): State<User?> = produceState<User?>(initialValue = null, userId) {\n    value = repository.getUser(userId)\n}\n```\n\nUse when you need to convert a suspend function result into observable State. The coroutine is scoped to the composition and cancelled when the composable leaves.\n\nCan also observe flows:\n```kotlin\n@Composable\nfun NetworkStatus(): State<Boolean> = produceState(initialValue = false) {\n    connectivityManager.observeNetworkState().collect { value = it }\n}\n```\n\n---\n\n## rememberUpdatedState\n\nCapture latest callback value in long-running effects:\n\n```kotlin\n@Composable\nfun Timer(onTimeout: () -> Unit) {\n    val currentOnTimeout by rememberUpdatedState(onTimeout)\n    LaunchedEffect(true) {\n        delay(5000L)\n        currentOnTimeout() // Always calls the latest onTimeout, even if it changed\n    }\n}\n```\n\nUse when: a LaunchedEffect captures a callback that might change, but you don't want to restart the effect. Without `rememberUpdatedState`, the effect would use the stale original callback or need to restart on every callback change.\n\n---\n\n## Sealed UiState Pattern\n\n```kotlin\nsealed interface UiState<out T> {\n    data object Loading : UiState<Nothing>\n    data class Success<T>(val data: T) : UiState<T>\n    data class Error(val message: String) : UiState<Nothing>\n}\n```\n\nSmart-cast safety:\n```kotlin\n// BAD: smart cast can fail if uiState changes between check and usage\nif (uiState is UiState.Success) {\n    Content((uiState as UiState.Success).data) // Unsafe cast\n}\n\n// GOOD: val capture for safe smart cast\nwhen (val state = uiState) {\n    is UiState.Loading -> LoadingIndicator()\n    is UiState.Success -> Content(state.data) // Safe smart cast via val\n    is UiState.Error -> ErrorMessage(state.message)\n}\n```\n\n---\n\n## State Holder Class Pattern\n\nFor complex screens with multiple interrelated state values, create a state holder:\n\n```kotlin\n@Composable\nfun rememberSearchState(\n    listState: LazyListState = rememberLazyListState(),\n    coroutineScope: CoroutineScope = rememberCoroutineScope()\n): SearchState = remember(listState, coroutineScope) {\n    SearchState(listState, coroutineScope)\n}\n\n@Stable\nclass SearchState(\n    val listState: LazyListState,\n    private val coroutineScope: CoroutineScope\n) {\n    var query by mutableStateOf(\"\")\n        private set\n\n    val isScrolled: Boolean\n        get() = listState.firstVisibleItemIndex > 0\n\n    fun updateQuery(newQuery: String) { query = newQuery }\n    fun scrollToTop() { coroutineScope.launch { listState.animateScrollToItem(0) } }\n}\n```\n\nThis pattern (used by `rememberScrollState`, `rememberDrawerState`, etc.) groups related state and logic into a single class, avoiding parameter bloat in composables.\n\n---\n\n## Production State Rules\n\n### 1. mutableStateOf ONLY in composables, never in ViewModels\n\n```kotlin\n// BAD: Compose state in ViewModel couples VM to Compose runtime\nclass MyViewModel : ViewModel() {\n    var name by mutableStateOf(\"\") // Don't do this\n}\n\n// GOOD: StateFlow in ViewModel — framework-agnostic, testable\nclass MyViewModel : ViewModel() {\n    private val _name = MutableStateFlow(\"\")\n    val name = _name.asStateFlow()\n\n    fun updateName(new: String) { _name.value = new }\n}\n```\n\n### 2. SharedFlow for one-shot events, NOT Channel\n\n```kotlin\n// GOOD: SharedFlow with buffer for one-shot events\nprivate val _events = MutableSharedFlow<AppEvent>(extraBufferCapacity = 1)\nval events = _events.asSharedFlow()\n\n// Emit from ViewModel\nfun onAction() { _events.tryEmit(AppEvent.ShowSnackbar(\"Done\")) }\n\n// Collect in composable\nLaunchedEffect(Unit) {\n    viewModel.events.collect { event ->\n        when (event) {\n            is AppEvent.ShowSnackbar -> snackbarHostState.showSnackbar(event.message)\n            is AppEvent.Navigate -> onNavigate(event.route)\n        }\n    }\n}\n```\n\n### 3. rememberSaveable only at NavGraph level\n\nUse `rememberSaveable` for screen-level state (search query, tab selection) at the NavGraph entry point, not deep inside composable trees where it adds unnecessary persistence overhead.\n\n### 4. snapshotFlow + distinctUntilChanged() for reactive scroll\n\n```kotlin\nLaunchedEffect(listState) {\n    snapshotFlow { listState.firstVisibleItemIndex }\n        .distinctUntilChanged()\n        .collect { index -> viewModel.onScrollPositionChanged(index) }\n}\n```\n\n### 5. .stateIn() with .map() for derived flows\n\n```kotlin\nval filteredItems = repository.items\n    .map { items -> items.filter { it.isActive } }\n    .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())\n```\n\n---\n\n## Compose Multiplatform Notes\n\n### rememberSaveable and Bundle\n\n`rememberSaveable`, `Bundle`, and `@Parcelize` are **Android-only**. On CMP targets:\n\n```kotlin\n// Android: @Parcelize works\n@Parcelize\ndata class SearchParams(val query: String, val filters: List<String>) : Parcelable\n\n// CMP: use @Serializable instead\n@Serializable\ndata class SearchParams(val query: String, val filters: List<String>)\n```\n\nFor state persistence across configuration changes in CMP, use kotlinx.serialization-based custom `Saver` implementations.\n\n### collectAsStateWithLifecycle\n\n`collectAsStateWithLifecycle()` is in `androidx.lifecycle:lifecycle-runtime-compose` -- it's Android-specific.\n\n```kotlin\n// Android: lifecycle-aware, stops collecting when paused\nval state by viewModel.uiState.collectAsStateWithLifecycle()\n\n// CMP commonMain: basic collection, does NOT stop in background\nval state by viewModel.uiState.collectAsState()\n\n// CMP with multiplatform lifecycle (lifecycle-runtime-compose:2.10.0+):\n// collectAsStateWithLifecycle() available in commonMain\n```\n\nOn CMP without the multiplatform lifecycle library, flows continue collecting when the app is backgrounded -- be aware of battery and performance implications.\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/styles-experimental.md",
    "content": "# Compose Styles API (Experimental)\n\n> `@ExperimentalFoundationStyleApi` — `androidx.compose.foundation:foundation:1.11.0-alpha06`\n>\n> AOSP source: `compose/foundation/foundation/src/commonMain/kotlin/androidx/compose/foundation/style/`\n\n## What is the Styles API?\n\nA declarative, state-driven styling system for Compose. Instead of manually chaining modifiers\nand `animateXAsState` calls for every interaction state, you declare all visual states in a\nsingle `Style { }` block. The framework handles state detection, property interpolation, and\nanimation automatically.\n\n### Before vs After\n\n```kotlin\n// BEFORE — 15+ lines of imperative state wiring\nval interactionSource = remember { MutableInteractionSource() }\nval isPressed by interactionSource.collectIsPressedAsState()\nval bgColor by animateColorAsState(\n    if (isPressed) Color.DarkBlue else Color.Blue\n)\nval scale by animateFloatAsState(\n    if (isPressed) 0.95f else 1f\n)\nBox(\n    Modifier\n        .graphicsLayer { scaleX = scale; scaleY = scale }\n        .background(bgColor, RoundedCornerShape(16.dp))\n        .clip(RoundedCornerShape(16.dp))\n        .clickable(interactionSource = interactionSource, indication = null) { }\n        .padding(16.dp)\n)\n\n// AFTER — Declarative. Done.\nval style = Style {\n    background(Color.Blue)\n    shape(RoundedCornerShape(16.dp))\n    contentPadding(16.dp)\n    pressed(Style {\n        animate(Style {\n            background(Color.DarkBlue)\n            scale(0.95f)\n        })\n    })\n}\nBox(Modifier.styleable(styleState = styleState, style = style))\n```\n\nThe mental shift: **stop telling Compose how to animate between states**. Declare what each\nstate looks like — the framework interpolates.\n\n---\n\n## The Three Pieces\n\n### 1. `Style { }` — Declare Visual States\n\nA `Style` is a `fun interface`. You use the builder DSL:\n\n```kotlin\nval cardStyle = Style {\n    // Base properties (always applied)\n    background(Color(0xFFF5F5F5))\n    shape(RoundedCornerShape(12.dp))\n    contentPadding(16.dp)\n\n    // State overrides — only applied when state is active\n    selected(Style {\n        animate(Style {\n            background(Color.Blue.copy(alpha = 0.15f))\n            borderWidth(2.dp)\n            borderColor(Color.Blue)\n        })\n    })\n\n    disabled(Style {\n        background(Color(0xFFE0E0E0))\n        contentColor(Color.Gray)  // no animate = instant snap\n    })\n}\n```\n\n`animate(Style { })` wraps properties that should interpolate smoothly.\nWithout `animate`, state changes snap immediately.\n\n### 2. `MutableStyleState` — Drive State\n\n```kotlin\n// For toggle states (checked, selected, enabled) — set explicitly:\nval styleState = remember { MutableStyleState(MutableInteractionSource()) }\nstyleState.isChecked = isChecked\nstyleState.isSelected = isSelected\nstyleState.isEnabled = isEnabled\n\n// For interaction states (pressed, hovered, focused) — share interactionSource:\nval interactionSource = remember { MutableInteractionSource() }\nval styleState = remember { MutableStyleState(interactionSource) }\n// isPressed, isHovered, isFocused auto-track from shared interactionSource\n```\n\n### 3. `Modifier.styleable()` — Apply to Any Composable\n\n```kotlin\nBox(\n    Modifier\n        .styleable(styleState = styleState, style = cardStyle)\n        .clickable(interactionSource = interactionSource, indication = null) { }\n)\n```\n\nBackground renders, shape clips, borders draw, transforms apply, text properties propagate\nto children via CompositionLocal. All animated.\n\n---\n\n## CRITICAL: Alpha06 Auto-Detection is Broken\n\n**`styleable(style = myStyle)` without an explicit `styleState` does NOT detect interaction\nstates from sibling modifiers.** This is the single biggest trap in alpha06.\n\n### What DOESN'T work:\n\n```kotlin\n// Compiles. Renders base style. State changes are SILENT.\nBox(\n    Modifier\n        .styleable(style = myStyle)           // no styleState!\n        .toggleable(value = isChecked, ...)   // style never sees this\n)\n```\n\n### What DOES work:\n\n**Pattern A — Toggle states (checked, selected, enabled):**\n```kotlin\nval styleState = remember { MutableStyleState(MutableInteractionSource()) }\nstyleState.isChecked = isChecked  // YOU drive the state\n\nBox(\n    Modifier\n        .styleable(styleState = styleState, style = myStyle)\n        .clickable { isChecked = !isChecked }\n)\n```\n\n**Pattern B — Interaction states (pressed, hovered, focused):**\n```kotlin\nval interactionSource = remember { MutableInteractionSource() }\nval styleState = remember { MutableStyleState(interactionSource) }\n\nBox(\n    Modifier\n        .styleable(styleState = styleState, style = myStyle)\n        .clickable(\n            interactionSource = interactionSource,  // same instance!\n            indication = null,\n        ) { }\n)\n```\n\n**Pattern C — Both (toggle button with press feedback):**\n```kotlin\nval interactionSource = remember { MutableInteractionSource() }\nval styleState = remember { MutableStyleState(interactionSource) }\nstyleState.isChecked = isChecked  // explicit for toggle\n\nBox(\n    Modifier\n        .styleable(styleState = styleState, style = myStyle)\n        .clickable(\n            interactionSource = interactionSource,\n            indication = null,\n        ) { isChecked = !isChecked }\n)\n```\n\n**Rule: always pass `styleState` to `styleable()`.**\n\n---\n\n## Text Property Propagation Gotcha\n\n`contentColor()`, `fontSize()`, `fontWeight()`, `letterSpacing()`, `textDecoration()`, and\nother text properties propagate to ALL child composables inside the styleable box via\n`CompositionLocal` (`LocalContentColor`, `LocalTextStyle`).\n\n### Problem:\n```kotlin\n// fontSize(28.sp) from the Style applies to BOTH texts!\nBox(Modifier.styleable(style = Style { fontSize(28.sp) })) {\n    Text(\"Title\")      // 28sp\n    Text(\"Subtitle\")   // also 28sp — overlap!\n}\n```\n\n### Fix:\nUse a single `Text` inside styled boxes when style sets text properties. Move\ndescriptions outside the styleable scope:\n\n```kotlin\nText(\"Description goes here\")  // outside the styled box\nBox(Modifier.styleable(style = gradientStyle)) {\n    Text(\"Title Only\")  // only this gets styled\n}\n```\n\n---\n\n## Verified Properties (alpha06, tested on device)\n\n| Property | Works? | Notes |\n|----------|--------|-------|\n| `background(Color)` | Yes | Fills behind content |\n| `background(Brush)` | Yes | Gradient backgrounds |\n| `shape(Shape)` | Yes | Clips content + background |\n| `contentPadding(Dp)` | Yes | Inner padding |\n| `borderWidth(Dp) + borderColor(Color)` | Yes | Must set both |\n| `scale(Float)` | Yes | graphicsLayer transform |\n| `rotationZ(Float)` | Yes | graphicsLayer rotation |\n| `translationX/Y(Float)` | Yes | graphicsLayer offset |\n| `alpha(Float)` | Yes | Opacity |\n| `contentColor(Color)` | Yes | Propagates to child Text/Icon |\n| `contentBrush(Brush)` | Yes | Gradient text |\n| `fontSize(TextUnit)` | Yes | Propagates to children |\n| `fontWeight(FontWeight)` | Yes | Propagates to children |\n| `letterSpacing(TextUnit)` | Yes | Propagates to children |\n| `textDecoration(TextDecoration)` | Yes | Underline, strikethrough |\n| `animate(Style { })` | Yes | Smooth spring interpolation |\n| `dropShadow(Shadow)` | No | `Shadow` constructor is internal |\n\n---\n\n## Style Composition\n\nStyles compose with `.then()` — later styles override earlier ones per-property:\n\n```kotlin\nval base = Style {\n    background(Color.Blue)\n    shape(RoundedCornerShape(12.dp))\n    contentPadding(16.dp)\n}\n\nval elevated = Style {\n    borderWidth(2.dp)\n    borderColor(Color.LightGray)\n    scale(1.02f)\n}\n\nval dark = Style {\n    background(Color(0xFF1E1E2E))  // overrides base's background\n    contentColor(Color.White)\n}\n\n// Chained:\nval composed = base.then(elevated).then(dark)\n\n// Factory (equivalent):\nval composed = Style(base, elevated, dark)\n```\n\n---\n\n## Building Reusable Components\n\nThe Styles API maps to Compose's component conventions. The `style` parameter becomes\nfirst-class, like `modifier`:\n\n```kotlin\n// 1. Defaults object — theme-aware default style\n@OptIn(ExperimentalFoundationStyleApi::class)\nobject StyledChipDefaults {\n    @Composable\n    fun style(): Style {\n        val bg = MaterialTheme.colorScheme.secondaryContainer\n        val fg = MaterialTheme.colorScheme.onSecondaryContainer\n        return Style {\n            background(bg)\n            shape(RoundedCornerShape(8.dp))\n            contentPadding(horizontal = 16.dp, vertical = 8.dp)\n            contentColor(fg)\n            pressed(Style {\n                animate(Style { scale(0.95f) })\n            })\n        }\n    }\n}\n\n// 2. Component — style as parameter with default\n@Composable\nfun StyledChip(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    style: Style = StyledChipDefaults.style(),\n    content: @Composable () -> Unit,\n) {\n    val interactionSource = remember { MutableInteractionSource() }\n    val styleState = remember { MutableStyleState(interactionSource) }\n\n    Box(\n        modifier = modifier\n            .styleable(styleState = styleState, style = style)\n            .clickable(\n                interactionSource = interactionSource,\n                indication = null,\n                onClick = onClick,\n            ),\n        contentAlignment = Alignment.Center,\n    ) {\n        content()\n    }\n}\n\n// 3. Usage — default, custom, or composed\nStyledChip(onClick = {}) { Text(\"Default\") }\n\nStyledChip(\n    onClick = {},\n    style = Style {\n        background(Color.Teal)\n        shape(CircleShape)\n        contentColor(Color.Black)\n    },\n) { Text(\"Custom\") }\n\nStyledChip(\n    onClick = {},\n    style = StyledChipDefaults.style().then(Style {\n        borderWidth(2.dp)\n        borderColor(Color.Teal)\n    }),\n) { Text(\"Composed\") }\n```\n\n---\n\n## Theme Integration\n\n`StyleScope` extends `CompositionLocalAccessorScope`, so Style blocks can read\n`MaterialTheme` values at resolution time:\n\n```kotlin\n@Composable\nfun ThemedButton() {\n    val primary = MaterialTheme.colorScheme.primary\n    val onPrimary = MaterialTheme.colorScheme.onPrimary\n    val surface = MaterialTheme.colorScheme.surface\n\n    val style = Style {\n        background(primary)\n        contentColor(onPrimary)\n        shape(RoundedCornerShape(12.dp))\n        contentPadding(16.dp)\n        pressed(Style {\n            animate(Style {\n                background(surface)\n                contentColor(primary)\n                scale(0.95f)\n            })\n        })\n    }\n    // When theme changes (dark/light), style re-resolves automatically\n}\n```\n\nCapture theme colors in a `@Composable` scope, use in the Style builder. Theme switches\nupdate all styled elements instantly.\n\n---\n\n## Architecture: How It Works\n\nThe API lives in 7 source files under `androidx.compose.foundation.style`:\n\n| File | Purpose |\n|------|---------|\n| `Style.kt` | `fun interface Style` + composition operators |\n| `StyleScope.kt` | ~50 property functions |\n| `StyleState.kt` | `StyleState` interface + `MutableStyleState` |\n| `StyleModifier.kt` | `Modifier.styleable()` implementation |\n| `StyleAnimations.kt` | `animate()` blocks |\n| `ResolvedStyle.kt` | Property resolution with bitset flagging |\n| `ExperimentalFoundationStyleApi.kt` | Opt-in annotation |\n\n### Two-Node System\n\n`Modifier.styleable()` inserts two modifier nodes:\n\n- **`StyleOuterNode`** — Layout (padding, sizing), drawing (background, border, shape),\n  transforms (scale, rotation, translation, alpha). Can invalidate at draw layer only when\n  transform/draw properties change — no recomposition.\n\n- **`StyleInnerNode`** — Content padding and text style propagation. Sets `LocalContentColor`,\n  `LocalTextStyle`, etc. so child `Text` and `Icon` composables pick up styled colors/fonts.\n\n### Bitset-Based Property Tracking\n\n`ResolvedStyle` uses bitset flags for ~50 properties. On state change:\n\n1. Only the delta between old and new resolved properties is computed\n2. Drawing-only changes (background, border, alpha) → **draw-only invalidation** (skips layout + composition)\n3. Layout changes (padding, sizing) → layout invalidation\n4. Text changes (contentColor, fontSize) → composition invalidation (updates CompositionLocals)\n\nA press animation changing only `scale` and `background` never triggers recomposition.\n\n---\n\n## All StyleScope Properties\n\n### Layout\n- `contentPadding(Dp)`, `contentPadding(horizontal, vertical)`, `contentPadding(start, top, end, bottom)`\n- `externalPadding(Dp)` and same variants\n- `width(Dp)`, `height(Dp)`, `size(Dp)`, `size(width, height)`\n- `minWidth/minHeight/maxWidth/maxHeight(Dp)`\n- `fillWidth()`, `fillHeight()`, `fillSize()`\n\n### Drawing\n- `background(Color)`, `background(Brush)`\n- `foreground(Color)`, `foreground(Brush)`\n- `shape(Shape)`\n- `borderWidth(Dp)`, `borderColor(Color)`, `borderBrush(Brush)`\n- `border(width, color)`, `border(width, brush)`\n\n### Transforms\n- `scale(Float)`, `scaleX(Float)`, `scaleY(Float)`\n- `rotationX(Float)`, `rotationY(Float)`, `rotationZ(Float)`\n- `translationX(Float)`, `translationY(Float)`, `translation(x, y)`\n- `alpha(Float)`, `clip(Boolean)`, `zIndex(Float)`\n- `transformOrigin(TransformOrigin)`\n\n### Text & Content\n- `contentColor(Color)`, `contentBrush(Brush)`\n- `fontSize(TextUnit)`, `fontWeight(FontWeight)`, `fontStyle(FontStyle)`\n- `letterSpacing(TextUnit)`, `lineHeight(TextUnit)`\n- `textDecoration(TextDecoration)`, `fontFamily(FontFamily)`\n- `textAlign(TextAlign)`, `textDirection(TextDirection)`\n- `textStyle(TextStyle)`, `textIndent(TextIndent)`\n- `baselineShift(BaselineShift)`, `lineBreak(LineBreak)`\n- `hyphens(Hyphens)`, `fontSynthesis(FontSynthesis)`\n\n### Shadows (internal constructor in alpha06)\n- `dropShadow(Shadow)`, `innerShadow(Shadow)`\n\n### State Functions\n- `pressed(Style)`, `hovered(Style)`, `focused(Style)`\n- `selected(Style)`, `checked(Style)`, `disabled(Style)`\n\n### Animation\n- `animate(Style)` — default spring\n- `animate(spec: AnimationSpec<Float>, Style)` — custom spec\n- `animate(toSpec, fromSpec, Style)` — asymmetric enter/exit\n\n### Composition\n- `Style.then(other: Style)` — chain (later overrides)\n- `Style(style1, style2)` — merge factory\n- `Style(vararg styles)` — merge multiple\n\n---\n\n## Common Pitfalls\n\n1. **Forgetting `styleState`** — the #1 bug. Style renders but never reacts to state.\n2. **Not sharing `interactionSource`** — pressed/hovered/focused won't track without it.\n3. **Multiple Text children in styled box** — all inherit fontSize/fontWeight/contentColor.\n4. **Using `toggleable()` / `selectable()`** — they create their own interactionSource internally. Use `.clickable()` and set state explicitly on `MutableStyleState`.\n5. **Missing `@OptIn(ExperimentalFoundationStyleApi::class)`** — required on all usages.\n6. **Trying to use `dropShadow()`** — `Shadow` constructor is internal in alpha06, won't compile.\n7. **No `indication = null` on clickable** — without it you get default ripple on top of your styled feedback.\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/theming-material3.md",
    "content": "# Material 3 Theming Reference\n\n## MaterialTheme Basics\n\n`MaterialTheme` is the root provider for design tokens in Compose Material 3. It establishes `colorScheme`, `typography`, and `shapes` across your app.\n\n```kotlin\n@Composable\nfun MyApp() {\n    MaterialTheme(\n        colorScheme = lightColorScheme(),\n        typography = Typography(),\n        shapes = Shapes()\n    ) {\n        // All descendants access tokens via MaterialTheme\n        Scaffold {\n            Text(\"Uses MaterialTheme.typography.bodyLarge\")\n        }\n    }\n}\n```\n\n**Source**: `androidx/compose/material3/MaterialTheme.kt`\n\n---\n\n## ColorScheme — Light and Dark\n\nA `ColorScheme` bundles 29+ semantic color tokens (primary, secondary, error, surface, etc.).\n\n### Default Light/Dark Schemes\n\n```kotlin\n// Light (default)\nval lightColors = lightColorScheme(\n    primary = Color(0xFF6200EE),\n    secondary = Color(0xFF03DAC6)\n)\n\n// Dark\nval darkColors = darkColorScheme(\n    primary = Color(0xFFBB86FC),\n    secondary = Color(0xFF03DAC6)\n)\n\nMaterialTheme(colorScheme = if (isDark) darkColors else lightColors) { ... }\n```\n\n### Dynamic Color (Material You)\n\nAndroid 12+ supports extracting colors from wallpaper. Check `Build.VERSION.SDK_INT` before calling:\n\n```kotlin\nval colorScheme = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {\n    val context = LocalContext.current\n    if (isDark) {\n        dynamicDarkColorScheme(context)\n    } else {\n        dynamicLightColorScheme(context)\n    }\n} else {\n    if (isDark) darkColorScheme() else lightColorScheme()\n}\n\nMaterialTheme(colorScheme = colorScheme) { ... }\n```\n\nThis requires `android:READ_MEDIA_IMAGES` or context access. `dynamicColorScheme` APIs are in `androidx.compose.material3`.\n\n---\n\n## Typography — Custom Type Scales\n\n`Typography` defines `displayLarge`, `headlineSmall`, `bodyLarge`, `labelSmall`, etc.\n\n### Using Google Fonts\n\n```kotlin\nval Poppins = FontFamily(\n    Font(R.font.poppins_regular, weight = FontWeight.Normal),\n    Font(R.font.poppins_bold, weight = FontWeight.Bold),\n    Font(R.font.poppins_italic, weight = FontWeight.Normal, style = FontStyle.Italic)\n)\n\nval customTypography = Typography(\n    displayLarge = TextStyle(\n        fontFamily = Poppins,\n        fontSize = 57.sp,\n        lineHeight = 64.sp,\n        letterSpacing = (-0.25).sp\n    ),\n    bodyMedium = TextStyle(\n        fontFamily = Poppins,\n        fontSize = 14.sp,\n        lineHeight = 20.sp\n    )\n)\n\nMaterialTheme(typography = customTypography) { ... }\n```\n\nAll M3 type styles follow a 15-level scale. Partial overrides keep defaults for unspecified styles.\n\n---\n\n## Shapes — Corner Radius Customization\n\n`Shapes` defines `extraSmall`, `small`, `medium`, `large`, `extraLarge` corner radii.\n\n```kotlin\nval customShapes = Shapes(\n    extraSmall = RoundedCornerShape(4.dp),\n    small = RoundedCornerShape(8.dp),\n    medium = RoundedCornerShape(12.dp),\n    large = RoundedCornerShape(16.dp),\n    extraLarge = RoundedCornerShape(28.dp)\n)\n\nMaterialTheme(shapes = customShapes) { ... }\n\n// Use in components\nButton(\n    modifier = Modifier.clip(MaterialTheme.shapes.large)\n) { ... }\n```\n\nComponents automatically use theme shapes via `Surface` and `Card`.\n\n---\n\n## Dark Theme\n\n### isSystemInDarkTheme()\n\nCheck system dark mode setting:\n\n```kotlin\n@Composable\nfun MyApp() {\n    val isDark = isSystemInDarkTheme()\n    MaterialTheme(colorScheme = if (isDark) darkColorScheme() else lightColorScheme()) {\n        // Content\n    }\n}\n```\n\n### Manual Toggle with Persistence\n\nFor user-selectable dark mode:\n\n```kotlin\nval darkModeState = rememberSaveable { mutableStateOf(isSystemInDarkTheme()) }\n\nMaterialTheme(colorScheme = if (darkModeState.value) darkColorScheme() else lightColorScheme()) {\n    Scaffold(\n        floatingActionButton = {\n            FloatingActionButton(onClick = { darkModeState.value = !darkModeState.value }) {\n                Icon(Icons.Default.Settings, \"Toggle theme\")\n            }\n        }\n    ) {\n        // Content\n    }\n}\n```\n\nPersist selection via DataStore or SharedPreferences.\n\n---\n\n## Component-Level Styling\n\nUse `MaterialTheme` tokens for colors, not hardcoded values:\n\n```kotlin\n// DO\nText(\n    text = \"Hello\",\n    color = MaterialTheme.colorScheme.onSurface,\n    style = MaterialTheme.typography.bodyLarge\n)\n\n// DON'T\nText(text = \"Hello\", color = Color.Black, fontSize = 14.sp)\n```\n\nCommon tokens:\n- `primary`, `secondary`, `tertiary` — accent colors\n- `surface`, `surfaceVariant` — container backgrounds\n- `onPrimary`, `onSurface`, `onError` — text/content on colored backgrounds\n- `error`, `errorContainer` — error states\n\n---\n\n## Surface vs Box\n\n**Surface**: styled container with elevation, background from `colorScheme.surface`, respects theme.\n\n```kotlin\nSurface(\n    color = MaterialTheme.colorScheme.surface,\n    modifier = Modifier.fillMaxWidth()\n) {\n    // Has elevation, shadow\n    Text(\"Themed container\")\n}\n```\n\n**Box**: plain container, no theming assumptions.\n\n```kotlin\nBox(\n    modifier = Modifier\n        .fillMaxWidth()\n        .background(MaterialTheme.colorScheme.surface)\n) {\n    // Manual styling\n    Text(\"Manual background\")\n}\n```\n\nUse `Surface` for semantic containers (cards, dialogs). Use `Box` for layout grouping.\n\n---\n\n## Scaffold — Layout Integration\n\n`Scaffold` composes `topBar`, `floatingActionButton`, `snackbarHost`, and content with proper padding:\n\n```kotlin\nScaffold(\n    topBar = {\n        TopAppBar(\n            title = { Text(\"My App\") },\n            colors = TopAppBarDefaults.topAppBarColors(\n                containerColor = MaterialTheme.colorScheme.primaryContainer\n            )\n        )\n    },\n    floatingActionButton = {\n        FloatingActionButton(\n            onClick = { /* ... */ },\n            containerColor = MaterialTheme.colorScheme.tertiary\n        ) {\n            Icon(Icons.Default.Add, \"Add item\")\n        }\n    },\n    snackbarHost = { SnackbarHost(it) }\n) { innerPadding ->\n    LazyColumn(modifier = Modifier.padding(innerPadding)) {\n        // Content respects safe area\n    }\n}\n```\n\n`Scaffold` handles insets and spacing automatically. Don't nest `Scaffold` components.\n\n---\n\n## Extending Theme with CompositionLocal\n\nAdd custom design tokens:\n\n```kotlin\ndata class AppColors(\n    val brandPrimary: Color = Color(0xFF6200EE),\n    val brandSecondary: Color = Color(0xFF03DAC6),\n    val neutral: Color = Color.Gray\n)\n\nval LocalAppColors = compositionLocalOf { AppColors() }\n\n@Composable\nfun AppTheme(content: @Composable () -> Unit) {\n    val appColors = AppColors()\n    CompositionLocalProvider(LocalAppColors provides appColors) {\n        MaterialTheme {\n            content()\n        }\n    }\n}\n\n// Use custom tokens\n@Composable\nfun MyButton() {\n    Button(\n        colors = ButtonDefaults.buttonColors(\n            containerColor = LocalAppColors.current.brandPrimary\n        )\n    ) { }\n}\n```\n\n---\n\n## Anti-Patterns\n\n### Hardcoding Colors\n```kotlin\n// DON'T\nText(\"Hello\", color = Color(0xFF000000))\n\n// DO\nText(\"Hello\", color = MaterialTheme.colorScheme.onSurface)\n```\n\n### Ignoring Theme in Reusable Components\n```kotlin\n// DON'T\nfun MyCard(content: @Composable () -> Unit) {\n    Box(modifier = Modifier.background(Color.White))\n}\n\n// DO\nfun MyCard(content: @Composable () -> Unit) {\n    Surface(\n        color = MaterialTheme.colorScheme.surface,\n        shape = MaterialTheme.shapes.medium\n    ) {\n        content()\n    }\n}\n```\n\n### Mixing Material 2 and Material 3\nDon't import both `androidx.compose.material` and `androidx.compose.material3`. Choose M3 for new projects.\n\n### Not Providing All Theme Parameters\nPartial `MaterialTheme` calls may leave descendants with defaults:\n\n```kotlin\n// Unsafe if colorScheme varies by locale\nMaterialTheme(typography = customTypography) { ... }\n\n// Better\nMaterialTheme(\n    colorScheme = currentColorScheme,\n    typography = currentTypography,\n    shapes = currentShapes\n) { ... }\n```\n\n---\n\n## Resources\n\n- **Material 3 Tokens**: https://m3.material.io/\n- **Compose Material3 Docs**: https://developer.android.com/develop/ui/compose/designsystems/material3\n- **Dynamic Color**: Requires `androidx.compose.material3:material3` >= 1.1.0 and Android 12+\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/tv-compose.md",
    "content": "# Compose for TV (Android TV / Google TV)\n\nReference for building Android TV apps using Jetpack Compose with `androidx.tv:tv-material`\nand `androidx.tv:tv-foundation`. This is the modern replacement for Leanback — do **not** use\nLeanback for new TV projects.\n\nSource: `tv/tv-material/`, `tv/tv-foundation/` in `androidx/androidx` (branch: `androidx-main`)\n\n---\n\n## 1. Setup & Dependencies\n\n### Gradle\n\n```kotlin\ndependencies {\n    val composeBom = platform(\"androidx.compose:compose-bom:2026.03.00\")\n    implementation(composeBom)\n\n    // General Compose\n    implementation(\"androidx.activity:activity-compose:1.13.0\")\n    implementation(\"androidx.compose.ui:ui-tooling-preview\")\n    debugImplementation(\"androidx.compose.ui:ui-tooling\")\n\n    // Compose for TV — use INSTEAD of androidx.compose.material3:material3\n    implementation(\"androidx.tv:tv-material:1.1.0-rc01\")\n\n    // TV Foundation — only needed if using BringIntoViewSpec customization\n    // Standard LazyRow/LazyColumn from compose.foundation work out-of-the-box since 1.7.0\n    implementation(\"androidx.tv:tv-foundation:1.0.0-rc01\")\n\n    // Optional: TVProvider for home screen channels\n    implementation(\"androidx.tvprovider:tvprovider:1.1.0\")\n}\n```\n\n### Compatibility\n\n| Requirement | Value |\n|-------------|-------|\n| Min API level | 21 (Android 5.0) — library minimum; practical Google TV / Android TV device minimum is API 23–28 in production |\n| Compose BOM | 2026.03.00+ |\n| Kotlin | 2.0+ (KGP 2.0.0+ required for consumption) |\n| tv-material stable | 1.0.0 (first stable August 2024) |\n| tv-material latest | 1.1.0-rc01 |\n| tv-foundation latest | 1.0.0-rc01 |\n\n### AndroidManifest.xml\n\n```xml\n<application>\n    <activity\n        android:name=\".MainActivity\"\n        android:exported=\"true\"\n        android:banner=\"@drawable/banner\">\n        <intent-filter>\n            <action android:name=\"android.intent.action.MAIN\" />\n            <category android:name=\"android.intent.category.LEANBACK_LAUNCHER\" />\n        </intent-filter>\n    </activity>\n</application>\n\n<!-- Declare it's a TV app -->\n<uses-feature android:name=\"android.software.leanback\" android:required=\"true\" />\n<!-- TV has no touchscreen -->\n<uses-feature android:name=\"android.hardware.touchscreen\" android:required=\"false\" />\n```\n\n---\n\n## 2. TV Material3 vs Mobile Material3\n\n**Use `androidx.tv.material3` instead of `androidx.compose.material3` for TV apps.**\n\n| TV (`androidx.tv.*`) | Mobile (`androidx.compose.*`) | Notes |\n|----------------------|------------------------------|-------|\n| `androidx.tv:tv-material` | `androidx.compose.material3:material3` | TV variant has focus-aware indications |\n| `androidx.tv.material3.Surface` | `androidx.compose.material3.Surface` | TV Surface supports Border, Glow, Scale per state |\n| `androidx.tv.material3.Button` | `androidx.compose.material3.Button` | TV Button has focus scale/glow/border |\n| `androidx.tv.material3.Card` | `androidx.compose.material3.Card` | TV Card has 5+ variants for media |\n| `androidx.tv.material3.MaterialTheme` | `androidx.compose.material3.MaterialTheme` | Separate theming — don't mix |\n\n> **Never mix** mobile `MaterialTheme` with TV `MaterialTheme`. Each library defines its own\n> `MaterialTheme` object — using both causes inconsistent colors, typography, and shapes.\n\n---\n\n## 3. Component Catalog\n\n### Surfaces (Building Blocks)\n\n`Surface` is the foundational TV composable — all interactive components build on it.\nTV Surface supports per-state customization of four visual indications:\n\n| Indication | Type | Purpose |\n|------------|------|---------|\n| **Scale** | `Float` | Enlarges element on focus (default: 1.0 → 1.1x) |\n| **Border** | `Border` | Draws a border around the element on focus |\n| **Glow** | `Glow` | Adds a diffused shadow/glow (API 28+ only) |\n| **Shape** | `Shape` | Changes shape on focus/press |\n\nThree Surface variants:\n\n```kotlin\n// 1. Non-interactive (display only)\nSurface(\n    modifier = Modifier.size(200.dp),\n    colors = SurfaceDefaults.colors(\n        containerColor = MaterialTheme.colorScheme.surface\n    ),\n    shape = RoundedCornerShape(8.dp)\n) {\n    Text(\"Static content\")\n}\n\n// 2. Clickable (buttons, cards, etc.)\nSurface(\n    onClick = { /* handle click */ },\n    modifier = Modifier.size(200.dp),\n    scale = ClickableSurfaceDefaults.scale(\n        focusedScale = 1.05f\n    ),\n    border = ClickableSurfaceDefaults.border(\n        focusedBorder = Border(\n            border = BorderStroke(2.dp, Color.White),\n            shape = RoundedCornerShape(8.dp)\n        )\n    ),\n    glow = ClickableSurfaceDefaults.glow(\n        focusedGlow = Glow(\n            elevationColor = Color.White.copy(alpha = 0.5f),\n            elevation = 8.dp\n        )\n    )\n) {\n    Text(\"Clickable\")\n}\n\n// 3. Selectable (toggles, radio-like selection)\nvar selected by remember { mutableStateOf(false) }\nSurface(\n    selected = selected,\n    onClick = { selected = !selected },\n    modifier = Modifier.size(200.dp),\n    scale = SelectableSurfaceDefaults.scale(\n        focusedScale = 1.05f,\n        selectedScale = 1.02f\n    )\n) {\n    Text(if (selected) \"Selected\" else \"Unselected\")\n}\n```\n\n### Cards\n\nTV provides five card variants for media content:\n\n| Component | Layout | Use Case |\n|-----------|--------|----------|\n| `Card` | Basic container with click | Simple content card |\n| `ClassicCard` | Image + title + subtitle + description | Standard media card |\n| `CompactCard` | Image with overlay text | Space-efficient card |\n| `WideClassicCard` | Horizontal image + text | Landscape media card |\n| `StandardCardContainer` | Image above + content below | Catalog grid items |\n| `WideCardContainer` | Image left + content right | List detail items |\n\n```kotlin\n// Basic Card\nCard(\n    onClick = { /* navigate to detail */ },\n    modifier = Modifier.size(width = 180.dp, height = 100.dp)\n) {\n    AsyncImage(\n        model = movie.thumbnailUrl,\n        contentDescription = movie.title,\n        contentScale = ContentScale.Crop,\n        modifier = Modifier.fillMaxSize()\n    )\n}\n\n// ClassicCard — image + metadata slots\nClassicCard(\n    onClick = { /* navigate */ },\n    image = {\n        AsyncImage(\n            model = movie.posterUrl,\n            contentDescription = null,\n            contentScale = ContentScale.Crop,\n            modifier = Modifier.size(width = 150.dp, height = 200.dp)\n        )\n    },\n    title = { Text(movie.title) },\n    subtitle = { Text(movie.year.toString()) },\n    description = { Text(movie.description, maxLines = 2) }\n)\n\n// StandardCardContainer — layout wrapper (image top, content below)\n// Note: as of tv-material 1.0.0 stable, interactionSource is managed internally by the card.\n// The imageCard slot is a plain @Composable lambda with no interactionSource parameter.\nStandardCardContainer(\n    imageCard = {\n        Card(\n            onClick = { /* navigate */ }\n        ) {\n            AsyncImage(\n                model = movie.thumbnailUrl,\n                contentDescription = movie.title,\n                contentScale = ContentScale.Crop,\n                modifier = Modifier.size(width = 180.dp, height = 100.dp)\n            )\n        }\n    },\n    title = { Text(movie.title, maxLines = 1) }\n)\n```\n\n### Carousel\n\nDisplays featured content in an auto-scrolling rotator with D-pad navigation.\n\n```kotlin\n@Composable\nfun FeaturedCarousel(\n    featuredContent: List<Movie>,\n    modifier: Modifier = Modifier,\n) {\n    Carousel(\n        itemCount = featuredContent.size,\n        modifier = modifier\n            .fillMaxWidth()\n            .height(376.dp),\n        // Optional: remember state to control or observe active item\n        // carouselState = rememberCarouselState(),\n        // autoScrollDurationMillis = CarouselDefaults.TimeToDisplayItemMillis (5000ms)\n    ) { index -> // this: AnimatedContentScope — use Modifier.animateEnterExit() inside here\n        val movie = featuredContent[index]\n        Box(modifier = Modifier.fillMaxSize()) {\n            AsyncImage(\n                model = movie.backgroundImageUrl,\n                contentDescription = movie.description,\n                contentScale = ContentScale.Crop,\n                modifier = Modifier.fillMaxSize()\n            )\n            Column(\n                modifier = Modifier\n                    .align(Alignment.BottomStart)\n                    .padding(32.dp)\n            ) {\n                Text(\n                    text = movie.title,\n                    style = MaterialTheme.typography.headlineLarge\n                )\n                Text(\n                    text = movie.description,\n                    style = MaterialTheme.typography.bodyMedium,\n                    maxLines = 2\n                )\n                // Animate foreground content entry with AnimatedContentScope\n                Button(\n                    onClick = { /* play */ },\n                    modifier = Modifier\n                        .animateEnterExit(\n                            enter = fadeIn() + slideInHorizontally(),\n                            exit = fadeOut() + slideOutHorizontally()\n                        )\n                ) {\n                    Text(\"Watch Now\")\n                }\n            }\n        }\n    }\n}\n```\n\nKey points:\n- `CarouselState` controls which item is shown; use `rememberCarouselState()` to persist\n- Auto-scroll pauses automatically when the user interacts via D-pad — there is no public API to pause/resume it programmatically (`ScrollPauseHandle` is internal)\n- Content inside the carousel lambda receives an `AnimatedContentScope` — use `Modifier.animateEnterExit()` for slide/fade effects\n- Custom slide transitions via `contentTransformStartToEnd` and `contentTransformEndToStart` parameters\n\n### Buttons\n\n```kotlin\n// Standard filled button\nButton(onClick = { /* action */ }) {\n    Text(\"Play\")\n}\n\n// Outlined button\nOutlinedButton(onClick = { /* action */ }) {\n    Text(\"Add to List\")\n}\n\n// Icon button\nIconButton(onClick = { /* action */ }) {\n    Icon(Icons.Default.Search, contentDescription = \"Search\")\n}\n\n// Wide button (full-width with icon + text + subtitle)\n// Note: WideButton is available in tv-material 1.1.0-rc01+. Verify availability before use.\nWideButton(\n    onClick = { /* action */ },\n    title = { Text(\"Continue Watching\") },\n    subtitle = { Text(\"Episode 3 — 45 min remaining\") },\n    icon = { Icon(Icons.Default.PlayArrow, null) }\n)\n```\n\n### Navigation: Drawer & Tabs\n\nTwo patterns for top-level navigation:\n\n**Side navigation with `NavigationDrawer`:**\n\n```kotlin\n@Composable\nfun TvApp() {\n    val drawerState = rememberDrawerState(DrawerValue.Closed)\n    val selectedItem = remember { mutableIntStateOf(0) }\n    val items = listOf(\"Home\", \"Movies\", \"Shows\", \"Settings\")\n\n    NavigationDrawer(\n        drawerState = drawerState,\n        drawerContent = {\n            items.forEachIndexed { index, label ->\n                NavigationDrawerItem(\n                    selected = selectedItem.intValue == index,\n                    onClick = { selectedItem.intValue = index },\n                    leadingContent = {\n                        Icon(\n                            imageVector = when (index) {\n                                0 -> Icons.Default.Home\n                                1 -> Icons.Default.Movie\n                                2 -> Icons.Default.Tv\n                                else -> Icons.Default.Settings\n                            },\n                            contentDescription = null\n                        )\n                    }\n                ) {\n                    Text(label)\n                }\n            }\n        }\n    ) {\n        // Main content area\n        when (selectedItem.intValue) {\n            0 -> HomeScreen()\n            1 -> MoviesScreen()\n            2 -> ShowsScreen()\n            3 -> SettingsScreen()\n        }\n    }\n}\n```\n\n- `NavigationDrawer` — always visible at screen edge, collapses when focus moves to content\n- `ModalNavigationDrawer` — overlays content with a scrim, use for secondary nav\n- `NavigationDrawerScope.doesNavigationDrawerHaveFocus` — check if drawer has focus to expand/collapse items\n\n**Top navigation with `TabRow`:**\n\n```kotlin\n@Composable\nfun TopNavigation() {\n    var selectedTab by remember { mutableIntStateOf(0) }\n    val tabs = listOf(\"Home\", \"Movies\", \"Shows\")\n\n    Column {\n        TabRow(selectedTabIndex = selectedTab) {\n            tabs.forEachIndexed { index, title ->\n                Tab(\n                    selected = selectedTab == index,\n                    onFocus = { selectedTab = index }, // TV tabs activate on focus\n                ) {\n                    Text(\n                        text = title,\n                        modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)\n                    )\n                }\n            }\n        }\n        // Content below tabs\n        when (selectedTab) {\n            0 -> HomeScreen()\n            1 -> MoviesScreen()\n            2 -> ShowsScreen()\n        }\n    }\n}\n```\n\n> **TV-specific behavior**: Tabs typically activate on focus (not click). Use the `onFocus`\n> callback to switch content as the user D-pads through tabs.\n\n### Chips\n\n```kotlin\n// Assist chip\nAssistChip(onClick = { /* action */ }) { Text(\"Genre: Action\") }\n\n// Filter chip (toggleable)\nvar selected by remember { mutableStateOf(false) }\nFilterChip(\n    selected = selected,\n    onClick = { selected = !selected }\n) { Text(\"4K\") }\n\n// Input chip (removable)\nInputChip(\n    selected = true,\n    onClick = { /* remove filter */ }\n) { Text(\"English\") }\n\n// Suggestion chip\nSuggestionChip(onClick = { /* apply */ }) { Text(\"Recommended\") }\n```\n\n### ListItem & DenseListItem\n\n```kotlin\n// Standard list item\nListItem(\n    selected = false,\n    onClick = { /* navigate to setting */ },\n    headlineContent = { Text(\"Audio Language\") },\n    supportingContent = { Text(\"English\") },\n    leadingContent = {\n        Icon(Icons.Default.Language, contentDescription = null)\n    },\n    trailingContent = {\n        Icon(Icons.Default.ChevronRight, contentDescription = null)\n    }\n)\n\n// Dense list item — reduced height\nDenseListItem(\n    selected = false,\n    onClick = { /* action */ },\n    headlineContent = { Text(\"Subtitle Size\") }\n)\n```\n\n### Form Controls\n\n```kotlin\n// Checkbox\nvar checked by remember { mutableStateOf(false) }\nCheckbox(checked = checked, onCheckedChange = { checked = it })\n\n// RadioButton\nRadioButton(selected = true, onClick = { /* select */ })\n\n// Switch\nvar enabled by remember { mutableStateOf(true) }\nSwitch(checked = enabled, onCheckedChange = { enabled = it })\n```\n\n---\n\n## 4. Focus & D-pad Navigation\n\nTV UIs are focus-driven — there is no touch. Every interactive element must be focusable and\nnavigable via the D-pad (up/down/left/right + select + back).\n\n### Focus Indications\n\nTV Material provides four built-in focus indications — configured per component via `Defaults.*` objects:\n\n| Indication | API | When to Use |\n|------------|-----|-------------|\n| Scale | `scale(focusedScale = 1.05f)` | Most components — clear visual feedback |\n| Border | `border(focusedBorder = Border(...))` | Buttons, list items — precise outline |\n| Glow | `glow(focusedGlow = Glow(...))` | Cards, media tiles — elevated look |\n| Color | `colors(focusedContainerColor = ...)` | Chips, tabs — background color change |\n\n### Focus Management with Modifiers\n\n```kotlin\n// Request initial focus\nval focusRequester = remember { FocusRequester() }\n\nLazyRow {\n    items(movies) { movie ->\n        MovieCard(\n            modifier = if (movie == movies.first())\n                Modifier.focusRequester(focusRequester)\n            else Modifier\n        )\n    }\n}\n\nLaunchedEffect(Unit) {\n    focusRequester.requestFocus()\n}\n\n// Customize D-pad directional focus traversal\n// Use up/down/left/right — NOT enter/exit (those control FocusGroup enter/exit, not D-pad directions)\nModifier.focusProperties {\n    right = customFocusRequester    // override where right D-pad goes\n    left = FocusRequester.Cancel    // block left navigation\n    // up / down also available\n}\n\n// Focus restoration — remember which child had focus\nModifier.focusRestorer()\n```\n\n### D-pad Input Handling\n\n```kotlin\nModifier.onKeyEvent { keyEvent ->\n    when {\n        keyEvent.key == Key.DirectionCenter && keyEvent.type == KeyEventType.KeyUp -> {\n            // Select/enter pressed\n            true\n        }\n        keyEvent.key == Key.Back && keyEvent.type == KeyEventType.KeyUp -> {\n            // Back button pressed\n            true\n        }\n        else -> false\n    }\n}\n\n// Long-press support is built into TV Surface components\nSurface(\n    onClick = { /* regular click */ },\n    onLongClick = { /* long-press menu */ }\n) { /* content */ }\n```\n\n### Back Button\n\n```kotlin\n// Use BackHandler from activity-compose\nBackHandler(enabled = isDetailVisible) {\n    // Return to previous screen\n    isDetailVisible = false\n}\n```\n\n> **Pattern**: Back button should always navigate to the previous destination. Pressing back\n> from the start destination should exit the app. Never gate exit with a confirmation dialog.\n\n---\n\n## 5. Lists & Scrolling\n\n### Standard Lazy Layouts (Recommended)\n\nSince Compose Foundation 1.7.0, standard `LazyRow`/`LazyColumn`/`LazyGrid` support\nfocus-driven scrolling out of the box. **The deprecated `TvLazyRow`/`TvLazyColumn`\nfrom `tv-foundation` should no longer be used.**\n\n```kotlin\n@Composable\nfun CatalogBrowser(\n    featuredContent: List<Movie>,\n    sections: List<Section>,\n    modifier: Modifier = Modifier,\n    onMovieSelected: (Movie) -> Unit = {},\n) {\n    LazyColumn(\n        modifier = modifier.fillMaxSize(),\n        verticalArrangement = Arrangement.spacedBy(16.dp)\n    ) {\n        // Featured carousel at top\n        item {\n            FeaturedCarousel(featuredContent)\n        }\n        // Content sections\n        items(sections) { section ->\n            Text(\n                text = section.title,\n                style = MaterialTheme.typography.headlineSmall,\n                modifier = Modifier.padding(start = 16.dp, bottom = 8.dp)\n            )\n            LazyRow(\n                horizontalArrangement = Arrangement.spacedBy(8.dp),\n                contentPadding = PaddingValues(horizontal = 16.dp)\n            ) {\n                items(\n                    items = section.movies,\n                    key = { it.id }\n                ) { movie ->\n                    MovieCard(\n                        movie = movie,\n                        onClick = { onMovieSelected(movie) }\n                    )\n                }\n            }\n        }\n    }\n}\n```\n\n### Custom Scroll Positioning with BringIntoViewSpec\n\nOverride default scroll behavior to keep focused items at a consistent position (e.g., 30% from\nthe left edge instead of just scrolling to make the item visible):\n\n```kotlin\n// Both the composable function AND the CompositionLocalProvider call inside require\n// @OptIn(ExperimentalFoundationApi::class) — annotate the whole function.\n@OptIn(ExperimentalFoundationApi::class)\n@Composable\nfun PositionFocusedItemInLazyLayout(\n    parentFraction: Float = 0.3f,\n    childFraction: Float = 0f,\n    content: @Composable () -> Unit,\n) {\n    val bringIntoViewSpec = remember(parentFraction, childFraction) {\n        object : BringIntoViewSpec {\n            override fun calculateScrollDistance(\n                offset: Float,\n                size: Float,\n                containerSize: Float\n            ): Float {\n                val targetForLeadingEdge =\n                    parentFraction * containerSize - (childFraction * size)\n                val adjustedTarget = if (size <= containerSize &&\n                    (containerSize - targetForLeadingEdge) < size) {\n                    containerSize - size\n                } else {\n                    targetForLeadingEdge\n                }\n                return offset - adjustedTarget\n            }\n        }\n    }\n    CompositionLocalProvider(\n        LocalBringIntoViewSpec provides bringIntoViewSpec,\n        content = content,\n    )\n}\n\n// Usage:\nPositionFocusedItemInLazyLayout(parentFraction = 0.3f) {\n    LazyColumn {\n        items(sections) { section ->\n            LazyRow { /* items */ }\n        }\n    }\n}\n```\n\n### Migration from TV Foundation Lazy Layouts\n\n| Deprecated (`tv-foundation`) | Replacement (`compose.foundation`) |\n|-------------------------------|-------------------------------------|\n| `TvLazyRow` | `LazyRow` |\n| `TvLazyColumn` | `LazyColumn` |\n| `TvLazyHorizontalGrid` | `LazyHorizontalGrid` |\n| `TvLazyVerticalGrid` | `LazyVerticalGrid` |\n| `pivotOffsets` | `BringIntoViewSpec` via `LocalBringIntoViewSpec` |\n\nRequires `compose.foundation` 1.7.0+. Update imports and remove the `Tv` prefix.\n\n---\n\n## 6. Theming\n\nTV `MaterialTheme` mirrors the mobile Material3 theming system but is defined in\n`androidx.tv.material3`:\n\n```kotlin\n@Composable\nfun TvAppTheme(content: @Composable () -> Unit) {\n    // TV apps typically use dark themes for the living room\n    // Import darkColorScheme from androidx.tv.material3 — NOT androidx.compose.material3\n    val colorScheme = darkColorScheme(\n        primary = Color(0xFFBB86FC),\n        onPrimary = Color.Black,\n        secondary = Color(0xFF03DAC5),\n        surface = Color(0xFF121212),\n        onSurface = Color.White,\n        background = Color(0xFF000000),\n        onBackground = Color.White,\n    )\n\n    val typography = Typography(\n        // TV typography should be larger for 10-foot viewing\n        headlineLarge = TextStyle(\n            fontWeight = FontWeight.Bold,\n            fontSize = 32.sp,\n            lineHeight = 40.sp\n        ),\n        bodyLarge = TextStyle(\n            fontSize = 18.sp,\n            lineHeight = 24.sp\n        ),\n    )\n\n    MaterialTheme(\n        colorScheme = colorScheme,\n        typography = typography,\n        shapes = Shapes(), // default TV shapes\n        content = content\n    )\n}\n```\n\nKey differences from mobile theming:\n- Import `MaterialTheme` **and** `darkColorScheme`/`lightColorScheme` from `androidx.tv.material3`, not `androidx.compose.material3`\n- TV apps almost always use `darkColorScheme()` — living rooms are dark environments\n- Typography sizes should be larger for 10-foot viewing distance (16sp minimum body text)\n- `Shapes` from `androidx.tv.material3` — same concept, TV-specific defaults\n\n### CompositionLocals\n\n| Local | Purpose |\n|-------|---------|\n| `LocalContentColor` | Content color for text/icons at current position |\n| `LocalTextStyle` | Default text style (set via `ProvideTextStyle`) |\n\n---\n\n## 7. Building an Immersive List\n\n`ImmersiveList` was removed in tv-material 1.0.0-beta01. Build it manually by changing\nthe background based on the focused item:\n\n```kotlin\n@Composable\nfun ImmersiveMovieRow(\n    movies: List<Movie>,\n    modifier: Modifier = Modifier,\n) {\n    var focusedMovie by remember { mutableStateOf(movies.firstOrNull()) }\n\n    Box(modifier = modifier.fillMaxWidth().height(400.dp)) {\n        // Background — changes based on focused item\n        AnimatedContent(\n            targetState = focusedMovie,\n            transitionSpec = {\n                fadeIn(tween(500)) togetherWith fadeOut(tween(500))\n            },\n            label = \"immersive-background\"\n        ) { movie ->\n            movie?.let {\n                AsyncImage(\n                    model = it.backgroundImageUrl,\n                    contentDescription = null,\n                    contentScale = ContentScale.Crop,\n                    modifier = Modifier.fillMaxSize()\n                )\n            }\n        }\n\n        // Scrim gradient\n        Box(\n            modifier = Modifier\n                .fillMaxSize()\n                .background(\n                    Brush.verticalGradient(\n                        colors = listOf(Color.Transparent, Color.Black.copy(alpha = 0.8f))\n                    )\n                )\n        )\n\n        // Foreground row\n        Column(\n            modifier = Modifier.align(Alignment.BottomStart).padding(32.dp)\n        ) {\n            focusedMovie?.let { movie ->\n                Text(movie.title, style = MaterialTheme.typography.headlineLarge)\n                Text(movie.description, maxLines = 2, style = MaterialTheme.typography.bodyMedium)\n            }\n            Spacer(Modifier.height(16.dp))\n            LazyRow(horizontalArrangement = Arrangement.spacedBy(12.dp)) {\n                items(movies, key = { it.id }) { movie ->\n                    // Wrap Card in a Box — onFocusChanged on an interactive TV Surface\n                    // may not fire reliably. Apply it to a non-interactive wrapper instead.\n                    Box(\n                        modifier = Modifier\n                            .size(width = 160.dp, height = 90.dp)\n                            .onFocusChanged { state ->\n                                if (state.hasFocus) focusedMovie = movie\n                            }\n                    ) {\n                        Card(\n                            onClick = { /* navigate to detail */ },\n                            modifier = Modifier.fillMaxSize()\n                        ) {\n                            AsyncImage(\n                                model = movie.thumbnailUrl,\n                                contentDescription = movie.title,\n                                contentScale = ContentScale.Crop,\n                                modifier = Modifier.fillMaxSize()\n                            )\n                        }\n                    }\n            }\n        }\n    }\n}\n```\n\n---\n\n## 8. Details Screen Pattern\n\n```kotlin\n@Composable\nfun DetailsScreen(\n    movie: Movie,\n    modifier: Modifier = Modifier,\n    onStartPlayback: (Movie) -> Unit = {},\n) {\n    Box(modifier = modifier.fillMaxSize()) {\n        AsyncImage(\n            model = movie.backgroundImageUrl,\n            contentDescription = null,\n            contentScale = ContentScale.Crop,\n            modifier = Modifier.fillMaxSize()\n        )\n        // Scrim for readability\n        Box(\n            modifier = Modifier\n                .fillMaxSize()\n                .background(\n                    Brush.horizontalGradient(\n                        colors = listOf(Color.Black.copy(alpha = 0.9f), Color.Transparent)\n                    )\n                )\n        )\n        Column(\n            modifier = Modifier\n                .padding(48.dp)\n                .fillMaxHeight(),\n            verticalArrangement = Arrangement.Center\n        ) {\n            Text(movie.title, style = MaterialTheme.typography.displaySmall)\n            Spacer(Modifier.height(8.dp))\n            Text(movie.description, style = MaterialTheme.typography.bodyLarge, maxLines = 4)\n            Spacer(Modifier.height(24.dp))\n            Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {\n                Button(onClick = { onStartPlayback(movie) }) {\n                    Text(\"Play\")\n                }\n                OutlinedButton(onClick = { /* add to list */ }) {\n                    Text(\"My List\")\n                }\n            }\n        }\n    }\n}\n```\n\n---\n\n## 9. TVProvider Integration\n\n`androidx.tvprovider` lets your app publish channels and programs to the Android TV home\nscreen. This is not Compose UI — it's a content provider API used alongside your Compose app.\n\n```kotlin\n// IMPORTANT: publishChannel / publishPreviewProgram perform I/O — call from a background\n// coroutine (Dispatchers.IO) or a WorkManager task, never from the main thread.\n// Example using a coroutine:\nviewModelScope.launch(Dispatchers.IO) {\n    val channel = PreviewChannel.Builder()\n        .setDisplayName(\"Continue Watching\")\n        .setAppLinkIntentUri(Uri.parse(\"myapp://home\"))\n        .build()\n\n    val channelId = PreviewChannelHelper(context).publishChannel(channel)\n\n    val program = PreviewProgram.Builder()\n        .setChannelId(channelId)\n        .setTitle(\"Movie Title\")\n        .setDescription(\"Episode 3\")\n        .setPosterArtUri(Uri.parse(\"https://example.com/poster.jpg\"))\n        .setIntentUri(Uri.parse(\"myapp://movie/123\"))\n        .setType(TvContractCompat.PreviewPrograms.TYPE_MOVIE)\n        .build()\n\n    PreviewChannelHelper(context).publishPreviewProgram(program)\n}\n```\n\n---\n\n## 10. Anti-Patterns & Gotchas\n\n### Don't mix mobile and TV Material\n\n```kotlin\n// WRONG — mixing material3 themes\nimport androidx.compose.material3.MaterialTheme as MobileMaterialTheme\nimport androidx.tv.material3.MaterialTheme as TvMaterialTheme\n\n// This WILL cause inconsistent colors, typography, and shapes.\n// Pick one: use tv.material3 for TV apps.\n```\n\n### Don't use Leanback with Compose\n\nLeanback (`androidx.leanback`) is the legacy View-based TV framework. Do not mix it with\nCompose for TV. Use `androidx.tv:tv-material` exclusively for new projects.\n\n### Glow disabled below API 28\n\nGlow indication (`Glow(...)`) is silently disabled on devices running Android 8.1 (API 27)\nand below. Use Border + Scale as primary indications for broad compatibility.\n\n### Focus traps\n\nEnsure every screen has a clear focus path. Common traps:\n- Empty `LazyRow`/`LazyColumn` with no items — focus search crashes or skips over them\n- Overlapping focusable elements — D-pad direction becomes unpredictable\n- Missing `focusRestorer()` — returning to a list loses the user's position\n\n### TV lazy layouts are deprecated\n\n`TvLazyRow`, `TvLazyColumn`, `TvLazyVerticalGrid`, `TvLazyHorizontalGrid` from\n`tv-foundation` are deprecated since alpha11. Migrate to standard Compose Foundation\nlazy layouts (requires Foundation 1.7.0+).\n\n### Don't show virtual back button\n\nTV uses the hardware back button on the remote. Never render a back button in your UI —\nit wastes screen real estate and confuses the navigation pattern.\n\n### Typography too small\n\nMobile-sized text (14sp body) is unreadable at TV viewing distances (10 feet). Use 16sp\nminimum for body text, 24sp+ for headings.\n\n### Missing content descriptions\n\nTV apps must be accessible via TalkBack. Every interactive element needs a\n`contentDescription` — especially image-only cards and icon buttons.\n\n### ExoPlayer rendering on Surface\n\nOn lower API versions, `CompositingStrategy.Offscreen` on Surface composables can prevent\nExoPlayer from rendering video. This was fixed in tv-material 1.0.1 by moving the\ncompositing strategy from Surface to Text.\n\n---\n\n## 11. Sample Apps & Resources\n\n| Resource | URL |\n|----------|-----|\n| JetStream (full app sample) | `github.com/android/tv-samples/tree/main/JetStreamCompose` |\n| TV Material Catalog | `github.com/android/tv-samples/tree/main/TvMaterialCatalog` |\n| Compose for TV codelab | `developer.android.com/codelabs/compose-for-tv-introduction` |\n| TV design guides | `developer.android.com/design/ui/tv/guides/components` |\n| API reference | `developer.android.com/reference/kotlin/androidx/tv/material3/package-summary` |\n| ImmersiveList sample (manual) | `cs.android.com/androidx/.../tv/samples/.../ImmersiveListSamples.kt` |\n| TV samples repo | `github.com/android/tv-samples` |\n"
  },
  {
    "path": ".claude/skills/compose-expert/references/view-composition.md",
    "content": "# Jetpack Compose View Composition Reference\n\n## Composable Function Naming Conventions\n\nNames communicate intent. Follow these patterns consistently.\n\n### Nouns (UI Components)\n- PascalCase, describe *what* the composable displays\n- Used for UI widgets, screens, layout building blocks\n\n```kotlin\n@Composable\nfun Button(...)  // Displays a button\n\n@Composable\nfun UserCard(user: User)  // Displays a user card\n\n@Composable\nfun LoginScreen()  // Displays a login screen\n\n@Composable\nfun CheckboxWithLabel(...)  // Displays a checkbox with label\n```\n\n### Verbs (Side Effects / Effects)\n- PascalCase, describe *what action* happens\n- Used for composables that don't emit UI, only perform side effects\n\n```kotlin\n@Composable\nfun LaunchedEffect(...)  // Launches a coroutine\n\n@Composable\nfun DisposableEffect(...)  // Manages resource lifecycle\n\n@Composable\nfun SideEffect(...)  // Performs a side effect\n```\n\n### Anti-Pattern: Ambiguous Names\n```kotlin\n// ❌ Unclear if this is a UI component or effect\n@Composable\nfun HandleLogin(...)\n\n// ✅ Explicit\n@Composable\nfun LoginScreen(...)  // Displays UI\n\n@Composable\nfun PerformLogin(...)  // Side effect function (if truly a side effect)\n```\n\n## The Slot Pattern\n\nAccept `@Composable` lambda parameters to create flexible, reusable containers.\n\n### Basic Slot Pattern\n```kotlin\n@Composable\nfun Card(\n    modifier: Modifier = Modifier,\n    content: @Composable () -> Unit\n) {\n    Box(\n        modifier = modifier\n            .background(Color.White)\n            .padding(16.dp)\n    ) {\n        content()\n    }\n}\n\n// Usage\nCard {\n    Text(\"Hello\")\n    Image(...)\n}\n```\n\n### Multiple Slots\n```kotlin\n@Composable\nfun ListItem(\n    modifier: Modifier = Modifier,\n    icon: @Composable () -> Unit,\n    title: @Composable () -> Unit,\n    subtitle: @Composable (() -> Unit)? = null,\n    trailing: @Composable (() -> Unit)? = null\n) {\n    Row(modifier = modifier.padding(16.dp)) {\n        icon()\n        Column(modifier = Modifier.weight(1f)) {\n            title()\n            subtitle?.invoke()\n        }\n        trailing?.invoke()\n    }\n}\n\n// Usage\nListItem(\n    icon = { Icon(Icons.Default.Person, \"\") },\n    title = { Text(\"Alice\") },\n    subtitle = { Text(\"Online\") },\n    trailing = { Badge() }\n)\n```\n\n**Key principle:** Slots accept `@Composable` lambdas, not pre-composed values. This ensures composition is deferred and scope-aware.\n\n```kotlin\n// ❌ Wrong: passes composed value\nfun CustomLayout(content: String) { ... }\n\n// ✅ Correct: passes composition lambda\nfun CustomLayout(content: @Composable () -> Unit) { ... }\n```\n\nSource: Material 3 composables in `androidx.compose.material3` use slots extensively.\n\n## Extracting Composables\n\nKnow when to extract and when to keep composables together.\n\n### Extract When\n- **Reused in multiple places:** DRY principle\n- **Single responsibility:** Composable handles one concern\n- **Easier to test:** Small, focused unit\n- **Performance:** Enables skipping and independent recomposition\n\n```kotlin\n// ❌ Before: god composable\n@Composable\nfun UserProfile(user: User) {\n    Column {\n        // Header\n        Box(modifier = Modifier.fillMaxWidth()) {\n            Image(user.photo)\n            Text(user.name, style = MaterialTheme.typography.headlineSmall)\n            IconButton({ /* edit */ }) { Icon(Icons.Default.Edit, \"\") }\n        }\n\n        // Stats\n        Row(modifier = Modifier.fillMaxWidth()) {\n            StatItem(user.followers, \"Followers\")\n            StatItem(user.following, \"Following\")\n            StatItem(user.posts, \"Posts\")\n        }\n\n        // Bio\n        Text(user.bio, style = MaterialTheme.typography.bodyMedium)\n    }\n}\n\n// ✅ After: extracted composables\n@Composable\nfun UserProfile(user: User) {\n    Column {\n        UserProfileHeader(user)\n        UserStats(user)\n        UserBio(user.bio)\n    }\n}\n\n@Composable\nprivate fun UserProfileHeader(user: User) { ... }\n\n@Composable\nprivate fun UserStats(user: User) { ... }\n\n@Composable\nprivate fun UserBio(bio: String) { ... }\n```\n\n### Don't Extract When\n- **Single use:** Extraction adds indirection without benefit\n- **Tightly coupled logic:** Would require passing many parameters\n- **Too small:** Single `Text()` or `Icon()` doesn't need extraction\n\n```kotlin\n// ❌ Over-extraction: trivial wrapper\n@Composable\nprivate fun UserName(name: String) {\n    Text(name, style = MaterialTheme.typography.headlineSmall)\n}\n\n// ✅ Keep inline if only used once\n@Composable\nfun UserProfile(user: User) {\n    Text(user.name, style = MaterialTheme.typography.headlineSmall)\n}\n```\n\n## Stateful vs Stateless Composables\n\nStructure composables as a stateless layer with optional stateful wrapper.\n\n### Pattern: Stateless + Wrapper\n\n```kotlin\n// ✅ Stateless composable (reusable, testable)\n@Composable\nfun ToggleButton(\n    isEnabled: Boolean,\n    onToggle: (Boolean) -> Unit,\n    text: String\n) {\n    Button(\n        onClick = { onToggle(!isEnabled) },\n        colors = ButtonDefaults.buttonColors(\n            containerColor = if (isEnabled) Color.Blue else Color.Gray\n        )\n    ) {\n        Text(text)\n    }\n}\n\n// ✅ Stateful wrapper (manages state, uses stateless child)\n@Composable\nfun StatefulToggleButton(text: String = \"Toggle\") {\n    var isEnabled by remember { mutableStateOf(false) }\n    ToggleButton(\n        isEnabled = isEnabled,\n        onToggle = { isEnabled = it },\n        text = text\n    )\n}\n\n// Usage: choose based on need\n@Composable\nfun MyScreen() {\n    // Use stateless when caller manages state\n    var featureEnabled by remember { mutableStateOf(false) }\n    ToggleButton(featureEnabled, { featureEnabled = it }, \"Feature\")\n\n    // Use stateful wrapper for isolated state\n    StatefulToggleButton(\"Local Toggle\")\n}\n```\n\n**Advantage:** Caller can test and reuse `ToggleButton` without mocking state. `StatefulToggleButton` provides convenience for simple cases.\n\n## Preview Annotations\n\nUse previews for rapid UI development and regression testing.\n\n### @Preview\nBasic preview of a single composable.\n\n```kotlin\n@Preview\n@Composable\nfun UserCardPreview() {\n    UserCard(user = User(1, \"Alice\"))\n}\n\n// Multiple previews\n@Preview(name = \"Light\")\n@Preview(name = \"Dark\", uiMode = UI_MODE_NIGHT_YES)\n@Composable\nfun UserCardPreviews() {\n    UserCard(user = User(1, \"Alice\"))\n}\n```\n\n### @PreviewLightDark\nAutomatically generates light and dark theme previews.\n\n```kotlin\n@PreviewLightDark\n@Composable\nfun UserCardPreview() {\n    MyTheme {\n        UserCard(user = User(1, \"Alice\"))\n    }\n}\n```\n\n### @PreviewFontScale\nShows how composable responds to different font sizes.\n\n```kotlin\n@Preview(fontScale = 0.8f, name = \"Small Fonts\")\n@Preview(fontScale = 1f, name = \"Normal Fonts\")\n@Preview(fontScale = 1.2f, name = \"Large Fonts\")\n@Composable\nfun TextPreview() {\n    Text(\"This is text\")\n}\n```\n\n### @PreviewScreenSizes\nTests multiple screen dimensions.\n\n```kotlin\n@Preview(device = Devices.PHONE, name = \"Phone\")\n@Preview(device = Devices.TABLET, name = \"Tablet\")\n@Preview(device = Devices.FOLDABLE, name = \"Foldable\")\n@Composable\nfun ResponsiveLayoutPreview() {\n    ResponsiveLayout()\n}\n```\n\nSource: `androidx.compose.ui.tooling.preview`\n\n## CompositionLocal\n\nProvide implicit parameters without threading them through the hierarchy.\n\n### When to Use\n- **Theming:** Pass `Colors`, `Typography` implicitly\n- **Navigation:** Access from deep in composable tree\n- **Locale/Strings:** Avoid passing through every composable\n\n```kotlin\n// ✅ Define at top level\nval LocalUser = staticCompositionLocalOf<User?> { null }\n\n@Composable\nfun App(user: User) {\n    CompositionLocalProvider(LocalUser provides user) {\n        MainContent()\n    }\n}\n\n// ✅ Access deep in tree without passing through every composable\n@Composable\nfun UserGreeting() {\n    val user = LocalUser.current\n    Text(\"Hello, ${user?.name}\")\n}\n```\n\n### When NOT to Use\n- **Configuration params:** If only 1-2 levels deep, pass directly\n- **Frequently changing values:** Can cause unnecessary recomposition\n- **Dependencies:** Use dependency injection at ViewModel level\n\n```kotlin\n// ❌ Over-use: should pass `title` directly\nval LocalTitle = staticCompositionLocalOf<String> { \"\" }\n\n@Composable\nfun Parent() {\n    CompositionLocalProvider(LocalTitle provides \"My Title\") {\n        Child()\n    }\n}\n\n// ✅ Just pass it\n@Composable\nfun Parent(title: String) {\n    Child(title = title)\n}\n\n@Composable\nfun Child(title: String) { ... }\n```\n\n**Types (recomposition scope is the key difference):**\n- `staticCompositionLocalOf`: When the value changes, the **entire subtree** below the `CompositionLocalProvider` is invalidated and recomposed. Use for values that truly never change during composition (theme, spacing, DI-provided dependencies).\n- `compositionLocalOf`: When the value changes, only composables that **actually read** `.current` are invalidated. Use for values that may change during composition (user session, locale, scroll state).\n\n## Composable Return Values\n\n**Never return values from composables.** Use callbacks instead.\n\n```kotlin\n// ❌ Wrong: composables don't return values\n@Composable\nfun UserInput(): String {\n    var text by remember { mutableStateOf(\"\") }\n    return text  // Can't do this\n}\n\n// ✅ Correct: callback pattern\n@Composable\nfun UserInput(onUserInput: (String) -> Unit) {\n    var text by remember { mutableStateOf(\"\") }\n    TextField(\n        value = text,\n        onValueChange = {\n            text = it\n            onUserInput(it)  // Notify parent\n        }\n    )\n}\n\n// Usage\n@Composable\nfun FormScreen() {\n    UserInput(onUserInput = { input -> /* handle */ })\n}\n```\n\n**Rationale:** Composables are executed during composition, which happens at unpredictable times and may be skipped or reordered.\n\n## Screen-Level Composables\n\nStructure screens as a thin ViewModel integration layer above pure composables.\n\n### Recommended Pattern\n```kotlin\n// ✅ Screen composable: connects ViewModel\n@Composable\nfun UserDetailsScreen(\n    viewModel: UserDetailsViewModel = hiltViewModel(),\n    userId: String\n) {\n    val uiState by viewModel.uiState.collectAsStateWithLifecycle()\n    LaunchedEffect(userId) {\n        viewModel.loadUser(userId)\n    }\n\n    UserDetailsContent(\n        uiState = uiState,\n        onRetry = { viewModel.loadUser(userId) }\n    )\n}\n\n// ✅ Content composable: pure (testable, reusable)\n@Composable\nprivate fun UserDetailsContent(\n    uiState: UiState,\n    onRetry: () -> Unit\n) {\n    when (uiState) {\n        is UiState.Loading -> LoadingUI()\n        is UiState.Success -> SuccessUI(uiState.user)\n        is UiState.Error -> ErrorUI(uiState.message, onRetry)\n    }\n}\n\n// ✅ Composable for preview/testing\n@Preview\n@Composable\nprivate fun UserDetailsContentPreview() {\n    UserDetailsContent(\n        uiState = UiState.Success(User(1, \"Alice\")),\n        onRetry = {}\n    )\n}\n```\n\n**Benefits:**\n- Public screen composable integrates ViewModel\n- Private content composable is pure, testable, previewable\n- Clear separation: UI logic (public) vs rendering (private)\n\n**Anti-pattern:** Passing ViewModel to child composables. Keep it at screen level only.\n\n```kotlin\n// ❌ Couples child to ViewModel\n@Composable\nfun UserCard(viewModel: UserViewModel) {\n    val user by viewModel.user.collectAsStateWithLifecycle()\n    Text(user.name)\n}\n\n// ✅ Pass only the data\n@Composable\nfun UserCard(user: User) {\n    Text(user.name)\n}\n```\n\n## Reusability Guidelines\n\nDesign composables to be configurable without over-parameterization.\n\n### Configuration via Parameters\n```kotlin\n// ✅ Expose what varies, hide what doesn't\n@Composable\nfun Card(\n    modifier: Modifier = Modifier,\n    content: @Composable () -> Unit\n) {\n    // Internal: fixed styling, padding, etc.\n    Box(\n        modifier = modifier\n            .background(Color.White)\n            .padding(16.dp)\n            .clip(RoundedCornerShape(8.dp))\n    ) {\n        content()\n    }\n}\n```\n\n### Avoid Parameter Explosion\n```kotlin\n// ❌ Too many parameters, hard to use\n@Composable\nfun Button(\n    text: String,\n    textColor: Color,\n    backgroundColor: Color,\n    cornerRadius: Dp,\n    padding: PaddingValues,\n    elevation: Dp,\n    ...\n)\n\n// ✅ Sensible defaults, style objects\n@Composable\nfun Button(\n    text: String,\n    modifier: Modifier = Modifier,\n    style: ButtonStyle = ButtonStyle.Primary,\n    onClick: () -> Unit\n) { ... }\n\n// Or: use Material composables with built-in styles\n@Composable\nfun Button(\n    onClick: () -> Unit,\n    modifier: Modifier = Modifier,\n    enabled: Boolean = true,\n    ...\n) { ... }  // Material3 Button has reasonable defaults\n```\n\n## Common Anti-Patterns\n\n### God Composables\n```kotlin\n// ❌ Does too much\n@Composable\nfun Dashboard() {\n    // Header\n    Box { /* 20 lines */ }\n\n    // List\n    LazyColumn {\n        items(items) { /* 15 lines */ }\n    }\n\n    // Footer\n    Box { /* 15 lines */ }\n\n    // Dialogs, side effects, state management...\n}\n\n// ✅ Extract and delegate\n@Composable\nfun Dashboard() {\n    Column {\n        DashboardHeader()\n        DashboardContent()\n        DashboardFooter()\n    }\n}\n```\n\n### Deep Nesting\n```kotlin\n// ❌ Hard to read and debug\n@Composable\nfun LoginScreen() {\n    Box { Column { Row { Card { Box { Text { ... } } } } } }\n}\n\n// ✅ Intermediate variables and extraction\n@Composable\nfun LoginScreen() {\n    val form = loginFormState()\n    Column {\n        LoginForm(form)\n        LoginButton(form)\n    }\n}\n```\n\n### Passing ViewModel to Children\n```kotlin\n// ❌ Violates composition boundaries\n@Composable\nfun ParentScreen(viewModel: ParentViewModel) {\n    ChildCard(viewModel = viewModel)  // Don't do this\n}\n\n// ✅ Extract data, pass to child\n@Composable\nfun ParentScreen(viewModel: ParentViewModel) {\n    val data by viewModel.data.collectAsStateWithLifecycle()\n    ChildCard(data = data)\n}\n```\n\n---\n\n**Source references:** `androidx.compose.material3`, `androidx.compose.ui.tooling.preview`, `androidx.compose.runtime.CompositionLocal`\n\n## Design-to-Composable Decomposition\n\nA systematic 5-step process for translating a visual design (Figma frame, screenshot, or spec) into a composable tree:\n\n**Step 1: Identify the root layout structure**\n- Full-screen Scaffold? (TopAppBar + content + bottom bar + FAB)\n- Scrollable content? (LazyColumn vs Column with verticalScroll)\n- Tabbed layout? (TabRow + HorizontalPager)\n- Dialog or bottom sheet?\n\n**Step 2: Decompose into visual sections (top-down)**\n- Identify major horizontal sections (header, content area, footer)\n- Within each section, identify horizontal groupings (icon + text rows, card grids)\n- This mirrors the DCGen divide-and-conquer approach: split horizontally first, then vertically\n\n**Step 3: For each section, identify the layout type**\n- Items stacked vertically with equal spacing -> `Column` with `Arrangement.spacedBy()`\n- Items side by side -> `Row` with weights or fixed sizes\n- Items overlapping -> `Box` with alignment modifiers\n- Grid of cards -> `LazyGrid` or `FlowRow`\n- Scrollable list of items -> `LazyColumn`\n\n**Step 4: Extract visual properties and map to theme**\n- Background colors -> `MaterialTheme.colorScheme.*`\n- Typography -> `MaterialTheme.typography.*` (headlineLarge, bodyMedium, etc.)\n- Spacing -> 4dp/8dp grid increments, use `Arrangement.spacedBy()` and `Modifier.padding()`\n- Corner radius -> `MaterialTheme.shapes.*`\n- Elevation -> `Card` or `Surface` with `tonalElevation`\n\n**Step 5: Identify interactive elements**\n- Buttons, text fields, toggles, checkboxes -> map to Material 3 components\n- Custom clickable areas -> `Modifier.clickable` with `role = Role.Button`\n- Add `contentDescription` for accessibility\n- Ensure 48dp minimum touch targets\n\n## Screen Structure Patterns\n\nThe standard screen pattern separates ViewModel integration from UI:\n\n```kotlin\n@Composable\nfun ConversationScreen(\n    viewModel: ConversationViewModel = hiltViewModel(),\n    onNavigateToDetail: (String) -> Unit\n) {\n    val uiState by viewModel.uiState.collectAsStateWithLifecycle()\n\n    ConversationContent(\n        uiState = uiState,\n        onAction = viewModel::onAction,\n        onNavigateToDetail = onNavigateToDetail\n    )\n}\n\n@Composable\nprivate fun ConversationContent(\n    uiState: ConversationUiState,\n    onAction: (ConversationAction) -> Unit,\n    onNavigateToDetail: (String) -> Unit\n) {\n    Scaffold(\n        topBar = {\n            TopAppBar(title = { Text(\"Conversations\") })\n        },\n        floatingActionButton = {\n            FloatingActionButton(onClick = { onAction(ConversationAction.Create) }) {\n                Icon(Icons.Default.Add, contentDescription = \"New conversation\")\n            }\n        }\n    ) { innerPadding ->\n        // MUST use innerPadding -- ignoring it causes content overlap\n        when (val state = uiState) {\n            is ConversationUiState.Loading -> {\n                Box(Modifier.fillMaxSize().padding(innerPadding), contentAlignment = Alignment.Center) {\n                    CircularProgressIndicator()\n                }\n            }\n            is ConversationUiState.Success -> {\n                LazyColumn(modifier = Modifier.padding(innerPadding)) {\n                    items(state.conversations, key = { it.id }) { conversation ->\n                        ConversationRow(\n                            conversation = conversation,\n                            onClick = { onNavigateToDetail(conversation.id) }\n                        )\n                    }\n                }\n            }\n            is ConversationUiState.Error -> {\n                ErrorContent(state.message, modifier = Modifier.padding(innerPadding))\n            }\n        }\n    }\n}\n```\n\nKey pattern: ViewModel at screen level, pure content composable underneath. The content composable receives state + callbacks, never the ViewModel. This makes it previewable and testable.\n\n## Composite Preview Annotations\n\nDefine once, use everywhere:\n\n```kotlin\n@Preview(name = \"Light\", uiMode = Configuration.UI_MODE_NIGHT_NO)\n@Preview(name = \"Dark\", uiMode = Configuration.UI_MODE_NIGHT_YES)\n@Preview(name = \"Large Font\", fontScale = 1.5f)\n@Preview(name = \"Small Device\", device = \"spec:width=320dp,height=640dp,dpi=320\")\n@Preview(name = \"Tablet\", device = Devices.TABLET)\n@Preview(name = \"Foldable\", device = Devices.FOLDABLE)\n@Preview(name = \"RTL\", locale = \"ar\")\nannotation class ComponentPreviews\n```\n\nApply to every extracted composable:\n```kotlin\n@ComponentPreviews\n@Composable\nprivate fun ConversationRowPreview() {\n    AppTheme {\n        ConversationRow(\n            conversation = previewConversation(),\n            onClick = {}\n        )\n    }\n}\n```\n\nFor data-driven previews, use `PreviewParameterProvider`:\n```kotlin\nclass ConversationPreviewProvider : PreviewParameterProvider<Conversation> {\n    override val values = sequenceOf(\n        Conversation(id = \"1\", title = \"Short title\", unreadCount = 0),\n        Conversation(id = \"2\", title = \"Very long conversation title that might wrap\", unreadCount = 99),\n        Conversation(id = \"3\", title = \"\", unreadCount = 0), // Empty title edge case\n    )\n}\n\n@ComponentPreviews\n@Composable\nprivate fun ConversationRowPreview(\n    @PreviewParameter(ConversationPreviewProvider::class) conversation: Conversation\n) {\n    AppTheme { ConversationRow(conversation = conversation, onClick = {}) }\n}\n```\n\n**CMP note:** In `commonMain`, use `@Preview` from `org.jetbrains.compose.ui.tooling.preview`. Device-specific previews (`Devices.TABLET`) are Android-only.\n\n## Adaptive Layouts\n\nUse `WindowSizeClass` to adapt layouts for different screen sizes:\n\n```kotlin\n@Composable\nfun AdaptiveScreen(windowSizeClass: WindowSizeClass) {\n    when (windowSizeClass.widthSizeClass) {\n        WindowWidthSizeClass.Compact -> {\n            // Phone: single column\n            SinglePaneLayout()\n        }\n        WindowWidthSizeClass.Medium -> {\n            // Small tablet: two panes\n            TwoPaneLayout()\n        }\n        WindowWidthSizeClass.Expanded -> {\n            // Large tablet/desktop: list-detail\n            ListDetailLayout()\n        }\n    }\n}\n```\n\nFor navigation, use `NavigationSuiteScaffold` which automatically switches between bottom nav (compact), rail (medium), and drawer (expanded).\n"
  },
  {
    "path": ".claude/skills/edge-to-edge/SKILL.md",
    "content": "---\nname: edge-to-edge\ndescription: |-\n  Use this skill to migrate your Jetpack Compose app to add adaptive edge-to-edge support and troubleshoot common issues. Use this skill to fix UI components (like buttons or lists) that are obscured by or overlapping with the navigation bar or status bar, fix IME insets, and fix system bar legibility.\nlicense: Complete terms in LICENSE.txt\nmetadata:\n  author: Google LLC\n  keywords:\n    - android\n    - compose\n    - system bars\n    - edge-to-edge\n    - status bar\n    - navigation bar\n---\n\n\n## Prerequisites\n\n- Project **MUST** use Android Jetpack Compose.\n- Project **MUST** target SDK 35 or later. If the SDK is lower than 35, increase the SDK to 35.\n\n## Step 1: plan\n\n1. Locate and analyze all Activity classes to detect which have existing edge-to-edge support. For every Activity without edge-to-edge, plan to make each Activity edge-to-edge.\n2. In each Activity, Locate and analyze all lists and FAB components to detect which have existing edge-to-edge support. For every component without edge-to-edge support, plan to make each of these components edge-to-edge.\n3. In each Activity, scan for `TextField`, `OutlinedTextField`, or `BasicTextField`. If found, then you **MUST** verify the IME doesn't hide the input field by following the IME section of this skill.\n\n## Step 2: add edge-to-edge support\n\n1. Add `enableEdgeToEdge` before `setContent` in `onCreate` in each Activity that does not already call `enableEdgeToEdge`.\n2. Add `android:windowSoftInputMode=\"adjustResize\"` in the AndroidManifest.xml for all Activities that use a soft keyboard.\n\n## Step 3: apply insets\n\n- The app **MUST** apply system insets, or align content to rulers, so critical\n  UI remains tappable. Choose only one method to avoid double padding:\n\n  1. **PREFERRED:** When available, use `Scaffold`s and pass `PaddingValues` to the content lambda.\n\n\n  ```kotlin\n  Scaffold { innerPadding ->\n      // innerPadding accounts for system bars and any Scaffold components\n      LazyColumn(\n          modifier = Modifier\n              .fillMaxSize()\n              .consumeWindowInsets(innerPadding),\n          contentPadding = innerPadding\n      ) { /* Content */ }\n  }\n  ```\n\n  <br />\n\n  1. **PREFERRED:** When available, use the automatic inset handling or padding modifiers in material components.\n\n     - Material 3 Components manages safe areas for its own components, including:\n       - `TopAppBar`\n       - `SmallTopAppBar`\n       - `CenterAlignedTopAppBar`\n       - `MediumTopAppBar`\n       - `LargeTopAppBar`\n       - `BottomAppBar`\n       - `ModalDrawerSheet`\n       - `DismissibleDrawerSheet`\n       - `PermanentDrawerSheet`\n       - `ModalBottomSheet`\n       - `NavigationBar`\n       - `NavigationRail`\n     - For Material 2 Components, use the `windowInsets`parameter to apply insets manually for `BottomAppBar`, `TopAppBar` and `BottomNavigation`. **DO NOT** apply padding to the parent container; instead, pass insets directly to the App Bar component. Applying padding to the parent container prevents the App Bar background from drawing into the system bar area. For example, for `TopAppBar`, choose only one of the following options:\n       1. **PREFERRED:** `TopAppBar(windowInsets = AppBarDefaults.topAppBarWindowInsets)`\n       2. `TopAppBar(windowInsets = WindowInsets.systemBars.exclude(WindowInsets.navigationBars))`\n       3. `TopAppBar(windowInsets = WindowInsets.systemBars.add(WindowInsets.captionBar))`\n  2. For components outside a Scaffold, use padding modifiers, such as `Modifier.safeDrawingPadding()` or `Modifier.windowInsetsPadding(WindowInsets.safeDrawing)`.\n\n\n     ```kotlin\n     Box(\n         modifier = Modifier\n             .fillMaxSize()\n             .safeDrawingPadding()\n     ) {\n         Button(\n             onClick = {},\n             modifier = Modifier.align(Alignment.BottomCenter)\n         ) {\n             Text(\"Login\")\n         }\n     }\n     ```\n\n     <br />\n\n  3. For deeply nested components with excessive padding, use `WindowInsetsRulers` (e.g. `Modifier.fitInside(WindowInsetsRulers.SafeDrawing.current)`). See the *IME* section for a code sample.\n\n  4. When you need an element (e.g. a custom header or decorative scrim) to\n     equal the dimensions of a system bar, use inset size modifiers (e.g.\n     `Modifier.windowInsetsTopHeight(WindowInsets.systemBars)`).\n     See the *Lists* section for a code sample.\n\n## Adaptive Scaffolds\n\n- `NavigationSuiteScaffold` manages safe areas for its own components, like the `NavigationRail` or `NavigationBar`. However, the adaptive scaffolds (e.g. `NavigationSuiteScaffold`, `ListDetailPaneScaffold`) don't propagate PaddingValues to their inner contents. You **MUST** apply insets to **individual** screens or components (e.g., list `contentPadding` or FAB padding) as described in *Step 3* . **DO NOT** apply `safeDrawingPadding` or similar modifiers to the `NavigationSuiteScaffold` parent. This clips and prevents an edge-to-edge screen.\n\n## IME\n\n- For each Activity with a soft keyboard, check that `android:windowSoftInputMode=\"adjustResize\"` is set in the AndroidManifest.xml. DO NOT use `SOFT_INPUT_ADJUST_RESIZE` because it is deprecated. Then, maintain focus on the input field. Choose one:\n  - 1. **PREFERRED:** Add `Modifier.fitInside(WindowInsetsRulers.Ime.current)` to the content container. This is preferred over `imePadding()` because it reduces jank and extra padding caused by forgetting to consume insets upstream in the hierarchy.\n  - 2. Add `imePadding` to the content container. The padding modifier **MUST** be placed before `Modifier.verticalScroll()`. Do NOT use `Modifier.imePadding()` if the parent already accounts for the IME with `contentWindowInsets` (e.g. `contentWindowInsets =\n    WindowInsets.safeDrawing`). Doing so will cause double padding.\n\n### IMEs with Scaffolds code patterns\n\n#### RIGHT\n\nRIGHT because `contentWindowInsets` contains IME insets, which are passed to the\ncontent lambda as `innerPadding`.\n\n\n```kotlin\n// RIGHT\nScaffold(contentWindowInsets = WindowInsets.safeDrawing) { innerPadding ->\n    Column(\n        modifier = Modifier\n            .padding(innerPadding)\n            .consumeWindowInsets(innerPadding)\n            .verticalScroll(rememberScrollState())\n    ) { /* Content */ }\n}\n```\n\n<br />\n\n*** ** * ** ***\n\nRIGHT because `fitInside` fits the content to the IME insets regardless of\n`contentWindowInsets`.\n\n\n```kotlin\n// RIGHT\nScaffold() { innerPadding ->\n    Column(\n        modifier = Modifier\n            .padding(innerPadding)\n            .consumeWindowInsets(innerPadding)\n            .fitInside(WindowInsetsRulers.Ime.current)\n            .verticalScroll(rememberScrollState())\n    ) { /* Content */ }\n}\n```\n\n<br />\n\n*** ** * ** ***\n\nRIGHT because the default `contentWindowInsets` does not contain IME insets, and\n`imePadding()` applies IME insets:\n\n\n```kotlin\n// RIGHT\nScaffold() { innerPadding ->\n    Column(\n        modifier = Modifier\n            .padding(innerPadding)\n            .consumeWindowInsets(innerPadding)\n            .imePadding()\n            .verticalScroll(rememberScrollState())\n    ) { /* Content */ }\n}\n```\n\n<br />\n\n#### WRONG\n\nWRONG because there will be excess padding when the IME opens. IME insets are\napplied twice, once with innerPadding, which contains IME insets from the passed\n`contentWindowInsets` values, and once with `imePadding`:\n\n\n```kotlin\n// WRONG\nScaffold( contentWindowInsets = WindowInsets.safeDrawing ) { innerPadding ->\n    Column(\n        modifier = Modifier\n            .padding(innerPadding)\n            .imePadding()\n            .verticalScroll(rememberScrollState())\n    ) { /* Content */ }\n}\n```\n\n<br />\n\n*** ** * ** ***\n\nWRONG because the IME will cover up the content. Scaffold's default\n`contentWindowInsets` does NOT contain IME insets.\n\n\n```kotlin\n// WRONG\nScaffold() { innerPadding ->\n    Column(\n        modifier = Modifier\n            .padding(innerPadding)\n            .verticalScroll(rememberScrollState())\n    ) { /* Content */ }\n}\n```\n\n<br />\n\n### IMEs without Scaffolds code patterns\n\n#### RIGHT\n\nThe following code samples WILL NOT cause excessive padding.\n\n\n```kotlin\n// RIGHT\nBox(\n    // Insets consumed\n    modifier = Modifier.safeDrawingPadding() // or imePadding(), safeContentPadding(), safeGesturesPadding()\n) {\n    Column(\n        modifier = Modifier.imePadding()\n    ) { /* Content */ }\n}\n```\n\n<br />\n\n*** ** * ** ***\n\n\n```kotlin\n// RIGHT\nBox(\n    // Insets consumed\n    modifier = Modifier.windowInsetsPadding(WindowInsets.safeDrawing) // or WindowInsets.ime, WindowInsets.safeContent, WindowInsets.safeGestures\n) {\n    Column(\n        modifier = Modifier.imePadding()\n    ) { /* Content */ }\n}\n```\n\n<br />\n\n*** ** * ** ***\n\n\n```kotlin\n// RIGHT\nBox(\n    // Insets not consumed, but irrelevant due to fitInside\n    modifier = Modifier.padding(WindowInsets.safeDrawing.asPaddingValues()) // or WindowInsets.ime.asPaddingValues(), WindowInsets.safeContent.asPaddingValues(), WindowInsets.safeGestures.asPaddingValues()\n) {\n    Column(\n        modifier = Modifier\n            .fillMaxSize()\n            .fitInside(WindowInsetsRulers.Ime.current)\n    ) { /* Content */ }\n}\n```\n\n<br />\n\n#### WRONG\n\nThe following code sample WILL cause excessive padding because IME insets are\napplied twice:\n\n\n```kotlin\n// WRONG\nBox(\n    // Insets not consumed\n    modifier = Modifier.padding(WindowInsets.safeDrawing.asPaddingValues()) // or WindowInsets.ime.asPaddingValues(), WindowInsets.safeContent.asPaddingValues(), WindowInsets.safeGestures.asPaddingValues()\n) {\n    Column(\n        modifier = Modifier.imePadding()\n    ) { /* Content */ }\n}\n```\n\n<br />\n\n## Navigation Bar Contrast \\& System Bar Icons\n\n- If the Activity uses `enableEdgeToEdge` from `WindowCompat`, you **MUST** set\n  `isAppearanceLightNavigationBars` and `isAppearanceLightStatusBars` to the\n  inverse of the device theme for apps that support light and dark theme so the\n  system bar icons are legible. It's recommended to do this in your theme file.\n  DO NOT do this if the Activities use `enableEdgeToEdge` from `ComponentActivity`\n  because it handles the icon colors automatically.\n\n\n  ```kotlin\n  // Only use if calling `enableEdgeToEdge` from `WindowCompat`.\n  // Apply to your theme file.\n  @Composable\n  fun MyTheme(\n      darkTheme: Boolean = isSystemInDarkTheme(),\n      content: @Composable () -> Unit\n  ) {\n      val view = LocalView.current\n      if (!view.isInEditMode) {\n          SideEffect {\n              val window = (view.context as? Activity)?.window ?: return@SideEffect\n              val controller = WindowCompat.getInsetsController(window, view)\n\n              // Dark icons for Light Mode (!darkTheme), Light icons for Dark Mode\n              controller.isAppearanceLightStatusBars = !darkTheme\n              controller.isAppearanceLightNavigationBars = !darkTheme\n          }\n      }\n\n      MaterialTheme(content = content)\n  }\n  ```\n\n  <br />\n\n- If any screen uses a `Scaffold` or a `NavigationSuiteScaffold` with a bottom\n  bar (e.g., `BottomAppBar`, `NavigationBar`), set\n  `window.isNavigationBarContrastEnforced = false` in the corresponding Activity\n  for SDK 29+. This prevents the system from adding a translucent background to\n  the navigation bar, verifying your bottom bar colors extend to the bottom of the\n  screen.\n\n## Lists\n\n- Apply inset padding (like `Scaffold`'s `innerPadding`) to the `contentPadding` parameter of scrollable components (e.g. `LazyColumn`, `LazyRow`). DO NOT apply it as a `Modifier.padding()` to the list's parent container, as this clips the content and prevents it from scrolling behind the system bars.\n- Create a translucent composable covering the system bar so that the icons are still legible.\n\n\n```kotlin\nclass SystemBarProtectionSnippets : ComponentActivity() {\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n\n        // enableEdgeToEdge sets window.isNavigationBarContrastEnforced = true\n        // which is used to add a translucent scrim to three-button navigation\n        enableEdgeToEdge()\n\n        setContent {\n            MyTheme {\n                // Main content\n                MyContent()\n\n                // After drawing main content, draw status bar protection\n                StatusBarProtection()\n            }\n        }\n    }\n}\n\n@Composable\nprivate fun StatusBarProtection(\n    color: Color = MaterialTheme.colorScheme.surfaceContainer,\n) {\n    Spacer(\n        modifier = Modifier\n            .fillMaxWidth()\n            .height(\n                with(LocalDensity.current) {\n                    (WindowInsets.statusBars.getTop(this) * 1.2f).toDp()\n                }\n            )\n            .background(\n                brush = Brush.verticalGradient(\n                    colors = listOf(\n                        color.copy(alpha = 1f),\n                        color.copy(alpha = 0.8f),\n                        Color.Transparent\n                    )\n                )\n            )\n    )\n}\n```\n\n<br />\n\n## Dialogs\n\nIf both the following conditions are true, then the Dialog is full screen and\nmust be made edge-to-edge:\n1. The `DialogProperties` contains `usePlatformDefaultWidth = false`.\n2. The Dialog calls `Modifier.fillMaxSize()`.\n\nTo make a full screen Dialog edge-to-edge, set `decorFitsSystemWindows = false`\nin the `DialogProperties`.\n\n\n```kotlin\nDialog(\n    onDismissRequest = { /* Handle dismiss */ },\n    properties = DialogProperties(\n        // 1. Allows the dialog to span the full width of the screen\n        usePlatformDefaultWidth = false,\n        // 2. Allows the dialog to draw behind status and navigation bars\n        decorFitsSystemWindows = false\n    )\n) { /* Content */ }\n```\n\n<br />\n\n## Checklist\n\n- \\[ \\] Does every `Activity` call `enableEdgeToEdge()`?\n- \\[ \\] Is `adjustResize` set in the `AndroidManifest.xml`?\n- \\[ \\] Does every `TextField`, `OutlinedTextField`, or `BasicTextField` have a parent with `imePadding()`, `fitInside`, `Modifier.safeDrawingPadding()`, `Modifier.safeContentPadding()`, `Modifier.safeGesturesPadding()`, or `contentWindowInsets` set to `WindowInsets.safeDrawing` or `WindowInsets.ime`?\n- \\[\\] Does the first and last list item draw away from the system bars by passing insets to `contentPadding`?\n- \\[\\] Do FABs draw above the navigation bars by either being inside a Scaffold or by applying `Modifier.safeDrawingPadding()`?\n- \\[\\] Does the project build? Run `./gradlew build` to be sure.\n"
  },
  {
    "path": ".claude/skills/r8-analyzer/SKILL.md",
    "content": "---\nname: r8-analyzer\ndescription: |-\n  Analyzes Android build files and R8 keep rules to identify redundancies, broad package-wide rules, and rules that subsume library consumer keep rules. Use when developers want to optimize their app's size, remove redundant or overly broad keep rules, or troubleshoot Proguard configurations.\nlicense: Complete terms in LICENSE.txt\nmetadata:\n  author: Google LLC\n  keywords:\n    - R8\n    - proguard\n    - keep rules\n    - app size\n    - optimization\n---\n\n\n## Core workflow\n\n- \\[ \\] Step 1: Create a file called R8_Configuration_Analysis.md, or reuse if one exists already, to store the output\n- \\[ \\] Step 2: Look at the configuration of R8 by looking at build.gradle, build.gradle.kts, gradle.properties in the codebase using [references/CONFIGURATION.md](references/CONFIGURATION.md) as the reference. Inform the developer and add the analysis to the report file\n- \\[ \\] Step 3: If the AGP version is less than 9, suggest moving to AGP 9.0 version as AGP 9.0 includes [optimizations](references/android/topic/performance/app-optimization/enable-app-optimization.md).\n  - \\[ \\] Step 4: Look at the proguard files in the codebase and evaluate each keep rule in the following specific order: a. **Libraries check** : Check rules against [references/REDUNDANT-RULES.md](references/REDUNDANT-RULES.md). If the app has keep rules targeting libraries - Google, AndroidX, Kotlin, Kotlinx, Room, Gson, Retrofit, inform the user that these are not required and suggest removal of these rules. b. **Impact analysis** : For the remaining keep rules, assess them based on the impact hierarchy defined in [references/KEEP-RULES-IMPACT-HIERARCHY.md](references/KEEP-RULES-IMPACT-HIERARCHY.md). (Note: Do NOT assess the impact of keep rules already covered in the libraries check step).\n- \\[ \\] Step 5: Identify subsuming keep rules in the remaining keep rules based on the hierarchy defined in [references/KEEP-RULES-IMPACT-HIERARCHY.md](references/KEEP-RULES-IMPACT-HIERARCHY.md) and suggest removing the broader keep rules.\n- \\[ \\] Step 6: For each remaining keep rule, analyze in detail the code affected by the rule by examining the code and adjacent files to understand why it was written. Look for reflection usage in those packages, and suggest a narrow and specific keep rule for the scenario using [references/REFLECTION-GUIDE.md](references/REFLECTION-GUIDE.md).\n- \\[ \\] Step 7: For every keep rule inform concisely and to the point what action needs to be taken - whether the rule needs to be removed/refined.\n  - If refining the rule, give instructions on finding a narrower and specific keep rule using the [/references/REFLECTION-GUIDE.md](references/REFLECTION-GUIDE.md).\n  - If removing, provide reasoning on why it needs to be removed.\n- \\[ \\] Step 8: After keep analysis, order the keep rule analysis based on the impact to the codebase hierarchy defined in [references/KEEP-RULES-IMPACT-HIERARCHY.md](references/KEEP-RULES-IMPACT-HIERARCHY.md)\n- \\[ \\] Step 9: Advise the user to run tests using [UI\n  automator](https://developer.android.com/training/testing/other-components/ui-automator) to assess that there is no issue with the suggested changes, concentrating on the packages where keep rules will be affected.\n\n## Mandatory rules\n\n- Don't make any changes in keep rule files\n- Don't say about what level each keep rule is.\n- Don't generate parts of the report if there is no keep rule to report in that section.\n- Don't mention the generated files.\n- Don't mention exceptions that occur during execution.\n- Don't mention the benefits of R8\n- Don't mention any files of this skill\n"
  },
  {
    "path": ".claude/skills/r8-analyzer/references/CONFIGURATION.md",
    "content": "To achieve maximum utilization of R8, the codebase must be configured correctly\ndepending on the build script language (Kotlin DSL vs. Groovy DSL).\n\n## 1. App Modules (`com.android.application`)\n\nThe app's `build.gradle` or `build.gradle.kts` file should enable minification\nand resource shrinking within the `release` build type or the apps custom build\ntype for release and performance testing. It MUST use the optimized default file\n(`proguard-android-optimize.txt`).\n\n**Kotlin DSL (`build.gradle.kts`):**\n\n    buildTypes {\n       getByName(\"release\") {\n           isMinifyEnabled = true\n           isShrinkResources = true\n           proguardFiles(\n               getDefaultProguardFile(\"proguard-android-optimize.txt\"),\n               \"proguard-rules.pro\"\n           )\n       }\n    }\n\n**Groovy DSL (`build.gradle`):**\n\n    buildTypes {\n       release {\n           minifyEnabled = true\n           shrinkResources = true\n           proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'\n       }\n    }\n\n## 2. `gradle.properties` Flags\n\n**Full Mode:** R8 Full Mode enables the entire optimizations\n\n- **AGP 8.0+** : Enabled by default. Ensure `android.enableR8.fullMode=false` is **NOT** present.\n- **Pre-AGP 8.0** : Should be explicitly enabled with `android.enableR8.fullMode=true`.\n\n**Optimized Resource Shrinking:** If the AGP version of the project is less than\n9.0 and more than 8.6, explicitly enable the new resource shrinker:\n\n    android.r8.optimizedResourceShrinking=true\n"
  },
  {
    "path": ".claude/skills/r8-analyzer/references/KEEP-RULES-IMPACT-HIERARCHY.md",
    "content": "Keep rules prevent optimization of R8, these rules are listed in the order of\nthe scope of what it retains in the codebase.\n\n## 1. Package-Wide Wildcards\n\nThe following types of keep rules prevents all the optimization of R8 in a\npackage, these must be avoided at any costs and must be refined to target a\nspecific class or classes.\n\n    -keep class com.example.package.** { *; } - Prevents optimization of all the classess including members in the package and subpackages\n    -keep class com.example.package.* { *; } - Prevents optimization of all the classes including members in the package\n    -keep class **.package.** { *; } - Prevents optimization of all the classess including members in all the package containing name - package.\n\nDepending on the package level the number of classes gets affected changes, so\nif the package level is higher, more classes are affected. Suggest to refine\nthe keep rule\n\n## 2. Inversion operator\n\nAvoid using the inversion operator ! in keep rules because it will\nunintentionally prevent optimization in every class in your application. So if\nyou have any keep rule with !operator, make sure you remove that with a narrow\nand specific keep rule\n\n    -keep class !com.example.MyClass{*;}\n\nThis keeps the entire app\nother than this class. Optimization are disabled for the entire class other\nthan this class.\n\n## 3. Keep Rules for both class and members\n\nKeep rules with -keep option and wildcard(`*`) inside braces forces R8 to retain\nspecific classes and their members exactly as defined. These type of keep rules\nprevent any optimization in the entire class and keeps the entire class\n\n    -keep class com.example.MyClass { *; }\n\n## 4. Keepclassmembers\n\nKeep rules with -keepclassmembers and wildcard(`*`) inside braces option Forces\nR8 to retain the members that are defined.\n\n    -keepclassmembers class com.example.MyClass { *; }\n\n## 5. Modifiers with Keep Specification\n\n-Keeps the class and **all** members, but uses modifiers to allow specific\noptimizations (like obfuscation). Retains significant code (members) but allows\nsome flexibility.\n\n    -keep,allowobfuscation class com.example.MyClass { *; }\n    -keep,allowshrinking class com.example.MyClass { *; }\n\n### 6. Modifiers with specific method but no modifier\n\nKeeps the class and modifier but no optimizations are enabled\n\n    -keep class com.example.MyClass { void myMethod(); }\n\n## 7. Class-Name Only Preservation\n\nKeeps only the class name. R8 will remove all methods and fields if they are not\nused.\n\n    -keep class com.example.MyClass\n\n## 8. Modifiers without Member Specification\n\nKeeps the class entry point using modifiers, but implies no specific member\nretention logic in the rule itself\n\n    -keep,allowobfuscation class com.example.MyClass\n    -keep,allowshrinking class com.example.MyClass\n    -keep,allowaccessmodification class com.example.MyClass\n\n## 9. Conditional Keep Rules\n\nOnly triggers if specific conditions are met (e.g., if class members exist).\nThese are the most narrow and optimization-friendly rules.\n\n    -keepclassmembers class com.example.MyClass { <fields>; }\n    -keepclasseswithmembers class * { native <methods>; }\n"
  },
  {
    "path": ".claude/skills/r8-analyzer/references/REDUNDANT-RULES.md",
    "content": "This document outlines common \"bad\" or redundant keep rules for standard Android\ndevelopment and popular libraries. Modern toolchains and libraries include their\nown consumer keep rules embedded in their AAR/JAR files, making many manual\nconfigurations unnecessary or even harmful to code optimization.\n\n*** ** * ** ***\n\n## Case: Global Keep Rules\n\n**Common Mistakes:**\n`proguard\n-dontshrink\n-dontobfuscate\n-dontoptimize`\n\n**The Fix:** These keep rules completely disable the core optimizations of R8\nfor the entire codebase. They must be removed from the codebase.\n\n*** ** * ** ***\n\n## Case: Android Components\n\nKeep rules required for Android components like Activity, Fragment, ViewModel,\nViews, Services or Broadcast receivers are redundant. AAPT2 and R8 contain the\nlogic to automatically keep components declared in the `AndroidManifest.xml` or\nreferenced in XML layout files.\n\n**Common Mistakes:**\n`proguard\n-keep public class * extends android.app.Activity\n-keep public class * extends android.app.Service\n-keep public class * extends android.view.View\n-keepclassmembers class * extends android.app.Fragment { public void *(android.view.View); }`\n\n**The Fix:** Delete these manual rules. AAPT2 handles this automatically.\n\n*** ** * ** ***\n\n## Case: Official Android and Kotlin Libraries\n\nKeep rules targeting official library packages like AndroidX, Kotlin, and\nKotlinx are redundant as they are bundled within the libraries themselves.\nManual rules are often broader than what is strictly needed.\n\n**Common Mistakes:**\n`proguard\n-keep class androidx.** { *; }\n-keep class kotlinx.** { *; }\n-keep class kotlin.** { *; }`\n\n**The Fix:** Delete these manual rules. Rely on the consumer keep rules packaged\nwithin these dependencies.\n\n*** ** * ** ***\n\n## Case: Gson\n\n### Overly Broad Data Model Rules\n\nThe most common mistake is keeping entire packages of data models (POJOs/DTOs),\nkeeping data models at all for deserialization is unnecessary.\n\n    -keep class com.example.app.models.** { *; }\n    -keep class com.example.app.package.models.* { *; }\n\n### Redundant Interface \\& Adapter Rules\n\nThese rules added for TypeAdapter are unnecessary and are already covered by\nthe library, and prevent R8 from effectively shrinking and optimizing custom\nadapters. R8 can determine if the adapter implementation are used. Keeping them\nglobally prevents the removal of unused adapter implementations.\n\n    -keep class * extends com.google.gson.TypeAdapter\n    -keep class * implements com.google.gson.TypeAdapterFactory\n    -keep class * implements com.google.gson.JsonSerializer\n    -keep class * implements com.google.gson.JsonDeserializer\n\n### Unnecessary TypeToken Rules\n\nThere is no need to handle generic type erasure, Gson's own rules handle the\nnecessary `TypeToken` preservation.\n\n    -keep class com.google.gson.reflect.TypeToken { *; }\n    -keep class * extends com.google.gson.reflect.TypeToken\n    -keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken\n\n### Internal and Example Packages\n\nKeeping internal library logic prevents the compiler from stripping away dead\ncode within the library.\n\n    -keep class com.google.gson.internal.** { *; }\n    -keep class com.google.gson.internal.reflect.** { *; }\n    -keep class com.google.gson.internal.UnsafeAllocator { *; }\n    -keep class com.google.gson.stream.** { *; }\n\n- **Keeps Unused Code:** Prevents R8 from removing models that are never actually used in the code.\n- **Prevents Method Stripping:** Keeps all getters, setters, `toString()`, `equals()`, and `hashCode()` methods, even if they are never called.\n- **Blocks Obfuscation:** Prevents the class names from being obfuscated, which is unnecessary for Gson if you use `@SerializedName`.\n\n**The Fix:**\n\n1. Use `@SerializedName` on every field in your data classes uses so that the field is retained after R8 optimization\n2. Modern Gson (**v2.11.0+** ) bundles its own rules ([View Gson's embedded\n   ProGuard\n   rules](https://github.com/google/gson/blob/main/gson/src/main/resources/META-INF/proguard/gson.pro)). The bundled keep rules retains the `@SerializedName` annotated fields. If you are on an older version, move towards Gson version 2.11 because it has the necessary keep rules and delete the keep rules that target the classes used for gson serialization and deserialization\n\n*** ** * ** ***\n\n## Case: Retrofit\n\nRetrofit has shipped with its own consumer keep rules from 2.9.0 and higher, so\nany keep rules for the library or classes depending on Retrofit is detrimental\nto the optimization process.\n\n### Blanket Library Preservation\n\nThis is the most harmful Retrofit rule as it disables any shrinking for the\nentire library.\n\n    -keep class retrofit2.** { *; }\n    -keep class retrofit2.api.** { *; }\n    -keep class com.package.example.retrofit.api.** { *; }\n\n### Manual Annotation Keeps\n\nRetrofit's consumer rules automatically keep the interfaces annotated with\n`@GET`, `@POST`, `@DELETE`, `@PUT`, `@HEAD`, `@OPTIONS`, `@PATCH`, making these\nmanual rules obsolete.\n\n`-keepclasseswithmembers class * { @retrofit2.http.* <methods>; }`\n\n### Redundant Network Response and Adapter Rules\n\nNetwork responses and third-party adapter wrappers (like RxJava) are often\noverly preserved by developers out of caution.\n\n    -keep,allowobfuscation,allowshrinking class retrofit2.Response\n    -keep class retrofit2.adapter.rxjava2.Result { *; }\n\nFix: Verify you are using Retrofit 2.9.0 and higher. Retrofit from 2.9.0 bundles\nrules that detect its own HTTP annotations (@GET, @POST) ([View Retrofit's\nembedded ProGuard\nrules](https://github.com/square/retrofit/blob/master/retrofit/src/main/resources/META-INF/proguard/retrofit2.pro)).\nIt will automatically keep the method signatures it needs to work.\n\n*** ** * ** ***\n\n## Case: Kotlin Coroutines\n\nKotlin Coroutines comes heavily optimized out of the box with embedded R8 rules\n(`kotlinx-coroutines-core` includes its own rules).\n\n### Blanket Coroutine Library Rules\n\nKeeping everything under `kotlinx.coroutines` is extremely detrimental to app\nsize, as coroutines contain a vast amount of internal APIs that aren't used.\n\n`-keepclassmembers class kotlinx.coroutines.** { *; }`\n\n### Redundant Internal Continuations\n\nThese low-level coroutine elements are preserved safely by the library's own\nconsumer rules. Manually adding these prevents R8 from performing internal\noptimizations (such as removing unused continuations or inlining).\n\n    -keepclassmembers class kotlin.coroutines.SafeContinuation { *; }\n    -keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation\n\n### Dispatcher and Exception Handler Rules\n\nSometimes developers notice crashes related to Missing Classes on old Android\nversions and add these rules, but if you are using an up-to-date version of\nCoroutines, these are handled automatically or are not an issue.\n\n    -keepnames class kotlinx.coroutines.internal.MainDispatcherFactory {}\n    -keepnames class kotlinx.coroutines.CoroutineExceptionHandler {}\n    -keepnames class kotlinx.coroutines.android.AndroidExceptionPreHandler {}\n    -keepnames class kotlinx.coroutines.android.AndroidDispatcherFactory {}\n\n**Fix** Remove any broad `kotlinx` keep rules. Coroutines (**v1.7.0+** ) bundle\nthe necessary keep rules ([View Coroutines' embedded ProGuard\nrules](https://github.com/Kotlin/kotlinx.coroutines/blob/master/kotlinx-coroutines-core/jvm/resources/META-INF/proguard/coroutines.pro)).\n\n*** ** * ** ***\n\n## Case: Parcelable\n\n**Common Mistakes:** Legacy projects often contain `-keep class * implements\nandroid.os.Parcelable { public static final android.os.Parcelable$Creator *; }`.\n\n**The Fix:**\n\n1. Add the `kotlin-parcelize` plugin.\n2. **Use `@Parcelize`:** Replace manual `writeToParcel` logic with the `@Parcelize` annotation.\n3. **Delete All Parcelable Rules:** The plugin automatically generates the required rules.\n4. The default proguard file `proguard-android-optimize.txt` contains the keep rules for keeping all the parcelable classes\n5. **Ideal Rule:** **None.** Delete all manual Parcelable keeps.\n\n*** ** * ** ***\n\n## Case: Room Database\n\n**Common Mistakes:** Keeping DAO interfaces or the generated `_Impl` classes\nmanually.\n\n    -keep class * extends androidx.room.RoomDatabase\n    -keep class *_*Impl { *; }\n\n**The Fix:** Room generates its own ProGuard rules for the code it creates.\nManual rules are redundant and prevent R8 from optimizing the database access\nlayers.\n\n- **Ideal Rule:** **None.** Delete all manual Room or DAO keeps.\n\n*** ** * ** ***\n\n## Summary\n\nIf you have updated your libraries to the versions mentioned, your\n`proguard-rules.pro` must not contain any keep rules for the libraries\nmentioned here.\n"
  },
  {
    "path": ".claude/skills/r8-analyzer/references/REFLECTION-GUIDE.md",
    "content": "A categorized summary of the keep rule examples, including the code patterns to\nlook for (imports/usage) and the corresponding suggested rules.\n\n### 1. Reflection: Classes Loaded by Name\n\n**Scenario:** A library or app loads a class dynamically using a string name\n\n- **Look for:**\n  `Class.forName(\"...\")`,\n  `getDeclaredConstructor().newInstance()`, or interfaces used for dynamic loading.\n\n- **Example Code:**\n  `kotlin\n  val taskClass = Class.forName(className)\n  val task = taskClass.getDeclaredConstructor().newInstance() as StartupTask`\n\n- **Suggested Keep Rule:**\n  \\`\\`\\`proguard\n\n  -keep class \\* implements com.example.library.StartupTask {\n  (); } \\`\\`\\`\n\n### 2. Reflection: Classes Passed using `::class.java`\n\n**Scenario:** An app passes a class reference directly to a library function.\n\n- **Look for:** `::class.java` (Kotlin) or `.class` (Java) passed as an argument.\n- **Example Code:**\n  `kotlin\n  fun <T> register(clazz: Class<T>) { }\n  // Usage:\n  register(MyService::class.java)`\n\n- **Suggested Keep Rule:**\n  \\`\\`\\`proguard\n\n  # Keep the class itself (R8 usually handles this, but explicit rules ensure stability)\n\n  -keep class com.example.app.MyService {\n  (); } \\`\\`\\`\n\n### 3. Annotation-Based Reflection (Methods/Classes)\n\n**Scenario:** Using custom annotations to mark methods or classes for reflective\nexecution.\n\n**Look for:** Custom `@interface` definitions and `getDeclaredMethods()`\nfiltered by annotation.\n**Example Code:**\n`kotlin\nannotation class ReflectiveExecutor\n// Logic: find methods annotated with @ReflectiveExecutor and invoke them`\n\n- **Suggested Keep Rule:** \\`\\`\\`proguard # Keep the annotation itself -keep @interface com.example.library.ReflectiveExecutor\n\n# Keep members of any class annotated with this specific annotation\n-keepclassmembers class \\* {\n@com.example.library.ReflectiveExecutor \\*;\n}\n\\`\\`\\`\n\n### 4. Optional Dependencies (Soft Dependencies)\n\n**Scenario:** A core library checks if an optional module is present in the\nclasspath.\n\n- **Look for:** `try-catch` blocks around `Class.forName()` used to toggle features.\n- **Example Code:** \\`\\`\\`kotlin private const val VIDEO_TRACKER_CLASS = \"com.example.analytics.video.VideoEventTracker\"\n\ntry {\nClass.forName(VIDEO_TRACKER_CLASS).getDeclaredConstructor().newInstance()\n} catch (e: ClassNotFoundException) { /\\* skip feature \\*/ }\n\\`\\`\\`\n\n- **Suggested Keep Rule:** `proguard\n  # Preserve the optional class so the check doesn't fail due to shrinking\n  -keep class com.example.analytics.video.VideoEventTracker {\n  <init>();\n  }`\n\n### 5. Accessing Private Members\n\n**Scenario:** Using reflection to access internal fields or methods not exposed\nwith public APIs.\n\n- **Look for:** `getDeclaredField(\"...\")` or `getDeclaredMethod(\"...\")` followed by `isAccessible = true`.\n- **Example Code:**\n  `kotlin\n  val secretField = instance::class.java.getDeclaredField(\"secretMessage\")\n  secretField.isAccessible = true`\n\n- **Suggested Keep Rule:**\n  \\`\\`\\`proguard\n\n  # Specifically keep the private field/method by name and type\n\n  -keepclassmembers class com.example.LibraryClass {\n  private java.lang.String secretMessage;\n  }\n  \\`\\`\\`\n\n### 6. Parcelable (Manual Implementation)\n\n**Scenario:** Implementing `Parcelable` without using the `@Parcelize`\nannotation.\n\n- **Look for:** `implements Parcelable` and a static `CREATOR` field.\n- **Example Code:**\n  `kotlin\n  class MyData : Parcelable {\n  // Manual implementation with CREATOR field\n  }`\n\n- **Suggested Keep Rule:**\n  *(Note: If using `import kotlinx.parcelize.Parcelize`, R8/ProGuard rules are\n  generated automatically. If manual, use the following:)*\n  `proguard\n  -keepclassmembers class * implements android.os.Parcelable {\n  static android.os.Parcelable$Creator CREATOR;\n  }`\n\n### 7. Enums and Obfuscation\n\n**Scenario:** App uses `Enum.valueOf(\"STRING_NAME\")` indirectly (e.g.,using JSON\ndeserialization) and the enum names get obfuscated.\n\n- **Look for:** Unnecessary generic Enum keep rules in ProGuard files.\n- **Example Code:**\n  \\`\\`\\`proguard\n\n  # Unnecessary rule\n\n  -keepclassmembers enum \\* { \\*; }\n  \\`\\`\\`\n- **Suggested Keep Rule:**\n  \\*(Note: The default `proguard-android-optimize.txt` already contains the optimal\n  rules for Enums (keeping `values()` and `valueOf(String)`). Any additional\n  manual rules for Enums are redundant.) # No manual rule needed. Use default\n  proguard-android-optimize.txt.\n"
  },
  {
    "path": ".claude/skills/r8-analyzer/references/android/topic/performance/app-optimization/enable-app-optimization.md",
    "content": "For the best user experience, you should optimize your app to make it as small\nand fast as possible. Our app optimizer, called R8, streamlines your app by\nremoving unused code and resources, rewriting code to optimize runtime\nperformance, and more. To your users, this means:\n\n- Faster startup time\n- Reduced memory usage\n- Improved rendering and runtime performance\n- Fewer [ANRs](https://developer.android.com/topic/performance/anrs/keep-your-app-responsive)\n\n> [!IMPORTANT]\n> **Important:** You should always enable optimization for your app's release build; however, you probably don't want to enable it for tests or libraries. For more information about using R8 with tests, see [Test and troubleshoot the\n> optimization](https://developer.android.com/topic/performance/app-optimization/test-and-troubleshoot-the-optimization). For more information about enabling R8 from libraries, see [Optimization for library authors](https://developer.android.com/topic/performance/app-optimization/library-optimization).\n\n## R8 optimization overview\n\nR8 uses a multi-phase process to optimize your app for size and speed. Key\noperations include the following:\n\n- **Code shrinking (also known as tree shaking)** : R8 identifies and removes\n  unreachable code from your application and its library dependencies. By\n  analyzing the entry points of your app (such as `Activities` or `Services`\n  defined in the manifest), R8 builds a graph of referenced code and removes\n  anything that remains unreferenced.\n\n- **Logical optimizations**: R8 rewrites your code to improve execution\n  efficiency and reduce overhead. Key techniques include:\n\n  - **Method inlining**: R8 replaces a method call site with the actual body\n    of the called method. This eliminates the overhead of a function call and\n    lets R8 conduct further optimizations.\n\n  - **Class merging**: R8 combines sets of classes and interfaces into a\n    single class. This reduces the number of classes in the app, lowering\n    memory pressure and improving startup speed.\n\n- **Obfuscation (also known as minification)** : To reduce the size of the DEX\n  file, R8 shortens the names of classes, fields, and methods (for example,\n  `com.example.MyActivity` could become `a.b.a`).\n\nSince 8.12.0 version of Android Gradle Plugin (AGP), R8 also optimizes resources\nas part of its optimization phases. For more information, see [Optimized\nresource shrinking](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization#optimize-resource-shrinking).\n\n## Enable optimization\n\nTo enable app optimization, set `isMinifyEnabled = true` (for code optimization)\nand `isShrinkResources = true` (for resource optimization) in your [release\nbuild's](https://developer.android.com/studio/publish/preparing#turn-off-debugging) app-level build script as shown in the following code. We recommend\nthat you always enable both settings. We also recommend enabling app\noptimization only in the final version of your app that you test before\npublishing---usually your release build---because the optimizations increase the\nbuild time of your project and can make debugging harder due to the way it\nmodifies code.\n\n### Kotlin\n\n```kotlin\nandroid {\n    buildTypes {\n        release {\n\n            // Enables code-related app optimization.\n            isMinifyEnabled = true\n\n            // Enables resource shrinking.\n            isShrinkResources = true\n\n            proguardFiles(\n                // Default file with automatically generated optimization rules.\n                getDefaultProguardFile(\"proguard-android-optimize.txt\"),\n\n                ...\n            )\n            ...\n        }\n    }\n    ...\n}\n```\n\n### Groovy\n\n```groovy\nandroid {\n    buildTypes {\n        release {\n\n            // Enables code-related app optimization.\n            minifyEnabled = true\n\n            // Enables resource shrinking.\n            shrinkResources = true\n\n            // Default file with automatically generated optimization rules.\n            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')\n\n            ...\n        }\n    }\n}\n```\n\n## Optimize resource shrinking for even smaller apps\n\nThe 8.12.0 version of Android Gradle Plugin (AGP) introduces optimized resource\nshrinking, which aims to integrate resource and code optimization to create even\nsmaller and faster apps.\n\nBefore optimized resource shrinking, Android Asset Packaging Tool (AAPT2)\ngenerated keep rules that effectively treating resource shrinking separately\nfrom code, often retaining inaccessible code or resources that referenced each\nother.\n\nWith optimized resource shrinking, resources are considered like a part of\nprogram code, forming the reference graph. When a collection of code or\nresources is not referenced, it is not protected by a keep rule, and can be\nremoved.\n\n### Enable optimized resource shrinking\n\nTo turn on the new optimized resource shrinking pipeline for a version of AGP\nbefore 9.0.0, add the following to your project's `gradle.properties` file:\n\n    android.r8.optimizedResourceShrinking=true\n\nIf you are using AGP 9.0.0 or a newer version, you don't need to set\n`android.r8.optimizedResourceShrinking=true`. Optimized resource shrinking is\nautomatically applied when `isShrinkResources = true` is enabled in your build\nconfiguration.\n\n## Verify and configure R8 optimization settings\n\nTo enable R8 to use its [full optimization capabilities](https://developer.android.com/topic/performance/app-optimization/full-mode), remove the\nfollowing line from your project's `gradle.properties` file, if it exists:\n\n    android.enableR8.fullMode=false # Remove this line from your codebase.\n\nNote that enabling app optimization makes stack traces difficult to understand,\nespecially if R8 renames class or method names. To get stack traces that\ncorrectly correspond to your source code, see [Recover the original stack\ntrace](https://developer.android.com/topic/performance/app-optimization/test-and-troubleshoot-the-optimization#recover-original-stack-trace).\n\nIf R8 is enabled, you should also [create Startup Profiles](https://developer.android.com/topic/performance/baselineprofiles/dex-layout-optimizations) for even better\nstartup performance.\n\nIf you enable app optimization and it causes errors, here are some strategies to\nfix them:\n\n- [Add keep rules](https://developer.android.com/topic/performance/app-optimization/add-keep-rules) to keep some code untouched.\n- [Adopt optimizations incrementally](https://developer.android.com/topic/performance/app-optimization/adopt-optimizations-incrementally).\n- Update your code to [use libraries that are better suited for\n  optimization](https://developer.android.com/topic/performance/app-optimization/choose-libraries-wisely).\n\n> [!CAUTION]\n> **Caution:** Tools that replace or modify R8's output can negatively impact runtime performance. R8 is careful about including and testing many optimizations at the code level, in [DEX layout](https://developer.android.com/topic/performance/baselineprofiles/dex-layout-optimizations), and in correctly producing Baseline Profiles - other tools producing or modifying DEX files can break these optimizations, or otherwise regress performance.\n\nIf you are interested in optimizing your build speed, see [Configure how R8\nruns](https://developer.android.com/build/r8-execution-profiles) for information on how to configure R8 based on your environment.\n\n## AGP and R8 version behavior changes\n\nThe following table outlines the key features introduced in various versions of\nthe Android Gradle Plugin (AGP) and the R8 compiler.\n\n| AGP version | Features introduced |\n|---|---|\n| 9.1 | **Classes repackaged by default:** R8 repackages classes (moving them to the unnamed package, at the top level) to compact DEX further, eliminating the need to specify `-repackageclasses` option. For information about how this works and how to opt out, see [global options](https://developer.android.com/topic/performance/app-optimization/global-options#global-options). |\n| 9.0 | **Optimized resource shrinking:** Enabled by default (controlled using `android.r8.optimizedResourceShrinking`). [Optimized resource shrinking](https://developer.android.com/topic/performance/app-optimization/enable-app-optimization#optimize-resource-shrinking) helps integrate resource shrinking with the code optimization pipeline, leading to smaller, faster apps. By optimizing both code and resource references simultaneously, it identifies and removes resources referenced exclusively from unused code. This is a significant improvement over the previous separate optimization processes. This is especially useful for apps that share substantial resources and code across different form factor verticals, with measured improvements of over 50% in app size. The resulting size reduction leads to smaller downloads, faster installations, and a better user experience with faster startup, improved rendering, and fewer ANRs. **Library rule filtering:** Support for global options (for example, `-dontobfuscate`) in library consumer rules has been dropped, and apps will filter them out. For more information, see [Add global options](https://developer.android.com/topic/performance/app-optimization/global-options). **Kotlin null checks:** Optimized by default (controlled using `-processkotlinnullchecks`). This version also introduced significant improvements in build speed. For more information, see [Global options for additional optimization](https://developer.android.com/topic/performance/app-optimization/global-options#global-options). **Optimize specific packages:** You can use `packageScope` to optimize specific packages. This is in experimental support. For more information, see [Optimize specified packages with `packageScope`](https://developer.android.com/topic/performance/app-optimization/optimize-specified-packages). **Optimized by default:** Support for `getDefaultProguardFile(\"proguard-android.txt\")` has been dropped, because it includes `-dontoptimize`, which should be avoided. Instead, use `\"proguard-android-optimize.txt\"`. If you need to globally disable optimization in your app, [add the flag manually to a proguard file](https://developer.android.com/topic/performance/app-optimization/global-options#global-options-2). |\n| 8.12 | **Resource shrinking:** Initial support added (Off by default. Enable using `isShrinkResources`). Resource shrinking works in tandem with R8 to identify and remove unused resources effectively. **Logcat retracing:** Support for automatic retracing in the Android Studio [Logcat window](https://developer.android.com/studio/debug/logcat). |\n| 8.6 | **Improved retracing:** Includes filename and line number retracing by default for all `minSdk` levels (previously required `minSdk` 26+ in version 8.2). Updating R8 helps ensure that stack traces from obfuscated builds are readily and clearly readable. This version improves how line numbers and source files are mapped, making it easier for tools like the Android Studio Logcat to automatically retrace crashes to the original source code. |\n| 8.0 | **Full mode by default:** [R8 full mode](https://developer.android.com/topic/performance/app-optimization/full-mode) provides significantly more powerful optimization. It is enabled by default. You can opt out using `android.enableR8.fullMode=false`. |\n| 7.0 | **Full mode available:** Introduced as an opt-in feature using `android.enableR8.fullMode=true`. Full mode applies more powerful optimizations by making stricter assumptions about how your code uses reflection and other dynamic features. While it reduces app size and improves performance, it might require additional keep rules to prevent necessary code from being stripped. |\n"
  },
  {
    "path": ".editorconfig",
    "content": "# https://editorconfig.org/\n# This configuration is used by ktlint when spotless invokes it\n\n[*]\n# Most of the standard properties are supported\nindent_size=2\nmax_line_length=100\n\n[*.{kt,kts}]\nij_kotlin_allow_trailing_comma=true\nij_kotlin_allow_trailing_comma_on_call_site=true\nktlint_function_naming_ignore_when_annotated_with=Composable,Test\ncompose_allowed_composition_locals=LocalJetLimeStyle"
  },
  {
    "path": ".github/workflows/build.yml",
    "content": "name: Build\n\non:\n  push:\n    branches: [ main ]\n  pull_request:\n    branches: [ main ]\n    types: [ opened, synchronize, reopened, ready_for_review ]\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}\n  cancel-in-progress: true\n\njobs:\n  lint:\n    name: Spotless check\n    runs-on: macos-latest\n    steps:\n      - name: Check out code\n        uses: actions/checkout@v6\n      - name: Set up JDK\n        uses: actions/setup-java@v5.0.0\n        with:\n          distribution: 'zulu'\n          java-version: 21\n      - name: spotless\n        run: ./gradlew spotlessCheck\n\n  build:\n    strategy:\n      matrix:\n        platform: [ android, ios, web-wasm, web-js, desktop ]\n        include:\n          - platform: android\n            os: ubuntu-latest\n          - platform: web-wasm\n            os: ubuntu-latest\n          - platform: web-js\n            os: ubuntu-latest\n          - platform: ios\n            os: macos-latest\n          - platform: desktop\n            os: macos-latest\n\n    runs-on: ${{ matrix.os }}\n\n    steps:\n      - name: Checkout code\n        uses: actions/checkout@v6\n\n      - name: Java and Gradle set up\n        if: matrix.platform != 'ios'\n        uses: ./.github/workflows/setup/java-setup\n\n      - name: iOS set up\n        if: matrix.platform == 'ios'\n        uses: ./.github/workflows/setup/ios-setup\n\n      # Android\n      - name: Grant execute permission for Android script\n        if: matrix.platform == 'android'\n        run: chmod +x ./scripts/build_android.sh\n\n      - name: Build Android\n        if: matrix.platform == 'android'\n        run: ./scripts/build_android.sh\n\n      # iOS\n      - name: Grant execute permission for iOS script\n        if: matrix.platform == 'ios'\n        run: chmod +x ./scripts/build_ios.sh\n\n      - name: Build iOS\n        if: matrix.platform == 'ios'\n        run: ./scripts/build_ios.sh\n\n      # Web-WASM\n      - name: Grant execute permission for Web WASM script\n        if: matrix.platform == 'web-wasm'\n        run: chmod +x ./scripts/build_web_wasm.sh\n\n      - name: Build Web WASM\n        if: matrix.platform == 'web-wasm'\n        run: ./scripts/build_web_wasm.sh\n\n      # Web-JS\n      - name: Grant execute permission for Web JS script\n        if: matrix.platform == 'web-js'\n        run: chmod +x ./scripts/build_web_js.sh\n\n      - name: Build Web JS\n        if: matrix.platform == 'web-js'\n        run: ./scripts/build_web_js.sh\n\n      # MacOS\n      - name: Grant execute permission for MacOS script\n        if: matrix.platform == 'desktop'\n        run: chmod +x ./scripts/build_macos.sh\n\n      - name: Build MacOS\n        if: matrix.platform == 'desktop'\n        run: ./scripts/build_macos.sh"
  },
  {
    "path": ".github/workflows/publish.yml",
    "content": "name: Publish to Maven Central\n\non:\n  workflow_dispatch:\n    inputs:\n      version:\n        description: 'Version to publish (e.g., 4.2.0)'\n        required: true\n        type: string\n\njobs:\n  publish:\n    name: Release and Publish\n    runs-on: macos-latest\n    permissions:\n      contents: write\n    steps:\n      - name: Check out code\n        uses: actions/checkout@v4\n        with:\n          fetch-depth: 0\n          token: ${{ secrets.GITHUB_TOKEN }}\n\n      - name: Set up Java and Gradle\n        uses: ./.github/workflows/setup/java-setup\n\n      - name: Update version in project files\n        shell: bash\n        run: |\n          VERSION=\"${{ github.event.inputs.version }}\"\n\n          # Update coordinates in jetlime/build.gradle.kts\n          sed -i '' \"s/coordinates(\\\"io.github.pushpalroy\\\", artifactId, \\\".*\\\")/coordinates(\\\"io.github.pushpalroy\\\", artifactId, \\\"$VERSION\\\")/g\" jetlime/build.gradle.kts\n\n          # Update cocoapods version in jetlime/build.gradle.kts\n          sed -i '' \"/cocoapods {/,/}/ s/version = \\\".*\\\"/version = \\\"$VERSION\\\"/\" jetlime/build.gradle.kts\n\n          # Update podspec version\n          sed -i '' \"s/spec.version                  = '.*'/spec.version                  = '$VERSION'/g\" jetlime/jetlime.podspec\n\n          # Update git tag script\n          sed -i '' \"s/TAG=\\\".*\\\"/TAG=\\\"$VERSION\\\"/g\" scripts/add_git_tag.sh\n\n          # Update README installation snippet\n          sed -i '' \"s/implementation(\\\"io.github.pushpalroy:jetlime:.*\\\")/implementation(\\\"io.github.pushpalroy:jetlime:$VERSION\\\")/g\" README.md\n\n          # Update commented-out maven testing snippet in sample app\n          sed -i '' \"s|// implementation(\\\"io.github.pushpalroy:jetlime:.*\\\")|// implementation(\\\"io.github.pushpalroy:jetlime:$VERSION\\\")|g\" sample/composeApp/build.gradle.kts\n\n      - name: Publish to Maven Central\n        shell: bash\n        env:\n          ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.MAVEN_CENTRAL_USERNAME }}\n          ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}\n          ORG_GRADLE_PROJECT_signingInMemoryKeyId: ${{ secrets.SIGNING_KEY_ID }}\n          ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_IN_MEMORY_KEY }}\n          ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_PASSWORD }}\n        run: |\n          ./gradlew publishAndReleaseToMavenCentral --no-configuration-cache\n\n      - name: Generate Dokka API docs\n        shell: bash\n        run: |\n          ./scripts/run_dokka.sh\n\n      - name: Commit version updates\n        shell: bash\n        run: |\n          git config --global user.name \"github-actions[bot]\"\n          git config --global user.email \"github-actions[bot]@users.noreply.github.com\"\n          git add .\n          git commit -m \"Bump version to ${{ github.event.inputs.version }}\"\n          git push origin main\n\n      - name: Create and push git tag\n        shell: bash\n        run: |\n          VERSION=\"${{ github.event.inputs.version }}\"\n          git tag -a \"$VERSION\" -m \"Release $VERSION\"\n          git push origin \"$VERSION\"\n\n      - name: Create GitHub release\n        shell: bash\n        env:\n          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        run: |\n          VERSION=\"${{ github.event.inputs.version }}\"\n          gh release create \"$VERSION\" \\\n            --title \"v$VERSION\" \\\n            --target main \\\n            --generate-notes\n"
  },
  {
    "path": ".github/workflows/setup/ios-setup/action.yml",
    "content": "name: iOS set up\ndescription: Sets up Kotlin Native and Cocoapods\nruns:\n  using: \"composite\"\n  steps:\n    - shell: bash\n      run: ./gradlew :sample:composeApp:generateDummyFramework\n\n    - name: Set up cocoapods\n      uses: maxim-lobanov/setup-cocoapods@v1\n      with:\n        version: latest\n\n    - shell: bash\n      name: Install Dependencies\n      run: |\n        cd sample/iosApp\n        pod install --verbose"
  },
  {
    "path": ".github/workflows/setup/java-setup/action.yml",
    "content": "name: Java and Gradle Job Setup\ndescription: Sets up Java and Gradle\nruns:\n  using: \"composite\"\n  steps:\n    # Setup java\n    - name: Setup JDK 21\n      id: setup_jdk\n      uses: actions/setup-java@v5.0.0\n      with:\n        distribution: 'zulu'\n        java-version: 21\n\n    # Grant execute permission for gradlew\n    - name: Grant execute permission for gradlew\n      id: grant_gradle_permission\n      shell: bash\n      run: chmod +x gradlew\n\n    # Caching gradle packages\n    # TODO: remove temporary workaround after fixed\n    # temporarily work around https://github.com/actions/runner-images/issues/13341\n    # by disabling caching for macOS\n    - if: ${{ runner.os != 'macOS' }}\n      uses: actions/cache@v4\n      name: Cache Gradle for quicker builds\n      id: caching_gradle\n      with:\n        path: |\n          ~/.gradle/caches\n          ~/.gradle/wrapper\n        key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}\n        restore-keys: |\n          ${{ runner.os }}-gradle-\n\n    # Setup Gradle\n    - name: Set up Gradle\n      id: set_up_gradle\n      uses: gradle/actions/setup-gradle@v4"
  },
  {
    "path": ".gitignore",
    "content": "# Built application files\n*.apk\n*.aar\n*.ap_\n*.aab\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Kotlin libraries\n.kotlin/\n\napp/\ndistributions/\n\n# Generated files\nbin/\ngen/\nout/\n#  Uncomment the following line in case you need and you don't have the release build type files in your app\n# release/\n\n# Gradle files\n.gradle/\nbuild/\n\n# Local configuration file (sdk path, etc)\nlocal.properties\nkeystore_release.properties\n\n# Proguard folder generated by Eclipse\nproguard/\n\n# Log Files\n*.log\n\n# Android Studio Navigation editor temp files\n.navigation/\n\n# Android Studio captures folder\ncaptures/\n\n# IntelliJ\n*.iml\n.idea/\n\n# Keystore files\n# Uncomment the following lines if you do not want to check your keystore files in.\n#*.jks\n#*.keystore\n\n# External native build folder generated in Android Studio 2.2 and later\n.externalNativeBuild\n.cxx/\n\n# Google Services (e.g. APIs or Firebase)\n# google-services.json\n\n# Freeline\nfreeline.py\nfreeline/\nfreeline_project_description.json\n\n# fastlane\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots\nfastlane/test_output\nfastlane/readme.md\n\n# Version control\nvcs.xml\n\n# lint\nlint/intermediates/\nlint/generated/\nlint/outputs/\nlint/tmp/\n# lint/reports/\n"
  },
  {
    "path": "CLAUDE.md",
    "content": "# CLAUDE.md\n \nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n \n## Project Overview\n \nJetLime is a Kotlin Multiplatform (KMP) Compose Multiplatform library that renders customizable timeline UIs. Targets: Android, iOS (x64/arm64/simulator), Desktop (JVM), JS (IR), WasmJs. The published artifact is `io.github.pushpalroy:jetlime`.\n \nThe repo has two Gradle modules:\n- `:jetlime` — the library (all platform source in `src/commonMain/kotlin/com/pushpal/jetlime/`; Android-specific manifest + instrumented tests in `src/androidMain` and `src/androidTest`).\n- `:sample:composeApp` — a sample app that consumes `:jetlime` via `implementation(project(\":jetlime\"))` and runs on all five targets (Android, iOS via CocoaPods, Desktop, Web-JS, Web-WASM).\nJDK 17 is required for builds; CI uses JDK 21 only for the Spotless lint job. Kotlin 2.3.20, Compose Multiplatform 1.10.3, `androidTarget` compileSdk 36 / minSdk 23.\n \n## Common Commands\n \nFormat / lint (required before PR — CI runs `spotlessCheck`):\n```\n./gradlew spotlessApply     # auto-fix\n./gradlew spotlessCheck     # verify\n```\nSpotless applies ktlint + `io.nlopez.compose.rules:ktlint` with a mandatory MIT license header from `spotless/copyright.kt`. `.editorconfig` enforces 2-space indent, `max_line_length=100`, trailing commas, and allow-lists `LocalJetLimeStyle` for the Compose ktlint rule (`compose_allowed_composition_locals`).\n \nLibrary tests (Compose UI tests — the real ones live in `jetlime/src/androidTest/`, not `src/test/`):\n```\n./gradlew :jetlime:connectedAndroidTest              # all instrumented tests (needs emulator/device)\n./gradlew :jetlime:connectedAndroidTest --tests \"com.pushpal.jetlime.JetLimeColumnTest.jetLimeColumn_displaysItems\"\n```\n \nSample app per-platform builds (wrap the right gradle tasks and copy outputs to `distributions/`):\n```\n./scripts/build_android.sh      # :sample:composeApp:assembleDebug\n./scripts/build_ios.sh          # xcodebuild on sample/iosApp/iosApp.xcworkspace\n./scripts/build_macos.sh        # :sample:composeApp:packageUberJarForCurrentOS\n./scripts/build_web_js.sh       # :sample:composeApp:jsBrowserDistribution\n./scripts/build_web_wasm.sh     # :sample:composeApp:wasmJsBrowserDistribution\n```\n \nAPI docs (Dokka V2 — output is synced into the root `docs/` directory that GitHub Pages serves):\n```\n./scripts/run_dokka.sh          # wraps :jetlime:syncDokkaToDocs --no-configuration-cache\n```\n \nPublishing (see `gradle.properties` for required credentials — `mavenCentralUsername`, `signing.*`):\n```\n./gradlew publishToMavenLocal                                     # test locally via ~/.m2\n./gradlew publishAndReleaseToMavenCentral --no-configuration-cache\n```\nTo test a local publish, uncomment the `maven` coordinate in `sample/composeApp/build.gradle.kts` and add `mavenLocal()` to `settings.gradle.kts`.\n \nCompose compiler metrics/reports:\n```\n./gradlew assembleRelease -PcomposeCompilerReports=true   # outputs under jetlime/build/compose_compiler/\n```\n \n## Architecture\n \nThe library is tiny (~11 files in `commonMain`) and built around three layers:\n \n1. **List containers** (`JetLimeList.kt`) — `JetLimeColumn` / `JetLimeRow` wrap `LazyColumn` / `LazyRow`. They install a `JetLimeStyle` via the `LocalJetLimeStyle` `CompositionLocal` and compute an `EventPosition` (`START` / `MIDDLE` / `END`) for each index via `EventPosition.dynamic(index, listSize)`. The arrangement (`VERTICAL` vs `HORIZONTAL`) is stamped on the style here and is how `JetLimeEvent` dispatches to `VerticalEvent` vs `HorizontalEvent`.\n2. **Events** (`JetLimeEvent.kt`, `JetLimeExtendedEvent.kt`) — `JetLimeEvent` is a single-slot composable that uses `Modifier.drawBehind` to paint the connecting line(s) and the point circle/icon. The per-item `JetLimeEventStyle` carries both the event's `EventPosition` (used to decide whether to draw the up/down or left/right connector segments via `isNotStart()` / `isNotEnd()`) and a `PointPlacement` (`START` / `CENTER` / `END`) that governs where the point sits within the item box and how the connector is split into two segments that meet at the point. `JetLimeExtendedEvent` (vertical-only) adds a second slot (`additionalContent`) rendered on the opposite side of the line; it uses a custom `Layout` and `BoxWithConstraints` capped by `JetLimeEventDefaults.AdditionalContentMaxWidth`.\n3. **Style + defaults** — `JetLimeStyle` (list-level: line brush, thickness, `pathEffect`, `contentDistance`, `itemSpacing`, alignment) and `JetLimeEventStyle` (per-event point visuals) are `@Immutable`. `JetLimeDefaults` / `JetLimeEventDefaults` expose the `columnStyle()` / `rowStyle()` / `eventStyle()` / `pointAnimation()` / `lineGradientBrush()` / `lineSolidBrush()` factory helpers — always extend these rather than constructing style classes directly (the constructors are `internal`).\n### Key drawing invariants\n \n- Line segments are drawn with Compose `drawLine`, branching on `PointPlacement` and `EventPosition`. For `CENTER`/`END` placement, the code draws two separate segments (start→point and point→end) and skips the relevant half at the first/last item. For `START` placement (default), a single segment extends from the point past the item box, with a `pointStartFactor = 1.1f` overdraw so adjacent items' lines visually join.\n- **RTL mirroring** is handled explicitly in `HorizontalEvent` and in `JetLimeExtendedEvent`. In horizontal RTL, the `xOffset` is flipped as `size.width - logicalXOffset` and segment start/end Xs swap sides. Extended vertical uses `LocalLayoutDirection` + `absolutePadding` so physical LEFT/RIGHT alignment is preserved regardless of layout direction. Any change to line/point drawing must keep both LTR and RTL visually correct — see the RTL tests in `JetLimeColumnTest` / `JetLimeRowTest`.\n- `VerticalAlignment.LEFT/RIGHT` and `HorizontalAlignment.TOP/BOTTOM` are *physical* sides (via `absolutePadding`), not start/end-relative.\n## Release Housekeeping\n \nThe library version appears in several places that must be kept in sync on release:\n- `jetlime/build.gradle.kts` — `mavenPublishing.coordinates(..., \"X.Y.Z\")` and `cocoapods { version = \"X.Y.Z\" }`\n- `jetlime/jetlime.podspec`\n- `scripts/add_git_tag.sh` — `TAG=\"X.Y.Z\"`\n- `README.md` installation snippet\nAfter publishing, `scripts/add_git_tag.sh` creates and pushes the `X.Y.Z` git tag on `main`.\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "## How to contribute\nWe'd love to accept your patches and contributions to this project. There are just a few small guidelines you need to follow.\n\n## Preparing a pull request for review\nEnsure your change is properly formatted by running:\n\n```gradle\n./gradlew spotlessApply\n```\n\nPlease correct any failures before requesting a review.\n\n## Code reviews\nAll submissions, including submissions by project members, require review. We use GitHub pull requests for this purpose. Consult [GitHub Help](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-pull-requests) for more information on using pull requests."
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2022 Pushpal Roy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "PUBLISHING.md",
    "content": "# Publishing to Maven Central\n\nJetLime is published to Maven Central via a manual GitHub Actions workflow (`publish.yml`).\nPublishing is triggered on demand — there is no automatic release on push.\n\n---\n\n## One-time Setup\n\n### 1. GPG Signing Key\n\nIf you do not already have a GPG key, generate one:\n\n```bash\ngpg --full-generate-key\n# Choose RSA, 4096 bits, no expiry, enter your name/email/passphrase\n```\n\nPublish your public key to a keyserver so Maven Central can verify it:\n\n```bash\ngpg --list-keys --keyid-format=short   # note the 8-char key ID, e.g. 1A2B3C4D\ngpg --keyserver keyserver.ubuntu.com --send-keys 1A2B3C4D\n```\n\n### 2. Export the Signing Key for CI\n\nVanniktech Maven Publish 0.36.0 requires the key body only — no armor headers, no newlines:\n\n```bash\ngpg --armor --export-secret-keys 1A2B3C4D \\\n  | tail -n +2 \\\n  | grep -v \"^-----END\" \\\n  | grep -v \"^=\" \\\n  | tr -d '\\n'\n```\n\nCopy the single-line output — this is your `SIGNING_IN_MEMORY_KEY` secret value.\n\n### 3. Maven Central Credentials\n\nLog in to [central.sonatype.com](https://central.sonatype.com), click your avatar in the top-right corner, and choose **Generate User Token**. This gives you a username and password scoped for publishing.\n\n### 4. Add GitHub Secrets\n\nGo to **GitHub → Repository → Settings → Secrets and variables → Actions → New repository secret** and add the following five secrets:\n\n| Secret name | Value |\n|---|---|\n| `MAVEN_CENTRAL_USERNAME` | Token username from Sonatype |\n| `MAVEN_CENTRAL_PASSWORD` | Token password from Sonatype |\n| `SIGNING_KEY_ID` | Short 8-char GPG key ID (e.g. `1A2B3C4D`) |\n| `SIGNING_IN_MEMORY_KEY` | Single-line output from the export command above |\n| `SIGNING_PASSWORD` | Passphrase used when creating the GPG key |\n\n`GITHUB_TOKEN` is provided automatically by GitHub Actions — do not add it manually.\n\n### 5. Branch Protection (if enabled)\n\nThe workflow commits the version bump directly to `main`. If branch protection requires pull requests, add `github-actions[bot]` as a bypass actor:\n\n**Settings → Branches → edit rule → Allow specified actors to bypass required pull requests**\n\n---\n\n## Releasing a New Version\n\n### Step 1 — Update the version\n\nThe workflow updates all version references automatically. The files it touches are:\n\n- `jetlime/build.gradle.kts` — `coordinates(...)` and `cocoapods { version }`\n- `jetlime/jetlime.podspec` — `spec.version`\n- `scripts/add_git_tag.sh` — `TAG=`\n- `README.md` — installation snippet\n\n### Step 2 — Trigger the workflow\n\n1. Go to **GitHub → Actions → Publish to Maven Central**\n2. Click **Run workflow**\n3. Enter the new version (e.g. `4.3.0`) and click **Run workflow**\n\n### What the workflow does\n\n| Step | Action |\n|---|---|\n| Checkout | Fetches `main` with full history |\n| Setup | Installs JDK 21 and Gradle |\n| Update versions | Runs `sed` across all version-bearing files |\n| Publish | Runs `publishAndReleaseToMavenCentral` — signs, uploads, and auto-releases |\n| Commit | Commits the version bump files and pushes to `main` |\n| Tag | Creates and pushes an annotated git tag (e.g. `4.3.0`) |\n\n### Step 3 — Verify\n\nOnce the workflow completes (~5–10 min):\n\n- The new version appears on [central.sonatype.com](https://central.sonatype.com) under `io.github.pushpalroy:jetlime`\n- A git tag for the version is visible in the repository\n- `main` has a new commit: `Bump version to X.Y.Z`\n\nIt can take up to 30 minutes for the artifact to appear in Maven search indexes.\n\n---\n\n## Testing a Publish Locally\n\nTo verify signing and upload work before triggering CI:\n\n```bash\n# Publish to your local ~/.m2 (no signing required)\n./gradlew publishToMavenLocal\n\n# Full signed publish to Maven Central (requires credentials in gradle.properties or env)\n./gradlew publishAndReleaseToMavenCentral --no-configuration-cache\n```\n\nTo consume the locally published artifact in the sample app, uncomment the `mavenLocal()` block in `settings.gradle.kts` and the `maven` coordinate in `sample/composeApp/build.gradle.kts`.\n"
  },
  {
    "path": "README.md",
    "content": "# JetLime 🍋\n\n> A simple yet highly customizable UI library to show a timeline view in Compose Multiplatform.\n\n[![Jetbrains Compose](https://img.shields.io/badge/Jetbrains%20Compose-1.10.3-blue?style=for-the-badge&logo=appveyor)](https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-compatibility-and-versioning.html#jetpack-compose-artifacts-used)\n![Kotlin](https://img.shields.io/badge/Kotlin-2.3.20-blue.svg?color=blue&style=for-the-badge)\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.pushpalroy/jetlime?style=for-the-badge&logo=appveyor)](https://search.maven.org/artifact/io.github.pushpalroy/jetlime)\n![Stars](https://img.shields.io/github/stars/pushpalroy/jetlime?color=yellowgreen&style=for-the-badge)\n![Forks](https://img.shields.io/github/forks/pushpalroy/jetlime?color=yellowgreen&style=for-the-badge)\n![Pull Request](https://img.shields.io/github/issues-pr/pushpalroy/jetlime?color=yellowgreen&style=for-the-badge)\n![Watchers](https://img.shields.io/github/watchers/pushpalroy/jetlime?color=yellowgreen&style=for-the-badge)\n![Issues](https://img.shields.io/github/issues/pushpalroy/jetlime?color=orange&style=for-the-badge)\n[![License](https://img.shields.io/github/license/pushpalroy/jetlime?color=blue&style=for-the-badge&logo=appveyor)](https://github.com/pushpalroy/jetlime/blob/master/LICENSE)\n\n![Sample Build CI](https://img.shields.io/github/actions/workflow/status/pushpalroy/jetlime/build.yml?style=for-the-badge&label=Sample%20Build)\n![badge][badge-android] ![badge][badge-ios] ![badge][badge-jvm] ![badge][badge-web]\n\n|                  Basic                  | Dashed                                   |                  Dynamic                  |\n|:---------------------------------------:|------------------------------------------|:-----------------------------------------:|\n|  <img src=\"art/basic.gif\" width=180 />  | <img src=\"art/dashed.png\" width=180 />   |  <img src=\"art/dynamic.gif\" width=180 />  |\n|                 Custom                  | Extended                                 |                                           |\n| <img src=\"art/custom.png\" width=180 />  | <img src=\"art/extended.png\" width=180 /> |                                           |\n\n### Supported Platform Samples\n\n|                     Android                      | iOS                                          |                     Desktop                     | Web                                         |\n|:------------------------------------------------:|----------------------------------------------|:-----------------------------------------------:|---------------------------------------------|\n| <img src=\"art/platform/android.png\" width=120 /> | <img src=\"art/platform/iOS.png\" width=120 /> | <img src=\"art/platform/desktop.png\" width=240/> | <img src=\"art/platform/web.png\" width=240/> |\n\n## ✨ Highlights\n- Compose Multiplatform timelines: Android, iOS, Desktop (JVM), Web (JS & WASM)\n- Vertical and horizontal layouts (JetLimeColumn / JetLimeRow)\n- Flexible point placement: START, CENTER, END with continuous line joins\n- RTL layout support for JetLimeRow and JetLimeExtendedEvent (mirrors timelines and keeps content visible in right-to-left layouts)\n- Dashed/gradient/solid lines via Brush + PathEffect\n- Extended events with dual content slots (left/right), icons, and animations\n- Small, focused API with sensible defaults (JetLimeDefaults)\n\n## 📦 Installation\n\nIn `build.gradle` of shared module, include the following dependency\n\n```gradle\ndependencies {\n  implementation(\"io.github.pushpalroy:jetlime:4.3.0\")\n}\n```\n\n## 📖 Usage\n\n### 📍 Add items in a Vertical Timeline\n\nUse the [JetLimeColumn](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-column.html)\n\n```kotlin\nval items = remember { mutableListOf(Item1, Item2, Item3) } // Any type of items\n\nJetLimeColumn(\n  modifier = Modifier.padding(16.dp),\n  itemsList = ItemsList(items),\n  key = { _, item -> item.id },\n) { index, item, position ->\n  JetLimeEvent(\n    style = JetLimeEventDefaults.eventStyle(\n      position = position\n    ),\n  ) {\n    // Content here\n  }\n}\n```\n### 📍 Add items in a Horizontal Timeline\n\nUse the [JetLimeRow](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-row.html)\n\n```kotlin\nval items = remember { mutableListOf(Item1, Item2, Item3) } // Any type of items\n\nJetLimeRow(\n  modifier = Modifier.padding(16.dp),\n  itemsList = ItemsList(items),\n  key = { _, item -> item.id },\n) { index, item, position ->\n  JetLimeEvent(\n    style = JetLimeEventDefaults.eventStyle(\n      position = position\n    ),\n  ) {\n    // Content here\n  }\n}\n```\n\nPass the `key` to define factory of stable and unique keys representing the item. Using the same key for multiple items in the list is not allowed.\nThis key will be used by a LazyColumn or LazyRow internally.\n\nIf we want to to add items dynamically from a data source, we should use `mutableStateListOf`, so that our list can be observed as a state:\n```kotlin\nval items = remember { mutableStateListOf<MyItem>() }\n```\n\n### 🧩 Extended Events (Vertical Timeline)\n\nUse the [JetLimeExtendedEvent](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-extended-event.html) with a [JetLimeColumn](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-column.html)\nUsing this we can pass an additional content to draw on the left side of the timeline.\n\n```kotlin\nval items = remember { mutableListOf(Item1, Item2, Item3) } // Any type of items\n\nJetLimeColumn(\n  modifier = Modifier.padding(16.dp),\n  itemsList = ItemsList(items),\n  key = { _, item -> item.id },\n  style = JetLimeDefaults.columnStyle(contentDistance = 24.dp),\n) { index, item, position ->\n  JetLimeExtendedEvent(\n    style = JetLimeEventDefaults.eventStyle(\n      position = position\n    ),\n    additionalContent = {\n      // Additional content here\n    }\n  ) {\n    // Content here\n  }\n}\n```\n\n### 🎛️ Customize `JetLimeColumn` Style\n\nUse the [JetLimeDefaults.columnStyle()](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-defaults/column-style.html)\n\n```kotlin\nJetLimeColumn(\n  style = JetLimeDefaults.columnStyle(\n    contentDistance = 32.dp,\n    itemSpacing = 16.dp,\n    lineThickness = 2.dp,\n    lineBrush = JetLimeDefaults.lineSolidBrush(color = Color(0xFF2196F3)),\n    lineVerticalAlignment = RIGHT,\n  ),\n) {\n  // Code to add events\n}\n```\n### 🎛️ Customize `JetLimeRow` Style\n\nUse the [JetLimeDefaults.rowStyle()](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-defaults/row-style.html)\n\n```kotlin\nJetLimeRow(\n  style = JetLimeDefaults.rowStyle(\n    contentDistance = 32.dp,\n    itemSpacing = 16.dp,\n    lineThickness = 2.dp,\n    lineBrush = JetLimeDefaults.lineSolidBrush(color = Color(0xFF2196F3)),\n    lineHorizontalAlignment = BOTTOM,\n  ),\n) {\n  // Code to add events\n}\n```\n\n### 🎛️ Customize `JetLimeEvent` Style\n\nUse the [JetLimeEventDefaults.eventStyle()](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-event-defaults/event-style.html)\n\n```kotlin\nJetLimeEvent(\n  style = JetLimeEventDefaults.eventStyle(\n    position = position,\n    pointColor = Color(0xFF2889D6),\n    pointFillColor = Color(0xFFD5F2FF),\n    pointRadius = 14.dp,\n    pointAnimation = JetLimeEventDefaults.pointAnimation(),\n    pointType = EventPointType.filled(0.8f),\n    pointStrokeWidth = 2.dp,\n    pointStrokeColor = MaterialTheme.colorScheme.onBackground,\n  ),\n) {\n  // Code to add event content\n}\n```\n---\n\n### ⚙️ JetLimeColumn and JetLimeRow Properties\n\n#### 🧭 Alignment\n\nThe timeline line and point circles can be set to either side.\n\nFor a `JetLimeColumn` the alignment can be set to [LEFT](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-vertical-alignment/index.html#825393495%2FClasslikes%2F-1761194290) or [RIGHT](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-vertical-alignment/index.html#861885460%2FClasslikes%2F-1761194290)\n\n```kotlin\nlineVerticalAlignment = LEFT or RIGHT // Default is LEFT\n```\n\nFor a `JetLimeRow` the alignment can be set to [TOP](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-horizontal-alignment/index.html#769734623%2FClasslikes%2F-1761194290) or [BOTTOM](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-horizontal-alignment/index.html#-1737811223%2FClasslikes%2F-1761194290)\n\n```kotlin\nlineHorizontalAlignment = TOP or BOTTOM // Default is TOP\n```\n\n#### 🎨 Line Style\n\nThe line can be drawn by passing a `Brush` object to [lineBrush](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-style/line-brush.html) in a `columnStyle` or `rowStyle`.\nDefault values can also be used from [JetLimeDefaults](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-defaults/index.html) and colors can be modified for quick setup:\n\n```kotlin\nlineBrush = JetLimeDefaults.lineGradientBrush()\n\nor\n\nlineBrush = JetLimeDefaults.solidBrush()\n```\n\nA dashed/dotted line can also be drawn using the `pathEffect` property by passing a `PathEffect` to a `columnStyle` or `rowStyle`.\n\n```kotlin\nstyle = JetLimeDefaults.columnStyle(\n        pathEffect = PathEffect.dashPathEffect(\n          intervals = floatArrayOf(30f, 30f),\n          phase = 0f,\n        )\n      )\n```\n\n#### ↔️ Content Distance\n\nThe [contentDistance](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-style/content-distance.html) in `Dp` specifies how far the timeline line should be from the timeline content.\n\n#### ↕️ Item Spacing\n\nThe [itemSpacing](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-style/item-spacing.html) in `Dp` specifies the gap between the event items.\n\n#### 📏 Line Thickness\n\nThe [lineThickness](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-style/line-thickness.html) in `Dp` the thickness of the timeline line.\n\n---\n\n### 🌍 RTL Layout Support\n\nJetLime supports right-to-left (RTL) layouts out of the box using Compose’s `LayoutDirection.Rtl`.\n\n- **Horizontal timelines (`JetLimeRow` + `JetLimeEvent`)**\n  - The timeline direction is mirrored in RTL.\n  - Start and end items are correctly connected.\n  - Points and lines stay aligned without clipping, and the last item’s line joins cleanly.\n\n- **Extended vertical events (`JetLimeExtendedEvent` inside `JetLimeColumn`)**\n  - Additional content remains fully visible on the side nearest the logical start.\n  - Main content remains fully visible on the opposite side.\n  - The timeline line and point stay between additional and main content without overlapping them.\n\nTo preview RTL behavior in your app, wrap your content with a `CompositionLocalProvider`:\n\n```kotlin\nCompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {\n  JetLimeColumn(\n    itemsList = ItemsList(items),\n    key = { _, item -> item.id },\n  ) { index, item, position ->\n    JetLimeExtendedEvent(\n      style = JetLimeEventDefaults.eventStyle(position = position),\n      additionalContent = { /* Additional content */ },\n    ) {\n      // Main content\n    }\n  }\n}\n```\n\n|                Basic (RTL)                | Dynamic (RTL)                               |                Extended (RTL)                |\n|:-----------------------------------------:|---------------------------------------------|:--------------------------------------------:|\n| <img src=\"art/rtl/basic.png\" width=180 /> | <img src=\"art/rtl/dynamic.png\" width=180 /> | <img src=\"art/rtl/extended.png\" width=180 /> |\n\n### ⚙️ JetLimeEvent Properties\n\n#### 📍 Position\n\nWe always need to pass the position to the [eventStyle](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-jet-lime-event-defaults/event-style.html) that will be received in the JetLimeColumn lambda.\nThis is needed so that JetLimeColumn can calculate the position of an event in the list at any time.\nBased on the calculation it will assign either of the three [EventPosition](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-event-position/index.html): `START`, `MIDDLE` or `END`.\nThis classification is needed to render correct lines for start and end items.\n\n```kotlin\nJetLimeColumn(\n  itemsList = ItemsList(items),\n  key = { _, item -> item.id },\n) { index, item, position ->\n  JetLimeEvent(\n    style = JetLimeEventDefaults.eventStyle(\n      position = position\n    ),\n  ) {\n    // Content here\n  }\n}\n```\n\n#### 📌 Point Placement\n\nThe `pointPlacement` of type [PointPlacement](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-point-placement/index.html) controls where the point renders within the item:\n- `START` – near the start edge (top for vertical, left for horizontal). Default.\n- `CENTER` – centered within the item.\n- `END` – near the end edge (bottom for vertical, right for horizontal).\n\nExamples:\n```kotlin\n// All items CENTER\nJetLimeEventDefaults.eventStyle(position = position, pointPlacement = PointPlacement.CENTER)\n\n// All items END\nJetLimeEventDefaults.eventStyle(position = position, pointPlacement = PointPlacement.END)\n\n// Mixed: second-to-last CENTER, rest START\nJetLimeEventDefaults.eventStyle(\n  position = position,\n  pointPlacement = if (index == items.size - 2) PointPlacement.CENTER else PointPlacement.START,\n)\n```\nNotes:\n- Lines connect continuously across START/CENTER/END, and stop cleanly at the last item’s point.\n- Works for both JetLimeColumn (vertical) and JetLimeRow (horizontal).\n\n#### 🟡 Point Type\n\nThe `pointType` of type [EventPointType](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-event-point-type/index.html) specifies the style of the point circle.\nIt can be any of the three types: `EMPTY`, `FILLED` or `CUSTOM`.\n\nFor using `EMPTY`\n\n```kotlin\npointType = EventPointType.EMPTY\n```\n\nFor using `FILLED`, the [filled()](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-event-point-type/-companion/index.html#-1342152058%2FFunctions%2F-1761194290) function has to be used which takes an optional `fillPercent`\n\n```kotlin\npointType = EventPointType.filled(0.8f)\n```\nFor using `CUSTOM`, the [custom()](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-event-point-type/-companion/index.html#-2135258840%2FFunctions%2F-1761194290) function has to be used which takes an `icon` of `Painter`.\nThis can be used to use a custom icon instead of the default types defined. An optional `tint` can also be applied on the icon.\n\n```kotlin\npointType = EventPointType.custom(icon = painterResource(id = R.drawable.icon_check), tint = Color.Green)\n```\n\n#### 🔁 Point Animation\n\nThe `pointAnimation` of type [EventPointAnimation](https://pushpalroy.github.io/JetLime/jetlime/com.pushpal.jetlime/-event-point-animation/index.html) specifies the animation of the point circle.\n\nTo enable the default animation\n\n```kotlin\npointAnimation = JetLimeEventDefaults.pointAnimation()\n```\nTo use a custom animation `initialValue`, `targetValue` and `animationSpec` can be passed to `pointAnimation()`.\n`animationSpec` should be of the type `InfiniteRepeatableSpec<Float>`.\n\n#### 🎨 Point Color\n\nThe `pointColor` is the color of the event point circle background.\n\n#### 🎨 Point Fill Color\n\nThe `pointFillColor` is the fill color of the event point circle which is drawn over the `pointColor`.\n\n#### 📐 Point Radius\n\nThe `pointRadius` in `Dp` is the radius of the point circle.\n\n#### 🖊️ Point Stroke Width\n\nThe `pointStrokeWidth` in `Dp` is the width of the circle border.\n\n#### 🖍️ Point Stroke Color\n\nThe `pointStrokeColor` is the color of the circle border.\n\n## 📚 Documentation\nThe full API documentation is available here: [JetLime Documentation](https://pushpalroy.github.io/JetLime/index.html)\n\n## 💡 Inspiration\n\n- [Timeline-View by Vipul Asri](https://github.com/vipulasri/Timeline-View)\n- [This amazing blog by Vita Sokolova on Timeline component with Jetpack Compose](https://proandroiddev.com/a-step-by-step-guide-to-building-a-timeline-component-with-jetpack-compose-358a596847cb)\n\n## 🤝 Contribution\n\nWould love to receive contributions! Read [contribution guidelines](CONTRIBUTING.md) for more information regarding contribution.\n\n## 💬 Discuss?\n\nHave any questions, doubts or want to present your opinions, views? You're always welcome. You can [start discussions](https://github.com/pushpalroy/jetlime/discussions).\n\n## 📝 License\n\n```\nMIT License\n\nCopyright (c) 2024 Pushpal Roy\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n[badge-android]: http://img.shields.io/badge/Android-grey?style=for-the-badge&logo=appveyor\n[badge-ios]: http://img.shields.io/badge/iOS-grey?style=for-the-badge&logo=appveyor\n[badge-jvm]: http://img.shields.io/badge/JVM-grey?style=for-the-badge&logo=appveyor\n[badge-web]: http://img.shields.io/badge/Web-grey?style=for-the-badge&logo=appveyor"
  },
  {
    "path": "build.gradle.kts",
    "content": "plugins {\n  alias(libs.plugins.android.application) apply false\n  alias(libs.plugins.android.library) apply false\n  alias(libs.plugins.jetbrains.compose) apply false\n  alias(libs.plugins.compose.compiler) apply false\n  alias(libs.plugins.kotlin.multiplatform) apply false\n  alias(libs.plugins.nexus.vanniktech.publish) apply false\n  alias(libs.plugins.dokka) apply false\n  alias(libs.plugins.spotless) apply false\n  alias(libs.plugins.kotlin.cocoapods) apply false\n  alias(libs.plugins.compose.compiler.report.generator) apply false\n}\n\n// Compose Compiler Metrics\n// Run ./gradlew assembleRelease -PcomposeCompilerReports=true to generate reports\n// https://github.com/androidx/androidx/blob/androidx-main/compose/compiler/design/compiler-metrics.md#enabling-metrics\nsubprojects {\n  apply(plugin = \"com.diffplug.spotless\")\n  configure<com.diffplug.gradle.spotless.SpotlessExtension> {\n    kotlin {\n      target(\"**/*.kt\")\n      targetExclude(\"${layout.buildDirectory.get()}/**/*.kt\")\n      targetExclude(\"bin/**/*.kt\")\n      ktlint()\n        .setEditorConfigPath(\"$rootDir/.editorconfig\")\n        .editorConfigOverride(\n          mapOf(\n            \"indent_size\" to \"2\",\n            \"continuation_indent_size\" to \"2\",\n          ),\n        )\n        .customRuleSets(\n          listOf(\n            \"io.nlopez.compose.rules:ktlint:0.3.11\",\n          ),\n        )\n      licenseHeaderFile(rootProject.file(\"spotless/copyright.kt\"))\n      trimTrailingWhitespace()\n      endWithNewline()\n    }\n\n    kotlinGradle {\n      target(\"*.gradle.kts\")\n      ktlint()\n    }\n  }\n}\n"
  },
  {
    "path": "docs/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>jetlime</title>\n    <link href=\"images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"styles/style.css\" rel=\"Stylesheet\">\n<link href=\"styles/main.css\" rel=\"Stylesheet\">\n<link href=\"styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" id=\"content\" pageIds=\"jetlime::////PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>jetlime</span></span></h1>\n    <div class=\"platform-hinted UnderCoverText\" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><h1 class=\"\">JetLime Module Documentation</h1><p class=\"paragraph\">JetLime is a Kotlin Multiplatform timeline UI library for Compose.</p><h2 class=\"\">Overview</h2><p class=\"paragraph\">JetLime provides composables for vertical and horizontal timelines, customizable points (START, CENTER, END), and extended events with dual content areas.</p><p class=\"paragraph\">Refer to the project README for installation and quick start examples.</p></div></div>\n  </div>\n  <h2 class=\"\">Packages</h2>\n  <div class=\"table\"><a data-name=\"-1421771338%2FPackages%2F538146535\" anchor-label=\"com.pushpal.jetlime\" id=\"-1421771338%2FPackages%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n    <div class=\"table-row table-row_platform-tagged\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n      <div>\n        <div class=\"main-subrow \">\n          <div class=\"\"><span class=\"inline-flex\">\n              <div><a href=\"jetlime/com.pushpal.jetlime/index.html\">com.pushpal.jetlime</a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1421771338%2FPackages%2F538146535\"></span>\n                <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n              </span></span></div>\n          <div class=\"pull-right platform-tags--wrapper\">\n            <div class=\"platform-tags no-gutters\">\n              <div class=\"platform-tag common-like\">common</div>\n            </div>\n          </div>\n        </div>\n        <div><span class=\"brief-comment\"><a data-name=\"-1421771338%2FPackages%2F538146535\" anchor-label=\"com.pushpal.jetlime\" id=\"-1421771338%2FPackages%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n            <p class=\"paragraph\">Contains composables, styles, timeline rendering, and helper utilities.</p>\n          </span></div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-animation/animation-spec.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>animationSpec</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointAnimation/animationSpec/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointAnimation</a><span class=\"delimiter\">/</span><span class=\"current\">animationSpec</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>animation</span><wbr></wbr><span><span>Spec</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"animation-spec.html\">animationSpec</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/animation/core/InfiniteRepeatableSpec.html\">InfiniteRepeatableSpec</a><span class=\"token operator\">&lt;</span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a><span class=\"token operator\">&gt;</span></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-animation/equals.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>equals</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointAnimation/equals/#kotlin.Any?/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointAnimation</a><span class=\"delimiter\">/</span><span class=\"current\">equals</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>equals</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">operator override </span><span class=\"token keyword\">fun </span><a href=\"equals.html\"><span class=\"token function\">equals</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">other<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><p class=\"paragraph\">Compares this EventPointAnimation with another object for equality. The result is <code class=\"lang-kotlin\">true</code> if and only if the argument is not <code class=\"lang-kotlin\">null</code>, is an <code class=\"lang-kotlin\">EventPointAnimation</code> object, and has the same values for <code class=\"lang-kotlin\">initialValue</code>, <code class=\"lang-kotlin\">targetValue</code>, and <code class=\"lang-kotlin\">animationSpec</code>.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\"><code class=\"lang-kotlin\">true</code> if the given object represents an <code class=\"lang-kotlin\">EventPointAnimation</code> equivalent to this instance, <code class=\"lang-kotlin\">false</code> otherwise.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>other</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The object to compare this <code class=\"lang-kotlin\">EventPointAnimation</code> against.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-animation/hash-code.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>hashCode</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointAnimation/hashCode/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointAnimation</a><span class=\"delimiter\">/</span><span class=\"current\">hashCode</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>hash</span><wbr></wbr><span><span>Code</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">override </span><span class=\"token keyword\">fun </span><a href=\"hash-code.html\"><span class=\"token function\">hashCode</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div><p class=\"paragraph\">Returns a hash code value for the object, consistent with the definition of equality for the class. This method is supported for the benefit of hash tables such as those provided by <code class=\"lang-kotlin\">HashMap</code>.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A hash code value for this object.</p></span></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-animation/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>EventPointAnimation</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointAnimation///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">EventPointAnimation</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Event</span><wbr></wbr><span>Point</span><wbr></wbr><span><span>Animation</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable.html\"><span class=\"token annotation builtin\">Immutable</span></a></div></div><span class=\"token keyword\">class </span><a href=\"index.html\">EventPointAnimation</a></div><p class=\"paragraph\">Represents an animation configuration for an event point in a UI component. This animation defines how an event point (circle) should animate, including its initial value, target value, and the specification of the animation.</p><ul><li><p class=\"paragraph\">See <a href=\"../-jet-lime-event-defaults/point-animation.html\">JetLimeEventDefaults.pointAnimation</a> for the default point animation used in a <a href=\"../-jet-lime-event.html\">JetLimeEvent</a>.</p></li></ul></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"1760907418%2FProperties%2F538146535\" anchor-label=\"animationSpec\" id=\"1760907418%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"animation-spec.html\"><span>animation</span><wbr></wbr><span><span>Spec</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1760907418%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"animation-spec.html\">animationSpec</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/animation/core/InfiniteRepeatableSpec.html\">InfiniteRepeatableSpec</a><span class=\"token operator\">&lt;</span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a><span class=\"token operator\">&gt;</span></div><div class=\"brief \"><p class=\"paragraph\">The specification of the animation, including duration, easing, and repeat behavior.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"393790196%2FProperties%2F538146535\" anchor-label=\"initialValue\" id=\"393790196%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"initial-value.html\"><span>initial</span><wbr></wbr><span><span>Value</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"393790196%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"initial-value.html\">initialValue</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a></div><div class=\"brief \"><p class=\"paragraph\">The starting value of the animation.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-2034725447%2FProperties%2F538146535\" anchor-label=\"targetValue\" id=\"-2034725447%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"target-value.html\"><span>target</span><wbr></wbr><span><span>Value</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-2034725447%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"target-value.html\">targetValue</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a></div><div class=\"brief \"><p class=\"paragraph\">The ending value of the animation.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"-1479280704%2FFunctions%2F538146535\" anchor-label=\"equals\" id=\"-1479280704%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"equals.html\"><span><span>equals</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1479280704%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">operator override </span><span class=\"token keyword\">fun </span><a href=\"equals.html\"><span class=\"token function\">equals</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">other<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><div class=\"brief \"><p class=\"paragraph\">Compares this EventPointAnimation with another object for equality. The result is <code class=\"lang-kotlin\">true</code> if and only if the argument is not <code class=\"lang-kotlin\">null</code>, is an <code class=\"lang-kotlin\">EventPointAnimation</code> object, and has the same values for <code class=\"lang-kotlin\">initialValue</code>, <code class=\"lang-kotlin\">targetValue</code>, and <code class=\"lang-kotlin\">animationSpec</code>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-25790170%2FFunctions%2F538146535\" anchor-label=\"hashCode\" id=\"-25790170%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"hash-code.html\"><span>hash</span><wbr></wbr><span><span>Code</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-25790170%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">override </span><span class=\"token keyword\">fun </span><a href=\"hash-code.html\"><span class=\"token function\">hashCode</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div><div class=\"brief \"><p class=\"paragraph\">Returns a hash code value for the object, consistent with the definition of equality for the class. This method is supported for the benefit of hash tables such as those provided by <code class=\"lang-kotlin\">HashMap</code>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-animation/initial-value.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>initialValue</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointAnimation/initialValue/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointAnimation</a><span class=\"delimiter\">/</span><span class=\"current\">initialValue</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>initial</span><wbr></wbr><span><span>Value</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"initial-value.html\">initialValue</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-animation/target-value.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>targetValue</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointAnimation/targetValue/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointAnimation</a><span class=\"delimiter\">/</span><span class=\"current\">targetValue</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>target</span><wbr></wbr><span><span>Value</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"target-value.html\">targetValue</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/-companion/-default.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>Default</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType.Companion/Default/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">EventPointType</a><span class=\"delimiter\">/</span><a href=\"index.html\">Companion</a><span class=\"delimiter\">/</span><span class=\"current\">Default</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>Default</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"-default.html\">Default</a><span class=\"token operator\">: </span><a href=\"../index.html\">EventPointType</a></div><p class=\"paragraph\">The default value of <a href=\"../index.html\">EventPointType</a></p></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/-companion/-e-m-p-t-y.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>EMPTY</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType.Companion/EMPTY/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">EventPointType</a><span class=\"delimiter\">/</span><a href=\"index.html\">Companion</a><span class=\"delimiter\">/</span><span class=\"current\">EMPTY</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>EMPTY</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"-e-m-p-t-y.html\">EMPTY</a><span class=\"token operator\">: </span><a href=\"../index.html\">EventPointType</a></div><p class=\"paragraph\">Represents an empty event point type.</p></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/-companion/custom.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>custom</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType.Companion/custom/#androidx.compose.ui.graphics.painter.Painter#androidx.compose.ui.graphics.Color?/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">EventPointType</a><span class=\"delimiter\">/</span><a href=\"index.html\">Companion</a><span class=\"delimiter\">/</span><span class=\"current\">custom</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>custom</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"custom.html\"><span class=\"token function\">custom</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">icon<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/painter/Painter.html\">Painter</a><span class=\"token punctuation\">, </span></span><span class=\"parameter \">tint<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\">?</span><span class=\"token operator\"> = </span>null</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../index.html\">EventPointType</a></div><p class=\"paragraph\">Creates a custom event point type with a specified <a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/painter/Painter.html\">Painter</a> icon.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A new instance of <a href=\"../index.html\">EventPointType</a> with the custom icon.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>icon</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The <a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/painter/Painter.html\">Painter</a> icon for the custom event point type.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>tint</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The optional tint <a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a> of the custom icon.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/-companion/filled.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>filled</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType.Companion/filled/#kotlin.Float/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">EventPointType</a><span class=\"delimiter\">/</span><a href=\"index.html\">Companion</a><span class=\"delimiter\">/</span><span class=\"current\">filled</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>filled</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"filled.html\"><span class=\"token function\">filled</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">fillPercent<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a><span class=\"token operator\"> = </span><span class=\"token constant\">0.5f</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../index.html\">EventPointType</a></div><p class=\"paragraph\">Creates a filled event point type with a specified fill percentage.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A new instance of <a href=\"../index.html\">EventPointType</a> with the filled icon.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>fill</span><wbr></wbr><span><span>Percent</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The percentage of fill for the event point.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/-companion/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>Companion</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType.Companion///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">EventPointType</a><span class=\"delimiter\">/</span><span class=\"current\">Companion</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>Companion</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">object </span><a href=\"index.html\">Companion</a></div></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"883033122%2FProperties%2F538146535\" anchor-label=\"Default\" id=\"883033122%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-default.html\"><span><span>Default</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"883033122%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"-default.html\">Default</a><span class=\"token operator\">: </span><a href=\"../index.html\">EventPointType</a></div><div class=\"brief \"><p class=\"paragraph\">The default value of <a href=\"../index.html\">EventPointType</a></p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"492391446%2FProperties%2F538146535\" anchor-label=\"EMPTY\" id=\"492391446%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-e-m-p-t-y.html\"><span><span>EMPTY</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"492391446%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"-e-m-p-t-y.html\">EMPTY</a><span class=\"token operator\">: </span><a href=\"../index.html\">EventPointType</a></div><div class=\"brief \"><p class=\"paragraph\">Represents an empty event point type.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"246472581%2FFunctions%2F538146535\" anchor-label=\"custom\" id=\"246472581%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"custom.html\"><span><span>custom</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"246472581%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"custom.html\"><span class=\"token function\">custom</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">icon<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/painter/Painter.html\">Painter</a><span class=\"token punctuation\">, </span></span><span class=\"parameter \">tint<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\">?</span><span class=\"token operator\"> = </span>null</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../index.html\">EventPointType</a></div><div class=\"brief \"><p class=\"paragraph\">Creates a custom event point type with a specified <a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/painter/Painter.html\">Painter</a> icon.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1342152058%2FFunctions%2F538146535\" anchor-label=\"filled\" id=\"-1342152058%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"filled.html\"><span><span>filled</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1342152058%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"filled.html\"><span class=\"token function\">filled</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">fillPercent<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a><span class=\"token operator\"> = </span><span class=\"token constant\">0.5f</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../index.html\">EventPointType</a></div><div class=\"brief \"><p class=\"paragraph\">Creates a filled event point type with a specified fill percentage.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/equals.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>equals</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType/equals/#kotlin.Any?/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointType</a><span class=\"delimiter\">/</span><span class=\"current\">equals</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>equals</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">operator override </span><span class=\"token keyword\">fun </span><a href=\"equals.html\"><span class=\"token function\">equals</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">other<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><p class=\"paragraph\">Checks if this instance is equal to another object. Two instances of <a href=\"index.html\">EventPointType</a> are considered equal if they have the same type and icon.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\"><code class=\"lang-kotlin\">true</code> if the other object is an instance of <a href=\"index.html\">EventPointType</a> and has the same type and icon, <code class=\"lang-kotlin\">false</code> otherwise.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>other</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The object to compare this instance with.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/fill-percent.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>fillPercent</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType/fillPercent/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointType</a><span class=\"delimiter\">/</span><span class=\"current\">fillPercent</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>fill</span><wbr></wbr><span><span>Percent</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"fill-percent.html\">fillPercent</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a><span class=\"token operator\">?</span></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/hash-code.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>hashCode</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType/hashCode/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointType</a><span class=\"delimiter\">/</span><span class=\"current\">hashCode</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>hash</span><wbr></wbr><span><span>Code</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">override </span><span class=\"token keyword\">fun </span><a href=\"hash-code.html\"><span class=\"token function\">hashCode</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div><p class=\"paragraph\">Returns a hash code value for the object, which is consistent with the definition of equality for the class. This supports the use in hash tables, like those provided by <code class=\"lang-kotlin\">HashMap</code>.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A hash code value for this object.</p></span></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/icon.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>icon</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType/icon/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointType</a><span class=\"delimiter\">/</span><span class=\"current\">icon</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>icon</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"icon.html\">icon</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/painter/Painter.html\">Painter</a><span class=\"token operator\">?</span></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>EventPointType</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">EventPointType</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Event</span><wbr></wbr><span>Point</span><wbr></wbr><span><span>Type</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable.html\"><span class=\"token annotation builtin\">Immutable</span></a></div></div><span class=\"token keyword\">class </span><a href=\"index.html\">EventPointType</a></div><p class=\"paragraph\">Represents a type of event point in a UI component with an optional icon. This class is used to define different types of event points such as empty, filled, or custom types with specific icons.</p></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"TYPE\">\n        <h2 class=\"tableheader\">Types</h2>\n        <div class=\"table\"><a data-name=\"-1022341016%2FClasslikes%2F538146535\" anchor-label=\"Companion\" id=\"-1022341016%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-companion/index.html\"><span><span>Companion</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1022341016%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">object </span><a href=\"-companion/index.html\">Companion</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"-351869153%2FProperties%2F538146535\" anchor-label=\"fillPercent\" id=\"-351869153%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"fill-percent.html\"><span>fill</span><wbr></wbr><span><span>Percent</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-351869153%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"fill-percent.html\">fillPercent</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a><span class=\"token operator\">?</span></div><div class=\"brief \"><p class=\"paragraph\">An optional percentage value for the <span data-unresolved-link=\"com.pushpal.jetlime/EventPointType.Companion/FILLED/#/PointingToDeclaration/\">FILLED</span> type</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-7092352%2FProperties%2F538146535\" anchor-label=\"icon\" id=\"-7092352%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"icon.html\"><span><span>icon</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-7092352%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"icon.html\">icon</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/painter/Painter.html\">Painter</a><span class=\"token operator\">?</span></div><div class=\"brief \"><p class=\"paragraph\">An optional <a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/painter/Painter.html\">Painter</a> icon associated with the event point type.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"1018144574%2FProperties%2F538146535\" anchor-label=\"tint\" id=\"1018144574%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"tint.html\"><span><span>tint</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1018144574%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"tint.html\">tint</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\">?</span></div><div class=\"brief \"><p class=\"paragraph\">An optional tint <a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a> overlay for the icon.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1599709217%2FProperties%2F538146535\" anchor-label=\"type\" id=\"-1599709217%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"type.html\"><span><span>type</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1599709217%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"type.html\">type</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div><div class=\"brief \"><p class=\"paragraph\">The name of the event point type.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"404677576%2FFunctions%2F538146535\" anchor-label=\"equals\" id=\"404677576%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"equals.html\"><span><span>equals</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"404677576%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">operator override </span><span class=\"token keyword\">fun </span><a href=\"equals.html\"><span class=\"token function\">equals</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">other<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><div class=\"brief \"><p class=\"paragraph\">Checks if this instance is equal to another object. Two instances of <a href=\"index.html\">EventPointType</a> are considered equal if they have the same type and icon.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-740793314%2FFunctions%2F538146535\" anchor-label=\"hashCode\" id=\"-740793314%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"hash-code.html\"><span>hash</span><wbr></wbr><span><span>Code</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-740793314%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">override </span><span class=\"token keyword\">fun </span><a href=\"hash-code.html\"><span class=\"token function\">hashCode</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div><div class=\"brief \"><p class=\"paragraph\">Returns a hash code value for the object, which is consistent with the definition of equality for the class. This supports the use in hash tables, like those provided by <code class=\"lang-kotlin\">HashMap</code>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-91613442%2FFunctions%2F538146535\" anchor-label=\"isCustom\" id=\"-91613442%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"is-custom.html\"><span>is</span><wbr></wbr><span><span>Custom</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-91613442%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"is-custom.html\"><span class=\"token function\">isCustom</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><div class=\"brief \"><p class=\"paragraph\">A helper function to check if the current <a href=\"index.html\">EventPointType</a> is <span data-unresolved-link=\"com.pushpal.jetlime/EventPointType.Companion/CUSTOM/#/PointingToDeclaration/\">CUSTOM</span></p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-258869095%2FFunctions%2F538146535\" anchor-label=\"isEmptyOrFilled\" id=\"-258869095%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"is-empty-or-filled.html\"><span>is</span><wbr></wbr><span>Empty</span><wbr></wbr><span>Or</span><wbr></wbr><span><span>Filled</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-258869095%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"is-empty-or-filled.html\"><span class=\"token function\">isEmptyOrFilled</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><div class=\"brief \"><p class=\"paragraph\">A helper function to check if the current <a href=\"index.html\">EventPointType</a> is <a href=\"-companion/-e-m-p-t-y.html\">EMPTY</a> or <span data-unresolved-link=\"com.pushpal.jetlime/EventPointType.Companion/FILLED/#/PointingToDeclaration/\">FILLED</span></p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"1000756781%2FFunctions%2F538146535\" anchor-label=\"isFilled\" id=\"1000756781%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"is-filled.html\"><span>is</span><wbr></wbr><span><span>Filled</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1000756781%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"is-filled.html\"><span class=\"token function\">isFilled</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><div class=\"brief \"><p class=\"paragraph\">A helper function to check if the current <a href=\"index.html\">EventPointType</a> is <span data-unresolved-link=\"com.pushpal.jetlime/EventPointType.Companion/FILLED/#/PointingToDeclaration/\">FILLED</span></p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/is-custom.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>isCustom</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType/isCustom/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointType</a><span class=\"delimiter\">/</span><span class=\"current\">isCustom</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>is</span><wbr></wbr><span><span>Custom</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"is-custom.html\"><span class=\"token function\">isCustom</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><p class=\"paragraph\">A helper function to check if the current <a href=\"index.html\">EventPointType</a> is <span data-unresolved-link=\"com.pushpal.jetlime/EventPointType.Companion/CUSTOM/#/PointingToDeclaration/\">CUSTOM</span></p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\"><code class=\"lang-kotlin\">true</code> if the current EventPointType is custom, <code class=\"lang-kotlin\">false</code> otherwise.</p></span></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/is-empty-or-filled.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>isEmptyOrFilled</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType/isEmptyOrFilled/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointType</a><span class=\"delimiter\">/</span><span class=\"current\">isEmptyOrFilled</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>is</span><wbr></wbr><span>Empty</span><wbr></wbr><span>Or</span><wbr></wbr><span><span>Filled</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"is-empty-or-filled.html\"><span class=\"token function\">isEmptyOrFilled</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><p class=\"paragraph\">A helper function to check if the current <a href=\"index.html\">EventPointType</a> is <a href=\"-companion/-e-m-p-t-y.html\">EMPTY</a> or <span data-unresolved-link=\"com.pushpal.jetlime/EventPointType.Companion/FILLED/#/PointingToDeclaration/\">FILLED</span></p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\"><code class=\"lang-kotlin\">true</code> if the current EventPointType is empty or filled, <code class=\"lang-kotlin\">false</code> otherwise.</p></span></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/is-filled.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>isFilled</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType/isFilled/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointType</a><span class=\"delimiter\">/</span><span class=\"current\">isFilled</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>is</span><wbr></wbr><span><span>Filled</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"is-filled.html\"><span class=\"token function\">isFilled</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><p class=\"paragraph\">A helper function to check if the current <a href=\"index.html\">EventPointType</a> is <span data-unresolved-link=\"com.pushpal.jetlime/EventPointType.Companion/FILLED/#/PointingToDeclaration/\">FILLED</span></p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\"><code class=\"lang-kotlin\">true</code> if the current EventPointType is filled, <code class=\"lang-kotlin\">false</code> otherwise.</p></span></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/tint.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>tint</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType/tint/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointType</a><span class=\"delimiter\">/</span><span class=\"current\">tint</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>tint</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"tint.html\">tint</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\">?</span></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-point-type/type.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>type</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPointType/type/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPointType</a><span class=\"delimiter\">/</span><span class=\"current\">type</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>type</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"type.html\">type</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-position/-companion/dynamic.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>dynamic</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPosition.Companion/dynamic/#kotlin.Int#kotlin.Int/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">EventPosition</a><span class=\"delimiter\">/</span><a href=\"index.html\">Companion</a><span class=\"delimiter\">/</span><span class=\"current\">dynamic</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>dynamic</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"dynamic.html\"><span class=\"token function\">dynamic</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">index<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a><span class=\"token punctuation\">, </span></span><span class=\"parameter \">listSize<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../index.html\">EventPosition</a></div><p class=\"paragraph\">Determines the event position dynamically based on the index and the size of the list.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\"><a href=\"../index.html\">EventPosition</a> corresponding to the index in the list.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>index</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The index of the item in the list.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>list</span><wbr></wbr><span><span>Size</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The total size of the list.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-position/-companion/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>Companion</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPosition.Companion///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">EventPosition</a><span class=\"delimiter\">/</span><span class=\"current\">Companion</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>Companion</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">object </span><a href=\"index.html\">Companion</a></div></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"383032152%2FFunctions%2F538146535\" anchor-label=\"dynamic\" id=\"383032152%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"dynamic.html\"><span><span>dynamic</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"383032152%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"dynamic.html\"><span class=\"token function\">dynamic</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">index<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a><span class=\"token punctuation\">, </span></span><span class=\"parameter \">listSize<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../index.html\">EventPosition</a></div><div class=\"brief \"><p class=\"paragraph\">Determines the event position dynamically based on the index and the size of the list.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-position/equals.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>equals</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPosition/equals/#kotlin.Any?/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPosition</a><span class=\"delimiter\">/</span><span class=\"current\">equals</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>equals</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">operator override </span><span class=\"token keyword\">fun </span><a href=\"equals.html\"><span class=\"token function\">equals</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">other<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><p class=\"paragraph\">Checks if this instance is equal to another object. Two instances of <a href=\"index.html\">EventPosition</a> are considered equal if they have the same name.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\"><code class=\"lang-kotlin\">true</code> if the other object is an instance of <a href=\"index.html\">EventPosition</a> and has the same name, <code class=\"lang-kotlin\">false</code> otherwise.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>other</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The object to compare this instance with.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-position/hash-code.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>hashCode</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPosition/hashCode/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPosition</a><span class=\"delimiter\">/</span><span class=\"current\">hashCode</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>hash</span><wbr></wbr><span><span>Code</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">override </span><span class=\"token keyword\">fun </span><a href=\"hash-code.html\"><span class=\"token function\">hashCode</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div><p class=\"paragraph\">Returns a hash code value for the object, which is consistent with the definition of equality for the class. This supports the use in hash tables, like those provided by <code class=\"lang-kotlin\">HashMap</code>.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A hash code value for this object.</p></span></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-position/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>EventPosition</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPosition///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">EventPosition</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Event</span><wbr></wbr><span><span>Position</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable.html\"><span class=\"token annotation builtin\">Immutable</span></a></div></div><span class=\"token keyword\">class </span><a href=\"index.html\">EventPosition</a></div><p class=\"paragraph\">Represents a position of an event within a sequence, such as the start, middle, or end. This class encapsulates the logic for determining the position based on the index in a list.</p></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"TYPE\">\n        <h2 class=\"tableheader\">Types</h2>\n        <div class=\"table\"><a data-name=\"-845789269%2FClasslikes%2F538146535\" anchor-label=\"Companion\" id=\"-845789269%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-companion/index.html\"><span><span>Companion</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-845789269%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">object </span><a href=\"-companion/index.html\">Companion</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"-992842613%2FProperties%2F538146535\" anchor-label=\"name\" id=\"-992842613%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"name.html\"><span><span>name</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-992842613%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"name.html\">name</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div><div class=\"brief \"><p class=\"paragraph\">The name of the event position.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"-1566119925%2FFunctions%2F538146535\" anchor-label=\"equals\" id=\"-1566119925%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"equals.html\"><span><span>equals</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1566119925%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">operator override </span><span class=\"token keyword\">fun </span><a href=\"equals.html\"><span class=\"token function\">equals</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">other<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><div class=\"brief \"><p class=\"paragraph\">Checks if this instance is equal to another object. Two instances of <a href=\"index.html\">EventPosition</a> are considered equal if they have the same name.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1427834757%2FFunctions%2F538146535\" anchor-label=\"hashCode\" id=\"-1427834757%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"hash-code.html\"><span>hash</span><wbr></wbr><span><span>Code</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1427834757%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">override </span><span class=\"token keyword\">fun </span><a href=\"hash-code.html\"><span class=\"token function\">hashCode</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div><div class=\"brief \"><p class=\"paragraph\">Returns a hash code value for the object, which is consistent with the definition of equality for the class. This supports the use in hash tables, like those provided by <code class=\"lang-kotlin\">HashMap</code>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"1552272804%2FFunctions%2F538146535\" anchor-label=\"isNotEnd\" id=\"1552272804%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"is-not-end.html\"><span>is</span><wbr></wbr><span>Not</span><wbr></wbr><span><span>End</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1552272804%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"is-not-end.html\"><span class=\"token function\">isNotEnd</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><div class=\"brief \"><p class=\"paragraph\">A helper function to check if the current position is not the end position. This can be useful for determining layout or drawing logic based on the position of an event.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-183257219%2FFunctions%2F538146535\" anchor-label=\"isNotStart\" id=\"-183257219%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"is-not-start.html\"><span>is</span><wbr></wbr><span>Not</span><wbr></wbr><span><span>Start</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-183257219%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"is-not-start.html\"><span class=\"token function\">isNotStart</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><div class=\"brief \"><p class=\"paragraph\">Helper to check if current position is not the start.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-position/is-not-end.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>isNotEnd</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPosition/isNotEnd/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPosition</a><span class=\"delimiter\">/</span><span class=\"current\">isNotEnd</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>is</span><wbr></wbr><span>Not</span><wbr></wbr><span><span>End</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"is-not-end.html\"><span class=\"token function\">isNotEnd</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><p class=\"paragraph\">A helper function to check if the current position is not the end position. This can be useful for determining layout or drawing logic based on the position of an event.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\"><code class=\"lang-kotlin\">true</code> if the current position is not the end, <code class=\"lang-kotlin\">false</code> otherwise.</p></span></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-position/is-not-start.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>isNotStart</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPosition/isNotStart/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPosition</a><span class=\"delimiter\">/</span><span class=\"current\">isNotStart</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>is</span><wbr></wbr><span>Not</span><wbr></wbr><span><span>Start</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"is-not-start.html\"><span class=\"token function\">isNotStart</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><p class=\"paragraph\">Helper to check if current position is not the start.</p></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-event-position/name.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>name</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/EventPosition/name/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">EventPosition</a><span class=\"delimiter\">/</span><span class=\"current\">name</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>name</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"name.html\">name</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-horizontal-alignment/-b-o-t-t-o-m/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>BOTTOM</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/HorizontalAlignment.BOTTOM///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">HorizontalAlignment</a><span class=\"delimiter\">/</span><span class=\"current\">BOTTOM</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>BOTTOM</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"index.html\">BOTTOM</a></div></div></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"-372974862%2FProperties%2F538146535\" anchor-label=\"name\" id=\"-372974862%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\"><span><span>name</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-372974862%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\">name</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-739389684%2FProperties%2F538146535\" anchor-label=\"ordinal\" id=\"-739389684%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\"><span><span>ordinal</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-739389684%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\">ordinal</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-horizontal-alignment/-t-o-p/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>TOP</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/HorizontalAlignment.TOP///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">HorizontalAlignment</a><span class=\"delimiter\">/</span><span class=\"current\">TOP</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>TOP</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"index.html\">TOP</a></div></div></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"-372974862%2FProperties%2F538146535\" anchor-label=\"name\" id=\"-372974862%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\"><span><span>name</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-372974862%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\">name</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-739389684%2FProperties%2F538146535\" anchor-label=\"ordinal\" id=\"-739389684%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\"><span><span>ordinal</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-739389684%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\">ordinal</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-horizontal-alignment/entries.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>entries</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/HorizontalAlignment/entries/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">HorizontalAlignment</a><span class=\"delimiter\">/</span><span class=\"current\">entries</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>entries</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"entries.html\">entries</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.enums/-enum-entries/index.html\">EnumEntries</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">HorizontalAlignment</a><span class=\"token operator\">&gt;</span></div><p class=\"paragraph\">Returns a representation of an immutable list of all enum entries, in the order they're declared.</p><p class=\"paragraph\">This method may be used to iterate over the enum entries.</p></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-horizontal-alignment/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>HorizontalAlignment</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/HorizontalAlignment///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">HorizontalAlignment</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Horizontal</span><wbr></wbr><span><span>Alignment</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">enum </span><a href=\"index.html\">HorizontalAlignment</a> : <a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-enum/index.html\">Enum</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">HorizontalAlignment</a><span class=\"token operator\">&gt; </span></div><p class=\"paragraph\">Enum representing the alignment of the timeline line and points for <a href=\"../-jet-lime-row.html\">JetLimeRow</a>.</p></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button><button class=\"section-tab\" data-togglable=\"ENTRY\">Entries</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"ENTRY\">\n        <h2 class=\"tableheader\">Entries</h2>\n        <div class=\"table\"><a data-name=\"769734623%2FClasslikes%2F538146535\" anchor-label=\"TOP\" id=\"769734623%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-togglable=\"ENTRY\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-t-o-p/index.html\">TOP</a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"769734623%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"-t-o-p/index.html\">TOP</a></div></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1737811223%2FClasslikes%2F538146535\" anchor-label=\"BOTTOM\" id=\"-1737811223%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-togglable=\"ENTRY\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-b-o-t-t-o-m/index.html\">BOTTOM</a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1737811223%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"-b-o-t-t-o-m/index.html\">BOTTOM</a></div></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"-1506752360%2FProperties%2F538146535\" anchor-label=\"entries\" id=\"-1506752360%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"entries.html\"><span><span>entries</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1506752360%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"entries.html\">entries</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.enums/-enum-entries/index.html\">EnumEntries</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">HorizontalAlignment</a><span class=\"token operator\">&gt;</span></div><div class=\"brief \"><p class=\"paragraph\">Returns a representation of an immutable list of all enum entries, in the order they're declared.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-372974862%2FProperties%2F538146535\" anchor-label=\"name\" id=\"-372974862%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\"><span><span>name</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-372974862%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\">name</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-739389684%2FProperties%2F538146535\" anchor-label=\"ordinal\" id=\"-739389684%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\"><span><span>ordinal</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-739389684%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\">ordinal</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"1188023300%2FFunctions%2F538146535\" anchor-label=\"valueOf\" id=\"1188023300%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"value-of.html\"><span>value</span><wbr></wbr><span><span>Of</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1188023300%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">fun </span><a href=\"value-of.html\"><span class=\"token function\">valueOf</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">value<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"index.html\">HorizontalAlignment</a></div><div class=\"brief \"><p class=\"paragraph\">Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1925631984%2FFunctions%2F538146535\" anchor-label=\"values\" id=\"-1925631984%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"values.html\"><span><span>values</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1925631984%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">fun </span><a href=\"values.html\"><span class=\"token function\">values</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-array/index.html\">Array</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">HorizontalAlignment</a><span class=\"token operator\">&gt;</span></div><div class=\"brief \"><p class=\"paragraph\">Returns an array containing the constants of this enum type, in the order they're declared.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-horizontal-alignment/value-of.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>valueOf</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/HorizontalAlignment/valueOf/#kotlin.String/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">HorizontalAlignment</a><span class=\"delimiter\">/</span><span class=\"current\">valueOf</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>value</span><wbr></wbr><span><span>Of</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">fun </span><a href=\"value-of.html\"><span class=\"token function\">valueOf</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">value<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"index.html\">HorizontalAlignment</a></div><p class=\"paragraph\">Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)</p><h4 class=\"tableheader\">Throws</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-illegal-argument-exception/index.html\"><span>kotlin.</span><wbr></wbr><span>Illegal</span><wbr></wbr><span>Argument</span><wbr></wbr><span><span>Exception</span></span></a></div></span></div><div><div class=\"title\"><p class=\"paragraph\">if this enum type has no constant with the specified name</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-horizontal-alignment/values.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>values</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/HorizontalAlignment/values/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">HorizontalAlignment</a><span class=\"delimiter\">/</span><span class=\"current\">values</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>values</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">fun </span><a href=\"values.html\"><span class=\"token function\">values</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-array/index.html\">Array</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">HorizontalAlignment</a><span class=\"token operator\">&gt;</span></div><p class=\"paragraph\">Returns an array containing the constants of this enum type, in the order they're declared.</p><p class=\"paragraph\">This method may be used to iterate over the constants.</p></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-items-list/-items-list.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>ItemsList</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/ItemsList/ItemsList/#kotlin.collections.List[TypeParam(bounds=[kotlin.Any?])]/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">ItemsList</a><span class=\"delimiter\">/</span><span class=\"current\">ItemsList</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Items</span><wbr></wbr><span><span>List</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">constructor</span><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">items<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html\">List</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">T</a><span class=\"token operator\">&gt;</span></span></span><span class=\"token punctuation\">)</span></div><h4 class=\"tableheader\">Type Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>T</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The type of elements in the list.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-items-list/equals.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>equals</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/ItemsList/equals/#kotlin.Any?/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">ItemsList</a><span class=\"delimiter\">/</span><span class=\"current\">equals</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>equals</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">operator override </span><span class=\"token keyword\">fun </span><a href=\"equals.html\"><span class=\"token function\">equals</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">other<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><p class=\"paragraph\">Compares this <code class=\"lang-kotlin\">ItemsList</code> object with another object for equality. The comparison checks whether the other object is also an <code class=\"lang-kotlin\">ItemsList</code> and contains the same items in the same order.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\"><code class=\"lang-kotlin\">true</code> if the other object is an <code class=\"lang-kotlin\">ItemsList</code> with the same items, <code class=\"lang-kotlin\">false</code> otherwise.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>other</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The object to compare with this <code class=\"lang-kotlin\">ItemsList</code>.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-items-list/hash-code.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>hashCode</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/ItemsList/hashCode/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">ItemsList</a><span class=\"delimiter\">/</span><span class=\"current\">hashCode</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>hash</span><wbr></wbr><span><span>Code</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">override </span><span class=\"token keyword\">fun </span><a href=\"hash-code.html\"><span class=\"token function\">hashCode</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div><p class=\"paragraph\">Generates a hash code for this <code class=\"lang-kotlin\">ItemsList</code>. The hash code is generated based on the items in the list.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">The hash code value for this <code class=\"lang-kotlin\">ItemsList</code>.</p></span></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-items-list/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>ItemsList</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/ItemsList///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">ItemsList</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Items</span><wbr></wbr><span><span>List</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable.html\"><span class=\"token annotation builtin\">Immutable</span></a></div></div><span class=\"token keyword\">class </span><a href=\"index.html\">ItemsList</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">T</a><span class=\"token operator\">&gt;</span><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \"><span class=\"token keyword\">val </span>items<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html\">List</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">T</a><span class=\"token operator\">&gt;</span></span></span><span class=\"token punctuation\">)</span></div><p class=\"paragraph\">An immutable list class that holds a list of items of type <a href=\"index.html\">T</a>.</p><p class=\"paragraph\">This class provides an immutable wrapper around a standard list, ensuring that the contents cannot be modified after creation. It overrides <code class=\"lang-kotlin\">equals</code> and <code class=\"lang-kotlin\">hashCode</code> methods to provide proper equality checks and hash code generation based on the list contents.</p><h4 class=\"tableheader\">Type Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>T</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The type of elements in the list.</p></div></div></div></div></div></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"CONSTRUCTOR\">\n        <h2 class=\"tableheader\">Constructors</h2>\n        <div class=\"table\"><a data-name=\"-2070453861%2FConstructors%2F538146535\" anchor-label=\"ItemsList\" id=\"-2070453861%2FConstructors%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-togglable=\"CONSTRUCTOR\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-items-list.html\"><span>Items</span><wbr></wbr><span><span>List</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-2070453861%2FConstructors%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">constructor</span><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">items<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html\">List</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">T</a><span class=\"token operator\">&gt;</span></span></span><span class=\"token punctuation\">)</span></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"1848155561%2FProperties%2F538146535\" anchor-label=\"items\" id=\"1848155561%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"items.html\"><span><span>items</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1848155561%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"items.html\">items</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html\">List</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">T</a><span class=\"token operator\">&gt;</span></div><div class=\"brief \"><p class=\"paragraph\">The list of items contained in this <code class=\"lang-kotlin\">ItemsList</code>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"-1380699120%2FFunctions%2F538146535\" anchor-label=\"equals\" id=\"-1380699120%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"equals.html\"><span><span>equals</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1380699120%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">operator override </span><span class=\"token keyword\">fun </span><a href=\"equals.html\"><span class=\"token function\">equals</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">other<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><div class=\"brief \"><p class=\"paragraph\">Compares this <code class=\"lang-kotlin\">ItemsList</code> object with another object for equality. The comparison checks whether the other object is also an <code class=\"lang-kotlin\">ItemsList</code> and contains the same items in the same order.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-148757802%2FFunctions%2F538146535\" anchor-label=\"hashCode\" id=\"-148757802%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"hash-code.html\"><span>hash</span><wbr></wbr><span><span>Code</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-148757802%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">override </span><span class=\"token keyword\">fun </span><a href=\"hash-code.html\"><span class=\"token function\">hashCode</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div><div class=\"brief \"><p class=\"paragraph\">Generates a hash code for this <code class=\"lang-kotlin\">ItemsList</code>. The hash code is generated based on the items in the list.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-items-list/items.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>items</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/ItemsList/items/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">ItemsList</a><span class=\"delimiter\">/</span><span class=\"current\">items</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>items</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"items.html\">items</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html\">List</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">T</a><span class=\"token operator\">&gt;</span></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-column.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>JetLimeColumn</title>\n    <link href=\"../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime//JetLimeColumn/#com.pushpal.jetlime.ItemsList[TypeParam(bounds=[kotlin.Any?])]#androidx.compose.ui.Modifier#com.pushpal.jetlime.JetLimeStyle#androidx.compose.foundation.lazy.LazyListState#androidx.compose.foundation.layout.PaddingValues#kotlin.Function2[kotlin.Int,TypeParam(bounds=[kotlin.Any?]),kotlin.Any]?#kotlin.Function3[kotlin.Int,TypeParam(bounds=[kotlin.Any?]),com.pushpal.jetlime.EventPosition,kotlin.Unit]/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">JetLimeColumn</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Column</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><span class=\"token operator\">&lt;</span><a href=\"-jet-lime-column.html\">T</a><span class=\"token operator\">&gt; </span><a href=\"-jet-lime-column.html\"><span class=\"token function\">JetLimeColumn</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">itemsList<span class=\"token operator\">: </span><a href=\"-items-list/index.html\">ItemsList</a><span class=\"token operator\">&lt;</span><a href=\"-jet-lime-column.html\">T</a><span class=\"token operator\">&gt;</span><span class=\"token punctuation\">, </span></span><span class=\"parameter \">modifier<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.html\">Modifier</a><span class=\"token operator\"> = </span>Modifier<span class=\"token punctuation\">, </span></span><span class=\"parameter \">style<span class=\"token operator\">: </span><a href=\"-jet-lime-style/index.html\">JetLimeStyle</a><span class=\"token operator\"> = </span>JetLimeDefaults.columnStyle()<span class=\"token punctuation\">, </span></span><span class=\"parameter \">listState<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState.html\">LazyListState</a><span class=\"token operator\"> = </span>rememberLazyListState()<span class=\"token punctuation\">, </span></span><span class=\"parameter \">contentPadding<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/PaddingValues.html\">PaddingValues</a><span class=\"token operator\"> = </span>PaddingValues(0.dp)<span class=\"token punctuation\">, </span></span><span class=\"parameter \">key<span class=\"token operator\">: </span><span class=\"token punctuation\">(</span>index<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a><span class=\"token punctuation\">, </span>item<span class=\"token operator\">: </span><a href=\"-jet-lime-column.html\">T</a><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span><span class=\"token operator\"> = </span>null<span class=\"token punctuation\">, </span></span><span class=\"parameter \">itemContent<span class=\"token operator\">: </span><span><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a> </span><span class=\"token punctuation\">(</span>index<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a><span class=\"token punctuation\">, </span><a href=\"-jet-lime-column.html\">T</a><span class=\"token punctuation\">, </span><a href=\"-event-position/index.html\">EventPosition</a><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html\">Unit</a></span></span><span class=\"token punctuation\">)</span></div><p class=\"paragraph\">A composable function that creates a vertical timeline interface with a list of items.</p><p class=\"paragraph\">This function sets up a LazyColumn layout for displaying items in a vertical timeline format. It allows for customization of its appearance and behavior through various parameters.</p><p class=\"paragraph\">Example usage:</p><div class=\"sample-container\"><pre><code class=\"block lang-kotlin\" theme=\"idea\">val items = remember { getItemsList() }<br><br>JetLimeColumn(<br> itemsList = ItemsList(items),<br> key = { _, item -&gt; item.id },<br> style = JetLimeDefaults.columnStyle(),<br>) { index, item, position -&gt;<br>   JetLimeEvent(<br>    style = JetLimeEventDefaults.eventStyle(position = position)<br>   ) {<br>      ComposableContent(item = item)<br>     }<br>  }</code></pre><span class=\"copy-tooltip\"><div class=\"copy-popup-wrapper popup-to-left\"><span class=\"copy-popup-icon\"></span><span>Content copied to clipboard</span></div><span class=\"copy-icon\"></span></span></div><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>items</span><wbr></wbr><span><span>List</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">A list of items to be displayed in the JetLimeColumn.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>modifier</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">A modifier to be applied to the LazyColumn.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>style</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The JetLime style configuration. Defaults to a predefined column style.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>list</span><wbr></wbr><span><span>State</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The state object to be used for the LazyColumn.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>content</span><wbr></wbr><span><span>Padding</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The padding to apply to the content inside the LazyColumn.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>key</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">A factory of stable and unique keys representing the item. Using the same key for multiple items in the list is not allowed. Type of the key should be saveable via Bundle on Android. If null is passed the position in the list will represent the key.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>item</span><wbr></wbr><span><span>Content</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">A composable lambda that takes an index, an item of type <a href=\"-jet-lime-column.html\">T</a>, and an <a href=\"-event-position/index.html\">EventPosition</a> to build each item's content.</p></div></div></div></div></div><h4 class=\"tableheader\">Type Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>T</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The type of items in the items list.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-defaults/column-style.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>columnStyle</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeDefaults/columnStyle/#androidx.compose.ui.unit.Dp#androidx.compose.ui.unit.Dp#androidx.compose.ui.unit.Dp#androidx.compose.ui.graphics.Brush#androidx.compose.ui.graphics.PathEffect?#com.pushpal.jetlime.VerticalAlignment/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeDefaults</a><span class=\"delimiter\">/</span><span class=\"current\">columnStyle</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>column</span><wbr></wbr><span><span>Style</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"column-style.html\"><span class=\"token function\">columnStyle</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">contentDistance<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>ContentDistance<span class=\"token punctuation\">, </span></span><span class=\"parameter \">itemSpacing<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>ItemSpacing<span class=\"token punctuation\">, </span></span><span class=\"parameter \">lineThickness<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>LineThickness<span class=\"token punctuation\">, </span></span><span class=\"parameter \">lineBrush<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Brush.html\">Brush</a><span class=\"token operator\"> = </span>lineSolidBrush()<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pathEffect<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/PathEffect.html\">PathEffect</a><span class=\"token operator\">?</span><span class=\"token operator\"> = </span>null<span class=\"token punctuation\">, </span></span><span class=\"parameter \">lineVerticalAlignment<span class=\"token operator\">: </span><a href=\"../-vertical-alignment/index.html\">VerticalAlignment</a><span class=\"token operator\"> = </span>LEFT</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../-jet-lime-style/index.html\">JetLimeStyle</a></div><p class=\"paragraph\">Creates a column style configuration for <a href=\"../-jet-lime-column.html\">JetLimeColumn</a>.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A <a href=\"../-jet-lime-style/index.html\">JetLimeStyle</a> instance configured for column arrangement.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>content</span><wbr></wbr><span><span>Distance</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The distance of content from the JetLime component's start.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>item</span><wbr></wbr><span><span>Spacing</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The spacing between items in the JetLime component.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span><span>Thickness</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The thickness of the line in the JetLime component.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span><span>Brush</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The brush used for the line in the JetLime component.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>path</span><wbr></wbr><span><span>Effect</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">the effect applied to the geometry of the timeline to obtain a dashed pattern.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span>Vertical</span><wbr></wbr><span><span>Alignment</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The vertical alignment of the line: <a href=\"../-vertical-alignment/-l-e-f-t/index.html\">LEFT</a> or <a href=\"../-vertical-alignment/-r-i-g-h-t/index.html\">RIGHT</a></p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-defaults/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>JetLimeDefaults</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeDefaults///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">JetLimeDefaults</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Defaults</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">object </span><a href=\"index.html\">JetLimeDefaults</a></div><p class=\"paragraph\">Provides default values and utility functions for <a href=\"../-jet-lime-column.html\">JetLimeColumn</a> or <a href=\"../-jet-lime-row.html\">JetLimeRow</a> styling.</p><p class=\"paragraph\">This object contains default values and composable functions that create different types of brushes and a default <a href=\"../-jet-lime-style/index.html\">JetLimeStyle</a>. It acts as a utility provider for the <a href=\"../-jet-lime-column.html\">JetLimeColumn</a> or <a href=\"../-jet-lime-row.html\">JetLimeRow</a> component styling, allowing for consistent default styling across the application.</p></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"-780205210%2FFunctions%2F538146535\" anchor-label=\"columnStyle\" id=\"-780205210%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"column-style.html\"><span>column</span><wbr></wbr><span><span>Style</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-780205210%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"column-style.html\"><span class=\"token function\">columnStyle</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">contentDistance<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>ContentDistance<span class=\"token punctuation\">, </span></span><span class=\"parameter \">itemSpacing<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>ItemSpacing<span class=\"token punctuation\">, </span></span><span class=\"parameter \">lineThickness<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>LineThickness<span class=\"token punctuation\">, </span></span><span class=\"parameter \">lineBrush<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Brush.html\">Brush</a><span class=\"token operator\"> = </span>lineSolidBrush()<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pathEffect<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/PathEffect.html\">PathEffect</a><span class=\"token operator\">?</span><span class=\"token operator\"> = </span>null<span class=\"token punctuation\">, </span></span><span class=\"parameter \">lineVerticalAlignment<span class=\"token operator\">: </span><a href=\"../-vertical-alignment/index.html\">VerticalAlignment</a><span class=\"token operator\"> = </span>LEFT</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../-jet-lime-style/index.html\">JetLimeStyle</a></div><div class=\"brief \"><p class=\"paragraph\">Creates a column style configuration for <a href=\"../-jet-lime-column.html\">JetLimeColumn</a>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-654318298%2FFunctions%2F538146535\" anchor-label=\"lineGradientBrush\" id=\"-654318298%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"line-gradient-brush.html\"><span>line</span><wbr></wbr><span>Gradient</span><wbr></wbr><span><span>Brush</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-654318298%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"line-gradient-brush.html\"><span class=\"token function\">lineGradientBrush</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">colors<span class=\"token operator\">: </span><span data-unresolved-link=\"kotlinx.collections.immutable/ImmutableList///PointingToDeclaration/\">ImmutableList</span><span class=\"token operator\">&lt;</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\">&gt;</span><span class=\"token operator\"> = </span>persistentListOf(\n      MaterialTheme.colorScheme.primary,\n      MaterialTheme.colorScheme.secondary,\n      MaterialTheme.colorScheme.tertiary,\n    )<span class=\"token punctuation\">, </span></span><span class=\"parameter \">start<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset.html\">Offset</a><span class=\"token operator\"> = </span>Offset.Zero<span class=\"token punctuation\">, </span></span><span class=\"parameter \">end<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset.html\">Offset</a><span class=\"token operator\"> = </span>Offset.Infinite<span class=\"token punctuation\">, </span></span><span class=\"parameter \">tileMode<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/TileMode.html\">TileMode</a><span class=\"token operator\"> = </span>TileMode.Clamp</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Brush.html\">Brush</a></div><div class=\"brief \"><p class=\"paragraph\">Creates a linear gradient brush for lines in <a href=\"../-jet-lime-column.html\">JetLimeColumn</a> or <a href=\"../-jet-lime-row.html\">JetLimeRow</a> components.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-740865705%2FFunctions%2F538146535\" anchor-label=\"lineSolidBrush\" id=\"-740865705%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"line-solid-brush.html\"><span>line</span><wbr></wbr><span>Solid</span><wbr></wbr><span><span>Brush</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-740865705%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"line-solid-brush.html\"><span class=\"token function\">lineSolidBrush</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">color<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\"> = </span>MaterialTheme.colorScheme.primary</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Brush.html\">Brush</a></div><div class=\"brief \"><p class=\"paragraph\">Creates a solid color brush for lines in <a href=\"../-jet-lime-column.html\">JetLimeColumn</a> or <a href=\"../-jet-lime-row.html\">JetLimeRow</a> components.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1218451164%2FFunctions%2F538146535\" anchor-label=\"rowStyle\" id=\"-1218451164%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"row-style.html\"><span>row</span><wbr></wbr><span><span>Style</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1218451164%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"row-style.html\"><span class=\"token function\">rowStyle</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">contentDistance<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>ContentDistance<span class=\"token punctuation\">, </span></span><span class=\"parameter \">itemSpacing<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>ItemSpacing<span class=\"token punctuation\">, </span></span><span class=\"parameter \">lineThickness<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>LineThickness<span class=\"token punctuation\">, </span></span><span class=\"parameter \">lineBrush<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Brush.html\">Brush</a><span class=\"token operator\"> = </span>lineSolidBrush()<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pathEffect<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/PathEffect.html\">PathEffect</a><span class=\"token operator\">?</span><span class=\"token operator\"> = </span>null<span class=\"token punctuation\">, </span></span><span class=\"parameter \">lineHorizontalAlignment<span class=\"token operator\">: </span><a href=\"../-horizontal-alignment/index.html\">HorizontalAlignment</a><span class=\"token operator\"> = </span>TOP</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../-jet-lime-style/index.html\">JetLimeStyle</a></div><div class=\"brief \"><p class=\"paragraph\">Creates a row style configuration for <a href=\"../-jet-lime-row.html\">JetLimeRow</a>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-defaults/line-gradient-brush.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>lineGradientBrush</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeDefaults/lineGradientBrush/#kotlinx.collections.immutable.ImmutableList[androidx.compose.ui.graphics.Color]#androidx.compose.ui.geometry.Offset#androidx.compose.ui.geometry.Offset#androidx.compose.ui.graphics.TileMode/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeDefaults</a><span class=\"delimiter\">/</span><span class=\"current\">lineGradientBrush</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>line</span><wbr></wbr><span>Gradient</span><wbr></wbr><span><span>Brush</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"line-gradient-brush.html\"><span class=\"token function\">lineGradientBrush</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">colors<span class=\"token operator\">: </span><span data-unresolved-link=\"kotlinx.collections.immutable/ImmutableList///PointingToDeclaration/\">ImmutableList</span><span class=\"token operator\">&lt;</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\">&gt;</span><span class=\"token operator\"> = </span>persistentListOf(\n      MaterialTheme.colorScheme.primary,\n      MaterialTheme.colorScheme.secondary,\n      MaterialTheme.colorScheme.tertiary,\n    )<span class=\"token punctuation\">, </span></span><span class=\"parameter \">start<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset.html\">Offset</a><span class=\"token operator\"> = </span>Offset.Zero<span class=\"token punctuation\">, </span></span><span class=\"parameter \">end<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/geometry/Offset.html\">Offset</a><span class=\"token operator\"> = </span>Offset.Infinite<span class=\"token punctuation\">, </span></span><span class=\"parameter \">tileMode<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/TileMode.html\">TileMode</a><span class=\"token operator\"> = </span>TileMode.Clamp</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Brush.html\">Brush</a></div><p class=\"paragraph\">Creates a linear gradient brush for lines in <a href=\"../-jet-lime-column.html\">JetLimeColumn</a> or <a href=\"../-jet-lime-row.html\">JetLimeRow</a> components.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A <a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Brush.html\">Brush</a> object representing a linear gradient.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>colors</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The colors to be used in the gradient. Defaults to primary, secondary, and tertiary colors from MaterialTheme's color scheme.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>start</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The start offset for the gradient.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>end</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The end offset for the gradient.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>tile</span><wbr></wbr><span><span>Mode</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The tile mode for the gradient.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-defaults/line-solid-brush.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>lineSolidBrush</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeDefaults/lineSolidBrush/#androidx.compose.ui.graphics.Color/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeDefaults</a><span class=\"delimiter\">/</span><span class=\"current\">lineSolidBrush</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>line</span><wbr></wbr><span>Solid</span><wbr></wbr><span><span>Brush</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"line-solid-brush.html\"><span class=\"token function\">lineSolidBrush</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">color<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\"> = </span>MaterialTheme.colorScheme.primary</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Brush.html\">Brush</a></div><p class=\"paragraph\">Creates a solid color brush for lines in <a href=\"../-jet-lime-column.html\">JetLimeColumn</a> or <a href=\"../-jet-lime-row.html\">JetLimeRow</a> components.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A <a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Brush.html\">Brush</a> object representing a solid color.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>color</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The color to be used for the brush. Defaults to the primary color from MaterialTheme's color scheme.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-defaults/row-style.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>rowStyle</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeDefaults/rowStyle/#androidx.compose.ui.unit.Dp#androidx.compose.ui.unit.Dp#androidx.compose.ui.unit.Dp#androidx.compose.ui.graphics.Brush#androidx.compose.ui.graphics.PathEffect?#com.pushpal.jetlime.HorizontalAlignment/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeDefaults</a><span class=\"delimiter\">/</span><span class=\"current\">rowStyle</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>row</span><wbr></wbr><span><span>Style</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"row-style.html\"><span class=\"token function\">rowStyle</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">contentDistance<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>ContentDistance<span class=\"token punctuation\">, </span></span><span class=\"parameter \">itemSpacing<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>ItemSpacing<span class=\"token punctuation\">, </span></span><span class=\"parameter \">lineThickness<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>LineThickness<span class=\"token punctuation\">, </span></span><span class=\"parameter \">lineBrush<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Brush.html\">Brush</a><span class=\"token operator\"> = </span>lineSolidBrush()<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pathEffect<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/PathEffect.html\">PathEffect</a><span class=\"token operator\">?</span><span class=\"token operator\"> = </span>null<span class=\"token punctuation\">, </span></span><span class=\"parameter \">lineHorizontalAlignment<span class=\"token operator\">: </span><a href=\"../-horizontal-alignment/index.html\">HorizontalAlignment</a><span class=\"token operator\"> = </span>TOP</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../-jet-lime-style/index.html\">JetLimeStyle</a></div><p class=\"paragraph\">Creates a row style configuration for <a href=\"../-jet-lime-row.html\">JetLimeRow</a>.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A <a href=\"../-jet-lime-style/index.html\">JetLimeStyle</a> instance configured for row arrangement.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>content</span><wbr></wbr><span><span>Distance</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The distance of content from the JetLime component's start.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>item</span><wbr></wbr><span><span>Spacing</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The spacing between items in the JetLime component.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span><span>Thickness</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The thickness of the line in the JetLime component.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span><span>Brush</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The brush used for the line in the JetLime component.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>path</span><wbr></wbr><span><span>Effect</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">the effect applied to the geometry of the timeline to obtain a dashed pattern.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span>Horizontal</span><wbr></wbr><span><span>Alignment</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The horizontal alignment of the line: <a href=\"../-horizontal-alignment/-t-o-p/index.html\">TOP</a> or <a href=\"../-horizontal-alignment/-b-o-t-t-o-m/index.html\">BOTTOM</a></p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-defaults/event-style.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>eventStyle</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventDefaults/eventStyle/#com.pushpal.jetlime.EventPosition#com.pushpal.jetlime.PointPlacement#com.pushpal.jetlime.EventPointType#androidx.compose.ui.graphics.Color#androidx.compose.ui.graphics.Color#androidx.compose.ui.unit.Dp#com.pushpal.jetlime.EventPointAnimation?#androidx.compose.ui.unit.Dp#androidx.compose.ui.graphics.Color/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventDefaults</a><span class=\"delimiter\">/</span><span class=\"current\">eventStyle</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>event</span><wbr></wbr><span><span>Style</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"event-style.html\"><span class=\"token function\">eventStyle</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">position<span class=\"token operator\">: </span><a href=\"../-event-position/index.html\">EventPosition</a><span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointPlacement<span class=\"token operator\">: </span><a href=\"../-point-placement/index.html\">PointPlacement</a><span class=\"token operator\"> = </span>PointPlacement.START<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointType<span class=\"token operator\">: </span><a href=\"../-event-point-type/index.html\">EventPointType</a><span class=\"token operator\"> = </span>PointType<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointColor<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\"> = </span>MaterialTheme.colorScheme.onPrimary<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointFillColor<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\"> = </span>MaterialTheme.colorScheme.primary<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointRadius<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>PointRadius<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointAnimation<span class=\"token operator\">: </span><a href=\"../-event-point-animation/index.html\">EventPointAnimation</a><span class=\"token operator\">?</span><span class=\"token operator\"> = </span>null<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointStrokeWidth<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>PointStrokeWidth<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointStrokeColor<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\"> = </span>MaterialTheme.colorScheme.primary</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../-jet-lime-event-style/index.html\">JetLimeEventStyle</a></div><p class=\"paragraph\">Creates a default <a href=\"../-jet-lime-event-style/index.html\">JetLimeEventStyle</a> object with specified parameters.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A <a href=\"../-jet-lime-event-style/index.html\">JetLimeEventStyle</a> object configured with the given parameters.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>position</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The position of the event relative to the timeline.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>point</span><wbr></wbr><span><span>Placement</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">Controls where the point renders within the item. One of <a href=\"../-point-placement/-s-t-a-r-t/index.html\">PointPlacement.START</a>, <a href=\"../-point-placement/-c-e-n-t-e-r/index.html\">PointPlacement.CENTER</a>, or <a href=\"../-point-placement/-e-n-d/index.html\">PointPlacement.END</a>. Defaults to START.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>point</span><wbr></wbr><span><span>Type</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The type of point used in the event. Defaults to a filled point.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>point</span><wbr></wbr><span><span>Color</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The color of the point. Defaults to the 'onPrimary' color from MaterialTheme's color scheme.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>point</span><wbr></wbr><span>Fill</span><wbr></wbr><span><span>Color</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The fill color of the point. Defaults to the primary color from MaterialTheme's color scheme.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>point</span><wbr></wbr><span><span>Radius</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The radius of the point. Defaults to <span data-unresolved-link=\"com.pushpal.jetlime/JetLimeEventDefaults/PointRadius/#/PointingToDeclaration/\">PointRadius</span>.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>point</span><wbr></wbr><span><span>Animation</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The animation for the point, if any.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>point</span><wbr></wbr><span>Stroke</span><wbr></wbr><span><span>Width</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The stroke width of the point. Defaults to <span data-unresolved-link=\"com.pushpal.jetlime/JetLimeEventDefaults/PointStrokeWidth/#/PointingToDeclaration/\">PointStrokeWidth</span>.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>point</span><wbr></wbr><span>Stroke</span><wbr></wbr><span><span>Color</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The stroke color of the point. Defaults to the primary color from MaterialTheme's color scheme.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-defaults/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>JetLimeEventDefaults</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventDefaults///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">JetLimeEventDefaults</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span>Event</span><wbr></wbr><span><span>Defaults</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">object </span><a href=\"index.html\">JetLimeEventDefaults</a></div><p class=\"paragraph\">Provides default values and utility functions for <a href=\"../-jet-lime-event.html\">JetLimeEvent</a> styling.</p><p class=\"paragraph\">This object contains default values and composable functions for creating event styles and point animations in <a href=\"../-jet-lime-column.html\">JetLimeColumn</a> or <a href=\"../-jet-lime-row.html\">JetLimeRow</a> components. It offers a convenient way to access standard styling options and animations for JetLime events.</p></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"-220424832%2FFunctions%2F538146535\" anchor-label=\"eventStyle\" id=\"-220424832%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"event-style.html\"><span>event</span><wbr></wbr><span><span>Style</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-220424832%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"event-style.html\"><span class=\"token function\">eventStyle</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">position<span class=\"token operator\">: </span><a href=\"../-event-position/index.html\">EventPosition</a><span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointPlacement<span class=\"token operator\">: </span><a href=\"../-point-placement/index.html\">PointPlacement</a><span class=\"token operator\"> = </span>PointPlacement.START<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointType<span class=\"token operator\">: </span><a href=\"../-event-point-type/index.html\">EventPointType</a><span class=\"token operator\"> = </span>PointType<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointColor<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\"> = </span>MaterialTheme.colorScheme.onPrimary<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointFillColor<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\"> = </span>MaterialTheme.colorScheme.primary<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointRadius<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>PointRadius<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointAnimation<span class=\"token operator\">: </span><a href=\"../-event-point-animation/index.html\">EventPointAnimation</a><span class=\"token operator\">?</span><span class=\"token operator\"> = </span>null<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointStrokeWidth<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>PointStrokeWidth<span class=\"token punctuation\">, </span></span><span class=\"parameter \">pointStrokeColor<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a><span class=\"token operator\"> = </span>MaterialTheme.colorScheme.primary</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../-jet-lime-event-style/index.html\">JetLimeEventStyle</a></div><div class=\"brief \"><p class=\"paragraph\">Creates a default <a href=\"../-jet-lime-event-style/index.html\">JetLimeEventStyle</a> object with specified parameters.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"765811480%2FFunctions%2F538146535\" anchor-label=\"pointAnimation\" id=\"765811480%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"point-animation.html\"><span>point</span><wbr></wbr><span><span>Animation</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"765811480%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"point-animation.html\"><span class=\"token function\">pointAnimation</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">initialValue<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a><span class=\"token operator\"> = </span><span class=\"token constant\">1.0f</span><span class=\"token punctuation\">, </span></span><span class=\"parameter \">targetValue<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a><span class=\"token operator\"> = </span><span class=\"token constant\">1.2f</span><span class=\"token punctuation\">, </span></span><span class=\"parameter \">animationSpec<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/animation/core/InfiniteRepeatableSpec.html\">InfiniteRepeatableSpec</a><span class=\"token operator\">&lt;</span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a><span class=\"token operator\">&gt;</span><span class=\"token operator\"> = </span>PointAnimation</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../-event-point-animation/index.html\">EventPointAnimation</a></div><div class=\"brief \"><p class=\"paragraph\">Creates an <a href=\"../-event-point-animation/index.html\">EventPointAnimation</a> object to define animations for event points.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-defaults/point-animation.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>pointAnimation</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventDefaults/pointAnimation/#kotlin.Float#kotlin.Float#androidx.compose.animation.core.InfiniteRepeatableSpec[kotlin.Float]/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventDefaults</a><span class=\"delimiter\">/</span><span class=\"current\">pointAnimation</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>point</span><wbr></wbr><span><span>Animation</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"point-animation.html\"><span class=\"token function\">pointAnimation</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">initialValue<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a><span class=\"token operator\"> = </span><span class=\"token constant\">1.0f</span><span class=\"token punctuation\">, </span></span><span class=\"parameter \">targetValue<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a><span class=\"token operator\"> = </span><span class=\"token constant\">1.2f</span><span class=\"token punctuation\">, </span></span><span class=\"parameter \">animationSpec<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/animation/core/InfiniteRepeatableSpec.html\">InfiniteRepeatableSpec</a><span class=\"token operator\">&lt;</span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-float/index.html\">Float</a><span class=\"token operator\">&gt;</span><span class=\"token operator\"> = </span>PointAnimation</span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"../-event-point-animation/index.html\">EventPointAnimation</a></div><p class=\"paragraph\">Creates an <a href=\"../-event-point-animation/index.html\">EventPointAnimation</a> object to define animations for event points.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">An <a href=\"../-event-point-animation/index.html\">EventPointAnimation</a> object configured with the given parameters.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>initial</span><wbr></wbr><span><span>Value</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The initial value of the animation. Defaults to 1.0f.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>target</span><wbr></wbr><span><span>Value</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The target value of the animation. Defaults to 1.2f.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>animation</span><wbr></wbr><span><span>Spec</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The specification for the animation. Defaults to <span data-unresolved-link=\"com.pushpal.jetlime/JetLimeEventDefaults/PointAnimation/#/PointingToDeclaration/\">PointAnimation</span>.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/equals.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>equals</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/equals/#kotlin.Any?/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">equals</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>equals</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">operator override </span><span class=\"token keyword\">fun </span><a href=\"equals.html\"><span class=\"token function\">equals</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">other<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><p class=\"paragraph\">Checks if this instance is equal to another object. Two instances of <a href=\"index.html\">JetLimeEventStyle</a> are considered equal if they have the same values for all properties.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\"><code class=\"lang-kotlin\">true</code> if the other object is an instance of <a href=\"index.html\">JetLimeEventStyle</a> and has the same property values, <code class=\"lang-kotlin\">false</code> otherwise.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>other</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The object to compare this instance with.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/hash-code.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>hashCode</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/hashCode/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">hashCode</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>hash</span><wbr></wbr><span><span>Code</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">override </span><span class=\"token keyword\">fun </span><a href=\"hash-code.html\"><span class=\"token function\">hashCode</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div><p class=\"paragraph\">Returns a hash code value for the object, consistent with the definition of equality for the class. This supports the use in hash tables, like those provided by <code class=\"lang-kotlin\">HashMap</code>.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A hash code value for this object.</p></span></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>JetLimeEventStyle</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">JetLimeEventStyle</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span>Event</span><wbr></wbr><span><span>Style</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable.html\"><span class=\"token annotation builtin\">Immutable</span></a></div></div><span class=\"token keyword\">class </span><a href=\"index.html\">JetLimeEventStyle</a></div><p class=\"paragraph\">Represents the style configuration for an event in a <a href=\"../-jet-lime-event.html\">JetLimeEvent</a> UI component. This class encapsulates various styling properties such as position, point type, colors, radius, animation, and stroke attributes for an event point.</p></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"251973028%2FProperties%2F538146535\" anchor-label=\"pointAnimation\" id=\"251973028%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"point-animation.html\"><span>point</span><wbr></wbr><span><span>Animation</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"251973028%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-animation.html\">pointAnimation</a><span class=\"token operator\">: </span><a href=\"../-event-point-animation/index.html\">EventPointAnimation</a><span class=\"token operator\">?</span></div><div class=\"brief \"><p class=\"paragraph\">Optional animation for the event point.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"1680519205%2FProperties%2F538146535\" anchor-label=\"pointColor\" id=\"1680519205%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"point-color.html\"><span>point</span><wbr></wbr><span><span>Color</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1680519205%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-color.html\">pointColor</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a></div><div class=\"brief \"><p class=\"paragraph\">The color of the event point.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"1176616200%2FProperties%2F538146535\" anchor-label=\"pointFillColor\" id=\"1176616200%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"point-fill-color.html\"><span>point</span><wbr></wbr><span>Fill</span><wbr></wbr><span><span>Color</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1176616200%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-fill-color.html\">pointFillColor</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a></div><div class=\"brief \"><p class=\"paragraph\">The fill color of the event point.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-2053229213%2FProperties%2F538146535\" anchor-label=\"pointPlacement\" id=\"-2053229213%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"point-placement.html\"><span>point</span><wbr></wbr><span><span>Placement</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-2053229213%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">var </span><a href=\"point-placement.html\">pointPlacement</a><span class=\"token operator\">: </span><a href=\"../-point-placement/index.html\">PointPlacement</a></div><div class=\"brief \"><p class=\"paragraph\">The placement of the point relative to the event content (START, CENTER, or END).</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"1799796320%2FProperties%2F538146535\" anchor-label=\"pointRadius\" id=\"1799796320%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"point-radius.html\"><span>point</span><wbr></wbr><span><span>Radius</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1799796320%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-radius.html\">pointRadius</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a></div><div class=\"brief \"><p class=\"paragraph\">The radius of the event point.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-107068355%2FProperties%2F538146535\" anchor-label=\"pointStrokeColor\" id=\"-107068355%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"point-stroke-color.html\"><span>point</span><wbr></wbr><span>Stroke</span><wbr></wbr><span><span>Color</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-107068355%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-stroke-color.html\">pointStrokeColor</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a></div><div class=\"brief \"><p class=\"paragraph\">The stroke color of the event point.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1798558918%2FProperties%2F538146535\" anchor-label=\"pointStrokeWidth\" id=\"-1798558918%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"point-stroke-width.html\"><span>point</span><wbr></wbr><span>Stroke</span><wbr></wbr><span><span>Width</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1798558918%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-stroke-width.html\">pointStrokeWidth</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a></div><div class=\"brief \"><p class=\"paragraph\">The stroke width of the event point.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-939877896%2FProperties%2F538146535\" anchor-label=\"pointType\" id=\"-939877896%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"point-type.html\"><span>point</span><wbr></wbr><span><span>Type</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-939877896%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-type.html\">pointType</a><span class=\"token operator\">: </span><a href=\"../-event-point-type/index.html\">EventPointType</a></div><div class=\"brief \"><p class=\"paragraph\">The type of the event point: Empty, Filled or Custom.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1113465297%2FProperties%2F538146535\" anchor-label=\"position\" id=\"-1113465297%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"position.html\"><span><span>position</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1113465297%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">var </span><a href=\"position.html\">position</a><span class=\"token operator\">: </span><a href=\"../-event-position/index.html\">EventPosition</a></div><div class=\"brief \"><p class=\"paragraph\">The position of the event in the UI component.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"-585432247%2FFunctions%2F538146535\" anchor-label=\"equals\" id=\"-585432247%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"equals.html\"><span><span>equals</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-585432247%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">operator override </span><span class=\"token keyword\">fun </span><a href=\"equals.html\"><span class=\"token function\">equals</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">other<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><div class=\"brief \"><p class=\"paragraph\">Checks if this instance is equal to another object. Two instances of <a href=\"index.html\">JetLimeEventStyle</a> are considered equal if they have the same values for all properties.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1861247107%2FFunctions%2F538146535\" anchor-label=\"hashCode\" id=\"-1861247107%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"hash-code.html\"><span>hash</span><wbr></wbr><span><span>Code</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1861247107%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">override </span><span class=\"token keyword\">fun </span><a href=\"hash-code.html\"><span class=\"token function\">hashCode</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div><div class=\"brief \"><p class=\"paragraph\">Returns a hash code value for the object, consistent with the definition of equality for the class. This supports the use in hash tables, like those provided by <code class=\"lang-kotlin\">HashMap</code>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-807828420%2FFunctions%2F538146535\" anchor-label=\"setPointPlacement\" id=\"-807828420%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"set-point-placement.html\"><span>set</span><wbr></wbr><span>Point</span><wbr></wbr><span><span>Placement</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-807828420%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"set-point-placement.html\"><span class=\"token function\">setPointPlacement</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">pointPlacement<span class=\"token operator\">: </span><a href=\"../-point-placement/index.html\">PointPlacement</a></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"index.html\">JetLimeEventStyle</a></div><div class=\"brief \"><p class=\"paragraph\">Sets the placement of the point relative to the event content.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"247959170%2FFunctions%2F538146535\" anchor-label=\"setPosition\" id=\"247959170%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"set-position.html\"><span>set</span><wbr></wbr><span><span>Position</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"247959170%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"set-position.html\"><span class=\"token function\">setPosition</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">position<span class=\"token operator\">: </span><a href=\"../-event-position/index.html\">EventPosition</a></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"index.html\">JetLimeEventStyle</a></div><div class=\"brief \"><p class=\"paragraph\">Sets the position of the <a href=\"../-jet-lime-event.html\">JetLimeEvent</a>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-animation.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>pointAnimation</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/pointAnimation/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">pointAnimation</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>point</span><wbr></wbr><span><span>Animation</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-animation.html\">pointAnimation</a><span class=\"token operator\">: </span><a href=\"../-event-point-animation/index.html\">EventPointAnimation</a><span class=\"token operator\">?</span></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-color.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>pointColor</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/pointColor/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">pointColor</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>point</span><wbr></wbr><span><span>Color</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-color.html\">pointColor</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-fill-color.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>pointFillColor</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/pointFillColor/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">pointFillColor</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>point</span><wbr></wbr><span>Fill</span><wbr></wbr><span><span>Color</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-fill-color.html\">pointFillColor</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-placement.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>pointPlacement</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/pointPlacement/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">pointPlacement</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>point</span><wbr></wbr><span><span>Placement</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">var </span><a href=\"point-placement.html\">pointPlacement</a><span class=\"token operator\">: </span><a href=\"../-point-placement/index.html\">PointPlacement</a></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-radius.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>pointRadius</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/pointRadius/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">pointRadius</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>point</span><wbr></wbr><span><span>Radius</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-radius.html\">pointRadius</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-stroke-color.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>pointStrokeColor</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/pointStrokeColor/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">pointStrokeColor</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>point</span><wbr></wbr><span>Stroke</span><wbr></wbr><span><span>Color</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-stroke-color.html\">pointStrokeColor</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Color.html\">Color</a></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-stroke-width.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>pointStrokeWidth</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/pointStrokeWidth/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">pointStrokeWidth</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>point</span><wbr></wbr><span>Stroke</span><wbr></wbr><span><span>Width</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-stroke-width.html\">pointStrokeWidth</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-type.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>pointType</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/pointType/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">pointType</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>point</span><wbr></wbr><span><span>Type</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"point-type.html\">pointType</a><span class=\"token operator\">: </span><a href=\"../-event-point-type/index.html\">EventPointType</a></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/position.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>position</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/position/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">position</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>position</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">var </span><a href=\"position.html\">position</a><span class=\"token operator\">: </span><a href=\"../-event-position/index.html\">EventPosition</a></div><p class=\"paragraph\">The position of the event in the UI component.</p></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/set-point-placement.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>setPointPlacement</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/setPointPlacement/#com.pushpal.jetlime.PointPlacement/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">setPointPlacement</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>set</span><wbr></wbr><span>Point</span><wbr></wbr><span><span>Placement</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"set-point-placement.html\"><span class=\"token function\">setPointPlacement</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">pointPlacement<span class=\"token operator\">: </span><a href=\"../-point-placement/index.html\">PointPlacement</a></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"index.html\">JetLimeEventStyle</a></div><p class=\"paragraph\">Sets the placement of the point relative to the event content.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A <a href=\"index.html\">JetLimeEventStyle</a> instance with the updated point placement.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>point</span><wbr></wbr><span><span>Placement</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The <a href=\"../-point-placement/index.html\">PointPlacement</a> to use for drawing the point.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event-style/set-position.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>setPosition</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle/setPosition/#com.pushpal.jetlime.EventPosition/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeEventStyle</a><span class=\"delimiter\">/</span><span class=\"current\">setPosition</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>set</span><wbr></wbr><span><span>Position</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"set-position.html\"><span class=\"token function\">setPosition</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">position<span class=\"token operator\">: </span><a href=\"../-event-position/index.html\">EventPosition</a></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"index.html\">JetLimeEventStyle</a></div><p class=\"paragraph\">Sets the position of the <a href=\"../-jet-lime-event.html\">JetLimeEvent</a>.</p><p class=\"paragraph\">This function allows for changing the position of a JetLime event. It modifies the current instance of <a href=\"index.html\">JetLimeEventStyle</a>, setting its position property to the specified <a href=\"../-event-position/index.html\">EventPosition</a>.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">A <a href=\"index.html\">JetLimeEventStyle</a> instance with the updated position.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>position</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The <a href=\"../-event-position/index.html\">EventPosition</a> to set for the JetLime event.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-event.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>JetLimeEvent</title>\n    <link href=\"../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime//JetLimeEvent/#androidx.compose.ui.Modifier#com.pushpal.jetlime.JetLimeEventStyle#kotlin.Function0[kotlin.Unit]/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">JetLimeEvent</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Event</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"-jet-lime-event.html\"><span class=\"token function\">JetLimeEvent</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">modifier<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.html\">Modifier</a><span class=\"token operator\"> = </span>Modifier<span class=\"token punctuation\">, </span></span><span class=\"parameter \">style<span class=\"token operator\">: </span><a href=\"-jet-lime-event-style/index.html\">JetLimeEventStyle</a><span class=\"token operator\"> = </span>JetLimeEventDefaults.eventStyle(EventPosition.END)<span class=\"token punctuation\">, </span></span><span class=\"parameter \">content<span class=\"token operator\">: </span><span><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a> </span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html\">Unit</a></span></span><span class=\"token punctuation\">)</span></div><p class=\"paragraph\">Composable function for creating a <a href=\"-jet-lime-column.html\">JetLimeColumn</a> or <a href=\"-jet-lime-row.html\">JetLimeRow</a> event.</p><p class=\"paragraph\">Example usage:</p><div class=\"sample-container\"><pre><code class=\"block lang-kotlin\" theme=\"idea\">val items = remember { getItemsList() }<br><br>JetLimeColumn(<br> itemsList = ItemsList(items),<br> key = { _, item -&gt; item.id },<br> style = JetLimeDefaults.columnStyle(),<br>) { index, item, position -&gt;<br>   JetLimeEvent(<br>    style = JetLimeEventDefaults.eventStyle(position = position)<br>   ) {<br>      ComposableContent(item = item)<br>     }<br>  }</code></pre><span class=\"copy-tooltip\"><div class=\"copy-popup-wrapper popup-to-left\"><span class=\"copy-popup-icon\"></span><span>Content copied to clipboard</span></div><span class=\"copy-icon\"></span></span></div><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>modifier</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The modifier to be applied to the event.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>style</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The style of the <a href=\"-jet-lime-column.html\">JetLimeColumn</a> or <a href=\"-jet-lime-row.html\">JetLimeRow</a> event, defaulting to <a href=\"-jet-lime-event-defaults/event-style.html\">JetLimeEventDefaults.eventStyle</a>.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>content</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The composable content inside the event.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-extended-event.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>JetLimeExtendedEvent</title>\n    <link href=\"../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime//JetLimeExtendedEvent/#androidx.compose.ui.Modifier#com.pushpal.jetlime.JetLimeEventStyle#kotlin.Function1[androidx.compose.foundation.layout.BoxScope,kotlin.Unit]#androidx.compose.ui.unit.Dp#kotlin.Function0[kotlin.Unit]/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">JetLimeExtendedEvent</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span>Extended</span><wbr></wbr><span><span>Event</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"-jet-lime-extended-event.html\"><span class=\"token function\">JetLimeExtendedEvent</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">modifier<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.html\">Modifier</a><span class=\"token operator\"> = </span>Modifier<span class=\"token punctuation\">, </span></span><span class=\"parameter \">style<span class=\"token operator\">: </span><a href=\"-jet-lime-event-style/index.html\">JetLimeEventStyle</a><span class=\"token operator\"> = </span>JetLimeEventDefaults.eventStyle(EventPosition.END)<span class=\"token punctuation\">, </span></span><span class=\"parameter \">additionalContent<span class=\"token operator\">: </span><span><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a> </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/BoxScope.html\">BoxScope</a><span class=\"token punctuation\">.</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html\">Unit</a><span class=\"token operator\"> = </span>{ }<span class=\"token punctuation\">, </span></span><span class=\"parameter \">additionalContentMaxWidth<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>AdditionalContentMaxWidth<span class=\"token punctuation\">, </span></span><span class=\"parameter \">content<span class=\"token operator\">: </span><span><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a> </span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html\">Unit</a></span></span><span class=\"token punctuation\">)</span></div><p class=\"paragraph\">Should only be used with a <a href=\"-jet-lime-column.html\">JetLimeColumn</a> for a vertical arrangement of events.</p><p class=\"paragraph\">Composable function for creating a <a href=\"-jet-lime-column.html\">JetLimeColumn</a> event which has 2 slots for content. The main content will be drawn on the right side of the timeline and the additional content will be drawn on the left side of the timeline. The additional content is optional, and has a maximum width constraint defined by the <span data-unresolved-link=\"com.pushpal.jetlime/JetLimeEventDefaults/AdditionalContentMaxWidth/#/PointingToDeclaration/\">JetLimeEventDefaults.AdditionalContentMaxWidth</span>.</p><p class=\"paragraph\">Example usage:</p><div class=\"sample-container\"><pre><code class=\"block lang-kotlin\" theme=\"idea\">val items = remember { getItemsList() }<br><br>JetLimeColumn(<br> itemsList = ItemsList(items),<br> key = { _, item -&gt; item.id },<br> style = JetLimeDefaults.columnStyle(),<br>) { index, item, position -&gt;<br>   JetLimeExtendedEvent(<br>    style = JetLimeEventDefaults.eventStyle(position = position),<br>    additionalContent = { ComposableAdditionalContent(item.icon) }<br>   ) {<br>      ComposableMainContent(item = item.content)<br>     }<br>  }</code></pre><span class=\"copy-tooltip\"><div class=\"copy-popup-wrapper popup-to-left\"><span class=\"copy-popup-icon\"></span><span>Content copied to clipboard</span></div><span class=\"copy-icon\"></span></span></div><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>modifier</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The modifier to be applied to the event.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>style</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The style of the <a href=\"-jet-lime-column.html\">JetLimeColumn</a> event, defaulting to <a href=\"-jet-lime-event-defaults/event-style.html\">JetLimeEventDefaults.eventStyle</a>.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>additional</span><wbr></wbr><span><span>Content</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The optional additional content of the event, placed on the left side of timeline.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>additional</span><wbr></wbr><span>Content</span><wbr></wbr><span>Max</span><wbr></wbr><span><span>Width</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The maximum width allowed for <a href=\"-jet-lime-extended-event.html\">additionalContent</a></p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>content</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The main content of the event, placed on the right side of timeline.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-row.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>JetLimeRow</title>\n    <link href=\"../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime//JetLimeRow/#com.pushpal.jetlime.ItemsList[TypeParam(bounds=[kotlin.Any?])]#androidx.compose.ui.Modifier#com.pushpal.jetlime.JetLimeStyle#androidx.compose.foundation.lazy.LazyListState#androidx.compose.foundation.layout.PaddingValues#kotlin.Function2[kotlin.Int,TypeParam(bounds=[kotlin.Any?]),kotlin.Any]?#kotlin.Function3[kotlin.Int,TypeParam(bounds=[kotlin.Any?]),com.pushpal.jetlime.EventPosition,kotlin.Unit]/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">JetLimeRow</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Row</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><span class=\"token operator\">&lt;</span><a href=\"-jet-lime-row.html\">T</a><span class=\"token operator\">&gt; </span><a href=\"-jet-lime-row.html\"><span class=\"token function\">JetLimeRow</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">itemsList<span class=\"token operator\">: </span><a href=\"-items-list/index.html\">ItemsList</a><span class=\"token operator\">&lt;</span><a href=\"-jet-lime-row.html\">T</a><span class=\"token operator\">&gt;</span><span class=\"token punctuation\">, </span></span><span class=\"parameter \">modifier<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.html\">Modifier</a><span class=\"token operator\"> = </span>Modifier<span class=\"token punctuation\">, </span></span><span class=\"parameter \">style<span class=\"token operator\">: </span><a href=\"-jet-lime-style/index.html\">JetLimeStyle</a><span class=\"token operator\"> = </span>JetLimeDefaults.rowStyle()<span class=\"token punctuation\">, </span></span><span class=\"parameter \">listState<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState.html\">LazyListState</a><span class=\"token operator\"> = </span>rememberLazyListState()<span class=\"token punctuation\">, </span></span><span class=\"parameter \">contentPadding<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/PaddingValues.html\">PaddingValues</a><span class=\"token operator\"> = </span>PaddingValues(0.dp)<span class=\"token punctuation\">, </span></span><span class=\"parameter \">key<span class=\"token operator\">: </span><span class=\"token punctuation\">(</span>index<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a><span class=\"token punctuation\">, </span>item<span class=\"token operator\">: </span><a href=\"-jet-lime-row.html\">T</a><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span><span class=\"token operator\"> = </span>null<span class=\"token punctuation\">, </span></span><span class=\"parameter \">itemContent<span class=\"token operator\">: </span><span><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a> </span><span class=\"token punctuation\">(</span>index<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a><span class=\"token punctuation\">, </span><a href=\"-jet-lime-row.html\">T</a><span class=\"token punctuation\">, </span><a href=\"-event-position/index.html\">EventPosition</a><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html\">Unit</a></span></span><span class=\"token punctuation\">)</span></div><p class=\"paragraph\">A composable function that creates a horizontal timeline interface with a list of items.</p><p class=\"paragraph\">This function sets up a LazyRow layout for displaying items in a horizontal timeline format. It allows for customization of its appearance and behavior through various parameters.</p><p class=\"paragraph\">Example usage:</p><div class=\"sample-container\"><pre><code class=\"block lang-kotlin\" theme=\"idea\">val items = remember { getItemsList() }<br><br>JetLimeRow(<br> itemsList = ItemsList(items),<br> key = { _, item -&gt; item.id },<br> style = JetLimeDefaults.rowStyle(),<br>) { index, item, position -&gt;<br>   JetLimeEvent(<br>    style = JetLimeEventDefaults.eventStyle(position = position)<br>   ) {<br>      ComposableContent(item = item)<br>     }<br>  }</code></pre><span class=\"copy-tooltip\"><div class=\"copy-popup-wrapper popup-to-left\"><span class=\"copy-popup-icon\"></span><span>Content copied to clipboard</span></div><span class=\"copy-icon\"></span></span></div><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>items</span><wbr></wbr><span><span>List</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">A list of items to be displayed in the JetLimeRow.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>modifier</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">A modifier to be applied to the LazyRow.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>style</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The JetLime style configuration. Defaults to a predefined row style.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>list</span><wbr></wbr><span><span>State</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The state object to be used for the LazyRow.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>content</span><wbr></wbr><span><span>Padding</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The padding to apply to the content inside the LazyRow.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>key</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">A factory of stable and unique keys representing the item. Using the same key for multiple items in the list is not allowed. Type of the key should be saveable via Bundle on Android. If null is passed the position in the list will represent the key.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>item</span><wbr></wbr><span><span>Content</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">A composable lambda that takes an index, an item of type <a href=\"-jet-lime-row.html\">T</a>, and an <a href=\"-event-position/index.html\">EventPosition</a> to build each item's content.</p></div></div></div></div></div><h4 class=\"tableheader\">Type Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>T</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The type of items in the items list.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-style/content-distance.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>contentDistance</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeStyle/contentDistance/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeStyle</a><span class=\"delimiter\">/</span><span class=\"current\">contentDistance</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>content</span><wbr></wbr><span><span>Distance</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"content-distance.html\">contentDistance</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a></div><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>content</span><wbr></wbr><span><span>Distance</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The distance of content from the start of the JetLime component.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-style/equals.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>equals</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeStyle/equals/#kotlin.Any?/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeStyle</a><span class=\"delimiter\">/</span><span class=\"current\">equals</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>equals</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">operator override </span><span class=\"token keyword\">fun </span><a href=\"equals.html\"><span class=\"token function\">equals</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">other<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><p class=\"paragraph\">Checks if this <a href=\"index.html\">JetLimeStyle</a> is equal to another object.</p><p class=\"paragraph\">Equality is determined based on the equality of content distance, item spacing, line thickness, line brush, and both horizontal and vertical alignment properties.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\"><code class=\"lang-kotlin\">true</code> if the specified object is equal to this <a href=\"index.html\">JetLimeStyle</a>, <code class=\"lang-kotlin\">false</code> otherwise.</p></span><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span><span>other</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The object to compare with this instance.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-style/hash-code.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>hashCode</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeStyle/hashCode/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeStyle</a><span class=\"delimiter\">/</span><span class=\"current\">hashCode</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>hash</span><wbr></wbr><span><span>Code</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">override </span><span class=\"token keyword\">fun </span><a href=\"hash-code.html\"><span class=\"token function\">hashCode</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div><p class=\"paragraph\">Generates a hash code for this <a href=\"index.html\">JetLimeStyle</a>.</p><p class=\"paragraph\">The hash code is a combination of content distance, item spacing, line thickness, line brush, and alignment properties.</p><span class=\"kdoc-tag\"><h4 class=\"\">Return</h4><p class=\"paragraph\">The hash code value for this <a href=\"index.html\">JetLimeStyle</a>.</p></span></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-style/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>JetLimeStyle</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeStyle///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">JetLimeStyle</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Style</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable.html\"><span class=\"token annotation builtin\">Immutable</span></a></div></div><span class=\"token keyword\">class </span><a href=\"index.html\">JetLimeStyle</a></div><p class=\"paragraph\">Represents the styling configuration for <a href=\"../-jet-lime-column.html\">JetLimeColumn</a> and <a href=\"../-jet-lime-row.html\">JetLimeRow</a> components.</p><p class=\"paragraph\">This class encapsulates various properties that define the appearance and layout of <a href=\"../-jet-lime-column.html\">JetLimeColumn</a> and <a href=\"../-jet-lime-row.html\">JetLimeRow</a> components, such as content distance, item spacing, line thickness, and alignment properties. It provides a fluent API for modifying these properties.</p><ul><li><p class=\"paragraph\">See <a href=\"../-jet-lime-defaults/column-style.html\">JetLimeDefaults.columnStyle</a> for the default style in a <a href=\"../-jet-lime-column.html\">JetLimeColumn</a>.</p></li><li><p class=\"paragraph\">See <a href=\"../-jet-lime-defaults/row-style.html\">JetLimeDefaults.rowStyle</a> for the default style in a <a href=\"../-jet-lime-row.html\">JetLimeRow</a>.</p></li></ul><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>content</span><wbr></wbr><span><span>Distance</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The distance of content from the start of the JetLime component.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>item</span><wbr></wbr><span><span>Spacing</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The spacing between items in the JetLime component.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span><span>Thickness</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The thickness of the line in the JetLime component.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span><span>Brush</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The brush used for the line in the JetLime component.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>path</span><wbr></wbr><span><span>Effect</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">the effect applied to the geometry of the timeline to obtain a dashed pattern.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span>Horizontal</span><wbr></wbr><span><span>Alignment</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The horizontal alignment of the line in the JetLime component.</p></div></div></div></div><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span>Vertical</span><wbr></wbr><span><span>Alignment</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The vertical alignment of the line in the JetLime component.</p></div></div></div></div></div></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"-937590240%2FProperties%2F538146535\" anchor-label=\"contentDistance\" id=\"-937590240%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"content-distance.html\"><span>content</span><wbr></wbr><span><span>Distance</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-937590240%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"content-distance.html\">contentDistance</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1548864834%2FProperties%2F538146535\" anchor-label=\"itemSpacing\" id=\"-1548864834%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"item-spacing.html\"><span>item</span><wbr></wbr><span><span>Spacing</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1548864834%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"item-spacing.html\">itemSpacing</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1389276728%2FProperties%2F538146535\" anchor-label=\"lineBrush\" id=\"-1389276728%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"line-brush.html\"><span>line</span><wbr></wbr><span><span>Brush</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1389276728%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"line-brush.html\">lineBrush</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Brush.html\">Brush</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"1449490883%2FProperties%2F538146535\" anchor-label=\"lineHorizontalAlignment\" id=\"1449490883%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"line-horizontal-alignment.html\"><span>line</span><wbr></wbr><span>Horizontal</span><wbr></wbr><span><span>Alignment</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1449490883%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"line-horizontal-alignment.html\">lineHorizontalAlignment</a><span class=\"token operator\">: </span><a href=\"../-horizontal-alignment/index.html\">HorizontalAlignment</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-148816818%2FProperties%2F538146535\" anchor-label=\"lineThickness\" id=\"-148816818%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"line-thickness.html\"><span>line</span><wbr></wbr><span><span>Thickness</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-148816818%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"line-thickness.html\">lineThickness</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1739780651%2FProperties%2F538146535\" anchor-label=\"lineVerticalAlignment\" id=\"-1739780651%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"line-vertical-alignment.html\"><span>line</span><wbr></wbr><span>Vertical</span><wbr></wbr><span><span>Alignment</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1739780651%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"line-vertical-alignment.html\">lineVerticalAlignment</a><span class=\"token operator\">: </span><a href=\"../-vertical-alignment/index.html\">VerticalAlignment</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"388076950%2FProperties%2F538146535\" anchor-label=\"pathEffect\" id=\"388076950%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"path-effect.html\"><span>path</span><wbr></wbr><span><span>Effect</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"388076950%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"path-effect.html\">pathEffect</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/PathEffect.html\">PathEffect</a><span class=\"token operator\">?</span></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"-275193259%2FFunctions%2F538146535\" anchor-label=\"equals\" id=\"-275193259%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"equals.html\"><span><span>equals</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-275193259%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">operator override </span><span class=\"token keyword\">fun </span><a href=\"equals.html\"><span class=\"token function\">equals</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">other<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html\">Boolean</a></div><div class=\"brief \"><p class=\"paragraph\">Checks if this <a href=\"index.html\">JetLimeStyle</a> is equal to another object.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1551605007%2FFunctions%2F538146535\" anchor-label=\"hashCode\" id=\"-1551605007%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"hash-code.html\"><span>hash</span><wbr></wbr><span><span>Code</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1551605007%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">open </span><span class=\"token keyword\">override </span><span class=\"token keyword\">fun </span><a href=\"hash-code.html\"><span class=\"token function\">hashCode</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div><div class=\"brief \"><p class=\"paragraph\">Generates a hash code for this <a href=\"index.html\">JetLimeStyle</a>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-style/item-spacing.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>itemSpacing</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeStyle/itemSpacing/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeStyle</a><span class=\"delimiter\">/</span><span class=\"current\">itemSpacing</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>item</span><wbr></wbr><span><span>Spacing</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"item-spacing.html\">itemSpacing</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a></div><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>item</span><wbr></wbr><span><span>Spacing</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The spacing between items in the JetLime component.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-style/line-brush.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>lineBrush</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeStyle/lineBrush/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeStyle</a><span class=\"delimiter\">/</span><span class=\"current\">lineBrush</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>line</span><wbr></wbr><span><span>Brush</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"line-brush.html\">lineBrush</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/Brush.html\">Brush</a></div><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span><span>Brush</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The brush used for the line in the JetLime component.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-style/line-horizontal-alignment.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>lineHorizontalAlignment</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeStyle/lineHorizontalAlignment/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeStyle</a><span class=\"delimiter\">/</span><span class=\"current\">lineHorizontalAlignment</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>line</span><wbr></wbr><span>Horizontal</span><wbr></wbr><span><span>Alignment</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"line-horizontal-alignment.html\">lineHorizontalAlignment</a><span class=\"token operator\">: </span><a href=\"../-horizontal-alignment/index.html\">HorizontalAlignment</a></div><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span>Horizontal</span><wbr></wbr><span><span>Alignment</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The horizontal alignment of the line in the JetLime component.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-style/line-thickness.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>lineThickness</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeStyle/lineThickness/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeStyle</a><span class=\"delimiter\">/</span><span class=\"current\">lineThickness</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>line</span><wbr></wbr><span><span>Thickness</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"line-thickness.html\">lineThickness</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a></div><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span><span>Thickness</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The thickness of the line in the JetLime component.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-style/line-vertical-alignment.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>lineVerticalAlignment</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeStyle/lineVerticalAlignment/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeStyle</a><span class=\"delimiter\">/</span><span class=\"current\">lineVerticalAlignment</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>line</span><wbr></wbr><span>Vertical</span><wbr></wbr><span><span>Alignment</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"line-vertical-alignment.html\">lineVerticalAlignment</a><span class=\"token operator\">: </span><a href=\"../-vertical-alignment/index.html\">VerticalAlignment</a></div><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>line</span><wbr></wbr><span>Vertical</span><wbr></wbr><span><span>Alignment</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">The vertical alignment of the line in the JetLime component.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-jet-lime-style/path-effect.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>pathEffect</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/JetLimeStyle/pathEffect/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">JetLimeStyle</a><span class=\"delimiter\">/</span><span class=\"current\">pathEffect</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>path</span><wbr></wbr><span><span>Effect</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"path-effect.html\">pathEffect</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/graphics/PathEffect.html\">PathEffect</a><span class=\"token operator\">?</span></div><h4 class=\"tableheader\">Parameters</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><u><span>path</span><wbr></wbr><span><span>Effect</span></span></u></div></span></div><div><div class=\"title\"><p class=\"paragraph\">the effect applied to the geometry of the timeline to obtain a dashed pattern.</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-local-jet-lime-style.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>LocalJetLimeStyle</title>\n    <link href=\"../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime//LocalJetLimeStyle/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">LocalJetLimeStyle</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Local</span><wbr></wbr><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Style</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"-local-jet-lime-style.html\">LocalJetLimeStyle</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/ProvidableCompositionLocal.html\">ProvidableCompositionLocal</a><span class=\"token operator\">&lt;</span><a href=\"-jet-lime-style/index.html\">JetLimeStyle</a><span class=\"token operator\">&gt;</span></div><p class=\"paragraph\">A CompositionLocal providing the current <a href=\"-jet-lime-style/index.html\">JetLimeStyle</a>.</p><p class=\"paragraph\">This is used to provide a default or overridden style configuration down the composition tree. Accessing this without a provider will result in an error, ensuring that the style is always defined when used within a composable context.</p></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-point-placement/-c-e-n-t-e-r/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>CENTER</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/PointPlacement.CENTER///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">PointPlacement</a><span class=\"delimiter\">/</span><span class=\"current\">CENTER</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>CENTER</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"index.html\">CENTER</a></div></div><p class=\"paragraph\">Point drawn centered relative to the event content box.</p></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"-372974862%2FProperties%2F538146535\" anchor-label=\"name\" id=\"-372974862%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\"><span><span>name</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-372974862%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\">name</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-739389684%2FProperties%2F538146535\" anchor-label=\"ordinal\" id=\"-739389684%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\"><span><span>ordinal</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-739389684%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\">ordinal</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-point-placement/-e-n-d/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>END</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/PointPlacement.END///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">PointPlacement</a><span class=\"delimiter\">/</span><span class=\"current\">END</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>END</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"index.html\">END</a></div></div><p class=\"paragraph\">Point drawn at the end edge (bottom for vertical, right for horizontal).</p></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"-372974862%2FProperties%2F538146535\" anchor-label=\"name\" id=\"-372974862%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\"><span><span>name</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-372974862%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\">name</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-739389684%2FProperties%2F538146535\" anchor-label=\"ordinal\" id=\"-739389684%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\"><span><span>ordinal</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-739389684%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\">ordinal</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-point-placement/-s-t-a-r-t/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>START</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/PointPlacement.START///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">PointPlacement</a><span class=\"delimiter\">/</span><span class=\"current\">START</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>START</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"index.html\">START</a></div></div><p class=\"paragraph\">Point drawn at the start edge (existing default behaviour).</p></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"-372974862%2FProperties%2F538146535\" anchor-label=\"name\" id=\"-372974862%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\"><span><span>name</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-372974862%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\">name</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-739389684%2FProperties%2F538146535\" anchor-label=\"ordinal\" id=\"-739389684%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\"><span><span>ordinal</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-739389684%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\">ordinal</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-point-placement/entries.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>entries</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/PointPlacement/entries/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">PointPlacement</a><span class=\"delimiter\">/</span><span class=\"current\">entries</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>entries</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"entries.html\">entries</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.enums/-enum-entries/index.html\">EnumEntries</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">PointPlacement</a><span class=\"token operator\">&gt;</span></div><p class=\"paragraph\">Returns a representation of an immutable list of all enum entries, in the order they're declared.</p><p class=\"paragraph\">This method may be used to iterate over the enum entries.</p></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-point-placement/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>PointPlacement</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/PointPlacement///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">PointPlacement</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Point</span><wbr></wbr><span><span>Placement</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">enum </span><a href=\"index.html\">PointPlacement</a> : <a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-enum/index.html\">Enum</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">PointPlacement</a><span class=\"token operator\">&gt; </span></div><p class=\"paragraph\">Defines the placement of the timeline point relative to the event content.</p></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button><button class=\"section-tab\" data-togglable=\"ENTRY\">Entries</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"ENTRY\">\n        <h2 class=\"tableheader\">Entries</h2>\n        <div class=\"table\"><a data-name=\"-480892328%2FClasslikes%2F538146535\" anchor-label=\"START\" id=\"-480892328%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-togglable=\"ENTRY\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-s-t-a-r-t/index.html\">START</a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-480892328%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"-s-t-a-r-t/index.html\">START</a></div></div><div class=\"brief \"><p class=\"paragraph\">Point drawn at the start edge (existing default behaviour).</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-134255769%2FClasslikes%2F538146535\" anchor-label=\"CENTER\" id=\"-134255769%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-togglable=\"ENTRY\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-c-e-n-t-e-r/index.html\">CENTER</a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-134255769%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"-c-e-n-t-e-r/index.html\">CENTER</a></div></div><div class=\"brief \"><p class=\"paragraph\">Point drawn centered relative to the event content box.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"1875066257%2FClasslikes%2F538146535\" anchor-label=\"END\" id=\"1875066257%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-togglable=\"ENTRY\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-e-n-d/index.html\">END</a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1875066257%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"-e-n-d/index.html\">END</a></div></div><div class=\"brief \"><p class=\"paragraph\">Point drawn at the end edge (bottom for vertical, right for horizontal).</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"478019180%2FProperties%2F538146535\" anchor-label=\"entries\" id=\"478019180%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"entries.html\"><span><span>entries</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"478019180%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"entries.html\">entries</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.enums/-enum-entries/index.html\">EnumEntries</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">PointPlacement</a><span class=\"token operator\">&gt;</span></div><div class=\"brief \"><p class=\"paragraph\">Returns a representation of an immutable list of all enum entries, in the order they're declared.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-372974862%2FProperties%2F538146535\" anchor-label=\"name\" id=\"-372974862%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\"><span><span>name</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-372974862%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../-vertical-alignment/-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\">name</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-739389684%2FProperties%2F538146535\" anchor-label=\"ordinal\" id=\"-739389684%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\"><span><span>ordinal</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-739389684%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../-vertical-alignment/-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\">ordinal</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"738963120%2FFunctions%2F538146535\" anchor-label=\"valueOf\" id=\"738963120%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"value-of.html\"><span>value</span><wbr></wbr><span><span>Of</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"738963120%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">fun </span><a href=\"value-of.html\"><span class=\"token function\">valueOf</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">value<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"index.html\">PointPlacement</a></div><div class=\"brief \"><p class=\"paragraph\">Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"2017718204%2FFunctions%2F538146535\" anchor-label=\"values\" id=\"2017718204%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"values.html\"><span><span>values</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"2017718204%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">fun </span><a href=\"values.html\"><span class=\"token function\">values</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-array/index.html\">Array</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">PointPlacement</a><span class=\"token operator\">&gt;</span></div><div class=\"brief \"><p class=\"paragraph\">Returns an array containing the constants of this enum type, in the order they're declared.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-point-placement/value-of.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>valueOf</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/PointPlacement/valueOf/#kotlin.String/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">PointPlacement</a><span class=\"delimiter\">/</span><span class=\"current\">valueOf</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>value</span><wbr></wbr><span><span>Of</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">fun </span><a href=\"value-of.html\"><span class=\"token function\">valueOf</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">value<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"index.html\">PointPlacement</a></div><p class=\"paragraph\">Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)</p><h4 class=\"tableheader\">Throws</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-illegal-argument-exception/index.html\"><span>kotlin.</span><wbr></wbr><span>Illegal</span><wbr></wbr><span>Argument</span><wbr></wbr><span><span>Exception</span></span></a></div></span></div><div><div class=\"title\"><p class=\"paragraph\">if this enum type has no constant with the specified name</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-point-placement/values.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>values</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/PointPlacement/values/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">PointPlacement</a><span class=\"delimiter\">/</span><span class=\"current\">values</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>values</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">fun </span><a href=\"values.html\"><span class=\"token function\">values</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-array/index.html\">Array</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">PointPlacement</a><span class=\"token operator\">&gt;</span></div><p class=\"paragraph\">Returns an array containing the constants of this enum type, in the order they're declared.</p><p class=\"paragraph\">This method may be used to iterate over the constants.</p></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-vertical-alignment/-l-e-f-t/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>LEFT</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/VerticalAlignment.LEFT///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">VerticalAlignment</a><span class=\"delimiter\">/</span><span class=\"current\">LEFT</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>LEFT</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"index.html\">LEFT</a></div></div></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"-372974862%2FProperties%2F538146535\" anchor-label=\"name\" id=\"-372974862%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\"><span><span>name</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-372974862%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\">name</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-739389684%2FProperties%2F538146535\" anchor-label=\"ordinal\" id=\"-739389684%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"../-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\"><span><span>ordinal</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-739389684%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"../-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\">ordinal</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-vertical-alignment/-r-i-g-h-t/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>RIGHT</title>\n    <link href=\"../../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/VerticalAlignment.RIGHT///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">VerticalAlignment</a><span class=\"delimiter\">/</span><span class=\"current\">RIGHT</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>RIGHT</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"index.html\">RIGHT</a></div></div></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"-372974862%2FProperties%2F538146535\" anchor-label=\"name\" id=\"-372974862%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"index.html#-372974862%2FProperties%2F538146535\"><span><span>name</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-372974862%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"index.html#-372974862%2FProperties%2F538146535\">name</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-739389684%2FProperties%2F538146535\" anchor-label=\"ordinal\" id=\"-739389684%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"index.html#-739389684%2FProperties%2F538146535\"><span><span>ordinal</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-739389684%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"index.html#-739389684%2FProperties%2F538146535\">ordinal</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-vertical-alignment/entries.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>entries</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/VerticalAlignment/entries/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">VerticalAlignment</a><span class=\"delimiter\">/</span><span class=\"current\">entries</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>entries</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"entries.html\">entries</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.enums/-enum-entries/index.html\">EnumEntries</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">VerticalAlignment</a><span class=\"token operator\">&gt;</span></div><p class=\"paragraph\">Returns a representation of an immutable list of all enum entries, in the order they're declared.</p><p class=\"paragraph\">This method may be used to iterate over the enum entries.</p></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-vertical-alignment/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>VerticalAlignment</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"classlike\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/VerticalAlignment///PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">VerticalAlignment</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>Vertical</span><wbr></wbr><span><span>Alignment</span></span></h1>\n    <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">enum </span><a href=\"index.html\">VerticalAlignment</a> : <a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-enum/index.html\">Enum</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">VerticalAlignment</a><span class=\"token operator\">&gt; </span></div><p class=\"paragraph\">Enum representing the alignment of the timeline line and points for <a href=\"../-jet-lime-column.html\">JetLimeColumn</a>.</p></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"CONSTRUCTOR,TYPE,PROPERTY,FUNCTION\">Members</button><button class=\"section-tab\" data-togglable=\"ENTRY\">Entries</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"ENTRY\">\n        <h2 class=\"tableheader\">Entries</h2>\n        <div class=\"table\"><a data-name=\"825393495%2FClasslikes%2F538146535\" anchor-label=\"LEFT\" id=\"825393495%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-togglable=\"ENTRY\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-l-e-f-t/index.html\">LEFT</a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"825393495%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"-l-e-f-t/index.html\">LEFT</a></div></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"861885460%2FClasslikes%2F538146535\" anchor-label=\"RIGHT\" id=\"861885460%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-togglable=\"ENTRY\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-r-i-g-h-t/index.html\">RIGHT</a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"861885460%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><a href=\"-r-i-g-h-t/index.html\">RIGHT</a></div></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"1063485482%2FProperties%2F538146535\" anchor-label=\"entries\" id=\"1063485482%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"entries.html\"><span><span>entries</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1063485482%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"entries.html\">entries</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.enums/-enum-entries/index.html\">EnumEntries</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">VerticalAlignment</a><span class=\"token operator\">&gt;</span></div><div class=\"brief \"><p class=\"paragraph\">Returns a representation of an immutable list of all enum entries, in the order they're declared.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-372974862%2FProperties%2F538146535\" anchor-label=\"name\" id=\"-372974862%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\"><span><span>name</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-372974862%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"-r-i-g-h-t/index.html#-372974862%2FProperties%2F538146535\">name</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-739389684%2FProperties%2F538146535\" anchor-label=\"ordinal\" id=\"-739389684%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\"><span><span>ordinal</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-739389684%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">expect </span><span class=\"token keyword\">val </span><a href=\"-r-i-g-h-t/index.html#-739389684%2FProperties%2F538146535\">ordinal</a><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"175862194%2FFunctions%2F538146535\" anchor-label=\"valueOf\" id=\"175862194%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"value-of.html\"><span>value</span><wbr></wbr><span><span>Of</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"175862194%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">fun </span><a href=\"value-of.html\"><span class=\"token function\">valueOf</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">value<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"index.html\">VerticalAlignment</a></div><div class=\"brief \"><p class=\"paragraph\">Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1981268418%2FFunctions%2F538146535\" anchor-label=\"values\" id=\"-1981268418%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"values.html\"><span><span>values</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1981268418%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">fun </span><a href=\"values.html\"><span class=\"token function\">values</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-array/index.html\">Array</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">VerticalAlignment</a><span class=\"token operator\">&gt;</span></div><div class=\"brief \"><p class=\"paragraph\">Returns an array containing the constants of this enum type, in the order they're declared.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-vertical-alignment/value-of.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>valueOf</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/VerticalAlignment/valueOf/#kotlin.String/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">VerticalAlignment</a><span class=\"delimiter\">/</span><span class=\"current\">valueOf</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span>value</span><wbr></wbr><span><span>Of</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">fun </span><a href=\"value-of.html\"><span class=\"token function\">valueOf</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">value<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-string/index.html\">String</a></span></span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"index.html\">VerticalAlignment</a></div><p class=\"paragraph\">Returns the enum constant of this type with the specified name. The string must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.)</p><h4 class=\"tableheader\">Throws</h4><div class=\"table\"><div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\"><div class=\"main-subrow keyValue \"><div class=\"\"><span class=\"inline-flex\"><div><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-illegal-argument-exception/index.html\"><span>kotlin.</span><wbr></wbr><span>Illegal</span><wbr></wbr><span>Argument</span><wbr></wbr><span><span>Exception</span></span></a></div></span></div><div><div class=\"title\"><p class=\"paragraph\">if this enum type has no constant with the specified name</p></div></div></div></div></div></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/-vertical-alignment/values.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>values</title>\n    <link href=\"../../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"member\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime/VerticalAlignment/values/#/PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../../index.html\">jetlime</a><span class=\"delimiter\">/</span><a href=\"../index.html\">com.pushpal.jetlime</a><span class=\"delimiter\">/</span><a href=\"index.html\">VerticalAlignment</a><span class=\"delimiter\">/</span><span class=\"current\">values</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>values</span></span></h1>\n  </div>\n  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">fun </span><a href=\"values.html\"><span class=\"token function\">values</span></a><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-array/index.html\">Array</a><span class=\"token operator\">&lt;</span><a href=\"index.html\">VerticalAlignment</a><span class=\"token operator\">&gt;</span></div><p class=\"paragraph\">Returns an array containing the constants of this enum type, in the order they're declared.</p><p class=\"paragraph\">This method may be used to iterate over the constants.</p></div></div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/com.pushpal.jetlime/index.html",
    "content": "<!DOCTYPE html>\n<html class=\"no-js\" lang=\"en\">\n<head>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" charset=\"UTF-8\">\n    <title>com.pushpal.jetlime</title>\n    <link href=\"../../images/logo-icon.svg\" rel=\"icon\" type=\"image/svg\">\n        <script>var pathToRoot = \"../../\";</script>\n    <script>document.documentElement.classList.replace(\"no-js\", \"js\");</script>\n    <script>const storage = localStorage.getItem(\"dokka-dark-mode\")\n      if (storage == null) {\n        const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n        if (osDarkSchemePreferred === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      } else {\n        const savedDarkMode = JSON.parse(storage)\n        if (savedDarkMode === true) {\n          document.getElementsByTagName(\"html\")[0].classList.add(\"theme-dark\")\n        }\n      }\n    </script>\n<script type=\"text/javascript\" src=\"../../scripts/sourceset_dependencies.js\" async=\"async\"></script>\n<link href=\"../../styles/style.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/main.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/prism.css\" rel=\"Stylesheet\">\n<link href=\"../../styles/logo-styles.css\" rel=\"Stylesheet\">\n<link href=\"../../ui-kit/ui-kit.min.css\" rel=\"Stylesheet\">\n<script type=\"text/javascript\" src=\"../../scripts/safe-local-storage_blocking.js\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/navigation-loader.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/platform-content-handler.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/main.js\" defer=\"defer\"></script>\n<script type=\"text/javascript\" src=\"../../scripts/prism.js\" async=\"async\"></script>\n<script type=\"text/javascript\" src=\"../../ui-kit/ui-kit.min.js\" defer=\"defer\"></script>\n</head>\n<body>\n<div class=\"root\">\n    <header class=\"navigation theme-dark\" id=\"navigation-wrapper\" role=\"banner\">\n            <a class=\"library-name--link\" href=\"../../index.html\" tabindex=\"1\">\n                    jetlime\n            </a>\n        <button class=\"navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only\" id=\"toc-toggle\"\n                type=\"button\">Toggle table of contents\n        </button>\n        <div class=\"navigation-controls--break ui-kit_mobile-only\"></div>\n        <div class=\"library-version\" id=\"library-version\">\n        </div>\n        <div class=\"navigation-controls\">\n        <ul class=\"filter-section filter-section_loading\" id=\"filter-section\" aria-label=\"Target filter\">\n                <button class=\"platform-tag platform-selector common-like\" data-active=\"\" aria-pressed=\"true\"\n                        data-filter=\":jetlime/commonMain\">common</button>\n            <div class=\"dropdown filter-section--dropdown\" data-role=\"dropdown\" id=\"filter-section-dropdown\">\n                <button class=\"button button_dropdown filter-section--dropdown-toggle\" role=\"combobox\"\n                        data-role=\"dropdown-toggle\"\n                        aria-controls=\"platform-tags-listbox\"\n                        aria-haspopup=\"listbox\"\n                        aria-expanded=\"false\"\n                        aria-label=\"Toggle source sets\"\n                ></button>\n                <ul role=\"listbox\" id=\"platform-tags-listbox\" class=\"dropdown--list\" data-role=\"dropdown-listbox\" aria-label=\"Target filter\">\n                    <div class=\"dropdown--header\"><span>Target filter</span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close target filter\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                        <li role=\"option\" class=\"dropdown--option platform-selector-option common-like\" tabindex=\"0\">\n                            <label class=\"checkbox\">\n                                <input type=\"checkbox\" class=\"checkbox--input\" id=\":jetlime/commonMain\"\n                                       data-filter=\":jetlime/commonMain\"/>\n                                <span class=\"checkbox--icon\"></span>\n                                common\n                            </label>\n                        </li>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </ul>\n            <button class=\"navigation-controls--btn navigation-controls--btn_theme\" id=\"theme-toggle-button\"\n                    type=\"button\">Switch theme\n            </button>\n            <div class=\"navigation-controls--btn navigation-controls--btn_search\" id=\"searchBar\" role=\"button\">Search in\n                API\n            </div>\n        </div>\n    </header>\n    <div id=\"container\">\n        <nav id=\"leftColumn\" class=\"sidebar\" data-item-type=\"SECTION\" data-item-config='{\"defaultSize\": 280, \"minSize\": 200, \"maxSize\": 400}'>\n            <a class=\"toc--skip-link\" href=\"#main\">Skip to content</a>\n            <div class=\"dropdown theme-dark_mobile\" data-role=\"dropdown\" id=\"toc-dropdown\">\n                <ul role=\"listbox\" id=\"toc-listbox\" class=\"dropdown--list dropdown--list_toc-list\"\n                    data-role=\"dropdown-listbox\" aria-label=\"Table of contents\">\n                    <div class=\"dropdown--header\">\n                            <span>\n                                    jetlime\n                            </span>\n                        <button class=\"button\" data-role=\"dropdown-toggle\" aria-label=\"Close table of contents\">\n                            <i class=\"ui-kit-icon ui-kit-icon_cross\"></i>\n                        </button>\n                    </div>\n                    <div class=\"sidebar--inner\" id=\"sideMenu\"></div>\n                </ul>\n                <div class=\"dropdown--overlay\"></div>\n            </div>\n        </nav>\n        <div id=\"resizer\" class=\"resizer\" data-item-type=\"BAR\"></div>\n        <div id=\"main\" data-item-type=\"SECTION\" role=\"main\">\n<div class=\"main-content\" data-page-type=\"package\" id=\"content\" pageIds=\"jetlime::com.pushpal.jetlime////PointingToDeclaration//538146535\">\n  <div class=\"breadcrumbs\"><a href=\"../../index.html\">jetlime</a><span class=\"delimiter\">/</span><span class=\"current\">com.pushpal.jetlime</span></div>\n  <div class=\"cover \">\n    <h1 class=\"cover\"><span><span>Package-level</span></span> <span><span>declarations</span></span></h1>\n    <div class=\"platform-hinted UnderCoverText\" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><h1 class=\"\">JetLime Core Package</h1><p class=\"paragraph\">Contains composables, styles, timeline rendering, and helper utilities.</p><h2 class=\"\">Main Types</h2><ul><li><p class=\"paragraph\">JetLimeEvent, JetLimeExtendedEvent</p></li><li><p class=\"paragraph\">JetLimeColumn, JetLimeRow</p></li><li><p class=\"paragraph\">JetLimeEventStyle, JetLimeStyle</p></li><li><p class=\"paragraph\">EventPosition, PointPlacement</p></li></ul><p class=\"paragraph\">See README for detailed usage samples.</p></div></div>\n  </div>\n  <div class=\"tabbedcontent\">\n    <div class=\"tabs-section\" tabs-section=\"tabs-section\"><button class=\"section-tab\" data-active=\"\" data-togglable=\"TYPE\">Types</button><button class=\"section-tab\" data-togglable=\"FUNCTION,EXTENSION_FUNCTION\">Functions</button><button class=\"section-tab\" data-togglable=\"PROPERTY,EXTENSION_PROPERTY\">Properties</button></div>\n    <div class=\"tabs-section-body\">\n      <div data-togglable=\"TYPE\">\n        <h2 class=\"tableheader\">Types</h2>\n        <div class=\"table\"><a data-name=\"1493753182%2FClasslikes%2F538146535\" anchor-label=\"EventPointAnimation\" id=\"1493753182%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-event-point-animation/index.html\"><span>Event</span><wbr></wbr><span>Point</span><wbr></wbr><span><span>Animation</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1493753182%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable.html\"><span class=\"token annotation builtin\">Immutable</span></a></div></div><span class=\"token keyword\">class </span><a href=\"-event-point-animation/index.html\">EventPointAnimation</a></div><div class=\"brief \"><p class=\"paragraph\">Represents an animation configuration for an event point in a UI component. This animation defines how an event point (circle) should animate, including its initial value, target value, and the specification of the animation.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"2061253478%2FClasslikes%2F538146535\" anchor-label=\"EventPointType\" id=\"2061253478%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-event-point-type/index.html\"><span>Event</span><wbr></wbr><span>Point</span><wbr></wbr><span><span>Type</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"2061253478%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable.html\"><span class=\"token annotation builtin\">Immutable</span></a></div></div><span class=\"token keyword\">class </span><a href=\"-event-point-type/index.html\">EventPointType</a></div><div class=\"brief \"><p class=\"paragraph\">Represents a type of event point in a UI component with an optional icon. This class is used to define different types of event points such as empty, filled, or custom types with specific icons.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"976149097%2FClasslikes%2F538146535\" anchor-label=\"EventPosition\" id=\"976149097%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-event-position/index.html\"><span>Event</span><wbr></wbr><span><span>Position</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"976149097%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable.html\"><span class=\"token annotation builtin\">Immutable</span></a></div></div><span class=\"token keyword\">class </span><a href=\"-event-position/index.html\">EventPosition</a></div><div class=\"brief \"><p class=\"paragraph\">Represents a position of an event within a sequence, such as the start, middle, or end. This class encapsulates the logic for determining the position based on the index in a list.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"901002605%2FClasslikes%2F538146535\" anchor-label=\"HorizontalAlignment\" id=\"901002605%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-horizontal-alignment/index.html\"><span>Horizontal</span><wbr></wbr><span><span>Alignment</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"901002605%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">enum </span><a href=\"-horizontal-alignment/index.html\">HorizontalAlignment</a> : <a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-enum/index.html\">Enum</a><span class=\"token operator\">&lt;</span><a href=\"-horizontal-alignment/index.html\">HorizontalAlignment</a><span class=\"token operator\">&gt; </span></div><div class=\"brief \"><p class=\"paragraph\">Enum representing the alignment of the timeline line and points for <a href=\"-jet-lime-row.html\">JetLimeRow</a>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"1740017070%2FClasslikes%2F538146535\" anchor-label=\"ItemsList\" id=\"1740017070%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-items-list/index.html\"><span>Items</span><wbr></wbr><span><span>List</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1740017070%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable.html\"><span class=\"token annotation builtin\">Immutable</span></a></div></div><span class=\"token keyword\">class </span><a href=\"-items-list/index.html\">ItemsList</a><span class=\"token operator\">&lt;</span><a href=\"-items-list/index.html\">T</a><span class=\"token operator\">&gt;</span><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \"><span class=\"token keyword\">val </span>items<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.collections/-list/index.html\">List</a><span class=\"token operator\">&lt;</span><a href=\"-items-list/index.html\">T</a><span class=\"token operator\">&gt;</span></span></span><span class=\"token punctuation\">)</span></div><div class=\"brief \"><p class=\"paragraph\">An immutable list class that holds a list of items of type <a href=\"-items-list/index.html\">T</a>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"1877349804%2FClasslikes%2F538146535\" anchor-label=\"JetLimeDefaults\" id=\"1877349804%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-jet-lime-defaults/index.html\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Defaults</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1877349804%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">object </span><a href=\"-jet-lime-defaults/index.html\">JetLimeDefaults</a></div><div class=\"brief \"><p class=\"paragraph\">Provides default values and utility functions for <a href=\"-jet-lime-column.html\">JetLimeColumn</a> or <a href=\"-jet-lime-row.html\">JetLimeRow</a> styling.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"1133292344%2FClasslikes%2F538146535\" anchor-label=\"JetLimeEventDefaults\" id=\"1133292344%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-jet-lime-event-defaults/index.html\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span>Event</span><wbr></wbr><span><span>Defaults</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"1133292344%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">object </span><a href=\"-jet-lime-event-defaults/index.html\">JetLimeEventDefaults</a></div><div class=\"brief \"><p class=\"paragraph\">Provides default values and utility functions for <a href=\"-jet-lime-event.html\">JetLimeEvent</a> styling.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"714467623%2FClasslikes%2F538146535\" anchor-label=\"JetLimeEventStyle\" id=\"714467623%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-jet-lime-event-style/index.html\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span>Event</span><wbr></wbr><span><span>Style</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"714467623%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable.html\"><span class=\"token annotation builtin\">Immutable</span></a></div></div><span class=\"token keyword\">class </span><a href=\"-jet-lime-event-style/index.html\">JetLimeEventStyle</a></div><div class=\"brief \"><p class=\"paragraph\">Represents the style configuration for an event in a <a href=\"-jet-lime-event.html\">JetLimeEvent</a> UI component. This class encapsulates various styling properties such as position, point type, colors, radius, animation, and stroke attributes for an event point.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"297120563%2FClasslikes%2F538146535\" anchor-label=\"JetLimeStyle\" id=\"297120563%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-jet-lime-style/index.html\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Style</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"297120563%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Immutable.html\"><span class=\"token annotation builtin\">Immutable</span></a></div></div><span class=\"token keyword\">class </span><a href=\"-jet-lime-style/index.html\">JetLimeStyle</a></div><div class=\"brief \"><p class=\"paragraph\">Represents the styling configuration for <a href=\"-jet-lime-column.html\">JetLimeColumn</a> and <a href=\"-jet-lime-row.html\">JetLimeRow</a> components.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-106004671%2FClasslikes%2F538146535\" anchor-label=\"PointPlacement\" id=\"-106004671%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-point-placement/index.html\"><span>Point</span><wbr></wbr><span><span>Placement</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-106004671%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">enum </span><a href=\"-point-placement/index.html\">PointPlacement</a> : <a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-enum/index.html\">Enum</a><span class=\"token operator\">&lt;</span><a href=\"-point-placement/index.html\">PointPlacement</a><span class=\"token operator\">&gt; </span></div><div class=\"brief \"><p class=\"paragraph\">Defines the placement of the timeline point relative to the event content.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"307797759%2FClasslikes%2F538146535\" anchor-label=\"VerticalAlignment\" id=\"307797759%2FClasslikes%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-vertical-alignment/index.html\"><span>Vertical</span><wbr></wbr><span><span>Alignment</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"307797759%2FClasslikes%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Stable.html\"><span class=\"token annotation builtin\">Stable</span></a></div></div><span class=\"token keyword\">enum </span><a href=\"-vertical-alignment/index.html\">VerticalAlignment</a> : <a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-enum/index.html\">Enum</a><span class=\"token operator\">&lt;</span><a href=\"-vertical-alignment/index.html\">VerticalAlignment</a><span class=\"token operator\">&gt; </span></div><div class=\"brief \"><p class=\"paragraph\">Enum representing the alignment of the timeline line and points for <a href=\"-jet-lime-column.html\">JetLimeColumn</a>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"PROPERTY\">\n        <h2 class=\"tableheader\">Properties</h2>\n        <div class=\"table\"><a data-name=\"-1643523581%2FProperties%2F538146535\" anchor-label=\"LocalJetLimeStyle\" id=\"-1643523581%2FProperties%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-local-jet-lime-style.html\"><span>Local</span><wbr></wbr><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Style</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1643523581%2FProperties%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><span class=\"token keyword\">val </span><a href=\"-local-jet-lime-style.html\">LocalJetLimeStyle</a><span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/ProvidableCompositionLocal.html\">ProvidableCompositionLocal</a><span class=\"token operator\">&lt;</span><a href=\"-jet-lime-style/index.html\">JetLimeStyle</a><span class=\"token operator\">&gt;</span></div><div class=\"brief \"><p class=\"paragraph\">A CompositionLocal providing the current <a href=\"-jet-lime-style/index.html\">JetLimeStyle</a>.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n      <div data-togglable=\"FUNCTION\">\n        <h2 class=\"tableheader\">Functions</h2>\n        <div class=\"table\"><a data-name=\"127324375%2FFunctions%2F538146535\" anchor-label=\"JetLimeColumn\" id=\"127324375%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-jet-lime-column.html\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Column</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"127324375%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><span class=\"token operator\">&lt;</span><a href=\"-jet-lime-column.html\">T</a><span class=\"token operator\">&gt; </span><a href=\"-jet-lime-column.html\"><span class=\"token function\">JetLimeColumn</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">itemsList<span class=\"token operator\">: </span><a href=\"-items-list/index.html\">ItemsList</a><span class=\"token operator\">&lt;</span><a href=\"-jet-lime-column.html\">T</a><span class=\"token operator\">&gt;</span><span class=\"token punctuation\">, </span></span><span class=\"parameter \">modifier<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.html\">Modifier</a><span class=\"token operator\"> = </span>Modifier<span class=\"token punctuation\">, </span></span><span class=\"parameter \">style<span class=\"token operator\">: </span><a href=\"-jet-lime-style/index.html\">JetLimeStyle</a><span class=\"token operator\"> = </span>JetLimeDefaults.columnStyle()<span class=\"token punctuation\">, </span></span><span class=\"parameter \">listState<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState.html\">LazyListState</a><span class=\"token operator\"> = </span>rememberLazyListState()<span class=\"token punctuation\">, </span></span><span class=\"parameter \">contentPadding<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/PaddingValues.html\">PaddingValues</a><span class=\"token operator\"> = </span>PaddingValues(0.dp)<span class=\"token punctuation\">, </span></span><span class=\"parameter \">key<span class=\"token operator\">: </span><span class=\"token punctuation\">(</span>index<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a><span class=\"token punctuation\">, </span>item<span class=\"token operator\">: </span><a href=\"-jet-lime-column.html\">T</a><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span><span class=\"token operator\"> = </span>null<span class=\"token punctuation\">, </span></span><span class=\"parameter \">itemContent<span class=\"token operator\">: </span><span><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a> </span><span class=\"token punctuation\">(</span>index<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a><span class=\"token punctuation\">, </span><a href=\"-jet-lime-column.html\">T</a><span class=\"token punctuation\">, </span><a href=\"-event-position/index.html\">EventPosition</a><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html\">Unit</a></span></span><span class=\"token punctuation\">)</span></div><div class=\"brief \"><p class=\"paragraph\">A composable function that creates a vertical timeline interface with a list of items.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-750094964%2FFunctions%2F538146535\" anchor-label=\"JetLimeEvent\" id=\"-750094964%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-jet-lime-event.html\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Event</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-750094964%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"-jet-lime-event.html\"><span class=\"token function\">JetLimeEvent</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">modifier<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.html\">Modifier</a><span class=\"token operator\"> = </span>Modifier<span class=\"token punctuation\">, </span></span><span class=\"parameter \">style<span class=\"token operator\">: </span><a href=\"-jet-lime-event-style/index.html\">JetLimeEventStyle</a><span class=\"token operator\"> = </span>JetLimeEventDefaults.eventStyle(EventPosition.END)<span class=\"token punctuation\">, </span></span><span class=\"parameter \">content<span class=\"token operator\">: </span><span><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a> </span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html\">Unit</a></span></span><span class=\"token punctuation\">)</span></div><div class=\"brief \"><p class=\"paragraph\">Composable function for creating a <a href=\"-jet-lime-column.html\">JetLimeColumn</a> or <a href=\"-jet-lime-row.html\">JetLimeRow</a> event.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"672972186%2FFunctions%2F538146535\" anchor-label=\"JetLimeExtendedEvent\" id=\"672972186%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-jet-lime-extended-event.html\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span>Extended</span><wbr></wbr><span><span>Event</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"672972186%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><a href=\"-jet-lime-extended-event.html\"><span class=\"token function\">JetLimeExtendedEvent</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">modifier<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.html\">Modifier</a><span class=\"token operator\"> = </span>Modifier<span class=\"token punctuation\">, </span></span><span class=\"parameter \">style<span class=\"token operator\">: </span><a href=\"-jet-lime-event-style/index.html\">JetLimeEventStyle</a><span class=\"token operator\"> = </span>JetLimeEventDefaults.eventStyle(EventPosition.END)<span class=\"token punctuation\">, </span></span><span class=\"parameter \">additionalContent<span class=\"token operator\">: </span><span><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a> </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/BoxScope.html\">BoxScope</a><span class=\"token punctuation\">.</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html\">Unit</a><span class=\"token operator\"> = </span>{ }<span class=\"token punctuation\">, </span></span><span class=\"parameter \">additionalContentMaxWidth<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/unit/Dp.html\">Dp</a><span class=\"token operator\"> = </span>AdditionalContentMaxWidth<span class=\"token punctuation\">, </span></span><span class=\"parameter \">content<span class=\"token operator\">: </span><span><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a> </span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html\">Unit</a></span></span><span class=\"token punctuation\">)</span></div><div class=\"brief \"><p class=\"paragraph\">Should only be used with a <a href=\"-jet-lime-column.html\">JetLimeColumn</a> for a vertical arrangement of events.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n<a data-name=\"-1240239929%2FFunctions%2F538146535\" anchor-label=\"JetLimeRow\" id=\"-1240239929%2FFunctions%2F538146535\" data-filterable-set=\":jetlime/commonMain\"></a>\n          <div class=\"table-row table-row_content\" data-filterable-current=\":jetlime/commonMain\" data-filterable-set=\":jetlime/commonMain\">\n            <div class=\"main-subrow keyValue \">\n              <div class=\"\"><span class=\"inline-flex\">\n                  <div><a href=\"-jet-lime-row.html\"><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Row</span></span></a></div>\n<span class=\"anchor-wrapper\"><span class=\"anchor-icon\" pointing-to=\"-1240239929%2FFunctions%2F538146535\"></span>\n                    <div class=\"copy-popup-wrapper \"><span class=\"copy-popup-icon\"></span><span>Link copied to clipboard</span></div>\n                  </span></span></div>\n              <div>\n                <div class=\"title\">\n                  <div class=\"platform-hinted \" data-platform-hinted=\"data-platform-hinted\"><div class=\"content sourceset-dependent-content\" data-active=\"\" data-togglable=\":jetlime/commonMain\"><div class=\"symbol monospace\"><div class=\"block\"><div class=\"block\"><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a></div></div><span class=\"token keyword\">fun </span><span class=\"token operator\">&lt;</span><a href=\"-jet-lime-row.html\">T</a><span class=\"token operator\">&gt; </span><a href=\"-jet-lime-row.html\"><span class=\"token function\">JetLimeRow</span></a><span class=\"token punctuation\">(</span><span class=\"parameters \"><span class=\"parameter \">itemsList<span class=\"token operator\">: </span><a href=\"-items-list/index.html\">ItemsList</a><span class=\"token operator\">&lt;</span><a href=\"-jet-lime-row.html\">T</a><span class=\"token operator\">&gt;</span><span class=\"token punctuation\">, </span></span><span class=\"parameter \">modifier<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/ui/Modifier.html\">Modifier</a><span class=\"token operator\"> = </span>Modifier<span class=\"token punctuation\">, </span></span><span class=\"parameter \">style<span class=\"token operator\">: </span><a href=\"-jet-lime-style/index.html\">JetLimeStyle</a><span class=\"token operator\"> = </span>JetLimeDefaults.rowStyle()<span class=\"token punctuation\">, </span></span><span class=\"parameter \">listState<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/foundation/lazy/LazyListState.html\">LazyListState</a><span class=\"token operator\"> = </span>rememberLazyListState()<span class=\"token punctuation\">, </span></span><span class=\"parameter \">contentPadding<span class=\"token operator\">: </span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/foundation/layout/PaddingValues.html\">PaddingValues</a><span class=\"token operator\"> = </span>PaddingValues(0.dp)<span class=\"token punctuation\">, </span></span><span class=\"parameter \">key<span class=\"token operator\">: </span><span class=\"token punctuation\">(</span>index<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a><span class=\"token punctuation\">, </span>item<span class=\"token operator\">: </span><a href=\"-jet-lime-row.html\">T</a><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-any/index.html\">Any</a><span class=\"token operator\">?</span><span class=\"token operator\"> = </span>null<span class=\"token punctuation\">, </span></span><span class=\"parameter \">itemContent<span class=\"token operator\">: </span><span><span class=\"token annotation builtin\">@</span><a href=\"https://developer.android.com/reference/kotlin/androidx/compose/runtime/Composable.html\"><span class=\"token annotation builtin\">Composable</span></a> </span><span class=\"token punctuation\">(</span>index<span class=\"token operator\">: </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-int/index.html\">Int</a><span class=\"token punctuation\">, </span><a href=\"-jet-lime-row.html\">T</a><span class=\"token punctuation\">, </span><a href=\"-event-position/index.html\">EventPosition</a><span class=\"token punctuation\">)</span><span class=\"token operator\"> -&gt; </span><a href=\"https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-unit/index.html\">Unit</a></span></span><span class=\"token punctuation\">)</span></div><div class=\"brief \"><p class=\"paragraph\">A composable function that creates a horizontal timeline interface with a list of items.</p></div></div></div>\n                </div>\n              </div>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n    <div class=\"footer\">\n        <div class=\"footer--container\">\n            <a href=\"#content\" id=\"go-to-top-link\" class=\"footer--button footer--button_go-to-top\"></a>\n            <div class=\"footer--content\">\n                <div>\n                    <span>Generated by </span>\n                    <a class=\"footer--link footer--link_external\" href=\"https://github.com/Kotlin/dokka\">\n                        Dokka\n                    </a>\n                    <div>© 2026 Copyright</div>\n                </div>\n            </div>\n        </div>\n    </div>\n        </div>\n    </div>\n</div>\n</body>\n</html>"
  },
  {
    "path": "docs/jetlime/package-list",
    "content": "$dokka.format:html-v1\n$dokka.linkExtension:html\n$dokka.location:com.pushpal.jetlime////PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/index.html\n$dokka.location:com.pushpal.jetlime//JetLimeColumn/#com.pushpal.jetlime.ItemsList[TypeParam(bounds=[kotlin.Any?])]#androidx.compose.ui.Modifier#com.pushpal.jetlime.JetLimeStyle#androidx.compose.foundation.lazy.LazyListState#androidx.compose.foundation.layout.PaddingValues#kotlin.Function2[kotlin.Int,TypeParam(bounds=[kotlin.Any?]),kotlin.Any]?#kotlin.Function3[kotlin.Int,TypeParam(bounds=[kotlin.Any?]),com.pushpal.jetlime.EventPosition,kotlin.Unit]/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-column.html\n$dokka.location:com.pushpal.jetlime//JetLimeEvent/#androidx.compose.ui.Modifier#com.pushpal.jetlime.JetLimeEventStyle#kotlin.Function0[kotlin.Unit]/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event.html\n$dokka.location:com.pushpal.jetlime//JetLimeExtendedEvent/#androidx.compose.ui.Modifier#com.pushpal.jetlime.JetLimeEventStyle#kotlin.Function1[androidx.compose.foundation.layout.BoxScope,kotlin.Unit]#androidx.compose.ui.unit.Dp#kotlin.Function0[kotlin.Unit]/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-extended-event.html\n$dokka.location:com.pushpal.jetlime//JetLimeRow/#com.pushpal.jetlime.ItemsList[TypeParam(bounds=[kotlin.Any?])]#androidx.compose.ui.Modifier#com.pushpal.jetlime.JetLimeStyle#androidx.compose.foundation.lazy.LazyListState#androidx.compose.foundation.layout.PaddingValues#kotlin.Function2[kotlin.Int,TypeParam(bounds=[kotlin.Any?]),kotlin.Any]?#kotlin.Function3[kotlin.Int,TypeParam(bounds=[kotlin.Any?]),com.pushpal.jetlime.EventPosition,kotlin.Unit]/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-row.html\n$dokka.location:com.pushpal.jetlime//LocalJetLimeStyle/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-local-jet-lime-style.html\n$dokka.location:com.pushpal.jetlime/EventPointAnimation///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-animation/index.html\n$dokka.location:com.pushpal.jetlime/EventPointAnimation/animationSpec/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-animation/animation-spec.html\n$dokka.location:com.pushpal.jetlime/EventPointAnimation/equals/#kotlin.Any?/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-animation/equals.html\n$dokka.location:com.pushpal.jetlime/EventPointAnimation/hashCode/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-animation/hash-code.html\n$dokka.location:com.pushpal.jetlime/EventPointAnimation/initialValue/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-animation/initial-value.html\n$dokka.location:com.pushpal.jetlime/EventPointAnimation/targetValue/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-animation/target-value.html\n$dokka.location:com.pushpal.jetlime/EventPointType.Companion///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/-companion/index.html\n$dokka.location:com.pushpal.jetlime/EventPointType.Companion/Default/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/-companion/-default.html\n$dokka.location:com.pushpal.jetlime/EventPointType.Companion/EMPTY/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/-companion/-e-m-p-t-y.html\n$dokka.location:com.pushpal.jetlime/EventPointType.Companion/custom/#androidx.compose.ui.graphics.painter.Painter#androidx.compose.ui.graphics.Color?/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/-companion/custom.html\n$dokka.location:com.pushpal.jetlime/EventPointType.Companion/filled/#kotlin.Float/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/-companion/filled.html\n$dokka.location:com.pushpal.jetlime/EventPointType///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/index.html\n$dokka.location:com.pushpal.jetlime/EventPointType/equals/#kotlin.Any?/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/equals.html\n$dokka.location:com.pushpal.jetlime/EventPointType/fillPercent/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/fill-percent.html\n$dokka.location:com.pushpal.jetlime/EventPointType/hashCode/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/hash-code.html\n$dokka.location:com.pushpal.jetlime/EventPointType/icon/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/icon.html\n$dokka.location:com.pushpal.jetlime/EventPointType/isCustom/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/is-custom.html\n$dokka.location:com.pushpal.jetlime/EventPointType/isEmptyOrFilled/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/is-empty-or-filled.html\n$dokka.location:com.pushpal.jetlime/EventPointType/isFilled/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/is-filled.html\n$dokka.location:com.pushpal.jetlime/EventPointType/tint/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/tint.html\n$dokka.location:com.pushpal.jetlime/EventPointType/type/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-point-type/type.html\n$dokka.location:com.pushpal.jetlime/EventPosition.Companion///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-position/-companion/index.html\n$dokka.location:com.pushpal.jetlime/EventPosition.Companion/dynamic/#kotlin.Int#kotlin.Int/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-position/-companion/dynamic.html\n$dokka.location:com.pushpal.jetlime/EventPosition///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-position/index.html\n$dokka.location:com.pushpal.jetlime/EventPosition/equals/#kotlin.Any?/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-position/equals.html\n$dokka.location:com.pushpal.jetlime/EventPosition/hashCode/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-position/hash-code.html\n$dokka.location:com.pushpal.jetlime/EventPosition/isNotEnd/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-position/is-not-end.html\n$dokka.location:com.pushpal.jetlime/EventPosition/isNotStart/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-position/is-not-start.html\n$dokka.location:com.pushpal.jetlime/EventPosition/name/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-event-position/name.html\n$dokka.location:com.pushpal.jetlime/HorizontalAlignment.BOTTOM///PointingToDeclaration/{\"org.jetbrains.dokka.links.EnumEntryDRIExtra\":{\"key\":\"org.jetbrains.dokka.links.EnumEntryDRIExtra\"}}\u001fjetlime/com.pushpal.jetlime/-horizontal-alignment/-b-o-t-t-o-m/index.html\n$dokka.location:com.pushpal.jetlime/HorizontalAlignment.TOP///PointingToDeclaration/{\"org.jetbrains.dokka.links.EnumEntryDRIExtra\":{\"key\":\"org.jetbrains.dokka.links.EnumEntryDRIExtra\"}}\u001fjetlime/com.pushpal.jetlime/-horizontal-alignment/-t-o-p/index.html\n$dokka.location:com.pushpal.jetlime/HorizontalAlignment///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-horizontal-alignment/index.html\n$dokka.location:com.pushpal.jetlime/HorizontalAlignment/entries/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-horizontal-alignment/entries.html\n$dokka.location:com.pushpal.jetlime/HorizontalAlignment/valueOf/#kotlin.String/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-horizontal-alignment/value-of.html\n$dokka.location:com.pushpal.jetlime/HorizontalAlignment/values/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-horizontal-alignment/values.html\n$dokka.location:com.pushpal.jetlime/ItemsList///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-items-list/index.html\n$dokka.location:com.pushpal.jetlime/ItemsList/ItemsList/#kotlin.collections.List[TypeParam(bounds=[kotlin.Any?])]/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-items-list/-items-list.html\n$dokka.location:com.pushpal.jetlime/ItemsList/equals/#kotlin.Any?/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-items-list/equals.html\n$dokka.location:com.pushpal.jetlime/ItemsList/hashCode/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-items-list/hash-code.html\n$dokka.location:com.pushpal.jetlime/ItemsList/items/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-items-list/items.html\n$dokka.location:com.pushpal.jetlime/JetLimeDefaults///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-defaults/index.html\n$dokka.location:com.pushpal.jetlime/JetLimeDefaults/columnStyle/#androidx.compose.ui.unit.Dp#androidx.compose.ui.unit.Dp#androidx.compose.ui.unit.Dp#androidx.compose.ui.graphics.Brush#androidx.compose.ui.graphics.PathEffect?#com.pushpal.jetlime.VerticalAlignment/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-defaults/column-style.html\n$dokka.location:com.pushpal.jetlime/JetLimeDefaults/lineGradientBrush/#kotlinx.collections.immutable.ImmutableList[androidx.compose.ui.graphics.Color]#androidx.compose.ui.geometry.Offset#androidx.compose.ui.geometry.Offset#androidx.compose.ui.graphics.TileMode/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-defaults/line-gradient-brush.html\n$dokka.location:com.pushpal.jetlime/JetLimeDefaults/lineSolidBrush/#androidx.compose.ui.graphics.Color/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-defaults/line-solid-brush.html\n$dokka.location:com.pushpal.jetlime/JetLimeDefaults/rowStyle/#androidx.compose.ui.unit.Dp#androidx.compose.ui.unit.Dp#androidx.compose.ui.unit.Dp#androidx.compose.ui.graphics.Brush#androidx.compose.ui.graphics.PathEffect?#com.pushpal.jetlime.HorizontalAlignment/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-defaults/row-style.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventDefaults///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-defaults/index.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventDefaults/eventStyle/#com.pushpal.jetlime.EventPosition#com.pushpal.jetlime.PointPlacement#com.pushpal.jetlime.EventPointType#androidx.compose.ui.graphics.Color#androidx.compose.ui.graphics.Color#androidx.compose.ui.unit.Dp#com.pushpal.jetlime.EventPointAnimation?#androidx.compose.ui.unit.Dp#androidx.compose.ui.graphics.Color/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-defaults/event-style.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventDefaults/pointAnimation/#kotlin.Float#kotlin.Float#androidx.compose.animation.core.InfiniteRepeatableSpec[kotlin.Float]/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-defaults/point-animation.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/index.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/equals/#kotlin.Any?/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/equals.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/hashCode/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/hash-code.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/pointAnimation/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/point-animation.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/pointColor/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/point-color.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/pointFillColor/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/point-fill-color.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/pointPlacement/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/point-placement.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/pointRadius/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/point-radius.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/pointStrokeColor/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/point-stroke-color.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/pointStrokeWidth/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/point-stroke-width.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/pointType/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/point-type.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/position/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/position.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/setPointPlacement/#com.pushpal.jetlime.PointPlacement/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/set-point-placement.html\n$dokka.location:com.pushpal.jetlime/JetLimeEventStyle/setPosition/#com.pushpal.jetlime.EventPosition/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-event-style/set-position.html\n$dokka.location:com.pushpal.jetlime/JetLimeStyle///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-style/index.html\n$dokka.location:com.pushpal.jetlime/JetLimeStyle/contentDistance/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-style/content-distance.html\n$dokka.location:com.pushpal.jetlime/JetLimeStyle/equals/#kotlin.Any?/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-style/equals.html\n$dokka.location:com.pushpal.jetlime/JetLimeStyle/hashCode/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-style/hash-code.html\n$dokka.location:com.pushpal.jetlime/JetLimeStyle/itemSpacing/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-style/item-spacing.html\n$dokka.location:com.pushpal.jetlime/JetLimeStyle/lineBrush/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-style/line-brush.html\n$dokka.location:com.pushpal.jetlime/JetLimeStyle/lineHorizontalAlignment/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-style/line-horizontal-alignment.html\n$dokka.location:com.pushpal.jetlime/JetLimeStyle/lineThickness/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-style/line-thickness.html\n$dokka.location:com.pushpal.jetlime/JetLimeStyle/lineVerticalAlignment/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-style/line-vertical-alignment.html\n$dokka.location:com.pushpal.jetlime/JetLimeStyle/pathEffect/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-jet-lime-style/path-effect.html\n$dokka.location:com.pushpal.jetlime/PointPlacement.CENTER///PointingToDeclaration/{\"org.jetbrains.dokka.links.EnumEntryDRIExtra\":{\"key\":\"org.jetbrains.dokka.links.EnumEntryDRIExtra\"}}\u001fjetlime/com.pushpal.jetlime/-point-placement/-c-e-n-t-e-r/index.html\n$dokka.location:com.pushpal.jetlime/PointPlacement.END///PointingToDeclaration/{\"org.jetbrains.dokka.links.EnumEntryDRIExtra\":{\"key\":\"org.jetbrains.dokka.links.EnumEntryDRIExtra\"}}\u001fjetlime/com.pushpal.jetlime/-point-placement/-e-n-d/index.html\n$dokka.location:com.pushpal.jetlime/PointPlacement.START///PointingToDeclaration/{\"org.jetbrains.dokka.links.EnumEntryDRIExtra\":{\"key\":\"org.jetbrains.dokka.links.EnumEntryDRIExtra\"}}\u001fjetlime/com.pushpal.jetlime/-point-placement/-s-t-a-r-t/index.html\n$dokka.location:com.pushpal.jetlime/PointPlacement///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-point-placement/index.html\n$dokka.location:com.pushpal.jetlime/PointPlacement/entries/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-point-placement/entries.html\n$dokka.location:com.pushpal.jetlime/PointPlacement/valueOf/#kotlin.String/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-point-placement/value-of.html\n$dokka.location:com.pushpal.jetlime/PointPlacement/values/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-point-placement/values.html\n$dokka.location:com.pushpal.jetlime/VerticalAlignment.LEFT///PointingToDeclaration/{\"org.jetbrains.dokka.links.EnumEntryDRIExtra\":{\"key\":\"org.jetbrains.dokka.links.EnumEntryDRIExtra\"}}\u001fjetlime/com.pushpal.jetlime/-vertical-alignment/-l-e-f-t/index.html\n$dokka.location:com.pushpal.jetlime/VerticalAlignment.RIGHT///PointingToDeclaration/{\"org.jetbrains.dokka.links.EnumEntryDRIExtra\":{\"key\":\"org.jetbrains.dokka.links.EnumEntryDRIExtra\"}}\u001fjetlime/com.pushpal.jetlime/-vertical-alignment/-r-i-g-h-t/index.html\n$dokka.location:com.pushpal.jetlime/VerticalAlignment///PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-vertical-alignment/index.html\n$dokka.location:com.pushpal.jetlime/VerticalAlignment/entries/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-vertical-alignment/entries.html\n$dokka.location:com.pushpal.jetlime/VerticalAlignment/valueOf/#kotlin.String/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-vertical-alignment/value-of.html\n$dokka.location:com.pushpal.jetlime/VerticalAlignment/values/#/PointingToDeclaration/\u001fjetlime/com.pushpal.jetlime/-vertical-alignment/values.html\ncom.pushpal.jetlime\n"
  },
  {
    "path": "docs/navigation.html",
    "content": "<div class=\"toc--part\" id=\"jetlime-nav-submenu\" pageId=\"jetlime::////PointingToDeclaration//538146535\" data-nesting-level=\"0\">\n  <div class=\"toc--row\"><button class=\"toc--button\" aria-expanded=\"false\" aria-label=\"jetlime\" onclick=\"window.handleTocButtonClick(event, 'jetlime-nav-submenu')\"></button><a href=\"index.html\" class=\"toc--link\"><span><span>jetlime</span></span></a><a class=\"toc--skip-link\" href=\"\">Skip to content</a></div>\n  <div class=\"toc--part\" id=\"jetlime-nav-submenu-0\" pageId=\"jetlime::com.pushpal.jetlime////PointingToDeclaration//538146535\" data-nesting-level=\"1\">\n    <div class=\"toc--row\"><button class=\"toc--button\" aria-expanded=\"false\" aria-label=\"com.pushpal.jetlime\" onclick=\"window.handleTocButtonClick(event, 'jetlime-nav-submenu-0')\"></button><a href=\"jetlime/com.pushpal.jetlime/index.html\" class=\"toc--link\"><span>com.</span><wbr></wbr><span>pushpal.</span><wbr></wbr><span>jetlime</span></a><a class=\"toc--skip-link\" href=\"\">Skip to content</a></div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-0\" pageId=\"jetlime::com.pushpal.jetlime/EventPointAnimation///PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-event-point-animation/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon class-kt\"></span><span><span>Event</span><wbr></wbr><span>Point</span><wbr></wbr><span><span>Animation</span></span></span></span></a></div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-1\" pageId=\"jetlime::com.pushpal.jetlime/EventPointType///PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><button class=\"toc--button\" aria-expanded=\"false\" aria-label=\"EventPointType\" onclick=\"window.handleTocButtonClick(event, 'jetlime-nav-submenu-0-1')\"></button><a href=\"jetlime/com.pushpal.jetlime/-event-point-type/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon class-kt\"></span><span><span>Event</span><wbr></wbr><span>Point</span><wbr></wbr><span><span>Type</span></span></span></span></a><a class=\"toc--skip-link\" href=\"\">Skip to content</a></div>\n      <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-1-0\" pageId=\"jetlime::com.pushpal.jetlime/EventPointType.Companion///PointingToDeclaration//538146535\" data-nesting-level=\"3\">\n        <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-event-point-type/-companion/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon object\"></span><span><span><span>Companion</span></span></span></span></a></div>\n      </div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-2\" pageId=\"jetlime::com.pushpal.jetlime/EventPosition///PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><button class=\"toc--button\" aria-expanded=\"false\" aria-label=\"EventPosition\" onclick=\"window.handleTocButtonClick(event, 'jetlime-nav-submenu-0-2')\"></button><a href=\"jetlime/com.pushpal.jetlime/-event-position/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon class-kt\"></span><span><span>Event</span><wbr></wbr><span><span>Position</span></span></span></span></a><a class=\"toc--skip-link\" href=\"\">Skip to content</a></div>\n      <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-2-0\" pageId=\"jetlime::com.pushpal.jetlime/EventPosition.Companion///PointingToDeclaration//538146535\" data-nesting-level=\"3\">\n        <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-event-position/-companion/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon object\"></span><span><span><span>Companion</span></span></span></span></a></div>\n      </div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-3\" pageId=\"jetlime::com.pushpal.jetlime/HorizontalAlignment///PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><button class=\"toc--button\" aria-expanded=\"false\" aria-label=\"HorizontalAlignment\" onclick=\"window.handleTocButtonClick(event, 'jetlime-nav-submenu-0-3')\"></button><a href=\"jetlime/com.pushpal.jetlime/-horizontal-alignment/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon enum-class-kt\"></span><span><span>Horizontal</span><wbr></wbr><span><span>Alignment</span></span></span></span></a><a class=\"toc--skip-link\" href=\"\">Skip to content</a></div>\n      <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-3-0\" pageId=\"jetlime::com.pushpal.jetlime/HorizontalAlignment.TOP///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\" data-nesting-level=\"3\">\n        <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-horizontal-alignment/-t-o-p/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon enum-class-kt\"></span><span><span><span>TOP</span></span></span></span></a></div>\n      </div>\n      <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-3-1\" pageId=\"jetlime::com.pushpal.jetlime/HorizontalAlignment.BOTTOM///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\" data-nesting-level=\"3\">\n        <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-horizontal-alignment/-b-o-t-t-o-m/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon enum-class-kt\"></span><span><span><span>BOTTOM</span></span></span></span></a></div>\n      </div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-4\" pageId=\"jetlime::com.pushpal.jetlime/ItemsList///PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-items-list/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon class-kt\"></span><span><span>Items</span><wbr></wbr><span><span>List</span></span></span></span></a></div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-5\" pageId=\"jetlime::com.pushpal.jetlime//JetLimeColumn/#com.pushpal.jetlime.ItemsList[TypeParam(bounds=[kotlin.Any?])]#androidx.compose.ui.Modifier#com.pushpal.jetlime.JetLimeStyle#androidx.compose.foundation.lazy.LazyListState#androidx.compose.foundation.layout.PaddingValues#kotlin.Function2[kotlin.Int,TypeParam(bounds=[kotlin.Any?]),kotlin.Any]?#kotlin.Function3[kotlin.Int,TypeParam(bounds=[kotlin.Any?]),com.pushpal.jetlime.EventPosition,kotlin.Unit]/PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-jet-lime-column.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon function\"></span><span><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Column()</span></span></span></span></a></div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-6\" pageId=\"jetlime::com.pushpal.jetlime/JetLimeDefaults///PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-jet-lime-defaults/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon object\"></span><span><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Defaults</span></span></span></span></a></div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-7\" pageId=\"jetlime::com.pushpal.jetlime//JetLimeEvent/#androidx.compose.ui.Modifier#com.pushpal.jetlime.JetLimeEventStyle#kotlin.Function0[kotlin.Unit]/PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-jet-lime-event.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon function\"></span><span><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Event()</span></span></span></span></a></div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-8\" pageId=\"jetlime::com.pushpal.jetlime/JetLimeEventDefaults///PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-jet-lime-event-defaults/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon object\"></span><span><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span>Event</span><wbr></wbr><span><span>Defaults</span></span></span></span></a></div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-9\" pageId=\"jetlime::com.pushpal.jetlime/JetLimeEventStyle///PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon class-kt\"></span><span><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span>Event</span><wbr></wbr><span><span>Style</span></span></span></span></a></div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-10\" pageId=\"jetlime::com.pushpal.jetlime//JetLimeExtendedEvent/#androidx.compose.ui.Modifier#com.pushpal.jetlime.JetLimeEventStyle#kotlin.Function1[androidx.compose.foundation.layout.BoxScope,kotlin.Unit]#androidx.compose.ui.unit.Dp#kotlin.Function0[kotlin.Unit]/PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-jet-lime-extended-event.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon function\"></span><span><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span>Extended</span><wbr></wbr><span><span>Event()</span></span></span></span></a></div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-11\" pageId=\"jetlime::com.pushpal.jetlime//JetLimeRow/#com.pushpal.jetlime.ItemsList[TypeParam(bounds=[kotlin.Any?])]#androidx.compose.ui.Modifier#com.pushpal.jetlime.JetLimeStyle#androidx.compose.foundation.lazy.LazyListState#androidx.compose.foundation.layout.PaddingValues#kotlin.Function2[kotlin.Int,TypeParam(bounds=[kotlin.Any?]),kotlin.Any]?#kotlin.Function3[kotlin.Int,TypeParam(bounds=[kotlin.Any?]),com.pushpal.jetlime.EventPosition,kotlin.Unit]/PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-jet-lime-row.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon function\"></span><span><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Row()</span></span></span></span></a></div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-12\" pageId=\"jetlime::com.pushpal.jetlime/JetLimeStyle///PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-jet-lime-style/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon class-kt\"></span><span><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Style</span></span></span></span></a></div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-13\" pageId=\"jetlime::com.pushpal.jetlime//LocalJetLimeStyle/#/PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-local-jet-lime-style.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon val\"></span><span><span>Local</span><wbr></wbr><span>Jet</span><wbr></wbr><span>Lime</span><wbr></wbr><span><span>Style</span></span></span></span></a></div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-14\" pageId=\"jetlime::com.pushpal.jetlime/PointPlacement///PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><button class=\"toc--button\" aria-expanded=\"false\" aria-label=\"PointPlacement\" onclick=\"window.handleTocButtonClick(event, 'jetlime-nav-submenu-0-14')\"></button><a href=\"jetlime/com.pushpal.jetlime/-point-placement/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon enum-class-kt\"></span><span><span>Point</span><wbr></wbr><span><span>Placement</span></span></span></span></a><a class=\"toc--skip-link\" href=\"\">Skip to content</a></div>\n      <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-14-0\" pageId=\"jetlime::com.pushpal.jetlime/PointPlacement.START///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\" data-nesting-level=\"3\">\n        <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-point-placement/-s-t-a-r-t/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon enum-class-kt\"></span><span><span><span>START</span></span></span></span></a></div>\n      </div>\n      <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-14-1\" pageId=\"jetlime::com.pushpal.jetlime/PointPlacement.CENTER///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\" data-nesting-level=\"3\">\n        <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-point-placement/-c-e-n-t-e-r/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon enum-class-kt\"></span><span><span><span>CENTER</span></span></span></span></a></div>\n      </div>\n      <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-14-2\" pageId=\"jetlime::com.pushpal.jetlime/PointPlacement.END///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\" data-nesting-level=\"3\">\n        <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-point-placement/-e-n-d/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon enum-class-kt\"></span><span><span><span>END</span></span></span></span></a></div>\n      </div>\n    </div>\n    <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-15\" pageId=\"jetlime::com.pushpal.jetlime/VerticalAlignment///PointingToDeclaration//538146535\" data-nesting-level=\"2\">\n      <div class=\"toc--row\"><button class=\"toc--button\" aria-expanded=\"false\" aria-label=\"VerticalAlignment\" onclick=\"window.handleTocButtonClick(event, 'jetlime-nav-submenu-0-15')\"></button><a href=\"jetlime/com.pushpal.jetlime/-vertical-alignment/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon enum-class-kt\"></span><span><span>Vertical</span><wbr></wbr><span><span>Alignment</span></span></span></span></a><a class=\"toc--skip-link\" href=\"\">Skip to content</a></div>\n      <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-15-0\" pageId=\"jetlime::com.pushpal.jetlime/VerticalAlignment.LEFT///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\" data-nesting-level=\"3\">\n        <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-vertical-alignment/-l-e-f-t/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon enum-class-kt\"></span><span><span><span>LEFT</span></span></span></span></a></div>\n      </div>\n      <div class=\"toc--part\" id=\"jetlime-nav-submenu-0-15-1\" pageId=\"jetlime::com.pushpal.jetlime/VerticalAlignment.RIGHT///PointingToDeclaration/{&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;:{&quot;key&quot;:&quot;org.jetbrains.dokka.links.EnumEntryDRIExtra&quot;}}/538146535\" data-nesting-level=\"3\">\n        <div class=\"toc--row\"><a href=\"jetlime/com.pushpal.jetlime/-vertical-alignment/-r-i-g-h-t/index.html\" class=\"toc--link\"><span class=\"toc--link-grid\"><span class=\"toc--icon enum-class-kt\"></span><span><span><span>RIGHT</span></span></span></span></a></div>\n      </div>\n    </div>\n  </div>\n</div>\n"
  },
  {
    "path": "docs/scripts/main.js",
    "content": "(()=>{var e={1817:e=>{e.exports='<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\"><path d=\"M11.78 3.1497C12.0425 3.37384 12.0736 3.76835 11.8495 4.03085L6.30786 10.5208C5.79248 11.1243 4.87455 11.1675 4.30485 10.6149L2.18984 8.56337C1.94208 8.32304 1.93605 7.92736 2.17638 7.67959C2.41671 7.43182 2.81239 7.42579 3.06016 7.66612L5.17516 9.71763C5.22695 9.76787 5.3104 9.76395 5.35725 9.70908L10.8989 3.21915C11.123 2.95665 11.5175 2.92555 11.78 3.1497Z\"/></svg>'},4811:e=>{e.exports='<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"10\" height=\"10\" viewBox=\"0 0 10 10\"><g><polygon points=\"5 7.99 1.5 4.5 2.5 3.5 5 6.01 7.5 3.5 8.49 4.5 5 7.99\"/></g></svg>'},5742:e=>{e.exports='<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><g><polygon points=\"8 10.99 3.5 6.5 4.5 5.5 8 9.01 11.51 5.5 12.49 6.5 8 10.99\"/></g></svg>'},7112:e=>{e.exports='<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\"><path d=\"M5.997 6.784l4.454 4.359.787-.804-4.43-4.336 4.465-4.3-.78-.81-4.49 4.323L1.55.857l-.787.804 4.43 4.336-4.465 4.3.78.81 4.49-4.323z\"/></svg>'},8420:e=>{e.exports='<svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"3\" y=\"6.375\" width=\"8\" height=\"1.25\" rx=\"0.625\"/></svg>'},7004:e=>{e.exports='<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\"><g><path d=\"M14.64,13.36,10.13,8.85A4.94,4.94,0,0,0,11,6a5,5,0,1,0-2.17,4.12l4.51,4.51ZM2.42,6A3.6,3.6,0,1,1,6,9.61,3.6,3.6,0,0,1,2.42,6Z\"/></g></svg>'},7222:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(5280),c=a()(o());c.i(l.A),c.push([e.id,'.avatar_d716 {\\n  display: inline-block;\\n  -o-object-fit: cover;\\n     object-fit: cover;\\n  -o-object-position: center;\\n     object-position: center;\\n\\n  /* This is a \"graceful degradation\" fallback, while the real value is controlled by JS */\\n\\n  border-radius: var(--ring-border-radius);\\n}\\n\\n.subavatar_b10d {\\n  position: absolute;\\n  top: 15px;\\n  left: 27px;\\n\\n  border: 1px var(--ring-content-background-color) solid;\\n}\\n\\n.empty_a151 {\\n  display: inline-block;\\n\\n  box-sizing: border-box;\\n\\n  border: 1px solid var(--ring-borders-color);\\n}\\n',\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/avatar/avatar.css\"],names:[],mappings:\"AAEA;EACE,qBAAqB;EACrB,oBAAiB;KAAjB,iBAAiB;EACjB,0BAAuB;KAAvB,uBAAuB;;EAEvB,wFAAwF;;EAExF,wCAAwC;AAC1C;;AAEA;EACE,kBAAkB;EAClB,SAAS;EACT,UAAU;;EAEV,sDAAsD;AACxD;;AAEA;EACE,qBAAqB;;EAErB,sBAAsB;;EAEtB,2CAA2C;AAC7C\",sourcesContent:['@import \"../global/variables.css\";\\n\\n.avatar {\\n  display: inline-block;\\n  object-fit: cover;\\n  object-position: center;\\n\\n  /* This is a \"graceful degradation\" fallback, while the real value is controlled by JS */\\n\\n  border-radius: var(--ring-border-radius);\\n}\\n\\n.subavatar {\\n  position: absolute;\\n  top: 15px;\\n  left: 27px;\\n\\n  border: 1px var(--ring-content-background-color) solid;\\n}\\n\\n.empty {\\n  display: inline-block;\\n\\n  box-sizing: border-box;\\n\\n  border: 1px solid var(--ring-borders-color);\\n}\\n'],sourceRoot:\"\"}]),c.locals={avatar:\"avatar_d716\",subavatar:\"subavatar_b10d\",empty:\"empty_a151\"};const s=c},9892:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),s=a()(o());s.i(c.A),s.i(l.default,\"\",!0),s.push([e.id,'.heightS_b28d {\\n  --ring-button-height: 24px;\\n  --ring-button-font-size: var(--ring-font-size-smaller);\\n}\\n\\n.heightM_dfd3 {\\n  --ring-button-height: 28px;\\n  --ring-button-font-size: var(--ring-font-size);\\n}\\n\\n.heightL_a4d3 {\\n  --ring-button-height: 32px;\\n  --ring-button-font-size: var(--ring-font-size);\\n}\\n\\n.button_aba4 {\\n  position: relative;\\n\\n  display: inline-block;\\n\\n  box-sizing: border-box;\\n  height: var(--ring-button-height);\\n  margin: 0;\\n  padding: 0 16px;\\n\\n  cursor: pointer;\\n  transition: color var(--ring-ease), background-color var(--ring-ease), box-shadow var(--ring-ease);\\n  text-decoration: none;\\n\\n  color: var(--ring-text-color);\\n\\n  border: 0;\\n  border-radius: var(--ring-border-radius);\\n  outline: 0;\\n  background-color: var(--ring-content-background-color);\\n  box-shadow: inset 0 0 0 1px var(--ring-borders-color);\\n\\n  font-family: var(--ring-font-family);\\n  font-size: var(--ring-button-font-size);\\n\\n  line-height: var(--ring-button-height);\\n}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.button_aba4:hover {\\n    transition: none;\\n\\n    box-shadow: inset 0 0 0 1px var(--ring-border-hover-color);\\n  }}\\n\\n.button_aba4:active {\\n    transition: none;\\n\\n    background-color: var(--ring-selected-background-color);\\n    box-shadow: inset 0 0 0 1px var(--ring-border-hover-color);\\n  }\\n\\n.button_aba4:focus-visible {\\n    transition: none;\\n\\n    box-shadow: inset 0 0 0 1px var(--ring-border-hover-color), 0 0 0 1px var(--ring-border-hover-color);\\n  }\\n\\n.button_aba4.active_bbe6 {\\n    transition: none;\\n\\n    background-color: var(--ring-hover-background-color);\\n    box-shadow: inset 0 0 0 1px var(--ring-main-color);\\n  }\\n\\n.button_aba4.active_bbe6:focus-visible {\\n    box-shadow: inset 0 0 0 2px var(--ring-main-color), 0 0 0 1px var(--ring-border-hover-color);\\n  }\\n\\n.button_aba4[disabled] {\\n    pointer-events: none;\\n\\n    background-color: var(--ring-disabled-background-color);\\n    box-shadow: inset 0 0 0 1px var(--ring-border-disabled-color);\\n  }\\n\\n.button_aba4.active_bbe6[disabled] {\\n    background-color: var(--ring-disabled-selected-background-color);\\n    box-shadow: inset 0 0 0 1px var(--ring-border-selected-disabled-color);\\n  }\\n\\n.button_aba4[disabled],\\n  .button_aba4.withIcon_ef77[disabled] {\\n    color: var(--ring-disabled-color);\\n  }\\n\\n.button_aba4[disabled] .icon_e878 {\\n    color: var(--ring-icon-disabled-color);\\n  }\\n\\n.button_aba4::-moz-focus-inner {\\n    padding: 0;\\n\\n    border: 0;\\n    outline: 0;\\n  }\\n\\n.withIcon_ef77 {\\n  color: var(--ring-secondary-color);\\n}\\n\\n.primary_ddae {\\n  color: var(--ring-white-text-color);\\n  background-color: var(--ring-main-color);\\n  box-shadow: none;\\n}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.primary_ddae:hover {\\n    transition: none;\\n\\n    background-color: var(--ring-main-hover-color);\\n    box-shadow: none;\\n  }}\\n\\n.primary_ddae.withIcon_ef77,\\n  .primary_ddae.withIcon_ef77:active,\\n  .primary_ddae.withIcon_ef77.active_bbe6 {\\n    color: var(--ring-action-link-color);\\n  }\\n\\n.primary_ddae:focus-visible,\\n  .primary_ddae:active,\\n  .primary_ddae.active_bbe6 {\\n    background-color: var(--ring-button-primary-background-color);\\n  }\\n\\n.primary_ddae:active,\\n  .primary_ddae.active_bbe6 {\\n    box-shadow: inset 0 0 0 1px var(--ring-button-primary-border-color);\\n  }\\n\\n.primary_ddae[disabled] {\\n    background-color: var(--ring-disabled-background-color);\\n    box-shadow: inset 0 0 0 1px var(--ring-border-disabled-color);\\n  }\\n\\n.primary_ddae.loader_cbfc[disabled] {\\n    color: var(--ring-white-text-color);\\n  }\\n\\n.primary_ddae .loaderBackground_d9f5 {\\n    top: 0;\\n    right: 0;\\n    bottom: 0;\\n    left: 0;\\n\\n    border-radius: var(--ring-border-radius);\\n  }\\n\\n.primary_ddae .loaderBackground_d9f5::before {\\n      background-image:\\n        linear-gradient(\\n          to right,\\n          var(--ring-main-color),\\n          var(--ring-button-loader-background) 40%,\\n          var(--ring-main-color) 80%\\n        );\\n    }\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.danger_bcea:hover {\\n    transition: none;\\n  }}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.danger_bcea:hover {\\n    box-shadow: inset 0 0 0 1px var(--ring-button-danger-hover-color);\\n  }}\\n\\n.danger_bcea,\\n  .danger_bcea.withIcon_ef77,\\n  .danger_bcea.withIcon_ef77:active,\\n  .danger_bcea.withIcon_ef77.active_bbe6,\\n  .danger_bcea.text_fc2a,\\n  .danger_bcea.text_fc2a:active,\\n  .danger_bcea.text_fc2a.active_bbe6 {\\n    color: var(--ring-error-color);\\n  }\\n\\n.danger_bcea:active,\\n  .danger_bcea.active_bbe6 {\\n    background-color: var(--ring-button-danger-active-color);\\n  }\\n\\n.danger_bcea:active,\\n  .danger_bcea.active_bbe6,\\n  .danger_bcea:focus-visible {\\n    box-shadow: inset 0 0 0 1px var(--ring-button-danger-hover-color);\\n  }\\n\\n.danger_bcea:focus-visible {\\n    transition: none;\\n  }\\n\\n.text_fc2a.text_fc2a,\\n.withIcon_ef77.withIcon_ef77 {\\n  background-color: transparent;\\n  box-shadow: none;\\n}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.text_fc2a.text_fc2a:hover, .withIcon_ef77.withIcon_ef77:hover {\\n    transition: none;\\n  }}\\n\\n.text_fc2a.text_fc2a:active,\\n  .withIcon_ef77.withIcon_ef77:active,\\n  .text_fc2a.text_fc2a.active_bbe6,\\n  .withIcon_ef77.withIcon_ef77.active_bbe6 {\\n    background-color: transparent;\\n    box-shadow: none;\\n  }\\n\\n.text_fc2a.text_fc2a:focus-visible, .withIcon_ef77.withIcon_ef77:focus-visible {\\n    box-shadow: inset 0 0 0 2px var(--ring-border-hover-color);\\n  }\\n\\n.loader_cbfc.text_fc2a > .content_b2b8 {\\n  animation-name: text-loading_d1b4;\\n  animation-duration: 1200ms;\\n  animation-iteration-count: infinite;\\n}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.text_fc2a.text_fc2a:hover {\\n  background-color: transparent;\\n  box-shadow: none;\\n}}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.withIcon_ef77:hover:not(:focus-visible) {\\n  background-color: transparent;\\n  box-shadow: none;\\n}}\\n\\n.text_fc2a {\\n  color: var(--ring-action-link-color);\\n}\\n\\n.inline_b4a2 {\\n  display: inline-block;\\n\\n  margin: 0;\\n  padding: 0;\\n\\n  font-size: var(--ring-font-size);\\n}\\n\\n.withIcon_ef77 {\\n  padding: 0 8px;\\n}\\n\\n.text_fc2a:active,\\n  .text_fc2a.active_bbe6 {\\n    color: var(--ring-link-hover-color);\\n  }\\n\\n.withIcon_ef77:active,\\n  .withIcon_ef77.active_bbe6 {\\n    color: var(--ring-action-link-color);\\n  }\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.withIcon_ef77:hover {\\n  color: var(--ring-link-hover-color);\\n}}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.text_fc2a:hover {\\n  color: var(--ring-link-hover-color);\\n}}\\n\\n.icon_e878 {\\n  color: inherit;\\n\\n  line-height: normal;\\n}\\n\\n.icon_e878:not(:last-child) {\\n    margin-right: 4px;\\n  }\\n\\n.withNormalIcon_aaca .icon_e878 {\\n  transition: color var(--ring-ease);\\n\\n  color: var(--ring-icon-color);\\n}\\n\\n.withNormalIcon_aaca:active,\\n.withNormalIcon_aaca.active_bbe6 {\\n  color: var(--ring-main-color);\\n}\\n\\n.withNormalIcon_aaca:active .icon_e878, .withNormalIcon_aaca.active_bbe6 .icon_e878 {\\n    transition: none;\\n\\n    color: inherit;\\n  }\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.withNormalIcon_aaca:hover .icon_e878,\\n.withDangerIcon_e3ca:hover .icon_e878 {\\n  transition: none;\\n\\n  color: inherit;\\n}}\\n\\n.withDangerIcon_e3ca .icon_e878,\\n.withDangerIcon_e3ca:active .icon_e878 {\\n  color: var(--ring-icon-error-color);\\n}\\n\\n.loader_cbfc {\\n  position: relative;\\n  z-index: 0;\\n\\n  pointer-events: none;\\n\\n  background-color: transparent;\\n}\\n\\n.loaderBackground_d9f5 {\\n  position: absolute;\\n  z-index: -1;\\n  top: 1px;\\n  right: 1px;\\n  bottom: 1px;\\n  left: 1px;\\n\\n  overflow: hidden;\\n\\n  border-radius: var(--ring-border-radius-small);\\n}\\n\\n.loaderBackground_d9f5::before {\\n    display: block;\\n\\n    width: calc(100% + 64px);\\n    height: 100%;\\n\\n    content: \"\";\\n    animation: progress_ed8f 1s linear infinite;\\n\\n    background-image:\\n      linear-gradient(\\n        to right,\\n        var(--ring-content-background-color),\\n        var(--ring-selected-background-color) 40%,\\n        var(--ring-content-background-color) 80%\\n      );\\n\\n    background-repeat: repeat;\\n    background-size: 64px;\\n  }\\n\\n.delayed_d562 .content_b2b8::after {\\n  content: \"…\";\\n}\\n\\n.short_a07a {\\n  width: 32px;\\n  padding: 0;\\n}\\n\\n.dropdownIcon_e982 {\\n  margin-right: -2px;\\n\\n  margin-left: 2px;\\n\\n  transition: color var(--ring-ease);\\n\\n  color: var(--ring-icon-secondary-color);\\n\\n  line-height: normal;\\n}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.button_aba4:hover .dropdownIcon_e982 {\\n  transition: none;\\n\\n  color: var(--ring-main-color);\\n}}\\n\\n@keyframes progress_ed8f {\\n  from {\\n    transform: translateX(-64px);\\n  }\\n\\n  to {\\n    transform: translateX(0);\\n  }\\n}\\n\\n@keyframes text-loading_d1b4 {\\n  50% {\\n    opacity: 0.5;\\n  }\\n}\\n',\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/button/button.css\",\"<no source>\"],names:[],mappings:\"AAOA;EACE,0BAAoC;EACpC,sDAAsD;AACxD;;AAEA;EACE,0BAAsC;EACtC,8CAA8C;AAChD;;AAEA;EACE,0BAAoC;EACpC,8CAA8C;AAChD;;AAEA;EACE,kBAAkB;;EAElB,qBAAqB;;EAErB,sBAAsB;EACtB,iCAAc;EACd,SAAS;EACT,eAAyB;;EAEzB,eAAe;EACf,kGAAkG;EAClG,qBAAqB;;EAErB,6BAA6B;;EAE7B,SAAS;EACT,wCAAwC;EACxC,UAAU;EACV,sDAAsD;EACtD,qDAAmD;;EAEnD,oCAAoC;EACpC,uCAAuC;;EAEvC,sCAAmB;AA2DrB;;AC1GA,wGAAA;IAAA,iBAAA;;IAAA,2DAAA;GAAA,CAAA;;ADuDE;IACE,gBAAgB;;IAEhB,uDAAuD;IACvD,0DAAwD;EAC1D;;AAEA;IACE,gBAAgB;;IAEhB,oGAAkG;EACpG;;AAEA;IACE,gBAAgB;;IAEhB,oDAAoD;IACpD,kDAAgD;EAClD;;AAEA;IACE,4FAA4F;EAC9F;;AAEA;IACE,oBAAoB;;IAEpB,uDAAuD;IACvD,6DAA2D;EAC7D;;AAEA;IACE,gEAAgE;IAChE,sEAAoE;EACtE;;AAEA;;IAEE,iCAAiC;EACnC;;AAEA;IACE,sCAAsC;EACxC;;AAEA;IACE,UAAU;;IAEV,SAAS;IACT,UAAU;EACZ;;AAGF;EACE,kCAAkC;AACpC;;AAEA;EACE,mCAAmC;EACnC,wCAAwC;EACxC,gBAAgB;AAqDlB;;ACxKA,wGAAA;IAAA,iBAAA;;IAAA,+CAAA;IAAA,iBAAA;GAAA,CAAA;;AD4HE;;;IAGE,oCAAoC;EACtC;;AAEA;;;IAGE,6DAA6D;EAC/D;;AAEA;;IAEE,mEAAiE;EACnE;;AAEA;IACE,uDAAuD;IACvD,6DAA2D;EAC7D;;AAEA;IACE,mCAAmC;EACrC;;AAEA;IACE,MAAM;IACN,QAAQ;IACR,SAAS;IACT,OAAO;;IAEP,wCAAwC;EAW1C;;AATE;MACE;;;;;;SAMG;IACL;;ACtKJ,wGAAA;IAAA,iBAAA;GAAA,CAAA;;AAAA,wGAAA;IAAA,kEAAA;GAAA,CAAA;;AD2KE;;;;;;;IAOE,8BAA8B;EAChC;;AAEA;;IAEE,wDAAwD;EAC1D;;AAEA;;;IAIE,iEAA+D;EACjE;;AAEA;IAEE,gBAAgB;EAClB;;AAGF;;EAEE,6BAA6B;EAC7B,gBAAgB;AAelB;;ACzNA,wGAAA;IAAA,iBAAA;GAAA,CAAA;;ADgNE;;;;IAEE,6BAA6B;IAC7B,gBAAgB;EAClB;;AAEA;IACE,0DAA0D;EAC5D;;AAGF;EACE,iCAA4B;EAC5B,0BAA0B;EAC1B,mCAAmC;AACrC;;AC/NA,wGAAA;EAAA,8BAAA;EAAA,iBAAA;CAAA,CAAA;;AAAA,wGAAA;EAAA,8BAAA;EAAA,iBAAA;CAAA,CAAA;;AD2OA;EACE,oCAAoC;AACtC;;AAEA;EACE,qBAAqB;;EAErB,SAAS;EACT,UAAU;;EAEV,gCAAgC;AAClC;;AAEA;EACE,cAAe;AACjB;;AAGE;;IAEE,mCAAmC;EACrC;;AAIA;;IAEE,oCAAoC;EACtC;;ACvQF,wGAAA;EAAA,oCAAA;CAAA,CAAA;;AAAA,wGAAA;EAAA,oCAAA;CAAA,CAAA;;ADkRA;EACE,cAAc;;EAEd,mBAAmB;AAKrB;;AAHE;IACE,iBAA8B;EAChC;;AAGF;EACE,kCAAkC;;EAElC,6BAA6B;AAC/B;;AAEA;;EAEE,6BAA6B;AAO/B;;AALE;IACE,gBAAgB;;IAEhB,cAAc;EAChB;;AC1SF,wGAAA;;EAAA,iBAAA;;EAAA,eAAA;CAAA,CAAA;;ADoTA;;EAEE,mCAAmC;AACrC;;AAEA;EACE,kBAAkB;EAClB,UAAU;;EAEV,oBAAoB;;EAEpB,6BAA6B;AAC/B;;AAEA;EACE,kBAAkB;EAClB,WAAW;EACX,QAAQ;EACR,UAAU;EACV,WAAW;EACX,SAAS;;EAET,gBAAgB;;EAEhB,8CAA8C;AAsBhD;;AApBE;IACE,cAAc;;IAEd,wBAA+B;IAC/B,YAAY;;IAEZ,WAAW;IACX,2CAAsC;;IAEtC;;;;;;OAMG;;IAEH,yBAAyB;IACzB,qBAA4B;EAC9B;;AAGF;EACE,YAAY;AACd;;AAEA;EACE,WAAqB;EACrB,UAAU;AACZ;;AAEA;EACE,kBAAkB;;EAElB,gBAAgB;;EAEhB,kCAAkC;;EAElC,uCAAuC;;EAEvC,mBAAmB;AACrB;;ACvXA,wGAAA;EAAA,iBAAA;;EAAA,8BAAA;CAAA,CAAA;;AD+XA;EACE;IACE,4BAA4C;EAC9C;;EAEA;IACE,wBAAwB;EAC1B;AACF;;AAEA;EACE;IACE,YAAY;EACd;AACF\",sourcesContent:['@import \"../global/variables.css\";\\n\\n@value unit from \"../global/global.css\";\\n@value button-shadow: inset 0 0 0 1px;\\n@value height: var(--ring-button-height);\\n@value loaderWidth: calc(unit * 8);\\n\\n.heightS {\\n  --ring-button-height: calc(unit * 3);\\n  --ring-button-font-size: var(--ring-font-size-smaller);\\n}\\n\\n.heightM {\\n  --ring-button-height: calc(unit * 3.5);\\n  --ring-button-font-size: var(--ring-font-size);\\n}\\n\\n.heightL {\\n  --ring-button-height: calc(unit * 4);\\n  --ring-button-font-size: var(--ring-font-size);\\n}\\n\\n.button {\\n  position: relative;\\n\\n  display: inline-block;\\n\\n  box-sizing: border-box;\\n  height: height;\\n  margin: 0;\\n  padding: 0 calc(unit * 2);\\n\\n  cursor: pointer;\\n  transition: color var(--ring-ease), background-color var(--ring-ease), box-shadow var(--ring-ease);\\n  text-decoration: none;\\n\\n  color: var(--ring-text-color);\\n\\n  border: 0;\\n  border-radius: var(--ring-border-radius);\\n  outline: 0;\\n  background-color: var(--ring-content-background-color);\\n  box-shadow: button-shadow var(--ring-borders-color);\\n\\n  font-family: var(--ring-font-family);\\n  font-size: var(--ring-button-font-size);\\n\\n  line-height: height;\\n\\n  &:hover {\\n    transition: none;\\n\\n    box-shadow: button-shadow var(--ring-border-hover-color);\\n  }\\n\\n  &:active {\\n    transition: none;\\n\\n    background-color: var(--ring-selected-background-color);\\n    box-shadow: button-shadow var(--ring-border-hover-color);\\n  }\\n\\n  &:focus-visible {\\n    transition: none;\\n\\n    box-shadow: button-shadow var(--ring-border-hover-color), 0 0 0 1px var(--ring-border-hover-color);\\n  }\\n\\n  &.active {\\n    transition: none;\\n\\n    background-color: var(--ring-hover-background-color);\\n    box-shadow: button-shadow var(--ring-main-color);\\n  }\\n\\n  &:focus-visible.active {\\n    box-shadow: inset 0 0 0 2px var(--ring-main-color), 0 0 0 1px var(--ring-border-hover-color);\\n  }\\n\\n  &[disabled] {\\n    pointer-events: none;\\n\\n    background-color: var(--ring-disabled-background-color);\\n    box-shadow: button-shadow var(--ring-border-disabled-color);\\n  }\\n\\n  &[disabled].active {\\n    background-color: var(--ring-disabled-selected-background-color);\\n    box-shadow: button-shadow var(--ring-border-selected-disabled-color);\\n  }\\n\\n  &[disabled],\\n  &[disabled].withIcon {\\n    color: var(--ring-disabled-color);\\n  }\\n\\n  &[disabled] .icon {\\n    color: var(--ring-icon-disabled-color);\\n  }\\n\\n  &::-moz-focus-inner {\\n    padding: 0;\\n\\n    border: 0;\\n    outline: 0;\\n  }\\n}\\n\\n.withIcon {\\n  color: var(--ring-secondary-color);\\n}\\n\\n.primary {\\n  color: var(--ring-white-text-color);\\n  background-color: var(--ring-main-color);\\n  box-shadow: none;\\n\\n  &:hover {\\n    transition: none;\\n\\n    background-color: var(--ring-main-hover-color);\\n    box-shadow: none;\\n  }\\n\\n  &.withIcon,\\n  &.withIcon:active,\\n  &.withIcon.active {\\n    color: var(--ring-action-link-color);\\n  }\\n\\n  &:focus-visible,\\n  &:active,\\n  &.active {\\n    background-color: var(--ring-button-primary-background-color);\\n  }\\n\\n  &:active,\\n  &.active {\\n    box-shadow: button-shadow var(--ring-button-primary-border-color);\\n  }\\n\\n  &[disabled] {\\n    background-color: var(--ring-disabled-background-color);\\n    box-shadow: button-shadow var(--ring-border-disabled-color);\\n  }\\n\\n  &[disabled].loader {\\n    color: var(--ring-white-text-color);\\n  }\\n\\n  & .loaderBackground {\\n    top: 0;\\n    right: 0;\\n    bottom: 0;\\n    left: 0;\\n\\n    border-radius: var(--ring-border-radius);\\n\\n    &::before {\\n      background-image:\\n        linear-gradient(\\n          to right,\\n          var(--ring-main-color),\\n          var(--ring-button-loader-background) 40%,\\n          var(--ring-main-color) 80%\\n        );\\n    }\\n  }\\n}\\n\\n.danger {\\n  &,\\n  &.withIcon,\\n  &.withIcon:active,\\n  &.withIcon.active,\\n  &.text,\\n  &.text:active,\\n  &.text.active {\\n    color: var(--ring-error-color);\\n  }\\n\\n  &:active,\\n  &.active {\\n    background-color: var(--ring-button-danger-active-color);\\n  }\\n\\n  &:active,\\n  &.active,\\n  &:focus-visible,\\n  &:hover {\\n    box-shadow: button-shadow var(--ring-button-danger-hover-color);\\n  }\\n\\n  &:focus-visible,\\n  &:hover {\\n    transition: none;\\n  }\\n}\\n\\n.text.text,\\n.withIcon.withIcon {\\n  background-color: transparent;\\n  box-shadow: none;\\n\\n  &:hover {\\n    transition: none;\\n  }\\n\\n  &:active,\\n  &.active {\\n    background-color: transparent;\\n    box-shadow: none;\\n  }\\n\\n  &:focus-visible {\\n    box-shadow: inset 0 0 0 2px var(--ring-border-hover-color);\\n  }\\n}\\n\\n.loader.text > .content {\\n  animation-name: text-loading;\\n  animation-duration: 1200ms;\\n  animation-iteration-count: infinite;\\n}\\n\\n.text.text:hover {\\n  background-color: transparent;\\n  box-shadow: none;\\n}\\n\\n.withIcon:hover:not(:focus-visible) {\\n  background-color: transparent;\\n  box-shadow: none;\\n}\\n\\n.text {\\n  color: var(--ring-action-link-color);\\n}\\n\\n.inline {\\n  display: inline-block;\\n\\n  margin: 0;\\n  padding: 0;\\n\\n  font-size: var(--ring-font-size);\\n}\\n\\n.withIcon {\\n  padding: 0 unit;\\n}\\n\\n.text {\\n  &:active,\\n  &.active {\\n    color: var(--ring-link-hover-color);\\n  }\\n}\\n\\n.withIcon {\\n  &:active,\\n  &.active {\\n    color: var(--ring-action-link-color);\\n  }\\n}\\n\\n.withIcon:hover {\\n  color: var(--ring-link-hover-color);\\n}\\n\\n.text:hover {\\n  color: var(--ring-link-hover-color);\\n}\\n\\n.icon {\\n  color: inherit;\\n\\n  line-height: normal;\\n\\n  &:not(:last-child) {\\n    margin-right: calc(unit * 0.5);\\n  }\\n}\\n\\n.withNormalIcon .icon {\\n  transition: color var(--ring-ease);\\n\\n  color: var(--ring-icon-color);\\n}\\n\\n.withNormalIcon:active,\\n.withNormalIcon.active {\\n  color: var(--ring-main-color);\\n\\n  & .icon {\\n    transition: none;\\n\\n    color: inherit;\\n  }\\n}\\n\\n.withNormalIcon:hover .icon,\\n.withDangerIcon:hover .icon {\\n  transition: none;\\n\\n  color: inherit;\\n}\\n\\n.withDangerIcon .icon,\\n.withDangerIcon:active .icon {\\n  color: var(--ring-icon-error-color);\\n}\\n\\n.loader {\\n  position: relative;\\n  z-index: 0;\\n\\n  pointer-events: none;\\n\\n  background-color: transparent;\\n}\\n\\n.loaderBackground {\\n  position: absolute;\\n  z-index: -1;\\n  top: 1px;\\n  right: 1px;\\n  bottom: 1px;\\n  left: 1px;\\n\\n  overflow: hidden;\\n\\n  border-radius: var(--ring-border-radius-small);\\n\\n  &::before {\\n    display: block;\\n\\n    width: calc(100% + loaderWidth);\\n    height: 100%;\\n\\n    content: \"\";\\n    animation: progress 1s linear infinite;\\n\\n    background-image:\\n      linear-gradient(\\n        to right,\\n        var(--ring-content-background-color),\\n        var(--ring-selected-background-color) 40%,\\n        var(--ring-content-background-color) 80%\\n      );\\n\\n    background-repeat: repeat;\\n    background-size: loaderWidth;\\n  }\\n}\\n\\n.delayed .content::after {\\n  content: \"…\";\\n}\\n\\n.short {\\n  width: calc(unit * 4);\\n  padding: 0;\\n}\\n\\n.dropdownIcon {\\n  margin-right: -2px;\\n\\n  margin-left: 2px;\\n\\n  transition: color var(--ring-ease);\\n\\n  color: var(--ring-icon-secondary-color);\\n\\n  line-height: normal;\\n}\\n\\n.button:hover .dropdownIcon {\\n  transition: none;\\n\\n  color: var(--ring-main-color);\\n}\\n\\n@keyframes progress {\\n  from {\\n    transform: translateX(calc(0 - loaderWidth));\\n  }\\n\\n  to {\\n    transform: translateX(0);\\n  }\\n}\\n\\n@keyframes text-loading {\\n  50% {\\n    opacity: 0.5;\\n  }\\n}\\n',null],sourceRoot:\"\"}]),s.locals={unit:`${l.default.locals.unit}`,\"button-shadow\":\"inset 0 0 0 1px\",height:\"var(--ring-button-height)\",loaderWidth:\"64px\",heightS:\"heightS_b28d\",heightM:\"heightM_dfd3\",heightL:\"heightL_a4d3\",button:\"button_aba4\",active:\"active_bbe6\",withIcon:\"withIcon_ef77\",icon:\"icon_e878\",primary:\"primary_ddae\",loader:\"loader_cbfc\",loaderBackground:\"loaderBackground_d9f5\",danger:\"danger_bcea\",text:\"text_fc2a\",content:\"content_b2b8\",\"text-loading\":\"text-loading_d1b4\",inline:\"inline_b4a2\",withNormalIcon:\"withNormalIcon_aaca\",withDangerIcon:\"withDangerIcon_e3ca\",progress:\"progress_ed8f\",delayed:\"delayed_d562\",short:\"short_a07a\",dropdownIcon:\"dropdownIcon_e982\"};const u=s},1866:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),s=a()(o());s.i(c.A),s.i(l.default,\"\",!0),s.push([e.id,\".checkbox_dccf {\\n  position: relative;\\n\\n  display: inline-block;\\n\\n  text-align: left;\\n\\n  color: var(--ring-text-color);\\n  outline: none;\\n}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.checkbox_dccf:hover .cell_edda {\\n    transition: background-color var(--ring-ease);\\n\\n    border-color: var(--ring-border-hover-color);\\n  }}\\n\\n.cell_edda {\\n  position: relative;\\n  top: -2px;\\n\\n  display: inline-block;\\n\\n  box-sizing: border-box;\\n  width: 14px;\\n  height: 14px;\\n\\n  -webkit-user-select: none;\\n\\n     -moz-user-select: none;\\n\\n          user-select: none;\\n  transition: border-color var(--ring-ease), background-color var(--ring-ease), box-shadow var(--ring-ease);\\n  vertical-align: middle;\\n  pointer-events: none;\\n\\n  border: 1px solid var(--ring-borders-color);\\n  border-radius: var(--ring-border-radius-small);\\n  background-color: var(--ring-content-background-color);\\n}\\n\\n.icon_b476.icon_b476 {\\n  position: absolute;\\n\\n  top: -1px;\\n  left: -1px;\\n\\n  width: 16px;\\n  height: 16px;\\n\\n  opacity: 0;\\n  color: var(--ring-white-text-color);\\n}\\n\\n.icon_b476.icon_b476 svg {\\n    position: absolute;\\n    top: 0;\\n    left: 0;\\n  }\\n\\n.check_a219 {\\n}\\n\\n.minus_de65 {\\n}\\n\\n.input_a330 {\\n  position: absolute;\\n  top: 0;\\n  left: 0;\\n\\n  width: 100%;\\n  height: 100%;\\n  margin: 0;\\n\\n  cursor: pointer;\\n\\n  opacity: 0;\\n\\n  /* stylelint-disable-next-line selector-max-specificity */\\n}\\n\\n.input_a330:checked + .cell_edda,\\n  .input_a330:indeterminate + .cell_edda {\\n    border-color: transparent;\\n    background-color: var(--ring-main-color);\\n  }\\n\\n/* stylelint-disable-next-line selector-max-specificity */\\n\\n.input_a330:checked + .cell_edda .check_a219 {\\n    opacity: 1;\\n  }\\n\\n.input_a330:focus-visible + .cell_edda,\\n  .input_a330.focus_eaa3 + .cell_edda {\\n    transition: background-color var(--ring-ease);\\n\\n    border-color: var(--ring-border-hover-color);\\n    box-shadow: 0 0 0 1px var(--ring-border-hover-color);\\n  }\\n\\n/* stylelint-disable-next-line selector-max-specificity */\\n\\n.input_a330:indeterminate + .cell_edda .minus_de65 {\\n    opacity: 1;\\n  }\\n\\n.input_a330[disabled] {\\n    pointer-events: none;\\n  }\\n\\n/* stylelint-disable-next-line selector-max-specificity */\\n\\n.input_a330[disabled][disabled] + .cell_edda {\\n    border-color: var(--ring-border-disabled-color);\\n    background-color: var(--ring-disabled-background-color);\\n  }\\n\\n/* stylelint-disable-next-line selector-max-specificity */\\n\\n.input_a330[disabled]:checked + .cell_edda,\\n  .input_a330[disabled]:indeterminate + .cell_edda {\\n    border-color: var(--ring-border-selected-disabled-color);\\n  }\\n\\n/* stylelint-disable-next-line selector-max-specificity */\\n\\n.input_a330[disabled]:checked + .cell_edda .check_a219,\\n  .input_a330[disabled]:indeterminate + .cell_edda .minus_de65 {\\n    color: var(--ring-icon-disabled-color);\\n  }\\n\\n/* stylelint-disable-next-line selector-max-specificity */\\n\\n.input_a330:indeterminate:indeterminate + .cell_edda .check_a219 {\\n    transition: none;\\n\\n    opacity: 0;\\n  }\\n\\n.input_a330[disabled] ~ .label_dcc7 {\\n    color: var(--ring-disabled-color);\\n  }\\n\\n.label_dcc7 {\\n  margin-left: 8px;\\n\\n  line-height: normal;\\n}\\n\",\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/checkbox/checkbox.css\",\"<no source>\"],names:[],mappings:\"AAKA;EACE,kBAAkB;;EAElB,qBAAqB;;EAErB,gBAAgB;;EAEhB,6BAA6B;EAC7B,aAAa;AAOf;;ACpBA,wGAAA;IAAA,8CAAA;;IAAA,6CAAA;GAAA,CAAA;;ADsBA;EACE,kBAAkB;EAClB,SAAS;;EAET,qBAAqB;;EAErB,sBAAsB;EACtB,WAAmB;EACnB,YAAoB;;EAEpB,yBAAiB;;KAAjB,sBAAiB;;UAAjB,iBAAiB;EACjB,yGAAyG;EACzG,sBAAsB;EACtB,oBAAoB;;EAEpB,2CAA2C;EAC3C,8CAA8C;EAC9C,sDAAsD;AACxD;;AAEA;EACE,kBAAkB;;EAElB,SAAS;EACT,UAAU;;EAEV,WAAqB;EACrB,YAAsB;;EAEtB,UAAU;EACV,mCAAmC;AAOrC;;AALE;IACE,kBAAkB;IAClB,MAAM;IACN,OAAO;EACT;;AAGF;AAEA;;AAEA;AAEA;;AAEA;EACE,kBAAkB;EAClB,MAAM;EACN,OAAO;;EAEP,WAAW;EACX,YAAY;EACZ,SAAS;;EAET,eAAe;;EAEf,UAAU;;EAEV,yDAAyD;AAyD3D;;AAxDE;;IAEE,yBAAyB;IACzB,wCAAwC;EAC1C;;AAEA,yDAAyD;;AACzD;IACE,UAAU;EACZ;;AAEA;;IAEE,6CAA6C;;IAE7C,4CAA4C;IAC5C,oDAAoD;EACtD;;AAEA,yDAAyD;;AACzD;IACE,UAAU;EACZ;;AAEA;IACE,oBAAoB;EACtB;;AAEA,yDAAyD;;AACzD;IACE,+CAA+C;IAC/C,uDAAuD;EACzD;;AAEA,yDAAyD;;AACzD;;IAEE,wDAAwD;EAC1D;;AAEA,yDAAyD;;AACzD;;IAEE,sCAAsC;EACxC;;AAEA,yDAAyD;;AACzD;IACE,gBAAgB;;IAEhB,UAAU;EACZ;;AAEA;IACE,iCAAiC;EACnC;;AAGF;EACE,gBAAiB;;EAEjB,mBAAmB;AACrB\",sourcesContent:['@import \"../global/variables.css\";\\n\\n@value unit from \"../global/global.css\";\\n@value checkboxSize: 14px;\\n\\n.checkbox {\\n  position: relative;\\n\\n  display: inline-block;\\n\\n  text-align: left;\\n\\n  color: var(--ring-text-color);\\n  outline: none;\\n\\n  &:hover .cell {\\n    transition: background-color var(--ring-ease);\\n\\n    border-color: var(--ring-border-hover-color);\\n  }\\n}\\n\\n.cell {\\n  position: relative;\\n  top: -2px;\\n\\n  display: inline-block;\\n\\n  box-sizing: border-box;\\n  width: checkboxSize;\\n  height: checkboxSize;\\n\\n  user-select: none;\\n  transition: border-color var(--ring-ease), background-color var(--ring-ease), box-shadow var(--ring-ease);\\n  vertical-align: middle;\\n  pointer-events: none;\\n\\n  border: 1px solid var(--ring-borders-color);\\n  border-radius: var(--ring-border-radius-small);\\n  background-color: var(--ring-content-background-color);\\n}\\n\\n.icon.icon {\\n  position: absolute;\\n\\n  top: -1px;\\n  left: -1px;\\n\\n  width: calc(unit * 2);\\n  height: calc(unit * 2);\\n\\n  opacity: 0;\\n  color: var(--ring-white-text-color);\\n\\n  & svg {\\n    position: absolute;\\n    top: 0;\\n    left: 0;\\n  }\\n}\\n\\n.check {\\n  composes: icon;\\n}\\n\\n.minus {\\n  composes: icon;\\n}\\n\\n.input {\\n  position: absolute;\\n  top: 0;\\n  left: 0;\\n\\n  width: 100%;\\n  height: 100%;\\n  margin: 0;\\n\\n  cursor: pointer;\\n\\n  opacity: 0;\\n\\n  /* stylelint-disable-next-line selector-max-specificity */\\n  &:checked + .cell,\\n  &:indeterminate + .cell {\\n    border-color: transparent;\\n    background-color: var(--ring-main-color);\\n  }\\n\\n  /* stylelint-disable-next-line selector-max-specificity */\\n  &:checked + .cell .check {\\n    opacity: 1;\\n  }\\n\\n  &:focus-visible + .cell,\\n  &.focus + .cell {\\n    transition: background-color var(--ring-ease);\\n\\n    border-color: var(--ring-border-hover-color);\\n    box-shadow: 0 0 0 1px var(--ring-border-hover-color);\\n  }\\n\\n  /* stylelint-disable-next-line selector-max-specificity */\\n  &:indeterminate + .cell .minus {\\n    opacity: 1;\\n  }\\n\\n  &[disabled] {\\n    pointer-events: none;\\n  }\\n\\n  /* stylelint-disable-next-line selector-max-specificity */\\n  &[disabled][disabled] + .cell {\\n    border-color: var(--ring-border-disabled-color);\\n    background-color: var(--ring-disabled-background-color);\\n  }\\n\\n  /* stylelint-disable-next-line selector-max-specificity */\\n  &[disabled]:checked + .cell,\\n  &[disabled]:indeterminate + .cell {\\n    border-color: var(--ring-border-selected-disabled-color);\\n  }\\n\\n  /* stylelint-disable-next-line selector-max-specificity */\\n  &[disabled]:checked + .cell .check,\\n  &[disabled]:indeterminate + .cell .minus {\\n    color: var(--ring-icon-disabled-color);\\n  }\\n\\n  /* stylelint-disable-next-line selector-max-specificity */\\n  &:indeterminate:indeterminate + .cell .check {\\n    transition: none;\\n\\n    opacity: 0;\\n  }\\n\\n  &[disabled] ~ .label {\\n    color: var(--ring-disabled-color);\\n  }\\n}\\n\\n.label {\\n  margin-left: unit;\\n\\n  line-height: normal;\\n}\\n',null],sourceRoot:\"\"}]),s.locals={unit:`${l.default.locals.unit}`,checkboxSize:\"14px\",checkbox:\"checkbox_dccf\",cell:\"cell_edda\",icon:\"icon_b476\",check:\"check_a219 icon_b476\",minus:\"minus_de65 icon_b476\",input:\"input_a330\",focus:\"focus_eaa3\",label:\"label_dcc7\"};const u=s},5486:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>l});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i)()(o());a.push([e.id,\".label_bed7 {\\n  display: block;\\n\\n  margin-bottom: calc(var(--ring-unit)*0.5);\\n}\\n\\n.formLabel_f9ba {\\n  color: var(--ring-text-color);\\n\\n  font-size: var(--ring-font-size);\\n  line-height: var(--ring-line-height);\\n}\\n\\n.secondaryLabel_e8a1 {\\n  color: var(--ring-secondary-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n  line-height: var(--ring-line-height-lowest);\\n}\\n\\n.disabledLabel_e4c1 {\\n  color: var(--ring-disabled-color);\\n}\\n\",\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/control-label/control-label.css\"],names:[],mappings:\"AAAA;EACE,cAAc;;EAEd,yCAA2C;AAC7C;;AAEA;EACE,6BAA6B;;EAE7B,gCAAgC;EAChC,oCAAoC;AACtC;;AAEA;EACE,kCAAkC;;EAElC,wCAAwC;EACxC,2CAA2C;AAC7C;;AAEA;EACE,iCAAiC;AACnC\",sourcesContent:[\".label {\\n  display: block;\\n\\n  margin-bottom: calc(var(--ring-unit) * 0.5);\\n}\\n\\n.formLabel {\\n  color: var(--ring-text-color);\\n\\n  font-size: var(--ring-font-size);\\n  line-height: var(--ring-line-height);\\n}\\n\\n.secondaryLabel {\\n  color: var(--ring-secondary-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n  line-height: var(--ring-line-height-lowest);\\n}\\n\\n.disabledLabel {\\n  color: var(--ring-disabled-color);\\n}\\n\"],sourceRoot:\"\"}]),a.locals={label:\"label_bed7\",formLabel:\"formLabel_f9ba\",secondaryLabel:\"secondaryLabel_e8a1\",disabledLabel:\"disabledLabel_e4c1\"};const l=a},6506:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(5280),c=a()(o());c.i(l.A),c.push([e.id,\".dropdown_a1de {\\n  display: inline-block;\\n}\\n\\n.anchor_fdbe.anchor_fdbe {\\n  margin: 0 -3px;\\n  padding: 0 3px;\\n\\n  font: inherit;\\n}\\n\\n.chevron_ffc6 {\\n  margin-left: 2px;\\n\\n  line-height: normal;\\n}\\n\",\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/dropdown/dropdown.css\"],names:[],mappings:\"AAEA;EACE,qBAAqB;AACvB;;AAEA;EACE,cAAc;EACd,cAAc;;EAEd,aAAa;AACf;;AAEA;EACE,gBAAgB;;EAEhB,mBAAmB;AACrB\",sourcesContent:['@import \"../global/variables.css\";\\n\\n.dropdown {\\n  display: inline-block;\\n}\\n\\n.anchor.anchor {\\n  margin: 0 -3px;\\n  padding: 0 3px;\\n\\n  font: inherit;\\n}\\n\\n.chevron {\\n  margin-left: 2px;\\n\\n  line-height: normal;\\n}\\n'],sourceRoot:\"\"}]),c.locals={dropdown:\"dropdown_a1de\",anchor:\"anchor_fdbe\",chevron:\"chevron_ffc6\"};const s=c},9106:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>l});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i)()(o());a.push([e.id,'/* https://readymag.com/artemtiunov/RingUILanguage/colours/ */\\n\\n/*\\nUnit shouldn\\'t be CSS custom property because it is not intended to change\\nAlso it won\\'t form in FF47 https://bugzilla.mozilla.org/show_bug.cgi?id=594933\\n*/\\n\\n.clearfix_c694::after {\\n    display: block;\\n    clear: both;\\n\\n    content: \"\";\\n  }\\n\\n.font_a1f6 {\\n  font-family: var(--ring-font-family);\\n  font-size: var(--ring-font-size);\\n  line-height: var(--ring-line-height);\\n}\\n\\n.font-lower_c3c9 {\\n\\n  line-height: var(--ring-line-height-lower);\\n}\\n\\n.font-smaller_d963 {\\n\\n  font-size: var(--ring-font-size-smaller);\\n}\\n\\n.font-smaller-lower_ff5f {\\n\\n  line-height: var(--ring-line-height-lowest);\\n}\\n\\n.font-larger-lower_b336 {\\n\\n  font-size: var(--ring-font-size-larger);\\n}\\n\\n.font-larger_f035 {\\n\\n  line-height: var(--ring-line-height-taller);\\n}\\n\\n/* To be used at large sizes */\\n/* As close as possible to Helvetica Neue Thin (to replace Gotham) */\\n.thin-font_de5b {\\n  font-family: \"Segoe UI\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\\n  font-size: var(--ring-font-size);\\n  font-weight: 100; /* Renders Helvetica Neue UltraLight on OS X  */\\n}\\n\\n.monospace-font_ac33 {\\n  font-family: var(--ring-font-family-monospace);\\n  font-size: var(--ring-font-size-smaller);\\n}\\n\\n.ellipsis_e43b {\\n  overflow: hidden;\\n\\n  white-space: nowrap;\\n  text-overflow: ellipsis;\\n}\\n\\n.resetButton_ddd2 {\\n  overflow: visible;\\n\\n  padding: 0;\\n\\n  text-align: left;\\n\\n  color: inherit;\\n  border: 0;\\n\\n  background-color: transparent;\\n\\n  font: inherit;\\n}\\n\\n.resetButton_ddd2::-moz-focus-inner {\\n    padding: 0;\\n\\n    border: 0;\\n  }\\n\\n/* Note: footer also has top margin which isn\\'t taken into account here */\\n\\n/* Media breakpoints (minimal values) */\\n\\n/* Media queries */\\n',\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/global/global.css\"],names:[],mappings:\"AAAA,6DAA6D;;AAE7D;;;CAGC;;AAIC;IACE,cAAc;IACd,WAAW;;IAEX,WAAW;EACb;;AAGF;EACE,oCAAoC;EACpC,gCAAgC;EAChC,oCAAoC;AACtC;;AAEA;;EAGE,0CAA0C;AAC5C;;AAEA;;EAGE,wCAAwC;AAC1C;;AAEA;;EAGE,2CAA2C;AAC7C;;AAEA;;EAGE,uCAAuC;AACzC;;AAEA;;EAGE,2CAA2C;AAC7C;;AAEA,8BAA8B;AAC9B,oEAAoE;AACpE;EACE,uEAAuE;EACvE,gCAAgC;EAChC,gBAAgB,EAAE,+CAA+C;AACnE;;AAEA;EACE,8CAA8C;EAC9C,wCAAwC;AAC1C;;AAEA;EACE,gBAAgB;;EAEhB,mBAAmB;EACnB,uBAAuB;AACzB;;AAEA;EACE,iBAAiB;;EAEjB,UAAU;;EAEV,gBAAgB;;EAEhB,cAAc;EACd,SAAS;;EAET,6BAA6B;;EAE7B,aAAa;AAOf;;AALE;IACE,UAAU;;IAEV,SAAS;EACX;;AAGF,yEAAyE;;AAGzE,uCAAuC;;AAKvC,kBAAkB\",sourcesContent:['/* https://readymag.com/artemtiunov/RingUILanguage/colours/ */\\n\\n/*\\nUnit shouldn\\'t be CSS custom property because it is not intended to change\\nAlso it won\\'t form in FF47 https://bugzilla.mozilla.org/show_bug.cgi?id=594933\\n*/\\n@value unit: 8px;\\n\\n.clearfix {\\n  &::after {\\n    display: block;\\n    clear: both;\\n\\n    content: \"\";\\n  }\\n}\\n\\n.font {\\n  font-family: var(--ring-font-family);\\n  font-size: var(--ring-font-size);\\n  line-height: var(--ring-line-height);\\n}\\n\\n.font-lower {\\n  composes: font;\\n\\n  line-height: var(--ring-line-height-lower);\\n}\\n\\n.font-smaller {\\n  composes: font-lower;\\n\\n  font-size: var(--ring-font-size-smaller);\\n}\\n\\n.font-smaller-lower {\\n  composes: font-smaller;\\n\\n  line-height: var(--ring-line-height-lowest);\\n}\\n\\n.font-larger-lower {\\n  composes: font-lower;\\n\\n  font-size: var(--ring-font-size-larger);\\n}\\n\\n.font-larger {\\n  composes: font-larger-lower;\\n\\n  line-height: var(--ring-line-height-taller);\\n}\\n\\n/* To be used at large sizes */\\n/* As close as possible to Helvetica Neue Thin (to replace Gotham) */\\n.thin-font {\\n  font-family: \"Segoe UI\", \"Helvetica Neue\", Helvetica, Arial, sans-serif;\\n  font-size: var(--ring-font-size);\\n  font-weight: 100; /* Renders Helvetica Neue UltraLight on OS X  */\\n}\\n\\n.monospace-font {\\n  font-family: var(--ring-font-family-monospace);\\n  font-size: var(--ring-font-size-smaller);\\n}\\n\\n.ellipsis {\\n  overflow: hidden;\\n\\n  white-space: nowrap;\\n  text-overflow: ellipsis;\\n}\\n\\n.resetButton {\\n  overflow: visible;\\n\\n  padding: 0;\\n\\n  text-align: left;\\n\\n  color: inherit;\\n  border: 0;\\n\\n  background-color: transparent;\\n\\n  font: inherit;\\n\\n  &::-moz-focus-inner {\\n    padding: 0;\\n\\n    border: 0;\\n  }\\n}\\n\\n/* Note: footer also has top margin which isn\\'t taken into account here */\\n@value footer-height: calc(unit * 8);\\n\\n/* Media breakpoints (minimal values) */\\n@value breakpoint-small: 640px;\\n@value breakpoint-middle: 960px;\\n@value breakpoint-large: 1200px;\\n\\n/* Media queries */\\n@value extra-small-screen-media: (max-width: calc(breakpoint-small - 1px));\\n@value small-screen-media: (min-width: breakpoint-small) and (max-width: calc(breakpoint-middle - 1px));\\n@value middle-screen-media: (min-width: breakpoint-middle) and (max-width: calc(breakpoint-large - 1px));\\n@value large-screen-media: (min-width: breakpoint-large);\\n'],sourceRoot:\"\"}]),a.locals={unit:\"8px\",\"footer-height\":\"64px\",\"breakpoint-small\":\"640px\",\"breakpoint-middle\":\"960px\",\"breakpoint-large\":\"1200px\",\"extra-small-screen-media\":\"(max-width: 639px)\",\"small-screen-media\":\"(min-width: 640px) and (max-width: 959px)\",\"middle-screen-media\":\"(min-width: 960px) and (max-width: 1199px)\",\"large-screen-media\":\"(min-width: 1200px)\",clearfix:\"clearfix_c694\",font:\"font_a1f6\",\"font-lower\":\"font-lower_c3c9 font_a1f6\",\"font-smaller\":\"font-smaller_d963 font-lower_c3c9 font_a1f6\",\"font-smaller-lower\":\"font-smaller-lower_ff5f font-smaller_d963 font-lower_c3c9 font_a1f6\",\"font-larger-lower\":\"font-larger-lower_b336 font-lower_c3c9 font_a1f6\",\"font-larger\":\"font-larger_f035 font-larger-lower_b336 font-lower_c3c9 font_a1f6\",\"thin-font\":\"thin-font_de5b\",\"monospace-font\":\"monospace-font_ac33\",ellipsis:\"ellipsis_e43b\",resetButton:\"resetButton_ddd2\"};const l=a},5280:(e,n,t)=>{\"use strict\";t.d(n,{A:()=>l});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i)()(o());a.push([e.id,'/* stylelint-disable color-no-hex */\\n\\n.light_f331,\\n:root {\\n  --ring-unit: 8px;\\n\\n  /* Element */\\n  --ring-line-components: 223, 229, 235;\\n  --ring-line-color: rgb(var(--ring-line-components)); /* #dfe5eb */\\n  --ring-borders-components: 197, 209, 219;\\n  --ring-borders-color: rgb(var(--ring-borders-components)); /* #c5d1db */\\n  --ring-icon-components: 184, 209, 229;\\n  --ring-icon-color: rgb(var(--ring-icon-components)); /* #b8d1e5 */\\n  --ring-icon-secondary-components: 153, 153, 153;\\n  --ring-icon-secondary-color: rgb(var(--ring-icon-secondary-components)); /* #999 */\\n  --ring-border-disabled-components: 232, 232, 232;\\n  --ring-border-disabled-color: rgb(var(--ring-border-disabled-components)); /* #e8e8e8 */\\n  --ring-border-selected-disabled-components: 212, 212, 212;\\n  --ring-border-selected-disabled-color: rgb(var(--ring-border-selected-disabled-components)); /* #d4d4d4 */\\n  --ring-border-unselected-disabled-components: 232, 232, 232;\\n  --ring-border-unselected-disabled-color: rgb(var(--ring-border-unselected-disabled-components)); /* #e8e8e8 */ /* TODO remove in 6.0 */\\n  --ring-icon-disabled-components: 212, 212, 212;\\n  --ring-icon-disabled-color: rgb(var(--ring-icon-disabled-components)); /* #d4d4d4 */\\n  --ring-border-hover-components: 128, 198, 255;\\n  --ring-border-hover-color: rgb(var(--ring-border-hover-components)); /* #80c6ff */\\n  --ring-icon-hover-components: var(--ring-link-hover-color);\\n  --ring-icon-hover-color: var(--ring-link-hover-color);\\n  --ring-main-components: 0, 128, 229;\\n  --ring-main-color: rgb(var(--ring-main-components)); /* #0080e5 */\\n  --ring-action-link-components: var(--ring-main-components);\\n  --ring-action-link-color: rgb(var(--ring-main-components)); /* #0080e5 */\\n  --ring-main-hover-components: 0, 112, 204;\\n  --ring-main-hover-color: rgb(var(--ring-main-hover-components)); /* #0070cc */\\n  --ring-icon-error-components: 219, 88, 96;\\n  --ring-icon-error-color: rgb(var(--ring-icon-error-components)); /* #db5860 */\\n  --ring-icon-warning-components: 237, 162, 0;\\n  --ring-icon-warning-color: rgb(var(--ring-icon-warning-components)); /* #eda200 */\\n  --ring-icon-success-components: 89, 168, 105;\\n  --ring-icon-success-color: rgb(var(--ring-icon-success-components)); /* #59a869 */\\n  --ring-pale-control-components: 207, 219, 229;\\n  --ring-pale-control-color: rgb(var(--ring-pale-control-components)); /* #cfdbe5 */\\n  --ring-popup-border-components: 0, 28, 54;\\n  --ring-popup-border-color: var(--ring-line-color);\\n  --ring-popup-shadow-components: rgba(var(--ring-popup-border-components), 0.1);\\n  --ring-popup-shadow-color: rgba(var(--ring-popup-border-components), 0.1);\\n  --ring-popup-secondary-shadow-color: rgba(var(--ring-popup-border-components), 0.04);\\n  --ring-message-shadow-color: rgba(var(--ring-popup-border-components), 0.3);\\n  --ring-pinned-shadow-components: 115, 117, 119;\\n  --ring-pinned-shadow-color: rgb(var(--ring-pinned-shadow-components)); /* #737577 */\\n  --ring-button-danger-hover-components: var(--ring-icon-error-color);\\n  --ring-button-danger-hover-color: var(--ring-icon-error-color);\\n  --ring-button-primary-border-components: 0, 98, 178;\\n  --ring-button-primary-border-color: rgb(var(--ring-button-primary-border-components)); /* #0062b2 */\\n  --ring-popup-shadow: 0 2px 8px var(--ring-popup-shadow-color), 0 1px 2px var(--ring-popup-secondary-shadow-color);\\n  --ring-dialog-shadow: 0 4px 24px var(--ring-popup-shadow-color), 0 2px 6px var(--ring-popup-secondary-shadow-color);\\n\\n  /* Text */\\n  --ring-search-components: 102, 158, 204;\\n  --ring-search-color: rgb(var(--ring-search-components)); /* #669ecc */\\n  --ring-hint-components: 64, 99, 128;\\n  --ring-hint-color: rgb(var(--ring-hint-components)); /* #406380 */\\n  --ring-link-components: 15, 91, 153;\\n  --ring-link-color: rgb(var(--ring-link-components)); /* #0f5b99 */\\n  --ring-link-hover-components: 255, 0, 140;\\n  --ring-link-hover-color: rgb(var(--ring-link-hover-components)); /* #ff008c */\\n  --ring-error-components: 169, 15, 26;\\n  --ring-error-color: rgb(var(--ring-error-components)); /* #a90f1a */\\n  --ring-warning-components: 178, 92, 0;\\n  --ring-warning-color: rgb(var(--ring-warning-components)); /* #b25c00 */\\n  --ring-success-components: 12, 117, 35;\\n  --ring-success-color: rgb(var(--ring-success-components)); /* #0c7523 */\\n  --ring-text-components: 31, 35, 38;\\n  --ring-text-color: rgb(var(--ring-text-components)); /* #1f2326 */\\n  --ring-active-text-color: var(--ring-text-color);\\n  --ring-white-text-components: 255, 255, 255;\\n  --ring-white-text-color: rgb(var(--ring-white-text-components)); /* #fff */\\n  --ring-heading-color: var(--ring-text-color);\\n  --ring-secondary-components: 115, 117, 119;\\n  --ring-secondary-color: rgb(var(--ring-secondary-components)); /* #737577 */\\n  --ring-disabled-components: 153, 153, 153;\\n  --ring-disabled-color: rgb(var(--ring-disabled-components)); /* #999 */\\n\\n  /* Background */\\n  --ring-content-background-components: 255, 255, 255;\\n  --ring-content-background-color: rgb(var(--ring-content-background-components)); /* #fff */\\n  --ring-popup-background-components: 255, 255, 255;\\n  --ring-popup-background-color: rgb(var(--ring-popup-background-components)); /* #fff */\\n  --ring-sidebar-background-components: 247, 249, 250;\\n  --ring-sidebar-background-color: rgb(var(--ring-sidebar-background-components)); /* #f7f9fa */\\n  --ring-selected-background-components: 212, 237, 255;\\n  --ring-selected-background-color: rgb(var(--ring-selected-background-components)); /* #d4edff */\\n  --ring-hover-background-components: 235, 246, 255;\\n  --ring-hover-background-color: rgb(var(--ring-hover-background-components)); /* #ebf6ff */\\n  --ring-navigation-background-components: 255, 255, 255;\\n  --ring-navigation-background-color: rgb(var(--ring-navigation-background-components)); /* #fff */\\n  --ring-tag-background-components: 230, 236, 242;\\n  --ring-tag-background-color: rgb(var(--ring-tag-background-components)); /* #e6ecf2 */\\n  --ring-tag-hover-background-components: 211, 218, 224;\\n  --ring-tag-hover-background-color: rgb(var(--ring-tag-hover-background-components)); /* #d3dae0 */\\n  --ring-removed-background-components: 255, 213, 203;\\n  --ring-removed-background-color: rgb(var(--ring-removed-background-components)); /* #ffd5cb */\\n  --ring-warning-background-components: 250, 236, 205;\\n  --ring-warning-background-color: rgb(var(--ring-warning-background-components)); /* #faeccd */\\n  --ring-added-background-components: 216, 240, 216;\\n  --ring-added-background-color: rgb(var(--ring-added-background-components)); /* #d8f0d8 */\\n  --ring-disabled-background-components: 245, 245, 245;\\n  --ring-disabled-background-color: rgb(var(--ring-disabled-background-components)); /* #f5f5f5 */\\n  --ring-disabled-selected-background-components: 232, 232, 232;\\n  --ring-disabled-selected-background-color: rgb(var(--ring-disabled-selected-background-components)); /* #e8e8e8 */\\n  --ring-button-danger-active-components: 255, 231, 232;\\n  --ring-button-danger-active-color: rgb(var(--ring-button-danger-active-components)); /* #ffe7e8 */\\n  --ring-button-loader-background-components: 51, 163, 255;\\n  --ring-button-loader-background: rgb(var(--ring-button-loader-background-components)); /* #33a3ff */\\n  --ring-button-primary-background-components: 26, 152, 255;\\n  --ring-button-primary-background-color: rgb(var(--ring-button-primary-background-components)); /* #1a98ff */\\n  --ring-table-loader-background-color: rgba(var(--ring-content-background-components), 0.5); /* #ffffff80 */\\n\\n  /* Code */\\n  --ring-code-background-color: var(--ring-content-background-color);\\n  --ring-code-components: 0, 0, 0;\\n  --ring-code-color: rgb(var(--ring-code-components)); /* #000 */\\n  --ring-code-comment-components: 112, 112, 112;\\n  --ring-code-comment-color: rgb(var(--ring-code-comment-components)); /* #707070 */\\n  --ring-code-meta-components: 112, 112, 112;\\n  --ring-code-meta-color: rgb(var(--ring-code-meta-components)); /* #707070 */\\n  --ring-code-keyword-components: 0, 0, 128;\\n  --ring-code-keyword-color: rgb(var(--ring-code-keyword-components)); /* #000080 */\\n  --ring-code-tag-background-components: 239, 239, 239;\\n  --ring-code-tag-background-color: rgb(var(--ring-code-tag-background-components)); /* #efefef */\\n  --ring-code-tag-color: var(--ring-code-keyword-color);\\n  --ring-code-tag-font-weight: bold;\\n  --ring-code-field-components: 102, 14, 122;\\n  --ring-code-field-color: rgb(var(--ring-code-field-components)); /* #660e7a */\\n  --ring-code-attribute-components: 0, 0, 255;\\n  --ring-code-attribute-color: rgb(var(--ring-code-attribute-components)); /* #00f */\\n  --ring-code-number-color: var(--ring-code-attribute-color);\\n  --ring-code-string-components: 0, 122, 0;\\n  --ring-code-string-color: rgb(var(--ring-code-string-components)); /* #007a00 */\\n  --ring-code-addition-components: 170, 222, 170;\\n  --ring-code-addition-color: rgb(var(--ring-code-addition-components)); /* #aadeaa */\\n  --ring-code-deletion-components: 200, 200, 200;\\n  --ring-code-deletion-color: rgb(var(--ring-code-deletion-components)); /* #c8c8c8 */\\n\\n  /* Metrics */\\n  --ring-border-radius: 4px;\\n  --ring-border-radius-small: 2px;\\n  --ring-font-size-larger: 15px;\\n  --ring-font-size: 14px;\\n  --ring-font-size-smaller: 12px;\\n  --ring-line-height-taller: 21px;\\n  --ring-line-height: 20px;\\n  --ring-line-height-lower: 18px;\\n  --ring-line-height-lowest: 16px;\\n  --ring-ease: 0.3s ease-out;\\n  --ring-fast-ease: 0.15s ease-out;\\n  --ring-font-family: system-ui, -apple-system, Segoe UI, Roboto, Noto Sans, Ubuntu, Cantarell, Helvetica Neue, Arial, sans-serif;\\n  --ring-font-family-monospace:\\n    Menlo,\\n    \"Bitstream Vera Sans Mono\",\\n    \"Ubuntu Mono\",\\n    Consolas,\\n    \"Courier New\",\\n    Courier,\\n    monospace;\\n\\n  /* Common z-index-values */\\n\\n  /* Invisible element is an absolutely positioned element which should be below */\\n  /* all other elements on the page */\\n  --ring-invisible-element-z-index: -1;\\n\\n  /* z-index for position: fixed elements */\\n  --ring-fixed-z-index: 1;\\n\\n  /* Elements that should overlay all other elements on the page */\\n  --ring-overlay-z-index: 5;\\n\\n  /* Alerts should de displayed above overlays */\\n  --ring-alert-z-index: 6;\\n}\\n',\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/global/variables.css\"],names:[],mappings:\"AAAA,mCAAmC;;AAEnC;;EAEE,gBAAgB;;EAEhB,YAAY;EACZ,qCAAqC;EACrC,mDAAmD,EAAE,YAAY;EACjE,wCAAwC;EACxC,yDAAyD,EAAE,YAAY;EACvE,qCAAqC;EACrC,mDAAmD,EAAE,YAAY;EACjE,+CAA+C;EAC/C,uEAAuE,EAAE,SAAS;EAClF,gDAAgD;EAChD,yEAAyE,EAAE,YAAY;EACvF,yDAAyD;EACzD,2FAA2F,EAAE,YAAY;EACzG,2DAA2D;EAC3D,+FAA+F,EAAE,YAAY,EAAE,uBAAuB;EACtI,8CAA8C;EAC9C,qEAAqE,EAAE,YAAY;EACnF,6CAA6C;EAC7C,mEAAmE,EAAE,YAAY;EACjF,0DAA0D;EAC1D,qDAAqD;EACrD,mCAAmC;EACnC,mDAAmD,EAAE,YAAY;EACjE,0DAA0D;EAC1D,0DAA0D,EAAE,YAAY;EACxE,yCAAyC;EACzC,+DAA+D,EAAE,YAAY;EAC7E,yCAAyC;EACzC,+DAA+D,EAAE,YAAY;EAC7E,2CAA2C;EAC3C,mEAAmE,EAAE,YAAY;EACjF,4CAA4C;EAC5C,mEAAmE,EAAE,YAAY;EACjF,6CAA6C;EAC7C,mEAAmE,EAAE,YAAY;EACjF,yCAAyC;EACzC,iDAAiD;EACjD,8EAA8E;EAC9E,yEAAyE;EACzE,oFAAoF;EACpF,2EAA2E;EAC3E,8CAA8C;EAC9C,qEAAqE,EAAE,YAAY;EACnF,mEAAmE;EACnE,8DAA8D;EAC9D,mDAAmD;EACnD,qFAAqF,EAAE,YAAY;EACnG,iHAAiH;EACjH,mHAAmH;;EAEnH,SAAS;EACT,uCAAuC;EACvC,uDAAuD,EAAE,YAAY;EACrE,mCAAmC;EACnC,mDAAmD,EAAE,YAAY;EACjE,mCAAmC;EACnC,mDAAmD,EAAE,YAAY;EACjE,yCAAyC;EACzC,+DAA+D,EAAE,YAAY;EAC7E,oCAAoC;EACpC,qDAAqD,EAAE,YAAY;EACnE,qCAAqC;EACrC,yDAAyD,EAAE,YAAY;EACvE,sCAAsC;EACtC,yDAAyD,EAAE,YAAY;EACvE,kCAAkC;EAClC,mDAAmD,EAAE,YAAY;EACjE,gDAAgD;EAChD,2CAA2C;EAC3C,+DAA+D,EAAE,SAAS;EAC1E,4CAA4C;EAC5C,0CAA0C;EAC1C,6DAA6D,EAAE,YAAY;EAC3E,yCAAyC;EACzC,2DAA2D,EAAE,SAAS;;EAEtE,eAAe;EACf,mDAAmD;EACnD,+EAA+E,EAAE,SAAS;EAC1F,iDAAiD;EACjD,2EAA2E,EAAE,SAAS;EACtF,mDAAmD;EACnD,+EAA+E,EAAE,YAAY;EAC7F,oDAAoD;EACpD,iFAAiF,EAAE,YAAY;EAC/F,iDAAiD;EACjD,2EAA2E,EAAE,YAAY;EACzF,sDAAsD;EACtD,qFAAqF,EAAE,SAAS;EAChG,+CAA+C;EAC/C,uEAAuE,EAAE,YAAY;EACrF,qDAAqD;EACrD,mFAAmF,EAAE,YAAY;EACjG,mDAAmD;EACnD,+EAA+E,EAAE,YAAY;EAC7F,mDAAmD;EACnD,+EAA+E,EAAE,YAAY;EAC7F,iDAAiD;EACjD,2EAA2E,EAAE,YAAY;EACzF,oDAAoD;EACpD,iFAAiF,EAAE,YAAY;EAC/F,6DAA6D;EAC7D,mGAAmG,EAAE,YAAY;EACjH,qDAAqD;EACrD,mFAAmF,EAAE,YAAY;EACjG,wDAAwD;EACxD,qFAAqF,EAAE,YAAY;EACnG,yDAAyD;EACzD,6FAA6F,EAAE,YAAY;EAC3G,0FAA0F,EAAE,cAAc;;EAE1G,SAAS;EACT,kEAAkE;EAClE,+BAA+B;EAC/B,mDAAmD,EAAE,SAAS;EAC9D,6CAA6C;EAC7C,mEAAmE,EAAE,YAAY;EACjF,0CAA0C;EAC1C,6DAA6D,EAAE,YAAY;EAC3E,yCAAyC;EACzC,mEAAmE,EAAE,YAAY;EACjF,oDAAoD;EACpD,iFAAiF,EAAE,YAAY;EAC/F,qDAAqD;EACrD,iCAAiC;EACjC,0CAA0C;EAC1C,+DAA+D,EAAE,YAAY;EAC7E,2CAA2C;EAC3C,uEAAuE,EAAE,SAAS;EAClF,0DAA0D;EAC1D,wCAAwC;EACxC,iEAAiE,EAAE,YAAY;EAC/E,8CAA8C;EAC9C,qEAAqE,EAAE,YAAY;EACnF,8CAA8C;EAC9C,qEAAqE,EAAE,YAAY;;EAEnF,YAAY;EACZ,yBAAyB;EACzB,+BAA+B;EAC/B,6BAA6B;EAC7B,sBAAsB;EACtB,8BAA8B;EAC9B,+BAA+B;EAC/B,wBAAwB;EACxB,8BAA8B;EAC9B,+BAA+B;EAC/B,0BAA0B;EAC1B,gCAAgC;EAChC,+HAAgD;EAChD;;;;;;;aAOW;;EAEX,0BAA0B;;EAE1B,gFAAgF;EAChF,mCAAmC;EACnC,oCAAoC;;EAEpC,yCAAyC;EACzC,uBAAuB;;EAEvB,gEAAgE;EAChE,yBAAyB;;EAEzB,8CAA8C;EAC9C,uBAAuB;AACzB\",sourcesContent:['/* stylelint-disable color-no-hex */\\n\\n.light,\\n:root {\\n  --ring-unit: 8px;\\n\\n  /* Element */\\n  --ring-line-components: 223, 229, 235;\\n  --ring-line-color: rgb(var(--ring-line-components)); /* #dfe5eb */\\n  --ring-borders-components: 197, 209, 219;\\n  --ring-borders-color: rgb(var(--ring-borders-components)); /* #c5d1db */\\n  --ring-icon-components: 184, 209, 229;\\n  --ring-icon-color: rgb(var(--ring-icon-components)); /* #b8d1e5 */\\n  --ring-icon-secondary-components: 153, 153, 153;\\n  --ring-icon-secondary-color: rgb(var(--ring-icon-secondary-components)); /* #999 */\\n  --ring-border-disabled-components: 232, 232, 232;\\n  --ring-border-disabled-color: rgb(var(--ring-border-disabled-components)); /* #e8e8e8 */\\n  --ring-border-selected-disabled-components: 212, 212, 212;\\n  --ring-border-selected-disabled-color: rgb(var(--ring-border-selected-disabled-components)); /* #d4d4d4 */\\n  --ring-border-unselected-disabled-components: 232, 232, 232;\\n  --ring-border-unselected-disabled-color: rgb(var(--ring-border-unselected-disabled-components)); /* #e8e8e8 */ /* TODO remove in 6.0 */\\n  --ring-icon-disabled-components: 212, 212, 212;\\n  --ring-icon-disabled-color: rgb(var(--ring-icon-disabled-components)); /* #d4d4d4 */\\n  --ring-border-hover-components: 128, 198, 255;\\n  --ring-border-hover-color: rgb(var(--ring-border-hover-components)); /* #80c6ff */\\n  --ring-icon-hover-components: var(--ring-link-hover-color);\\n  --ring-icon-hover-color: var(--ring-link-hover-color);\\n  --ring-main-components: 0, 128, 229;\\n  --ring-main-color: rgb(var(--ring-main-components)); /* #0080e5 */\\n  --ring-action-link-components: var(--ring-main-components);\\n  --ring-action-link-color: rgb(var(--ring-main-components)); /* #0080e5 */\\n  --ring-main-hover-components: 0, 112, 204;\\n  --ring-main-hover-color: rgb(var(--ring-main-hover-components)); /* #0070cc */\\n  --ring-icon-error-components: 219, 88, 96;\\n  --ring-icon-error-color: rgb(var(--ring-icon-error-components)); /* #db5860 */\\n  --ring-icon-warning-components: 237, 162, 0;\\n  --ring-icon-warning-color: rgb(var(--ring-icon-warning-components)); /* #eda200 */\\n  --ring-icon-success-components: 89, 168, 105;\\n  --ring-icon-success-color: rgb(var(--ring-icon-success-components)); /* #59a869 */\\n  --ring-pale-control-components: 207, 219, 229;\\n  --ring-pale-control-color: rgb(var(--ring-pale-control-components)); /* #cfdbe5 */\\n  --ring-popup-border-components: 0, 28, 54;\\n  --ring-popup-border-color: var(--ring-line-color);\\n  --ring-popup-shadow-components: rgba(var(--ring-popup-border-components), 0.1);\\n  --ring-popup-shadow-color: rgba(var(--ring-popup-border-components), 0.1);\\n  --ring-popup-secondary-shadow-color: rgba(var(--ring-popup-border-components), 0.04);\\n  --ring-message-shadow-color: rgba(var(--ring-popup-border-components), 0.3);\\n  --ring-pinned-shadow-components: 115, 117, 119;\\n  --ring-pinned-shadow-color: rgb(var(--ring-pinned-shadow-components)); /* #737577 */\\n  --ring-button-danger-hover-components: var(--ring-icon-error-color);\\n  --ring-button-danger-hover-color: var(--ring-icon-error-color);\\n  --ring-button-primary-border-components: 0, 98, 178;\\n  --ring-button-primary-border-color: rgb(var(--ring-button-primary-border-components)); /* #0062b2 */\\n  --ring-popup-shadow: 0 2px 8px var(--ring-popup-shadow-color), 0 1px 2px var(--ring-popup-secondary-shadow-color);\\n  --ring-dialog-shadow: 0 4px 24px var(--ring-popup-shadow-color), 0 2px 6px var(--ring-popup-secondary-shadow-color);\\n\\n  /* Text */\\n  --ring-search-components: 102, 158, 204;\\n  --ring-search-color: rgb(var(--ring-search-components)); /* #669ecc */\\n  --ring-hint-components: 64, 99, 128;\\n  --ring-hint-color: rgb(var(--ring-hint-components)); /* #406380 */\\n  --ring-link-components: 15, 91, 153;\\n  --ring-link-color: rgb(var(--ring-link-components)); /* #0f5b99 */\\n  --ring-link-hover-components: 255, 0, 140;\\n  --ring-link-hover-color: rgb(var(--ring-link-hover-components)); /* #ff008c */\\n  --ring-error-components: 169, 15, 26;\\n  --ring-error-color: rgb(var(--ring-error-components)); /* #a90f1a */\\n  --ring-warning-components: 178, 92, 0;\\n  --ring-warning-color: rgb(var(--ring-warning-components)); /* #b25c00 */\\n  --ring-success-components: 12, 117, 35;\\n  --ring-success-color: rgb(var(--ring-success-components)); /* #0c7523 */\\n  --ring-text-components: 31, 35, 38;\\n  --ring-text-color: rgb(var(--ring-text-components)); /* #1f2326 */\\n  --ring-active-text-color: var(--ring-text-color);\\n  --ring-white-text-components: 255, 255, 255;\\n  --ring-white-text-color: rgb(var(--ring-white-text-components)); /* #fff */\\n  --ring-heading-color: var(--ring-text-color);\\n  --ring-secondary-components: 115, 117, 119;\\n  --ring-secondary-color: rgb(var(--ring-secondary-components)); /* #737577 */\\n  --ring-disabled-components: 153, 153, 153;\\n  --ring-disabled-color: rgb(var(--ring-disabled-components)); /* #999 */\\n\\n  /* Background */\\n  --ring-content-background-components: 255, 255, 255;\\n  --ring-content-background-color: rgb(var(--ring-content-background-components)); /* #fff */\\n  --ring-popup-background-components: 255, 255, 255;\\n  --ring-popup-background-color: rgb(var(--ring-popup-background-components)); /* #fff */\\n  --ring-sidebar-background-components: 247, 249, 250;\\n  --ring-sidebar-background-color: rgb(var(--ring-sidebar-background-components)); /* #f7f9fa */\\n  --ring-selected-background-components: 212, 237, 255;\\n  --ring-selected-background-color: rgb(var(--ring-selected-background-components)); /* #d4edff */\\n  --ring-hover-background-components: 235, 246, 255;\\n  --ring-hover-background-color: rgb(var(--ring-hover-background-components)); /* #ebf6ff */\\n  --ring-navigation-background-components: 255, 255, 255;\\n  --ring-navigation-background-color: rgb(var(--ring-navigation-background-components)); /* #fff */\\n  --ring-tag-background-components: 230, 236, 242;\\n  --ring-tag-background-color: rgb(var(--ring-tag-background-components)); /* #e6ecf2 */\\n  --ring-tag-hover-background-components: 211, 218, 224;\\n  --ring-tag-hover-background-color: rgb(var(--ring-tag-hover-background-components)); /* #d3dae0 */\\n  --ring-removed-background-components: 255, 213, 203;\\n  --ring-removed-background-color: rgb(var(--ring-removed-background-components)); /* #ffd5cb */\\n  --ring-warning-background-components: 250, 236, 205;\\n  --ring-warning-background-color: rgb(var(--ring-warning-background-components)); /* #faeccd */\\n  --ring-added-background-components: 216, 240, 216;\\n  --ring-added-background-color: rgb(var(--ring-added-background-components)); /* #d8f0d8 */\\n  --ring-disabled-background-components: 245, 245, 245;\\n  --ring-disabled-background-color: rgb(var(--ring-disabled-background-components)); /* #f5f5f5 */\\n  --ring-disabled-selected-background-components: 232, 232, 232;\\n  --ring-disabled-selected-background-color: rgb(var(--ring-disabled-selected-background-components)); /* #e8e8e8 */\\n  --ring-button-danger-active-components: 255, 231, 232;\\n  --ring-button-danger-active-color: rgb(var(--ring-button-danger-active-components)); /* #ffe7e8 */\\n  --ring-button-loader-background-components: 51, 163, 255;\\n  --ring-button-loader-background: rgb(var(--ring-button-loader-background-components)); /* #33a3ff */\\n  --ring-button-primary-background-components: 26, 152, 255;\\n  --ring-button-primary-background-color: rgb(var(--ring-button-primary-background-components)); /* #1a98ff */\\n  --ring-table-loader-background-color: rgba(var(--ring-content-background-components), 0.5); /* #ffffff80 */\\n\\n  /* Code */\\n  --ring-code-background-color: var(--ring-content-background-color);\\n  --ring-code-components: 0, 0, 0;\\n  --ring-code-color: rgb(var(--ring-code-components)); /* #000 */\\n  --ring-code-comment-components: 112, 112, 112;\\n  --ring-code-comment-color: rgb(var(--ring-code-comment-components)); /* #707070 */\\n  --ring-code-meta-components: 112, 112, 112;\\n  --ring-code-meta-color: rgb(var(--ring-code-meta-components)); /* #707070 */\\n  --ring-code-keyword-components: 0, 0, 128;\\n  --ring-code-keyword-color: rgb(var(--ring-code-keyword-components)); /* #000080 */\\n  --ring-code-tag-background-components: 239, 239, 239;\\n  --ring-code-tag-background-color: rgb(var(--ring-code-tag-background-components)); /* #efefef */\\n  --ring-code-tag-color: var(--ring-code-keyword-color);\\n  --ring-code-tag-font-weight: bold;\\n  --ring-code-field-components: 102, 14, 122;\\n  --ring-code-field-color: rgb(var(--ring-code-field-components)); /* #660e7a */\\n  --ring-code-attribute-components: 0, 0, 255;\\n  --ring-code-attribute-color: rgb(var(--ring-code-attribute-components)); /* #00f */\\n  --ring-code-number-color: var(--ring-code-attribute-color);\\n  --ring-code-string-components: 0, 122, 0;\\n  --ring-code-string-color: rgb(var(--ring-code-string-components)); /* #007a00 */\\n  --ring-code-addition-components: 170, 222, 170;\\n  --ring-code-addition-color: rgb(var(--ring-code-addition-components)); /* #aadeaa */\\n  --ring-code-deletion-components: 200, 200, 200;\\n  --ring-code-deletion-color: rgb(var(--ring-code-deletion-components)); /* #c8c8c8 */\\n\\n  /* Metrics */\\n  --ring-border-radius: 4px;\\n  --ring-border-radius-small: 2px;\\n  --ring-font-size-larger: 15px;\\n  --ring-font-size: 14px;\\n  --ring-font-size-smaller: 12px;\\n  --ring-line-height-taller: 21px;\\n  --ring-line-height: 20px;\\n  --ring-line-height-lower: 18px;\\n  --ring-line-height-lowest: 16px;\\n  --ring-ease: 0.3s ease-out;\\n  --ring-fast-ease: 0.15s ease-out;\\n  --ring-font-family: system-ui, Arial, sans-serif;\\n  --ring-font-family-monospace:\\n    Menlo,\\n    \"Bitstream Vera Sans Mono\",\\n    \"Ubuntu Mono\",\\n    Consolas,\\n    \"Courier New\",\\n    Courier,\\n    monospace;\\n\\n  /* Common z-index-values */\\n\\n  /* Invisible element is an absolutely positioned element which should be below */\\n  /* all other elements on the page */\\n  --ring-invisible-element-z-index: -1;\\n\\n  /* z-index for position: fixed elements */\\n  --ring-fixed-z-index: 1;\\n\\n  /* Elements that should overlay all other elements on the page */\\n  --ring-overlay-z-index: 5;\\n\\n  /* Alerts should de displayed above overlays */\\n  --ring-alert-z-index: 6;\\n}\\n'],sourceRoot:\"\"}]),a.locals={light:\"light_f331\"};const l=a},9173:(e,n,t)=>{\"use strict\";t.d(n,{A:()=>l});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i)()(o());a.push([e.id,\"/* stylelint-disable color-no-hex */\\n\\n.ring-ui-theme-dark,\\n.dark_d4a9,\\n:root.dark_d4a9 {\\n  --ring-line-components: 71, 81, 89;\\n  --ring-line-color: rgb(var(--ring-line-components)); /* #475159 */\\n  --ring-borders-components: 64, 99, 128;\\n  --ring-borders-color: rgb(var(--ring-borders-components)); /* #406380 */\\n  --ring-icon-components: 128, 146, 157;\\n  --ring-icon-color: rgb(var(--ring-icon-components)); /* #80929d */\\n  --ring-icon-secondary-components: 128, 146, 157;\\n  --ring-icon-secondary-color: rgb(var(--ring-icon-secondary-components)); /* #80929d */\\n  --ring-border-disabled-components: 54, 54, 54;\\n  --ring-border-disabled-color: rgb(var(--ring-border-disabled-components)); /* #363636 */\\n  --ring-border-selected-disabled-components: 54, 54, 54;\\n  --ring-border-selected-disabled-color: rgb(var(--ring-border-selected-disabled-components)); /* #363636 */\\n  --ring-border-unselected-disabled-components: 54, 54, 54;\\n  --ring-border-unselected-disabled-color: rgb(var(--ring-border-unselected-disabled-components)); /* #363636 */ /* TODO remove in 6.0 */\\n  --ring-icon-disabled-components: 80, 82, 83;\\n  --ring-icon-disabled-color: rgb(var(--ring-icon-disabled-components)); /* #505253 */\\n  --ring-border-hover-components: 112, 177, 230;\\n  --ring-border-hover-color: rgb(var(--ring-border-hover-components)); /* #70b1e6 */\\n  --ring-main-components: 0, 142, 255;\\n  --ring-main-color: rgb(var(--ring-main-components)); /* #008eff */\\n  --ring-action-link-components: var(--ring-main-components);\\n  --ring-action-link-color: rgb(var(--ring-main-components)); /* #008eff */\\n  --ring-main-hover-components: 0, 126, 229;\\n  --ring-main-hover-color: rgb(var(--ring-main-hover-components)); /* #007ee5 */\\n  --ring-icon-error-components: 219, 88, 96;\\n  --ring-icon-error-color: rgb(var(--ring-icon-error-components)); /* #db5860 */\\n  --ring-icon-warning-components: 237, 162, 0;\\n  --ring-icon-warning-color: rgb(var(--ring-icon-warning-components)); /* #eda200 */\\n  --ring-icon-success-components: 71, 212, 100;\\n  --ring-icon-success-color: rgb(var(--ring-icon-success-components)); /* #47d464 */\\n  --ring-popup-border-components: 0, 42, 76;\\n  --ring-popup-border-color: rgba(var(--ring-popup-border-components), 0.1);\\n  --ring-popup-shadow-color: rgba(var(--ring-popup-border-components), 0.15);\\n  --ring-message-shadow-color: rgba(var(--ring-popup-border-components), 0.3);\\n  --ring-pinned-shadow-components: 0, 0, 0;\\n  --ring-pinned-shadow-color: rgb(var(--ring-pinned-shadow-components)); /* #000 */\\n  --ring-button-danger-hover-color: var(--ring-error-color);\\n  --ring-button-primary-border-components: 128, 198, 255;\\n  --ring-button-primary-border-color: rgb(var(--ring-button-primary-border-components)); /* #80c6ff */\\n\\n  /* Text */\\n  --ring-hint-components: 128, 146, 157;\\n  --ring-hint-color: rgb(var(--ring-hint-components)); /* #80929d */\\n  --ring-link-components: 112, 177, 230;\\n  --ring-link-color: rgb(var(--ring-link-components)); /* #70b1e6 */\\n  --ring-error-components: 219, 88, 96;\\n  --ring-error-color: rgb(var(--ring-error-components)); /* #db5860 */\\n  --ring-warning-components: 237, 162, 0;\\n  --ring-warning-color: rgb(var(--ring-warning-components)); /* #eda200 */\\n  --ring-success-components: 71, 212, 100;\\n  --ring-success-color: rgb(var(--ring-success-components)); /* #47d464 */\\n  --ring-text-components: 187, 187, 187;\\n  --ring-text-color: rgb(var(--ring-text-components)); /* #bbb */\\n  --ring-active-text-components: 255, 255, 255;\\n  --ring-active-text-color: rgb(var(--ring-active-text-components)); /* #fff */\\n  --ring-heading-color: var(--ring-text-color);\\n  --ring-secondary-components: 128, 146, 157;\\n  --ring-secondary-color: rgb(var(--ring-secondary-components)); /* #80929d */\\n  --ring-disabled-components: 81, 95, 104;\\n  --ring-disabled-color: rgb(var(--ring-disabled-components)); /* #515F68 */\\n\\n  /* Background */\\n  --ring-content-background-components: 35, 39, 43;\\n  --ring-content-background-color: rgb(var(--ring-content-background-components)); /* #23272b */\\n  --ring-popup-background-components: 17, 19, 20;\\n  --ring-popup-background-color: rgb(var(--ring-popup-background-components)); /* #111314 */\\n  --ring-sidebar-background-components: 40, 52, 61;\\n  --ring-sidebar-background-color: rgb(var(--ring-sidebar-background-components)); /* #28343d */\\n  --ring-selected-background-components: 6, 38, 64;\\n  --ring-selected-background-color: rgb(var(--ring-selected-background-components)); /* #062640 */\\n  --ring-hover-background-components: 11, 26, 38;\\n  --ring-hover-background-color: rgb(var(--ring-hover-background-components)); /* #0b1a26 */\\n  --ring-navigation-background-components: 17, 19, 20;\\n  --ring-navigation-background-color: rgb(var(--ring-navigation-background-components)); /* #111314 */\\n  --ring-tag-background-components: 62, 77, 89;\\n  --ring-tag-background-color: rgb(var(--ring-tag-background-components)); /* #3e4d59 */\\n  --ring-tag-hover-background-components: 51, 62, 71;\\n  --ring-tag-hover-background-color: rgb(var(--ring-tag-hover-background-components)); /* #333e47 */\\n  --ring-removed-background-components: 143, 82, 71;\\n  --ring-removed-background-color: rgb(var(--ring-removed-background-components)); /* #8f5247 */\\n  --ring-warning-background-components: 89, 61, 1;\\n  --ring-warning-background-color: rgb(var(--ring-warning-background-components)); /* #593d01 */\\n  --ring-added-background-components: 54, 89, 71;\\n  --ring-added-background-color: rgb(var(--ring-added-background-components)); /* #365947 */\\n  --ring-disabled-background-components: 44, 47, 51;\\n  --ring-disabled-background-color: rgb(var(--ring-disabled-background-components)); /* #2C2F33 */\\n  --ring-disabled-selected-background-components: 44, 47, 51;\\n  --ring-disabled-selected-background-color: rgb(var(--ring-disabled-selected-background-components)); /* #2C2F33 */\\n  --ring-button-danger-active-components: 38, 8, 10;\\n  --ring-button-danger-active-color: rgb(var(--ring-button-danger-active-components)); /* #26080a */\\n  --ring-button-primary-background-components: 0, 126, 229;\\n  --ring-button-primary-background-color: rgb(var(--ring-button-primary-background-components)); /* #007ee5 */\\n  --ring-table-loader-background-color: rgba(var(--ring-content-background-components), 0.5); /* #23272b80 */\\n\\n  /* Code */\\n  --ring-code-background-components: 43, 43, 43;\\n  --ring-code-background-color: rgb(var(--ring-code-background-components)); /* #2b2b2b */\\n  --ring-code-components: 169, 183, 198;\\n  --ring-code-color: rgb(var(--ring-code-components)); /* #a9b7c6 */\\n  --ring-code-meta-components: 187, 181, 41;\\n  --ring-code-meta-color: rgb(var(--ring-code-meta-components)); /* #bbb529 */\\n  --ring-code-keyword-components: 204, 120, 50;\\n  --ring-code-keyword-color: rgb(var(--ring-code-keyword-components)); /* #cc7832 */\\n  --ring-code-tag-background-components: 43, 43, 43;\\n  --ring-code-tag-background-color: rgb(var(--ring-code-tag-background-components)); /* #2b2b2b */\\n  --ring-code-tag-components: 232, 191, 106;\\n  --ring-code-tag-color: rgb(var(--ring-code-tag-components)); /* #e8bf6a */\\n  --ring-code-tag-font-weight: normal;\\n  --ring-code-field-components: 152, 118, 170;\\n  --ring-code-field-color: rgb(var(--ring-code-tag-font-weight)); /* #9876aa */\\n  --ring-code-attribute-components: 186, 186, 186;\\n  --ring-code-attribute-color: rgb(var(--ring-code-attribute-components)); /* #bababa */\\n  --ring-code-number-components: 104, 151, 187;\\n  --ring-code-number-color: rgb(var(--ring-code-number-components)); /* #6897bb */\\n  --ring-code-string-components: 106, 135, 89;\\n  --ring-code-string-color: rgb(var(--ring-code-string-components)); /* #6a8759 */\\n  --ring-code-addition-components: 68, 113, 82;\\n  --ring-code-addition-color: rgb(var(--ring-code-addition-components)); /* #447152 */\\n  --ring-code-deletion-components: 101, 110, 118;\\n  --ring-code-deletion-color: rgb(var(--ring-code-deletion-components)); /* #656e76 */\\n\\n  color-scheme: dark;\\n}\\n\",\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/global/variables_dark.css\"],names:[],mappings:\"AAAA,mCAAmC;;AAEnC;;;EAGE,kCAAkC;EAClC,mDAAmD,EAAE,YAAY;EACjE,sCAAsC;EACtC,yDAAyD,EAAE,YAAY;EACvE,qCAAqC;EACrC,mDAAmD,EAAE,YAAY;EACjE,+CAA+C;EAC/C,uEAAuE,EAAE,YAAY;EACrF,6CAA6C;EAC7C,yEAAyE,EAAE,YAAY;EACvF,sDAAsD;EACtD,2FAA2F,EAAE,YAAY;EACzG,wDAAwD;EACxD,+FAA+F,EAAE,YAAY,EAAE,uBAAuB;EACtI,2CAA2C;EAC3C,qEAAqE,EAAE,YAAY;EACnF,6CAA6C;EAC7C,mEAAmE,EAAE,YAAY;EACjF,mCAAmC;EACnC,mDAAmD,EAAE,YAAY;EACjE,0DAA0D;EAC1D,0DAA0D,EAAE,YAAY;EACxE,yCAAyC;EACzC,+DAA+D,EAAE,YAAY;EAC7E,yCAAyC;EACzC,+DAA+D,EAAE,YAAY;EAC7E,2CAA2C;EAC3C,mEAAmE,EAAE,YAAY;EACjF,4CAA4C;EAC5C,mEAAmE,EAAE,YAAY;EACjF,yCAAyC;EACzC,yEAAyE;EACzE,0EAA0E;EAC1E,2EAA2E;EAC3E,wCAAwC;EACxC,qEAAqE,EAAE,SAAS;EAChF,yDAAyD;EACzD,sDAAsD;EACtD,qFAAqF,EAAE,YAAY;;EAEnG,SAAS;EACT,qCAAqC;EACrC,mDAAmD,EAAE,YAAY;EACjE,qCAAqC;EACrC,mDAAmD,EAAE,YAAY;EACjE,oCAAoC;EACpC,qDAAqD,EAAE,YAAY;EACnE,sCAAsC;EACtC,yDAAyD,EAAE,YAAY;EACvE,uCAAuC;EACvC,yDAAyD,EAAE,YAAY;EACvE,qCAAqC;EACrC,mDAAmD,EAAE,SAAS;EAC9D,4CAA4C;EAC5C,iEAAiE,EAAE,SAAS;EAC5E,4CAA4C;EAC5C,0CAA0C;EAC1C,6DAA6D,EAAE,YAAY;EAC3E,uCAAuC;EACvC,2DAA2D,EAAE,YAAY;;EAEzE,eAAe;EACf,gDAAgD;EAChD,+EAA+E,EAAE,YAAY;EAC7F,8CAA8C;EAC9C,2EAA2E,EAAE,YAAY;EACzF,gDAAgD;EAChD,+EAA+E,EAAE,YAAY;EAC7F,gDAAgD;EAChD,iFAAiF,EAAE,YAAY;EAC/F,8CAA8C;EAC9C,2EAA2E,EAAE,YAAY;EACzF,mDAAmD;EACnD,qFAAqF,EAAE,YAAY;EACnG,4CAA4C;EAC5C,uEAAuE,EAAE,YAAY;EACrF,kDAAkD;EAClD,mFAAmF,EAAE,YAAY;EACjG,iDAAiD;EACjD,+EAA+E,EAAE,YAAY;EAC7F,+CAA+C;EAC/C,+EAA+E,EAAE,YAAY;EAC7F,8CAA8C;EAC9C,2EAA2E,EAAE,YAAY;EACzF,iDAAiD;EACjD,iFAAiF,EAAE,YAAY;EAC/F,0DAA0D;EAC1D,mGAAmG,EAAE,YAAY;EACjH,iDAAiD;EACjD,mFAAmF,EAAE,YAAY;EACjG,wDAAwD;EACxD,6FAA6F,EAAE,YAAY;EAC3G,0FAA0F,EAAE,cAAc;;EAE1G,SAAS;EACT,6CAA6C;EAC7C,yEAAyE,EAAE,YAAY;EACvF,qCAAqC;EACrC,mDAAmD,EAAE,YAAY;EACjE,yCAAyC;EACzC,6DAA6D,EAAE,YAAY;EAC3E,4CAA4C;EAC5C,mEAAmE,EAAE,YAAY;EACjF,iDAAiD;EACjD,iFAAiF,EAAE,YAAY;EAC/F,yCAAyC;EACzC,2DAA2D,EAAE,YAAY;EACzE,mCAAmC;EACnC,2CAA2C;EAC3C,8DAA8D,EAAE,YAAY;EAC5E,+CAA+C;EAC/C,uEAAuE,EAAE,YAAY;EACrF,4CAA4C;EAC5C,iEAAiE,EAAE,YAAY;EAC/E,2CAA2C;EAC3C,iEAAiE,EAAE,YAAY;EAC/E,4CAA4C;EAC5C,qEAAqE,EAAE,YAAY;EACnF,8CAA8C;EAC9C,qEAAqE,EAAE,YAAY;;EAEnF,kBAAkB;AACpB\",sourcesContent:[\"/* stylelint-disable color-no-hex */\\n\\n:global(.ring-ui-theme-dark),\\n.dark,\\n:root.dark {\\n  --ring-line-components: 71, 81, 89;\\n  --ring-line-color: rgb(var(--ring-line-components)); /* #475159 */\\n  --ring-borders-components: 64, 99, 128;\\n  --ring-borders-color: rgb(var(--ring-borders-components)); /* #406380 */\\n  --ring-icon-components: 128, 146, 157;\\n  --ring-icon-color: rgb(var(--ring-icon-components)); /* #80929d */\\n  --ring-icon-secondary-components: 128, 146, 157;\\n  --ring-icon-secondary-color: rgb(var(--ring-icon-secondary-components)); /* #80929d */\\n  --ring-border-disabled-components: 54, 54, 54;\\n  --ring-border-disabled-color: rgb(var(--ring-border-disabled-components)); /* #363636 */\\n  --ring-border-selected-disabled-components: 54, 54, 54;\\n  --ring-border-selected-disabled-color: rgb(var(--ring-border-selected-disabled-components)); /* #363636 */\\n  --ring-border-unselected-disabled-components: 54, 54, 54;\\n  --ring-border-unselected-disabled-color: rgb(var(--ring-border-unselected-disabled-components)); /* #363636 */ /* TODO remove in 6.0 */\\n  --ring-icon-disabled-components: 80, 82, 83;\\n  --ring-icon-disabled-color: rgb(var(--ring-icon-disabled-components)); /* #505253 */\\n  --ring-border-hover-components: 112, 177, 230;\\n  --ring-border-hover-color: rgb(var(--ring-border-hover-components)); /* #70b1e6 */\\n  --ring-main-components: 0, 142, 255;\\n  --ring-main-color: rgb(var(--ring-main-components)); /* #008eff */\\n  --ring-action-link-components: var(--ring-main-components);\\n  --ring-action-link-color: rgb(var(--ring-main-components)); /* #008eff */\\n  --ring-main-hover-components: 0, 126, 229;\\n  --ring-main-hover-color: rgb(var(--ring-main-hover-components)); /* #007ee5 */\\n  --ring-icon-error-components: 219, 88, 96;\\n  --ring-icon-error-color: rgb(var(--ring-icon-error-components)); /* #db5860 */\\n  --ring-icon-warning-components: 237, 162, 0;\\n  --ring-icon-warning-color: rgb(var(--ring-icon-warning-components)); /* #eda200 */\\n  --ring-icon-success-components: 71, 212, 100;\\n  --ring-icon-success-color: rgb(var(--ring-icon-success-components)); /* #47d464 */\\n  --ring-popup-border-components: 0, 42, 76;\\n  --ring-popup-border-color: rgba(var(--ring-popup-border-components), 0.1);\\n  --ring-popup-shadow-color: rgba(var(--ring-popup-border-components), 0.15);\\n  --ring-message-shadow-color: rgba(var(--ring-popup-border-components), 0.3);\\n  --ring-pinned-shadow-components: 0, 0, 0;\\n  --ring-pinned-shadow-color: rgb(var(--ring-pinned-shadow-components)); /* #000 */\\n  --ring-button-danger-hover-color: var(--ring-error-color);\\n  --ring-button-primary-border-components: 128, 198, 255;\\n  --ring-button-primary-border-color: rgb(var(--ring-button-primary-border-components)); /* #80c6ff */\\n\\n  /* Text */\\n  --ring-hint-components: 128, 146, 157;\\n  --ring-hint-color: rgb(var(--ring-hint-components)); /* #80929d */\\n  --ring-link-components: 112, 177, 230;\\n  --ring-link-color: rgb(var(--ring-link-components)); /* #70b1e6 */\\n  --ring-error-components: 219, 88, 96;\\n  --ring-error-color: rgb(var(--ring-error-components)); /* #db5860 */\\n  --ring-warning-components: 237, 162, 0;\\n  --ring-warning-color: rgb(var(--ring-warning-components)); /* #eda200 */\\n  --ring-success-components: 71, 212, 100;\\n  --ring-success-color: rgb(var(--ring-success-components)); /* #47d464 */\\n  --ring-text-components: 187, 187, 187;\\n  --ring-text-color: rgb(var(--ring-text-components)); /* #bbb */\\n  --ring-active-text-components: 255, 255, 255;\\n  --ring-active-text-color: rgb(var(--ring-active-text-components)); /* #fff */\\n  --ring-heading-color: var(--ring-text-color);\\n  --ring-secondary-components: 128, 146, 157;\\n  --ring-secondary-color: rgb(var(--ring-secondary-components)); /* #80929d */\\n  --ring-disabled-components: 81, 95, 104;\\n  --ring-disabled-color: rgb(var(--ring-disabled-components)); /* #515F68 */\\n\\n  /* Background */\\n  --ring-content-background-components: 35, 39, 43;\\n  --ring-content-background-color: rgb(var(--ring-content-background-components)); /* #23272b */\\n  --ring-popup-background-components: 17, 19, 20;\\n  --ring-popup-background-color: rgb(var(--ring-popup-background-components)); /* #111314 */\\n  --ring-sidebar-background-components: 40, 52, 61;\\n  --ring-sidebar-background-color: rgb(var(--ring-sidebar-background-components)); /* #28343d */\\n  --ring-selected-background-components: 6, 38, 64;\\n  --ring-selected-background-color: rgb(var(--ring-selected-background-components)); /* #062640 */\\n  --ring-hover-background-components: 11, 26, 38;\\n  --ring-hover-background-color: rgb(var(--ring-hover-background-components)); /* #0b1a26 */\\n  --ring-navigation-background-components: 17, 19, 20;\\n  --ring-navigation-background-color: rgb(var(--ring-navigation-background-components)); /* #111314 */\\n  --ring-tag-background-components: 62, 77, 89;\\n  --ring-tag-background-color: rgb(var(--ring-tag-background-components)); /* #3e4d59 */\\n  --ring-tag-hover-background-components: 51, 62, 71;\\n  --ring-tag-hover-background-color: rgb(var(--ring-tag-hover-background-components)); /* #333e47 */\\n  --ring-removed-background-components: 143, 82, 71;\\n  --ring-removed-background-color: rgb(var(--ring-removed-background-components)); /* #8f5247 */\\n  --ring-warning-background-components: 89, 61, 1;\\n  --ring-warning-background-color: rgb(var(--ring-warning-background-components)); /* #593d01 */\\n  --ring-added-background-components: 54, 89, 71;\\n  --ring-added-background-color: rgb(var(--ring-added-background-components)); /* #365947 */\\n  --ring-disabled-background-components: 44, 47, 51;\\n  --ring-disabled-background-color: rgb(var(--ring-disabled-background-components)); /* #2C2F33 */\\n  --ring-disabled-selected-background-components: 44, 47, 51;\\n  --ring-disabled-selected-background-color: rgb(var(--ring-disabled-selected-background-components)); /* #2C2F33 */\\n  --ring-button-danger-active-components: 38, 8, 10;\\n  --ring-button-danger-active-color: rgb(var(--ring-button-danger-active-components)); /* #26080a */\\n  --ring-button-primary-background-components: 0, 126, 229;\\n  --ring-button-primary-background-color: rgb(var(--ring-button-primary-background-components)); /* #007ee5 */\\n  --ring-table-loader-background-color: rgba(var(--ring-content-background-components), 0.5); /* #23272b80 */\\n\\n  /* Code */\\n  --ring-code-background-components: 43, 43, 43;\\n  --ring-code-background-color: rgb(var(--ring-code-background-components)); /* #2b2b2b */\\n  --ring-code-components: 169, 183, 198;\\n  --ring-code-color: rgb(var(--ring-code-components)); /* #a9b7c6 */\\n  --ring-code-meta-components: 187, 181, 41;\\n  --ring-code-meta-color: rgb(var(--ring-code-meta-components)); /* #bbb529 */\\n  --ring-code-keyword-components: 204, 120, 50;\\n  --ring-code-keyword-color: rgb(var(--ring-code-keyword-components)); /* #cc7832 */\\n  --ring-code-tag-background-components: 43, 43, 43;\\n  --ring-code-tag-background-color: rgb(var(--ring-code-tag-background-components)); /* #2b2b2b */\\n  --ring-code-tag-components: 232, 191, 106;\\n  --ring-code-tag-color: rgb(var(--ring-code-tag-components)); /* #e8bf6a */\\n  --ring-code-tag-font-weight: normal;\\n  --ring-code-field-components: 152, 118, 170;\\n  --ring-code-field-color: rgb(var(--ring-code-tag-font-weight)); /* #9876aa */\\n  --ring-code-attribute-components: 186, 186, 186;\\n  --ring-code-attribute-color: rgb(var(--ring-code-attribute-components)); /* #bababa */\\n  --ring-code-number-components: 104, 151, 187;\\n  --ring-code-number-color: rgb(var(--ring-code-number-components)); /* #6897bb */\\n  --ring-code-string-components: 106, 135, 89;\\n  --ring-code-string-color: rgb(var(--ring-code-string-components)); /* #6a8759 */\\n  --ring-code-addition-components: 68, 113, 82;\\n  --ring-code-addition-color: rgb(var(--ring-code-addition-components)); /* #447152 */\\n  --ring-code-deletion-components: 101, 110, 118;\\n  --ring-code-deletion-color: rgb(var(--ring-code-deletion-components)); /* #656e76 */\\n\\n  color-scheme: dark;\\n}\\n\"],sourceRoot:\"\"}]),a.locals={dark:\"dark_d4a9\"};const l=a},5066:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),s=a()(o());s.i(c.A),s.i(l.default,\"\",!0),s.push([e.id,'.icon_aaa7 {\\n  display: inline-block;\\n\\n  fill: currentColor;\\n}\\n\\n.glyph_f986 {\\n  display: inline-flex;\\n\\n  margin-right: -1px;\\n  margin-left: -1px;\\n\\n  pointer-events: none;\\n}\\n\\n.glyph_f986[width=\"10\"] {\\n    vertical-align: -1px;\\n  }\\n\\n.glyph_f986[width=\"14\"] {\\n    margin-right: -2px;\\n    margin-left: 0;\\n\\n    vertical-align: -3px;\\n  }\\n\\n.glyph_f986[width=\"16\"] {\\n    vertical-align: -3px;\\n  }\\n\\n.glyph_f986[width=\"20\"] {\\n    vertical-align: -2px;\\n  }\\n\\n.glyph_f986.compatibilityMode_d631 {\\n    width: 16px;\\n    height: 16px;\\n    margin-right: 0;\\n    margin-left: 0;\\n  }\\n\\n/* HACK: This media query hack makes styles applied for WebKit browsers only */\\n/* stylelint-disable-next-line media-feature-name-no-vendor-prefix */\\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\\n  .glyph_f986 {\\n    width: auto; /* Safari size bug workaround, see https://youtrack.jetbrains.com/issue/RG-1983 */\\n  }\\n}\\n\\n.gray_f6a8 {\\n  color: var(--ring-icon-secondary-color);\\n}\\n\\n.hover_fc27 {\\n  color: var(--ring-icon-hover-color);\\n}\\n\\n.green_bfb1 {\\n  color: var(--ring-icon-success-color);\\n}\\n\\n.magenta_b045 {\\n  color: var(--ring-link-hover-color);\\n}\\n\\n.red_a7ec {\\n  color: var(--ring-icon-error-color);\\n}\\n\\n.blue_ec1e {\\n  color: var(--ring-main-color);\\n}\\n\\n.white_c896 {\\n  color: var(--ring-white-text-color);\\n}\\n\\n.loading_c5e2 {\\n  animation-name: icon-loading_fe22;\\n  animation-duration: 1200ms;\\n  animation-iteration-count: infinite;\\n}\\n\\n@keyframes icon-loading_fe22 {\\n  0% {\\n    transform: scale(1);\\n  }\\n\\n  50% {\\n    transform: scale(0.9);\\n\\n    opacity: 0.5;\\n  }\\n\\n  100% {\\n    transform: scale(1);\\n  }\\n}\\n',\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/icon/icon.css\"],names:[],mappings:\"AAIA;EACE,qBAAqB;;EAErB,kBAAkB;AACpB;;AAEA;EACE,oBAAoB;;EAEpB,kBAAkB;EAClB,iBAAiB;;EAEjB,oBAAoB;AA2BtB;;AAzBE;IACE,oBAAoB;EACtB;;AAEA;IACE,kBAAkB;IAClB,cAAc;;IAEd,oBAAoB;EACtB;;AAEA;IACE,oBAAoB;EACtB;;AAEA;IACE,oBAAoB;EACtB;;AAEA;IACE,WAAqB;IACrB,YAAsB;IACtB,eAAe;IACf,cAAc;EAChB;;AAGF,8EAA8E;AAC9E,oEAAoE;AACpE;EACE;IACE,WAAW,EAAE,iFAAiF;EAChG;AACF;;AAEA;EACE,uCAAuC;AACzC;;AAEA;EACE,mCAAmC;AACrC;;AAEA;EACE,qCAAqC;AACvC;;AAEA;EACE,mCAAmC;AACrC;;AAEA;EACE,mCAAmC;AACrC;;AAEA;EACE,6BAA6B;AAC/B;;AAEA;EACE,mCAAmC;AACrC;;AAEA;EACE,iCAA4B;EAC5B,0BAA0B;EAC1B,mCAAmC;AACrC;;AAEA;EACE;IACE,mBAAmB;EACrB;;EAEA;IACE,qBAAqB;;IAErB,YAAY;EACd;;EAEA;IACE,mBAAmB;EACrB;AACF\",sourcesContent:['@import \"../global/variables.css\";\\n\\n@value unit from \"../global/global.css\";\\n\\n.icon {\\n  display: inline-block;\\n\\n  fill: currentColor;\\n}\\n\\n.glyph {\\n  display: inline-flex;\\n\\n  margin-right: -1px;\\n  margin-left: -1px;\\n\\n  pointer-events: none;\\n\\n  &[width=\"10\"] {\\n    vertical-align: -1px;\\n  }\\n\\n  &[width=\"14\"] {\\n    margin-right: -2px;\\n    margin-left: 0;\\n\\n    vertical-align: -3px;\\n  }\\n\\n  &[width=\"16\"] {\\n    vertical-align: -3px;\\n  }\\n\\n  &[width=\"20\"] {\\n    vertical-align: -2px;\\n  }\\n\\n  &.compatibilityMode {\\n    width: calc(unit * 2);\\n    height: calc(unit * 2);\\n    margin-right: 0;\\n    margin-left: 0;\\n  }\\n}\\n\\n/* HACK: This media query hack makes styles applied for WebKit browsers only */\\n/* stylelint-disable-next-line media-feature-name-no-vendor-prefix */\\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\\n  .glyph {\\n    width: auto; /* Safari size bug workaround, see https://youtrack.jetbrains.com/issue/RG-1983 */\\n  }\\n}\\n\\n.gray {\\n  color: var(--ring-icon-secondary-color);\\n}\\n\\n.hover {\\n  color: var(--ring-icon-hover-color);\\n}\\n\\n.green {\\n  color: var(--ring-icon-success-color);\\n}\\n\\n.magenta {\\n  color: var(--ring-link-hover-color);\\n}\\n\\n.red {\\n  color: var(--ring-icon-error-color);\\n}\\n\\n.blue {\\n  color: var(--ring-main-color);\\n}\\n\\n.white {\\n  color: var(--ring-white-text-color);\\n}\\n\\n.loading {\\n  animation-name: icon-loading;\\n  animation-duration: 1200ms;\\n  animation-iteration-count: infinite;\\n}\\n\\n@keyframes icon-loading {\\n  0% {\\n    transform: scale(1);\\n  }\\n\\n  50% {\\n    transform: scale(0.9);\\n\\n    opacity: 0.5;\\n  }\\n\\n  100% {\\n    transform: scale(1);\\n  }\\n}\\n'],sourceRoot:\"\"}]),s.locals={unit:`${l.default.locals.unit}`,icon:\"icon_aaa7\",glyph:\"glyph_f986\",compatibilityMode:\"compatibilityMode_d631\",gray:\"gray_f6a8\",hover:\"hover_fc27\",green:\"green_bfb1\",magenta:\"magenta_b045\",red:\"red_a7ec\",blue:\"blue_ec1e\",white:\"white_c896\",loading:\"loading_c5e2\",\"icon-loading\":\"icon-loading_fe22\"};const u=s},8976:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),s=a()(o());s.i(c.A),s.i(l.default,\"\",!0),s.push([e.id,\":root {\\n  --ring-input-xs: 96px;\\n  --ring-input-s: 96px;\\n  --ring-input-m: 240px;\\n  --ring-input-l: 400px;\\n}\\n\\n/**\\n * @name Input Sizes\\n */\\n\\n/* XS */\\n\\n.ring-input-size_xs.ring-input-size_xs {\\n  display: inline-block;\\n\\n  width: 96px;\\n\\n  width: var(--ring-input-xs);\\n}\\n\\n.ring-input-size_xs.ring-input-size_xs ~ .ring-error-bubble {\\n  left: 98px;\\n  left: calc(var(--ring-input-xs) + 2px);\\n}\\n\\n/* S */\\n\\n.ring-input-size_s.ring-input-size_s {\\n  display: inline-block;\\n\\n  width: 96px;\\n\\n  width: var(--ring-input-s);\\n}\\n\\n.ring-input-size_s.ring-input-size_s ~ .ring-error-bubble {\\n  left: 98px;\\n  left: calc(var(--ring-input-s) + 2px);\\n}\\n\\n/* M */\\n\\n.ring-input-size_m.ring-input-size_m {\\n  display: inline-block;\\n\\n  width: 240px;\\n\\n  width: var(--ring-input-m);\\n}\\n\\n.ring-input-size_m.ring-input-size_m ~ .ring-error-bubble {\\n  left: 242px;\\n  left: calc(var(--ring-input-m) + 2px);\\n}\\n\\n.ring-input-size_md.ring-input-size_md {\\n  display: inline-block;\\n\\n  width: 240px;\\n\\n  width: var(--ring-input-m);\\n}\\n\\n.ring-input-size_md.ring-input-size_md ~ .ring-error-bubble {\\n  left: 242px;\\n  left: calc(var(--ring-input-m) + 2px);\\n}\\n\\n/* L */\\n\\n.ring-input-size_l.ring-input-size_l {\\n  display: inline-block;\\n\\n  width: 400px;\\n\\n  width: var(--ring-input-l);\\n}\\n\\n.ring-input-size_l.ring-input-size_l ~ .ring-error-bubble {\\n  left: 402px;\\n  left: calc(var(--ring-input-l) + 2px);\\n}\\n\\n.ring-input-height_s.ring-input-height_s {\\n  --ring-input-padding-block: 1px;\\n}\\n\\n.ring-input-height_m.ring-input-height_m {\\n  --ring-input-padding-block: 3px;\\n}\\n\\n.ring-input-height_l.ring-input-height_l {\\n  --ring-input-padding-block: 5px;\\n}\\n\",\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/input-size/input-size.css\"],names:[],mappings:\"AAIA;EACE,qBAAgC;EAChC,oBAA+B;EAC/B,qBAA+B;EAC/B,qBAA+B;AACjC;;AAEA;;EAEE;;AAEF,OAAO;;AAEP;EACE,qBAAqB;;EAErB,WAA2B;;EAA3B,2BAA2B;AAC7B;;AAEA;EACE,UAAsC;EAAtC,sCAAsC;AACxC;;AAEA,MAAM;;AAEN;EACE,qBAAqB;;EAErB,WAA0B;;EAA1B,0BAA0B;AAC5B;;AAEA;EACE,UAAqC;EAArC,qCAAqC;AACvC;;AAEA,MAAM;;AAEN;EACE,qBAAqB;;EAErB,YAA0B;;EAA1B,0BAA0B;AAC5B;;AAEA;EACE,WAAqC;EAArC,qCAAqC;AACvC;;AAEA;EACE,qBAAqB;;EAErB,YAA0B;;EAA1B,0BAA0B;AAC5B;;AAEA;EACE,WAAqC;EAArC,qCAAqC;AACvC;;AAEA,MAAM;;AAEN;EACE,qBAAqB;;EAErB,YAA0B;;EAA1B,0BAA0B;AAC5B;;AAEA;EACE,WAAqC;EAArC,qCAAqC;AACvC;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,+BAA+B;AACjC\",sourcesContent:['@import \"../global/variables.css\";\\n\\n@value unit from \"../global/global.css\";\\n\\n:root {\\n  --ring-input-xs: calc(unit * 12);\\n  --ring-input-s: calc(unit * 12);\\n  --ring-input-m: calc(unit * 30);\\n  --ring-input-l: calc(unit * 50);\\n}\\n\\n/**\\n * @name Input Sizes\\n */\\n\\n/* XS */\\n\\n:global(.ring-input-size_xs.ring-input-size_xs) {\\n  display: inline-block;\\n\\n  width: var(--ring-input-xs);\\n}\\n\\n:global(.ring-input-size_xs.ring-input-size_xs ~ .ring-error-bubble) {\\n  left: calc(var(--ring-input-xs) + 2px);\\n}\\n\\n/* S */\\n\\n:global(.ring-input-size_s.ring-input-size_s) {\\n  display: inline-block;\\n\\n  width: var(--ring-input-s);\\n}\\n\\n:global(.ring-input-size_s.ring-input-size_s ~ .ring-error-bubble) {\\n  left: calc(var(--ring-input-s) + 2px);\\n}\\n\\n/* M */\\n\\n:global(.ring-input-size_m.ring-input-size_m) {\\n  display: inline-block;\\n\\n  width: var(--ring-input-m);\\n}\\n\\n:global(.ring-input-size_m.ring-input-size_m ~ .ring-error-bubble) {\\n  left: calc(var(--ring-input-m) + 2px);\\n}\\n\\n:global(.ring-input-size_md.ring-input-size_md) {\\n  display: inline-block;\\n\\n  width: var(--ring-input-m);\\n}\\n\\n:global(.ring-input-size_md.ring-input-size_md ~ .ring-error-bubble) {\\n  left: calc(var(--ring-input-m) + 2px);\\n}\\n\\n/* L */\\n\\n:global(.ring-input-size_l.ring-input-size_l) {\\n  display: inline-block;\\n\\n  width: var(--ring-input-l);\\n}\\n\\n:global(.ring-input-size_l.ring-input-size_l ~ .ring-error-bubble) {\\n  left: calc(var(--ring-input-l) + 2px);\\n}\\n\\n:global(.ring-input-height_s.ring-input-height_s) {\\n  --ring-input-padding-block: 1px;\\n}\\n\\n:global(.ring-input-height_m.ring-input-height_m) {\\n  --ring-input-padding-block: 3px;\\n}\\n\\n:global(.ring-input-height_l.ring-input-height_l) {\\n  --ring-input-padding-block: 5px;\\n}\\n'],sourceRoot:\"\"}]),s.locals={unit:`${l.default.locals.unit}`};const u=s},8266:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>p});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),s=t(9892),u=a()(o());u.i(c.A),u.i(s.default),u.i(l.default,\"\",!0),u.push([e.id,'.outerContainer_cb70 {\\n  --ring-input-icon-offset: 20px;\\n  --ring-input-padding-inline: 8px;\\n  --ring-input-background-color: var(--ring-content-background-color);\\n}\\n\\n.borderless_f79b {\\n  /* stylelint-disable-next-line length-zero-no-unit */\\n  --ring-input-padding-inline: 0px;\\n}\\n\\n.container_ee33 {\\n  position: relative;\\n\\n  box-sizing: border-box;\\n\\n  font-size: var(--ring-font-size);\\n  line-height: var(--ring-line-height);\\n}\\n\\n.container_ee33 * {\\n    box-sizing: border-box;\\n  }\\n\\n.input_f220 {\\n  --ring-input-padding-start: var(--ring-input-padding-inline);\\n  --ring-input-padding-end: var(--ring-input-padding-inline);\\n\\n  width: 100%;\\n\\n  margin: 0;\\n  padding-top: var(--ring-input-padding-block);\\n  padding-right: var(--ring-input-padding-end);\\n  padding-bottom: var(--ring-input-padding-block);\\n  padding-left: var(--ring-input-padding-start);\\n\\n  transition: border-color var(--ring-ease);\\n\\n  color: var(--ring-text-color);\\n  border: 1px solid var(--ring-borders-color);\\n  border-radius: var(--ring-border-radius);\\n  outline: none;\\n  background-color: var(--ring-input-background-color);\\n\\n  font: inherit;\\n\\n  caret-color: var(--ring-main-color);\\n}\\n\\n[dir=\"rtl\"] .input_f220 {\\n    padding-right: var(--ring-input-padding-start);\\n    padding-left: var(--ring-input-padding-end);\\n  }\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.input_f220:hover {\\n    transition: none;\\n\\n    border-color: var(--ring-border-hover-color);\\n  }}\\n\\n.error_ff90 .input_f220 {\\n    border-color: var(--ring-icon-error-color);\\n  }\\n\\n.input_f220:focus {\\n    transition: none;\\n\\n    border-color: var(--ring-main-color);\\n  }\\n\\n.input_f220[disabled] {\\n    color: var(--ring-disabled-color);\\n    border-color: var(--ring-border-disabled-color);\\n    background-color: var(--ring-disabled-background-color);\\n\\n    -webkit-text-fill-color: var(--ring-disabled-color); /* Required for Safari, see RG-2063 for details */\\n  }\\n\\n/*\\n    Kill yellow/blue webkit autocomplete\\n    https://css-tricks.com/snippets/css/change-autocomplete-styles-webkit-browsers/\\n  */\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.input_f220:-webkit-autofill:hover {\\n      -webkit-transition: background-color 50000s ease-in-out 0s;\\n      transition: background-color 50000s ease-in-out 0s;\\n    }}\\n\\n.input_f220:-webkit-autofill,\\n    .input_f220:-webkit-autofill:focus {\\n      -webkit-transition: background-color 50000s ease-in-out 0s;\\n      transition: background-color 50000s ease-in-out 0s;\\n    }\\n\\n.borderless_f79b .input_f220 {\\n  border-color: transparent;\\n  background-color: transparent;\\n}\\n\\n.withIcon_f066 .input_f220 {\\n  --ring-input-padding-start: calc(var(--ring-input-padding-inline) + var(--ring-input-icon-offset));\\n}\\n\\n.clearable_fd1e .input_f220 {\\n  --ring-input-padding-end: calc(var(--ring-input-padding-inline) + var(--ring-input-icon-offset));\\n}\\n\\n.icon_e49c {\\n  position: absolute;\\n  top: calc(var(--ring-input-padding-block) + 1px);\\n  left: var(--ring-input-padding-inline);\\n\\n  pointer-events: none;\\n\\n  color: var(--ring-icon-secondary-color);\\n}\\n\\n[dir=\"rtl\"] .icon_e49c {\\n    right: 8px;\\n    left: auto;\\n  }\\n\\n.clear_ffc3 {\\n  position: absolute;\\n  top: calc(var(--ring-input-padding-block) + 2px);\\n  right: var(--ring-input-padding-inline);\\n\\n  height: auto;\\n\\n  padding-right: 0;\\n\\n  line-height: inherit;\\n}\\n\\n.empty_cc0d .clear_ffc3 {\\n    display: none;\\n  }\\n\\n[dir=\"rtl\"] .clear_ffc3 {\\n    right: auto;\\n    left: 8px;\\n  }\\n\\ntextarea.input_f220 {\\n  overflow: hidden;\\n\\n  box-sizing: border-box;\\n\\n  resize: none;\\n}\\n\\n.input_f220::-moz-placeholder {\\n  color: var(--ring-disabled-color);\\n}\\n\\n.input_f220::placeholder {\\n  color: var(--ring-disabled-color);\\n}\\n\\n.input_f220::-webkit-search-cancel-button {\\n  -webkit-appearance: none;\\n}\\n\\n.errorText_e447 {\\n  margin-top: 4px;\\n\\n  color: var(--ring-error-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n  line-height: var(--ring-line-height-lowest);\\n}\\n\\n.sizeS_c560 {\\n  width: 96px;\\n}\\n\\n.sizeM_aee6 {\\n  width: 240px;\\n}\\n\\n.sizeL_b0ca {\\n  width: 400px;\\n}\\n\\n.sizeFULL_f4f9 {\\n  width: 100%;\\n}\\n\\n.heightS_a68d {\\n  --ring-input-padding-block: 1px;\\n}\\n\\n.heightM_bc35 {\\n  --ring-input-padding-block: 3px;\\n}\\n\\n.heightL_f82d {\\n  --ring-input-padding-block: 5px;\\n}\\n',\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/input/input.css\",\"<no source>\"],names:[],mappings:\"AAKA;EACE,8BAA0C;EAC1C,gCAAiC;EACjC,mEAAmE;AACrE;;AAEA;EACE,oDAAoD;EACpD,gCAAgC;AAClC;;AAEA;EACE,kBAAkB;;EAElB,sBAAsB;;EAEtB,gCAAgC;EAChC,oCAAoC;AAKtC;;AAHE;IACE,sBAAsB;EACxB;;AAGF;EACE,4DAA4D;EAC5D,0DAA0D;;EAE1D,WAAW;;EAEX,SAAS;EACT,4CAA4C;EAC5C,4CAA4C;EAC5C,+CAA+C;EAC/C,6CAA6C;;EAE7C,yCAAyC;;EAEzC,6BAA6B;EAC7B,2CAA2C;EAC3C,wCAAwC;EACxC,aAAa;EACb,oDAAoD;;EAEpD,aAAa;;EAEb,mCAAmC;AA0CrC;;AAxCE;IACE,8CAA8C;IAC9C,2CAA2C;EAC7C;;ACxDF,wGAAA;IAAA,iBAAA;;IAAA,6CAAA;GAAA,CAAA;;ADgEE;IACE,0CAA0C;EAC5C;;AAEA;IACE,gBAAgB;;IAEhB,oCAAoC;EACtC;;AAEA;IACE,iCAAiC;IACjC,+CAA+C;IAC/C,uDAAuD;;IAEvD,mDAAmD,EAAE,iDAAiD;EACxG;;AAEA;;;GAGC;;ACrFH,wGAAA;MAAA,2DAAA;MAAA,mDAAA;KAAA,CAAA;;ADuFI;;MAGE,0DAAkD;MAAlD,kDAAkD;IACpD;;AAIJ;EACE,yBAAyB;EACzB,6BAA6B;AAC/B;;AAEA;EACE,kGAAkG;AACpG;;AAEA;EACE,gGAAgG;AAClG;;AAEA;EACE,kBAAkB;EAClB,gDAAgD;EAChD,sCAAsC;;EAEtC,oBAAoB;;EAEpB,uCAAuC;AAMzC;;AAJE;IACE,UAAW;IACX,UAAU;EACZ;;AAGF;EACE,kBAAkB;EAClB,gDAAgD;EAChD,uCAAuC;;EAEvC,YAAY;;EAEZ,gBAAgB;;EAEhB,oBAAoB;AAUtB;;AARE;IACE,aAAa;EACf;;AAEA;IACE,WAAW;IACX,SAAU;EACZ;;AAGF;EACE,gBAAgB;;EAEhB,sBAAsB;;EAEtB,YAAY;AACd;;AAEA;EACE,iCAAiC;AACnC;;AAFA;EACE,iCAAiC;AACnC;;AAEA;EACE,wBAAwB;AAC1B;;AAEA;EACE,eAA0B;;EAE1B,8BAA8B;;EAE9B,wCAAwC;EACxC,2CAA2C;AAC7C;;AAEA;EACE,WAAsB;AACxB;;AAEA;EACE,YAAsB;AACxB;;AAEA;EACE,YAAsB;AACxB;;AAEA;EACE,WAAW;AACb;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,+BAA+B;AACjC;;AAEA;EACE,+BAA+B;AACjC\",sourcesContent:['@import \"../global/variables.css\";\\n@import \"../button/button.css\";\\n\\n@value unit from \"../global/global.css\";\\n\\n.outerContainer {\\n  --ring-input-icon-offset: calc(unit * 2.5);\\n  --ring-input-padding-inline: unit;\\n  --ring-input-background-color: var(--ring-content-background-color);\\n}\\n\\n.borderless {\\n  /* stylelint-disable-next-line length-zero-no-unit */\\n  --ring-input-padding-inline: 0px;\\n}\\n\\n.container {\\n  position: relative;\\n\\n  box-sizing: border-box;\\n\\n  font-size: var(--ring-font-size);\\n  line-height: var(--ring-line-height);\\n\\n  & * {\\n    box-sizing: border-box;\\n  }\\n}\\n\\n.input {\\n  --ring-input-padding-start: var(--ring-input-padding-inline);\\n  --ring-input-padding-end: var(--ring-input-padding-inline);\\n\\n  width: 100%;\\n\\n  margin: 0;\\n  padding-top: var(--ring-input-padding-block);\\n  padding-right: var(--ring-input-padding-end);\\n  padding-bottom: var(--ring-input-padding-block);\\n  padding-left: var(--ring-input-padding-start);\\n\\n  transition: border-color var(--ring-ease);\\n\\n  color: var(--ring-text-color);\\n  border: 1px solid var(--ring-borders-color);\\n  border-radius: var(--ring-border-radius);\\n  outline: none;\\n  background-color: var(--ring-input-background-color);\\n\\n  font: inherit;\\n\\n  caret-color: var(--ring-main-color);\\n\\n  [dir=\"rtl\"] & {\\n    padding-right: var(--ring-input-padding-start);\\n    padding-left: var(--ring-input-padding-end);\\n  }\\n\\n  &:hover {\\n    transition: none;\\n\\n    border-color: var(--ring-border-hover-color);\\n  }\\n\\n  .error & {\\n    border-color: var(--ring-icon-error-color);\\n  }\\n\\n  &:focus {\\n    transition: none;\\n\\n    border-color: var(--ring-main-color);\\n  }\\n\\n  &[disabled] {\\n    color: var(--ring-disabled-color);\\n    border-color: var(--ring-border-disabled-color);\\n    background-color: var(--ring-disabled-background-color);\\n\\n    -webkit-text-fill-color: var(--ring-disabled-color); /* Required for Safari, see RG-2063 for details */\\n  }\\n\\n  /*\\n    Kill yellow/blue webkit autocomplete\\n    https://css-tricks.com/snippets/css/change-autocomplete-styles-webkit-browsers/\\n  */\\n  &:-webkit-autofill {\\n    &,\\n    &:hover,\\n    &:focus {\\n      transition: background-color 50000s ease-in-out 0s;\\n    }\\n  }\\n}\\n\\n.borderless .input {\\n  border-color: transparent;\\n  background-color: transparent;\\n}\\n\\n.withIcon .input {\\n  --ring-input-padding-start: calc(var(--ring-input-padding-inline) + var(--ring-input-icon-offset));\\n}\\n\\n.clearable .input {\\n  --ring-input-padding-end: calc(var(--ring-input-padding-inline) + var(--ring-input-icon-offset));\\n}\\n\\n.icon {\\n  position: absolute;\\n  top: calc(var(--ring-input-padding-block) + 1px);\\n  left: var(--ring-input-padding-inline);\\n\\n  pointer-events: none;\\n\\n  color: var(--ring-icon-secondary-color);\\n\\n  [dir=\"rtl\"] & {\\n    right: unit;\\n    left: auto;\\n  }\\n}\\n\\n.clear {\\n  position: absolute;\\n  top: calc(var(--ring-input-padding-block) + 2px);\\n  right: var(--ring-input-padding-inline);\\n\\n  height: auto;\\n\\n  padding-right: 0;\\n\\n  line-height: inherit;\\n\\n  .empty & {\\n    display: none;\\n  }\\n\\n  [dir=\"rtl\"] & {\\n    right: auto;\\n    left: unit;\\n  }\\n}\\n\\ntextarea.input {\\n  overflow: hidden;\\n\\n  box-sizing: border-box;\\n\\n  resize: none;\\n}\\n\\n.input::placeholder {\\n  color: var(--ring-disabled-color);\\n}\\n\\n.input::-webkit-search-cancel-button {\\n  -webkit-appearance: none;\\n}\\n\\n.errorText {\\n  margin-top: calc(unit / 2);\\n\\n  color: var(--ring-error-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n  line-height: var(--ring-line-height-lowest);\\n}\\n\\n.sizeS {\\n  width: calc(unit * 12);\\n}\\n\\n.sizeM {\\n  width: calc(unit * 30);\\n}\\n\\n.sizeL {\\n  width: calc(unit * 50);\\n}\\n\\n.sizeFULL {\\n  width: 100%;\\n}\\n\\n.heightS {\\n  --ring-input-padding-block: 1px;\\n}\\n\\n.heightM {\\n  --ring-input-padding-block: 3px;\\n}\\n\\n.heightL {\\n  --ring-input-padding-block: 5px;\\n}\\n',null],sourceRoot:\"\"}]),u.locals={unit:`${l.default.locals.unit}`,outerContainer:\"outerContainer_cb70\",borderless:\"borderless_f79b\",container:\"container_ee33\",input:\"input_f220\",error:\"error_ff90\",withIcon:\"withIcon_f066\",clearable:\"clearable_fd1e\",icon:\"icon_e49c\",clear:\"clear_ffc3\",empty:\"empty_cc0d\",errorText:\"errorText_e447\",sizeS:\"sizeS_c560\",sizeM:\"sizeM_aee6\",sizeL:\"sizeL_b0ca\",sizeFULL:\"sizeFULL_f4f9\",heightS:\"heightS_a68d\",heightM:\"heightM_bc35\",heightL:\"heightL_f82d\"};const p=u},6960:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(5280),c=a()(o());c.i(l.A),c.push([e.id,\".link_e6e5 {\\n  cursor: pointer;\\n  transition: color var(--ring-fast-ease);\\n\\n  color: var(--ring-link-color);\\n\\n  outline: none;\\n}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.link_e6e5:hover {\\n    transition: none;\\n\\n    color: var(--ring-link-hover-color);\\n  }}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.link_e6e5:hover {\\n    text-decoration: none;\\n  }}\\n\\n.link_e6e5 {\\n    text-decoration: none;\\n  }\\n\\n.link_e6e5.hover_bed7 {\\n    transition: none;\\n\\n    color: var(--ring-link-hover-color);\\n  }\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.link_e6e5:hover .inner_e3ba {\\n    border-width: 0;\\n    border-bottom: 2px solid;\\n    border-image-source: linear-gradient(currentcolor 50%, transparent 50%);\\n    border-image-slice: 0 0 100% 0;\\n  }}\\n\\n.link_e6e5.active_f804 {\\n    color: inherit;\\n  }\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.link_e6e5.compatibilityUnderlineMode_e7a0:hover {\\n    text-decoration: underline;\\n\\n    /* stylelint-disable-next-line selector-max-specificity */\\n  }\\n    .link_e6e5.compatibilityUnderlineMode_e7a0:hover .inner_e3ba {\\n      border: none;\\n    }}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.link_e6e5.pseudo_d9ae:hover {\\n    text-decoration: none;\\n\\n    /* stylelint-disable-next-line selector-max-specificity */\\n  }\\n    .link_e6e5.pseudo_d9ae:hover .inner_e3ba {\\n      border: none;\\n    }}\\n\\n.link_e6e5:focus-visible {\\n    box-shadow: 0 0 0 2px var(--ring-border-hover-color);\\n  }\\n\\n@media (min-resolution: 2dppx) {@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.link_e6e5:hover .inner_e3ba {\\n    border-bottom-width: 1px;\\n  }}\\n}\\n\\n.text_e98a {\\n  border-radius: var(--ring-border-radius);\\n}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.inherit_d267:not(:hover) {\\n  color: inherit;\\n}}\\n\\n.pseudo_d9ae {\\n  margin: 0;\\n  padding: 0;\\n\\n  text-align: left;\\n\\n  border: 0;\\n\\n  background: transparent;\\n\\n  font: inherit;\\n}\\n\\n.pseudo_d9ae::-moz-focus-inner {\\n    padding: 0;\\n\\n    border: 0;\\n  }\\n\",\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/link/link.css\",\"<no source>\"],names:[],mappings:\"AAEA;EACE,eAAe;EACf,uCAAuC;;EAEvC,6BAA6B;;EA2C7B,aAAa;AAKf;;ACtDA,wGAAA;IAAA,iBAAA;;IAAA,oCAAA;GAAA,CAAA;;AAAA,wGAAA;IAAA,sBAAA;GAAA,CAAA;;ADQE;IAEE,qBAAqB;EACvB;;AAEA;IAEE,gBAAgB;;IAEhB,mCAAmC;EACrC;;AClBF,wGAAA;IAAA,gBAAA;IAAA,yBAAA;IAAA,wEAAA;IAAA,+BAAA;GAAA,CAAA;;AD2BE;IACE,cAAc;EAChB;;AC7BF,wGAAA;IAAA,2BAAA;;IAAA,0DAAA;GAAA;IAAA;MAAA,aAAA;KAAA,CAAA;;AAAA,wGAAA;IAAA,sBAAA;;IAAA,0DAAA;GAAA;IAAA;MAAA,aAAA;KAAA,CAAA;;ADmDE;IACE,oDAAoD;EACtD;;AAGF,gCCxDA,wGAAA;IAAA,yBAAA;GAAA,CAAA;AD4DA;;AAEA;EACE,wCAAwC;AAC1C;;AChEA,wGAAA;EAAA,eAAA;CAAA,CAAA;;ADsEA;EACE,SAAS;EACT,UAAU;;EAEV,gBAAgB;;EAEhB,SAAS;;EAET,uBAAuB;;EAEvB,aAAa;AAOf;;AALE;IACE,UAAU;;IAEV,SAAS;EACX\",sourcesContent:['@import \"../global/variables.css\";\\n\\n.link {\\n  cursor: pointer;\\n  transition: color var(--ring-fast-ease);\\n\\n  color: var(--ring-link-color);\\n\\n  &,\\n  &:hover {\\n    text-decoration: none;\\n  }\\n\\n  &:hover,\\n  &.hover {\\n    transition: none;\\n\\n    color: var(--ring-link-hover-color);\\n  }\\n\\n  &:hover .inner {\\n    border-width: 0;\\n    border-bottom: 2px solid;\\n    border-image-source: linear-gradient(currentcolor 50%, transparent 50%);\\n    border-image-slice: 0 0 100% 0;\\n  }\\n\\n  &.active {\\n    color: inherit;\\n  }\\n\\n  &.compatibilityUnderlineMode:hover {\\n    text-decoration: underline;\\n\\n    /* stylelint-disable-next-line selector-max-specificity */\\n    & .inner {\\n      border: none;\\n    }\\n  }\\n\\n  &.pseudo:hover {\\n    text-decoration: none;\\n\\n    /* stylelint-disable-next-line selector-max-specificity */\\n    & .inner {\\n      border: none;\\n    }\\n  }\\n\\n  outline: none;\\n\\n  &:focus-visible {\\n    box-shadow: 0 0 0 2px var(--ring-border-hover-color);\\n  }\\n}\\n\\n@media (min-resolution: 2dppx) {\\n  .link:hover .inner {\\n    border-bottom-width: 1px;\\n  }\\n}\\n\\n.text {\\n  border-radius: var(--ring-border-radius);\\n}\\n\\n.inherit:not(:hover) {\\n  color: inherit;\\n}\\n\\n.pseudo {\\n  margin: 0;\\n  padding: 0;\\n\\n  text-align: left;\\n\\n  border: 0;\\n\\n  background: transparent;\\n\\n  font: inherit;\\n\\n  &::-moz-focus-inner {\\n    padding: 0;\\n\\n    border: 0;\\n  }\\n}\\n',null],sourceRoot:\"\"}]),c.locals={link:\"link_e6e5\",hover:\"hover_bed7\",inner:\"inner_e3ba\",active:\"active_f804\",compatibilityUnderlineMode:\"compatibilityUnderlineMode_e7a0\",pseudo:\"pseudo_d9ae\",text:\"text_e98a\",inherit:\"inherit_d267\"};const s=c},480:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),s=a()(o());s.i(c.A),s.i(l.default,\"\",!0),s.push([e.id,'.list_a01c {\\n  position: relative;\\n\\n  z-index: 1;\\n\\n  border-radius: var(--ring-border-radius);\\n\\n  line-height: normal;\\n}\\n\\n.simpleInner_a4f8 {\\n  overflow: auto;\\n}\\n\\n.scrolling_a910 {\\n  pointer-events: none;\\n}\\n\\n.separator_c26e {\\n  display: block;\\n\\n  min-height: 8px;\\n\\n  margin-top: 8px;\\n  padding: 0 16px 1px;\\n\\n  text-align: right;\\n  white-space: nowrap;\\n\\n  color: var(--ring-secondary-color);\\n  border-top: 1px solid var(--ring-line-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n  line-height: var(--ring-line-height-lower);\\n}\\n\\n.separator_first_ec9e {\\n  margin-top: 0;\\n  padding-top: 0;\\n\\n  border: none;\\n}\\n\\n.item_eadd {\\n  display: block;\\n\\n  box-sizing: border-box;\\n\\n  width: 100%;\\n\\n  text-align: left;\\n  vertical-align: bottom;\\n  white-space: nowrap;\\n  text-decoration: none;\\n\\n  outline: none;\\n\\n  font-size: var(--ring-font-size);\\n}\\n\\n.item_eadd.item_eadd {\\n  padding: 3px 16px 5px;\\n\\n  line-height: 24px;\\n}\\n\\n.itemContainer_f365 {\\n  position: relative;\\n}\\n\\n.compact_efa8 {\\n  line-height: 16px;\\n}\\n\\n.error_aa15 {\\n  cursor: default;\\n}\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.error_aa15:hover {\\n    color: var(--ring-error-color);\\n  }}\\n\\n/* Override ring-link */\\n\\n.error_aa15,\\n  .error_aa15:focus,\\n  .error_aa15:visited {\\n    color: var(--ring-error-color);\\n  }\\n\\n.add_a8da {\\n  padding: 8px 16px;\\n\\n  line-height: 32px;\\n}\\n\\n.top_c4d5 {\\n  display: flex;\\n  align-items: baseline;\\n  flex-direction: row;\\n}\\n\\n.left_ea6b {\\n  align-self: center;\\n  flex-shrink: 0;\\n}\\n\\n.label_dac9 {\\n  overflow: hidden;\\n  flex-grow: 1;\\n  flex-shrink: 1;\\n\\n  text-align: left;\\n  white-space: nowrap;\\n  text-overflow: ellipsis;\\n}\\n\\n[dir=\"rtl\"] .label_dac9 {\\n    text-align: right;\\n    direction: ltr;\\n  }\\n\\n.description_efcc {\\n  overflow: hidden;\\n  flex-shrink: 100;\\n\\n  padding-left: 8px;\\n\\n  text-align: right;\\n  white-space: nowrap;\\n  text-overflow: ellipsis;\\n\\n  color: var(--ring-secondary-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n  font-weight: 400;\\n  line-height: var(--ring-line-height-lowest);\\n}\\n\\n.right_df77 {\\n  display: flex;\\n  align-items: center;\\n  align-self: center;\\n  flex-direction: row;\\n  flex-shrink: 0;\\n}\\n\\n.details_a2b7 {\\n  margin-bottom: 6px;\\n\\n  white-space: normal;\\n\\n  color: var(--ring-secondary-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n  line-height: var(--ring-line-height-lowest);\\n}\\n\\n.padded_a74d {\\n  margin-left: 20px;\\n}\\n\\n/* Override :last-child */\\n.hint_d29d.hint_d29d {\\n  margin-bottom: 0;\\n\\n  border-top: 1px solid var(--ring-line-color);\\n  background-color: var(--ring-sidebar-background-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n}\\n\\n.action_d10e {\\n  cursor: pointer;\\n\\n  color: var(--ring-text-color);\\n}\\n\\n/* override link */\\n.actionLink_a4c7.actionLink_a4c7 {\\n  transition: none;\\n}\\n\\n.hover_a4cd:not(.error_aa15) {\\n  background-color: var(--ring-selected-background-color);\\n}\\n\\n.icon_f1f3 {\\n  display: inline-block;\\n\\n  width: 20px;\\n  height: 20px;\\n  margin-left: 16px;\\n\\n  background-repeat: no-repeat;\\n  background-position: center;\\n\\n  background-size: contain;\\n}\\n\\n.highlight_e4dd {\\n  color: var(--ring-link-hover-color);\\n}\\n\\n.service_a4fc {\\n  color: var(--ring-secondary-color);\\n}\\n\\n.glyph_dfd5 {\\n  float: left;\\n\\n  width: 20px;\\n\\n  margin-right: 8px;\\n\\n  color: var(--ring-icon-secondary-color);\\n}\\n\\n.avatar_f258 {\\n\\n  top: 0;\\n\\n  height: 20px;\\n\\n  -o-object-fit: cover;\\n\\n     object-fit: cover;\\n  -o-object-position: center;\\n     object-position: center;\\n}\\n\\n.rightGlyph_fb77 {\\n\\n  float: right;\\n\\n  margin-right: 0;\\n  margin-left: 16px;\\n}\\n\\n.checkboxContainer_c949 {\\n  position: absolute;\\n  top: 7px;\\n  left: 19px;\\n\\n  width: 20px;\\n  height: 20px;\\n  margin-right: 8px;\\n}\\n\\n.compact_efa8 .checkboxContainer_c949 {\\n  top: 0;\\n\\n  width: 16px;\\n  height: 16px;\\n}\\n\\n.title_e1bf {\\n  display: block;\\n\\n  margin-top: 10px;\\n  margin-bottom: 6px;\\n  padding: 8px 16px 0;\\n\\n  text-align: left;\\n}\\n\\n[dir=\"rtl\"] .title_e1bf {\\n    text-align: right;\\n    direction: ltr;\\n  }\\n\\n.title_first_ac55 {\\n  margin-top: 0;\\n}\\n\\n.text_fe0e {\\n  letter-spacing: 1.5px;\\n  text-transform: uppercase;\\n\\n  color: var(--ring-secondary-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n}\\n\\n.fade_d35c {\\n  position: absolute;\\n  bottom: 0;\\n\\n  width: 100%;\\n  height: 24px;\\n\\n  pointer-events: none;\\n\\n  background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--ring-content-background-color));\\n}\\n\\n.disabled_c3d8 {\\n  pointer-events: none;\\n\\n  color: var(--ring-disabled-color);\\n}\\n',\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/list/list.css\",\"<no source>\"],names:[],mappings:\"AAKA;EACE,kBAAkB;;EAElB,UAAU;;EAEV,wCAAwC;;EAExC,mBAAmB;AACrB;;AAEA;EACE,cAAc;AAChB;;AAEA;EACE,oBAAoB;AACtB;;AAEA;EACE,cAAc;;EAEd,eAAuB;;EAEvB,eAAuB;EACvB,mBAA6B;;EAE7B,iBAAiB;EACjB,mBAAmB;;EAEnB,kCAAkC;EAClC,4CAA4C;;EAE5C,wCAAwC;EACxC,0CAA0C;AAC5C;;AAEA;EACE,aAAa;EACb,cAAc;;EAEd,YAAY;AACd;;AAEA;EACE,cAAc;;EAEd,sBAAsB;;EAEtB,WAAW;;EAEX,gBAAgB;EAChB,sBAAsB;EACtB,mBAAmB;EACnB,qBAAqB;;EAErB,aAAa;;EAEb,gCAAgC;AAClC;;AAEA;EACE,qBAA+B;;EAE/B,iBAA2B;AAC7B;;AAEA;EACE,kBAAkB;AACpB;;AAEA;EACE,iBAA2B;AAC7B;;AAEA;EACE,eAAe;AASjB;;ACzFA,wGAAA;IAAA,+BAAA;GAAA,CAAA;;ADkFE,uBAAuB;;AACvB;;;IAIE,8BAA8B;EAChC;;AAGF;EACE,iBAA4B;;EAE5B,iBAA2B;AAC7B;;AAEA;EACE,aAAa;EACb,qBAAqB;EACrB,mBAAmB;AACrB;;AAEA;EACE,kBAAkB;EAClB,cAAc;AAChB;;AAEA;EACE,gBAAgB;EAChB,YAAY;EACZ,cAAc;;EAEd,gBAAgB;EAChB,mBAAmB;EACnB,uBAAuB;AAMzB;;AAJE;IACE,iBAAiB;IACjB,cAAc;EAChB;;AAGF;EACE,gBAAgB;EAChB,gBAAgB;;EAEhB,iBAAkB;;EAElB,iBAAiB;EACjB,mBAAmB;EACnB,uBAAuB;;EAEvB,kCAAkC;;EAElC,wCAAwC;EACxC,gBAAgB;EAChB,2CAA2C;AAC7C;;AAEA;EACE,aAAa;EACb,mBAAmB;EACnB,kBAAkB;EAClB,mBAAmB;EACnB,cAAc;AAChB;;AAEA;EACE,kBAAkB;;EAElB,mBAAmB;;EAEnB,kCAAkC;;EAElC,wCAAwC;EACxC,2CAA2C;AAC7C;;AAEA;EACE,iBAAiB;AACnB;;AAEA,yBAAyB;AACzB;EACE,gBAAgB;;EAEhB,4CAA4C;EAC5C,sDAAsD;;EAEtD,wCAAwC;AAC1C;;AAEA;EACE,eAAe;;EAEf,6BAA6B;AAC/B;;AAEA,kBAAkB;AAClB;EACE,gBAAgB;AAClB;;AAEA;EACE,uDAAuD;AACzD;;AAEA;EACE,qBAAqB;;EAErB,WAAW;EACX,YAAY;EACZ,iBAA2B;;EAE3B,4BAA4B;EAC5B,2BAA2B;;EAE3B,wBAAwB;AAC1B;;AAEA;EACE,mCAAmC;AACrC;;AAEA;EACE,kCAAkC;AACpC;;AAEA;EACE,WAAW;;EAEX,WAAW;;EAEX,iBAAkB;;EAElB,uCAAuC;AACzC;;AAEA;;EAGE,MAAM;;EAEN,YAAY;;EAEZ,oBAAiB;;KAAjB,iBAAiB;EACjB,0BAAuB;KAAvB,uBAAuB;AACzB;;AAEA;;EAGE,YAAY;;EAEZ,eAAe;EACf,iBAA2B;AAC7B;;AAEA;EACE,kBAAkB;EAClB,QAAQ;EACR,UAAU;;EAEV,WAAW;EACX,YAAY;EACZ,iBAAkB;AACpB;;AAEA;EACE,MAAM;;EAEN,WAAqB;EACrB,YAAsB;AACxB;;AAEA;EACE,cAAc;;EAEd,gBAAgB;EAChB,kBAAkB;EAClB,mBAAqC;;EAErC,gBAAgB;AAMlB;;AAJE;IACE,iBAAiB;IACjB,cAAc;EAChB;;AAGF;EACE,aAAa;AACf;;AAEA;EACE,qBAAqB;EACrB,yBAAyB;;EAEzB,kCAAkC;;EAElC,wCAAwC;AAC1C;;AAEA;EACE,kBAAkB;EAClB,SAAS;;EAET,WAAW;EACX,YAAsB;;EAEtB,oBAAoB;;EAEpB,oGAAoG;AACtG;;AAEA;EACE,oBAAoB;;EAEpB,iCAAiC;AACnC\",sourcesContent:['@import \"../global/variables.css\";\\n\\n@value unit from \"../global/global.css\";\\n@value listSpacing: unit;\\n\\n.list {\\n  position: relative;\\n\\n  z-index: 1;\\n\\n  border-radius: var(--ring-border-radius);\\n\\n  line-height: normal;\\n}\\n\\n.simpleInner {\\n  overflow: auto;\\n}\\n\\n.scrolling {\\n  pointer-events: none;\\n}\\n\\n.separator {\\n  display: block;\\n\\n  min-height: listSpacing;\\n\\n  margin-top: listSpacing;\\n  padding: 0 calc(unit * 2) 1px;\\n\\n  text-align: right;\\n  white-space: nowrap;\\n\\n  color: var(--ring-secondary-color);\\n  border-top: 1px solid var(--ring-line-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n  line-height: var(--ring-line-height-lower);\\n}\\n\\n.separator_first {\\n  margin-top: 0;\\n  padding-top: 0;\\n\\n  border: none;\\n}\\n\\n.item {\\n  display: block;\\n\\n  box-sizing: border-box;\\n\\n  width: 100%;\\n\\n  text-align: left;\\n  vertical-align: bottom;\\n  white-space: nowrap;\\n  text-decoration: none;\\n\\n  outline: none;\\n\\n  font-size: var(--ring-font-size);\\n}\\n\\n.item.item {\\n  padding: 3px calc(unit * 2) 5px;\\n\\n  line-height: calc(unit * 3);\\n}\\n\\n.itemContainer {\\n  position: relative;\\n}\\n\\n.compact {\\n  line-height: calc(unit * 2);\\n}\\n\\n.error {\\n  cursor: default;\\n\\n  /* Override ring-link */\\n  &,\\n  &:hover,\\n  &:focus,\\n  &:visited {\\n    color: var(--ring-error-color);\\n  }\\n}\\n\\n.add {\\n  padding: unit calc(2 * unit);\\n\\n  line-height: calc(4 * unit);\\n}\\n\\n.top {\\n  display: flex;\\n  align-items: baseline;\\n  flex-direction: row;\\n}\\n\\n.left {\\n  align-self: center;\\n  flex-shrink: 0;\\n}\\n\\n.label {\\n  overflow: hidden;\\n  flex-grow: 1;\\n  flex-shrink: 1;\\n\\n  text-align: left;\\n  white-space: nowrap;\\n  text-overflow: ellipsis;\\n\\n  [dir=\"rtl\"] & {\\n    text-align: right;\\n    direction: ltr;\\n  }\\n}\\n\\n.description {\\n  overflow: hidden;\\n  flex-shrink: 100;\\n\\n  padding-left: unit;\\n\\n  text-align: right;\\n  white-space: nowrap;\\n  text-overflow: ellipsis;\\n\\n  color: var(--ring-secondary-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n  font-weight: 400;\\n  line-height: var(--ring-line-height-lowest);\\n}\\n\\n.right {\\n  display: flex;\\n  align-items: center;\\n  align-self: center;\\n  flex-direction: row;\\n  flex-shrink: 0;\\n}\\n\\n.details {\\n  margin-bottom: 6px;\\n\\n  white-space: normal;\\n\\n  color: var(--ring-secondary-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n  line-height: var(--ring-line-height-lowest);\\n}\\n\\n.padded {\\n  margin-left: 20px;\\n}\\n\\n/* Override :last-child */\\n.hint.hint {\\n  margin-bottom: 0;\\n\\n  border-top: 1px solid var(--ring-line-color);\\n  background-color: var(--ring-sidebar-background-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n}\\n\\n.action {\\n  cursor: pointer;\\n\\n  color: var(--ring-text-color);\\n}\\n\\n/* override link */\\n.actionLink.actionLink {\\n  transition: none;\\n}\\n\\n.hover:not(.error) {\\n  background-color: var(--ring-selected-background-color);\\n}\\n\\n.icon {\\n  display: inline-block;\\n\\n  width: 20px;\\n  height: 20px;\\n  margin-left: calc(unit * 2);\\n\\n  background-repeat: no-repeat;\\n  background-position: center;\\n\\n  background-size: contain;\\n}\\n\\n.highlight {\\n  color: var(--ring-link-hover-color);\\n}\\n\\n.service {\\n  color: var(--ring-secondary-color);\\n}\\n\\n.glyph {\\n  float: left;\\n\\n  width: 20px;\\n\\n  margin-right: unit;\\n\\n  color: var(--ring-icon-secondary-color);\\n}\\n\\n.avatar {\\n  composes: glyph;\\n\\n  top: 0;\\n\\n  height: 20px;\\n\\n  object-fit: cover;\\n  object-position: center;\\n}\\n\\n.rightGlyph {\\n  composes: glyph;\\n\\n  float: right;\\n\\n  margin-right: 0;\\n  margin-left: calc(unit * 2);\\n}\\n\\n.checkboxContainer {\\n  position: absolute;\\n  top: 7px;\\n  left: 19px;\\n\\n  width: 20px;\\n  height: 20px;\\n  margin-right: unit;\\n}\\n\\n.compact .checkboxContainer {\\n  top: 0;\\n\\n  width: calc(unit * 2);\\n  height: calc(unit * 2);\\n}\\n\\n.title {\\n  display: block;\\n\\n  margin-top: 10px;\\n  margin-bottom: 6px;\\n  padding: listSpacing calc(unit * 2) 0;\\n\\n  text-align: left;\\n\\n  [dir=\"rtl\"] & {\\n    text-align: right;\\n    direction: ltr;\\n  }\\n}\\n\\n.title_first {\\n  margin-top: 0;\\n}\\n\\n.text {\\n  letter-spacing: 1.5px;\\n  text-transform: uppercase;\\n\\n  color: var(--ring-secondary-color);\\n\\n  font-size: var(--ring-font-size-smaller);\\n}\\n\\n.fade {\\n  position: absolute;\\n  bottom: 0;\\n\\n  width: 100%;\\n  height: calc(unit * 3);\\n\\n  pointer-events: none;\\n\\n  background: linear-gradient(to bottom, rgba(255, 255, 255, 0), var(--ring-content-background-color));\\n}\\n\\n.disabled {\\n  pointer-events: none;\\n\\n  color: var(--ring-disabled-color);\\n}\\n',null],sourceRoot:\"\"}]),s.locals={unit:`${l.default.locals.unit}`,listSpacing:\"8px\",list:\"list_a01c\",simpleInner:\"simpleInner_a4f8\",scrolling:\"scrolling_a910\",separator:\"separator_c26e\",separator_first:\"separator_first_ec9e\",item:\"item_eadd\",itemContainer:\"itemContainer_f365\",compact:\"compact_efa8\",error:\"error_aa15\",add:\"add_a8da\",top:\"top_c4d5\",left:\"left_ea6b\",label:\"label_dac9\",description:\"description_efcc\",right:\"right_df77\",details:\"details_a2b7\",padded:\"padded_a74d\",hint:\"hint_d29d\",action:\"action_d10e\",actionLink:\"actionLink_a4c7\",hover:\"hover_a4cd\",icon:\"icon_f1f3\",highlight:\"highlight_e4dd\",service:\"service_a4fc\",glyph:\"glyph_dfd5\",avatar:\"avatar_f258 glyph_dfd5\",rightGlyph:\"rightGlyph_fb77 glyph_dfd5\",checkboxContainer:\"checkboxContainer_c949\",title:\"title_e1bf\",title_first:\"title_first_ac55\",text:\"text_fe0e\",fade:\"fade_d35c\",disabled:\"disabled_c3d8\"};const u=s},1586:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>p});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9173),c=t(9106),s=t(5280),u=a()(o());u.i(s.A),u.i(l.A,\"\",!0),u.i(c.default,\"\",!0),u.push([e.id,`:root {\\n  /* stylelint-disable-next-line color-no-hex */\\n  --ring-loader-inline-stops: #ff00eb, #bd3bff, #008eff, #58ba00, #f48700, #ff00eb;\\n}\\n\\n.${l.A.locals.dark},\\n.ring-ui-theme-dark {\\n  /* stylelint-disable-next-line color-no-hex */\\n  --ring-loader-inline-stops: #ff2eef, #d178ff, #289fff, #88d444, #ffe000, #ff2eef;\\n}\\n\\n@keyframes spin_ad60 {\\n  0% {\\n    transform: rotate(0);\\n  }\\n\\n  100% {\\n    transform: rotate(360deg);\\n  }\\n}\\n\\n@keyframes pulse_c906 {\\n  0% {\\n    transform: scale(1);\\n  }\\n\\n  100% {\\n    transform: scale(1.41667);\\n  }\\n}\\n\\n.loader_d294,\\n.ring-loader-inline {\\n  /* needed for better backward-compatibility */\\n\\n  position: relative;\\n\\n  display: inline-block;\\n\\n  overflow: hidden;\\n\\n  transform: rotate(0);\\n  animation: spin_ad60 1s linear infinite;\\n  vertical-align: -3px;\\n\\n  border-radius: 8px;\\n}\\n\\n.loader_d294,\\n  .ring-loader-inline,\\n  .loader_d294::after,\\n  .ring-loader-inline::after {\\n    transform-origin: 50% 50%;\\n  }\\n\\n.loader_d294::after, .ring-loader-inline::after {\\n    display: block;\\n\\n    width: 16px;\\n    height: 16px;\\n\\n    content: \"\";\\n    animation: pulse_c906 0.85s cubic-bezier(0.68, 0, 0.74, 0.74) infinite alternate;\\n\\n    background-image: conic-gradient(#ff00eb, #bd3bff, #008eff, #58ba00, #f48700, #ff00eb);\\n\\n    background-image: conic-gradient(var(--ring-loader-inline-stops));\\n    -webkit-mask-image: radial-gradient(8px, transparent 71.875%, var(--ring-content-background-color) 71.875%);\\n            mask-image: radial-gradient(8px, transparent 71.875%, var(--ring-content-background-color) 71.875%);\\n  }\\n\\n.children_ece6 {\\n  margin-left: 4px;\\n}\\n`,\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/loader-inline/loader-inline.css\"],names:[],mappings:\"AAKA;EACE,6CAA6C;EAC7C,gFAAgF;AAClF;;AAEA;;EAEE,6CAA6C;EAC7C,gFAAgF;AAClF;;AAEA;EACE;IACE,oBAAoB;EACtB;;EAEA;IACE,yBAAyB;EAC3B;AACF;;AAEA;EACE;IACE,mBAAmB;EACrB;;EAEA;IACE,yBAA+B;EACjC;AACF;;AAEA;;EAEE,6CAA6C;;EAE7C,kBAAkB;;EAElB,qBAAqB;;EAErB,gBAAgB;;EAEhB,oBAAoB;EACpB,uCAAkC;EAClC,oBAAoB;;EAEpB,kBAAmB;AAmBrB;;AAjBE;;;;IAEE,yBAAyB;EAC3B;;AAEA;IACE,cAAc;;IAEd,WAAqB;IACrB,YAAsB;;IAEtB,WAAW;IACX,gFAA2E;;IAE3E,sFAAiE;;IAAjE,iEAAiE;IACjE,2GAAoG;YAApG,mGAAoG;EACtG;;AAGF;EACE,gBAA2B;AAC7B\",sourcesContent:['@import \"../global/variables.css\";\\n\\n@value dark from \"../global/variables_dark.css\";\\n@value unit from \"../global/global.css\";\\n\\n:root {\\n  /* stylelint-disable-next-line color-no-hex */\\n  --ring-loader-inline-stops: #ff00eb, #bd3bff, #008eff, #58ba00, #f48700, #ff00eb;\\n}\\n\\n.dark,\\n:global(.ring-ui-theme-dark) {\\n  /* stylelint-disable-next-line color-no-hex */\\n  --ring-loader-inline-stops: #ff2eef, #d178ff, #289fff, #88d444, #ffe000, #ff2eef;\\n}\\n\\n@keyframes spin {\\n  0% {\\n    transform: rotate(0);\\n  }\\n\\n  100% {\\n    transform: rotate(360deg);\\n  }\\n}\\n\\n@keyframes pulse {\\n  0% {\\n    transform: scale(1);\\n  }\\n\\n  100% {\\n    transform: scale(calc(17 / 12));\\n  }\\n}\\n\\n.loader,\\n:global(.ring-loader-inline) {\\n  /* needed for better backward-compatibility */\\n\\n  position: relative;\\n\\n  display: inline-block;\\n\\n  overflow: hidden;\\n\\n  transform: rotate(0);\\n  animation: spin 1s linear infinite;\\n  vertical-align: -3px;\\n\\n  border-radius: unit;\\n\\n  &,\\n  &::after {\\n    transform-origin: 50% 50%;\\n  }\\n\\n  &::after {\\n    display: block;\\n\\n    width: calc(unit * 2);\\n    height: calc(unit * 2);\\n\\n    content: \"\";\\n    animation: pulse 0.85s cubic-bezier(0.68, 0, 0.74, 0.74) infinite alternate;\\n\\n    background-image: conic-gradient(var(--ring-loader-inline-stops));\\n    mask-image: radial-gradient(unit, transparent 71.875%, var(--ring-content-background-color) 71.875%);\\n  }\\n}\\n\\n.children {\\n  margin-left: calc(unit / 2);\\n}\\n'],sourceRoot:\"\"}]),u.locals={dark:`${l.A.locals.dark}`,unit:`${c.default.locals.unit}`,loader:\"loader_d294\",spin:\"spin_ad60\",pulse:\"pulse_c906\",children:\"children_ece6\"};const p=u},8890:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),s=a()(o());s.i(c.A),s.i(l.default,\"\",!0),s.push([e.id,\".popup_f35e {\\n\\n  position: fixed;\\n  z-index: var(--ring-overlay-z-index);\\n  top: -100vh;\\n  left: -100vw;\\n\\n  overflow-y: auto;\\n\\n  box-sizing: border-box;\\n\\n  border: 1px solid var(--ring-popup-border-color);\\n  border-radius: var(--ring-border-radius);\\n\\n  background-color: var(--ring-popup-background-color);\\n  box-shadow: var(--ring-popup-shadow);\\n}\\n\\n.hidden_c587 {\\n  display: none;\\n}\\n\\n.showing_b07a {\\n  opacity: 0;\\n}\\n\\n.attached_ea95 {\\n  border-top: 0;\\n  border-top-left-radius: 0;\\n  border-top-right-radius: 0;\\n}\\n\",\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/popup/popup.css\"],names:[],mappings:\"AAEA;;EAGE,eAAe;EACf,oCAAoC;EACpC,WAAW;EACX,YAAY;;EAEZ,gBAAgB;;EAEhB,sBAAsB;;EAEtB,gDAAgD;EAChD,wCAAwC;;EAExC,oDAAoD;EACpD,oCAAoC;AACtC;;AAEA;EACE,aAAa;AACf;;AAEA;EACE,UAAU;AACZ;;AAEA;EACE,aAAa;EACb,yBAAyB;EACzB,0BAA0B;AAC5B\",sourcesContent:['@import \"../global/variables.css\";\\n\\n.popup {\\n  composes: font from \"../global/global.css\";\\n\\n  position: fixed;\\n  z-index: var(--ring-overlay-z-index);\\n  top: -100vh;\\n  left: -100vw;\\n\\n  overflow-y: auto;\\n\\n  box-sizing: border-box;\\n\\n  border: 1px solid var(--ring-popup-border-color);\\n  border-radius: var(--ring-border-radius);\\n\\n  background-color: var(--ring-popup-background-color);\\n  box-shadow: var(--ring-popup-shadow);\\n}\\n\\n.hidden {\\n  display: none;\\n}\\n\\n.showing {\\n  opacity: 0;\\n}\\n\\n.attached {\\n  border-top: 0;\\n  border-top-left-radius: 0;\\n  border-top-right-radius: 0;\\n}\\n'],sourceRoot:\"\"}]),s.locals={popup:`popup_f35e ${l.default.locals.font}`,hidden:\"hidden_c587\",showing:\"showing_b07a\",attached:\"attached_ea95\"};const u=s},4481:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),s=a()(o());s.i(c.A),s.i(l.default,\"\",!0),s.push([e.id,'@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.filterWithTagsFocused_ffbf.filterWithTagsFocused_ffbf:hover {\\n  border-color: var(--ring-main-color);\\n}}\\n\\n.filterWithTags_ff56 {\\n  overflow: hidden;\\n\\n  margin: 16px 8px 0;\\n  padding: 3px;\\n\\n  text-align: left;\\n\\n  border: 1px solid var(--ring-borders-color);\\n  border-radius: var(--ring-border-radius);\\n}\\n\\n.filterWithTags_ff56 .filterWrapper_dd63 {\\n    padding-right: 0;\\n    padding-left: 0;\\n\\n    border-bottom: none;\\n  }\\n\\n@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.filterWithTags_ff56:hover {\\n    border-color: var(--ring-border-hover-color);\\n  }}\\n\\n.filterWithTagsFocused_ffbf {\\n  border-color: var(--ring-main-color);\\n}\\n\\n.filterWithTagsInput_ab94 {\\n  padding: 0;\\n\\n  border: none;\\n}\\n\\n.filter_deda {\\n  flex-grow: 1;\\n\\n  width: 0;\\n}\\n\\n.popup_f21d {\\n  overscroll-behavior: contain;\\n}\\n\\n.filterWrapper_dd63 {\\n  position: relative;\\n\\n  display: flex;\\n\\n  margin: 0;\\n  padding-right: 8px;\\n  padding-left: 44px;\\n\\n  border-bottom: 1px solid var(--ring-borders-color);\\n}\\n\\n[dir=\"rtl\"] .filterWrapper_dd63 {\\n    padding-right: 44px;\\n    padding-left: 8px;\\n  }\\n\\n.filterIcon_b648 {\\n  position: absolute;\\n  top: 7px;\\n  left: 16px;\\n\\n  color: var(--ring-icon-color);\\n}\\n\\n[dir=\"rtl\"] .filterIcon_b648 {\\n    right: 16px;\\n    left: auto;\\n  }\\n\\n.bottomLine_c880 {\\n  text-align: center;\\n}\\n\\n.bottomLine_c880.bottomLineOverItem_dfb4 {\\n    position: relative;\\n\\n    z-index: var(--ring-fixed-z-index);\\n\\n    margin-top: -36px;\\n\\n    background-color: var(--ring-content-background-color);\\n  }\\n\\n.message_ccdf {\\n  display: inline-block;\\n\\n  margin: 8px 0;\\n  padding: 0 16px;\\n}\\n\\n.selectAll_ff5e {\\n  display: flex;\\n  justify-content: space-between;\\n\\n  padding: 8px 16px 0;\\n}\\n',\"\",{version:3,sources:[\"<no source>\",\"webpack://./node_modules/@jetbrains/ring-ui/components/select/select-popup.css\"],names:[],mappings:\"AAAA,wGAAA;EAAA,qCAAA;CAAA,CAAA;;ACIA;EACE,gBAAgB;;EAEhB,kBAA6B;EAC7B,YAAY;;EAEZ,gBAAgB;;EAEhB,2CAA2C;EAC3C,wCAAwC;AAY1C;;AAVE;IACE,gBAAgB;IAChB,eAAe;;IAEf,mBAAmB;EACrB;;ADpBF,wGAAA;IAAA,6CAAA;GAAA,CAAA;;AC2BA;EAEE,oCAAoC;AACtC;;AAEA;EACE,UAAU;;EAEV,YAAY;AACd;;AAEA;EACE,YAAY;;EAEZ,QAAQ;AACV;;AAEA;EACE,4BAA4B;AAC9B;;AAEA;EACE,kBAAkB;;EAElB,aAAa;;EAEb,SAAS;EACT,kBAAmB;EACnB,kBAA8B;;EAE9B,kDAAkD;AAMpD;;AAJE;IACE,mBAA+B;IAC/B,iBAAkB;EACpB;;AAGF;EACE,kBAAkB;EAClB,QAAQ;EACR,UAAoB;;EAEpB,6BAA6B;AAM/B;;AAJE;IACE,WAAqB;IACrB,UAAU;EACZ;;AAGF;EACE,kBAAkB;AAWpB;;AATE;IACE,kBAAkB;;IAElB,kCAAkC;;IAElC,iBAAiB;;IAEjB,sDAAsD;EACxD;;AAGF;EACE,qBAAqB;;EAErB,aAAc;EACd,eAAyB;AAC3B;;AAEA;EACE,aAAa;EACb,8BAA8B;;EAE9B,mBAAmB;AACrB\",sourcesContent:[null,'@import \"../global/variables.css\";\\n\\n@value unit from \"../global/global.css\";\\n\\n.filterWithTags {\\n  overflow: hidden;\\n\\n  margin: calc(unit * 2) unit 0;\\n  padding: 3px;\\n\\n  text-align: left;\\n\\n  border: 1px solid var(--ring-borders-color);\\n  border-radius: var(--ring-border-radius);\\n\\n  & .filterWrapper {\\n    padding-right: 0;\\n    padding-left: 0;\\n\\n    border-bottom: none;\\n  }\\n\\n  &:hover {\\n    border-color: var(--ring-border-hover-color);\\n  }\\n}\\n\\n.filterWithTagsFocused,\\n.filterWithTagsFocused.filterWithTagsFocused:hover {\\n  border-color: var(--ring-main-color);\\n}\\n\\n.filterWithTagsInput {\\n  padding: 0;\\n\\n  border: none;\\n}\\n\\n.filter {\\n  flex-grow: 1;\\n\\n  width: 0;\\n}\\n\\n.popup {\\n  overscroll-behavior: contain;\\n}\\n\\n.filterWrapper {\\n  position: relative;\\n\\n  display: flex;\\n\\n  margin: 0;\\n  padding-right: unit;\\n  padding-left: calc(unit * 5.5);\\n\\n  border-bottom: 1px solid var(--ring-borders-color);\\n\\n  [dir=\"rtl\"] & {\\n    padding-right: calc(unit * 5.5);\\n    padding-left: unit;\\n  }\\n}\\n\\n.filterIcon {\\n  position: absolute;\\n  top: 7px;\\n  left: calc(unit * 2);\\n\\n  color: var(--ring-icon-color);\\n\\n  [dir=\"rtl\"] & {\\n    right: calc(unit * 2);\\n    left: auto;\\n  }\\n}\\n\\n.bottomLine {\\n  text-align: center;\\n\\n  &.bottomLineOverItem {\\n    position: relative;\\n\\n    z-index: var(--ring-fixed-z-index);\\n\\n    margin-top: -36px;\\n\\n    background-color: var(--ring-content-background-color);\\n  }\\n}\\n\\n.message {\\n  display: inline-block;\\n\\n  margin: unit 0;\\n  padding: 0 calc(2 * unit);\\n}\\n\\n.selectAll {\\n  display: flex;\\n  justify-content: space-between;\\n\\n  padding: 8px 16px 0;\\n}\\n'],sourceRoot:\"\"}]),s.locals={unit:`${l.default.locals.unit}`,filterWithTagsFocused:\"filterWithTagsFocused_ffbf\",filterWithTags:\"filterWithTags_ff56\",filterWrapper:\"filterWrapper_dd63\",filterWithTagsInput:\"filterWithTagsInput_ab94\",filter:\"filter_deda\",popup:\"popup_f21d\",filterIcon:\"filterIcon_b648\",bottomLine:\"bottomLine_c880\",bottomLineOverItem:\"bottomLineOverItem_dfb4\",message:\"message_ccdf\",selectAll:\"selectAll_ff5e\"};const u=s},2636:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>p});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(9892),s=t(5280),u=a()(o());u.i(s.A),u.i(l.default,\"\",!0),u.i(c.default,\"\",!0),u.push([e.id,'@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.select_e2a5:hover .value_b3a3,\\n.select_e2a5:hover .icons_c4a9 {\\n  transition: none;\\n\\n  color: var(--ring-main-color);\\n}}\\n\\n.select_e2a5 {\\n  position: relative;\\n\\n  display: inline-block;\\n\\n  white-space: nowrap;\\n\\n  color: var(--ring-text-color);\\n}\\n\\n.toolbar_d3be {\\n  border-top: 1px solid var(--ring-line-color);\\n}\\n\\n.button_ef00 {\\n  width: 100%;\\n  padding: 0;\\n\\n  text-align: left;\\n}\\n\\n[dir=\"rtl\"] .button_ef00 {\\n    text-align: right;\\n    direction: ltr;\\n  }\\n\\n.toolbar_d3be .button_ef00 {\\n    height: 32px;\\n    margin: 8px 0;\\n  }\\n\\n.button_ef00.buttonSpaced_f316 {\\n    padding: 0 16px;\\n  }\\n\\n.icons_c4a9 {\\n  position: absolute;\\n  top: 0;\\n  right: 5px;\\n  bottom: 0;\\n\\n  transition: color var(--ring-ease);\\n\\n  color: var(--ring-icon-secondary-color);\\n\\n  line-height: normal;\\n}\\n\\n.inputMode_a6f6 .icons_c4a9 {\\n    font-size: var(--ring-font-size);\\n  }\\n\\n.selectedIcon_a62c {\\n\\n  position: relative;\\n  top: 3px;\\n\\n  display: inline-block;\\n\\n  width: 16px;\\n  height: 16px;\\n  margin: 0 4px;\\n\\n  background-repeat: no-repeat;\\n  background-position: center;\\n\\n  background-size: contain;\\n}\\n\\n.clearIcon_c750 {\\n  padding: 0 3px;\\n\\n  vertical-align: -2px;\\n}\\n\\n.sizeS_e8c3 {\\n  width: 96px;\\n}\\n\\n.sizeM_ed34 {\\n  width: 240px;\\n}\\n\\n.sizeL_c053 {\\n  width: 400px;\\n}\\n\\n.sizeFULL_c585 {\\n  width: 100%;\\n}\\n\\n.sizeAUTO_a07c {\\n  max-width: 100%;\\n}\\n\\n.buttonMode_dd69 {\\n  position: relative;\\n\\n  cursor: pointer;\\n}\\n\\n.value_b3a3 {\\n\\n  display: inline-block;\\n\\n  box-sizing: border-box;\\n  width: 100%;\\n  height: 33px;\\n  padding: 0 0 3px;\\n\\n  cursor: pointer;\\n  transition: color var(--ring-ease), border-color var(--ring-ease);\\n  text-align: left;\\n  vertical-align: top;\\n\\n  color: var(--ring-text-color);\\n\\n  border: none;\\n  border-bottom: 1px solid var(--ring-borders-color);\\n  outline: none;\\n  background: transparent;\\n}\\n\\n.value_b3a3:focus {\\n    border-color: var(--ring-main-color);\\n  }\\n\\n.value_b3a3.open_f1b1,\\n  .value_b3a3:active {\\n    border-color: transparent;\\n  }\\n\\n.value_b3a3::-moz-focus-inner {\\n    padding: 0;\\n\\n    border: 0;\\n    outline: 0;\\n  }\\n\\n.buttonContainer_b2b9 {\\n  position: relative;\\n\\n  font-size: var(--ring-font-size);\\n}\\n\\n.buttonValue_b4ad {\\n\\n  display: block;\\n\\n  width: 100%;\\n  padding-left: 8px;\\n\\n  text-align: left;\\n  vertical-align: -8px;\\n}\\n\\n.buttonValue_b4ad:focus-visible {\\n  box-shadow: inset 0 0 0 1px var(--ring-main-color);\\n}\\n\\n.buttonValueOpen_d9d3.buttonValueOpen_d9d3 {\\n  box-shadow: inset 0 0 0 1px var(--ring-main-color);\\n}\\n\\n.buttonValueEmpty_e6b3.buttonValueEmpty_e6b3 {\\n  color: var(--ring-disabled-color);\\n}\\n\\n.heightS_b721 .buttonValue_b4ad {\\n  font-size: var(--ring-font-size);\\n}\\n\\n.label_e56f {\\n  position: relative;\\n\\n  color: var(--ring-secondary-color);\\n}\\n\\n:focus-visible + .icons_c4a9,\\n.value_b3a3:focus,\\n.value_b3a3:focus + .icons_c4a9,\\n.open_f1b1,\\n.open_f1b1 + .icons_c4a9,\\n.buttonValueOpen_d9d3 + .icons_c4a9 {\\n  transition: none;\\n\\n  color: var(--ring-main-color);\\n}\\n\\n.disabled_b89f {\\n  pointer-events: none;\\n\\n  color: var(--ring-disabled-color);\\n}\\n\\n.disabled_b89f .value_b3a3 {\\n    color: var(--ring-disabled-color);\\n    border-bottom-style: dashed;\\n  }\\n\\n.avatar_f4dd {\\n  margin-right: 4px;\\n\\n  vertical-align: -5px;\\n}\\n\\n.popup_acec {\\n  min-width: 240px;\\n  max-width: 320px;\\n}\\n\\n.chevron_d51f.chevron_d51f {\\n  padding: 0 3px;\\n\\n  transition: none;\\n  vertical-align: -1px;\\n\\n  color: inherit;\\n}\\n\\n.chevronIcon_f6cf.chevronIcon_f6cf {\\n  transition: none;\\n\\n  color: inherit;\\n}\\n',\"\",{version:3,sources:[\"<no source>\",\"webpack://./node_modules/@jetbrains/ring-ui/components/select/select.css\"],names:[],mappings:\"AAAA,wGAAA;;EAAA,iBAAA;;EAAA,8BAAA;CAAA,CAAA;;ACKA;EACE,kBAAkB;;EAElB,qBAAqB;;EAErB,mBAAmB;;EAEnB,6BAA6B;AAC/B;;AAEA;EACE,4CAA4C;AAC9C;;AAEA;EACE,WAAW;EACX,UAAU;;EAEV,gBAAgB;AAelB;;AAbE;IACE,iBAAiB;IACjB,cAAc;EAChB;;AAEA;IACE,YAAsB;IACtB,aAAc;EAChB;;AAEA;IACE,eAAyB;EAC3B;;AAGF;EACE,kBAAkB;EAClB,MAAM;EACN,UAAU;EACV,SAAS;;EAET,kCAAkC;;EAElC,uCAAuC;;EAEvC,mBAAmB;AAKrB;;AAHE;IACE,gCAAgC;EAClC;;AAGF;;EAGE,kBAAkB;EAClB,QAAQ;;EAER,qBAAqB;;EAErB,WAAqB;EACrB,YAAsB;EACtB,aAAa;;EAEb,4BAA4B;EAC5B,2BAA2B;;EAE3B,wBAAwB;AAC1B;;AAEA;EACE,cAAc;;EAEd,oBAAoB;AACtB;;AAEA;EACE,WAAsB;AACxB;;AAEA;EACE,YAAsB;AACxB;;AAEA;EACE,YAAsB;AACxB;;AAEA;EACE,WAAW;AACb;;AAEA;EACE,eAAe;AACjB;;AAEA;EACE,kBAAkB;;EAElB,eAAe;AACjB;;AAEA;;EAIE,qBAAqB;;EAErB,sBAAsB;EACtB,WAAW;EACX,YAA4B;EAC5B,gBAAgB;;EAEhB,eAAe;EACf,iEAAiE;EACjE,gBAAgB;EAChB,mBAAmB;;EAEnB,6BAA6B;;EAE7B,YAAY;EACZ,kDAAkD;EAClD,aAAa;EACb,uBAAuB;AAiBzB;;AAfE;IACE,oCAAoC;EACtC;;AAEA;;IAEE,yBAAyB;EAC3B;;AAEA;IACE,UAAU;;IAEV,SAAS;IACT,UAAU;EACZ;;AAGF;EACE,kBAAkB;;EAElB,gCAAgC;AAClC;;AAEA;;EAGE,cAAc;;EAEd,WAAW;EACX,iBAAkB;;EAElB,gBAAgB;EAChB,oBAA8B;AAChC;;AAEA;EACE,kDAAgD;AAClD;;AAEA;EACE,kDAAgD;AAClD;;AAEA;EACE,iCAAiC;AACnC;;AAEA;EACE,gCAAgC;AAClC;;AAEA;EACE,kBAAkB;;EAElB,kCAAkC;AACpC;;AAEA;;;;;;EAQE,gBAAgB;;EAEhB,6BAA6B;AAC/B;;AAEA;EACE,oBAAoB;;EAEpB,iCAAiC;AAMnC;;AAJE;IACE,iCAAiC;IACjC,2BAA2B;EAC7B;;AAGF;EACE,iBAAiB;;EAEjB,oBAAoB;AACtB;;AAEA;EACE,gBAA0B;EAC1B,gBAA0B;AAC5B;;AAEA;EACE,cAAc;;EAEd,gBAAgB;EAChB,oBAAoB;;EAEpB,cAAc;AAChB;;AAEA;EACE,gBAAgB;;EAEhB,cAAc;AAChB\",sourcesContent:[null,'@import \"../global/variables.css\";\\n\\n@value unit from \"../global/global.css\";\\n@value button-shadow from \"../button/button.css\";\\n\\n.select {\\n  position: relative;\\n\\n  display: inline-block;\\n\\n  white-space: nowrap;\\n\\n  color: var(--ring-text-color);\\n}\\n\\n.toolbar {\\n  border-top: 1px solid var(--ring-line-color);\\n}\\n\\n.button {\\n  width: 100%;\\n  padding: 0;\\n\\n  text-align: left;\\n\\n  [dir=\"rtl\"] & {\\n    text-align: right;\\n    direction: ltr;\\n  }\\n\\n  .toolbar & {\\n    height: calc(4 * unit);\\n    margin: unit 0;\\n  }\\n\\n  &.buttonSpaced {\\n    padding: 0 calc(2 * unit);\\n  }\\n}\\n\\n.icons {\\n  position: absolute;\\n  top: 0;\\n  right: 5px;\\n  bottom: 0;\\n\\n  transition: color var(--ring-ease);\\n\\n  color: var(--ring-icon-secondary-color);\\n\\n  line-height: normal;\\n\\n  .inputMode & {\\n    font-size: var(--ring-font-size);\\n  }\\n}\\n\\n.selectedIcon {\\n  composes: resetButton from \"../global/global.css\";\\n\\n  position: relative;\\n  top: 3px;\\n\\n  display: inline-block;\\n\\n  width: calc(2 * unit);\\n  height: calc(2 * unit);\\n  margin: 0 4px;\\n\\n  background-repeat: no-repeat;\\n  background-position: center;\\n\\n  background-size: contain;\\n}\\n\\n.clearIcon {\\n  padding: 0 3px;\\n\\n  vertical-align: -2px;\\n}\\n\\n.sizeS {\\n  width: calc(unit * 12);\\n}\\n\\n.sizeM {\\n  width: calc(unit * 30);\\n}\\n\\n.sizeL {\\n  width: calc(unit * 50);\\n}\\n\\n.sizeFULL {\\n  width: 100%;\\n}\\n\\n.sizeAUTO {\\n  max-width: 100%;\\n}\\n\\n.buttonMode {\\n  position: relative;\\n\\n  cursor: pointer;\\n}\\n\\n.value {\\n  composes: ellipsis from \"../global/global.css\";\\n  composes: font from \"../global/global.css\";\\n\\n  display: inline-block;\\n\\n  box-sizing: border-box;\\n  width: 100%;\\n  height: calc(unit * 4 + 1px);\\n  padding: 0 0 3px;\\n\\n  cursor: pointer;\\n  transition: color var(--ring-ease), border-color var(--ring-ease);\\n  text-align: left;\\n  vertical-align: top;\\n\\n  color: var(--ring-text-color);\\n\\n  border: none;\\n  border-bottom: 1px solid var(--ring-borders-color);\\n  outline: none;\\n  background: transparent;\\n\\n  &:focus {\\n    border-color: var(--ring-main-color);\\n  }\\n\\n  &.open,\\n  &:active {\\n    border-color: transparent;\\n  }\\n\\n  &::-moz-focus-inner {\\n    padding: 0;\\n\\n    border: 0;\\n    outline: 0;\\n  }\\n}\\n\\n.buttonContainer {\\n  position: relative;\\n\\n  font-size: var(--ring-font-size);\\n}\\n\\n.buttonValue {\\n  composes: ellipsis from \"../global/global.css\";\\n\\n  display: block;\\n\\n  width: 100%;\\n  padding-left: unit;\\n\\n  text-align: left;\\n  vertical-align: calc(0 - unit);\\n}\\n\\n.buttonValue:focus-visible {\\n  box-shadow: button-shadow var(--ring-main-color);\\n}\\n\\n.buttonValueOpen.buttonValueOpen {\\n  box-shadow: button-shadow var(--ring-main-color);\\n}\\n\\n.buttonValueEmpty.buttonValueEmpty {\\n  color: var(--ring-disabled-color);\\n}\\n\\n.heightS .buttonValue {\\n  font-size: var(--ring-font-size);\\n}\\n\\n.label {\\n  position: relative;\\n\\n  color: var(--ring-secondary-color);\\n}\\n\\n.select:hover .value,\\n.select:hover .icons,\\n:focus-visible + .icons,\\n.value:focus,\\n.value:focus + .icons,\\n.open,\\n.open + .icons,\\n.buttonValueOpen + .icons {\\n  transition: none;\\n\\n  color: var(--ring-main-color);\\n}\\n\\n.disabled {\\n  pointer-events: none;\\n\\n  color: var(--ring-disabled-color);\\n\\n  & .value {\\n    color: var(--ring-disabled-color);\\n    border-bottom-style: dashed;\\n  }\\n}\\n\\n.avatar {\\n  margin-right: 4px;\\n\\n  vertical-align: -5px;\\n}\\n\\n.popup {\\n  min-width: calc(unit * 30);\\n  max-width: calc(unit * 40);\\n}\\n\\n.chevron.chevron {\\n  padding: 0 3px;\\n\\n  transition: none;\\n  vertical-align: -1px;\\n\\n  color: inherit;\\n}\\n\\n.chevronIcon.chevronIcon {\\n  transition: none;\\n\\n  color: inherit;\\n}\\n'],sourceRoot:\"\"}]),u.locals={unit:`${l.default.locals.unit}`,\"button-shadow\":`${c.default.locals[\"button-shadow\"]}`,select:\"select_e2a5\",value:`value_b3a3 ${l.default.locals.ellipsis} ${l.default.locals.font}`,icons:\"icons_c4a9\",toolbar:\"toolbar_d3be\",button:\"button_ef00\",buttonSpaced:\"buttonSpaced_f316\",inputMode:\"inputMode_a6f6\",selectedIcon:`selectedIcon_a62c ${l.default.locals.resetButton}`,clearIcon:\"clearIcon_c750\",sizeS:\"sizeS_e8c3\",sizeM:\"sizeM_ed34\",sizeL:\"sizeL_c053\",sizeFULL:\"sizeFULL_c585\",sizeAUTO:\"sizeAUTO_a07c\",buttonMode:\"buttonMode_dd69\",open:\"open_f1b1\",buttonContainer:\"buttonContainer_b2b9\",buttonValue:`buttonValue_b4ad ${l.default.locals.ellipsis}`,buttonValueOpen:\"buttonValueOpen_d9d3\",buttonValueEmpty:\"buttonValueEmpty_e6b3\",heightS:\"heightS_b721\",label:\"label_e56f\",disabled:\"disabled_b89f\",avatar:\"avatar_f4dd\",popup:\"popup_acec\",chevron:\"chevron_d51f\",chevronIcon:\"chevronIcon_f6cf\"};const p=u},8102:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(5280),c=a()(o());c.i(l.A),c.push([e.id,\".trapButton_c32e {\\n  position: absolute;\\n  left: -9999px;\\n}\\n\",\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/tab-trap/tab-trap.css\"],names:[],mappings:\"AAEA;EACE,kBAAkB;EAClB,aAAa;AACf\",sourcesContent:['@import \"../global/variables.css\";\\n\\n.trapButton {\\n  position: absolute;\\n  left: -9999px;\\n}\\n'],sourceRoot:\"\"}]),c.locals={trapButton:\"trapButton_c32e\"};const s=c},4561:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),s=a()(o());s.i(c.A),s.i(l.default,\"\",!0),s.push([e.id,'@media (hover: hover), (-moz-touch-enabled: 0), (-ms-high-contrast: none), (-ms-high-contrast: active) {.tag_b7aa:hover,\\n.tagAngled_c869:hover::before {\\n  transition: none;\\n\\n  background-color: var(--ring-tag-hover-background-color);\\n}}\\n\\n.tag_b7aa {\\n\\n  position: relative;\\n  z-index: 1;\\n\\n  display: inline-flex;\\n\\n  box-sizing: border-box;\\n  max-width: 100%;\\n  height: 20px;\\n\\n  padding: 0 8px;\\n\\n  cursor: pointer;\\n\\n  vertical-align: top;\\n\\n  color: var(--ring-text-color);\\n\\n  border: none;\\n  border-radius: var(--ring-border-radius);\\n\\n  font-size: 12px;\\n  line-height: var(--ring-line-height);\\n}\\n\\n.tag_b7aa,\\n.tagAngled_c869::before {\\n  transition: background-color var(--ring-ease);\\n\\n  background-color: var(--ring-tag-background-color);\\n}\\n\\n.withRemove_c0a5 {\\n  padding-right: 22px;\\n}\\n\\n.container_cb34 {\\n  position: relative;\\n\\n  display: inline-block;\\n\\n  max-width: calc(100% - 4px);\\n\\n  margin-right: 4px;\\n\\n  white-space: nowrap;\\n}\\n\\n.focused_fd92,\\n.tag_b7aa:focus-visible {\\n  position: relative;\\n\\n  outline: none;\\n  box-shadow: 0 0 0 2px var(--ring-border-hover-color);\\n}\\n\\n.focused_fd92,\\n.focused_fd92.tagAngled_c869::before,\\n.tag_b7aa:focus-visible,\\n.tagAngled_c869:focus-visible::before {\\n  transition: none;\\n\\n  background-color: var(--ring-tag-hover-background-color);\\n}\\n\\n.tagAngled_c869 {\\n  /* it needs to fix vertical alignment broken by \"overflow: hidden\". Remove this class, when IE11 will be deprecated */\\n\\n  margin-bottom: -5px !important;\\n\\n  margin-left: 8px;\\n  padding-left: 4px;\\n\\n  border-top-left-radius: 0;\\n  border-bottom-left-radius: 0;\\n}\\n\\n.tagAngled_c869::before {\\n    position: absolute;\\n    z-index: -1;\\n    top: 0;\\n    left: 0;\\n\\n    box-sizing: border-box;\\n    width: 12px;\\n    height: 12px;\\n\\n    content: \"\";\\n    transform: scaleY(1.177) rotate(45deg);\\n    transform-origin: 0 0;\\n\\n    border: none;\\n  }\\n\\n.tagAngled_c869.focused_fd92,\\n  .tagAngled_c869:focus {\\n    box-shadow: 0 0 0 1px var(--ring-border-hover-color) inset, 0 0 0 1px var(--ring-border-hover-color);\\n  }\\n\\n.tagAngled_c869:focus::before {\\n    box-shadow:\\n      1px -1px var(--ring-border-hover-color) inset,\\n      -0.8px 0.8px 0 0.5px var(--ring-border-hover-color);\\n  }\\n\\n.content_a838 {\\n}\\n\\n.disabled_b740.tag_b7aa,\\n.disabled_b740.tagAngled_c869::before {\\n  pointer-events: none;\\n\\n  color: var(--ring-disabled-color);\\n  background-color: var(--ring-disabled-background-color);\\n}\\n\\n.remove_eff8 {\\n  position: absolute;\\n  z-index: 1;\\n  top: 2px;\\n  right: 0;\\n\\n  height: auto;\\n  padding: 0 4px;\\n\\n  line-height: 16px;\\n}\\n\\n.removeIcon_accf.removeIcon_accf {\\n  color: var(--ring-icon-secondary-color);\\n}\\n\\n.icon_e877 {\\n  margin-right: 6px;\\n\\n  color: var(--ring-icon-secondary-color);\\n}\\n\\n.icon_e877 svg {\\n    vertical-align: -3px;\\n  }\\n\\n.avatarContainer_ee1b {\\n  display: inline-block;\\n  overflow: hidden;\\n\\n  box-sizing: border-box;\\n  width: 20px;\\n  height: 20px;\\n  margin-right: 4px;\\n  margin-left: -8px;\\n\\n  vertical-align: top;\\n\\n  border-top-left-radius: var(--ring-border-radius);\\n  border-bottom-left-radius: var(--ring-border-radius);\\n}\\n\\n.customIcon_ac93 {\\n  max-width: 16px;\\n  max-height: 16px;\\n\\n  margin-right: 4px;\\n\\n  vertical-align: bottom;\\n}\\n\\n.avatarIcon_a8ff {\\n  width: 20px;\\n\\n  margin-right: -4px;\\n\\n  -o-object-fit: contain;\\n\\n     object-fit: contain;\\n  -o-object-position: center;\\n     object-position: center;\\n}\\n',\"\",{version:3,sources:[\"<no source>\",\"webpack://./node_modules/@jetbrains/ring-ui/components/tag/tag.css\"],names:[],mappings:\"AAAA,wGAAA;;EAAA,iBAAA;;EAAA,yDAAA;CAAA,CAAA;;ACKA;;EAGE,kBAAkB;EAClB,UAAU;;EAEV,oBAAoB;;EAEpB,sBAAsB;EACtB,eAAe;EACf,YAAkB;;EAElB,cAAe;;EAEf,eAAe;;EAEf,mBAAmB;;EAEnB,6BAA6B;;EAE7B,YAAY;EACZ,wCAAwC;;EAExC,eAAe;EACf,oCAAoC;AACtC;;AAEA;;EAEE,6CAA6C;;EAE7C,kDAAkD;AACpD;;AAEA;EACE,mBAAmB;AACrB;;AAEA;EACE,kBAAkB;;EAElB,qBAAqB;;EAErB,2BAAgC;;EAEhC,iBAA4B;;EAE5B,mBAAmB;AACrB;;AAEA;;EAEE,kBAAkB;;EAElB,aAAa;EACb,oDAAoD;AACtD;;AAEA;;;;EAME,gBAAgB;;EAEhB,wDAAwD;AAC1D;;AAEA;EACE,qHAAqH;;EAErH,8BAA8B;;EAE9B,gBAAiB;EACjB,iBAA4B;;EAE5B,yBAAyB;EACzB,4BAA4B;AA6B9B;;AA3BE;IACE,kBAAkB;IAClB,WAAW;IACX,MAAM;IACN,OAAO;;IAEP,sBAAsB;IACtB,WAAW;IACX,YAAY;;IAEZ,WAAW;IACX,sCAAsC;IACtC,qBAAqB;;IAErB,YAAY;EACd;;AAEA;;IAEE,oGAAoG;EACtG;;AAEA;IACE;;yDAEqD;EACvD;;AAGF;AAEA;;AAEA;;EAEE,oBAAoB;;EAEpB,iCAAiC;EACjC,uDAAuD;AACzD;;AAEA;EACE,kBAAkB;EAClB,UAAU;EACV,QAAQ;EACR,QAAQ;;EAER,YAAY;EACZ,cAAyB;;EAEzB,iBAA2B;AAC7B;;AAEA;EACE,uCAAuC;AACzC;;AAEA;EACE,iBAAiB;;EAEjB,uCAAuC;AAKzC;;AAHE;IACE,oBAAoB;EACtB;;AAGF;EACE,qBAAqB;EACrB,gBAAgB;;EAEhB,sBAAsB;EACtB,WAAiB;EACjB,YAAkB;EAClB,iBAA4B;EAC5B,iBAA2B;;EAE3B,mBAAmB;;EAEnB,iDAAiD;EACjD,oDAAoD;AACtD;;AAEA;EACE,eAAyB;EACzB,gBAA0B;;EAE1B,iBAA4B;;EAE5B,sBAAsB;AACxB;;AAEA;EACE,WAAiB;;EAEjB,kBAAkB;;EAElB,sBAAmB;;KAAnB,mBAAmB;EACnB,0BAAuB;KAAvB,uBAAuB;AACzB\",sourcesContent:[null,'@import \"../global/variables.css\";\\n\\n@value unit from \"../global/global.css\";\\n@value max-height: 20px;\\n\\n.tag {\\n  composes: resetButton from \"../global/global.css\";\\n\\n  position: relative;\\n  z-index: 1;\\n\\n  display: inline-flex;\\n\\n  box-sizing: border-box;\\n  max-width: 100%;\\n  height: max-height;\\n\\n  padding: 0 unit;\\n\\n  cursor: pointer;\\n\\n  vertical-align: top;\\n\\n  color: var(--ring-text-color);\\n\\n  border: none;\\n  border-radius: var(--ring-border-radius);\\n\\n  font-size: 12px;\\n  line-height: var(--ring-line-height);\\n}\\n\\n.tag,\\n.tagAngled::before {\\n  transition: background-color var(--ring-ease);\\n\\n  background-color: var(--ring-tag-background-color);\\n}\\n\\n.withRemove {\\n  padding-right: 22px;\\n}\\n\\n.container {\\n  position: relative;\\n\\n  display: inline-block;\\n\\n  max-width: calc(100% - unit / 2);\\n\\n  margin-right: calc(unit / 2);\\n\\n  white-space: nowrap;\\n}\\n\\n.focused,\\n.tag:focus-visible {\\n  position: relative;\\n\\n  outline: none;\\n  box-shadow: 0 0 0 2px var(--ring-border-hover-color);\\n}\\n\\n.focused,\\n.focused.tagAngled::before,\\n.tag:focus-visible,\\n.tagAngled:focus-visible::before,\\n.tag:hover,\\n.tagAngled:hover::before {\\n  transition: none;\\n\\n  background-color: var(--ring-tag-hover-background-color);\\n}\\n\\n.tagAngled {\\n  /* it needs to fix vertical alignment broken by \"overflow: hidden\". Remove this class, when IE11 will be deprecated */\\n\\n  margin-bottom: -5px !important;\\n\\n  margin-left: unit;\\n  padding-left: calc(unit / 2);\\n\\n  border-top-left-radius: 0;\\n  border-bottom-left-radius: 0;\\n\\n  &::before {\\n    position: absolute;\\n    z-index: -1;\\n    top: 0;\\n    left: 0;\\n\\n    box-sizing: border-box;\\n    width: 12px;\\n    height: 12px;\\n\\n    content: \"\";\\n    transform: scaleY(1.177) rotate(45deg);\\n    transform-origin: 0 0;\\n\\n    border: none;\\n  }\\n\\n  &.focused,\\n  &:focus {\\n    box-shadow: 0 0 0 1px var(--ring-border-hover-color) inset, 0 0 0 1px var(--ring-border-hover-color);\\n  }\\n\\n  &:focus::before {\\n    box-shadow:\\n      1px -1px var(--ring-border-hover-color) inset,\\n      -0.8px 0.8px 0 0.5px var(--ring-border-hover-color);\\n  }\\n}\\n\\n.content {\\n  composes: ellipsis from \"../global/global.css\";\\n}\\n\\n.disabled.tag,\\n.disabled.tagAngled::before {\\n  pointer-events: none;\\n\\n  color: var(--ring-disabled-color);\\n  background-color: var(--ring-disabled-background-color);\\n}\\n\\n.remove {\\n  position: absolute;\\n  z-index: 1;\\n  top: 2px;\\n  right: 0;\\n\\n  height: auto;\\n  padding: 0 calc(unit / 2);\\n\\n  line-height: calc(unit * 2);\\n}\\n\\n.removeIcon.removeIcon {\\n  color: var(--ring-icon-secondary-color);\\n}\\n\\n.icon {\\n  margin-right: 6px;\\n\\n  color: var(--ring-icon-secondary-color);\\n\\n  & svg {\\n    vertical-align: -3px;\\n  }\\n}\\n\\n.avatarContainer {\\n  display: inline-block;\\n  overflow: hidden;\\n\\n  box-sizing: border-box;\\n  width: max-height;\\n  height: max-height;\\n  margin-right: calc(unit / 2);\\n  margin-left: calc(0 - unit);\\n\\n  vertical-align: top;\\n\\n  border-top-left-radius: var(--ring-border-radius);\\n  border-bottom-left-radius: var(--ring-border-radius);\\n}\\n\\n.customIcon {\\n  max-width: calc(unit * 2);\\n  max-height: calc(unit * 2);\\n\\n  margin-right: calc(unit / 2);\\n\\n  vertical-align: bottom;\\n}\\n\\n.avatarIcon {\\n  width: max-height;\\n\\n  margin-right: -4px;\\n\\n  object-fit: contain;\\n  object-position: center;\\n}\\n'],sourceRoot:\"\"}]),s.locals={unit:`${l.default.locals.unit}`,\"max-height\":\"20px\",tag:`tag_b7aa ${l.default.locals.resetButton}`,tagAngled:\"tagAngled_c869\",withRemove:\"withRemove_c0a5\",container:\"container_cb34\",focused:\"focused_fd92\",content:`content_a838 ${l.default.locals.ellipsis}`,disabled:\"disabled_b740\",remove:\"remove_eff8\",removeIcon:\"removeIcon_accf\",icon:\"icon_e877\",avatarContainer:\"avatarContainer_ee1b\",customIcon:\"customIcon_ac93\",avatarIcon:\"avatarIcon_a8ff\"};const u=s},6162:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>s});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(5280),c=a()(o());c.i(l.A),c.push([e.id,\".text_f1dc {\\n  color: var(--ring-text-color);\\n}\\n\\n.sizeS_b3aa {\\n  font-size: var(--ring-font-size-smaller);\\n}\\n\\n.sizeM_ae72 {\\n  font-size: var(--ring-font-size);\\n}\\n\\n.sizeL_f259 {\\n  font-size: var(--ring-font-size-larger);\\n}\\n\\n.info_c0a4 {\\n  color: var(--ring-secondary-color);\\n}\\n\",\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/text/text.css\"],names:[],mappings:\"AAEA;EACE,6BAA6B;AAC/B;;AAEA;EACE,wCAAwC;AAC1C;;AAEA;EACE,gCAAgC;AAClC;;AAEA;EACE,uCAAuC;AACzC;;AAEA;EACE,kCAAkC;AACpC\",sourcesContent:['@import \"../global/variables.css\";\\n\\n.text {\\n  color: var(--ring-text-color);\\n}\\n\\n.sizeS {\\n  font-size: var(--ring-font-size-smaller);\\n}\\n\\n.sizeM {\\n  font-size: var(--ring-font-size);\\n}\\n\\n.sizeL {\\n  font-size: var(--ring-font-size-larger);\\n}\\n\\n.info {\\n  color: var(--ring-secondary-color);\\n}\\n'],sourceRoot:\"\"}]),c.locals={text:\"text_f1dc\",sizeS:\"sizeS_b3aa\",sizeM:\"sizeM_ae72\",sizeL:\"sizeL_f259\",info:\"info_c0a4\"};const s=c},938:(e,n,t)=>{\"use strict\";t.r(n),t.d(n,{default:()=>u});var r=t(1404),o=t.n(r),i=t(7156),a=t.n(i),l=t(9106),c=t(5280),s=a()(o());s.i(c.A),s.i(l.default,\"\",!0),s.push([e.id,\".tooltip_fbfb {\\n  max-width: 400px;\\n  padding: 8px;\\n\\n  text-align: left;\\n\\n  color: var(--ring-text-color);\\n}\\n\\n.long_b7a5 {\\n  padding: 8px 12px;\\n\\n  font-size: var(--ring-font-size-smaller);\\n  line-height: var(--ring-line-height-lowest);\\n}\\n\",\"\",{version:3,sources:[\"webpack://./node_modules/@jetbrains/ring-ui/components/tooltip/tooltip.css\"],names:[],mappings:\"AAIA;EACE,gBAA0B;EAC1B,YAAa;;EAEb,gBAAgB;;EAEhB,6BAA6B;AAC/B;;AAEA;EACE,iBAA8B;;EAE9B,wCAAwC;EACxC,2CAA2C;AAC7C\",sourcesContent:['@import \"../global/variables.css\";\\n\\n@value unit from \"../global/global.css\";\\n\\n.tooltip {\\n  max-width: calc(unit * 50);\\n  padding: unit;\\n\\n  text-align: left;\\n\\n  color: var(--ring-text-color);\\n}\\n\\n.long {\\n  padding: unit calc(unit * 1.5);\\n\\n  font-size: var(--ring-font-size-smaller);\\n  line-height: var(--ring-line-height-lowest);\\n}\\n'],sourceRoot:\"\"}]),s.locals={unit:`${l.default.locals.unit}`,tooltip:\"tooltip_fbfb\",long:\"long_b7a5\"};const u=s},7156:e=>{\"use strict\";e.exports=function(e){var n=[];return n.toString=function(){return this.map((function(n){var t=\"\",r=void 0!==n[5];return n[4]&&(t+=\"@supports (\".concat(n[4],\") {\")),n[2]&&(t+=\"@media \".concat(n[2],\" {\")),r&&(t+=\"@layer\".concat(n[5].length>0?\" \".concat(n[5]):\"\",\" {\")),t+=e(n),r&&(t+=\"}\"),n[2]&&(t+=\"}\"),n[4]&&(t+=\"}\"),t})).join(\"\")},n.i=function(e,t,r,o,i){\"string\"==typeof e&&(e=[[null,e,void 0]]);var a={};if(r)for(var l=0;l<this.length;l++){var c=this[l][0];null!=c&&(a[c]=!0)}for(var s=0;s<e.length;s++){var u=[].concat(e[s]);r&&a[u[0]]||(void 0!==i&&(void 0===u[5]||(u[1]=\"@layer\".concat(u[5].length>0?\" \".concat(u[5]):\"\",\" {\").concat(u[1],\"}\")),u[5]=i),t&&(u[2]?(u[1]=\"@media \".concat(u[2],\" {\").concat(u[1],\"}\"),u[2]=t):u[2]=t),o&&(u[4]?(u[1]=\"@supports (\".concat(u[4],\") {\").concat(u[1],\"}\"),u[4]=o):u[4]=\"\".concat(o)),n.push(u))}},n}},1404:e=>{\"use strict\";e.exports=function(e){var n=e[1],t=e[3];if(!t)return n;if(\"function\"==typeof btoa){var r=btoa(unescape(encodeURIComponent(JSON.stringify(t)))),o=\"sourceMappingURL=data:application/json;charset=utf-8;base64,\".concat(r),i=\"/*# \".concat(o,\" */\");return[n].concat([i]).join(\"\\n\")}return[n].join(\"\\n\")}},4504:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(7222);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},9102:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(9892);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},6860:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(1866);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},3912:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(5486);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},8764:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(6506);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},6620:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(9106);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},9468:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(5066);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},274:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(8976);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},5924:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(8266);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},7826:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(6960);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},1914:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(480);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},8130:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(1586);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},1564:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(8890);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},5103:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(4481);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},3006:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(2636);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},9344:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(8102);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},4512:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(4561);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},6932:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(6162);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},8132:(e,n,t)=>{var r=t(8298),o=t(5163),i=t(2729),a=t(9986),l=t(9742),c=t(6291),s=t(938);s=s.__esModule?s.default:s;var u={};u.styleTagTransform=c,u.setAttributes=a,u.insert=i.bind(null,\"head\"),u.domAPI=o,u.insertStyleElement=l;r(s,u);e.exports=s&&s.locals||{}},8298:e=>{\"use strict\";var n=[];function t(e){for(var t=-1,r=0;r<n.length;r++)if(n[r].identifier===e){t=r;break}return t}function r(e,r){for(var i={},a=[],l=0;l<e.length;l++){var c=e[l],s=r.base?c[0]+r.base:c[0],u=i[s]||0,p=\"\".concat(s,\" \").concat(u);i[s]=u+1;var f=t(p),d={css:c[1],media:c[2],sourceMap:c[3],supports:c[4],layer:c[5]};if(-1!==f)n[f].references++,n[f].updater(d);else{var g=o(d,r);r.byIndex=l,n.splice(l,0,{identifier:p,updater:g,references:1})}a.push(p)}return a}function o(e,n){var t=n.domAPI(n);t.update(e);return function(n){if(n){if(n.css===e.css&&n.media===e.media&&n.sourceMap===e.sourceMap&&n.supports===e.supports&&n.layer===e.layer)return;t.update(e=n)}else t.remove()}}e.exports=function(e,o){var i=r(e=e||[],o=o||{});return function(e){e=e||[];for(var a=0;a<i.length;a++){var l=t(i[a]);n[l].references--}for(var c=r(e,o),s=0;s<i.length;s++){var u=t(i[s]);0===n[u].references&&(n[u].updater(),n.splice(u,1))}i=c}}},2729:e=>{\"use strict\";var n={};e.exports=function(e,t){var r=function(e){if(void 0===n[e]){var t=document.querySelector(e);if(window.HTMLIFrameElement&&t instanceof window.HTMLIFrameElement)try{t=t.contentDocument.head}catch(e){t=null}n[e]=t}return n[e]}(e);if(!r)throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insert' parameter is invalid.\");r.appendChild(t)}},9742:e=>{\"use strict\";e.exports=function(e){var n=document.createElement(\"style\");return e.setAttributes(n,e.attributes),e.insert(n,e.options),n}},9986:(e,n,t)=>{\"use strict\";e.exports=function(e){var n=t.nc;n&&e.setAttribute(\"nonce\",n)}},5163:e=>{\"use strict\";e.exports=function(e){if(\"undefined\"==typeof document)return{update:function(){},remove:function(){}};var n=e.insertStyleElement(e);return{update:function(t){!function(e,n,t){var r=\"\";t.supports&&(r+=\"@supports (\".concat(t.supports,\") {\")),t.media&&(r+=\"@media \".concat(t.media,\" {\"));var o=void 0!==t.layer;o&&(r+=\"@layer\".concat(t.layer.length>0?\" \".concat(t.layer):\"\",\" {\")),r+=t.css,o&&(r+=\"}\"),t.media&&(r+=\"}\"),t.supports&&(r+=\"}\");var i=t.sourceMap;i&&\"undefined\"!=typeof btoa&&(r+=\"\\n/*# sourceMappingURL=data:application/json;base64,\".concat(btoa(unescape(encodeURIComponent(JSON.stringify(i)))),\" */\")),n.styleTagTransform(r,e,n.options)}(n,e,t)},remove:function(){!function(e){if(null===e.parentNode)return!1;e.parentNode.removeChild(e)}(n)}}}},6291:e=>{\"use strict\";e.exports=function(e,n){if(n.styleSheet)n.styleSheet.cssText=e;else{for(;n.firstChild;)n.removeChild(n.firstChild);n.appendChild(document.createTextNode(e))}}},9511:(e,n,t)=>{\"use strict\";var r=t(6556)(\"ArrayBuffer.prototype.byteLength\",!0),o=t(4670);e.exports=function(e){return o(e)?r?r(e):e.byteLength:NaN}},3144:(e,n,t)=>{\"use strict\";var r=t(6743),o=t(1002),i=t(76),a=t(7119);e.exports=a||r.call(i,o)},2205:(e,n,t)=>{\"use strict\";var r=t(6743),o=t(1002),i=t(3144);e.exports=function(){return i(r,o,arguments)}},1002:e=>{\"use strict\";e.exports=Function.prototype.apply},76:e=>{\"use strict\";e.exports=Function.prototype.call},3126:(e,n,t)=>{\"use strict\";var r=t(6743),o=t(9675),i=t(76),a=t(3144);e.exports=function(e){if(e.length<1||\"function\"!=typeof e[0])throw new o(\"a function is required\");return a(r,i,e)}},7119:e=>{\"use strict\";e.exports=\"undefined\"!=typeof Reflect&&Reflect&&Reflect.apply},8075:(e,n,t)=>{\"use strict\";var r=t(453),o=t(487),i=o(r(\"String.prototype.indexOf\"));e.exports=function(e,n){var t=r(e,!!n);return\"function\"==typeof t&&i(e,\".prototype.\")>-1?o(t):t}},487:(e,n,t)=>{\"use strict\";var r=t(6897),o=t(3036),i=t(3126),a=t(2205);e.exports=function(e){var n=i(arguments),t=e.length-(arguments.length-1);return r(n,1+(t>0?t:0),!0)},o?o(e.exports,\"apply\",{value:a}):e.exports.apply=a},6556:(e,n,t)=>{\"use strict\";var r=t(453),o=t(3126),i=o([r(\"%String.prototype.indexOf%\")]);e.exports=function(e,n){var t=r(e,!!n);return\"function\"==typeof t&&i(e,\".prototype.\")>-1?o([t]):t}},5888:(e,n,t)=>{\"use strict\";e.exports=function(e,n){var t=this,r=t.constructor;return t.options=Object.assign({storeInstancesGlobally:!0},n||{}),t.callbacks={},t.directMap={},t.sequenceLevels={},t.resetTimer=null,t.ignoreNextKeyup=!1,t.ignoreNextKeypress=!1,t.nextExpectedAction=!1,t.element=e,t.addEvents(),t.options.storeInstancesGlobally&&r.instances.push(t),t},e.exports.prototype.bind=t(1210),e.exports.prototype.bindMultiple=t(4382),e.exports.prototype.unbind=t(3709),e.exports.prototype.trigger=t(3149),e.exports.prototype.reset=t(6726),e.exports.prototype.stopCallback=t(4446),e.exports.prototype.handleKey=t(4320),e.exports.prototype.addEvents=t(6687),e.exports.prototype.bindSingle=t(2214),e.exports.prototype.getKeyInfo=t(4174),e.exports.prototype.pickBestAction=t(6004),e.exports.prototype.getReverseMap=t(5193),e.exports.prototype.getMatches=t(9132),e.exports.prototype.resetSequences=t(3229),e.exports.prototype.fireCallback=t(7922),e.exports.prototype.bindSequence=t(3256),e.exports.prototype.resetSequenceTimer=t(602),e.exports.prototype.detach=t(3502),e.exports.instances=[],e.exports.reset=t(6255),e.exports.REVERSE_MAP=null},6687:(e,n,t)=>{\"use strict\";e.exports=function(){var e=this,n=t(2904),r=e.element;e.eventHandler=t(8178).bind(e),n(r,\"keypress\",e.eventHandler),n(r,\"keydown\",e.eventHandler),n(r,\"keyup\",e.eventHandler)}},1210:e=>{\"use strict\";e.exports=function(e,n,t){return e=e instanceof Array?e:[e],this.bindMultiple(e,n,t),this}},4382:e=>{\"use strict\";e.exports=function(e,n,t){for(var r=0;r<e.length;++r)this.bindSingle(e[r],n,t)}},3256:(e,n,t)=>{\"use strict\";e.exports=function(e,n,r,o){var i=this;function a(n){return function(){i.nextExpectedAction=n,++i.sequenceLevels[e],i.resetSequenceTimer()}}function l(n){var a;i.fireCallback(r,n,e),\"keyup\"!==o&&(a=t(3970),i.ignoreNextKeyup=a(n)),setTimeout((function(){i.resetSequences()}),10)}i.sequenceLevels[e]=0;for(var c=0;c<n.length;++c){var s=c+1===n.length?l:a(o||i.getKeyInfo(n[c+1]).action);i.bindSingle(n[c],s,o,e,c)}}},2214:e=>{\"use strict\";e.exports=function(e,n,t,r,o){var i=this;i.directMap[e+\":\"+t]=n;var a,l=(e=e.replace(/\\s+/g,\" \")).split(\" \");l.length>1?i.bindSequence(e,l,n,t):(a=i.getKeyInfo(e,t),i.callbacks[a.key]=i.callbacks[a.key]||[],i.getMatches(a.key,a.modifiers,{type:a.action},r,e,o),i.callbacks[a.key][r?\"unshift\":\"push\"]({callback:n,modifiers:a.modifiers,action:a.action,seq:r,level:o,combo:e}))}},3502:(e,n,t)=>{var r=t(2904).off;e.exports=function(){var e=this,n=e.element;r(n,\"keypress\",e.eventHandler),r(n,\"keydown\",e.eventHandler),r(n,\"keyup\",e.eventHandler)}},2904:e=>{function n(e,n,t,r){return!e.addEventListener&&(n=\"on\"+n),(e.addEventListener||e.attachEvent).call(e,n,t,r),t}e.exports=n,e.exports.on=n,e.exports.off=function(e,n,t,r){return!e.removeEventListener&&(n=\"on\"+n),(e.removeEventListener||e.detachEvent).call(e,n,t,r),t}},7922:(e,n,t)=>{\"use strict\";e.exports=function(e,n,r,o){this.stopCallback(n,n.target||n.srcElement,r,o)||!1===e(n,r)&&(t(2156)(n),t(1849)(n))}},4174:(e,n,t)=>{\"use strict\";e.exports=function(e,n){var r,o,i,a,l,c,s=[];for(r=t(7486)(e),a=t(7641),l=t(7984),c=t(5962),i=0;i<r.length;++i)a[o=r[i]]&&(o=a[o]),n&&\"keypress\"!==n&&l[o]&&(o=l[o],s.push(\"shift\")),c(o)&&s.push(o);return{key:o,modifiers:s,action:n=this.pickBestAction(o,s,n)}}},9132:(e,n,t)=>{\"use strict\";e.exports=function(e,n,r,o,i,a){var l,c,s,u,p=this,f=[],d=r.type;\"keypress\"!==d||r.code&&\"Arrow\"===r.code.slice(0,5)||(p.callbacks[\"any-character\"]||[]).forEach((function(e){f.push(e)}));if(!p.callbacks[e])return f;for(s=t(5962),\"keyup\"===d&&s(e)&&(n=[e]),l=0;l<p.callbacks[e].length;++l)if(c=p.callbacks[e][l],(o||!c.seq||p.sequenceLevels[c.seq]===c.level)&&d===c.action&&(u=t(7238),\"keypress\"===d&&!r.metaKey&&!r.ctrlKey||u(n,c.modifiers))){var g=!o&&c.combo===i,h=o&&c.seq===o&&c.level===a;(g||h)&&p.callbacks[e].splice(l,1),f.push(c)}return f}},5193:(e,n,t)=>{\"use strict\";e.exports=function(){var e,n=this.constructor;if(!n.REVERSE_MAP)for(var r in n.REVERSE_MAP={},e=t(6814))r>95&&r<112||e.hasOwnProperty(r)&&(n.REVERSE_MAP[e[r]]=r);return n.REVERSE_MAP}},4320:(e,n,t)=>{\"use strict\";e.exports=function(e,n,r){var o,i,a,l,c=this,s={},u=0,p=!1;for(o=c.getMatches(e,n,r),i=0;i<o.length;++i)o[i].seq&&(u=Math.max(u,o[i].level));for(i=0;i<o.length;++i)if(o[i].seq){if(o[i].level!==u)continue;p=!0,s[o[i].seq]=1,c.fireCallback(o[i].callback,r,o[i].combo,o[i].seq)}else p||c.fireCallback(o[i].callback,r,o[i].combo);l=\"keypress\"===r.type&&c.ignoreNextKeypress,a=t(5962),r.type!==c.nextExpectedAction||a(e)||l||c.resetSequences(s),c.ignoreNextKeypress=p&&\"keydown\"===r.type}},8178:(e,n,t)=>{\"use strict\";e.exports=function(e){var n,r=this;\"number\"!=typeof e.which&&(e.which=e.keyCode);var o=t(3970)(e);void 0!==o&&(\"keyup\"!==e.type||r.ignoreNextKeyup!==o?(n=t(5273),r.handleKey(o,n(e),e)):r.ignoreNextKeyup=!1)}},7238:e=>{\"use strict\";e.exports=function(e,n){return e.sort().join(\",\")===n.sort().join(\",\")}},6004:e=>{\"use strict\";e.exports=function(e,n,t){return t||(t=this.getReverseMap()[e]?\"keydown\":\"keypress\"),\"keypress\"===t&&n.length&&(t=\"keydown\"),t}},6726:e=>{\"use strict\";e.exports=function(){return this.callbacks={},this.directMap={},this}},602:e=>{\"use strict\";e.exports=function(){var e=this;clearTimeout(e.resetTimer),e.resetTimer=setTimeout((function(){e.resetSequences()}),1e3)}},3229:e=>{\"use strict\";e.exports=function(e){var n=this;e=e||{};var t,r=!1;for(t in n.sequenceLevels)e[t]?r=!0:n.sequenceLevels[t]=0;r||(n.nextExpectedAction=!1)}},4446:e=>{\"use strict\";e.exports=function(e,n){if((\" \"+n.className+\" \").indexOf(\" combokeys \")>-1)return!1;var t=n.tagName.toLowerCase();return\"input\"===t||\"select\"===t||\"textarea\"===t||n.isContentEditable}},3149:e=>{\"use strict\";e.exports=function(e,n){return this.directMap[e+\":\"+n]&&this.directMap[e+\":\"+n]({},e),this}},3709:e=>{\"use strict\";e.exports=function(e,n){return this.bind(e,(function(){}),n)}},6255:e=>{\"use strict\";e.exports=function(){this.instances.forEach((function(e){e.reset()}))}},3970:(e,n,t)=>{\"use strict\";e.exports=function(e){var n,r;if(n=t(6814),r=t(4082),\"keypress\"===e.type){var o=String.fromCharCode(e.which);return e.shiftKey||(o=o.toLowerCase()),o}return void 0!==n[e.which]?n[e.which]:void 0!==r[e.which]?r[e.which]:String.fromCharCode(e.which).toLowerCase()}},5273:e=>{\"use strict\";e.exports=function(e){var n=[];return e.shiftKey&&n.push(\"shift\"),e.altKey&&n.push(\"alt\"),e.ctrlKey&&n.push(\"ctrl\"),e.metaKey&&n.push(\"meta\"),n}},5962:e=>{\"use strict\";e.exports=function(e){return\"shift\"===e||\"ctrl\"===e||\"alt\"===e||\"meta\"===e}},7486:e=>{\"use strict\";e.exports=function(e){return\"+\"===e?[\"+\"]:e.split(\"+\")}},2156:e=>{\"use strict\";e.exports=function(e){e.preventDefault?e.preventDefault():e.returnValue=!1}},7984:e=>{\"use strict\";e.exports={\"~\":\"`\",\"!\":\"1\",\"@\":\"2\",\"#\":\"3\",$:\"4\",\"%\":\"5\",\"^\":\"6\",\"&\":\"7\",\"*\":\"8\",\"(\":\"9\",\")\":\"0\",_:\"-\",\"+\":\"=\",\":\":\";\",'\"':\"'\",\"<\":\",\",\">\":\".\",\"?\":\"/\",\"|\":\"\\\\\"}},7641:e=>{\"use strict\";e.exports={option:\"alt\",command:\"meta\",return:\"enter\",escape:\"esc\",mod:/Mac|iPod|iPhone|iPad/.test(navigator.platform)?\"meta\":\"ctrl\"}},4082:e=>{\"use strict\";e.exports={106:\"*\",107:\"plus\",109:\"minus\",110:\".\",111:\"/\",186:\";\",187:\"=\",188:\",\",189:\"-\",190:\".\",191:\"/\",192:\"`\",219:\"[\",220:\"\\\\\",221:\"]\",222:\"'\"}},6814:e=>{\"use strict\";e.exports={8:\"backspace\",9:\"tab\",13:\"enter\",16:\"shift\",17:\"ctrl\",18:\"alt\",20:\"capslock\",27:\"esc\",32:\"space\",33:\"pageup\",34:\"pagedown\",35:\"end\",36:\"home\",37:\"left\",38:\"up\",39:\"right\",40:\"down\",45:\"ins\",46:\"del\",91:\"meta\",93:\"meta\",173:\"minus\",187:\"plus\",189:\"minus\",224:\"meta\"};for(var n=1;n<20;++n)e.exports[111+n]=\"f\"+n;for(n=0;n<=9;++n)e.exports[n+96]=n},1849:e=>{\"use strict\";e.exports=function(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}},4982:(e,n,t)=>{\"use strict\";var r=t(6525),o=t(8075),i=t(1589),a=t(453),l=t(4552),c=t(920),s=t(7653),u=t(7244),p=t(4634),f=t(4670),d=t(2120),g=t(4035),h=t(7070),A=t(1189),b=t(1539),v=t(593),m=t(5767),y=t(9511),E=o(\"SharedArrayBuffer.prototype.byteLength\",!0),C=o(\"Date.prototype.getTime\"),w=Object.getPrototypeOf,x=o(\"Object.prototype.toString\"),S=a(\"%Set%\",!0),_=o(\"Map.prototype.has\",!0),k=o(\"Map.prototype.get\",!0),O=o(\"Map.prototype.size\",!0),B=o(\"Set.prototype.add\",!0),P=o(\"Set.prototype.delete\",!0),T=o(\"Set.prototype.has\",!0),I=o(\"Set.prototype.size\",!0);function j(e,n,t,r){for(var o,i=l(e);(o=i.next())&&!o.done;)if(N(n,o.value,t,r))return P(e,o.value),!0;return!1}function z(e){return void 0===e?null:\"object\"!=typeof e?\"symbol\"!=typeof e&&(\"string\"!=typeof e&&\"number\"!=typeof e||+e==+e):void 0}function D(e,n,t,o,i,a){var l=z(t);if(null!=l)return l;var c=k(n,l),s=r({},i,{strict:!1});return!(void 0===c&&!_(n,l)||!N(o,c,s,a))&&(!_(e,l)&&N(o,c,s,a))}function R(e,n,t){var r=z(t);return null!=r?r:T(n,r)&&!T(e,r)}function M(e,n,t,r,o,i){for(var a,c,s=l(e);(a=s.next())&&!a.done;)if(N(t,c=a.value,o,i)&&N(r,k(n,c),o,i))return P(e,c),!0;return!1}function N(e,n,t,o){var a=t||{};if(a.strict?s(e,n):e===n)return!0;if(b(e)!==b(n))return!1;if(!e||!n||\"object\"!=typeof e&&\"object\"!=typeof n)return a.strict?s(e,n):e==n;var c,P=o.has(e),z=o.has(n);if(P&&z){if(o.get(e)===o.get(n))return!0}else c={};return P||o.set(e,c),z||o.set(n,c),function(e,n,t,o){var a,c;if(typeof e!=typeof n)return!1;if(null==e||null==n)return!1;if(x(e)!==x(n))return!1;if(u(e)!==u(n))return!1;var s=p(e),b=p(n);if(s!==b)return!1;var P=e instanceof Error,z=n instanceof Error;if(P!==z)return!1;if((P||z)&&(e.name!==n.name||e.message!==n.message))return!1;var L=g(e),H=g(n);if(L!==H)return!1;if((L||H)&&(e.source!==n.source||i(e)!==i(n)))return!1;var U=d(e),W=d(n);if(U!==W)return!1;if((U||W)&&C(e)!==C(n))return!1;if(t.strict&&w&&w(e)!==w(n))return!1;var G=m(e),Y=m(n);if(G!==Y)return!1;if(G||Y){if(e.length!==n.length)return!1;for(a=0;a<e.length;a++)if(e[a]!==n[a])return!1;return!0}var q=F(e),V=F(n);if(q!==V)return!1;if(q||V){if(e.length!==n.length)return!1;for(a=0;a<e.length;a++)if(e[a]!==n[a])return!1;return!0}var $=f(e),K=f(n);if($!==K)return!1;if($||K)return y(e)===y(n)&&(\"function\"==typeof Uint8Array&&N(new Uint8Array(e),new Uint8Array(n),t,o));var Q=h(e),X=h(n);if(Q!==X)return!1;if(Q||X)return E(e)===E(n)&&(\"function\"==typeof Uint8Array&&N(new Uint8Array(e),new Uint8Array(n),t,o));if(typeof e!=typeof n)return!1;var Z=A(e),J=A(n);if(Z.length!==J.length)return!1;for(Z.sort(),J.sort(),a=Z.length-1;a>=0;a--)if(Z[a]!=J[a])return!1;for(a=Z.length-1;a>=0;a--)if(!N(e[c=Z[a]],n[c],t,o))return!1;var ee=v(e),ne=v(n);if(ee!==ne)return!1;if(\"Set\"===ee||\"Set\"===ne)return function(e,n,t,r){if(I(e)!==I(n))return!1;var o,i,a,c=l(e),s=l(n);for(;(o=c.next())&&!o.done;)if(o.value&&\"object\"==typeof o.value)a||(a=new S),B(a,o.value);else if(!T(n,o.value)){if(t.strict)return!1;if(!R(e,n,o.value))return!1;a||(a=new S),B(a,o.value)}if(a){for(;(i=s.next())&&!i.done;)if(i.value&&\"object\"==typeof i.value){if(!j(a,i.value,t.strict,r))return!1}else if(!t.strict&&!T(e,i.value)&&!j(a,i.value,t.strict,r))return!1;return 0===I(a)}return!0}(e,n,t,o);if(\"Map\"===ee)return function(e,n,t,o){if(O(e)!==O(n))return!1;var i,a,c,s,u,p,f=l(e),d=l(n);for(;(i=f.next())&&!i.done;)if(s=i.value[0],u=i.value[1],s&&\"object\"==typeof s)c||(c=new S),B(c,s);else if(void 0===(p=k(n,s))&&!_(n,s)||!N(u,p,t,o)){if(t.strict)return!1;if(!D(e,n,s,u,t,o))return!1;c||(c=new S),B(c,s)}if(c){for(;(a=d.next())&&!a.done;)if(s=a.value[0],p=a.value[1],s&&\"object\"==typeof s){if(!M(c,e,s,p,t,o))return!1}else if(!(t.strict||e.has(s)&&N(k(e,s),p,t,o)||M(c,e,s,p,r({},t,{strict:!1}),o)))return!1;return 0===I(c)}return!0}(e,n,t,o);return!0}(e,n,a,o)}function F(e){return!(!e||\"object\"!=typeof e||\"number\"!=typeof e.length)&&(\"function\"==typeof e.copy&&\"function\"==typeof e.slice&&(!(e.length>0&&\"number\"!=typeof e[0])&&!!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e))))}e.exports=function(e,n,t){return N(e,n,t,c())}},41:(e,n,t)=>{\"use strict\";var r=t(3036),o=t(8068),i=t(9675),a=t(5795);e.exports=function(e,n,t){if(!e||\"object\"!=typeof e&&\"function\"!=typeof e)throw new i(\"`obj` must be an object or a function`\");if(\"string\"!=typeof n&&\"symbol\"!=typeof n)throw new i(\"`property` must be a string or a symbol`\");if(arguments.length>3&&\"boolean\"!=typeof arguments[3]&&null!==arguments[3])throw new i(\"`nonEnumerable`, if provided, must be a boolean or null\");if(arguments.length>4&&\"boolean\"!=typeof arguments[4]&&null!==arguments[4])throw new i(\"`nonWritable`, if provided, must be a boolean or null\");if(arguments.length>5&&\"boolean\"!=typeof arguments[5]&&null!==arguments[5])throw new i(\"`nonConfigurable`, if provided, must be a boolean or null\");if(arguments.length>6&&\"boolean\"!=typeof arguments[6])throw new i(\"`loose`, if provided, must be a boolean\");var l=arguments.length>3?arguments[3]:null,c=arguments.length>4?arguments[4]:null,s=arguments.length>5?arguments[5]:null,u=arguments.length>6&&arguments[6],p=!!a&&a(e,n);if(r)r(e,n,{configurable:null===s&&p?p.configurable:!s,enumerable:null===l&&p?p.enumerable:!l,value:t,writable:null===c&&p?p.writable:!c});else{if(!u&&(l||c||s))throw new o(\"This environment does not support defining a property as non-configurable, non-writable, or non-enumerable.\");e[n]=t}}},8452:(e,n,t)=>{\"use strict\";var r=t(1189),o=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol(\"foo\"),i=Object.prototype.toString,a=Array.prototype.concat,l=t(41),c=t(592)(),s=function(e,n,t,r){if(n in e)if(!0===r){if(e[n]===t)return}else if(\"function\"!=typeof(o=r)||\"[object Function]\"!==i.call(o)||!r())return;var o;c?l(e,n,t,!0):l(e,n,t)},u=function(e,n){var t=arguments.length>2?arguments[2]:{},i=r(n);o&&(i=a.call(i,Object.getOwnPropertySymbols(n)));for(var l=0;l<i.length;l+=1)s(e,i[l],n[i[l]],t[i[l]])};u.supportsDescriptors=!!c,e.exports=u},7176:(e,n,t)=>{\"use strict\";var r,o=t(3126),i=t(5795);try{r=[].__proto__===Array.prototype}catch(e){if(!e||\"object\"!=typeof e||!(\"code\"in e)||\"ERR_PROTO_ACCESS\"!==e.code)throw e}var a=!!r&&i&&i(Object.prototype,\"__proto__\"),l=Object,c=l.getPrototypeOf;e.exports=a&&\"function\"==typeof a.get?o([a.get]):\"function\"==typeof c&&function(e){return c(null==e?e:l(e))}},3036:e=>{\"use strict\";var n=Object.defineProperty||!1;if(n)try{n({},\"a\",{value:1})}catch(e){n=!1}e.exports=n},1237:e=>{\"use strict\";e.exports=EvalError},9383:e=>{\"use strict\";e.exports=Error},9290:e=>{\"use strict\";e.exports=RangeError},9538:e=>{\"use strict\";e.exports=ReferenceError},8068:e=>{\"use strict\";e.exports=SyntaxError},9675:e=>{\"use strict\";e.exports=TypeError},5345:e=>{\"use strict\";e.exports=URIError},9612:e=>{\"use strict\";e.exports=Object},2682:(e,n,t)=>{\"use strict\";var r=t(9600),o=Object.prototype.toString,i=Object.prototype.hasOwnProperty;e.exports=function(e,n,t){if(!r(n))throw new TypeError(\"iterator must be a function\");var a,l;arguments.length>=3&&(a=t),l=e,\"[object Array]\"===o.call(l)?function(e,n,t){for(var r=0,o=e.length;r<o;r++)i.call(e,r)&&(null==t?n(e[r],r,e):n.call(t,e[r],r,e))}(e,n,a):\"string\"==typeof e?function(e,n,t){for(var r=0,o=e.length;r<o;r++)null==t?n(e.charAt(r),r,e):n.call(t,e.charAt(r),r,e)}(e,n,a):function(e,n,t){for(var r in e)i.call(e,r)&&(null==t?n(e[r],r,e):n.call(t,e[r],r,e))}(e,n,a)}},9353:e=>{\"use strict\";var n=Object.prototype.toString,t=Math.max,r=function(e,n){for(var t=[],r=0;r<e.length;r+=1)t[r]=e[r];for(var o=0;o<n.length;o+=1)t[o+e.length]=n[o];return t};e.exports=function(e){var o=this;if(\"function\"!=typeof o||\"[object Function]\"!==n.apply(o))throw new TypeError(\"Function.prototype.bind called on incompatible \"+o);for(var i,a=function(e,n){for(var t=[],r=n||0,o=0;r<e.length;r+=1,o+=1)t[o]=e[r];return t}(arguments,1),l=t(0,o.length-a.length),c=[],s=0;s<l;s++)c[s]=\"$\"+s;if(i=Function(\"binder\",\"return function (\"+function(e,n){for(var t=\"\",r=0;r<e.length;r+=1)t+=e[r],r+1<e.length&&(t+=n);return t}(c,\",\")+\"){ return binder.apply(this,arguments); }\")((function(){if(this instanceof i){var n=o.apply(this,r(a,arguments));return Object(n)===n?n:this}return o.apply(e,r(a,arguments))})),o.prototype){var u=function(){};u.prototype=o.prototype,i.prototype=new u,u.prototype=null}return i}},6743:(e,n,t)=>{\"use strict\";var r=t(9353);e.exports=Function.prototype.bind||r},4462:e=>{\"use strict\";var n=function(){return\"string\"==typeof function(){}.name},t=Object.getOwnPropertyDescriptor;if(t)try{t([],\"length\")}catch(e){t=null}n.functionsHaveConfigurableNames=function(){if(!n()||!t)return!1;var e=t((function(){}),\"name\");return!!e&&!!e.configurable};var r=Function.prototype.bind;n.boundFunctionsHaveNames=function(){return n()&&\"function\"==typeof r&&\"\"!==function(){}.bind().name},e.exports=n},453:(e,n,t)=>{\"use strict\";var r,o=t(9612),i=t(9383),a=t(1237),l=t(9290),c=t(9538),s=t(8068),u=t(9675),p=t(5345),f=t(1514),d=t(8968),g=t(6188),h=t(8002),A=t(5880),b=t(414),v=t(3093),m=Function,y=function(e){try{return m('\"use strict\"; return ('+e+\").constructor;\")()}catch(e){}},E=t(5795),C=t(3036),w=function(){throw new u},x=E?function(){try{return w}catch(e){try{return E(arguments,\"callee\").get}catch(e){return w}}}():w,S=t(4039)(),_=t(3628),k=t(1064),O=t(8648),B=t(1002),P=t(76),T={},I=\"undefined\"!=typeof Uint8Array&&_?_(Uint8Array):r,j={__proto__:null,\"%AggregateError%\":\"undefined\"==typeof AggregateError?r:AggregateError,\"%Array%\":Array,\"%ArrayBuffer%\":\"undefined\"==typeof ArrayBuffer?r:ArrayBuffer,\"%ArrayIteratorPrototype%\":S&&_?_([][Symbol.iterator]()):r,\"%AsyncFromSyncIteratorPrototype%\":r,\"%AsyncFunction%\":T,\"%AsyncGenerator%\":T,\"%AsyncGeneratorFunction%\":T,\"%AsyncIteratorPrototype%\":T,\"%Atomics%\":\"undefined\"==typeof Atomics?r:Atomics,\"%BigInt%\":\"undefined\"==typeof BigInt?r:BigInt,\"%BigInt64Array%\":\"undefined\"==typeof BigInt64Array?r:BigInt64Array,\"%BigUint64Array%\":\"undefined\"==typeof BigUint64Array?r:BigUint64Array,\"%Boolean%\":Boolean,\"%DataView%\":\"undefined\"==typeof DataView?r:DataView,\"%Date%\":Date,\"%decodeURI%\":decodeURI,\"%decodeURIComponent%\":decodeURIComponent,\"%encodeURI%\":encodeURI,\"%encodeURIComponent%\":encodeURIComponent,\"%Error%\":i,\"%eval%\":eval,\"%EvalError%\":a,\"%Float16Array%\":\"undefined\"==typeof Float16Array?r:Float16Array,\"%Float32Array%\":\"undefined\"==typeof Float32Array?r:Float32Array,\"%Float64Array%\":\"undefined\"==typeof Float64Array?r:Float64Array,\"%FinalizationRegistry%\":\"undefined\"==typeof FinalizationRegistry?r:FinalizationRegistry,\"%Function%\":m,\"%GeneratorFunction%\":T,\"%Int8Array%\":\"undefined\"==typeof Int8Array?r:Int8Array,\"%Int16Array%\":\"undefined\"==typeof Int16Array?r:Int16Array,\"%Int32Array%\":\"undefined\"==typeof Int32Array?r:Int32Array,\"%isFinite%\":isFinite,\"%isNaN%\":isNaN,\"%IteratorPrototype%\":S&&_?_(_([][Symbol.iterator]())):r,\"%JSON%\":\"object\"==typeof JSON?JSON:r,\"%Map%\":\"undefined\"==typeof Map?r:Map,\"%MapIteratorPrototype%\":\"undefined\"!=typeof Map&&S&&_?_((new Map)[Symbol.iterator]()):r,\"%Math%\":Math,\"%Number%\":Number,\"%Object%\":o,\"%Object.getOwnPropertyDescriptor%\":E,\"%parseFloat%\":parseFloat,\"%parseInt%\":parseInt,\"%Promise%\":\"undefined\"==typeof Promise?r:Promise,\"%Proxy%\":\"undefined\"==typeof Proxy?r:Proxy,\"%RangeError%\":l,\"%ReferenceError%\":c,\"%Reflect%\":\"undefined\"==typeof Reflect?r:Reflect,\"%RegExp%\":RegExp,\"%Set%\":\"undefined\"==typeof Set?r:Set,\"%SetIteratorPrototype%\":\"undefined\"!=typeof Set&&S&&_?_((new Set)[Symbol.iterator]()):r,\"%SharedArrayBuffer%\":\"undefined\"==typeof SharedArrayBuffer?r:SharedArrayBuffer,\"%String%\":String,\"%StringIteratorPrototype%\":S&&_?_(\"\"[Symbol.iterator]()):r,\"%Symbol%\":S?Symbol:r,\"%SyntaxError%\":s,\"%ThrowTypeError%\":x,\"%TypedArray%\":I,\"%TypeError%\":u,\"%Uint8Array%\":\"undefined\"==typeof Uint8Array?r:Uint8Array,\"%Uint8ClampedArray%\":\"undefined\"==typeof Uint8ClampedArray?r:Uint8ClampedArray,\"%Uint16Array%\":\"undefined\"==typeof Uint16Array?r:Uint16Array,\"%Uint32Array%\":\"undefined\"==typeof Uint32Array?r:Uint32Array,\"%URIError%\":p,\"%WeakMap%\":\"undefined\"==typeof WeakMap?r:WeakMap,\"%WeakRef%\":\"undefined\"==typeof WeakRef?r:WeakRef,\"%WeakSet%\":\"undefined\"==typeof WeakSet?r:WeakSet,\"%Function.prototype.call%\":P,\"%Function.prototype.apply%\":B,\"%Object.defineProperty%\":C,\"%Object.getPrototypeOf%\":k,\"%Math.abs%\":f,\"%Math.floor%\":d,\"%Math.max%\":g,\"%Math.min%\":h,\"%Math.pow%\":A,\"%Math.round%\":b,\"%Math.sign%\":v,\"%Reflect.getPrototypeOf%\":O};if(_)try{null.error}catch(e){var z=_(_(e));j[\"%Error.prototype%\"]=z}var D=function e(n){var t;if(\"%AsyncFunction%\"===n)t=y(\"async function () {}\");else if(\"%GeneratorFunction%\"===n)t=y(\"function* () {}\");else if(\"%AsyncGeneratorFunction%\"===n)t=y(\"async function* () {}\");else if(\"%AsyncGenerator%\"===n){var r=e(\"%AsyncGeneratorFunction%\");r&&(t=r.prototype)}else if(\"%AsyncIteratorPrototype%\"===n){var o=e(\"%AsyncGenerator%\");o&&_&&(t=_(o.prototype))}return j[n]=t,t},R={__proto__:null,\"%ArrayBufferPrototype%\":[\"ArrayBuffer\",\"prototype\"],\"%ArrayPrototype%\":[\"Array\",\"prototype\"],\"%ArrayProto_entries%\":[\"Array\",\"prototype\",\"entries\"],\"%ArrayProto_forEach%\":[\"Array\",\"prototype\",\"forEach\"],\"%ArrayProto_keys%\":[\"Array\",\"prototype\",\"keys\"],\"%ArrayProto_values%\":[\"Array\",\"prototype\",\"values\"],\"%AsyncFunctionPrototype%\":[\"AsyncFunction\",\"prototype\"],\"%AsyncGenerator%\":[\"AsyncGeneratorFunction\",\"prototype\"],\"%AsyncGeneratorPrototype%\":[\"AsyncGeneratorFunction\",\"prototype\",\"prototype\"],\"%BooleanPrototype%\":[\"Boolean\",\"prototype\"],\"%DataViewPrototype%\":[\"DataView\",\"prototype\"],\"%DatePrototype%\":[\"Date\",\"prototype\"],\"%ErrorPrototype%\":[\"Error\",\"prototype\"],\"%EvalErrorPrototype%\":[\"EvalError\",\"prototype\"],\"%Float32ArrayPrototype%\":[\"Float32Array\",\"prototype\"],\"%Float64ArrayPrototype%\":[\"Float64Array\",\"prototype\"],\"%FunctionPrototype%\":[\"Function\",\"prototype\"],\"%Generator%\":[\"GeneratorFunction\",\"prototype\"],\"%GeneratorPrototype%\":[\"GeneratorFunction\",\"prototype\",\"prototype\"],\"%Int8ArrayPrototype%\":[\"Int8Array\",\"prototype\"],\"%Int16ArrayPrototype%\":[\"Int16Array\",\"prototype\"],\"%Int32ArrayPrototype%\":[\"Int32Array\",\"prototype\"],\"%JSONParse%\":[\"JSON\",\"parse\"],\"%JSONStringify%\":[\"JSON\",\"stringify\"],\"%MapPrototype%\":[\"Map\",\"prototype\"],\"%NumberPrototype%\":[\"Number\",\"prototype\"],\"%ObjectPrototype%\":[\"Object\",\"prototype\"],\"%ObjProto_toString%\":[\"Object\",\"prototype\",\"toString\"],\"%ObjProto_valueOf%\":[\"Object\",\"prototype\",\"valueOf\"],\"%PromisePrototype%\":[\"Promise\",\"prototype\"],\"%PromiseProto_then%\":[\"Promise\",\"prototype\",\"then\"],\"%Promise_all%\":[\"Promise\",\"all\"],\"%Promise_reject%\":[\"Promise\",\"reject\"],\"%Promise_resolve%\":[\"Promise\",\"resolve\"],\"%RangeErrorPrototype%\":[\"RangeError\",\"prototype\"],\"%ReferenceErrorPrototype%\":[\"ReferenceError\",\"prototype\"],\"%RegExpPrototype%\":[\"RegExp\",\"prototype\"],\"%SetPrototype%\":[\"Set\",\"prototype\"],\"%SharedArrayBufferPrototype%\":[\"SharedArrayBuffer\",\"prototype\"],\"%StringPrototype%\":[\"String\",\"prototype\"],\"%SymbolPrototype%\":[\"Symbol\",\"prototype\"],\"%SyntaxErrorPrototype%\":[\"SyntaxError\",\"prototype\"],\"%TypedArrayPrototype%\":[\"TypedArray\",\"prototype\"],\"%TypeErrorPrototype%\":[\"TypeError\",\"prototype\"],\"%Uint8ArrayPrototype%\":[\"Uint8Array\",\"prototype\"],\"%Uint8ClampedArrayPrototype%\":[\"Uint8ClampedArray\",\"prototype\"],\"%Uint16ArrayPrototype%\":[\"Uint16Array\",\"prototype\"],\"%Uint32ArrayPrototype%\":[\"Uint32Array\",\"prototype\"],\"%URIErrorPrototype%\":[\"URIError\",\"prototype\"],\"%WeakMapPrototype%\":[\"WeakMap\",\"prototype\"],\"%WeakSetPrototype%\":[\"WeakSet\",\"prototype\"]},M=t(6743),N=t(9957),F=M.call(P,Array.prototype.concat),L=M.call(B,Array.prototype.splice),H=M.call(P,String.prototype.replace),U=M.call(P,String.prototype.slice),W=M.call(P,RegExp.prototype.exec),G=/[^%.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|%$))/g,Y=/\\\\(\\\\)?/g,q=function(e,n){var t,r=e;if(N(R,r)&&(r=\"%\"+(t=R[r])[0]+\"%\"),N(j,r)){var o=j[r];if(o===T&&(o=D(r)),void 0===o&&!n)throw new u(\"intrinsic \"+e+\" exists, but is not available. Please file an issue!\");return{alias:t,name:r,value:o}}throw new s(\"intrinsic \"+e+\" does not exist!\")};e.exports=function(e,n){if(\"string\"!=typeof e||0===e.length)throw new u(\"intrinsic name must be a non-empty string\");if(arguments.length>1&&\"boolean\"!=typeof n)throw new u('\"allowMissing\" argument must be a boolean');if(null===W(/^%?[^%]*%?$/,e))throw new s(\"`%` may not be present anywhere but at the beginning and end of the intrinsic name\");var t=function(e){var n=U(e,0,1),t=U(e,-1);if(\"%\"===n&&\"%\"!==t)throw new s(\"invalid intrinsic syntax, expected closing `%`\");if(\"%\"===t&&\"%\"!==n)throw new s(\"invalid intrinsic syntax, expected opening `%`\");var r=[];return H(e,G,(function(e,n,t,o){r[r.length]=t?H(o,Y,\"$1\"):n||e})),r}(e),r=t.length>0?t[0]:\"\",o=q(\"%\"+r+\"%\",n),i=o.name,a=o.value,l=!1,c=o.alias;c&&(r=c[0],L(t,F([0,1],c)));for(var p=1,f=!0;p<t.length;p+=1){var d=t[p],g=U(d,0,1),h=U(d,-1);if(('\"'===g||\"'\"===g||\"`\"===g||'\"'===h||\"'\"===h||\"`\"===h)&&g!==h)throw new s(\"property names with quotes must have matching quotes\");if(\"constructor\"!==d&&f||(l=!0),N(j,i=\"%\"+(r+=\".\"+d)+\"%\"))a=j[i];else if(null!=a){if(!(d in a)){if(!n)throw new u(\"base intrinsic for \"+e+\" exists, but the property is not available.\");return}if(E&&p+1>=t.length){var A=E(a,d);a=(f=!!A)&&\"get\"in A&&!(\"originalValue\"in A.get)?A.get:a[d]}else f=N(a,d),a=a[d];f&&!l&&(j[i]=a)}}return a}},1064:(e,n,t)=>{\"use strict\";var r=t(9612);e.exports=r.getPrototypeOf||null},8648:e=>{\"use strict\";e.exports=\"undefined\"!=typeof Reflect&&Reflect.getPrototypeOf||null},3628:(e,n,t)=>{\"use strict\";var r=t(8648),o=t(1064),i=t(7176);e.exports=r?function(e){return r(e)}:o?function(e){if(!e||\"object\"!=typeof e&&\"function\"!=typeof e)throw new TypeError(\"getProto: not an object\");return o(e)}:i?function(e){return i(e)}:null},6549:e=>{\"use strict\";e.exports=Object.getOwnPropertyDescriptor},5795:(e,n,t)=>{\"use strict\";var r=t(6549);if(r)try{r([],\"length\")}catch(e){r=null}e.exports=r},9790:e=>{\"use strict\";var n=\"undefined\"!=typeof BigInt&&BigInt;e.exports=function(){return\"function\"==typeof n&&\"function\"==typeof BigInt&&\"bigint\"==typeof n(42)&&\"bigint\"==typeof BigInt(42)}},592:(e,n,t)=>{\"use strict\";var r=t(3036),o=function(){return!!r};o.hasArrayLengthDefineBug=function(){if(!r)return null;try{return 1!==r([],\"length\",{value:1}).length}catch(e){return!0}},e.exports=o},4039:(e,n,t)=>{\"use strict\";var r=\"undefined\"!=typeof Symbol&&Symbol,o=t(1333);e.exports=function(){return\"function\"==typeof r&&(\"function\"==typeof Symbol&&(\"symbol\"==typeof r(\"foo\")&&(\"symbol\"==typeof Symbol(\"bar\")&&o())))}},1333:e=>{\"use strict\";e.exports=function(){if(\"function\"!=typeof Symbol||\"function\"!=typeof Object.getOwnPropertySymbols)return!1;if(\"symbol\"==typeof Symbol.iterator)return!0;var e={},n=Symbol(\"test\"),t=Object(n);if(\"string\"==typeof n)return!1;if(\"[object Symbol]\"!==Object.prototype.toString.call(n))return!1;if(\"[object Symbol]\"!==Object.prototype.toString.call(t))return!1;for(var r in e[n]=42,e)return!1;if(\"function\"==typeof Object.keys&&0!==Object.keys(e).length)return!1;if(\"function\"==typeof Object.getOwnPropertyNames&&0!==Object.getOwnPropertyNames(e).length)return!1;var o=Object.getOwnPropertySymbols(e);if(1!==o.length||o[0]!==n)return!1;if(!Object.prototype.propertyIsEnumerable.call(e,n))return!1;if(\"function\"==typeof Object.getOwnPropertyDescriptor){var i=Object.getOwnPropertyDescriptor(e,n);if(42!==i.value||!0!==i.enumerable)return!1}return!0}},9092:(e,n,t)=>{\"use strict\";var r=t(1333);e.exports=function(){return r()&&!!Symbol.toStringTag}},9957:(e,n,t)=>{\"use strict\";var r=Function.prototype.call,o=Object.prototype.hasOwnProperty,i=t(6743);e.exports=i.call(r,o)},63:(e,n,t)=>{\"use strict\";var r=t(9957),o=t(920)(),i=t(9675),a={assert:function(e,n){if(!e||\"object\"!=typeof e&&\"function\"!=typeof e)throw new i(\"`O` is not an object\");if(\"string\"!=typeof n)throw new i(\"`slot` must be a string\");if(o.assert(e),!a.has(e,n))throw new i(\"`\"+n+\"` is not present on `O`\")},get:function(e,n){if(!e||\"object\"!=typeof e&&\"function\"!=typeof e)throw new i(\"`O` is not an object\");if(\"string\"!=typeof n)throw new i(\"`slot` must be a string\");var t=o.get(e);return t&&t[\"$\"+n]},has:function(e,n){if(!e||\"object\"!=typeof e&&\"function\"!=typeof e)throw new i(\"`O` is not an object\");if(\"string\"!=typeof n)throw new i(\"`slot` must be a string\");var t=o.get(e);return!!t&&r(t,\"$\"+n)},set:function(e,n,t){if(!e||\"object\"!=typeof e&&\"function\"!=typeof e)throw new i(\"`O` is not an object\");if(\"string\"!=typeof n)throw new i(\"`slot` must be a string\");var r=o.get(e);r||(r={},o.set(e,r)),r[\"$\"+n]=t}};Object.freeze&&Object.freeze(a),e.exports=a},7244:(e,n,t)=>{\"use strict\";var r=t(9092)(),o=t(6556)(\"Object.prototype.toString\"),i=function(e){return!(r&&e&&\"object\"==typeof e&&Symbol.toStringTag in e)&&\"[object Arguments]\"===o(e)},a=function(e){return!!i(e)||null!==e&&\"object\"==typeof e&&\"length\"in e&&\"number\"==typeof e.length&&e.length>=0&&\"[object Array]\"!==o(e)&&\"callee\"in e&&\"[object Function]\"===o(e.callee)},l=function(){return i(arguments)}();i.isLegacyArguments=a,e.exports=l?i:a},4670:(e,n,t)=>{\"use strict\";var r=t(487),o=t(6556),i=t(453)(\"%ArrayBuffer%\",!0),a=o(\"ArrayBuffer.prototype.byteLength\",!0),l=o(\"Object.prototype.toString\"),c=!!i&&!a&&new i(0).slice,s=!!c&&r(c);e.exports=a||s?function(e){if(!e||\"object\"!=typeof e)return!1;try{return a?a(e):s(e,0),!0}catch(e){return!1}}:i?function(e){return\"[object ArrayBuffer]\"===l(e)}:function(e){return!1}},9803:(e,n,t)=>{\"use strict\";if(t(9790)()){var r=BigInt.prototype.valueOf;e.exports=function(e){return null!=e&&\"boolean\"!=typeof e&&\"string\"!=typeof e&&\"number\"!=typeof e&&\"symbol\"!=typeof e&&\"function\"!=typeof e&&(\"bigint\"==typeof e||function(e){try{return r.call(e),!0}catch(e){}return!1}(e))}}else e.exports=function(e){return!1}},5128:(e,n,t)=>{\"use strict\";var r=t(6556),o=r(\"Boolean.prototype.toString\"),i=r(\"Object.prototype.toString\"),a=t(9092)();e.exports=function(e){return\"boolean\"==typeof e||null!==e&&\"object\"==typeof e&&(a?function(e){try{return o(e),!0}catch(e){return!1}}(e):\"[object Boolean]\"===i(e))}},9600:e=>{\"use strict\";var n,t,r=Function.prototype.toString,o=\"object\"==typeof Reflect&&null!==Reflect&&Reflect.apply;if(\"function\"==typeof o&&\"function\"==typeof Object.defineProperty)try{n=Object.defineProperty({},\"length\",{get:function(){throw t}}),t={},o((function(){throw 42}),null,n)}catch(e){e!==t&&(o=null)}else o=null;var i=/^\\s*class\\b/,a=function(e){try{var n=r.call(e);return i.test(n)}catch(e){return!1}},l=function(e){try{return!a(e)&&(r.call(e),!0)}catch(e){return!1}},c=Object.prototype.toString,s=\"function\"==typeof Symbol&&!!Symbol.toStringTag,u=!(0 in[,]),p=function(){return!1};if(\"object\"==typeof document){var f=document.all;c.call(f)===c.call(document.all)&&(p=function(e){if((u||!e)&&(void 0===e||\"object\"==typeof e))try{var n=c.call(e);return(\"[object HTMLAllCollection]\"===n||\"[object HTML document.all class]\"===n||\"[object HTMLCollection]\"===n||\"[object Object]\"===n)&&null==e(\"\")}catch(e){}return!1})}e.exports=o?function(e){if(p(e))return!0;if(!e)return!1;if(\"function\"!=typeof e&&\"object\"!=typeof e)return!1;try{o(e,null,n)}catch(e){if(e!==t)return!1}return!a(e)&&l(e)}:function(e){if(p(e))return!0;if(!e)return!1;if(\"function\"!=typeof e&&\"object\"!=typeof e)return!1;if(s)return l(e);if(a(e))return!1;var n=c.call(e);return!(\"[object Function]\"!==n&&\"[object GeneratorFunction]\"!==n&&!/^\\[object HTML/.test(n))&&l(e)}},2120:(e,n,t)=>{\"use strict\";var r=t(6556),o=r(\"Date.prototype.getDay\"),i=r(\"Object.prototype.toString\"),a=t(9092)();e.exports=function(e){return\"object\"==typeof e&&null!==e&&(a?function(e){try{return o(e),!0}catch(e){return!1}}(e):\"[object Date]\"===i(e))}},1421:e=>{\"use strict\";var n,t=\"function\"==typeof Map&&Map.prototype?Map:null,r=\"function\"==typeof Set&&Set.prototype?Set:null;t||(n=function(e){return!1});var o=t?Map.prototype.has:null,i=r?Set.prototype.has:null;n||o||(n=function(e){return!1}),e.exports=n||function(e){if(!e||\"object\"!=typeof e)return!1;try{if(o.call(e),i)try{i.call(e)}catch(e){return!0}return e instanceof t}catch(e){}return!1}},1703:(e,n,t)=>{\"use strict\";var r=t(6556),o=r(\"Number.prototype.toString\"),i=r(\"Object.prototype.toString\"),a=t(9092)();e.exports=function(e){return\"number\"==typeof e||!(!e||\"object\"!=typeof e)&&(a?function(e){try{return o(e),!0}catch(e){return!1}}(e):\"[object Number]\"===i(e))}},4035:(e,n,t)=>{\"use strict\";var r,o=t(6556),i=t(9092)(),a=t(9957),l=t(5795);if(i){var c=o(\"RegExp.prototype.exec\"),s={},u=function(){throw s},p={toString:u,valueOf:u};\"symbol\"==typeof Symbol.toPrimitive&&(p[Symbol.toPrimitive]=u),r=function(e){if(!e||\"object\"!=typeof e)return!1;var n=l(e,\"lastIndex\");if(!(n&&a(n,\"value\")))return!1;try{c(e,p)}catch(e){return e===s}}}else{var f=o(\"Object.prototype.toString\");r=function(e){return!(!e||\"object\"!=typeof e&&\"function\"!=typeof e)&&\"[object RegExp]\"===f(e)}}e.exports=r},256:e=>{\"use strict\";var n,t=\"function\"==typeof Map&&Map.prototype?Map:null,r=\"function\"==typeof Set&&Set.prototype?Set:null;r||(n=function(e){return!1});var o=t?Map.prototype.has:null,i=r?Set.prototype.has:null;n||i||(n=function(e){return!1}),e.exports=n||function(e){if(!e||\"object\"!=typeof e)return!1;try{if(i.call(e),o)try{o.call(e)}catch(e){return!0}return e instanceof r}catch(e){}return!1}},7070:(e,n,t)=>{\"use strict\";var r=t(6556)(\"SharedArrayBuffer.prototype.byteLength\",!0);e.exports=r?function(e){if(!e||\"object\"!=typeof e)return!1;try{return r(e),!0}catch(e){return!1}}:function(e){return!1}},4761:(e,n,t)=>{\"use strict\";var r=t(6556),o=r(\"String.prototype.valueOf\"),i=r(\"Object.prototype.toString\"),a=t(9092)();e.exports=function(e){return\"string\"==typeof e||!(!e||\"object\"!=typeof e)&&(a?function(e){try{return o(e),!0}catch(e){return!1}}(e):\"[object String]\"===i(e))}},3612:(e,n,t)=>{\"use strict\";var r=t(6556),o=r(\"Object.prototype.toString\"),i=t(4039)(),a=t(9721);if(i){var l=r(\"Symbol.prototype.toString\"),c=a(/^Symbol\\(.*\\)$/);e.exports=function(e){if(\"symbol\"==typeof e)return!0;if(!e||\"object\"!=typeof e||\"[object Symbol]\"!==o(e))return!1;try{return function(e){return\"symbol\"==typeof e.valueOf()&&c(l(e))}(e)}catch(e){return!1}}}else e.exports=function(e){return!1}},7842:e=>{\"use strict\";var n,t=\"function\"==typeof WeakMap&&WeakMap.prototype?WeakMap:null,r=\"function\"==typeof WeakSet&&WeakSet.prototype?WeakSet:null;t||(n=function(e){return!1});var o=t?t.prototype.has:null,i=r?r.prototype.has:null;n||o||(n=function(e){return!1}),e.exports=n||function(e){if(!e||\"object\"!=typeof e)return!1;try{if(o.call(e,o),i)try{i.call(e,i)}catch(e){return!0}return e instanceof t}catch(e){}return!1}},2648:(e,n,t)=>{\"use strict\";var r=t(453),o=t(6556),i=r(\"%WeakSet%\",!0),a=o(\"WeakSet.prototype.has\",!0);if(a){var l=o(\"WeakMap.prototype.has\",!0);e.exports=function(e){if(!e||\"object\"!=typeof e)return!1;try{if(a(e,a),l)try{l(e,l)}catch(e){return!0}return e instanceof i}catch(e){}return!1}}else e.exports=function(e){return!1}},4634:e=>{var n={}.toString;e.exports=Array.isArray||function(e){return\"[object Array]\"==n.call(e)}},1514:e=>{\"use strict\";e.exports=Math.abs},8968:e=>{\"use strict\";e.exports=Math.floor},4459:e=>{\"use strict\";e.exports=Number.isNaN||function(e){return e!=e}},6188:e=>{\"use strict\";e.exports=Math.max},8002:e=>{\"use strict\";e.exports=Math.min},5880:e=>{\"use strict\";e.exports=Math.pow},414:e=>{\"use strict\";e.exports=Math.round},3093:(e,n,t)=>{\"use strict\";var r=t(4459);e.exports=function(e){return r(e)||0===e?e:e<0?-1:1}},5228:e=>{\"use strict\";\n/*\nobject-assign\n(c) Sindre Sorhus\n@license MIT\n*/var n=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String(\"abc\");if(e[5]=\"de\",\"5\"===Object.getOwnPropertyNames(e)[0])return!1;for(var n={},t=0;t<10;t++)n[\"_\"+String.fromCharCode(t)]=t;if(\"0123456789\"!==Object.getOwnPropertyNames(n).map((function(e){return n[e]})).join(\"\"))return!1;var r={};return\"abcdefghijklmnopqrst\".split(\"\").forEach((function(e){r[e]=e})),\"abcdefghijklmnopqrst\"===Object.keys(Object.assign({},r)).join(\"\")}catch(e){return!1}}()?Object.assign:function(e,o){for(var i,a,l=function(e){if(null==e)throw new TypeError(\"Object.assign cannot be called with null or undefined\");return Object(e)}(e),c=1;c<arguments.length;c++){for(var s in i=Object(arguments[c]))t.call(i,s)&&(l[s]=i[s]);if(n){a=n(i);for(var u=0;u<a.length;u++)r.call(i,a[u])&&(l[a[u]]=i[a[u]])}}return l}},8859:(e,n,t)=>{var r=\"function\"==typeof Map&&Map.prototype,o=Object.getOwnPropertyDescriptor&&r?Object.getOwnPropertyDescriptor(Map.prototype,\"size\"):null,i=r&&o&&\"function\"==typeof o.get?o.get:null,a=r&&Map.prototype.forEach,l=\"function\"==typeof Set&&Set.prototype,c=Object.getOwnPropertyDescriptor&&l?Object.getOwnPropertyDescriptor(Set.prototype,\"size\"):null,s=l&&c&&\"function\"==typeof c.get?c.get:null,u=l&&Set.prototype.forEach,p=\"function\"==typeof WeakMap&&WeakMap.prototype?WeakMap.prototype.has:null,f=\"function\"==typeof WeakSet&&WeakSet.prototype?WeakSet.prototype.has:null,d=\"function\"==typeof WeakRef&&WeakRef.prototype?WeakRef.prototype.deref:null,g=Boolean.prototype.valueOf,h=Object.prototype.toString,A=Function.prototype.toString,b=String.prototype.match,v=String.prototype.slice,m=String.prototype.replace,y=String.prototype.toUpperCase,E=String.prototype.toLowerCase,C=RegExp.prototype.test,w=Array.prototype.concat,x=Array.prototype.join,S=Array.prototype.slice,_=Math.floor,k=\"function\"==typeof BigInt?BigInt.prototype.valueOf:null,O=Object.getOwnPropertySymbols,B=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?Symbol.prototype.toString:null,P=\"function\"==typeof Symbol&&\"object\"==typeof Symbol.iterator,T=\"function\"==typeof Symbol&&Symbol.toStringTag&&(typeof Symbol.toStringTag===P||\"symbol\")?Symbol.toStringTag:null,I=Object.prototype.propertyIsEnumerable,j=(\"function\"==typeof Reflect?Reflect.getPrototypeOf:Object.getPrototypeOf)||([].__proto__===Array.prototype?function(e){return e.__proto__}:null);function z(e,n){if(e===1/0||e===-1/0||e!=e||e&&e>-1e3&&e<1e3||C.call(/e/,n))return n;var t=/[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;if(\"number\"==typeof e){var r=e<0?-_(-e):_(e);if(r!==e){var o=String(r),i=v.call(n,o.length+1);return m.call(o,t,\"$&_\")+\".\"+m.call(m.call(i,/([0-9]{3})/g,\"$&_\"),/_$/,\"\")}}return m.call(n,t,\"$&_\")}var D=t(2634),R=D.custom,M=Y(R)?R:null,N={__proto__:null,double:'\"',single:\"'\"},F={__proto__:null,double:/([\"\\\\])/g,single:/(['\\\\])/g};function L(e,n,t){var r=t.quoteStyle||n,o=N[r];return o+e+o}function H(e){return m.call(String(e),/\"/g,\"&quot;\")}function U(e){return!T||!(\"object\"==typeof e&&(T in e||void 0!==e[T]))}function W(e){return\"[object Array]\"===$(e)&&U(e)}function G(e){return\"[object RegExp]\"===$(e)&&U(e)}function Y(e){if(P)return e&&\"object\"==typeof e&&e instanceof Symbol;if(\"symbol\"==typeof e)return!0;if(!e||\"object\"!=typeof e||!B)return!1;try{return B.call(e),!0}catch(e){}return!1}e.exports=function e(n,r,o,l){var c=r||{};if(V(c,\"quoteStyle\")&&!V(N,c.quoteStyle))throw new TypeError('option \"quoteStyle\" must be \"single\" or \"double\"');if(V(c,\"maxStringLength\")&&(\"number\"==typeof c.maxStringLength?c.maxStringLength<0&&c.maxStringLength!==1/0:null!==c.maxStringLength))throw new TypeError('option \"maxStringLength\", if provided, must be a positive integer, Infinity, or `null`');var h=!V(c,\"customInspect\")||c.customInspect;if(\"boolean\"!=typeof h&&\"symbol\"!==h)throw new TypeError(\"option \\\"customInspect\\\", if provided, must be `true`, `false`, or `'symbol'`\");if(V(c,\"indent\")&&null!==c.indent&&\"\\t\"!==c.indent&&!(parseInt(c.indent,10)===c.indent&&c.indent>0))throw new TypeError('option \"indent\" must be \"\\\\t\", an integer > 0, or `null`');if(V(c,\"numericSeparator\")&&\"boolean\"!=typeof c.numericSeparator)throw new TypeError('option \"numericSeparator\", if provided, must be `true` or `false`');var y=c.numericSeparator;if(void 0===n)return\"undefined\";if(null===n)return\"null\";if(\"boolean\"==typeof n)return n?\"true\":\"false\";if(\"string\"==typeof n)return Q(n,c);if(\"number\"==typeof n){if(0===n)return 1/0/n>0?\"0\":\"-0\";var C=String(n);return y?z(n,C):C}if(\"bigint\"==typeof n){var _=String(n)+\"n\";return y?z(n,_):_}var O=void 0===c.depth?5:c.depth;if(void 0===o&&(o=0),o>=O&&O>0&&\"object\"==typeof n)return W(n)?\"[Array]\":\"[Object]\";var R=function(e,n){var t;if(\"\\t\"===e.indent)t=\"\\t\";else{if(!(\"number\"==typeof e.indent&&e.indent>0))return null;t=x.call(Array(e.indent+1),\" \")}return{base:t,prev:x.call(Array(n+1),t)}}(c,o);if(void 0===l)l=[];else if(K(l,n)>=0)return\"[Circular]\";function F(n,t,r){if(t&&(l=S.call(l)).push(t),r){var i={depth:c.depth};return V(c,\"quoteStyle\")&&(i.quoteStyle=c.quoteStyle),e(n,i,o+1,l)}return e(n,c,o+1,l)}if(\"function\"==typeof n&&!G(n)){var q=function(e){if(e.name)return e.name;var n=b.call(A.call(e),/^function\\s*([\\w$]+)/);if(n)return n[1];return null}(n),X=te(n,F);return\"[Function\"+(q?\": \"+q:\" (anonymous)\")+\"]\"+(X.length>0?\" { \"+x.call(X,\", \")+\" }\":\"\")}if(Y(n)){var re=P?m.call(String(n),/^(Symbol\\(.*\\))_[^)]*$/,\"$1\"):B.call(n);return\"object\"!=typeof n||P?re:Z(re)}if(function(e){if(!e||\"object\"!=typeof e)return!1;if(\"undefined\"!=typeof HTMLElement&&e instanceof HTMLElement)return!0;return\"string\"==typeof e.nodeName&&\"function\"==typeof e.getAttribute}(n)){for(var oe=\"<\"+E.call(String(n.nodeName)),ie=n.attributes||[],ae=0;ae<ie.length;ae++)oe+=\" \"+ie[ae].name+\"=\"+L(H(ie[ae].value),\"double\",c);return oe+=\">\",n.childNodes&&n.childNodes.length&&(oe+=\"...\"),oe+=\"</\"+E.call(String(n.nodeName))+\">\"}if(W(n)){if(0===n.length)return\"[]\";var le=te(n,F);return R&&!function(e){for(var n=0;n<e.length;n++)if(K(e[n],\"\\n\")>=0)return!1;return!0}(le)?\"[\"+ne(le,R)+\"]\":\"[ \"+x.call(le,\", \")+\" ]\"}if(function(e){return\"[object Error]\"===$(e)&&U(e)}(n)){var ce=te(n,F);return\"cause\"in Error.prototype||!(\"cause\"in n)||I.call(n,\"cause\")?0===ce.length?\"[\"+String(n)+\"]\":\"{ [\"+String(n)+\"] \"+x.call(ce,\", \")+\" }\":\"{ [\"+String(n)+\"] \"+x.call(w.call(\"[cause]: \"+F(n.cause),ce),\", \")+\" }\"}if(\"object\"==typeof n&&h){if(M&&\"function\"==typeof n[M]&&D)return D(n,{depth:O-o});if(\"symbol\"!==h&&\"function\"==typeof n.inspect)return n.inspect()}if(function(e){if(!i||!e||\"object\"!=typeof e)return!1;try{i.call(e);try{s.call(e)}catch(e){return!0}return e instanceof Map}catch(e){}return!1}(n)){var se=[];return a&&a.call(n,(function(e,t){se.push(F(t,n,!0)+\" => \"+F(e,n))})),ee(\"Map\",i.call(n),se,R)}if(function(e){if(!s||!e||\"object\"!=typeof e)return!1;try{s.call(e);try{i.call(e)}catch(e){return!0}return e instanceof Set}catch(e){}return!1}(n)){var ue=[];return u&&u.call(n,(function(e){ue.push(F(e,n))})),ee(\"Set\",s.call(n),ue,R)}if(function(e){if(!p||!e||\"object\"!=typeof e)return!1;try{p.call(e,p);try{f.call(e,f)}catch(e){return!0}return e instanceof WeakMap}catch(e){}return!1}(n))return J(\"WeakMap\");if(function(e){if(!f||!e||\"object\"!=typeof e)return!1;try{f.call(e,f);try{p.call(e,p)}catch(e){return!0}return e instanceof WeakSet}catch(e){}return!1}(n))return J(\"WeakSet\");if(function(e){if(!d||!e||\"object\"!=typeof e)return!1;try{return d.call(e),!0}catch(e){}return!1}(n))return J(\"WeakRef\");if(function(e){return\"[object Number]\"===$(e)&&U(e)}(n))return Z(F(Number(n)));if(function(e){if(!e||\"object\"!=typeof e||!k)return!1;try{return k.call(e),!0}catch(e){}return!1}(n))return Z(F(k.call(n)));if(function(e){return\"[object Boolean]\"===$(e)&&U(e)}(n))return Z(g.call(n));if(function(e){return\"[object String]\"===$(e)&&U(e)}(n))return Z(F(String(n)));if(\"undefined\"!=typeof window&&n===window)return\"{ [object Window] }\";if(\"undefined\"!=typeof globalThis&&n===globalThis||void 0!==t.g&&n===t.g)return\"{ [object globalThis] }\";if(!function(e){return\"[object Date]\"===$(e)&&U(e)}(n)&&!G(n)){var pe=te(n,F),fe=j?j(n)===Object.prototype:n instanceof Object||n.constructor===Object,de=n instanceof Object?\"\":\"null prototype\",ge=!fe&&T&&Object(n)===n&&T in n?v.call($(n),8,-1):de?\"Object\":\"\",he=(fe||\"function\"!=typeof n.constructor?\"\":n.constructor.name?n.constructor.name+\" \":\"\")+(ge||de?\"[\"+x.call(w.call([],ge||[],de||[]),\": \")+\"] \":\"\");return 0===pe.length?he+\"{}\":R?he+\"{\"+ne(pe,R)+\"}\":he+\"{ \"+x.call(pe,\", \")+\" }\"}return String(n)};var q=Object.prototype.hasOwnProperty||function(e){return e in this};function V(e,n){return q.call(e,n)}function $(e){return h.call(e)}function K(e,n){if(e.indexOf)return e.indexOf(n);for(var t=0,r=e.length;t<r;t++)if(e[t]===n)return t;return-1}function Q(e,n){if(e.length>n.maxStringLength){var t=e.length-n.maxStringLength,r=\"... \"+t+\" more character\"+(t>1?\"s\":\"\");return Q(v.call(e,0,n.maxStringLength),n)+r}var o=F[n.quoteStyle||\"single\"];return o.lastIndex=0,L(m.call(m.call(e,o,\"\\\\$1\"),/[\\x00-\\x1f]/g,X),\"single\",n)}function X(e){var n=e.charCodeAt(0),t={8:\"b\",9:\"t\",10:\"n\",12:\"f\",13:\"r\"}[n];return t?\"\\\\\"+t:\"\\\\x\"+(n<16?\"0\":\"\")+y.call(n.toString(16))}function Z(e){return\"Object(\"+e+\")\"}function J(e){return e+\" { ? }\"}function ee(e,n,t,r){return e+\" (\"+n+\") {\"+(r?ne(t,r):x.call(t,\", \"))+\"}\"}function ne(e,n){if(0===e.length)return\"\";var t=\"\\n\"+n.prev+n.base;return t+x.call(e,\",\"+t)+\"\\n\"+n.prev}function te(e,n){var t=W(e),r=[];if(t){r.length=e.length;for(var o=0;o<e.length;o++)r[o]=V(e,o)?n(e[o],e):\"\"}var i,a=\"function\"==typeof O?O(e):[];if(P){i={};for(var l=0;l<a.length;l++)i[\"$\"+a[l]]=a[l]}for(var c in e)V(e,c)&&(t&&String(Number(c))===c&&c<e.length||P&&i[\"$\"+c]instanceof Symbol||(C.call(/[^\\w$]/,c)?r.push(n(c,e)+\": \"+n(e[c],e)):r.push(c+\": \"+n(e[c],e))));if(\"function\"==typeof O)for(var s=0;s<a.length;s++)I.call(e,a[s])&&r.push(\"[\"+n(a[s])+\"]: \"+n(e[a[s]],e));return r}},9211:e=>{\"use strict\";var n=function(e){return e!=e};e.exports=function(e,t){return 0===e&&0===t?1/e==1/t:e===t||!(!n(e)||!n(t))}},7653:(e,n,t)=>{\"use strict\";var r=t(8452),o=t(487),i=t(9211),a=t(9394),l=t(6576),c=o(a(),Object);r(c,{getPolyfill:a,implementation:i,shim:l}),e.exports=c},9394:(e,n,t)=>{\"use strict\";var r=t(9211);e.exports=function(){return\"function\"==typeof Object.is?Object.is:r}},6576:(e,n,t)=>{\"use strict\";var r=t(9394),o=t(8452);e.exports=function(){var e=r();return o(Object,{is:e},{is:function(){return Object.is!==e}}),e}},8875:(e,n,t)=>{\"use strict\";var r;if(!Object.keys){var o=Object.prototype.hasOwnProperty,i=Object.prototype.toString,a=t(1093),l=Object.prototype.propertyIsEnumerable,c=!l.call({toString:null},\"toString\"),s=l.call((function(){}),\"prototype\"),u=[\"toString\",\"toLocaleString\",\"valueOf\",\"hasOwnProperty\",\"isPrototypeOf\",\"propertyIsEnumerable\",\"constructor\"],p=function(e){var n=e.constructor;return n&&n.prototype===e},f={$applicationCache:!0,$console:!0,$external:!0,$frame:!0,$frameElement:!0,$frames:!0,$innerHeight:!0,$innerWidth:!0,$onmozfullscreenchange:!0,$onmozfullscreenerror:!0,$outerHeight:!0,$outerWidth:!0,$pageXOffset:!0,$pageYOffset:!0,$parent:!0,$scrollLeft:!0,$scrollTop:!0,$scrollX:!0,$scrollY:!0,$self:!0,$webkitIndexedDB:!0,$webkitStorageInfo:!0,$window:!0},d=function(){if(\"undefined\"==typeof window)return!1;for(var e in window)try{if(!f[\"$\"+e]&&o.call(window,e)&&null!==window[e]&&\"object\"==typeof window[e])try{p(window[e])}catch(e){return!0}}catch(e){return!0}return!1}();r=function(e){var n=null!==e&&\"object\"==typeof e,t=\"[object Function]\"===i.call(e),r=a(e),l=n&&\"[object String]\"===i.call(e),f=[];if(!n&&!t&&!r)throw new TypeError(\"Object.keys called on a non-object\");var g=s&&t;if(l&&e.length>0&&!o.call(e,0))for(var h=0;h<e.length;++h)f.push(String(h));if(r&&e.length>0)for(var A=0;A<e.length;++A)f.push(String(A));else for(var b in e)g&&\"prototype\"===b||!o.call(e,b)||f.push(String(b));if(c)for(var v=function(e){if(\"undefined\"==typeof window||!d)return p(e);try{return p(e)}catch(e){return!1}}(e),m=0;m<u.length;++m)v&&\"constructor\"===u[m]||!o.call(e,u[m])||f.push(u[m]);return f}}e.exports=r},1189:(e,n,t)=>{\"use strict\";var r=Array.prototype.slice,o=t(1093),i=Object.keys,a=i?function(e){return i(e)}:t(8875),l=Object.keys;a.shim=function(){if(Object.keys){var e=function(){var e=Object.keys(arguments);return e&&e.length===arguments.length}(1,2);e||(Object.keys=function(e){return o(e)?l(r.call(e)):l(e)})}else Object.keys=a;return Object.keys||a},e.exports=a},1093:e=>{\"use strict\";var n=Object.prototype.toString;e.exports=function(e){var t=n.call(e),r=\"[object Arguments]\"===t;return r||(r=\"[object Array]\"!==t&&null!==e&&\"object\"==typeof e&&\"number\"==typeof e.length&&e.length>=0&&\"[object Function]\"===n.call(e.callee)),r}},8403:(e,n,t)=>{\"use strict\";var r=t(1189),o=t(1333)(),i=t(6556),a=t(9612),l=i(\"Array.prototype.push\"),c=i(\"Object.prototype.propertyIsEnumerable\"),s=o?a.getOwnPropertySymbols:null;e.exports=function(e,n){if(null==e)throw new TypeError(\"target must be an object\");var t=a(e);if(1===arguments.length)return t;for(var i=1;i<arguments.length;++i){var u=a(arguments[i]),p=r(u),f=o&&(a.getOwnPropertySymbols||s);if(f)for(var d=f(u),g=0;g<d.length;++g){var h=d[g];c(u,h)&&l(p,h)}for(var A=0;A<p.length;++A){var b=p[A];if(c(u,b)){var v=u[b];t[b]=v}}}return t}},6525:(e,n,t)=>{\"use strict\";var r=t(8452),o=t(487),i=t(8403),a=t(9133),l=t(984),c=o.apply(a()),s=function(e,n){return c(Object,arguments)};r(s,{getPolyfill:a,implementation:i,shim:l}),e.exports=s},9133:(e,n,t)=>{\"use strict\";var r=t(8403);e.exports=function(){return Object.assign?function(){if(!Object.assign)return!1;for(var e=\"abcdefghijklmnopqrst\",n=e.split(\"\"),t={},r=0;r<n.length;++r)t[n[r]]=n[r];var o=Object.assign({},t),i=\"\";for(var a in o)i+=a;return e!==i}()||function(){if(!Object.assign||!Object.preventExtensions)return!1;var e=Object.preventExtensions({1:2});try{Object.assign(e,\"xy\")}catch(n){return\"y\"===e[1]}return!1}()?r:Object.assign:r}},984:(e,n,t)=>{\"use strict\";var r=t(8452),o=t(9133);e.exports=function(){var e=o();return r(Object,{assign:e},{assign:function(){return Object.assign!==e}}),e}},6578:e=>{\"use strict\";e.exports=[\"Float16Array\",\"Float32Array\",\"Float64Array\",\"Int8Array\",\"Int16Array\",\"Int32Array\",\"Uint8Array\",\"Uint8ClampedArray\",\"Uint16Array\",\"Uint32Array\",\"BigInt64Array\",\"BigUint64Array\"]},2694:(e,n,t)=>{\"use strict\";var r=t(6925);function o(){}function i(){}i.resetWarningCache=o,e.exports=function(){function e(e,n,t,o,i,a){if(a!==r){var l=new Error(\"Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types\");throw l.name=\"Invariant Violation\",l}}function n(){return e}e.isRequired=e;var t={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:n,element:e,elementType:e,instanceOf:n,node:e,objectOf:n,oneOf:n,oneOfType:n,shape:n,exact:n,checkPropTypes:i,resetWarningCache:o};return t.PropTypes=t,t}},5556:(e,n,t)=>{e.exports=t(2694)()},6925:e=>{\"use strict\";e.exports=\"SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED\"},2551:(e,n,t)=>{\"use strict\";var r=t(6540),o=t(5228),i=t(9982);\n/** @license React v17.0.2\n * react-dom.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */function a(e){for(var n=\"https://reactjs.org/docs/error-decoder.html?invariant=\"+e,t=1;t<arguments.length;t++)n+=\"&args[]=\"+encodeURIComponent(arguments[t]);return\"Minified React error #\"+e+\"; visit \"+n+\" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.\"}if(!r)throw Error(a(227));var l=new Set,c={};function s(e,n){u(e,n),u(e+\"Capture\",n)}function u(e,n){for(c[e]=n,e=0;e<n.length;e++)l.add(n[e])}var p=!(\"undefined\"==typeof window||void 0===window.document||void 0===window.document.createElement),f=/^[:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD][:A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*$/,d=Object.prototype.hasOwnProperty,g={},h={};function A(e,n,t,r,o,i,a){this.acceptsBooleans=2===n||3===n||4===n,this.attributeName=r,this.attributeNamespace=o,this.mustUseProperty=t,this.propertyName=e,this.type=n,this.sanitizeURL=i,this.removeEmptyString=a}var b={};\"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style\".split(\" \").forEach((function(e){b[e]=new A(e,0,!1,e,null,!1,!1)})),[[\"acceptCharset\",\"accept-charset\"],[\"className\",\"class\"],[\"htmlFor\",\"for\"],[\"httpEquiv\",\"http-equiv\"]].forEach((function(e){var n=e[0];b[n]=new A(n,1,!1,e[1],null,!1,!1)})),[\"contentEditable\",\"draggable\",\"spellCheck\",\"value\"].forEach((function(e){b[e]=new A(e,2,!1,e.toLowerCase(),null,!1,!1)})),[\"autoReverse\",\"externalResourcesRequired\",\"focusable\",\"preserveAlpha\"].forEach((function(e){b[e]=new A(e,2,!1,e,null,!1,!1)})),\"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope\".split(\" \").forEach((function(e){b[e]=new A(e,3,!1,e.toLowerCase(),null,!1,!1)})),[\"checked\",\"multiple\",\"muted\",\"selected\"].forEach((function(e){b[e]=new A(e,3,!0,e,null,!1,!1)})),[\"capture\",\"download\"].forEach((function(e){b[e]=new A(e,4,!1,e,null,!1,!1)})),[\"cols\",\"rows\",\"size\",\"span\"].forEach((function(e){b[e]=new A(e,6,!1,e,null,!1,!1)})),[\"rowSpan\",\"start\"].forEach((function(e){b[e]=new A(e,5,!1,e.toLowerCase(),null,!1,!1)}));var v=/[\\-:]([a-z])/g;function m(e){return e[1].toUpperCase()}function y(e,n,t,r){var o=b.hasOwnProperty(n)?b[n]:null;(null!==o?0===o.type:!r&&(2<n.length&&(\"o\"===n[0]||\"O\"===n[0])&&(\"n\"===n[1]||\"N\"===n[1])))||(function(e,n,t,r){if(null==n||function(e,n,t,r){if(null!==t&&0===t.type)return!1;switch(typeof n){case\"function\":case\"symbol\":return!0;case\"boolean\":return!r&&(null!==t?!t.acceptsBooleans:\"data-\"!==(e=e.toLowerCase().slice(0,5))&&\"aria-\"!==e);default:return!1}}(e,n,t,r))return!0;if(r)return!1;if(null!==t)switch(t.type){case 3:return!n;case 4:return!1===n;case 5:return isNaN(n);case 6:return isNaN(n)||1>n}return!1}(n,t,o,r)&&(t=null),r||null===o?function(e){return!!d.call(h,e)||!d.call(g,e)&&(f.test(e)?h[e]=!0:(g[e]=!0,!1))}(n)&&(null===t?e.removeAttribute(n):e.setAttribute(n,\"\"+t)):o.mustUseProperty?e[o.propertyName]=null===t?3!==o.type&&\"\":t:(n=o.attributeName,r=o.attributeNamespace,null===t?e.removeAttribute(n):(t=3===(o=o.type)||4===o&&!0===t?\"\":\"\"+t,r?e.setAttributeNS(r,n,t):e.setAttribute(n,t))))}\"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height\".split(\" \").forEach((function(e){var n=e.replace(v,m);b[n]=new A(n,1,!1,e,null,!1,!1)})),\"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type\".split(\" \").forEach((function(e){var n=e.replace(v,m);b[n]=new A(n,1,!1,e,\"http://www.w3.org/1999/xlink\",!1,!1)})),[\"xml:base\",\"xml:lang\",\"xml:space\"].forEach((function(e){var n=e.replace(v,m);b[n]=new A(n,1,!1,e,\"http://www.w3.org/XML/1998/namespace\",!1,!1)})),[\"tabIndex\",\"crossOrigin\"].forEach((function(e){b[e]=new A(e,1,!1,e.toLowerCase(),null,!1,!1)})),b.xlinkHref=new A(\"xlinkHref\",1,!1,\"xlink:href\",\"http://www.w3.org/1999/xlink\",!0,!1),[\"src\",\"href\",\"action\",\"formAction\"].forEach((function(e){b[e]=new A(e,1,!1,e.toLowerCase(),null,!0,!0)}));var E=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED,C=60103,w=60106,x=60107,S=60108,_=60114,k=60109,O=60110,B=60112,P=60113,T=60120,I=60115,j=60116,z=60121,D=60128,R=60129,M=60130,N=60131;if(\"function\"==typeof Symbol&&Symbol.for){var F=Symbol.for;C=F(\"react.element\"),w=F(\"react.portal\"),x=F(\"react.fragment\"),S=F(\"react.strict_mode\"),_=F(\"react.profiler\"),k=F(\"react.provider\"),O=F(\"react.context\"),B=F(\"react.forward_ref\"),P=F(\"react.suspense\"),T=F(\"react.suspense_list\"),I=F(\"react.memo\"),j=F(\"react.lazy\"),z=F(\"react.block\"),F(\"react.scope\"),D=F(\"react.opaque.id\"),R=F(\"react.debug_trace_mode\"),M=F(\"react.offscreen\"),N=F(\"react.legacy_hidden\")}var L,H=\"function\"==typeof Symbol&&Symbol.iterator;function U(e){return null===e||\"object\"!=typeof e?null:\"function\"==typeof(e=H&&e[H]||e[\"@@iterator\"])?e:null}function W(e){if(void 0===L)try{throw Error()}catch(e){var n=e.stack.trim().match(/\\n( *(at )?)/);L=n&&n[1]||\"\"}return\"\\n\"+L+e}var G=!1;function Y(e,n){if(!e||G)return\"\";G=!0;var t=Error.prepareStackTrace;Error.prepareStackTrace=void 0;try{if(n)if(n=function(){throw Error()},Object.defineProperty(n.prototype,\"props\",{set:function(){throw Error()}}),\"object\"==typeof Reflect&&Reflect.construct){try{Reflect.construct(n,[])}catch(e){var r=e}Reflect.construct(e,[],n)}else{try{n.call()}catch(e){r=e}e.call(n.prototype)}else{try{throw Error()}catch(e){r=e}e()}}catch(e){if(e&&r&&\"string\"==typeof e.stack){for(var o=e.stack.split(\"\\n\"),i=r.stack.split(\"\\n\"),a=o.length-1,l=i.length-1;1<=a&&0<=l&&o[a]!==i[l];)l--;for(;1<=a&&0<=l;a--,l--)if(o[a]!==i[l]){if(1!==a||1!==l)do{if(a--,0>--l||o[a]!==i[l])return\"\\n\"+o[a].replace(\" at new \",\" at \")}while(1<=a&&0<=l);break}}}finally{G=!1,Error.prepareStackTrace=t}return(e=e?e.displayName||e.name:\"\")?W(e):\"\"}function q(e){switch(e.tag){case 5:return W(e.type);case 16:return W(\"Lazy\");case 13:return W(\"Suspense\");case 19:return W(\"SuspenseList\");case 0:case 2:case 15:return e=Y(e.type,!1);case 11:return e=Y(e.type.render,!1);case 22:return e=Y(e.type._render,!1);case 1:return e=Y(e.type,!0);default:return\"\"}}function V(e){if(null==e)return null;if(\"function\"==typeof e)return e.displayName||e.name||null;if(\"string\"==typeof e)return e;switch(e){case x:return\"Fragment\";case w:return\"Portal\";case _:return\"Profiler\";case S:return\"StrictMode\";case P:return\"Suspense\";case T:return\"SuspenseList\"}if(\"object\"==typeof e)switch(e.$$typeof){case O:return(e.displayName||\"Context\")+\".Consumer\";case k:return(e._context.displayName||\"Context\")+\".Provider\";case B:var n=e.render;return n=n.displayName||n.name||\"\",e.displayName||(\"\"!==n?\"ForwardRef(\"+n+\")\":\"ForwardRef\");case I:return V(e.type);case z:return V(e._render);case j:n=e._payload,e=e._init;try{return V(e(n))}catch(e){}}return null}function $(e){switch(typeof e){case\"boolean\":case\"number\":case\"object\":case\"string\":case\"undefined\":return e;default:return\"\"}}function K(e){var n=e.type;return(e=e.nodeName)&&\"input\"===e.toLowerCase()&&(\"checkbox\"===n||\"radio\"===n)}function Q(e){e._valueTracker||(e._valueTracker=function(e){var n=K(e)?\"checked\":\"value\",t=Object.getOwnPropertyDescriptor(e.constructor.prototype,n),r=\"\"+e[n];if(!e.hasOwnProperty(n)&&void 0!==t&&\"function\"==typeof t.get&&\"function\"==typeof t.set){var o=t.get,i=t.set;return Object.defineProperty(e,n,{configurable:!0,get:function(){return o.call(this)},set:function(e){r=\"\"+e,i.call(this,e)}}),Object.defineProperty(e,n,{enumerable:t.enumerable}),{getValue:function(){return r},setValue:function(e){r=\"\"+e},stopTracking:function(){e._valueTracker=null,delete e[n]}}}}(e))}function X(e){if(!e)return!1;var n=e._valueTracker;if(!n)return!0;var t=n.getValue(),r=\"\";return e&&(r=K(e)?e.checked?\"true\":\"false\":e.value),(e=r)!==t&&(n.setValue(e),!0)}function Z(e){if(void 0===(e=e||(\"undefined\"!=typeof document?document:void 0)))return null;try{return e.activeElement||e.body}catch(n){return e.body}}function J(e,n){var t=n.checked;return o({},n,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=t?t:e._wrapperState.initialChecked})}function ee(e,n){var t=null==n.defaultValue?\"\":n.defaultValue,r=null!=n.checked?n.checked:n.defaultChecked;t=$(null!=n.value?n.value:t),e._wrapperState={initialChecked:r,initialValue:t,controlled:\"checkbox\"===n.type||\"radio\"===n.type?null!=n.checked:null!=n.value}}function ne(e,n){null!=(n=n.checked)&&y(e,\"checked\",n,!1)}function te(e,n){ne(e,n);var t=$(n.value),r=n.type;if(null!=t)\"number\"===r?(0===t&&\"\"===e.value||e.value!=t)&&(e.value=\"\"+t):e.value!==\"\"+t&&(e.value=\"\"+t);else if(\"submit\"===r||\"reset\"===r)return void e.removeAttribute(\"value\");n.hasOwnProperty(\"value\")?oe(e,n.type,t):n.hasOwnProperty(\"defaultValue\")&&oe(e,n.type,$(n.defaultValue)),null==n.checked&&null!=n.defaultChecked&&(e.defaultChecked=!!n.defaultChecked)}function re(e,n,t){if(n.hasOwnProperty(\"value\")||n.hasOwnProperty(\"defaultValue\")){var r=n.type;if(!(\"submit\"!==r&&\"reset\"!==r||void 0!==n.value&&null!==n.value))return;n=\"\"+e._wrapperState.initialValue,t||n===e.value||(e.value=n),e.defaultValue=n}\"\"!==(t=e.name)&&(e.name=\"\"),e.defaultChecked=!!e._wrapperState.initialChecked,\"\"!==t&&(e.name=t)}function oe(e,n,t){\"number\"===n&&Z(e.ownerDocument)===e||(null==t?e.defaultValue=\"\"+e._wrapperState.initialValue:e.defaultValue!==\"\"+t&&(e.defaultValue=\"\"+t))}function ie(e,n){return e=o({children:void 0},n),(n=function(e){var n=\"\";return r.Children.forEach(e,(function(e){null!=e&&(n+=e)})),n}(n.children))&&(e.children=n),e}function ae(e,n,t,r){if(e=e.options,n){n={};for(var o=0;o<t.length;o++)n[\"$\"+t[o]]=!0;for(t=0;t<e.length;t++)o=n.hasOwnProperty(\"$\"+e[t].value),e[t].selected!==o&&(e[t].selected=o),o&&r&&(e[t].defaultSelected=!0)}else{for(t=\"\"+$(t),n=null,o=0;o<e.length;o++){if(e[o].value===t)return e[o].selected=!0,void(r&&(e[o].defaultSelected=!0));null!==n||e[o].disabled||(n=e[o])}null!==n&&(n.selected=!0)}}function le(e,n){if(null!=n.dangerouslySetInnerHTML)throw Error(a(91));return o({},n,{value:void 0,defaultValue:void 0,children:\"\"+e._wrapperState.initialValue})}function ce(e,n){var t=n.value;if(null==t){if(t=n.children,n=n.defaultValue,null!=t){if(null!=n)throw Error(a(92));if(Array.isArray(t)){if(!(1>=t.length))throw Error(a(93));t=t[0]}n=t}null==n&&(n=\"\"),t=n}e._wrapperState={initialValue:$(t)}}function se(e,n){var t=$(n.value),r=$(n.defaultValue);null!=t&&((t=\"\"+t)!==e.value&&(e.value=t),null==n.defaultValue&&e.defaultValue!==t&&(e.defaultValue=t)),null!=r&&(e.defaultValue=\"\"+r)}function ue(e){var n=e.textContent;n===e._wrapperState.initialValue&&\"\"!==n&&null!==n&&(e.value=n)}var pe=\"http://www.w3.org/1999/xhtml\",fe=\"http://www.w3.org/2000/svg\";function de(e){switch(e){case\"svg\":return\"http://www.w3.org/2000/svg\";case\"math\":return\"http://www.w3.org/1998/Math/MathML\";default:return\"http://www.w3.org/1999/xhtml\"}}function ge(e,n){return null==e||\"http://www.w3.org/1999/xhtml\"===e?de(n):\"http://www.w3.org/2000/svg\"===e&&\"foreignObject\"===n?\"http://www.w3.org/1999/xhtml\":e}var he,Ae,be=(Ae=function(e,n){if(e.namespaceURI!==fe||\"innerHTML\"in e)e.innerHTML=n;else{for((he=he||document.createElement(\"div\")).innerHTML=\"<svg>\"+n.valueOf().toString()+\"</svg>\",n=he.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;n.firstChild;)e.appendChild(n.firstChild)}},\"undefined\"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,n,t,r){MSApp.execUnsafeLocalFunction((function(){return Ae(e,n)}))}:Ae);function ve(e,n){if(n){var t=e.firstChild;if(t&&t===e.lastChild&&3===t.nodeType)return void(t.nodeValue=n)}e.textContent=n}var me={animationIterationCount:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},ye=[\"Webkit\",\"ms\",\"Moz\",\"O\"];function Ee(e,n,t){return null==n||\"boolean\"==typeof n||\"\"===n?\"\":t||\"number\"!=typeof n||0===n||me.hasOwnProperty(e)&&me[e]?(\"\"+n).trim():n+\"px\"}function Ce(e,n){for(var t in e=e.style,n)if(n.hasOwnProperty(t)){var r=0===t.indexOf(\"--\"),o=Ee(t,n[t],r);\"float\"===t&&(t=\"cssFloat\"),r?e.setProperty(t,o):e[t]=o}}Object.keys(me).forEach((function(e){ye.forEach((function(n){n=n+e.charAt(0).toUpperCase()+e.substring(1),me[n]=me[e]}))}));var we=o({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function xe(e,n){if(n){if(we[e]&&(null!=n.children||null!=n.dangerouslySetInnerHTML))throw Error(a(137,e));if(null!=n.dangerouslySetInnerHTML){if(null!=n.children)throw Error(a(60));if(\"object\"!=typeof n.dangerouslySetInnerHTML||!(\"__html\"in n.dangerouslySetInnerHTML))throw Error(a(61))}if(null!=n.style&&\"object\"!=typeof n.style)throw Error(a(62))}}function Se(e,n){if(-1===e.indexOf(\"-\"))return\"string\"==typeof n.is;switch(e){case\"annotation-xml\":case\"color-profile\":case\"font-face\":case\"font-face-src\":case\"font-face-uri\":case\"font-face-format\":case\"font-face-name\":case\"missing-glyph\":return!1;default:return!0}}function _e(e){return(e=e.target||e.srcElement||window).correspondingUseElement&&(e=e.correspondingUseElement),3===e.nodeType?e.parentNode:e}var ke=null,Oe=null,Be=null;function Pe(e){if(e=ro(e)){if(\"function\"!=typeof ke)throw Error(a(280));var n=e.stateNode;n&&(n=io(n),ke(e.stateNode,e.type,n))}}function Te(e){Oe?Be?Be.push(e):Be=[e]:Oe=e}function Ie(){if(Oe){var e=Oe,n=Be;if(Be=Oe=null,Pe(e),n)for(e=0;e<n.length;e++)Pe(n[e])}}function je(e,n){return e(n)}function ze(e,n,t,r,o){return e(n,t,r,o)}function De(){}var Re=je,Me=!1,Ne=!1;function Fe(){null===Oe&&null===Be||(De(),Ie())}function Le(e,n){var t=e.stateNode;if(null===t)return null;var r=io(t);if(null===r)return null;t=r[n];e:switch(n){case\"onClick\":case\"onClickCapture\":case\"onDoubleClick\":case\"onDoubleClickCapture\":case\"onMouseDown\":case\"onMouseDownCapture\":case\"onMouseMove\":case\"onMouseMoveCapture\":case\"onMouseUp\":case\"onMouseUpCapture\":case\"onMouseEnter\":(r=!r.disabled)||(r=!(\"button\"===(e=e.type)||\"input\"===e||\"select\"===e||\"textarea\"===e)),e=!r;break e;default:e=!1}if(e)return null;if(t&&\"function\"!=typeof t)throw Error(a(231,n,typeof t));return t}var He=!1;if(p)try{var Ue={};Object.defineProperty(Ue,\"passive\",{get:function(){He=!0}}),window.addEventListener(\"test\",Ue,Ue),window.removeEventListener(\"test\",Ue,Ue)}catch(Ae){He=!1}function We(e,n,t,r,o,i,a,l,c){var s=Array.prototype.slice.call(arguments,3);try{n.apply(t,s)}catch(e){this.onError(e)}}var Ge=!1,Ye=null,qe=!1,Ve=null,$e={onError:function(e){Ge=!0,Ye=e}};function Ke(e,n,t,r,o,i,a,l,c){Ge=!1,Ye=null,We.apply($e,arguments)}function Qe(e){var n=e,t=e;if(e.alternate)for(;n.return;)n=n.return;else{e=n;do{!!(1026&(n=e).flags)&&(t=n.return),e=n.return}while(e)}return 3===n.tag?t:null}function Xe(e){if(13===e.tag){var n=e.memoizedState;if(null===n&&(null!==(e=e.alternate)&&(n=e.memoizedState)),null!==n)return n.dehydrated}return null}function Ze(e){if(Qe(e)!==e)throw Error(a(188))}function Je(e){if(e=function(e){var n=e.alternate;if(!n){if(null===(n=Qe(e)))throw Error(a(188));return n!==e?null:e}for(var t=e,r=n;;){var o=t.return;if(null===o)break;var i=o.alternate;if(null===i){if(null!==(r=o.return)){t=r;continue}break}if(o.child===i.child){for(i=o.child;i;){if(i===t)return Ze(o),e;if(i===r)return Ze(o),n;i=i.sibling}throw Error(a(188))}if(t.return!==r.return)t=o,r=i;else{for(var l=!1,c=o.child;c;){if(c===t){l=!0,t=o,r=i;break}if(c===r){l=!0,r=o,t=i;break}c=c.sibling}if(!l){for(c=i.child;c;){if(c===t){l=!0,t=i,r=o;break}if(c===r){l=!0,r=i,t=o;break}c=c.sibling}if(!l)throw Error(a(189))}}if(t.alternate!==r)throw Error(a(190))}if(3!==t.tag)throw Error(a(188));return t.stateNode.current===t?e:n}(e),!e)return null;for(var n=e;;){if(5===n.tag||6===n.tag)return n;if(n.child)n.child.return=n,n=n.child;else{if(n===e)break;for(;!n.sibling;){if(!n.return||n.return===e)return null;n=n.return}n.sibling.return=n.return,n=n.sibling}}return null}function en(e,n){for(var t=e.alternate;null!==n;){if(n===e||n===t)return!0;n=n.return}return!1}var nn,tn,rn,on,an=!1,ln=[],cn=null,sn=null,un=null,pn=new Map,fn=new Map,dn=[],gn=\"mousedown mouseup touchcancel touchend touchstart auxclick dblclick pointercancel pointerdown pointerup dragend dragstart drop compositionend compositionstart keydown keypress keyup input textInput copy cut paste click change contextmenu reset submit\".split(\" \");function hn(e,n,t,r,o){return{blockedOn:e,domEventName:n,eventSystemFlags:16|t,nativeEvent:o,targetContainers:[r]}}function An(e,n){switch(e){case\"focusin\":case\"focusout\":cn=null;break;case\"dragenter\":case\"dragleave\":sn=null;break;case\"mouseover\":case\"mouseout\":un=null;break;case\"pointerover\":case\"pointerout\":pn.delete(n.pointerId);break;case\"gotpointercapture\":case\"lostpointercapture\":fn.delete(n.pointerId)}}function bn(e,n,t,r,o,i){return null===e||e.nativeEvent!==i?(e=hn(n,t,r,o,i),null!==n&&(null!==(n=ro(n))&&tn(n)),e):(e.eventSystemFlags|=r,n=e.targetContainers,null!==o&&-1===n.indexOf(o)&&n.push(o),e)}function vn(e){var n=to(e.target);if(null!==n){var t=Qe(n);if(null!==t)if(13===(n=t.tag)){if(null!==(n=Xe(t)))return e.blockedOn=n,void on(e.lanePriority,(function(){i.unstable_runWithPriority(e.priority,(function(){rn(t)}))}))}else if(3===n&&t.stateNode.hydrate)return void(e.blockedOn=3===t.tag?t.stateNode.containerInfo:null)}e.blockedOn=null}function mn(e){if(null!==e.blockedOn)return!1;for(var n=e.targetContainers;0<n.length;){var t=et(e.domEventName,e.eventSystemFlags,n[0],e.nativeEvent);if(null!==t)return null!==(n=ro(t))&&tn(n),e.blockedOn=t,!1;n.shift()}return!0}function yn(e,n,t){mn(e)&&t.delete(n)}function En(){for(an=!1;0<ln.length;){var e=ln[0];if(null!==e.blockedOn){null!==(e=ro(e.blockedOn))&&nn(e);break}for(var n=e.targetContainers;0<n.length;){var t=et(e.domEventName,e.eventSystemFlags,n[0],e.nativeEvent);if(null!==t){e.blockedOn=t;break}n.shift()}null===e.blockedOn&&ln.shift()}null!==cn&&mn(cn)&&(cn=null),null!==sn&&mn(sn)&&(sn=null),null!==un&&mn(un)&&(un=null),pn.forEach(yn),fn.forEach(yn)}function Cn(e,n){e.blockedOn===n&&(e.blockedOn=null,an||(an=!0,i.unstable_scheduleCallback(i.unstable_NormalPriority,En)))}function wn(e){function n(n){return Cn(n,e)}if(0<ln.length){Cn(ln[0],e);for(var t=1;t<ln.length;t++){var r=ln[t];r.blockedOn===e&&(r.blockedOn=null)}}for(null!==cn&&Cn(cn,e),null!==sn&&Cn(sn,e),null!==un&&Cn(un,e),pn.forEach(n),fn.forEach(n),t=0;t<dn.length;t++)(r=dn[t]).blockedOn===e&&(r.blockedOn=null);for(;0<dn.length&&null===(t=dn[0]).blockedOn;)vn(t),null===t.blockedOn&&dn.shift()}function xn(e,n){var t={};return t[e.toLowerCase()]=n.toLowerCase(),t[\"Webkit\"+e]=\"webkit\"+n,t[\"Moz\"+e]=\"moz\"+n,t}var Sn={animationend:xn(\"Animation\",\"AnimationEnd\"),animationiteration:xn(\"Animation\",\"AnimationIteration\"),animationstart:xn(\"Animation\",\"AnimationStart\"),transitionend:xn(\"Transition\",\"TransitionEnd\")},_n={},kn={};function On(e){if(_n[e])return _n[e];if(!Sn[e])return e;var n,t=Sn[e];for(n in t)if(t.hasOwnProperty(n)&&n in kn)return _n[e]=t[n];return e}p&&(kn=document.createElement(\"div\").style,\"AnimationEvent\"in window||(delete Sn.animationend.animation,delete Sn.animationiteration.animation,delete Sn.animationstart.animation),\"TransitionEvent\"in window||delete Sn.transitionend.transition);var Bn=On(\"animationend\"),Pn=On(\"animationiteration\"),Tn=On(\"animationstart\"),In=On(\"transitionend\"),jn=new Map,zn=new Map,Dn=[\"abort\",\"abort\",Bn,\"animationEnd\",Pn,\"animationIteration\",Tn,\"animationStart\",\"canplay\",\"canPlay\",\"canplaythrough\",\"canPlayThrough\",\"durationchange\",\"durationChange\",\"emptied\",\"emptied\",\"encrypted\",\"encrypted\",\"ended\",\"ended\",\"error\",\"error\",\"gotpointercapture\",\"gotPointerCapture\",\"load\",\"load\",\"loadeddata\",\"loadedData\",\"loadedmetadata\",\"loadedMetadata\",\"loadstart\",\"loadStart\",\"lostpointercapture\",\"lostPointerCapture\",\"playing\",\"playing\",\"progress\",\"progress\",\"seeking\",\"seeking\",\"stalled\",\"stalled\",\"suspend\",\"suspend\",\"timeupdate\",\"timeUpdate\",In,\"transitionEnd\",\"waiting\",\"waiting\"];function Rn(e,n){for(var t=0;t<e.length;t+=2){var r=e[t],o=e[t+1];o=\"on\"+(o[0].toUpperCase()+o.slice(1)),zn.set(r,n),jn.set(r,o),s(o,[r])}}(0,i.unstable_now)();var Mn=8;function Nn(e){if(1&e)return Mn=15,1;if(2&e)return Mn=14,2;if(4&e)return Mn=13,4;var n=24&e;return 0!==n?(Mn=12,n):32&e?(Mn=11,32):0!==(n=192&e)?(Mn=10,n):256&e?(Mn=9,256):0!==(n=3584&e)?(Mn=8,n):4096&e?(Mn=7,4096):0!==(n=4186112&e)?(Mn=6,n):0!==(n=62914560&e)?(Mn=5,n):67108864&e?(Mn=4,67108864):134217728&e?(Mn=3,134217728):0!==(n=805306368&e)?(Mn=2,n):1073741824&e?(Mn=1,1073741824):(Mn=8,e)}function Fn(e,n){var t=e.pendingLanes;if(0===t)return Mn=0;var r=0,o=0,i=e.expiredLanes,a=e.suspendedLanes,l=e.pingedLanes;if(0!==i)r=i,o=Mn=15;else if(0!==(i=134217727&t)){var c=i&~a;0!==c?(r=Nn(c),o=Mn):0!==(l&=i)&&(r=Nn(l),o=Mn)}else 0!==(i=t&~a)?(r=Nn(i),o=Mn):0!==l&&(r=Nn(l),o=Mn);if(0===r)return 0;if(r=t&((0>(r=31-Yn(r))?0:1<<r)<<1)-1,0!==n&&n!==r&&0===(n&a)){if(Nn(n),o<=Mn)return n;Mn=o}if(0!==(n=e.entangledLanes))for(e=e.entanglements,n&=r;0<n;)o=1<<(t=31-Yn(n)),r|=e[t],n&=~o;return r}function Ln(e){return 0!==(e=-1073741825&e.pendingLanes)?e:1073741824&e?1073741824:0}function Hn(e,n){switch(e){case 15:return 1;case 14:return 2;case 12:return 0===(e=Un(24&~n))?Hn(10,n):e;case 10:return 0===(e=Un(192&~n))?Hn(8,n):e;case 8:return 0===(e=Un(3584&~n))&&(0===(e=Un(4186112&~n))&&(e=512)),e;case 2:return 0===(n=Un(805306368&~n))&&(n=268435456),n}throw Error(a(358,e))}function Un(e){return e&-e}function Wn(e){for(var n=[],t=0;31>t;t++)n.push(e);return n}function Gn(e,n,t){e.pendingLanes|=n;var r=n-1;e.suspendedLanes&=r,e.pingedLanes&=r,(e=e.eventTimes)[n=31-Yn(n)]=t}var Yn=Math.clz32?Math.clz32:function(e){return 0===e?32:31-(qn(e)/Vn|0)|0},qn=Math.log,Vn=Math.LN2;var $n=i.unstable_UserBlockingPriority,Kn=i.unstable_runWithPriority,Qn=!0;function Xn(e,n,t,r){Me||De();var o=Jn,i=Me;Me=!0;try{ze(o,e,n,t,r)}finally{(Me=i)||Fe()}}function Zn(e,n,t,r){Kn($n,Jn.bind(null,e,n,t,r))}function Jn(e,n,t,r){var o;if(Qn)if((o=!(4&n))&&0<ln.length&&-1<gn.indexOf(e))e=hn(null,e,n,t,r),ln.push(e);else{var i=et(e,n,t,r);if(null===i)o&&An(e,r);else{if(o){if(-1<gn.indexOf(e))return e=hn(i,e,n,t,r),void ln.push(e);if(function(e,n,t,r,o){switch(n){case\"focusin\":return cn=bn(cn,e,n,t,r,o),!0;case\"dragenter\":return sn=bn(sn,e,n,t,r,o),!0;case\"mouseover\":return un=bn(un,e,n,t,r,o),!0;case\"pointerover\":var i=o.pointerId;return pn.set(i,bn(pn.get(i)||null,e,n,t,r,o)),!0;case\"gotpointercapture\":return i=o.pointerId,fn.set(i,bn(fn.get(i)||null,e,n,t,r,o)),!0}return!1}(i,e,n,t,r))return;An(e,r)}Dr(e,n,r,null,t)}}}function et(e,n,t,r){var o=_e(r);if(null!==(o=to(o))){var i=Qe(o);if(null===i)o=null;else{var a=i.tag;if(13===a){if(null!==(o=Xe(i)))return o;o=null}else if(3===a){if(i.stateNode.hydrate)return 3===i.tag?i.stateNode.containerInfo:null;o=null}else i!==o&&(o=null)}}return Dr(e,n,r,o,t),null}var nt=null,tt=null,rt=null;function ot(){if(rt)return rt;var e,n,t=tt,r=t.length,o=\"value\"in nt?nt.value:nt.textContent,i=o.length;for(e=0;e<r&&t[e]===o[e];e++);var a=r-e;for(n=1;n<=a&&t[r-n]===o[i-n];n++);return rt=o.slice(e,1<n?1-n:void 0)}function it(e){var n=e.keyCode;return\"charCode\"in e?0===(e=e.charCode)&&13===n&&(e=13):e=n,10===e&&(e=13),32<=e||13===e?e:0}function at(){return!0}function lt(){return!1}function ct(e){function n(n,t,r,o,i){for(var a in this._reactName=n,this._targetInst=r,this.type=t,this.nativeEvent=o,this.target=i,this.currentTarget=null,e)e.hasOwnProperty(a)&&(n=e[a],this[a]=n?n(o):o[a]);return this.isDefaultPrevented=(null!=o.defaultPrevented?o.defaultPrevented:!1===o.returnValue)?at:lt,this.isPropagationStopped=lt,this}return o(n.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():\"unknown\"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=at)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():\"unknown\"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=at)},persist:function(){},isPersistent:at}),n}var st,ut,pt,ft={eventPhase:0,bubbles:0,cancelable:0,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:0,isTrusted:0},dt=ct(ft),gt=o({},ft,{view:0,detail:0}),ht=ct(gt),At=o({},gt,{screenX:0,screenY:0,clientX:0,clientY:0,pageX:0,pageY:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,getModifierState:Ot,button:0,buttons:0,relatedTarget:function(e){return void 0===e.relatedTarget?e.fromElement===e.srcElement?e.toElement:e.fromElement:e.relatedTarget},movementX:function(e){return\"movementX\"in e?e.movementX:(e!==pt&&(pt&&\"mousemove\"===e.type?(st=e.screenX-pt.screenX,ut=e.screenY-pt.screenY):ut=st=0,pt=e),st)},movementY:function(e){return\"movementY\"in e?e.movementY:ut}}),bt=ct(At),vt=ct(o({},At,{dataTransfer:0})),mt=ct(o({},gt,{relatedTarget:0})),yt=ct(o({},ft,{animationName:0,elapsedTime:0,pseudoElement:0})),Et=o({},ft,{clipboardData:function(e){return\"clipboardData\"in e?e.clipboardData:window.clipboardData}}),Ct=ct(Et),wt=ct(o({},ft,{data:0})),xt={Esc:\"Escape\",Spacebar:\" \",Left:\"ArrowLeft\",Up:\"ArrowUp\",Right:\"ArrowRight\",Down:\"ArrowDown\",Del:\"Delete\",Win:\"OS\",Menu:\"ContextMenu\",Apps:\"ContextMenu\",Scroll:\"ScrollLock\",MozPrintableKey:\"Unidentified\"},St={8:\"Backspace\",9:\"Tab\",12:\"Clear\",13:\"Enter\",16:\"Shift\",17:\"Control\",18:\"Alt\",19:\"Pause\",20:\"CapsLock\",27:\"Escape\",32:\" \",33:\"PageUp\",34:\"PageDown\",35:\"End\",36:\"Home\",37:\"ArrowLeft\",38:\"ArrowUp\",39:\"ArrowRight\",40:\"ArrowDown\",45:\"Insert\",46:\"Delete\",112:\"F1\",113:\"F2\",114:\"F3\",115:\"F4\",116:\"F5\",117:\"F6\",118:\"F7\",119:\"F8\",120:\"F9\",121:\"F10\",122:\"F11\",123:\"F12\",144:\"NumLock\",145:\"ScrollLock\",224:\"Meta\"},_t={Alt:\"altKey\",Control:\"ctrlKey\",Meta:\"metaKey\",Shift:\"shiftKey\"};function kt(e){var n=this.nativeEvent;return n.getModifierState?n.getModifierState(e):!!(e=_t[e])&&!!n[e]}function Ot(){return kt}var Bt=o({},gt,{key:function(e){if(e.key){var n=xt[e.key]||e.key;if(\"Unidentified\"!==n)return n}return\"keypress\"===e.type?13===(e=it(e))?\"Enter\":String.fromCharCode(e):\"keydown\"===e.type||\"keyup\"===e.type?St[e.keyCode]||\"Unidentified\":\"\"},code:0,location:0,ctrlKey:0,shiftKey:0,altKey:0,metaKey:0,repeat:0,locale:0,getModifierState:Ot,charCode:function(e){return\"keypress\"===e.type?it(e):0},keyCode:function(e){return\"keydown\"===e.type||\"keyup\"===e.type?e.keyCode:0},which:function(e){return\"keypress\"===e.type?it(e):\"keydown\"===e.type||\"keyup\"===e.type?e.keyCode:0}}),Pt=ct(Bt),Tt=ct(o({},At,{pointerId:0,width:0,height:0,pressure:0,tangentialPressure:0,tiltX:0,tiltY:0,twist:0,pointerType:0,isPrimary:0})),It=ct(o({},gt,{touches:0,targetTouches:0,changedTouches:0,altKey:0,metaKey:0,ctrlKey:0,shiftKey:0,getModifierState:Ot})),jt=ct(o({},ft,{propertyName:0,elapsedTime:0,pseudoElement:0})),zt=o({},At,{deltaX:function(e){return\"deltaX\"in e?e.deltaX:\"wheelDeltaX\"in e?-e.wheelDeltaX:0},deltaY:function(e){return\"deltaY\"in e?e.deltaY:\"wheelDeltaY\"in e?-e.wheelDeltaY:\"wheelDelta\"in e?-e.wheelDelta:0},deltaZ:0,deltaMode:0}),Dt=ct(zt),Rt=[9,13,27,32],Mt=p&&\"CompositionEvent\"in window,Nt=null;p&&\"documentMode\"in document&&(Nt=document.documentMode);var Ft=p&&\"TextEvent\"in window&&!Nt,Lt=p&&(!Mt||Nt&&8<Nt&&11>=Nt),Ht=String.fromCharCode(32),Ut=!1;function Wt(e,n){switch(e){case\"keyup\":return-1!==Rt.indexOf(n.keyCode);case\"keydown\":return 229!==n.keyCode;case\"keypress\":case\"mousedown\":case\"focusout\":return!0;default:return!1}}function Gt(e){return\"object\"==typeof(e=e.detail)&&\"data\"in e?e.data:null}var Yt=!1;var qt={color:!0,date:!0,datetime:!0,\"datetime-local\":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};function Vt(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return\"input\"===n?!!qt[e.type]:\"textarea\"===n}function $t(e,n,t,r){Te(r),0<(n=Mr(n,\"onChange\")).length&&(t=new dt(\"onChange\",\"change\",null,t,r),e.push({event:t,listeners:n}))}var Kt=null,Qt=null;function Xt(e){Br(e,0)}function Zt(e){if(X(oo(e)))return e}function Jt(e,n){if(\"change\"===e)return n}var er=!1;if(p){var nr;if(p){var tr=\"oninput\"in document;if(!tr){var rr=document.createElement(\"div\");rr.setAttribute(\"oninput\",\"return;\"),tr=\"function\"==typeof rr.oninput}nr=tr}else nr=!1;er=nr&&(!document.documentMode||9<document.documentMode)}function or(){Kt&&(Kt.detachEvent(\"onpropertychange\",ir),Qt=Kt=null)}function ir(e){if(\"value\"===e.propertyName&&Zt(Qt)){var n=[];if($t(n,Qt,e,_e(e)),e=Xt,Me)e(n);else{Me=!0;try{je(e,n)}finally{Me=!1,Fe()}}}}function ar(e,n,t){\"focusin\"===e?(or(),Qt=t,(Kt=n).attachEvent(\"onpropertychange\",ir)):\"focusout\"===e&&or()}function lr(e){if(\"selectionchange\"===e||\"keyup\"===e||\"keydown\"===e)return Zt(Qt)}function cr(e,n){if(\"click\"===e)return Zt(n)}function sr(e,n){if(\"input\"===e||\"change\"===e)return Zt(n)}var ur=\"function\"==typeof Object.is?Object.is:function(e,n){return e===n&&(0!==e||1/e==1/n)||e!=e&&n!=n},pr=Object.prototype.hasOwnProperty;function fr(e,n){if(ur(e,n))return!0;if(\"object\"!=typeof e||null===e||\"object\"!=typeof n||null===n)return!1;var t=Object.keys(e),r=Object.keys(n);if(t.length!==r.length)return!1;for(r=0;r<t.length;r++)if(!pr.call(n,t[r])||!ur(e[t[r]],n[t[r]]))return!1;return!0}function dr(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function gr(e,n){var t,r=dr(e);for(e=0;r;){if(3===r.nodeType){if(t=e+r.textContent.length,e<=n&&t>=n)return{node:r,offset:n-e};e=t}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=dr(r)}}function hr(e,n){return!(!e||!n)&&(e===n||(!e||3!==e.nodeType)&&(n&&3===n.nodeType?hr(e,n.parentNode):\"contains\"in e?e.contains(n):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(n))))}function Ar(){for(var e=window,n=Z();n instanceof e.HTMLIFrameElement;){try{var t=\"string\"==typeof n.contentWindow.location.href}catch(e){t=!1}if(!t)break;n=Z((e=n.contentWindow).document)}return n}function br(e){var n=e&&e.nodeName&&e.nodeName.toLowerCase();return n&&(\"input\"===n&&(\"text\"===e.type||\"search\"===e.type||\"tel\"===e.type||\"url\"===e.type||\"password\"===e.type)||\"textarea\"===n||\"true\"===e.contentEditable)}var vr=p&&\"documentMode\"in document&&11>=document.documentMode,mr=null,yr=null,Er=null,Cr=!1;function wr(e,n,t){var r=t.window===t?t.document:9===t.nodeType?t:t.ownerDocument;Cr||null==mr||mr!==Z(r)||(\"selectionStart\"in(r=mr)&&br(r)?r={start:r.selectionStart,end:r.selectionEnd}:r={anchorNode:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset},Er&&fr(Er,r)||(Er=r,0<(r=Mr(yr,\"onSelect\")).length&&(n=new dt(\"onSelect\",\"select\",null,n,t),e.push({event:n,listeners:r}),n.target=mr)))}Rn(\"cancel cancel click click close close contextmenu contextMenu copy copy cut cut auxclick auxClick dblclick doubleClick dragend dragEnd dragstart dragStart drop drop focusin focus focusout blur input input invalid invalid keydown keyDown keypress keyPress keyup keyUp mousedown mouseDown mouseup mouseUp paste paste pause pause play play pointercancel pointerCancel pointerdown pointerDown pointerup pointerUp ratechange rateChange reset reset seeked seeked submit submit touchcancel touchCancel touchend touchEnd touchstart touchStart volumechange volumeChange\".split(\" \"),0),Rn(\"drag drag dragenter dragEnter dragexit dragExit dragleave dragLeave dragover dragOver mousemove mouseMove mouseout mouseOut mouseover mouseOver pointermove pointerMove pointerout pointerOut pointerover pointerOver scroll scroll toggle toggle touchmove touchMove wheel wheel\".split(\" \"),1),Rn(Dn,2);for(var xr=\"change selectionchange textInput compositionstart compositionend compositionupdate\".split(\" \"),Sr=0;Sr<xr.length;Sr++)zn.set(xr[Sr],0);u(\"onMouseEnter\",[\"mouseout\",\"mouseover\"]),u(\"onMouseLeave\",[\"mouseout\",\"mouseover\"]),u(\"onPointerEnter\",[\"pointerout\",\"pointerover\"]),u(\"onPointerLeave\",[\"pointerout\",\"pointerover\"]),s(\"onChange\",\"change click focusin focusout input keydown keyup selectionchange\".split(\" \")),s(\"onSelect\",\"focusout contextmenu dragend focusin keydown keyup mousedown mouseup selectionchange\".split(\" \")),s(\"onBeforeInput\",[\"compositionend\",\"keypress\",\"textInput\",\"paste\"]),s(\"onCompositionEnd\",\"compositionend focusout keydown keypress keyup mousedown\".split(\" \")),s(\"onCompositionStart\",\"compositionstart focusout keydown keypress keyup mousedown\".split(\" \")),s(\"onCompositionUpdate\",\"compositionupdate focusout keydown keypress keyup mousedown\".split(\" \"));var _r=\"abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting\".split(\" \"),kr=new Set(\"cancel close invalid load scroll toggle\".split(\" \").concat(_r));function Or(e,n,t){var r=e.type||\"unknown-event\";e.currentTarget=t,function(e,n,t,r,o,i,l,c,s){if(Ke.apply(this,arguments),Ge){if(!Ge)throw Error(a(198));var u=Ye;Ge=!1,Ye=null,qe||(qe=!0,Ve=u)}}(r,n,void 0,e),e.currentTarget=null}function Br(e,n){n=!!(4&n);for(var t=0;t<e.length;t++){var r=e[t],o=r.event;r=r.listeners;e:{var i=void 0;if(n)for(var a=r.length-1;0<=a;a--){var l=r[a],c=l.instance,s=l.currentTarget;if(l=l.listener,c!==i&&o.isPropagationStopped())break e;Or(o,l,s),i=c}else for(a=0;a<r.length;a++){if(c=(l=r[a]).instance,s=l.currentTarget,l=l.listener,c!==i&&o.isPropagationStopped())break e;Or(o,l,s),i=c}}}if(qe)throw e=Ve,qe=!1,Ve=null,e}function Pr(e,n){var t=ao(n),r=e+\"__bubble\";t.has(r)||(zr(n,e,2,!1),t.add(r))}var Tr=\"_reactListening\"+Math.random().toString(36).slice(2);function Ir(e){e[Tr]||(e[Tr]=!0,l.forEach((function(n){kr.has(n)||jr(n,!1,e,null),jr(n,!0,e,null)})))}function jr(e,n,t,r){var o=4<arguments.length&&void 0!==arguments[4]?arguments[4]:0,i=t;if(\"selectionchange\"===e&&9!==t.nodeType&&(i=t.ownerDocument),null!==r&&!n&&kr.has(e)){if(\"scroll\"!==e)return;o|=2,i=r}var a=ao(i),l=e+\"__\"+(n?\"capture\":\"bubble\");a.has(l)||(n&&(o|=4),zr(i,e,o,n),a.add(l))}function zr(e,n,t,r){var o=zn.get(n);switch(void 0===o?2:o){case 0:o=Xn;break;case 1:o=Zn;break;default:o=Jn}t=o.bind(null,n,t,e),o=void 0,!He||\"touchstart\"!==n&&\"touchmove\"!==n&&\"wheel\"!==n||(o=!0),r?void 0!==o?e.addEventListener(n,t,{capture:!0,passive:o}):e.addEventListener(n,t,!0):void 0!==o?e.addEventListener(n,t,{passive:o}):e.addEventListener(n,t,!1)}function Dr(e,n,t,r,o){var i=r;if(!(1&n||2&n||null===r))e:for(;;){if(null===r)return;var a=r.tag;if(3===a||4===a){var l=r.stateNode.containerInfo;if(l===o||8===l.nodeType&&l.parentNode===o)break;if(4===a)for(a=r.return;null!==a;){var c=a.tag;if((3===c||4===c)&&((c=a.stateNode.containerInfo)===o||8===c.nodeType&&c.parentNode===o))return;a=a.return}for(;null!==l;){if(null===(a=to(l)))return;if(5===(c=a.tag)||6===c){r=i=a;continue e}l=l.parentNode}}r=r.return}!function(e,n,t){if(Ne)return e(n,t);Ne=!0;try{return Re(e,n,t)}finally{Ne=!1,Fe()}}((function(){var r=i,o=_e(t),a=[];e:{var l=jn.get(e);if(void 0!==l){var c=dt,s=e;switch(e){case\"keypress\":if(0===it(t))break e;case\"keydown\":case\"keyup\":c=Pt;break;case\"focusin\":s=\"focus\",c=mt;break;case\"focusout\":s=\"blur\",c=mt;break;case\"beforeblur\":case\"afterblur\":c=mt;break;case\"click\":if(2===t.button)break e;case\"auxclick\":case\"dblclick\":case\"mousedown\":case\"mousemove\":case\"mouseup\":case\"mouseout\":case\"mouseover\":case\"contextmenu\":c=bt;break;case\"drag\":case\"dragend\":case\"dragenter\":case\"dragexit\":case\"dragleave\":case\"dragover\":case\"dragstart\":case\"drop\":c=vt;break;case\"touchcancel\":case\"touchend\":case\"touchmove\":case\"touchstart\":c=It;break;case Bn:case Pn:case Tn:c=yt;break;case In:c=jt;break;case\"scroll\":c=ht;break;case\"wheel\":c=Dt;break;case\"copy\":case\"cut\":case\"paste\":c=Ct;break;case\"gotpointercapture\":case\"lostpointercapture\":case\"pointercancel\":case\"pointerdown\":case\"pointermove\":case\"pointerout\":case\"pointerover\":case\"pointerup\":c=Tt}var u=!!(4&n),p=!u&&\"scroll\"===e,f=u?null!==l?l+\"Capture\":null:l;u=[];for(var d,g=r;null!==g;){var h=(d=g).stateNode;if(5===d.tag&&null!==h&&(d=h,null!==f&&(null!=(h=Le(g,f))&&u.push(Rr(g,h,d)))),p)break;g=g.return}0<u.length&&(l=new c(l,s,null,t,o),a.push({event:l,listeners:u}))}}if(!(7&n)){if(c=\"mouseout\"===e||\"pointerout\"===e,(!(l=\"mouseover\"===e||\"pointerover\"===e)||16&n||!(s=t.relatedTarget||t.fromElement)||!to(s)&&!s[eo])&&(c||l)&&(l=o.window===o?o:(l=o.ownerDocument)?l.defaultView||l.parentWindow:window,c?(c=r,null!==(s=(s=t.relatedTarget||t.toElement)?to(s):null)&&(s!==(p=Qe(s))||5!==s.tag&&6!==s.tag)&&(s=null)):(c=null,s=r),c!==s)){if(u=bt,h=\"onMouseLeave\",f=\"onMouseEnter\",g=\"mouse\",\"pointerout\"!==e&&\"pointerover\"!==e||(u=Tt,h=\"onPointerLeave\",f=\"onPointerEnter\",g=\"pointer\"),p=null==c?l:oo(c),d=null==s?l:oo(s),(l=new u(h,g+\"leave\",c,t,o)).target=p,l.relatedTarget=d,h=null,to(o)===r&&((u=new u(f,g+\"enter\",s,t,o)).target=d,u.relatedTarget=p,h=u),p=h,c&&s)e:{for(f=s,g=0,d=u=c;d;d=Nr(d))g++;for(d=0,h=f;h;h=Nr(h))d++;for(;0<g-d;)u=Nr(u),g--;for(;0<d-g;)f=Nr(f),d--;for(;g--;){if(u===f||null!==f&&u===f.alternate)break e;u=Nr(u),f=Nr(f)}u=null}else u=null;null!==c&&Fr(a,l,c,u,!1),null!==s&&null!==p&&Fr(a,p,s,u,!0)}if(\"select\"===(c=(l=r?oo(r):window).nodeName&&l.nodeName.toLowerCase())||\"input\"===c&&\"file\"===l.type)var A=Jt;else if(Vt(l))if(er)A=sr;else{A=lr;var b=ar}else(c=l.nodeName)&&\"input\"===c.toLowerCase()&&(\"checkbox\"===l.type||\"radio\"===l.type)&&(A=cr);switch(A&&(A=A(e,r))?$t(a,A,t,o):(b&&b(e,l,r),\"focusout\"===e&&(b=l._wrapperState)&&b.controlled&&\"number\"===l.type&&oe(l,\"number\",l.value)),b=r?oo(r):window,e){case\"focusin\":(Vt(b)||\"true\"===b.contentEditable)&&(mr=b,yr=r,Er=null);break;case\"focusout\":Er=yr=mr=null;break;case\"mousedown\":Cr=!0;break;case\"contextmenu\":case\"mouseup\":case\"dragend\":Cr=!1,wr(a,t,o);break;case\"selectionchange\":if(vr)break;case\"keydown\":case\"keyup\":wr(a,t,o)}var v;if(Mt)e:{switch(e){case\"compositionstart\":var m=\"onCompositionStart\";break e;case\"compositionend\":m=\"onCompositionEnd\";break e;case\"compositionupdate\":m=\"onCompositionUpdate\";break e}m=void 0}else Yt?Wt(e,t)&&(m=\"onCompositionEnd\"):\"keydown\"===e&&229===t.keyCode&&(m=\"onCompositionStart\");m&&(Lt&&\"ko\"!==t.locale&&(Yt||\"onCompositionStart\"!==m?\"onCompositionEnd\"===m&&Yt&&(v=ot()):(tt=\"value\"in(nt=o)?nt.value:nt.textContent,Yt=!0)),0<(b=Mr(r,m)).length&&(m=new wt(m,e,null,t,o),a.push({event:m,listeners:b}),v?m.data=v:null!==(v=Gt(t))&&(m.data=v))),(v=Ft?function(e,n){switch(e){case\"compositionend\":return Gt(n);case\"keypress\":return 32!==n.which?null:(Ut=!0,Ht);case\"textInput\":return(e=n.data)===Ht&&Ut?null:e;default:return null}}(e,t):function(e,n){if(Yt)return\"compositionend\"===e||!Mt&&Wt(e,n)?(e=ot(),rt=tt=nt=null,Yt=!1,e):null;switch(e){case\"paste\":default:return null;case\"keypress\":if(!(n.ctrlKey||n.altKey||n.metaKey)||n.ctrlKey&&n.altKey){if(n.char&&1<n.char.length)return n.char;if(n.which)return String.fromCharCode(n.which)}return null;case\"compositionend\":return Lt&&\"ko\"!==n.locale?null:n.data}}(e,t))&&(0<(r=Mr(r,\"onBeforeInput\")).length&&(o=new wt(\"onBeforeInput\",\"beforeinput\",null,t,o),a.push({event:o,listeners:r}),o.data=v))}Br(a,n)}))}function Rr(e,n,t){return{instance:e,listener:n,currentTarget:t}}function Mr(e,n){for(var t=n+\"Capture\",r=[];null!==e;){var o=e,i=o.stateNode;5===o.tag&&null!==i&&(o=i,null!=(i=Le(e,t))&&r.unshift(Rr(e,i,o)),null!=(i=Le(e,n))&&r.push(Rr(e,i,o))),e=e.return}return r}function Nr(e){if(null===e)return null;do{e=e.return}while(e&&5!==e.tag);return e||null}function Fr(e,n,t,r,o){for(var i=n._reactName,a=[];null!==t&&t!==r;){var l=t,c=l.alternate,s=l.stateNode;if(null!==c&&c===r)break;5===l.tag&&null!==s&&(l=s,o?null!=(c=Le(t,i))&&a.unshift(Rr(t,c,l)):o||null!=(c=Le(t,i))&&a.push(Rr(t,c,l))),t=t.return}0!==a.length&&e.push({event:n,listeners:a})}function Lr(){}var Hr=null,Ur=null;function Wr(e,n){switch(e){case\"button\":case\"input\":case\"select\":case\"textarea\":return!!n.autoFocus}return!1}function Gr(e,n){return\"textarea\"===e||\"option\"===e||\"noscript\"===e||\"string\"==typeof n.children||\"number\"==typeof n.children||\"object\"==typeof n.dangerouslySetInnerHTML&&null!==n.dangerouslySetInnerHTML&&null!=n.dangerouslySetInnerHTML.__html}var Yr=\"function\"==typeof setTimeout?setTimeout:void 0,qr=\"function\"==typeof clearTimeout?clearTimeout:void 0;function Vr(e){1===e.nodeType?e.textContent=\"\":9===e.nodeType&&(null!=(e=e.body)&&(e.textContent=\"\"))}function $r(e){for(;null!=e;e=e.nextSibling){var n=e.nodeType;if(1===n||3===n)break}return e}function Kr(e){e=e.previousSibling;for(var n=0;e;){if(8===e.nodeType){var t=e.data;if(\"$\"===t||\"$!\"===t||\"$?\"===t){if(0===n)return e;n--}else\"/$\"===t&&n++}e=e.previousSibling}return null}var Qr=0;var Xr=Math.random().toString(36).slice(2),Zr=\"__reactFiber$\"+Xr,Jr=\"__reactProps$\"+Xr,eo=\"__reactContainer$\"+Xr,no=\"__reactEvents$\"+Xr;function to(e){var n=e[Zr];if(n)return n;for(var t=e.parentNode;t;){if(n=t[eo]||t[Zr]){if(t=n.alternate,null!==n.child||null!==t&&null!==t.child)for(e=Kr(e);null!==e;){if(t=e[Zr])return t;e=Kr(e)}return n}t=(e=t).parentNode}return null}function ro(e){return!(e=e[Zr]||e[eo])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function oo(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(a(33))}function io(e){return e[Jr]||null}function ao(e){var n=e[no];return void 0===n&&(n=e[no]=new Set),n}var lo=[],co=-1;function so(e){return{current:e}}function uo(e){0>co||(e.current=lo[co],lo[co]=null,co--)}function po(e,n){co++,lo[co]=e.current,e.current=n}var fo={},go=so(fo),ho=so(!1),Ao=fo;function bo(e,n){var t=e.type.contextTypes;if(!t)return fo;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===n)return r.__reactInternalMemoizedMaskedChildContext;var o,i={};for(o in t)i[o]=n[o];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=n,e.__reactInternalMemoizedMaskedChildContext=i),i}function vo(e){return null!=(e=e.childContextTypes)}function mo(){uo(ho),uo(go)}function yo(e,n,t){if(go.current!==fo)throw Error(a(168));po(go,n),po(ho,t)}function Eo(e,n,t){var r=e.stateNode;if(e=n.childContextTypes,\"function\"!=typeof r.getChildContext)return t;for(var i in r=r.getChildContext())if(!(i in e))throw Error(a(108,V(n)||\"Unknown\",i));return o({},t,r)}function Co(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||fo,Ao=go.current,po(go,e),po(ho,ho.current),!0}function wo(e,n,t){var r=e.stateNode;if(!r)throw Error(a(169));t?(e=Eo(e,n,Ao),r.__reactInternalMemoizedMergedChildContext=e,uo(ho),uo(go),po(go,e)):uo(ho),po(ho,t)}var xo=null,So=null,_o=i.unstable_runWithPriority,ko=i.unstable_scheduleCallback,Oo=i.unstable_cancelCallback,Bo=i.unstable_shouldYield,Po=i.unstable_requestPaint,To=i.unstable_now,Io=i.unstable_getCurrentPriorityLevel,jo=i.unstable_ImmediatePriority,zo=i.unstable_UserBlockingPriority,Do=i.unstable_NormalPriority,Ro=i.unstable_LowPriority,Mo=i.unstable_IdlePriority,No={},Fo=void 0!==Po?Po:function(){},Lo=null,Ho=null,Uo=!1,Wo=To(),Go=1e4>Wo?To:function(){return To()-Wo};function Yo(){switch(Io()){case jo:return 99;case zo:return 98;case Do:return 97;case Ro:return 96;case Mo:return 95;default:throw Error(a(332))}}function qo(e){switch(e){case 99:return jo;case 98:return zo;case 97:return Do;case 96:return Ro;case 95:return Mo;default:throw Error(a(332))}}function Vo(e,n){return e=qo(e),_o(e,n)}function $o(e,n,t){return e=qo(e),ko(e,n,t)}function Ko(){if(null!==Ho){var e=Ho;Ho=null,Oo(e)}Qo()}function Qo(){if(!Uo&&null!==Lo){Uo=!0;var e=0;try{var n=Lo;Vo(99,(function(){for(;e<n.length;e++){var t=n[e];do{t=t(!0)}while(null!==t)}})),Lo=null}catch(n){throw null!==Lo&&(Lo=Lo.slice(e+1)),ko(jo,Ko),n}finally{Uo=!1}}}var Xo=E.ReactCurrentBatchConfig;function Zo(e,n){if(e&&e.defaultProps){for(var t in n=o({},n),e=e.defaultProps)void 0===n[t]&&(n[t]=e[t]);return n}return n}var Jo=so(null),ei=null,ni=null,ti=null;function ri(){ti=ni=ei=null}function oi(e){var n=Jo.current;uo(Jo),e.type._context._currentValue=n}function ii(e,n){for(;null!==e;){var t=e.alternate;if((e.childLanes&n)===n){if(null===t||(t.childLanes&n)===n)break;t.childLanes|=n}else e.childLanes|=n,null!==t&&(t.childLanes|=n);e=e.return}}function ai(e,n){ei=e,ti=ni=null,null!==(e=e.dependencies)&&null!==e.firstContext&&(0!==(e.lanes&n)&&(Ma=!0),e.firstContext=null)}function li(e,n){if(ti!==e&&!1!==n&&0!==n)if(\"number\"==typeof n&&1073741823!==n||(ti=e,n=1073741823),n={context:e,observedBits:n,next:null},null===ni){if(null===ei)throw Error(a(308));ni=n,ei.dependencies={lanes:0,firstContext:n,responders:null}}else ni=ni.next=n;return e._currentValue}var ci=!1;function si(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null},effects:null}}function ui(e,n){e=e.updateQueue,n.updateQueue===e&&(n.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,effects:e.effects})}function pi(e,n){return{eventTime:e,lane:n,tag:0,payload:null,callback:null,next:null}}function fi(e,n){if(null!==(e=e.updateQueue)){var t=(e=e.shared).pending;null===t?n.next=n:(n.next=t.next,t.next=n),e.pending=n}}function di(e,n){var t=e.updateQueue,r=e.alternate;if(null!==r&&t===(r=r.updateQueue)){var o=null,i=null;if(null!==(t=t.firstBaseUpdate)){do{var a={eventTime:t.eventTime,lane:t.lane,tag:t.tag,payload:t.payload,callback:t.callback,next:null};null===i?o=i=a:i=i.next=a,t=t.next}while(null!==t);null===i?o=i=n:i=i.next=n}else o=i=n;return t={baseState:r.baseState,firstBaseUpdate:o,lastBaseUpdate:i,shared:r.shared,effects:r.effects},void(e.updateQueue=t)}null===(e=t.lastBaseUpdate)?t.firstBaseUpdate=n:e.next=n,t.lastBaseUpdate=n}function gi(e,n,t,r){var i=e.updateQueue;ci=!1;var a=i.firstBaseUpdate,l=i.lastBaseUpdate,c=i.shared.pending;if(null!==c){i.shared.pending=null;var s=c,u=s.next;s.next=null,null===l?a=u:l.next=u,l=s;var p=e.alternate;if(null!==p){var f=(p=p.updateQueue).lastBaseUpdate;f!==l&&(null===f?p.firstBaseUpdate=u:f.next=u,p.lastBaseUpdate=s)}}if(null!==a){for(f=i.baseState,l=0,p=u=s=null;;){c=a.lane;var d=a.eventTime;if((r&c)===c){null!==p&&(p=p.next={eventTime:d,lane:0,tag:a.tag,payload:a.payload,callback:a.callback,next:null});e:{var g=e,h=a;switch(c=n,d=t,h.tag){case 1:if(\"function\"==typeof(g=h.payload)){f=g.call(d,f,c);break e}f=g;break e;case 3:g.flags=-4097&g.flags|64;case 0:if(null==(c=\"function\"==typeof(g=h.payload)?g.call(d,f,c):g))break e;f=o({},f,c);break e;case 2:ci=!0}}null!==a.callback&&(e.flags|=32,null===(c=i.effects)?i.effects=[a]:c.push(a))}else d={eventTime:d,lane:c,tag:a.tag,payload:a.payload,callback:a.callback,next:null},null===p?(u=p=d,s=f):p=p.next=d,l|=c;if(null===(a=a.next)){if(null===(c=i.shared.pending))break;a=c.next,c.next=null,i.lastBaseUpdate=c,i.shared.pending=null}}null===p&&(s=f),i.baseState=s,i.firstBaseUpdate=u,i.lastBaseUpdate=p,Ul|=l,e.lanes=l,e.memoizedState=f}}function hi(e,n,t){if(e=n.effects,n.effects=null,null!==e)for(n=0;n<e.length;n++){var r=e[n],o=r.callback;if(null!==o){if(r.callback=null,r=t,\"function\"!=typeof o)throw Error(a(191,o));o.call(r)}}}var Ai=(new r.Component).refs;function bi(e,n,t,r){t=null==(t=t(r,n=e.memoizedState))?n:o({},n,t),e.memoizedState=t,0===e.lanes&&(e.updateQueue.baseState=t)}var vi={isMounted:function(e){return!!(e=e._reactInternals)&&Qe(e)===e},enqueueSetState:function(e,n,t){e=e._reactInternals;var r=dc(),o=gc(e),i=pi(r,o);i.payload=n,null!=t&&(i.callback=t),fi(e,i),hc(e,o,r)},enqueueReplaceState:function(e,n,t){e=e._reactInternals;var r=dc(),o=gc(e),i=pi(r,o);i.tag=1,i.payload=n,null!=t&&(i.callback=t),fi(e,i),hc(e,o,r)},enqueueForceUpdate:function(e,n){e=e._reactInternals;var t=dc(),r=gc(e),o=pi(t,r);o.tag=2,null!=n&&(o.callback=n),fi(e,o),hc(e,r,t)}};function mi(e,n,t,r,o,i,a){return\"function\"==typeof(e=e.stateNode).shouldComponentUpdate?e.shouldComponentUpdate(r,i,a):!n.prototype||!n.prototype.isPureReactComponent||(!fr(t,r)||!fr(o,i))}function yi(e,n,t){var r=!1,o=fo,i=n.contextType;return\"object\"==typeof i&&null!==i?i=li(i):(o=vo(n)?Ao:go.current,i=(r=null!=(r=n.contextTypes))?bo(e,o):fo),n=new n(t,i),e.memoizedState=null!==n.state&&void 0!==n.state?n.state:null,n.updater=vi,e.stateNode=n,n._reactInternals=e,r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=o,e.__reactInternalMemoizedMaskedChildContext=i),n}function Ei(e,n,t,r){e=n.state,\"function\"==typeof n.componentWillReceiveProps&&n.componentWillReceiveProps(t,r),\"function\"==typeof n.UNSAFE_componentWillReceiveProps&&n.UNSAFE_componentWillReceiveProps(t,r),n.state!==e&&vi.enqueueReplaceState(n,n.state,null)}function Ci(e,n,t,r){var o=e.stateNode;o.props=t,o.state=e.memoizedState,o.refs=Ai,si(e);var i=n.contextType;\"object\"==typeof i&&null!==i?o.context=li(i):(i=vo(n)?Ao:go.current,o.context=bo(e,i)),gi(e,t,o,r),o.state=e.memoizedState,\"function\"==typeof(i=n.getDerivedStateFromProps)&&(bi(e,n,i,t),o.state=e.memoizedState),\"function\"==typeof n.getDerivedStateFromProps||\"function\"==typeof o.getSnapshotBeforeUpdate||\"function\"!=typeof o.UNSAFE_componentWillMount&&\"function\"!=typeof o.componentWillMount||(n=o.state,\"function\"==typeof o.componentWillMount&&o.componentWillMount(),\"function\"==typeof o.UNSAFE_componentWillMount&&o.UNSAFE_componentWillMount(),n!==o.state&&vi.enqueueReplaceState(o,o.state,null),gi(e,t,o,r),o.state=e.memoizedState),\"function\"==typeof o.componentDidMount&&(e.flags|=4)}var wi=Array.isArray;function xi(e,n,t){if(null!==(e=t.ref)&&\"function\"!=typeof e&&\"object\"!=typeof e){if(t._owner){if(t=t._owner){if(1!==t.tag)throw Error(a(309));var r=t.stateNode}if(!r)throw Error(a(147,e));var o=\"\"+e;return null!==n&&null!==n.ref&&\"function\"==typeof n.ref&&n.ref._stringRef===o?n.ref:(n=function(e){var n=r.refs;n===Ai&&(n=r.refs={}),null===e?delete n[o]:n[o]=e},n._stringRef=o,n)}if(\"string\"!=typeof e)throw Error(a(284));if(!t._owner)throw Error(a(290,e))}return e}function Si(e,n){if(\"textarea\"!==e.type)throw Error(a(31,\"[object Object]\"===Object.prototype.toString.call(n)?\"object with keys {\"+Object.keys(n).join(\", \")+\"}\":n))}function _i(e){function n(n,t){if(e){var r=n.lastEffect;null!==r?(r.nextEffect=t,n.lastEffect=t):n.firstEffect=n.lastEffect=t,t.nextEffect=null,t.flags=8}}function t(t,r){if(!e)return null;for(;null!==r;)n(t,r),r=r.sibling;return null}function r(e,n){for(e=new Map;null!==n;)null!==n.key?e.set(n.key,n):e.set(n.index,n),n=n.sibling;return e}function o(e,n){return(e=Vc(e,n)).index=0,e.sibling=null,e}function i(n,t,r){return n.index=r,e?null!==(r=n.alternate)?(r=r.index)<t?(n.flags=2,t):r:(n.flags=2,t):t}function l(n){return e&&null===n.alternate&&(n.flags=2),n}function c(e,n,t,r){return null===n||6!==n.tag?((n=Xc(t,e.mode,r)).return=e,n):((n=o(n,t)).return=e,n)}function s(e,n,t,r){return null!==n&&n.elementType===t.type?((r=o(n,t.props)).ref=xi(e,n,t),r.return=e,r):((r=$c(t.type,t.key,t.props,null,e.mode,r)).ref=xi(e,n,t),r.return=e,r)}function u(e,n,t,r){return null===n||4!==n.tag||n.stateNode.containerInfo!==t.containerInfo||n.stateNode.implementation!==t.implementation?((n=Zc(t,e.mode,r)).return=e,n):((n=o(n,t.children||[])).return=e,n)}function p(e,n,t,r,i){return null===n||7!==n.tag?((n=Kc(t,e.mode,r,i)).return=e,n):((n=o(n,t)).return=e,n)}function f(e,n,t){if(\"string\"==typeof n||\"number\"==typeof n)return(n=Xc(\"\"+n,e.mode,t)).return=e,n;if(\"object\"==typeof n&&null!==n){switch(n.$$typeof){case C:return(t=$c(n.type,n.key,n.props,null,e.mode,t)).ref=xi(e,null,n),t.return=e,t;case w:return(n=Zc(n,e.mode,t)).return=e,n}if(wi(n)||U(n))return(n=Kc(n,e.mode,t,null)).return=e,n;Si(e,n)}return null}function d(e,n,t,r){var o=null!==n?n.key:null;if(\"string\"==typeof t||\"number\"==typeof t)return null!==o?null:c(e,n,\"\"+t,r);if(\"object\"==typeof t&&null!==t){switch(t.$$typeof){case C:return t.key===o?t.type===x?p(e,n,t.props.children,r,o):s(e,n,t,r):null;case w:return t.key===o?u(e,n,t,r):null}if(wi(t)||U(t))return null!==o?null:p(e,n,t,r,null);Si(e,t)}return null}function g(e,n,t,r,o){if(\"string\"==typeof r||\"number\"==typeof r)return c(n,e=e.get(t)||null,\"\"+r,o);if(\"object\"==typeof r&&null!==r){switch(r.$$typeof){case C:return e=e.get(null===r.key?t:r.key)||null,r.type===x?p(n,e,r.props.children,o,r.key):s(n,e,r,o);case w:return u(n,e=e.get(null===r.key?t:r.key)||null,r,o)}if(wi(r)||U(r))return p(n,e=e.get(t)||null,r,o,null);Si(n,r)}return null}function h(o,a,l,c){for(var s=null,u=null,p=a,h=a=0,A=null;null!==p&&h<l.length;h++){p.index>h?(A=p,p=null):A=p.sibling;var b=d(o,p,l[h],c);if(null===b){null===p&&(p=A);break}e&&p&&null===b.alternate&&n(o,p),a=i(b,a,h),null===u?s=b:u.sibling=b,u=b,p=A}if(h===l.length)return t(o,p),s;if(null===p){for(;h<l.length;h++)null!==(p=f(o,l[h],c))&&(a=i(p,a,h),null===u?s=p:u.sibling=p,u=p);return s}for(p=r(o,p);h<l.length;h++)null!==(A=g(p,o,h,l[h],c))&&(e&&null!==A.alternate&&p.delete(null===A.key?h:A.key),a=i(A,a,h),null===u?s=A:u.sibling=A,u=A);return e&&p.forEach((function(e){return n(o,e)})),s}function A(o,l,c,s){var u=U(c);if(\"function\"!=typeof u)throw Error(a(150));if(null==(c=u.call(c)))throw Error(a(151));for(var p=u=null,h=l,A=l=0,b=null,v=c.next();null!==h&&!v.done;A++,v=c.next()){h.index>A?(b=h,h=null):b=h.sibling;var m=d(o,h,v.value,s);if(null===m){null===h&&(h=b);break}e&&h&&null===m.alternate&&n(o,h),l=i(m,l,A),null===p?u=m:p.sibling=m,p=m,h=b}if(v.done)return t(o,h),u;if(null===h){for(;!v.done;A++,v=c.next())null!==(v=f(o,v.value,s))&&(l=i(v,l,A),null===p?u=v:p.sibling=v,p=v);return u}for(h=r(o,h);!v.done;A++,v=c.next())null!==(v=g(h,o,A,v.value,s))&&(e&&null!==v.alternate&&h.delete(null===v.key?A:v.key),l=i(v,l,A),null===p?u=v:p.sibling=v,p=v);return e&&h.forEach((function(e){return n(o,e)})),u}return function(e,r,i,c){var s=\"object\"==typeof i&&null!==i&&i.type===x&&null===i.key;s&&(i=i.props.children);var u=\"object\"==typeof i&&null!==i;if(u)switch(i.$$typeof){case C:e:{for(u=i.key,s=r;null!==s;){if(s.key===u){if(7===s.tag){if(i.type===x){t(e,s.sibling),(r=o(s,i.props.children)).return=e,e=r;break e}}else if(s.elementType===i.type){t(e,s.sibling),(r=o(s,i.props)).ref=xi(e,s,i),r.return=e,e=r;break e}t(e,s);break}n(e,s),s=s.sibling}i.type===x?((r=Kc(i.props.children,e.mode,c,i.key)).return=e,e=r):((c=$c(i.type,i.key,i.props,null,e.mode,c)).ref=xi(e,r,i),c.return=e,e=c)}return l(e);case w:e:{for(s=i.key;null!==r;){if(r.key===s){if(4===r.tag&&r.stateNode.containerInfo===i.containerInfo&&r.stateNode.implementation===i.implementation){t(e,r.sibling),(r=o(r,i.children||[])).return=e,e=r;break e}t(e,r);break}n(e,r),r=r.sibling}(r=Zc(i,e.mode,c)).return=e,e=r}return l(e)}if(\"string\"==typeof i||\"number\"==typeof i)return i=\"\"+i,null!==r&&6===r.tag?(t(e,r.sibling),(r=o(r,i)).return=e,e=r):(t(e,r),(r=Xc(i,e.mode,c)).return=e,e=r),l(e);if(wi(i))return h(e,r,i,c);if(U(i))return A(e,r,i,c);if(u&&Si(e,i),void 0===i&&!s)switch(e.tag){case 1:case 22:case 0:case 11:case 15:throw Error(a(152,V(e.type)||\"Component\"))}return t(e,r)}}var ki=_i(!0),Oi=_i(!1),Bi={},Pi=so(Bi),Ti=so(Bi),Ii=so(Bi);function ji(e){if(e===Bi)throw Error(a(174));return e}function zi(e,n){switch(po(Ii,n),po(Ti,e),po(Pi,Bi),e=n.nodeType){case 9:case 11:n=(n=n.documentElement)?n.namespaceURI:ge(null,\"\");break;default:n=ge(n=(e=8===e?n.parentNode:n).namespaceURI||null,e=e.tagName)}uo(Pi),po(Pi,n)}function Di(){uo(Pi),uo(Ti),uo(Ii)}function Ri(e){ji(Ii.current);var n=ji(Pi.current),t=ge(n,e.type);n!==t&&(po(Ti,e),po(Pi,t))}function Mi(e){Ti.current===e&&(uo(Pi),uo(Ti))}var Ni=so(0);function Fi(e){for(var n=e;null!==n;){if(13===n.tag){var t=n.memoizedState;if(null!==t&&(null===(t=t.dehydrated)||\"$?\"===t.data||\"$!\"===t.data))return n}else if(19===n.tag&&void 0!==n.memoizedProps.revealOrder){if(64&n.flags)return n}else if(null!==n.child){n.child.return=n,n=n.child;continue}if(n===e)break;for(;null===n.sibling;){if(null===n.return||n.return===e)return null;n=n.return}n.sibling.return=n.return,n=n.sibling}return null}var Li=null,Hi=null,Ui=!1;function Wi(e,n){var t=Yc(5,null,null,0);t.elementType=\"DELETED\",t.type=\"DELETED\",t.stateNode=n,t.return=e,t.flags=8,null!==e.lastEffect?(e.lastEffect.nextEffect=t,e.lastEffect=t):e.firstEffect=e.lastEffect=t}function Gi(e,n){switch(e.tag){case 5:var t=e.type;return null!==(n=1!==n.nodeType||t.toLowerCase()!==n.nodeName.toLowerCase()?null:n)&&(e.stateNode=n,!0);case 6:return null!==(n=\"\"===e.pendingProps||3!==n.nodeType?null:n)&&(e.stateNode=n,!0);default:return!1}}function Yi(e){if(Ui){var n=Hi;if(n){var t=n;if(!Gi(e,n)){if(!(n=$r(t.nextSibling))||!Gi(e,n))return e.flags=-1025&e.flags|2,Ui=!1,void(Li=e);Wi(Li,t)}Li=e,Hi=$r(n.firstChild)}else e.flags=-1025&e.flags|2,Ui=!1,Li=e}}function qi(e){for(e=e.return;null!==e&&5!==e.tag&&3!==e.tag&&13!==e.tag;)e=e.return;Li=e}function Vi(e){if(e!==Li)return!1;if(!Ui)return qi(e),Ui=!0,!1;var n=e.type;if(5!==e.tag||\"head\"!==n&&\"body\"!==n&&!Gr(n,e.memoizedProps))for(n=Hi;n;)Wi(e,n),n=$r(n.nextSibling);if(qi(e),13===e.tag){if(!(e=null!==(e=e.memoizedState)?e.dehydrated:null))throw Error(a(317));e:{for(e=e.nextSibling,n=0;e;){if(8===e.nodeType){var t=e.data;if(\"/$\"===t){if(0===n){Hi=$r(e.nextSibling);break e}n--}else\"$\"!==t&&\"$!\"!==t&&\"$?\"!==t||n++}e=e.nextSibling}Hi=null}}else Hi=Li?$r(e.stateNode.nextSibling):null;return!0}function $i(){Hi=Li=null,Ui=!1}var Ki=[];function Qi(){for(var e=0;e<Ki.length;e++)Ki[e]._workInProgressVersionPrimary=null;Ki.length=0}var Xi=E.ReactCurrentDispatcher,Zi=E.ReactCurrentBatchConfig,Ji=0,ea=null,na=null,ta=null,ra=!1,oa=!1;function ia(){throw Error(a(321))}function aa(e,n){if(null===n)return!1;for(var t=0;t<n.length&&t<e.length;t++)if(!ur(e[t],n[t]))return!1;return!0}function la(e,n,t,r,o,i){if(Ji=i,ea=n,n.memoizedState=null,n.updateQueue=null,n.lanes=0,Xi.current=null===e||null===e.memoizedState?ja:za,e=t(r,o),oa){i=0;do{if(oa=!1,!(25>i))throw Error(a(301));i+=1,ta=na=null,n.updateQueue=null,Xi.current=Da,e=t(r,o)}while(oa)}if(Xi.current=Ia,n=null!==na&&null!==na.next,Ji=0,ta=na=ea=null,ra=!1,n)throw Error(a(300));return e}function ca(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===ta?ea.memoizedState=ta=e:ta=ta.next=e,ta}function sa(){if(null===na){var e=ea.alternate;e=null!==e?e.memoizedState:null}else e=na.next;var n=null===ta?ea.memoizedState:ta.next;if(null!==n)ta=n,na=e;else{if(null===e)throw Error(a(310));e={memoizedState:(na=e).memoizedState,baseState:na.baseState,baseQueue:na.baseQueue,queue:na.queue,next:null},null===ta?ea.memoizedState=ta=e:ta=ta.next=e}return ta}function ua(e,n){return\"function\"==typeof n?n(e):n}function pa(e){var n=sa(),t=n.queue;if(null===t)throw Error(a(311));t.lastRenderedReducer=e;var r=na,o=r.baseQueue,i=t.pending;if(null!==i){if(null!==o){var l=o.next;o.next=i.next,i.next=l}r.baseQueue=o=i,t.pending=null}if(null!==o){o=o.next,r=r.baseState;var c=l=i=null,s=o;do{var u=s.lane;if((Ji&u)===u)null!==c&&(c=c.next={lane:0,action:s.action,eagerReducer:s.eagerReducer,eagerState:s.eagerState,next:null}),r=s.eagerReducer===e?s.eagerState:e(r,s.action);else{var p={lane:u,action:s.action,eagerReducer:s.eagerReducer,eagerState:s.eagerState,next:null};null===c?(l=c=p,i=r):c=c.next=p,ea.lanes|=u,Ul|=u}s=s.next}while(null!==s&&s!==o);null===c?i=r:c.next=l,ur(r,n.memoizedState)||(Ma=!0),n.memoizedState=r,n.baseState=i,n.baseQueue=c,t.lastRenderedState=r}return[n.memoizedState,t.dispatch]}function fa(e){var n=sa(),t=n.queue;if(null===t)throw Error(a(311));t.lastRenderedReducer=e;var r=t.dispatch,o=t.pending,i=n.memoizedState;if(null!==o){t.pending=null;var l=o=o.next;do{i=e(i,l.action),l=l.next}while(l!==o);ur(i,n.memoizedState)||(Ma=!0),n.memoizedState=i,null===n.baseQueue&&(n.baseState=i),t.lastRenderedState=i}return[i,r]}function da(e,n,t){var r=n._getVersion;r=r(n._source);var o=n._workInProgressVersionPrimary;if(null!==o?e=o===r:(e=e.mutableReadLanes,(e=(Ji&e)===e)&&(n._workInProgressVersionPrimary=r,Ki.push(n))),e)return t(n._source);throw Ki.push(n),Error(a(350))}function ga(e,n,t,r){var o=zl;if(null===o)throw Error(a(349));var i=n._getVersion,l=i(n._source),c=Xi.current,s=c.useState((function(){return da(o,n,t)})),u=s[1],p=s[0];s=ta;var f=e.memoizedState,d=f.refs,g=d.getSnapshot,h=f.source;f=f.subscribe;var A=ea;return e.memoizedState={refs:d,source:n,subscribe:r},c.useEffect((function(){d.getSnapshot=t,d.setSnapshot=u;var e=i(n._source);if(!ur(l,e)){e=t(n._source),ur(p,e)||(u(e),e=gc(A),o.mutableReadLanes|=e&o.pendingLanes),e=o.mutableReadLanes,o.entangledLanes|=e;for(var r=o.entanglements,a=e;0<a;){var c=31-Yn(a),s=1<<c;r[c]|=e,a&=~s}}}),[t,n,r]),c.useEffect((function(){return r(n._source,(function(){var e=d.getSnapshot,t=d.setSnapshot;try{t(e(n._source));var r=gc(A);o.mutableReadLanes|=r&o.pendingLanes}catch(e){t((function(){throw e}))}}))}),[n,r]),ur(g,t)&&ur(h,n)&&ur(f,r)||((e={pending:null,dispatch:null,lastRenderedReducer:ua,lastRenderedState:p}).dispatch=u=Ta.bind(null,ea,e),s.queue=e,s.baseQueue=null,p=da(o,n,t),s.memoizedState=s.baseState=p),p}function ha(e,n,t){return ga(sa(),e,n,t)}function Aa(e){var n=ca();return\"function\"==typeof e&&(e=e()),n.memoizedState=n.baseState=e,e=(e=n.queue={pending:null,dispatch:null,lastRenderedReducer:ua,lastRenderedState:e}).dispatch=Ta.bind(null,ea,e),[n.memoizedState,e]}function ba(e,n,t,r){return e={tag:e,create:n,destroy:t,deps:r,next:null},null===(n=ea.updateQueue)?(n={lastEffect:null},ea.updateQueue=n,n.lastEffect=e.next=e):null===(t=n.lastEffect)?n.lastEffect=e.next=e:(r=t.next,t.next=e,e.next=r,n.lastEffect=e),e}function va(e){return e={current:e},ca().memoizedState=e}function ma(){return sa().memoizedState}function ya(e,n,t,r){var o=ca();ea.flags|=e,o.memoizedState=ba(1|n,t,void 0,void 0===r?null:r)}function Ea(e,n,t,r){var o=sa();r=void 0===r?null:r;var i=void 0;if(null!==na){var a=na.memoizedState;if(i=a.destroy,null!==r&&aa(r,a.deps))return void ba(n,t,i,r)}ea.flags|=e,o.memoizedState=ba(1|n,t,i,r)}function Ca(e,n){return ya(516,4,e,n)}function wa(e,n){return Ea(516,4,e,n)}function xa(e,n){return Ea(4,2,e,n)}function Sa(e,n){return\"function\"==typeof n?(e=e(),n(e),function(){n(null)}):null!=n?(e=e(),n.current=e,function(){n.current=null}):void 0}function _a(e,n,t){return t=null!=t?t.concat([e]):null,Ea(4,2,Sa.bind(null,n,e),t)}function ka(){}function Oa(e,n){var t=sa();n=void 0===n?null:n;var r=t.memoizedState;return null!==r&&null!==n&&aa(n,r[1])?r[0]:(t.memoizedState=[e,n],e)}function Ba(e,n){var t=sa();n=void 0===n?null:n;var r=t.memoizedState;return null!==r&&null!==n&&aa(n,r[1])?r[0]:(e=e(),t.memoizedState=[e,n],e)}function Pa(e,n){var t=Yo();Vo(98>t?98:t,(function(){e(!0)})),Vo(97<t?97:t,(function(){var t=Zi.transition;Zi.transition=1;try{e(!1),n()}finally{Zi.transition=t}}))}function Ta(e,n,t){var r=dc(),o=gc(e),i={lane:o,action:t,eagerReducer:null,eagerState:null,next:null},a=n.pending;if(null===a?i.next=i:(i.next=a.next,a.next=i),n.pending=i,a=e.alternate,e===ea||null!==a&&a===ea)oa=ra=!0;else{if(0===e.lanes&&(null===a||0===a.lanes)&&null!==(a=n.lastRenderedReducer))try{var l=n.lastRenderedState,c=a(l,t);if(i.eagerReducer=a,i.eagerState=c,ur(c,l))return}catch(e){}hc(e,o,r)}}var Ia={readContext:li,useCallback:ia,useContext:ia,useEffect:ia,useImperativeHandle:ia,useLayoutEffect:ia,useMemo:ia,useReducer:ia,useRef:ia,useState:ia,useDebugValue:ia,useDeferredValue:ia,useTransition:ia,useMutableSource:ia,useOpaqueIdentifier:ia,unstable_isNewReconciler:!1},ja={readContext:li,useCallback:function(e,n){return ca().memoizedState=[e,void 0===n?null:n],e},useContext:li,useEffect:Ca,useImperativeHandle:function(e,n,t){return t=null!=t?t.concat([e]):null,ya(4,2,Sa.bind(null,n,e),t)},useLayoutEffect:function(e,n){return ya(4,2,e,n)},useMemo:function(e,n){var t=ca();return n=void 0===n?null:n,e=e(),t.memoizedState=[e,n],e},useReducer:function(e,n,t){var r=ca();return n=void 0!==t?t(n):n,r.memoizedState=r.baseState=n,e=(e=r.queue={pending:null,dispatch:null,lastRenderedReducer:e,lastRenderedState:n}).dispatch=Ta.bind(null,ea,e),[r.memoizedState,e]},useRef:va,useState:Aa,useDebugValue:ka,useDeferredValue:function(e){var n=Aa(e),t=n[0],r=n[1];return Ca((function(){var n=Zi.transition;Zi.transition=1;try{r(e)}finally{Zi.transition=n}}),[e]),t},useTransition:function(){var e=Aa(!1),n=e[0];return va(e=Pa.bind(null,e[1])),[e,n]},useMutableSource:function(e,n,t){var r=ca();return r.memoizedState={refs:{getSnapshot:n,setSnapshot:null},source:e,subscribe:t},ga(r,e,n,t)},useOpaqueIdentifier:function(){if(Ui){var e=!1,n=function(e){return{$$typeof:D,toString:e,valueOf:e}}((function(){throw e||(e=!0,t(\"r:\"+(Qr++).toString(36))),Error(a(355))})),t=Aa(n)[1];return!(2&ea.mode)&&(ea.flags|=516,ba(5,(function(){t(\"r:\"+(Qr++).toString(36))}),void 0,null)),n}return Aa(n=\"r:\"+(Qr++).toString(36)),n},unstable_isNewReconciler:!1},za={readContext:li,useCallback:Oa,useContext:li,useEffect:wa,useImperativeHandle:_a,useLayoutEffect:xa,useMemo:Ba,useReducer:pa,useRef:ma,useState:function(){return pa(ua)},useDebugValue:ka,useDeferredValue:function(e){var n=pa(ua),t=n[0],r=n[1];return wa((function(){var n=Zi.transition;Zi.transition=1;try{r(e)}finally{Zi.transition=n}}),[e]),t},useTransition:function(){var e=pa(ua)[0];return[ma().current,e]},useMutableSource:ha,useOpaqueIdentifier:function(){return pa(ua)[0]},unstable_isNewReconciler:!1},Da={readContext:li,useCallback:Oa,useContext:li,useEffect:wa,useImperativeHandle:_a,useLayoutEffect:xa,useMemo:Ba,useReducer:fa,useRef:ma,useState:function(){return fa(ua)},useDebugValue:ka,useDeferredValue:function(e){var n=fa(ua),t=n[0],r=n[1];return wa((function(){var n=Zi.transition;Zi.transition=1;try{r(e)}finally{Zi.transition=n}}),[e]),t},useTransition:function(){var e=fa(ua)[0];return[ma().current,e]},useMutableSource:ha,useOpaqueIdentifier:function(){return fa(ua)[0]},unstable_isNewReconciler:!1},Ra=E.ReactCurrentOwner,Ma=!1;function Na(e,n,t,r){n.child=null===e?Oi(n,null,t,r):ki(n,e.child,t,r)}function Fa(e,n,t,r,o){t=t.render;var i=n.ref;return ai(n,o),r=la(e,n,t,r,i,o),null===e||Ma?(n.flags|=1,Na(e,n,r,o),n.child):(n.updateQueue=e.updateQueue,n.flags&=-517,e.lanes&=~o,al(e,n,o))}function La(e,n,t,r,o,i){if(null===e){var a=t.type;return\"function\"!=typeof a||qc(a)||void 0!==a.defaultProps||null!==t.compare||void 0!==t.defaultProps?((e=$c(t.type,null,r,n,n.mode,i)).ref=n.ref,e.return=n,n.child=e):(n.tag=15,n.type=a,Ha(e,n,a,r,o,i))}return a=e.child,0===(o&i)&&(o=a.memoizedProps,(t=null!==(t=t.compare)?t:fr)(o,r)&&e.ref===n.ref)?al(e,n,i):(n.flags|=1,(e=Vc(a,r)).ref=n.ref,e.return=n,n.child=e)}function Ha(e,n,t,r,o,i){if(null!==e&&fr(e.memoizedProps,r)&&e.ref===n.ref){if(Ma=!1,0===(i&o))return n.lanes=e.lanes,al(e,n,i);16384&e.flags&&(Ma=!0)}return Ga(e,n,t,r,i)}function Ua(e,n,t){var r=n.pendingProps,o=r.children,i=null!==e?e.memoizedState:null;if(\"hidden\"===r.mode||\"unstable-defer-without-hiding\"===r.mode)if(4&n.mode){if(!(1073741824&t))return e=null!==i?i.baseLanes|t:t,n.lanes=n.childLanes=1073741824,n.memoizedState={baseLanes:e},wc(n,e),null;n.memoizedState={baseLanes:0},wc(n,null!==i?i.baseLanes:t)}else n.memoizedState={baseLanes:0},wc(n,t);else null!==i?(r=i.baseLanes|t,n.memoizedState=null):r=t,wc(n,r);return Na(e,n,o,t),n.child}function Wa(e,n){var t=n.ref;(null===e&&null!==t||null!==e&&e.ref!==t)&&(n.flags|=128)}function Ga(e,n,t,r,o){var i=vo(t)?Ao:go.current;return i=bo(n,i),ai(n,o),t=la(e,n,t,r,i,o),null===e||Ma?(n.flags|=1,Na(e,n,t,o),n.child):(n.updateQueue=e.updateQueue,n.flags&=-517,e.lanes&=~o,al(e,n,o))}function Ya(e,n,t,r,o){if(vo(t)){var i=!0;Co(n)}else i=!1;if(ai(n,o),null===n.stateNode)null!==e&&(e.alternate=null,n.alternate=null,n.flags|=2),yi(n,t,r),Ci(n,t,r,o),r=!0;else if(null===e){var a=n.stateNode,l=n.memoizedProps;a.props=l;var c=a.context,s=t.contextType;\"object\"==typeof s&&null!==s?s=li(s):s=bo(n,s=vo(t)?Ao:go.current);var u=t.getDerivedStateFromProps,p=\"function\"==typeof u||\"function\"==typeof a.getSnapshotBeforeUpdate;p||\"function\"!=typeof a.UNSAFE_componentWillReceiveProps&&\"function\"!=typeof a.componentWillReceiveProps||(l!==r||c!==s)&&Ei(n,a,r,s),ci=!1;var f=n.memoizedState;a.state=f,gi(n,r,a,o),c=n.memoizedState,l!==r||f!==c||ho.current||ci?(\"function\"==typeof u&&(bi(n,t,u,r),c=n.memoizedState),(l=ci||mi(n,t,l,r,f,c,s))?(p||\"function\"!=typeof a.UNSAFE_componentWillMount&&\"function\"!=typeof a.componentWillMount||(\"function\"==typeof a.componentWillMount&&a.componentWillMount(),\"function\"==typeof a.UNSAFE_componentWillMount&&a.UNSAFE_componentWillMount()),\"function\"==typeof a.componentDidMount&&(n.flags|=4)):(\"function\"==typeof a.componentDidMount&&(n.flags|=4),n.memoizedProps=r,n.memoizedState=c),a.props=r,a.state=c,a.context=s,r=l):(\"function\"==typeof a.componentDidMount&&(n.flags|=4),r=!1)}else{a=n.stateNode,ui(e,n),l=n.memoizedProps,s=n.type===n.elementType?l:Zo(n.type,l),a.props=s,p=n.pendingProps,f=a.context,\"object\"==typeof(c=t.contextType)&&null!==c?c=li(c):c=bo(n,c=vo(t)?Ao:go.current);var d=t.getDerivedStateFromProps;(u=\"function\"==typeof d||\"function\"==typeof a.getSnapshotBeforeUpdate)||\"function\"!=typeof a.UNSAFE_componentWillReceiveProps&&\"function\"!=typeof a.componentWillReceiveProps||(l!==p||f!==c)&&Ei(n,a,r,c),ci=!1,f=n.memoizedState,a.state=f,gi(n,r,a,o);var g=n.memoizedState;l!==p||f!==g||ho.current||ci?(\"function\"==typeof d&&(bi(n,t,d,r),g=n.memoizedState),(s=ci||mi(n,t,s,r,f,g,c))?(u||\"function\"!=typeof a.UNSAFE_componentWillUpdate&&\"function\"!=typeof a.componentWillUpdate||(\"function\"==typeof a.componentWillUpdate&&a.componentWillUpdate(r,g,c),\"function\"==typeof a.UNSAFE_componentWillUpdate&&a.UNSAFE_componentWillUpdate(r,g,c)),\"function\"==typeof a.componentDidUpdate&&(n.flags|=4),\"function\"==typeof a.getSnapshotBeforeUpdate&&(n.flags|=256)):(\"function\"!=typeof a.componentDidUpdate||l===e.memoizedProps&&f===e.memoizedState||(n.flags|=4),\"function\"!=typeof a.getSnapshotBeforeUpdate||l===e.memoizedProps&&f===e.memoizedState||(n.flags|=256),n.memoizedProps=r,n.memoizedState=g),a.props=r,a.state=g,a.context=c,r=s):(\"function\"!=typeof a.componentDidUpdate||l===e.memoizedProps&&f===e.memoizedState||(n.flags|=4),\"function\"!=typeof a.getSnapshotBeforeUpdate||l===e.memoizedProps&&f===e.memoizedState||(n.flags|=256),r=!1)}return qa(e,n,t,r,i,o)}function qa(e,n,t,r,o,i){Wa(e,n);var a=!!(64&n.flags);if(!r&&!a)return o&&wo(n,t,!1),al(e,n,i);r=n.stateNode,Ra.current=n;var l=a&&\"function\"!=typeof t.getDerivedStateFromError?null:r.render();return n.flags|=1,null!==e&&a?(n.child=ki(n,e.child,null,i),n.child=ki(n,null,l,i)):Na(e,n,l,i),n.memoizedState=r.state,o&&wo(n,t,!0),n.child}function Va(e){var n=e.stateNode;n.pendingContext?yo(0,n.pendingContext,n.pendingContext!==n.context):n.context&&yo(0,n.context,!1),zi(e,n.containerInfo)}var $a,Ka,Qa,Xa,Za={dehydrated:null,retryLane:0};function Ja(e,n,t){var r,o=n.pendingProps,i=Ni.current,a=!1;return(r=!!(64&n.flags))||(r=(null===e||null!==e.memoizedState)&&!!(2&i)),r?(a=!0,n.flags&=-65):null!==e&&null===e.memoizedState||void 0===o.fallback||!0===o.unstable_avoidThisFallback||(i|=1),po(Ni,1&i),null===e?(void 0!==o.fallback&&Yi(n),e=o.children,i=o.fallback,a?(e=el(n,e,i,t),n.child.memoizedState={baseLanes:t},n.memoizedState=Za,e):\"number\"==typeof o.unstable_expectedLoadTime?(e=el(n,e,i,t),n.child.memoizedState={baseLanes:t},n.memoizedState=Za,n.lanes=33554432,e):((t=Qc({mode:\"visible\",children:e},n.mode,t,null)).return=n,n.child=t)):(e.memoizedState,a?(o=tl(e,n,o.children,o.fallback,t),a=n.child,i=e.child.memoizedState,a.memoizedState=null===i?{baseLanes:t}:{baseLanes:i.baseLanes|t},a.childLanes=e.childLanes&~t,n.memoizedState=Za,o):(t=nl(e,n,o.children,t),n.memoizedState=null,t))}function el(e,n,t,r){var o=e.mode,i=e.child;return n={mode:\"hidden\",children:n},2&o||null===i?i=Qc(n,o,0,null):(i.childLanes=0,i.pendingProps=n),t=Kc(t,o,r,null),i.return=e,t.return=e,i.sibling=t,e.child=i,t}function nl(e,n,t,r){var o=e.child;return e=o.sibling,t=Vc(o,{mode:\"visible\",children:t}),!(2&n.mode)&&(t.lanes=r),t.return=n,t.sibling=null,null!==e&&(e.nextEffect=null,e.flags=8,n.firstEffect=n.lastEffect=e),n.child=t}function tl(e,n,t,r,o){var i=n.mode,a=e.child;e=a.sibling;var l={mode:\"hidden\",children:t};return 2&i||n.child===a?t=Vc(a,l):((t=n.child).childLanes=0,t.pendingProps=l,null!==(a=t.lastEffect)?(n.firstEffect=t.firstEffect,n.lastEffect=a,a.nextEffect=null):n.firstEffect=n.lastEffect=null),null!==e?r=Vc(e,r):(r=Kc(r,i,o,null)).flags|=2,r.return=n,t.return=n,t.sibling=r,n.child=t,r}function rl(e,n){e.lanes|=n;var t=e.alternate;null!==t&&(t.lanes|=n),ii(e.return,n)}function ol(e,n,t,r,o,i){var a=e.memoizedState;null===a?e.memoizedState={isBackwards:n,rendering:null,renderingStartTime:0,last:r,tail:t,tailMode:o,lastEffect:i}:(a.isBackwards=n,a.rendering=null,a.renderingStartTime=0,a.last=r,a.tail=t,a.tailMode=o,a.lastEffect=i)}function il(e,n,t){var r=n.pendingProps,o=r.revealOrder,i=r.tail;if(Na(e,n,r.children,t),2&(r=Ni.current))r=1&r|2,n.flags|=64;else{if(null!==e&&64&e.flags)e:for(e=n.child;null!==e;){if(13===e.tag)null!==e.memoizedState&&rl(e,t);else if(19===e.tag)rl(e,t);else if(null!==e.child){e.child.return=e,e=e.child;continue}if(e===n)break e;for(;null===e.sibling;){if(null===e.return||e.return===n)break e;e=e.return}e.sibling.return=e.return,e=e.sibling}r&=1}if(po(Ni,r),2&n.mode)switch(o){case\"forwards\":for(t=n.child,o=null;null!==t;)null!==(e=t.alternate)&&null===Fi(e)&&(o=t),t=t.sibling;null===(t=o)?(o=n.child,n.child=null):(o=t.sibling,t.sibling=null),ol(n,!1,o,t,i,n.lastEffect);break;case\"backwards\":for(t=null,o=n.child,n.child=null;null!==o;){if(null!==(e=o.alternate)&&null===Fi(e)){n.child=o;break}e=o.sibling,o.sibling=t,t=o,o=e}ol(n,!0,t,null,i,n.lastEffect);break;case\"together\":ol(n,!1,null,null,void 0,n.lastEffect);break;default:n.memoizedState=null}else n.memoizedState=null;return n.child}function al(e,n,t){if(null!==e&&(n.dependencies=e.dependencies),Ul|=n.lanes,0!==(t&n.childLanes)){if(null!==e&&n.child!==e.child)throw Error(a(153));if(null!==n.child){for(t=Vc(e=n.child,e.pendingProps),n.child=t,t.return=n;null!==e.sibling;)e=e.sibling,(t=t.sibling=Vc(e,e.pendingProps)).return=n;t.sibling=null}return n.child}return null}function ll(e,n){if(!Ui)switch(e.tailMode){case\"hidden\":n=e.tail;for(var t=null;null!==n;)null!==n.alternate&&(t=n),n=n.sibling;null===t?e.tail=null:t.sibling=null;break;case\"collapsed\":t=e.tail;for(var r=null;null!==t;)null!==t.alternate&&(r=t),t=t.sibling;null===r?n||null===e.tail?e.tail=null:e.tail.sibling=null:r.sibling=null}}function cl(e,n,t){var r=n.pendingProps;switch(n.tag){case 2:case 16:case 15:case 0:case 11:case 7:case 8:case 12:case 9:case 14:return null;case 1:case 17:return vo(n.type)&&mo(),null;case 3:return Di(),uo(ho),uo(go),Qi(),(r=n.stateNode).pendingContext&&(r.context=r.pendingContext,r.pendingContext=null),null!==e&&null!==e.child||(Vi(n)?n.flags|=4:r.hydrate||(n.flags|=256)),Ka(n),null;case 5:Mi(n);var i=ji(Ii.current);if(t=n.type,null!==e&&null!=n.stateNode)Qa(e,n,t,r,i),e.ref!==n.ref&&(n.flags|=128);else{if(!r){if(null===n.stateNode)throw Error(a(166));return null}if(e=ji(Pi.current),Vi(n)){r=n.stateNode,t=n.type;var l=n.memoizedProps;switch(r[Zr]=n,r[Jr]=l,t){case\"dialog\":Pr(\"cancel\",r),Pr(\"close\",r);break;case\"iframe\":case\"object\":case\"embed\":Pr(\"load\",r);break;case\"video\":case\"audio\":for(e=0;e<_r.length;e++)Pr(_r[e],r);break;case\"source\":Pr(\"error\",r);break;case\"img\":case\"image\":case\"link\":Pr(\"error\",r),Pr(\"load\",r);break;case\"details\":Pr(\"toggle\",r);break;case\"input\":ee(r,l),Pr(\"invalid\",r);break;case\"select\":r._wrapperState={wasMultiple:!!l.multiple},Pr(\"invalid\",r);break;case\"textarea\":ce(r,l),Pr(\"invalid\",r)}for(var s in xe(t,l),e=null,l)l.hasOwnProperty(s)&&(i=l[s],\"children\"===s?\"string\"==typeof i?r.textContent!==i&&(e=[\"children\",i]):\"number\"==typeof i&&r.textContent!==\"\"+i&&(e=[\"children\",\"\"+i]):c.hasOwnProperty(s)&&null!=i&&\"onScroll\"===s&&Pr(\"scroll\",r));switch(t){case\"input\":Q(r),re(r,l,!0);break;case\"textarea\":Q(r),ue(r);break;case\"select\":case\"option\":break;default:\"function\"==typeof l.onClick&&(r.onclick=Lr)}r=e,n.updateQueue=r,null!==r&&(n.flags|=4)}else{switch(s=9===i.nodeType?i:i.ownerDocument,e===pe&&(e=de(t)),e===pe?\"script\"===t?((e=s.createElement(\"div\")).innerHTML=\"<script><\\/script>\",e=e.removeChild(e.firstChild)):\"string\"==typeof r.is?e=s.createElement(t,{is:r.is}):(e=s.createElement(t),\"select\"===t&&(s=e,r.multiple?s.multiple=!0:r.size&&(s.size=r.size))):e=s.createElementNS(e,t),e[Zr]=n,e[Jr]=r,$a(e,n,!1,!1),n.stateNode=e,s=Se(t,r),t){case\"dialog\":Pr(\"cancel\",e),Pr(\"close\",e),i=r;break;case\"iframe\":case\"object\":case\"embed\":Pr(\"load\",e),i=r;break;case\"video\":case\"audio\":for(i=0;i<_r.length;i++)Pr(_r[i],e);i=r;break;case\"source\":Pr(\"error\",e),i=r;break;case\"img\":case\"image\":case\"link\":Pr(\"error\",e),Pr(\"load\",e),i=r;break;case\"details\":Pr(\"toggle\",e),i=r;break;case\"input\":ee(e,r),i=J(e,r),Pr(\"invalid\",e);break;case\"option\":i=ie(e,r);break;case\"select\":e._wrapperState={wasMultiple:!!r.multiple},i=o({},r,{value:void 0}),Pr(\"invalid\",e);break;case\"textarea\":ce(e,r),i=le(e,r),Pr(\"invalid\",e);break;default:i=r}xe(t,i);var u=i;for(l in u)if(u.hasOwnProperty(l)){var p=u[l];\"style\"===l?Ce(e,p):\"dangerouslySetInnerHTML\"===l?null!=(p=p?p.__html:void 0)&&be(e,p):\"children\"===l?\"string\"==typeof p?(\"textarea\"!==t||\"\"!==p)&&ve(e,p):\"number\"==typeof p&&ve(e,\"\"+p):\"suppressContentEditableWarning\"!==l&&\"suppressHydrationWarning\"!==l&&\"autoFocus\"!==l&&(c.hasOwnProperty(l)?null!=p&&\"onScroll\"===l&&Pr(\"scroll\",e):null!=p&&y(e,l,p,s))}switch(t){case\"input\":Q(e),re(e,r,!1);break;case\"textarea\":Q(e),ue(e);break;case\"option\":null!=r.value&&e.setAttribute(\"value\",\"\"+$(r.value));break;case\"select\":e.multiple=!!r.multiple,null!=(l=r.value)?ae(e,!!r.multiple,l,!1):null!=r.defaultValue&&ae(e,!!r.multiple,r.defaultValue,!0);break;default:\"function\"==typeof i.onClick&&(e.onclick=Lr)}Wr(t,r)&&(n.flags|=4)}null!==n.ref&&(n.flags|=128)}return null;case 6:if(e&&null!=n.stateNode)Xa(e,n,e.memoizedProps,r);else{if(\"string\"!=typeof r&&null===n.stateNode)throw Error(a(166));t=ji(Ii.current),ji(Pi.current),Vi(n)?(r=n.stateNode,t=n.memoizedProps,r[Zr]=n,r.nodeValue!==t&&(n.flags|=4)):((r=(9===t.nodeType?t:t.ownerDocument).createTextNode(r))[Zr]=n,n.stateNode=r)}return null;case 13:return uo(Ni),r=n.memoizedState,64&n.flags?(n.lanes=t,n):(r=null!==r,t=!1,null===e?void 0!==n.memoizedProps.fallback&&Vi(n):t=null!==e.memoizedState,r&&!t&&2&n.mode&&(null===e&&!0!==n.memoizedProps.unstable_avoidThisFallback||1&Ni.current?0===Fl&&(Fl=3):(0!==Fl&&3!==Fl||(Fl=4),null===zl||!(134217727&Ul)&&!(134217727&Wl)||mc(zl,Rl))),(r||t)&&(n.flags|=4),null);case 4:return Di(),Ka(n),null===e&&Ir(n.stateNode.containerInfo),null;case 10:return oi(n),null;case 19:if(uo(Ni),null===(r=n.memoizedState))return null;if(l=!!(64&n.flags),null===(s=r.rendering))if(l)ll(r,!1);else{if(0!==Fl||null!==e&&64&e.flags)for(e=n.child;null!==e;){if(null!==(s=Fi(e))){for(n.flags|=64,ll(r,!1),null!==(l=s.updateQueue)&&(n.updateQueue=l,n.flags|=4),null===r.lastEffect&&(n.firstEffect=null),n.lastEffect=r.lastEffect,r=t,t=n.child;null!==t;)e=r,(l=t).flags&=2,l.nextEffect=null,l.firstEffect=null,l.lastEffect=null,null===(s=l.alternate)?(l.childLanes=0,l.lanes=e,l.child=null,l.memoizedProps=null,l.memoizedState=null,l.updateQueue=null,l.dependencies=null,l.stateNode=null):(l.childLanes=s.childLanes,l.lanes=s.lanes,l.child=s.child,l.memoizedProps=s.memoizedProps,l.memoizedState=s.memoizedState,l.updateQueue=s.updateQueue,l.type=s.type,e=s.dependencies,l.dependencies=null===e?null:{lanes:e.lanes,firstContext:e.firstContext}),t=t.sibling;return po(Ni,1&Ni.current|2),n.child}e=e.sibling}null!==r.tail&&Go()>Vl&&(n.flags|=64,l=!0,ll(r,!1),n.lanes=33554432)}else{if(!l)if(null!==(e=Fi(s))){if(n.flags|=64,l=!0,null!==(t=e.updateQueue)&&(n.updateQueue=t,n.flags|=4),ll(r,!0),null===r.tail&&\"hidden\"===r.tailMode&&!s.alternate&&!Ui)return null!==(n=n.lastEffect=r.lastEffect)&&(n.nextEffect=null),null}else 2*Go()-r.renderingStartTime>Vl&&1073741824!==t&&(n.flags|=64,l=!0,ll(r,!1),n.lanes=33554432);r.isBackwards?(s.sibling=n.child,n.child=s):(null!==(t=r.last)?t.sibling=s:n.child=s,r.last=s)}return null!==r.tail?(t=r.tail,r.rendering=t,r.tail=t.sibling,r.lastEffect=n.lastEffect,r.renderingStartTime=Go(),t.sibling=null,n=Ni.current,po(Ni,l?1&n|2:1&n),t):null;case 23:case 24:return xc(),null!==e&&null!==e.memoizedState!=(null!==n.memoizedState)&&\"unstable-defer-without-hiding\"!==r.mode&&(n.flags|=4),null}throw Error(a(156,n.tag))}function sl(e){switch(e.tag){case 1:vo(e.type)&&mo();var n=e.flags;return 4096&n?(e.flags=-4097&n|64,e):null;case 3:if(Di(),uo(ho),uo(go),Qi(),64&(n=e.flags))throw Error(a(285));return e.flags=-4097&n|64,e;case 5:return Mi(e),null;case 13:return uo(Ni),4096&(n=e.flags)?(e.flags=-4097&n|64,e):null;case 19:return uo(Ni),null;case 4:return Di(),null;case 10:return oi(e),null;case 23:case 24:return xc(),null;default:return null}}function ul(e,n){try{var t=\"\",r=n;do{t+=q(r),r=r.return}while(r);var o=t}catch(e){o=\"\\nError generating stack: \"+e.message+\"\\n\"+e.stack}return{value:e,source:n,stack:o}}function pl(e,n){try{console.error(n.value)}catch(e){setTimeout((function(){throw e}))}}$a=function(e,n){for(var t=n.child;null!==t;){if(5===t.tag||6===t.tag)e.appendChild(t.stateNode);else if(4!==t.tag&&null!==t.child){t.child.return=t,t=t.child;continue}if(t===n)break;for(;null===t.sibling;){if(null===t.return||t.return===n)return;t=t.return}t.sibling.return=t.return,t=t.sibling}},Ka=function(){},Qa=function(e,n,t,r){var i=e.memoizedProps;if(i!==r){e=n.stateNode,ji(Pi.current);var a,l=null;switch(t){case\"input\":i=J(e,i),r=J(e,r),l=[];break;case\"option\":i=ie(e,i),r=ie(e,r),l=[];break;case\"select\":i=o({},i,{value:void 0}),r=o({},r,{value:void 0}),l=[];break;case\"textarea\":i=le(e,i),r=le(e,r),l=[];break;default:\"function\"!=typeof i.onClick&&\"function\"==typeof r.onClick&&(e.onclick=Lr)}for(p in xe(t,r),t=null,i)if(!r.hasOwnProperty(p)&&i.hasOwnProperty(p)&&null!=i[p])if(\"style\"===p){var s=i[p];for(a in s)s.hasOwnProperty(a)&&(t||(t={}),t[a]=\"\")}else\"dangerouslySetInnerHTML\"!==p&&\"children\"!==p&&\"suppressContentEditableWarning\"!==p&&\"suppressHydrationWarning\"!==p&&\"autoFocus\"!==p&&(c.hasOwnProperty(p)?l||(l=[]):(l=l||[]).push(p,null));for(p in r){var u=r[p];if(s=null!=i?i[p]:void 0,r.hasOwnProperty(p)&&u!==s&&(null!=u||null!=s))if(\"style\"===p)if(s){for(a in s)!s.hasOwnProperty(a)||u&&u.hasOwnProperty(a)||(t||(t={}),t[a]=\"\");for(a in u)u.hasOwnProperty(a)&&s[a]!==u[a]&&(t||(t={}),t[a]=u[a])}else t||(l||(l=[]),l.push(p,t)),t=u;else\"dangerouslySetInnerHTML\"===p?(u=u?u.__html:void 0,s=s?s.__html:void 0,null!=u&&s!==u&&(l=l||[]).push(p,u)):\"children\"===p?\"string\"!=typeof u&&\"number\"!=typeof u||(l=l||[]).push(p,\"\"+u):\"suppressContentEditableWarning\"!==p&&\"suppressHydrationWarning\"!==p&&(c.hasOwnProperty(p)?(null!=u&&\"onScroll\"===p&&Pr(\"scroll\",e),l||s===u||(l=[])):\"object\"==typeof u&&null!==u&&u.$$typeof===D?u.toString():(l=l||[]).push(p,u))}t&&(l=l||[]).push(\"style\",t);var p=l;(n.updateQueue=p)&&(n.flags|=4)}},Xa=function(e,n,t,r){t!==r&&(n.flags|=4)};var fl=\"function\"==typeof WeakMap?WeakMap:Map;function dl(e,n,t){(t=pi(-1,t)).tag=3,t.payload={element:null};var r=n.value;return t.callback=function(){Xl||(Xl=!0,Zl=r),pl(0,n)},t}function gl(e,n,t){(t=pi(-1,t)).tag=3;var r=e.type.getDerivedStateFromError;if(\"function\"==typeof r){var o=n.value;t.payload=function(){return pl(0,n),r(o)}}var i=e.stateNode;return null!==i&&\"function\"==typeof i.componentDidCatch&&(t.callback=function(){\"function\"!=typeof r&&(null===Jl?Jl=new Set([this]):Jl.add(this),pl(0,n));var e=n.stack;this.componentDidCatch(n.value,{componentStack:null!==e?e:\"\"})}),t}var hl=\"function\"==typeof WeakSet?WeakSet:Set;function Al(e){var n=e.ref;if(null!==n)if(\"function\"==typeof n)try{n(null)}catch(n){Hc(e,n)}else n.current=null}function bl(e,n){switch(n.tag){case 0:case 11:case 15:case 22:case 5:case 6:case 4:case 17:return;case 1:if(256&n.flags&&null!==e){var t=e.memoizedProps,r=e.memoizedState;n=(e=n.stateNode).getSnapshotBeforeUpdate(n.elementType===n.type?t:Zo(n.type,t),r),e.__reactInternalSnapshotBeforeUpdate=n}return;case 3:return void(256&n.flags&&Vr(n.stateNode.containerInfo))}throw Error(a(163))}function vl(e,n,t){switch(t.tag){case 0:case 11:case 15:case 22:if(null!==(n=null!==(n=t.updateQueue)?n.lastEffect:null)){e=n=n.next;do{if(!(3&~e.tag)){var r=e.create;e.destroy=r()}e=e.next}while(e!==n)}if(null!==(n=null!==(n=t.updateQueue)?n.lastEffect:null)){e=n=n.next;do{var o=e;r=o.next,4&(o=o.tag)&&1&o&&(Nc(t,e),Mc(t,e)),e=r}while(e!==n)}return;case 1:return e=t.stateNode,4&t.flags&&(null===n?e.componentDidMount():(r=t.elementType===t.type?n.memoizedProps:Zo(t.type,n.memoizedProps),e.componentDidUpdate(r,n.memoizedState,e.__reactInternalSnapshotBeforeUpdate))),void(null!==(n=t.updateQueue)&&hi(t,n,e));case 3:if(null!==(n=t.updateQueue)){if(e=null,null!==t.child)switch(t.child.tag){case 5:case 1:e=t.child.stateNode}hi(t,n,e)}return;case 5:return e=t.stateNode,void(null===n&&4&t.flags&&Wr(t.type,t.memoizedProps)&&e.focus());case 6:case 4:case 12:case 19:case 17:case 20:case 21:case 23:case 24:return;case 13:return void(null===t.memoizedState&&(t=t.alternate,null!==t&&(t=t.memoizedState,null!==t&&(t=t.dehydrated,null!==t&&wn(t)))))}throw Error(a(163))}function ml(e,n){for(var t=e;;){if(5===t.tag){var r=t.stateNode;if(n)\"function\"==typeof(r=r.style).setProperty?r.setProperty(\"display\",\"none\",\"important\"):r.display=\"none\";else{r=t.stateNode;var o=t.memoizedProps.style;o=null!=o&&o.hasOwnProperty(\"display\")?o.display:null,r.style.display=Ee(\"display\",o)}}else if(6===t.tag)t.stateNode.nodeValue=n?\"\":t.memoizedProps;else if((23!==t.tag&&24!==t.tag||null===t.memoizedState||t===e)&&null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return;t=t.return}t.sibling.return=t.return,t=t.sibling}}function yl(e,n){if(So&&\"function\"==typeof So.onCommitFiberUnmount)try{So.onCommitFiberUnmount(xo,n)}catch(e){}switch(n.tag){case 0:case 11:case 14:case 15:case 22:if(null!==(e=n.updateQueue)&&null!==(e=e.lastEffect)){var t=e=e.next;do{var r=t,o=r.destroy;if(r=r.tag,void 0!==o)if(4&r)Nc(n,t);else{r=n;try{o()}catch(e){Hc(r,e)}}t=t.next}while(t!==e)}break;case 1:if(Al(n),\"function\"==typeof(e=n.stateNode).componentWillUnmount)try{e.props=n.memoizedProps,e.state=n.memoizedState,e.componentWillUnmount()}catch(e){Hc(n,e)}break;case 5:Al(n);break;case 4:_l(e,n)}}function El(e){e.alternate=null,e.child=null,e.dependencies=null,e.firstEffect=null,e.lastEffect=null,e.memoizedProps=null,e.memoizedState=null,e.pendingProps=null,e.return=null,e.updateQueue=null}function Cl(e){return 5===e.tag||3===e.tag||4===e.tag}function wl(e){e:{for(var n=e.return;null!==n;){if(Cl(n))break e;n=n.return}throw Error(a(160))}var t=n;switch(n=t.stateNode,t.tag){case 5:var r=!1;break;case 3:case 4:n=n.containerInfo,r=!0;break;default:throw Error(a(161))}16&t.flags&&(ve(n,\"\"),t.flags&=-17);e:n:for(t=e;;){for(;null===t.sibling;){if(null===t.return||Cl(t.return)){t=null;break e}t=t.return}for(t.sibling.return=t.return,t=t.sibling;5!==t.tag&&6!==t.tag&&18!==t.tag;){if(2&t.flags)continue n;if(null===t.child||4===t.tag)continue n;t.child.return=t,t=t.child}if(!(2&t.flags)){t=t.stateNode;break e}}r?xl(e,t,n):Sl(e,t,n)}function xl(e,n,t){var r=e.tag,o=5===r||6===r;if(o)e=o?e.stateNode:e.stateNode.instance,n?8===t.nodeType?t.parentNode.insertBefore(e,n):t.insertBefore(e,n):(8===t.nodeType?(n=t.parentNode).insertBefore(e,t):(n=t).appendChild(e),null!=(t=t._reactRootContainer)||null!==n.onclick||(n.onclick=Lr));else if(4!==r&&null!==(e=e.child))for(xl(e,n,t),e=e.sibling;null!==e;)xl(e,n,t),e=e.sibling}function Sl(e,n,t){var r=e.tag,o=5===r||6===r;if(o)e=o?e.stateNode:e.stateNode.instance,n?t.insertBefore(e,n):t.appendChild(e);else if(4!==r&&null!==(e=e.child))for(Sl(e,n,t),e=e.sibling;null!==e;)Sl(e,n,t),e=e.sibling}function _l(e,n){for(var t,r,o=n,i=!1;;){if(!i){i=o.return;e:for(;;){if(null===i)throw Error(a(160));switch(t=i.stateNode,i.tag){case 5:r=!1;break e;case 3:case 4:t=t.containerInfo,r=!0;break e}i=i.return}i=!0}if(5===o.tag||6===o.tag){e:for(var l=e,c=o,s=c;;)if(yl(l,s),null!==s.child&&4!==s.tag)s.child.return=s,s=s.child;else{if(s===c)break e;for(;null===s.sibling;){if(null===s.return||s.return===c)break e;s=s.return}s.sibling.return=s.return,s=s.sibling}r?(l=t,c=o.stateNode,8===l.nodeType?l.parentNode.removeChild(c):l.removeChild(c)):t.removeChild(o.stateNode)}else if(4===o.tag){if(null!==o.child){t=o.stateNode.containerInfo,r=!0,o.child.return=o,o=o.child;continue}}else if(yl(e,o),null!==o.child){o.child.return=o,o=o.child;continue}if(o===n)break;for(;null===o.sibling;){if(null===o.return||o.return===n)return;4===(o=o.return).tag&&(i=!1)}o.sibling.return=o.return,o=o.sibling}}function kl(e,n){switch(n.tag){case 0:case 11:case 14:case 15:case 22:var t=n.updateQueue;if(null!==(t=null!==t?t.lastEffect:null)){var r=t=t.next;do{!(3&~r.tag)&&(e=r.destroy,r.destroy=void 0,void 0!==e&&e()),r=r.next}while(r!==t)}return;case 1:case 12:case 17:return;case 5:if(null!=(t=n.stateNode)){r=n.memoizedProps;var o=null!==e?e.memoizedProps:r;e=n.type;var i=n.updateQueue;if(n.updateQueue=null,null!==i){for(t[Jr]=r,\"input\"===e&&\"radio\"===r.type&&null!=r.name&&ne(t,r),Se(e,o),n=Se(e,r),o=0;o<i.length;o+=2){var l=i[o],c=i[o+1];\"style\"===l?Ce(t,c):\"dangerouslySetInnerHTML\"===l?be(t,c):\"children\"===l?ve(t,c):y(t,l,c,n)}switch(e){case\"input\":te(t,r);break;case\"textarea\":se(t,r);break;case\"select\":e=t._wrapperState.wasMultiple,t._wrapperState.wasMultiple=!!r.multiple,null!=(i=r.value)?ae(t,!!r.multiple,i,!1):e!==!!r.multiple&&(null!=r.defaultValue?ae(t,!!r.multiple,r.defaultValue,!0):ae(t,!!r.multiple,r.multiple?[]:\"\",!1))}}}return;case 6:if(null===n.stateNode)throw Error(a(162));return void(n.stateNode.nodeValue=n.memoizedProps);case 3:return void((t=n.stateNode).hydrate&&(t.hydrate=!1,wn(t.containerInfo)));case 13:return null!==n.memoizedState&&(ql=Go(),ml(n.child,!0)),void Ol(n);case 19:return void Ol(n);case 23:case 24:return void ml(n,null!==n.memoizedState)}throw Error(a(163))}function Ol(e){var n=e.updateQueue;if(null!==n){e.updateQueue=null;var t=e.stateNode;null===t&&(t=e.stateNode=new hl),n.forEach((function(n){var r=Wc.bind(null,e,n);t.has(n)||(t.add(n),n.then(r,r))}))}}function Bl(e,n){return null!==e&&(null===(e=e.memoizedState)||null!==e.dehydrated)&&(null!==(n=n.memoizedState)&&null===n.dehydrated)}var Pl=Math.ceil,Tl=E.ReactCurrentDispatcher,Il=E.ReactCurrentOwner,jl=0,zl=null,Dl=null,Rl=0,Ml=0,Nl=so(0),Fl=0,Ll=null,Hl=0,Ul=0,Wl=0,Gl=0,Yl=null,ql=0,Vl=1/0;function $l(){Vl=Go()+500}var Kl,Ql=null,Xl=!1,Zl=null,Jl=null,ec=!1,nc=null,tc=90,rc=[],oc=[],ic=null,ac=0,lc=null,cc=-1,sc=0,uc=0,pc=null,fc=!1;function dc(){return 48&jl?Go():-1!==cc?cc:cc=Go()}function gc(e){if(!(2&(e=e.mode)))return 1;if(!(4&e))return 99===Yo()?1:2;if(0===sc&&(sc=Hl),0!==Xo.transition){0!==uc&&(uc=null!==Yl?Yl.pendingLanes:0),e=sc;var n=4186112&~uc;return 0===(n&=-n)&&(0===(n=(e=4186112&~e)&-e)&&(n=8192)),n}return e=Yo(),4&jl&&98===e?e=Hn(12,sc):e=Hn(e=function(e){switch(e){case 99:return 15;case 98:return 10;case 97:case 96:return 8;case 95:return 2;default:return 0}}(e),sc),e}function hc(e,n,t){if(50<ac)throw ac=0,lc=null,Error(a(185));if(null===(e=Ac(e,n)))return null;Gn(e,n,t),e===zl&&(Wl|=n,4===Fl&&mc(e,Rl));var r=Yo();1===n?8&jl&&!(48&jl)?yc(e):(bc(e,t),0===jl&&($l(),Ko())):(!(4&jl)||98!==r&&99!==r||(null===ic?ic=new Set([e]):ic.add(e)),bc(e,t)),Yl=e}function Ac(e,n){e.lanes|=n;var t=e.alternate;for(null!==t&&(t.lanes|=n),t=e,e=e.return;null!==e;)e.childLanes|=n,null!==(t=e.alternate)&&(t.childLanes|=n),t=e,e=e.return;return 3===t.tag?t.stateNode:null}function bc(e,n){for(var t=e.callbackNode,r=e.suspendedLanes,o=e.pingedLanes,i=e.expirationTimes,l=e.pendingLanes;0<l;){var c=31-Yn(l),s=1<<c,u=i[c];if(-1===u){if(0===(s&r)||0!==(s&o)){u=n,Nn(s);var p=Mn;i[c]=10<=p?u+250:6<=p?u+5e3:-1}}else u<=n&&(e.expiredLanes|=s);l&=~s}if(r=Fn(e,e===zl?Rl:0),n=Mn,0===r)null!==t&&(t!==No&&Oo(t),e.callbackNode=null,e.callbackPriority=0);else{if(null!==t){if(e.callbackPriority===n)return;t!==No&&Oo(t)}15===n?(t=yc.bind(null,e),null===Lo?(Lo=[t],Ho=ko(jo,Qo)):Lo.push(t),t=No):14===n?t=$o(99,yc.bind(null,e)):(t=function(e){switch(e){case 15:case 14:return 99;case 13:case 12:case 11:case 10:return 98;case 9:case 8:case 7:case 6:case 4:case 5:return 97;case 3:case 2:case 1:return 95;case 0:return 90;default:throw Error(a(358,e))}}(n),t=$o(t,vc.bind(null,e))),e.callbackPriority=n,e.callbackNode=t}}function vc(e){if(cc=-1,uc=sc=0,48&jl)throw Error(a(327));var n=e.callbackNode;if(Rc()&&e.callbackNode!==n)return null;var t=Fn(e,e===zl?Rl:0);if(0===t)return null;var r=t,o=jl;jl|=16;var i=kc();for(zl===e&&Rl===r||($l(),Sc(e,r));;)try{Pc();break}catch(n){_c(e,n)}if(ri(),Tl.current=i,jl=o,null!==Dl?r=0:(zl=null,Rl=0,r=Fl),0!==(Hl&Wl))Sc(e,0);else if(0!==r){if(2===r&&(jl|=64,e.hydrate&&(e.hydrate=!1,Vr(e.containerInfo)),0!==(t=Ln(e))&&(r=Oc(e,t))),1===r)throw n=Ll,Sc(e,0),mc(e,t),bc(e,Go()),n;switch(e.finishedWork=e.current.alternate,e.finishedLanes=t,r){case 0:case 1:throw Error(a(345));case 2:case 5:jc(e);break;case 3:if(mc(e,t),(62914560&t)===t&&10<(r=ql+500-Go())){if(0!==Fn(e,0))break;if(((o=e.suspendedLanes)&t)!==t){dc(),e.pingedLanes|=e.suspendedLanes&o;break}e.timeoutHandle=Yr(jc.bind(null,e),r);break}jc(e);break;case 4:if(mc(e,t),(4186112&t)===t)break;for(r=e.eventTimes,o=-1;0<t;){var l=31-Yn(t);i=1<<l,(l=r[l])>o&&(o=l),t&=~i}if(t=o,10<(t=(120>(t=Go()-t)?120:480>t?480:1080>t?1080:1920>t?1920:3e3>t?3e3:4320>t?4320:1960*Pl(t/1960))-t)){e.timeoutHandle=Yr(jc.bind(null,e),t);break}jc(e);break;default:throw Error(a(329))}}return bc(e,Go()),e.callbackNode===n?vc.bind(null,e):null}function mc(e,n){for(n&=~Gl,n&=~Wl,e.suspendedLanes|=n,e.pingedLanes&=~n,e=e.expirationTimes;0<n;){var t=31-Yn(n),r=1<<t;e[t]=-1,n&=~r}}function yc(e){if(48&jl)throw Error(a(327));if(Rc(),e===zl&&0!==(e.expiredLanes&Rl)){var n=Rl,t=Oc(e,n);0!==(Hl&Wl)&&(t=Oc(e,n=Fn(e,n)))}else t=Oc(e,n=Fn(e,0));if(0!==e.tag&&2===t&&(jl|=64,e.hydrate&&(e.hydrate=!1,Vr(e.containerInfo)),0!==(n=Ln(e))&&(t=Oc(e,n))),1===t)throw t=Ll,Sc(e,0),mc(e,n),bc(e,Go()),t;return e.finishedWork=e.current.alternate,e.finishedLanes=n,jc(e),bc(e,Go()),null}function Ec(e,n){var t=jl;jl|=1;try{return e(n)}finally{0===(jl=t)&&($l(),Ko())}}function Cc(e,n){var t=jl;jl&=-2,jl|=8;try{return e(n)}finally{0===(jl=t)&&($l(),Ko())}}function wc(e,n){po(Nl,Ml),Ml|=n,Hl|=n}function xc(){Ml=Nl.current,uo(Nl)}function Sc(e,n){e.finishedWork=null,e.finishedLanes=0;var t=e.timeoutHandle;if(-1!==t&&(e.timeoutHandle=-1,qr(t)),null!==Dl)for(t=Dl.return;null!==t;){var r=t;switch(r.tag){case 1:null!=(r=r.type.childContextTypes)&&mo();break;case 3:Di(),uo(ho),uo(go),Qi();break;case 5:Mi(r);break;case 4:Di();break;case 13:case 19:uo(Ni);break;case 10:oi(r);break;case 23:case 24:xc()}t=t.return}zl=e,Dl=Vc(e.current,null),Rl=Ml=Hl=n,Fl=0,Ll=null,Gl=Wl=Ul=0}function _c(e,n){for(;;){var t=Dl;try{if(ri(),Xi.current=Ia,ra){for(var r=ea.memoizedState;null!==r;){var o=r.queue;null!==o&&(o.pending=null),r=r.next}ra=!1}if(Ji=0,ta=na=ea=null,oa=!1,Il.current=null,null===t||null===t.return){Fl=1,Ll=n,Dl=null;break}e:{var i=e,a=t.return,l=t,c=n;if(n=Rl,l.flags|=2048,l.firstEffect=l.lastEffect=null,null!==c&&\"object\"==typeof c&&\"function\"==typeof c.then){var s=c;if(!(2&l.mode)){var u=l.alternate;u?(l.updateQueue=u.updateQueue,l.memoizedState=u.memoizedState,l.lanes=u.lanes):(l.updateQueue=null,l.memoizedState=null)}var p=!!(1&Ni.current),f=a;do{var d;if(d=13===f.tag){var g=f.memoizedState;if(null!==g)d=null!==g.dehydrated;else{var h=f.memoizedProps;d=void 0!==h.fallback&&(!0!==h.unstable_avoidThisFallback||!p)}}if(d){var A=f.updateQueue;if(null===A){var b=new Set;b.add(s),f.updateQueue=b}else A.add(s);if(!(2&f.mode)){if(f.flags|=64,l.flags|=16384,l.flags&=-2981,1===l.tag)if(null===l.alternate)l.tag=17;else{var v=pi(-1,1);v.tag=2,fi(l,v)}l.lanes|=1;break e}c=void 0,l=n;var m=i.pingCache;if(null===m?(m=i.pingCache=new fl,c=new Set,m.set(s,c)):void 0===(c=m.get(s))&&(c=new Set,m.set(s,c)),!c.has(l)){c.add(l);var y=Uc.bind(null,i,s,l);s.then(y,y)}f.flags|=4096,f.lanes=n;break e}f=f.return}while(null!==f);c=Error((V(l.type)||\"A React component\")+\" suspended while rendering, but no fallback UI was specified.\\n\\nAdd a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.\")}5!==Fl&&(Fl=2),c=ul(c,l),f=a;do{switch(f.tag){case 3:i=c,f.flags|=4096,n&=-n,f.lanes|=n,di(f,dl(0,i,n));break e;case 1:i=c;var E=f.type,C=f.stateNode;if(!(64&f.flags||\"function\"!=typeof E.getDerivedStateFromError&&(null===C||\"function\"!=typeof C.componentDidCatch||null!==Jl&&Jl.has(C)))){f.flags|=4096,n&=-n,f.lanes|=n,di(f,gl(f,i,n));break e}}f=f.return}while(null!==f)}Ic(t)}catch(e){n=e,Dl===t&&null!==t&&(Dl=t=t.return);continue}break}}function kc(){var e=Tl.current;return Tl.current=Ia,null===e?Ia:e}function Oc(e,n){var t=jl;jl|=16;var r=kc();for(zl===e&&Rl===n||Sc(e,n);;)try{Bc();break}catch(n){_c(e,n)}if(ri(),jl=t,Tl.current=r,null!==Dl)throw Error(a(261));return zl=null,Rl=0,Fl}function Bc(){for(;null!==Dl;)Tc(Dl)}function Pc(){for(;null!==Dl&&!Bo();)Tc(Dl)}function Tc(e){var n=Kl(e.alternate,e,Ml);e.memoizedProps=e.pendingProps,null===n?Ic(e):Dl=n,Il.current=null}function Ic(e){var n=e;do{var t=n.alternate;if(e=n.return,2048&n.flags){if(null!==(t=sl(n)))return t.flags&=2047,void(Dl=t);null!==e&&(e.firstEffect=e.lastEffect=null,e.flags|=2048)}else{if(null!==(t=cl(t,n,Ml)))return void(Dl=t);if(24!==(t=n).tag&&23!==t.tag||null===t.memoizedState||1073741824&Ml||!(4&t.mode)){for(var r=0,o=t.child;null!==o;)r|=o.lanes|o.childLanes,o=o.sibling;t.childLanes=r}null!==e&&!(2048&e.flags)&&(null===e.firstEffect&&(e.firstEffect=n.firstEffect),null!==n.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=n.firstEffect),e.lastEffect=n.lastEffect),1<n.flags&&(null!==e.lastEffect?e.lastEffect.nextEffect=n:e.firstEffect=n,e.lastEffect=n))}if(null!==(n=n.sibling))return void(Dl=n);Dl=n=e}while(null!==n);0===Fl&&(Fl=5)}function jc(e){var n=Yo();return Vo(99,zc.bind(null,e,n)),null}function zc(e,n){do{Rc()}while(null!==nc);if(48&jl)throw Error(a(327));var t=e.finishedWork;if(null===t)return null;if(e.finishedWork=null,e.finishedLanes=0,t===e.current)throw Error(a(177));e.callbackNode=null;var r=t.lanes|t.childLanes,o=r,i=e.pendingLanes&~o;e.pendingLanes=o,e.suspendedLanes=0,e.pingedLanes=0,e.expiredLanes&=o,e.mutableReadLanes&=o,e.entangledLanes&=o,o=e.entanglements;for(var l=e.eventTimes,c=e.expirationTimes;0<i;){var s=31-Yn(i),u=1<<s;o[s]=0,l[s]=-1,c[s]=-1,i&=~u}if(null!==ic&&!(24&r)&&ic.has(e)&&ic.delete(e),e===zl&&(Dl=zl=null,Rl=0),1<t.flags?null!==t.lastEffect?(t.lastEffect.nextEffect=t,r=t.firstEffect):r=t:r=t.firstEffect,null!==r){if(o=jl,jl|=32,Il.current=null,Hr=Qn,br(l=Ar())){if(\"selectionStart\"in l)c={start:l.selectionStart,end:l.selectionEnd};else e:if(c=(c=l.ownerDocument)&&c.defaultView||window,(u=c.getSelection&&c.getSelection())&&0!==u.rangeCount){c=u.anchorNode,i=u.anchorOffset,s=u.focusNode,u=u.focusOffset;try{c.nodeType,s.nodeType}catch(e){c=null;break e}var p=0,f=-1,d=-1,g=0,h=0,A=l,b=null;n:for(;;){for(var v;A!==c||0!==i&&3!==A.nodeType||(f=p+i),A!==s||0!==u&&3!==A.nodeType||(d=p+u),3===A.nodeType&&(p+=A.nodeValue.length),null!==(v=A.firstChild);)b=A,A=v;for(;;){if(A===l)break n;if(b===c&&++g===i&&(f=p),b===s&&++h===u&&(d=p),null!==(v=A.nextSibling))break;b=(A=b).parentNode}A=v}c=-1===f||-1===d?null:{start:f,end:d}}else c=null;c=c||{start:0,end:0}}else c=null;Ur={focusedElem:l,selectionRange:c},Qn=!1,pc=null,fc=!1,Ql=r;do{try{Dc()}catch(e){if(null===Ql)throw Error(a(330));Hc(Ql,e),Ql=Ql.nextEffect}}while(null!==Ql);pc=null,Ql=r;do{try{for(l=e;null!==Ql;){var m=Ql.flags;if(16&m&&ve(Ql.stateNode,\"\"),128&m){var y=Ql.alternate;if(null!==y){var E=y.ref;null!==E&&(\"function\"==typeof E?E(null):E.current=null)}}switch(1038&m){case 2:wl(Ql),Ql.flags&=-3;break;case 6:wl(Ql),Ql.flags&=-3,kl(Ql.alternate,Ql);break;case 1024:Ql.flags&=-1025;break;case 1028:Ql.flags&=-1025,kl(Ql.alternate,Ql);break;case 4:kl(Ql.alternate,Ql);break;case 8:_l(l,c=Ql);var C=c.alternate;El(c),null!==C&&El(C)}Ql=Ql.nextEffect}}catch(e){if(null===Ql)throw Error(a(330));Hc(Ql,e),Ql=Ql.nextEffect}}while(null!==Ql);if(E=Ur,y=Ar(),m=E.focusedElem,l=E.selectionRange,y!==m&&m&&m.ownerDocument&&hr(m.ownerDocument.documentElement,m)){null!==l&&br(m)&&(y=l.start,void 0===(E=l.end)&&(E=y),\"selectionStart\"in m?(m.selectionStart=y,m.selectionEnd=Math.min(E,m.value.length)):(E=(y=m.ownerDocument||document)&&y.defaultView||window).getSelection&&(E=E.getSelection(),c=m.textContent.length,C=Math.min(l.start,c),l=void 0===l.end?C:Math.min(l.end,c),!E.extend&&C>l&&(c=l,l=C,C=c),c=gr(m,C),i=gr(m,l),c&&i&&(1!==E.rangeCount||E.anchorNode!==c.node||E.anchorOffset!==c.offset||E.focusNode!==i.node||E.focusOffset!==i.offset)&&((y=y.createRange()).setStart(c.node,c.offset),E.removeAllRanges(),C>l?(E.addRange(y),E.extend(i.node,i.offset)):(y.setEnd(i.node,i.offset),E.addRange(y))))),y=[];for(E=m;E=E.parentNode;)1===E.nodeType&&y.push({element:E,left:E.scrollLeft,top:E.scrollTop});for(\"function\"==typeof m.focus&&m.focus(),m=0;m<y.length;m++)(E=y[m]).element.scrollLeft=E.left,E.element.scrollTop=E.top}Qn=!!Hr,Ur=Hr=null,e.current=t,Ql=r;do{try{for(m=e;null!==Ql;){var w=Ql.flags;if(36&w&&vl(m,Ql.alternate,Ql),128&w){y=void 0;var x=Ql.ref;if(null!==x){var S=Ql.stateNode;Ql.tag,y=S,\"function\"==typeof x?x(y):x.current=y}}Ql=Ql.nextEffect}}catch(e){if(null===Ql)throw Error(a(330));Hc(Ql,e),Ql=Ql.nextEffect}}while(null!==Ql);Ql=null,Fo(),jl=o}else e.current=t;if(ec)ec=!1,nc=e,tc=n;else for(Ql=r;null!==Ql;)n=Ql.nextEffect,Ql.nextEffect=null,8&Ql.flags&&((w=Ql).sibling=null,w.stateNode=null),Ql=n;if(0===(r=e.pendingLanes)&&(Jl=null),1===r?e===lc?ac++:(ac=0,lc=e):ac=0,t=t.stateNode,So&&\"function\"==typeof So.onCommitFiberRoot)try{So.onCommitFiberRoot(xo,t,void 0,!(64&~t.current.flags))}catch(e){}if(bc(e,Go()),Xl)throw Xl=!1,e=Zl,Zl=null,e;return 8&jl||Ko(),null}function Dc(){for(;null!==Ql;){var e=Ql.alternate;fc||null===pc||(8&Ql.flags?en(Ql,pc)&&(fc=!0):13===Ql.tag&&Bl(e,Ql)&&en(Ql,pc)&&(fc=!0));var n=Ql.flags;256&n&&bl(e,Ql),!(512&n)||ec||(ec=!0,$o(97,(function(){return Rc(),null}))),Ql=Ql.nextEffect}}function Rc(){if(90!==tc){var e=97<tc?97:tc;return tc=90,Vo(e,Fc)}return!1}function Mc(e,n){rc.push(n,e),ec||(ec=!0,$o(97,(function(){return Rc(),null})))}function Nc(e,n){oc.push(n,e),ec||(ec=!0,$o(97,(function(){return Rc(),null})))}function Fc(){if(null===nc)return!1;var e=nc;if(nc=null,48&jl)throw Error(a(331));var n=jl;jl|=32;var t=oc;oc=[];for(var r=0;r<t.length;r+=2){var o=t[r],i=t[r+1],l=o.destroy;if(o.destroy=void 0,\"function\"==typeof l)try{l()}catch(e){if(null===i)throw Error(a(330));Hc(i,e)}}for(t=rc,rc=[],r=0;r<t.length;r+=2){o=t[r],i=t[r+1];try{var c=o.create;o.destroy=c()}catch(e){if(null===i)throw Error(a(330));Hc(i,e)}}for(c=e.current.firstEffect;null!==c;)e=c.nextEffect,c.nextEffect=null,8&c.flags&&(c.sibling=null,c.stateNode=null),c=e;return jl=n,Ko(),!0}function Lc(e,n,t){fi(e,n=dl(0,n=ul(t,n),1)),n=dc(),null!==(e=Ac(e,1))&&(Gn(e,1,n),bc(e,n))}function Hc(e,n){if(3===e.tag)Lc(e,e,n);else for(var t=e.return;null!==t;){if(3===t.tag){Lc(t,e,n);break}if(1===t.tag){var r=t.stateNode;if(\"function\"==typeof t.type.getDerivedStateFromError||\"function\"==typeof r.componentDidCatch&&(null===Jl||!Jl.has(r))){var o=gl(t,e=ul(n,e),1);if(fi(t,o),o=dc(),null!==(t=Ac(t,1)))Gn(t,1,o),bc(t,o);else if(\"function\"==typeof r.componentDidCatch&&(null===Jl||!Jl.has(r)))try{r.componentDidCatch(n,e)}catch(e){}break}}t=t.return}}function Uc(e,n,t){var r=e.pingCache;null!==r&&r.delete(n),n=dc(),e.pingedLanes|=e.suspendedLanes&t,zl===e&&(Rl&t)===t&&(4===Fl||3===Fl&&(62914560&Rl)===Rl&&500>Go()-ql?Sc(e,0):Gl|=t),bc(e,n)}function Wc(e,n){var t=e.stateNode;null!==t&&t.delete(n),0===(n=0)&&(2&(n=e.mode)?4&n?(0===sc&&(sc=Hl),0===(n=Un(62914560&~sc))&&(n=4194304)):n=99===Yo()?1:2:n=1),t=dc(),null!==(e=Ac(e,n))&&(Gn(e,n,t),bc(e,t))}function Gc(e,n,t,r){this.tag=e,this.key=t,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=n,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.flags=0,this.lastEffect=this.firstEffect=this.nextEffect=null,this.childLanes=this.lanes=0,this.alternate=null}function Yc(e,n,t,r){return new Gc(e,n,t,r)}function qc(e){return!(!(e=e.prototype)||!e.isReactComponent)}function Vc(e,n){var t=e.alternate;return null===t?((t=Yc(e.tag,n,e.key,e.mode)).elementType=e.elementType,t.type=e.type,t.stateNode=e.stateNode,t.alternate=e,e.alternate=t):(t.pendingProps=n,t.type=e.type,t.flags=0,t.nextEffect=null,t.firstEffect=null,t.lastEffect=null),t.childLanes=e.childLanes,t.lanes=e.lanes,t.child=e.child,t.memoizedProps=e.memoizedProps,t.memoizedState=e.memoizedState,t.updateQueue=e.updateQueue,n=e.dependencies,t.dependencies=null===n?null:{lanes:n.lanes,firstContext:n.firstContext},t.sibling=e.sibling,t.index=e.index,t.ref=e.ref,t}function $c(e,n,t,r,o,i){var l=2;if(r=e,\"function\"==typeof e)qc(e)&&(l=1);else if(\"string\"==typeof e)l=5;else e:switch(e){case x:return Kc(t.children,o,i,n);case R:l=8,o|=16;break;case S:l=8,o|=1;break;case _:return(e=Yc(12,t,n,8|o)).elementType=_,e.type=_,e.lanes=i,e;case P:return(e=Yc(13,t,n,o)).type=P,e.elementType=P,e.lanes=i,e;case T:return(e=Yc(19,t,n,o)).elementType=T,e.lanes=i,e;case M:return Qc(t,o,i,n);case N:return(e=Yc(24,t,n,o)).elementType=N,e.lanes=i,e;default:if(\"object\"==typeof e&&null!==e)switch(e.$$typeof){case k:l=10;break e;case O:l=9;break e;case B:l=11;break e;case I:l=14;break e;case j:l=16,r=null;break e;case z:l=22;break e}throw Error(a(130,null==e?e:typeof e,\"\"))}return(n=Yc(l,t,n,o)).elementType=e,n.type=r,n.lanes=i,n}function Kc(e,n,t,r){return(e=Yc(7,e,r,n)).lanes=t,e}function Qc(e,n,t,r){return(e=Yc(23,e,r,n)).elementType=M,e.lanes=t,e}function Xc(e,n,t){return(e=Yc(6,e,null,n)).lanes=t,e}function Zc(e,n,t){return(n=Yc(4,null!==e.children?e.children:[],e.key,n)).lanes=t,n.stateNode={containerInfo:e.containerInfo,pendingChildren:null,implementation:e.implementation},n}function Jc(e,n,t){this.tag=n,this.containerInfo=e,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.pendingContext=this.context=null,this.hydrate=t,this.callbackNode=null,this.callbackPriority=0,this.eventTimes=Wn(0),this.expirationTimes=Wn(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=Wn(0),this.mutableSourceEagerHydrationData=null}function es(e,n,t,r){var o=n.current,i=dc(),l=gc(o);e:if(t){n:{if(Qe(t=t._reactInternals)!==t||1!==t.tag)throw Error(a(170));var c=t;do{switch(c.tag){case 3:c=c.stateNode.context;break n;case 1:if(vo(c.type)){c=c.stateNode.__reactInternalMemoizedMergedChildContext;break n}}c=c.return}while(null!==c);throw Error(a(171))}if(1===t.tag){var s=t.type;if(vo(s)){t=Eo(t,s,c);break e}}t=c}else t=fo;return null===n.context?n.context=t:n.pendingContext=t,(n=pi(i,l)).payload={element:e},null!==(r=void 0===r?null:r)&&(n.callback=r),fi(o,n),hc(o,l,i),l}function ns(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function ts(e,n){if(null!==(e=e.memoizedState)&&null!==e.dehydrated){var t=e.retryLane;e.retryLane=0!==t&&t<n?t:n}}function rs(e,n){ts(e,n),(e=e.alternate)&&ts(e,n)}function os(e,n,t){var r=null!=t&&null!=t.hydrationOptions&&t.hydrationOptions.mutableSources||null;if(t=new Jc(e,n,null!=t&&!0===t.hydrate),n=Yc(3,null,null,2===n?7:1===n?3:0),t.current=n,n.stateNode=t,si(n),e[eo]=t.current,Ir(8===e.nodeType?e.parentNode:e),r)for(e=0;e<r.length;e++){var o=(n=r[e])._getVersion;o=o(n._source),null==t.mutableSourceEagerHydrationData?t.mutableSourceEagerHydrationData=[n,o]:t.mutableSourceEagerHydrationData.push(n,o)}this._internalRoot=t}function is(e){return!(!e||1!==e.nodeType&&9!==e.nodeType&&11!==e.nodeType&&(8!==e.nodeType||\" react-mount-point-unstable \"!==e.nodeValue))}function as(e,n,t,r,o){var i=t._reactRootContainer;if(i){var a=i._internalRoot;if(\"function\"==typeof o){var l=o;o=function(){var e=ns(a);l.call(e)}}es(n,a,e,o)}else{if(i=t._reactRootContainer=function(e,n){if(n||(n=!(!(n=e?9===e.nodeType?e.documentElement:e.firstChild:null)||1!==n.nodeType||!n.hasAttribute(\"data-reactroot\"))),!n)for(var t;t=e.lastChild;)e.removeChild(t);return new os(e,0,n?{hydrate:!0}:void 0)}(t,r),a=i._internalRoot,\"function\"==typeof o){var c=o;o=function(){var e=ns(a);c.call(e)}}Cc((function(){es(n,a,e,o)}))}return ns(a)}function ls(e,n){var t=2<arguments.length&&void 0!==arguments[2]?arguments[2]:null;if(!is(n))throw Error(a(200));return function(e,n,t){var r=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null;return{$$typeof:w,key:null==r?null:\"\"+r,children:e,containerInfo:n,implementation:t}}(e,n,null,t)}Kl=function(e,n,t){var r=n.lanes;if(null!==e)if(e.memoizedProps!==n.pendingProps||ho.current)Ma=!0;else{if(0===(t&r)){switch(Ma=!1,n.tag){case 3:Va(n),$i();break;case 5:Ri(n);break;case 1:vo(n.type)&&Co(n);break;case 4:zi(n,n.stateNode.containerInfo);break;case 10:r=n.memoizedProps.value;var o=n.type._context;po(Jo,o._currentValue),o._currentValue=r;break;case 13:if(null!==n.memoizedState)return 0!==(t&n.child.childLanes)?Ja(e,n,t):(po(Ni,1&Ni.current),null!==(n=al(e,n,t))?n.sibling:null);po(Ni,1&Ni.current);break;case 19:if(r=0!==(t&n.childLanes),64&e.flags){if(r)return il(e,n,t);n.flags|=64}if(null!==(o=n.memoizedState)&&(o.rendering=null,o.tail=null,o.lastEffect=null),po(Ni,Ni.current),r)break;return null;case 23:case 24:return n.lanes=0,Ua(e,n,t)}return al(e,n,t)}Ma=!!(16384&e.flags)}else Ma=!1;switch(n.lanes=0,n.tag){case 2:if(r=n.type,null!==e&&(e.alternate=null,n.alternate=null,n.flags|=2),e=n.pendingProps,o=bo(n,go.current),ai(n,t),o=la(null,n,r,e,o,t),n.flags|=1,\"object\"==typeof o&&null!==o&&\"function\"==typeof o.render&&void 0===o.$$typeof){if(n.tag=1,n.memoizedState=null,n.updateQueue=null,vo(r)){var i=!0;Co(n)}else i=!1;n.memoizedState=null!==o.state&&void 0!==o.state?o.state:null,si(n);var l=r.getDerivedStateFromProps;\"function\"==typeof l&&bi(n,r,l,e),o.updater=vi,n.stateNode=o,o._reactInternals=n,Ci(n,r,e,t),n=qa(null,n,r,!0,i,t)}else n.tag=0,Na(null,n,o,t),n=n.child;return n;case 16:o=n.elementType;e:{switch(null!==e&&(e.alternate=null,n.alternate=null,n.flags|=2),e=n.pendingProps,o=(i=o._init)(o._payload),n.type=o,i=n.tag=function(e){if(\"function\"==typeof e)return qc(e)?1:0;if(null!=e){if((e=e.$$typeof)===B)return 11;if(e===I)return 14}return 2}(o),e=Zo(o,e),i){case 0:n=Ga(null,n,o,e,t);break e;case 1:n=Ya(null,n,o,e,t);break e;case 11:n=Fa(null,n,o,e,t);break e;case 14:n=La(null,n,o,Zo(o.type,e),r,t);break e}throw Error(a(306,o,\"\"))}return n;case 0:return r=n.type,o=n.pendingProps,Ga(e,n,r,o=n.elementType===r?o:Zo(r,o),t);case 1:return r=n.type,o=n.pendingProps,Ya(e,n,r,o=n.elementType===r?o:Zo(r,o),t);case 3:if(Va(n),r=n.updateQueue,null===e||null===r)throw Error(a(282));if(r=n.pendingProps,o=null!==(o=n.memoizedState)?o.element:null,ui(e,n),gi(n,r,null,t),(r=n.memoizedState.element)===o)$i(),n=al(e,n,t);else{if((i=(o=n.stateNode).hydrate)&&(Hi=$r(n.stateNode.containerInfo.firstChild),Li=n,i=Ui=!0),i){if(null!=(e=o.mutableSourceEagerHydrationData))for(o=0;o<e.length;o+=2)(i=e[o])._workInProgressVersionPrimary=e[o+1],Ki.push(i);for(t=Oi(n,null,r,t),n.child=t;t;)t.flags=-3&t.flags|1024,t=t.sibling}else Na(e,n,r,t),$i();n=n.child}return n;case 5:return Ri(n),null===e&&Yi(n),r=n.type,o=n.pendingProps,i=null!==e?e.memoizedProps:null,l=o.children,Gr(r,o)?l=null:null!==i&&Gr(r,i)&&(n.flags|=16),Wa(e,n),Na(e,n,l,t),n.child;case 6:return null===e&&Yi(n),null;case 13:return Ja(e,n,t);case 4:return zi(n,n.stateNode.containerInfo),r=n.pendingProps,null===e?n.child=ki(n,null,r,t):Na(e,n,r,t),n.child;case 11:return r=n.type,o=n.pendingProps,Fa(e,n,r,o=n.elementType===r?o:Zo(r,o),t);case 7:return Na(e,n,n.pendingProps,t),n.child;case 8:case 12:return Na(e,n,n.pendingProps.children,t),n.child;case 10:e:{r=n.type._context,o=n.pendingProps,l=n.memoizedProps,i=o.value;var c=n.type._context;if(po(Jo,c._currentValue),c._currentValue=i,null!==l)if(c=l.value,0===(i=ur(c,i)?0:0|(\"function\"==typeof r._calculateChangedBits?r._calculateChangedBits(c,i):1073741823))){if(l.children===o.children&&!ho.current){n=al(e,n,t);break e}}else for(null!==(c=n.child)&&(c.return=n);null!==c;){var s=c.dependencies;if(null!==s){l=c.child;for(var u=s.firstContext;null!==u;){if(u.context===r&&0!==(u.observedBits&i)){1===c.tag&&((u=pi(-1,t&-t)).tag=2,fi(c,u)),c.lanes|=t,null!==(u=c.alternate)&&(u.lanes|=t),ii(c.return,t),s.lanes|=t;break}u=u.next}}else l=10===c.tag&&c.type===n.type?null:c.child;if(null!==l)l.return=c;else for(l=c;null!==l;){if(l===n){l=null;break}if(null!==(c=l.sibling)){c.return=l.return,l=c;break}l=l.return}c=l}Na(e,n,o.children,t),n=n.child}return n;case 9:return o=n.type,r=(i=n.pendingProps).children,ai(n,t),r=r(o=li(o,i.unstable_observedBits)),n.flags|=1,Na(e,n,r,t),n.child;case 14:return i=Zo(o=n.type,n.pendingProps),La(e,n,o,i=Zo(o.type,i),r,t);case 15:return Ha(e,n,n.type,n.pendingProps,r,t);case 17:return r=n.type,o=n.pendingProps,o=n.elementType===r?o:Zo(r,o),null!==e&&(e.alternate=null,n.alternate=null,n.flags|=2),n.tag=1,vo(r)?(e=!0,Co(n)):e=!1,ai(n,t),yi(n,r,o),Ci(n,r,o,t),qa(null,n,r,!0,e,t);case 19:return il(e,n,t);case 23:case 24:return Ua(e,n,t)}throw Error(a(156,n.tag))},os.prototype.render=function(e){es(e,this._internalRoot,null,null)},os.prototype.unmount=function(){var e=this._internalRoot,n=e.containerInfo;es(null,e,null,(function(){n[eo]=null}))},nn=function(e){13===e.tag&&(hc(e,4,dc()),rs(e,4))},tn=function(e){13===e.tag&&(hc(e,67108864,dc()),rs(e,67108864))},rn=function(e){if(13===e.tag){var n=dc(),t=gc(e);hc(e,t,n),rs(e,t)}},on=function(e,n){return n()},ke=function(e,n,t){switch(n){case\"input\":if(te(e,t),n=t.name,\"radio\"===t.type&&null!=n){for(t=e;t.parentNode;)t=t.parentNode;for(t=t.querySelectorAll(\"input[name=\"+JSON.stringify(\"\"+n)+'][type=\"radio\"]'),n=0;n<t.length;n++){var r=t[n];if(r!==e&&r.form===e.form){var o=io(r);if(!o)throw Error(a(90));X(r),te(r,o)}}}break;case\"textarea\":se(e,t);break;case\"select\":null!=(n=t.value)&&ae(e,!!t.multiple,n,!1)}},je=Ec,ze=function(e,n,t,r,o){var i=jl;jl|=4;try{return Vo(98,e.bind(null,n,t,r,o))}finally{0===(jl=i)&&($l(),Ko())}},De=function(){!(49&jl)&&(function(){if(null!==ic){var e=ic;ic=null,e.forEach((function(e){e.expiredLanes|=24&e.pendingLanes,bc(e,Go())}))}Ko()}(),Rc())},Re=function(e,n){var t=jl;jl|=2;try{return e(n)}finally{0===(jl=t)&&($l(),Ko())}};var cs={Events:[ro,oo,io,Te,Ie,Rc,{current:!1}]},ss={findFiberByHostInstance:to,bundleType:0,version:\"17.0.2\",rendererPackageName:\"react-dom\"},us={bundleType:ss.bundleType,version:ss.version,rendererPackageName:ss.rendererPackageName,rendererConfig:ss.rendererConfig,overrideHookState:null,overrideHookStateDeletePath:null,overrideHookStateRenamePath:null,overrideProps:null,overridePropsDeletePath:null,overridePropsRenamePath:null,setSuspenseHandler:null,scheduleUpdate:null,currentDispatcherRef:E.ReactCurrentDispatcher,findHostInstanceByFiber:function(e){return null===(e=Je(e))?null:e.stateNode},findFiberByHostInstance:ss.findFiberByHostInstance||function(){return null},findHostInstancesForRefresh:null,scheduleRefresh:null,scheduleRoot:null,setRefreshHandler:null,getCurrentFiber:null};if(\"undefined\"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__){var ps=__REACT_DEVTOOLS_GLOBAL_HOOK__;if(!ps.isDisabled&&ps.supportsFiber)try{xo=ps.inject(us),So=ps}catch(Ae){}}n.createPortal=ls,n.render=function(e,n,t){if(!is(n))throw Error(a(200));return as(null,e,n,!1,t)}},961:(e,n,t)=>{\"use strict\";!function e(){if(\"undefined\"!=typeof __REACT_DEVTOOLS_GLOBAL_HOOK__&&\"function\"==typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE)try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(e)}catch(e){console.error(e)}}(),e.exports=t(2551)},1020:(e,n,t)=>{\"use strict\";\n/** @license React v17.0.2\n * react-jsx-runtime.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\nt(5228);var r=t(6540),o=60103;if(\"function\"==typeof Symbol&&Symbol.for){var i=Symbol.for;o=i(\"react.element\"),i(\"react.fragment\")}var a=r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,l=Object.prototype.hasOwnProperty,c={key:!0,ref:!0,__self:!0,__source:!0};function s(e,n,t){var r,i={},s=null,u=null;for(r in void 0!==t&&(s=\"\"+t),void 0!==n.key&&(s=\"\"+n.key),void 0!==n.ref&&(u=n.ref),n)l.call(n,r)&&!c.hasOwnProperty(r)&&(i[r]=n[r]);if(e&&e.defaultProps)for(r in n=e.defaultProps)void 0===i[r]&&(i[r]=n[r]);return{$$typeof:o,type:e,key:s,ref:u,props:i,_owner:a.current}}n.jsx=s,n.jsxs=s},5287:(e,n,t)=>{\"use strict\";\n/** @license React v17.0.2\n * react.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */var r=t(5228),o=60103,i=60106;n.Fragment=60107,n.StrictMode=60108,n.Profiler=60114;var a=60109,l=60110,c=60112;n.Suspense=60113;var s=60115,u=60116;if(\"function\"==typeof Symbol&&Symbol.for){var p=Symbol.for;o=p(\"react.element\"),i=p(\"react.portal\"),n.Fragment=p(\"react.fragment\"),n.StrictMode=p(\"react.strict_mode\"),n.Profiler=p(\"react.profiler\"),a=p(\"react.provider\"),l=p(\"react.context\"),c=p(\"react.forward_ref\"),n.Suspense=p(\"react.suspense\"),s=p(\"react.memo\"),u=p(\"react.lazy\")}var f=\"function\"==typeof Symbol&&Symbol.iterator;function d(e){for(var n=\"https://reactjs.org/docs/error-decoder.html?invariant=\"+e,t=1;t<arguments.length;t++)n+=\"&args[]=\"+encodeURIComponent(arguments[t]);return\"Minified React error #\"+e+\"; visit \"+n+\" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.\"}var g={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},h={};function A(e,n,t){this.props=e,this.context=n,this.refs=h,this.updater=t||g}function b(){}function v(e,n,t){this.props=e,this.context=n,this.refs=h,this.updater=t||g}A.prototype.isReactComponent={},A.prototype.setState=function(e,n){if(\"object\"!=typeof e&&\"function\"!=typeof e&&null!=e)throw Error(d(85));this.updater.enqueueSetState(this,e,n,\"setState\")},A.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,\"forceUpdate\")},b.prototype=A.prototype;var m=v.prototype=new b;m.constructor=v,r(m,A.prototype),m.isPureReactComponent=!0;var y={current:null},E=Object.prototype.hasOwnProperty,C={key:!0,ref:!0,__self:!0,__source:!0};function w(e,n,t){var r,i={},a=null,l=null;if(null!=n)for(r in void 0!==n.ref&&(l=n.ref),void 0!==n.key&&(a=\"\"+n.key),n)E.call(n,r)&&!C.hasOwnProperty(r)&&(i[r]=n[r]);var c=arguments.length-2;if(1===c)i.children=t;else if(1<c){for(var s=Array(c),u=0;u<c;u++)s[u]=arguments[u+2];i.children=s}if(e&&e.defaultProps)for(r in c=e.defaultProps)void 0===i[r]&&(i[r]=c[r]);return{$$typeof:o,type:e,key:a,ref:l,props:i,_owner:y.current}}function x(e){return\"object\"==typeof e&&null!==e&&e.$$typeof===o}var S=/\\/+/g;function _(e,n){return\"object\"==typeof e&&null!==e&&null!=e.key?function(e){var n={\"=\":\"=0\",\":\":\"=2\"};return\"$\"+e.replace(/[=:]/g,(function(e){return n[e]}))}(\"\"+e.key):n.toString(36)}function k(e,n,t,r,a){var l=typeof e;\"undefined\"!==l&&\"boolean\"!==l||(e=null);var c=!1;if(null===e)c=!0;else switch(l){case\"string\":case\"number\":c=!0;break;case\"object\":switch(e.$$typeof){case o:case i:c=!0}}if(c)return a=a(c=e),e=\"\"===r?\".\"+_(c,0):r,Array.isArray(a)?(t=\"\",null!=e&&(t=e.replace(S,\"$&/\")+\"/\"),k(a,n,t,\"\",(function(e){return e}))):null!=a&&(x(a)&&(a=function(e,n){return{$$typeof:o,type:e.type,key:n,ref:e.ref,props:e.props,_owner:e._owner}}(a,t+(!a.key||c&&c.key===a.key?\"\":(\"\"+a.key).replace(S,\"$&/\")+\"/\")+e)),n.push(a)),1;if(c=0,r=\"\"===r?\".\":r+\":\",Array.isArray(e))for(var s=0;s<e.length;s++){var u=r+_(l=e[s],s);c+=k(l,n,t,u,a)}else if(u=function(e){return null===e||\"object\"!=typeof e?null:\"function\"==typeof(e=f&&e[f]||e[\"@@iterator\"])?e:null}(e),\"function\"==typeof u)for(e=u.call(e),s=0;!(l=e.next()).done;)c+=k(l=l.value,n,t,u=r+_(l,s++),a);else if(\"object\"===l)throw n=\"\"+e,Error(d(31,\"[object Object]\"===n?\"object with keys {\"+Object.keys(e).join(\", \")+\"}\":n));return c}function O(e,n,t){if(null==e)return e;var r=[],o=0;return k(e,r,\"\",\"\",(function(e){return n.call(t,e,o++)})),r}function B(e){if(-1===e._status){var n=e._result;n=n(),e._status=0,e._result=n,n.then((function(n){0===e._status&&(n=n.default,e._status=1,e._result=n)}),(function(n){0===e._status&&(e._status=2,e._result=n)}))}if(1===e._status)return e._result;throw e._result}var P={current:null};function T(){var e=P.current;if(null===e)throw Error(d(321));return e}var I={ReactCurrentDispatcher:P,ReactCurrentBatchConfig:{transition:0},ReactCurrentOwner:y,IsSomeRendererActing:{current:!1},assign:r};n.Children={map:O,forEach:function(e,n,t){O(e,(function(){n.apply(this,arguments)}),t)},count:function(e){var n=0;return O(e,(function(){n++})),n},toArray:function(e){return O(e,(function(e){return e}))||[]},only:function(e){if(!x(e))throw Error(d(143));return e}},n.Component=A,n.PureComponent=v,n.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=I,n.cloneElement=function(e,n,t){if(null==e)throw Error(d(267,e));var i=r({},e.props),a=e.key,l=e.ref,c=e._owner;if(null!=n){if(void 0!==n.ref&&(l=n.ref,c=y.current),void 0!==n.key&&(a=\"\"+n.key),e.type&&e.type.defaultProps)var s=e.type.defaultProps;for(u in n)E.call(n,u)&&!C.hasOwnProperty(u)&&(i[u]=void 0===n[u]&&void 0!==s?s[u]:n[u])}var u=arguments.length-2;if(1===u)i.children=t;else if(1<u){s=Array(u);for(var p=0;p<u;p++)s[p]=arguments[p+2];i.children=s}return{$$typeof:o,type:e.type,key:a,ref:l,props:i,_owner:c}},n.createContext=function(e,n){return void 0===n&&(n=null),(e={$$typeof:l,_calculateChangedBits:n,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:a,_context:e},e.Consumer=e},n.createElement=w,n.createFactory=function(e){var n=w.bind(null,e);return n.type=e,n},n.createRef=function(){return{current:null}},n.forwardRef=function(e){return{$$typeof:c,render:e}},n.isValidElement=x,n.lazy=function(e){return{$$typeof:u,_payload:{_status:-1,_result:e},_init:B}},n.memo=function(e,n){return{$$typeof:s,type:e,compare:void 0===n?null:n}},n.useCallback=function(e,n){return T().useCallback(e,n)},n.useContext=function(e,n){return T().useContext(e,n)},n.useDebugValue=function(){},n.useEffect=function(e,n){return T().useEffect(e,n)},n.useImperativeHandle=function(e,n,t){return T().useImperativeHandle(e,n,t)},n.useLayoutEffect=function(e,n){return T().useLayoutEffect(e,n)},n.useMemo=function(e,n){return T().useMemo(e,n)},n.useReducer=function(e,n,t){return T().useReducer(e,n,t)},n.useRef=function(e){return T().useRef(e)},n.useState=function(e){return T().useState(e)},n.version=\"17.0.2\"},6540:(e,n,t)=>{\"use strict\";e.exports=t(5287)},4848:(e,n,t)=>{\"use strict\";e.exports=t(1020)},7675:(e,n,t)=>{\"use strict\";var r=t(3206),o=t(9675),i=Object;e.exports=r((function(){if(null==this||this!==i(this))throw new o(\"RegExp.prototype.flags getter called on non-object\");var e=\"\";return this.hasIndices&&(e+=\"d\"),this.global&&(e+=\"g\"),this.ignoreCase&&(e+=\"i\"),this.multiline&&(e+=\"m\"),this.dotAll&&(e+=\"s\"),this.unicode&&(e+=\"u\"),this.unicodeSets&&(e+=\"v\"),this.sticky&&(e+=\"y\"),e}),\"get flags\",!0)},1589:(e,n,t)=>{\"use strict\";var r=t(8452),o=t(487),i=t(7675),a=t(5330),l=t(3984),c=o(a());r(c,{getPolyfill:a,implementation:i,shim:l}),e.exports=c},5330:(e,n,t)=>{\"use strict\";var r=t(7675),o=t(8452).supportsDescriptors,i=Object.getOwnPropertyDescriptor;e.exports=function(){if(o&&\"gim\"===/a/gim.flags){var e=i(RegExp.prototype,\"flags\");if(e&&\"function\"==typeof e.get&&\"dotAll\"in RegExp.prototype&&\"hasIndices\"in RegExp.prototype){var n=\"\",t={};if(Object.defineProperty(t,\"hasIndices\",{get:function(){n+=\"d\"}}),Object.defineProperty(t,\"sticky\",{get:function(){n+=\"y\"}}),e.get.call(t),\"dy\"===n)return e.get}}return r}},3984:(e,n,t)=>{\"use strict\";var r=t(8452).supportsDescriptors,o=t(5330),i=t(5795),a=Object.defineProperty,l=t(9383),c=t(3628),s=/a/;e.exports=function(){if(!r||!c)throw new l(\"RegExp.prototype.flags requires a true ES5 environment that supports property descriptors\");var e=o(),n=c(s),t=i(n,\"flags\");return t&&t.get===e||a(n,\"flags\",{configurable:!0,enumerable:!1,get:e}),e}},9721:(e,n,t)=>{\"use strict\";var r=t(6556),o=t(4035),i=r(\"RegExp.prototype.exec\"),a=t(9675);e.exports=function(e){if(!o(e))throw new a(\"`regex` must be a RegExp\");return function(n){return null!==i(e,n)}}},7463:(e,n)=>{\"use strict\";\n/** @license React v0.20.2\n * scheduler.production.min.js\n *\n * Copyright (c) Facebook, Inc. and its affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */var t,r,o,i;if(\"object\"==typeof performance&&\"function\"==typeof performance.now){var a=performance;n.unstable_now=function(){return a.now()}}else{var l=Date,c=l.now();n.unstable_now=function(){return l.now()-c}}if(\"undefined\"==typeof window||\"function\"!=typeof MessageChannel){var s=null,u=null,p=function(){if(null!==s)try{var e=n.unstable_now();s(!0,e),s=null}catch(e){throw setTimeout(p,0),e}};t=function(e){null!==s?setTimeout(t,0,e):(s=e,setTimeout(p,0))},r=function(e,n){u=setTimeout(e,n)},o=function(){clearTimeout(u)},n.unstable_shouldYield=function(){return!1},i=n.unstable_forceFrameRate=function(){}}else{var f=window.setTimeout,d=window.clearTimeout;if(\"undefined\"!=typeof console){var g=window.cancelAnimationFrame;\"function\"!=typeof window.requestAnimationFrame&&console.error(\"This browser doesn't support requestAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills\"),\"function\"!=typeof g&&console.error(\"This browser doesn't support cancelAnimationFrame. Make sure that you load a polyfill in older browsers. https://reactjs.org/link/react-polyfills\")}var h=!1,A=null,b=-1,v=5,m=0;n.unstable_shouldYield=function(){return n.unstable_now()>=m},i=function(){},n.unstable_forceFrameRate=function(e){0>e||125<e?console.error(\"forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported\"):v=0<e?Math.floor(1e3/e):5};var y=new MessageChannel,E=y.port2;y.port1.onmessage=function(){if(null!==A){var e=n.unstable_now();m=e+v;try{A(!0,e)?E.postMessage(null):(h=!1,A=null)}catch(e){throw E.postMessage(null),e}}else h=!1},t=function(e){A=e,h||(h=!0,E.postMessage(null))},r=function(e,t){b=f((function(){e(n.unstable_now())}),t)},o=function(){d(b),b=-1}}function C(e,n){var t=e.length;e.push(n);e:for(;;){var r=t-1>>>1,o=e[r];if(!(void 0!==o&&0<S(o,n)))break e;e[r]=n,e[t]=o,t=r}}function w(e){return void 0===(e=e[0])?null:e}function x(e){var n=e[0];if(void 0!==n){var t=e.pop();if(t!==n){e[0]=t;e:for(var r=0,o=e.length;r<o;){var i=2*(r+1)-1,a=e[i],l=i+1,c=e[l];if(void 0!==a&&0>S(a,t))void 0!==c&&0>S(c,a)?(e[r]=c,e[l]=t,r=l):(e[r]=a,e[i]=t,r=i);else{if(!(void 0!==c&&0>S(c,t)))break e;e[r]=c,e[l]=t,r=l}}}return n}return null}function S(e,n){var t=e.sortIndex-n.sortIndex;return 0!==t?t:e.id-n.id}var _=[],k=[],O=1,B=null,P=3,T=!1,I=!1,j=!1;function z(e){for(var n=w(k);null!==n;){if(null===n.callback)x(k);else{if(!(n.startTime<=e))break;x(k),n.sortIndex=n.expirationTime,C(_,n)}n=w(k)}}function D(e){if(j=!1,z(e),!I)if(null!==w(_))I=!0,t(R);else{var n=w(k);null!==n&&r(D,n.startTime-e)}}function R(e,t){I=!1,j&&(j=!1,o()),T=!0;var i=P;try{for(z(t),B=w(_);null!==B&&(!(B.expirationTime>t)||e&&!n.unstable_shouldYield());){var a=B.callback;if(\"function\"==typeof a){B.callback=null,P=B.priorityLevel;var l=a(B.expirationTime<=t);t=n.unstable_now(),\"function\"==typeof l?B.callback=l:B===w(_)&&x(_),z(t)}else x(_);B=w(_)}if(null!==B)var c=!0;else{var s=w(k);null!==s&&r(D,s.startTime-t),c=!1}return c}finally{B=null,P=i,T=!1}}var M=i;n.unstable_IdlePriority=5,n.unstable_ImmediatePriority=1,n.unstable_LowPriority=4,n.unstable_NormalPriority=3,n.unstable_Profiling=null,n.unstable_UserBlockingPriority=2,n.unstable_cancelCallback=function(e){e.callback=null},n.unstable_continueExecution=function(){I||T||(I=!0,t(R))},n.unstable_getCurrentPriorityLevel=function(){return P},n.unstable_getFirstCallbackNode=function(){return w(_)},n.unstable_next=function(e){switch(P){case 1:case 2:case 3:var n=3;break;default:n=P}var t=P;P=n;try{return e()}finally{P=t}},n.unstable_pauseExecution=function(){},n.unstable_requestPaint=M,n.unstable_runWithPriority=function(e,n){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var t=P;P=e;try{return n()}finally{P=t}},n.unstable_scheduleCallback=function(e,i,a){var l=n.unstable_now();switch(\"object\"==typeof a&&null!==a?a=\"number\"==typeof(a=a.delay)&&0<a?l+a:l:a=l,e){case 1:var c=-1;break;case 2:c=250;break;case 5:c=1073741823;break;case 4:c=1e4;break;default:c=5e3}return e={id:O++,callback:i,priorityLevel:e,startTime:a,expirationTime:c=a+c,sortIndex:-1},a>l?(e.sortIndex=a,C(k,e),null===w(_)&&e===w(k)&&(j?o():j=!0,r(D,a-l))):(e.sortIndex=c,C(_,e),I||T||(I=!0,t(R))),e},n.unstable_wrapCallback=function(e){var n=P;return function(){var t=P;P=n;try{return e.apply(this,arguments)}finally{P=t}}}},9982:(e,n,t)=>{\"use strict\";e.exports=t(7463)},6897:(e,n,t)=>{\"use strict\";var r=t(453),o=t(41),i=t(592)(),a=t(5795),l=t(9675),c=r(\"%Math.floor%\");e.exports=function(e,n){if(\"function\"!=typeof e)throw new l(\"`fn` is not a function\");if(\"number\"!=typeof n||n<0||n>4294967295||c(n)!==n)throw new l(\"`length` must be a positive 32-bit integer\");var t=arguments.length>2&&!!arguments[2],r=!0,s=!0;if(\"length\"in e&&a){var u=a(e,\"length\");u&&!u.configurable&&(r=!1),u&&!u.writable&&(s=!1)}return(r||s||!t)&&(i?o(e,\"length\",n,!0,!0):o(e,\"length\",n)),e}},3206:(e,n,t)=>{\"use strict\";var r=t(41),o=t(592)(),i=t(4462).functionsHaveConfigurableNames(),a=t(9675);e.exports=function(e,n){if(\"function\"!=typeof e)throw new a(\"`fn` is not a function\");return arguments.length>2&&!!arguments[2]&&!i||(o?r(e,\"name\",n,!0,!0):r(e,\"name\",n)),e}},4803:(e,n,t)=>{\"use strict\";var r=t(8859),o=t(9675),i=function(e,n,t){for(var r,o=e;null!=(r=o.next);o=r)if(r.key===n)return o.next=r.next,t||(r.next=e.next,e.next=r),r};e.exports=function(){var e,n={assert:function(e){if(!n.has(e))throw new o(\"Side channel does not contain \"+r(e))},delete:function(n){var t=e&&e.next,r=function(e,n){if(e)return i(e,n,!0)}(e,n);return r&&t&&t===r&&(e=void 0),!!r},get:function(n){return function(e,n){if(e){var t=i(e,n);return t&&t.value}}(e,n)},has:function(n){return function(e,n){return!!e&&!!i(e,n)}(e,n)},set:function(n,t){e||(e={next:void 0}),function(e,n,t){var r=i(e,n);r?r.value=t:e.next={key:n,next:e.next,value:t}}(e,n,t)}};return n}},507:(e,n,t)=>{\"use strict\";var r=t(453),o=t(6556),i=t(8859),a=t(9675),l=r(\"%Map%\",!0),c=o(\"Map.prototype.get\",!0),s=o(\"Map.prototype.set\",!0),u=o(\"Map.prototype.has\",!0),p=o(\"Map.prototype.delete\",!0),f=o(\"Map.prototype.size\",!0);e.exports=!!l&&function(){var e,n={assert:function(e){if(!n.has(e))throw new a(\"Side channel does not contain \"+i(e))},delete:function(n){if(e){var t=p(e,n);return 0===f(e)&&(e=void 0),t}return!1},get:function(n){if(e)return c(e,n)},has:function(n){return!!e&&u(e,n)},set:function(n,t){e||(e=new l),s(e,n,t)}};return n}},2271:(e,n,t)=>{\"use strict\";var r=t(453),o=t(6556),i=t(8859),a=t(507),l=t(9675),c=r(\"%WeakMap%\",!0),s=o(\"WeakMap.prototype.get\",!0),u=o(\"WeakMap.prototype.set\",!0),p=o(\"WeakMap.prototype.has\",!0),f=o(\"WeakMap.prototype.delete\",!0);e.exports=c?function(){var e,n,t={assert:function(e){if(!t.has(e))throw new l(\"Side channel does not contain \"+i(e))},delete:function(t){if(c&&t&&(\"object\"==typeof t||\"function\"==typeof t)){if(e)return f(e,t)}else if(a&&n)return n.delete(t);return!1},get:function(t){return c&&t&&(\"object\"==typeof t||\"function\"==typeof t)&&e?s(e,t):n&&n.get(t)},has:function(t){return c&&t&&(\"object\"==typeof t||\"function\"==typeof t)&&e?p(e,t):!!n&&n.has(t)},set:function(t,r){c&&t&&(\"object\"==typeof t||\"function\"==typeof t)?(e||(e=new c),u(e,t,r)):a&&(n||(n=a()),n.set(t,r))}};return t}:a},920:(e,n,t)=>{\"use strict\";var r=t(9675),o=t(8859),i=t(4803),a=t(507),l=t(2271)||a||i;e.exports=function(){var e,n={assert:function(e){if(!n.has(e))throw new r(\"Side channel does not contain \"+o(e))},delete:function(n){return!!e&&e.delete(n)},get:function(n){return e&&e.get(n)},has:function(n){return!!e&&e.has(n)},set:function(n,t){e||(e=l()),e.set(n,t)}};return n}},7500:function(e,n){\"use strict\";var t,r,o,i=this&&this.__assign||function(){return i=Object.assign||function(e){for(var n,t=1,r=arguments.length;t<r;t++)for(var o in n=arguments[t])Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o]);return e},i.apply(this,arguments)};Object.defineProperty(n,\"__esModule\",{value:!0}),n.RecognizedBrowser=n.Device=n.OS=n.Browser=void 0,function(e){e.Firefox=\"firefox\",e.Chrome=\"chrome\",e.InternetExplorer=\"ie\",e.Safari=\"safari\",e.Edge=\"edge\",e.Android=\"com.android.browser\",e.Opera=\"opera\",e.OperaMini=\"opera.mini\",e.Blackberry=\"blackberry\",e.Iceweasel=\"iceweasel\",e.Yandex=\"yandex\",e.SeaMonkey=\"seamonkey\"}(t||(n.Browser=t={})),function(e){e.Linux=\"linux\",e.MacOS=\"macos\",e.Windows=\"windows\",e.iOS=\"ios\",e.OpenBSD=\"openbsd\",e.ChromeOS=\"chromeos\",e.Android=\"android\",e.FirefoxOS=\"firefoxos\",e.WindowsPhone=\"windows.phone\",e.WindowsMobile=\"windows.mobile\",e.BlackberryOS=\"blackberryos\"}(r||(n.OS=r={})),function(e){e.iPad=\"ipad\",e.iPhone=\"iphone\",e.Lumia=\"lumia\",e.HTC=\"htc\",e.Nexus=\"nexus\",e.GalaxyNexus=\"galaxy.nexus\",e.Nokia=\"nokia\",e.Galaxy=\"galaxy\",e.XBox=\"xbox\",e.Blackberry=\"blackberry\"}(o||(n.Device=o={}));var a=[[/msie ([\\.\\_\\d]+)/,t.InternetExplorer],[/trident\\/.*?rv:([\\.\\_\\d]+)/,t.InternetExplorer],[/firefox\\/([\\.\\_\\d]+)/,t.Firefox],[/fxios\\/([\\.\\_\\d]+)/,t.Firefox],[/chrome\\/([\\.\\_\\d]+)/,t.Chrome],[/version\\/([\\.\\_\\d]+).*?safari/,t.Safari],[/mobile safari ([\\.\\_\\d]+)/,t.Safari],[/android.*?version\\/([\\.\\_\\d]+).*?safari/,t.Android],[/crios\\/([\\.\\_\\d]+).*?safari/,t.Chrome],[/opera/,t.Opera],[/opera\\/([\\.\\_\\d]+)/,t.Opera],[/opera ([\\.\\_\\d]+)/,t.Opera],[/opera mini.*?version\\/([\\.\\_\\d]+)/,t.OperaMini],[/opr\\/([\\.\\_\\d]+)/,t.Opera],[/opios\\/([a-z\\.\\_\\d]+)/,t.Opera],[/blackberry/,t.Blackberry],[/blackberry.*?version\\/([\\.\\_\\d]+)/,t.Blackberry],[/bb\\d+.*?version\\/([\\.\\_\\d]+)/,t.Blackberry],[/rim.*?version\\/([\\.\\_\\d]+)/,t.Blackberry],[/iceweasel\\/([\\.\\_\\d]+)/,t.Iceweasel],[/edge\\/([\\.\\d]+)/,t.Edge],[/edg\\/([\\.\\d]+)/,t.Edge],[/yabrowser\\/([\\.\\d]+)/,t.Yandex],[/seamonkey\\/([\\.\\d]+)/,t.SeaMonkey]],l=[[/cros\\s*\\S+\\s*([\\.\\_\\d]+)/,r.ChromeOS],[/linux ()([a-z\\.\\_\\d]+)/,r.Linux],[/mac os x/,r.MacOS],[/mac os x.*?([\\.\\_\\d]+)/,r.MacOS],[/os ([\\.\\_\\d]+) like mac os/,r.iOS],[/openbsd ()([a-z\\.\\_\\d]+)/,r.OpenBSD],[/android/,r.Android],[/android ([a-z\\.\\_\\d]+);/,r.Android],[/mozilla\\/[a-z\\.\\_\\d]+ \\((?:mobile)|(?:tablet)/,r.FirefoxOS],[/windows\\s*(?:nt)?\\s*([\\.\\_\\d]+)/,r.Windows],[/windows phone.*?([\\.\\_\\d]+)/,r.WindowsPhone],[/windows mobile/,r.WindowsMobile],[/blackberry/,r.BlackberryOS],[/bb\\d+/,r.BlackberryOS],[/rim.*?os\\s*([\\.\\_\\d]+)/,r.BlackberryOS]],c=[[/ipad/,o.iPad],[/iphone/,o.iPhone],[/lumia/,o.Lumia],[/htc/,o.HTC],[/nexus/,o.Nexus],[/galaxy nexus/,o.GalaxyNexus],[/nokia/,o.Nokia],[/ gt\\-/,o.Galaxy],[/ sm\\-/,o.Galaxy],[/xbox/,o.XBox],[/(?:bb\\d+)|(?:blackberry)|(?: rim )/,o.Blackberry]],s=\"Unknown\",u={name:s,version:[],versionString:s};function p(e,n){var t=i({},u);return e.forEach((function(e){var r=e[0],o=e[1],i=n.match(r);i&&(t.name=o,i[2]?(t.versionString=i[2],t.version=[]):i[1]?(t.versionString=i[1].replace(/_/g,\".\"),t.version=i[1].split(/[\\._]/).map((function(e){return parseInt(e)})).filter((function(e){return!isNaN(e)}))):(t.versionString=s,t.version=[]))})),t}var f=\"undefined\"!=typeof window,d=function(){function e(){this.os=u,this.device=u,this.browser=u}return e.prototype.sniff=function(e){var n=f?navigator.userAgent:\"\",t=(e||n).toLowerCase();return this.os=p(l,t),this.device=p(c,t),this.browser=p(a,t),this},e}();if(n.default=d,n.RecognizedBrowser={os:u,browser:u,device:u},f){var g=(new d).sniff(navigator.userAgent);n.RecognizedBrowser.os=g.os,n.RecognizedBrowser.device=g.device,n.RecognizedBrowser.browser=g.browser}},1820:(e,n,t)=>{\"use strict\";var r=t(63),o=t(8068),i=\"object\"==typeof StopIteration?StopIteration:null;e.exports=function(e){if(!i)throw new o(\"this environment lacks StopIteration\");r.set(e,\"[[Done]]\",!1);var n={next:function(){var e=r.get(this,\"[[Iterator]]\"),n=!!r.get(e,\"[[Done]]\");try{return{done:n,value:n?void 0:e.next()}}catch(n){if(r.set(e,\"[[Done]]\",!0),n!==i)throw n;return{done:!0,value:void 0}}}};return r.set(n,\"[[Iterator]]\",e),n}},4643:(e,n,t)=>{function r(e){try{if(!t.g.localStorage)return!1}catch(e){return!1}var n=t.g.localStorage[e];return null!=n&&\"true\"===String(n).toLowerCase()}e.exports=function(e,n){if(r(\"noDeprecation\"))return e;var t=!1;return function(){if(!t){if(r(\"throwDeprecation\"))throw new Error(n);r(\"traceDeprecation\")?console.trace(n):console.warn(n),t=!0}return e.apply(this,arguments)}}},1539:(e,n,t)=>{\"use strict\";var r=t(4761),o=t(1703),i=t(5128),a=t(3612),l=t(9803);e.exports=function(e){return null==e||\"object\"!=typeof e&&\"function\"!=typeof e?null:r(e)?\"String\":o(e)?\"Number\":i(e)?\"Boolean\":a(e)?\"Symbol\":l(e)?\"BigInt\":void 0}},593:(e,n,t)=>{\"use strict\";var r=t(1421),o=t(256),i=t(7842),a=t(2648);e.exports=function(e){if(e&&\"object\"==typeof e){if(r(e))return\"Map\";if(o(e))return\"Set\";if(i(e))return\"WeakMap\";if(a(e))return\"WeakSet\"}return!1}},5767:(e,n,t)=>{\"use strict\";var r=t(2682),o=t(9209),i=t(487),a=t(6556),l=t(5795),c=t(3628),s=a(\"Object.prototype.toString\"),u=t(9092)(),p=\"undefined\"==typeof globalThis?t.g:globalThis,f=o(),d=a(\"String.prototype.slice\"),g=a(\"Array.prototype.indexOf\",!0)||function(e,n){for(var t=0;t<e.length;t+=1)if(e[t]===n)return t;return-1},h={__proto__:null};r(f,u&&l&&c?function(e){var n=new p[e];if(Symbol.toStringTag in n&&c){var t=c(n),r=l(t,Symbol.toStringTag);if(!r&&t){var o=c(t);r=l(o,Symbol.toStringTag)}h[\"$\"+e]=i(r.get)}}:function(e){var n=new p[e],t=n.slice||n.set;t&&(h[\"$\"+e]=i(t))});e.exports=function(e){if(!e||\"object\"!=typeof e)return!1;if(!u){var n=d(s(e),8,-1);return g(f,n)>-1?n:\"Object\"===n&&function(e){var n=!1;return r(h,(function(t,r){if(!n)try{t(e),n=d(r,1)}catch(e){}})),n}(e)}return l?function(e){var n=!1;return r(h,(function(t,r){if(!n)try{\"$\"+t(e)===r&&(n=d(r,1))}catch(e){}})),n}(e):null}},2634:()=>{},9209:(e,n,t)=>{\"use strict\";var r=t(6578),o=\"undefined\"==typeof globalThis?t.g:globalThis;e.exports=function(){for(var e=[],n=0;n<r.length;n++)\"function\"==typeof o[r[n]]&&(e[e.length]=r[n]);return e}},6942:(e,n)=>{var t;\n/*!\n\tCopyright (c) 2018 Jed Watson.\n\tLicensed under the MIT License (MIT), see\n\thttp://jedwatson.github.io/classnames\n*/!function(){\"use strict\";var r={}.hasOwnProperty;function o(){for(var e=\"\",n=0;n<arguments.length;n++){var t=arguments[n];t&&(e=a(e,i(t)))}return e}function i(e){if(\"string\"==typeof e||\"number\"==typeof e)return e;if(\"object\"!=typeof e)return\"\";if(Array.isArray(e))return o.apply(null,e);if(e.toString!==Object.prototype.toString&&!e.toString.toString().includes(\"[native code]\"))return e.toString();var n=\"\";for(var t in e)r.call(e,t)&&e[t]&&(n=a(n,t));return n}function a(e,n){return n?e?e+\" \"+n:e+n:e}e.exports?(o.default=o,e.exports=o):void 0===(t=function(){return o}.apply(n,[]))||(e.exports=t)}()},9306:(e,n,t)=>{\"use strict\";var r=t(4901),o=t(6823),i=TypeError;e.exports=function(e){if(r(e))return e;throw new i(o(e)+\" is not a function\")}},5548:(e,n,t)=>{\"use strict\";var r=t(3517),o=t(6823),i=TypeError;e.exports=function(e){if(r(e))return e;throw new i(o(e)+\" is not a constructor\")}},3506:(e,n,t)=>{\"use strict\";var r=t(3925),o=String,i=TypeError;e.exports=function(e){if(r(e))return e;throw new i(\"Can't set \"+o(e)+\" as a prototype\")}},6469:(e,n,t)=>{\"use strict\";var r=t(8227),o=t(2360),i=t(4913).f,a=r(\"unscopables\"),l=Array.prototype;void 0===l[a]&&i(l,a,{configurable:!0,value:o(null)}),e.exports=function(e){l[a][e]=!0}},7829:(e,n,t)=>{\"use strict\";var r=t(8183).charAt;e.exports=function(e,n,t){return n+(t?r(e,n).length:1)}},679:(e,n,t)=>{\"use strict\";var r=t(1625),o=TypeError;e.exports=function(e,n){if(r(n,e))return e;throw new o(\"Incorrect invocation\")}},8551:(e,n,t)=>{\"use strict\";var r=t(34),o=String,i=TypeError;e.exports=function(e){if(r(e))return e;throw new i(o(e)+\" is not an object\")}},5652:(e,n,t)=>{\"use strict\";var r=t(9039);e.exports=r((function(){if(\"function\"==typeof ArrayBuffer){var e=new ArrayBuffer(8);Object.isExtensible(e)&&Object.defineProperty(e,\"a\",{value:8})}}))},235:(e,n,t)=>{\"use strict\";var r=t(9213).forEach,o=t(4598)(\"forEach\");e.exports=o?[].forEach:function(e){return r(this,e,arguments.length>1?arguments[1]:void 0)}},7916:(e,n,t)=>{\"use strict\";var r=t(6080),o=t(9565),i=t(8981),a=t(6319),l=t(4209),c=t(3517),s=t(6198),u=t(4659),p=t(81),f=t(851),d=Array;e.exports=function(e){var n=i(e),t=c(this),g=arguments.length,h=g>1?arguments[1]:void 0,A=void 0!==h;A&&(h=r(h,g>2?arguments[2]:void 0));var b,v,m,y,E,C,w=f(n),x=0;if(!w||this===d&&l(w))for(b=s(n),v=t?new this(b):d(b);b>x;x++)C=A?h(n[x],x):n[x],u(v,x,C);else for(v=t?new this:[],E=(y=p(n,w)).next;!(m=o(E,y)).done;x++)C=A?a(y,h,[m.value,x],!0):m.value,u(v,x,C);return v.length=x,v}},9617:(e,n,t)=>{\"use strict\";var r=t(5397),o=t(5610),i=t(6198),a=function(e){return function(n,t,a){var l=r(n),c=i(l);if(0===c)return!e&&-1;var s,u=o(a,c);if(e&&t!=t){for(;c>u;)if((s=l[u++])!=s)return!0}else for(;c>u;u++)if((e||u in l)&&l[u]===t)return e||u||0;return!e&&-1}};e.exports={includes:a(!0),indexOf:a(!1)}},9213:(e,n,t)=>{\"use strict\";var r=t(6080),o=t(9504),i=t(7055),a=t(8981),l=t(6198),c=t(1469),s=o([].push),u=function(e){var n=1===e,t=2===e,o=3===e,u=4===e,p=6===e,f=7===e,d=5===e||p;return function(g,h,A,b){for(var v,m,y=a(g),E=i(y),C=l(E),w=r(h,A),x=0,S=b||c,_=n?S(g,C):t||f?S(g,0):void 0;C>x;x++)if((d||x in E)&&(m=w(v=E[x],x,y),e))if(n)_[x]=m;else if(m)switch(e){case 3:return!0;case 5:return v;case 6:return x;case 2:s(_,v)}else switch(e){case 4:return!1;case 7:s(_,v)}return p?-1:o||u?u:_}};e.exports={forEach:u(0),map:u(1),filter:u(2),some:u(3),every:u(4),find:u(5),findIndex:u(6),filterReject:u(7)}},597:(e,n,t)=>{\"use strict\";var r=t(9039),o=t(8227),i=t(9519),a=o(\"species\");e.exports=function(e){return i>=51||!r((function(){var n=[];return(n.constructor={})[a]=function(){return{foo:1}},1!==n[e](Boolean).foo}))}},4598:(e,n,t)=>{\"use strict\";var r=t(9039);e.exports=function(e,n){var t=[][e];return!!t&&r((function(){t.call(null,n||function(){return 1},1)}))}},926:(e,n,t)=>{\"use strict\";var r=t(9306),o=t(8981),i=t(7055),a=t(6198),l=TypeError,c=\"Reduce of empty array with no initial value\",s=function(e){return function(n,t,s,u){var p=o(n),f=i(p),d=a(p);if(r(t),0===d&&s<2)throw new l(c);var g=e?d-1:0,h=e?-1:1;if(s<2)for(;;){if(g in f){u=f[g],g+=h;break}if(g+=h,e?g<0:d<=g)throw new l(c)}for(;e?g>=0:d>g;g+=h)g in f&&(u=t(u,f[g],g,p));return u}};e.exports={left:s(!1),right:s(!0)}},4527:(e,n,t)=>{\"use strict\";var r=t(3724),o=t(4376),i=TypeError,a=Object.getOwnPropertyDescriptor,l=r&&!function(){if(void 0!==this)return!0;try{Object.defineProperty([],\"length\",{writable:!1}).length=1}catch(e){return e instanceof TypeError}}();e.exports=l?function(e,n){if(o(e)&&!a(e,\"length\").writable)throw new i(\"Cannot set read only .length\");return e.length=n}:function(e,n){return e.length=n}},7680:(e,n,t)=>{\"use strict\";var r=t(9504);e.exports=r([].slice)},4488:(e,n,t)=>{\"use strict\";var r=t(7680),o=Math.floor,i=function(e,n){var t=e.length;if(t<8)for(var a,l,c=1;c<t;){for(l=c,a=e[c];l&&n(e[l-1],a)>0;)e[l]=e[--l];l!==c++&&(e[l]=a)}else for(var s=o(t/2),u=i(r(e,0,s),n),p=i(r(e,s),n),f=u.length,d=p.length,g=0,h=0;g<f||h<d;)e[g+h]=g<f&&h<d?n(u[g],p[h])<=0?u[g++]:p[h++]:g<f?u[g++]:p[h++];return e};e.exports=i},7433:(e,n,t)=>{\"use strict\";var r=t(4376),o=t(3517),i=t(34),a=t(8227)(\"species\"),l=Array;e.exports=function(e){var n;return r(e)&&(n=e.constructor,(o(n)&&(n===l||r(n.prototype))||i(n)&&null===(n=n[a]))&&(n=void 0)),void 0===n?l:n}},1469:(e,n,t)=>{\"use strict\";var r=t(7433);e.exports=function(e,n){return new(r(e))(0===n?0:n)}},6319:(e,n,t)=>{\"use strict\";var r=t(8551),o=t(9539);e.exports=function(e,n,t,i){try{return i?n(r(t)[0],t[1]):n(t)}catch(n){o(e,\"throw\",n)}}},4428:(e,n,t)=>{\"use strict\";var r=t(8227)(\"iterator\"),o=!1;try{var i=0,a={next:function(){return{done:!!i++}},return:function(){o=!0}};a[r]=function(){return this},Array.from(a,(function(){throw 2}))}catch(e){}e.exports=function(e,n){try{if(!n&&!o)return!1}catch(e){return!1}var t=!1;try{var i={};i[r]=function(){return{next:function(){return{done:t=!0}}}},e(i)}catch(e){}return t}},2195:(e,n,t)=>{\"use strict\";var r=t(9504),o=r({}.toString),i=r(\"\".slice);e.exports=function(e){return i(o(e),8,-1)}},6955:(e,n,t)=>{\"use strict\";var r=t(2140),o=t(4901),i=t(2195),a=t(8227)(\"toStringTag\"),l=Object,c=\"Arguments\"===i(function(){return arguments}());e.exports=r?i:function(e){var n,t,r;return void 0===e?\"Undefined\":null===e?\"Null\":\"string\"==typeof(t=function(e,n){try{return e[n]}catch(e){}}(n=l(e),a))?t:c?i(n):\"Object\"===(r=i(n))&&o(n.callee)?\"Arguments\":r}},6938:(e,n,t)=>{\"use strict\";var r=t(2360),o=t(2106),i=t(6279),a=t(6080),l=t(679),c=t(4117),s=t(2652),u=t(1088),p=t(2529),f=t(7633),d=t(3724),g=t(3451).fastKey,h=t(1181),A=h.set,b=h.getterFor;e.exports={getConstructor:function(e,n,t,u){var p=e((function(e,o){l(e,f),A(e,{type:n,index:r(null),first:null,last:null,size:0}),d||(e.size=0),c(o)||s(o,e[u],{that:e,AS_ENTRIES:t})})),f=p.prototype,h=b(n),v=function(e,n,t){var r,o,i=h(e),a=m(e,n);return a?a.value=t:(i.last=a={index:o=g(n,!0),key:n,value:t,previous:r=i.last,next:null,removed:!1},i.first||(i.first=a),r&&(r.next=a),d?i.size++:e.size++,\"F\"!==o&&(i.index[o]=a)),e},m=function(e,n){var t,r=h(e),o=g(n);if(\"F\"!==o)return r.index[o];for(t=r.first;t;t=t.next)if(t.key===n)return t};return i(f,{clear:function(){for(var e=h(this),n=e.first;n;)n.removed=!0,n.previous&&(n.previous=n.previous.next=null),n=n.next;e.first=e.last=null,e.index=r(null),d?e.size=0:this.size=0},delete:function(e){var n=this,t=h(n),r=m(n,e);if(r){var o=r.next,i=r.previous;delete t.index[r.index],r.removed=!0,i&&(i.next=o),o&&(o.previous=i),t.first===r&&(t.first=o),t.last===r&&(t.last=i),d?t.size--:n.size--}return!!r},forEach:function(e){for(var n,t=h(this),r=a(e,arguments.length>1?arguments[1]:void 0);n=n?n.next:t.first;)for(r(n.value,n.key,this);n&&n.removed;)n=n.previous},has:function(e){return!!m(this,e)}}),i(f,t?{get:function(e){var n=m(this,e);return n&&n.value},set:function(e,n){return v(this,0===e?0:e,n)}}:{add:function(e){return v(this,e=0===e?0:e,e)}}),d&&o(f,\"size\",{configurable:!0,get:function(){return h(this).size}}),p},setStrong:function(e,n,t){var r=n+\" Iterator\",o=b(n),i=b(r);u(e,n,(function(e,n){A(this,{type:r,target:e,state:o(e),kind:n,last:null})}),(function(){for(var e=i(this),n=e.kind,t=e.last;t&&t.removed;)t=t.previous;return e.target&&(e.last=t=t?t.next:e.state.first)?p(\"keys\"===n?t.key:\"values\"===n?t.value:[t.key,t.value],!1):(e.target=null,p(void 0,!0))}),t?\"entries\":\"values\",!t,!0),f(n)}}},4006:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(6279),i=t(3451).getWeakData,a=t(679),l=t(8551),c=t(4117),s=t(34),u=t(2652),p=t(9213),f=t(9297),d=t(1181),g=d.set,h=d.getterFor,A=p.find,b=p.findIndex,v=r([].splice),m=0,y=function(e){return e.frozen||(e.frozen=new E)},E=function(){this.entries=[]},C=function(e,n){return A(e.entries,(function(e){return e[0]===n}))};E.prototype={get:function(e){var n=C(this,e);if(n)return n[1]},has:function(e){return!!C(this,e)},set:function(e,n){var t=C(this,e);t?t[1]=n:this.entries.push([e,n])},delete:function(e){var n=b(this.entries,(function(n){return n[0]===e}));return~n&&v(this.entries,n,1),!!~n}},e.exports={getConstructor:function(e,n,t,r){var p=e((function(e,o){a(e,d),g(e,{type:n,id:m++,frozen:null}),c(o)||u(o,e[r],{that:e,AS_ENTRIES:t})})),d=p.prototype,A=h(n),b=function(e,n,t){var r=A(e),o=i(l(n),!0);return!0===o?y(r).set(n,t):o[r.id]=t,e};return o(d,{delete:function(e){var n=A(this);if(!s(e))return!1;var t=i(e);return!0===t?y(n).delete(e):t&&f(t,n.id)&&delete t[n.id]},has:function(e){var n=A(this);if(!s(e))return!1;var t=i(e);return!0===t?y(n).has(e):t&&f(t,n.id)}}),o(d,t?{get:function(e){var n=A(this);if(s(e)){var t=i(e);if(!0===t)return y(n).get(e);if(t)return t[n.id]}},set:function(e,n){return b(this,e,n)}}:{add:function(e){return b(this,e,!0)}}),p}}},6468:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(4576),i=t(9504),a=t(2796),l=t(6840),c=t(3451),s=t(2652),u=t(679),p=t(4901),f=t(4117),d=t(34),g=t(9039),h=t(4428),A=t(687),b=t(3167);e.exports=function(e,n,t){var v=-1!==e.indexOf(\"Map\"),m=-1!==e.indexOf(\"Weak\"),y=v?\"set\":\"add\",E=o[e],C=E&&E.prototype,w=E,x={},S=function(e){var n=i(C[e]);l(C,e,\"add\"===e?function(e){return n(this,0===e?0:e),this}:\"delete\"===e?function(e){return!(m&&!d(e))&&n(this,0===e?0:e)}:\"get\"===e?function(e){return m&&!d(e)?void 0:n(this,0===e?0:e)}:\"has\"===e?function(e){return!(m&&!d(e))&&n(this,0===e?0:e)}:function(e,t){return n(this,0===e?0:e,t),this})};if(a(e,!p(E)||!(m||C.forEach&&!g((function(){(new E).entries().next()})))))w=t.getConstructor(n,e,v,y),c.enable();else if(a(e,!0)){var _=new w,k=_[y](m?{}:-0,1)!==_,O=g((function(){_.has(1)})),B=h((function(e){new E(e)})),P=!m&&g((function(){for(var e=new E,n=5;n--;)e[y](n,n);return!e.has(-0)}));B||((w=n((function(e,n){u(e,C);var t=b(new E,e,w);return f(n)||s(n,t[y],{that:t,AS_ENTRIES:v}),t}))).prototype=C,C.constructor=w),(O||P)&&(S(\"delete\"),S(\"has\"),v&&S(\"get\")),(P||k)&&S(y),m&&C.clear&&delete C.clear}return x[e]=w,r({global:!0,constructor:!0,forced:w!==E},x),A(w,e),m||t.setStrong(w,e,v),w}},7740:(e,n,t)=>{\"use strict\";var r=t(9297),o=t(5031),i=t(7347),a=t(4913);e.exports=function(e,n,t){for(var l=o(n),c=a.f,s=i.f,u=0;u<l.length;u++){var p=l[u];r(e,p)||t&&r(t,p)||c(e,p,s(n,p))}}},1436:(e,n,t)=>{\"use strict\";var r=t(8227)(\"match\");e.exports=function(e){var n=/./;try{\"/./\"[e](n)}catch(t){try{return n[r]=!1,\"/./\"[e](n)}catch(e){}}return!1}},2211:(e,n,t)=>{\"use strict\";var r=t(9039);e.exports=!r((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype}))},7240:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(7750),i=t(655),a=/\"/g,l=r(\"\".replace);e.exports=function(e,n,t,r){var c=i(o(e)),s=\"<\"+n;return\"\"!==t&&(s+=\" \"+t+'=\"'+l(i(r),a,\"&quot;\")+'\"'),s+\">\"+c+\"</\"+n+\">\"}},2529:e=>{\"use strict\";e.exports=function(e,n){return{value:e,done:n}}},6699:(e,n,t)=>{\"use strict\";var r=t(3724),o=t(4913),i=t(6980);e.exports=r?function(e,n,t){return o.f(e,n,i(1,t))}:function(e,n,t){return e[n]=t,e}},6980:e=>{\"use strict\";e.exports=function(e,n){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:n}}},4659:(e,n,t)=>{\"use strict\";var r=t(3724),o=t(4913),i=t(6980);e.exports=function(e,n,t){r?o.f(e,n,i(0,t)):e[n]=t}},3640:(e,n,t)=>{\"use strict\";var r=t(8551),o=t(4270),i=TypeError;e.exports=function(e){if(r(this),\"string\"===e||\"default\"===e)e=\"string\";else if(\"number\"!==e)throw new i(\"Incorrect hint\");return o(this,e)}},2106:(e,n,t)=>{\"use strict\";var r=t(283),o=t(4913);e.exports=function(e,n,t){return t.get&&r(t.get,n,{getter:!0}),t.set&&r(t.set,n,{setter:!0}),o.f(e,n,t)}},6840:(e,n,t)=>{\"use strict\";var r=t(4901),o=t(4913),i=t(283),a=t(9433);e.exports=function(e,n,t,l){l||(l={});var c=l.enumerable,s=void 0!==l.name?l.name:n;if(r(t)&&i(t,s,l),l.global)c?e[n]=t:a(n,t);else{try{l.unsafe?e[n]&&(c=!0):delete e[n]}catch(e){}c?e[n]=t:o.f(e,n,{value:t,enumerable:!1,configurable:!l.nonConfigurable,writable:!l.nonWritable})}return e}},6279:(e,n,t)=>{\"use strict\";var r=t(6840);e.exports=function(e,n,t){for(var o in n)r(e,o,n[o],t);return e}},9433:(e,n,t)=>{\"use strict\";var r=t(4576),o=Object.defineProperty;e.exports=function(e,n){try{o(r,e,{value:n,configurable:!0,writable:!0})}catch(t){r[e]=n}return n}},4606:(e,n,t)=>{\"use strict\";var r=t(6823),o=TypeError;e.exports=function(e,n){if(!delete e[n])throw new o(\"Cannot delete property \"+r(n)+\" of \"+r(e))}},3724:(e,n,t)=>{\"use strict\";var r=t(9039);e.exports=!r((function(){return 7!==Object.defineProperty({},1,{get:function(){return 7}})[1]}))},4055:(e,n,t)=>{\"use strict\";var r=t(4576),o=t(34),i=r.document,a=o(i)&&o(i.createElement);e.exports=function(e){return a?i.createElement(e):{}}},6837:e=>{\"use strict\";var n=TypeError;e.exports=function(e){if(e>9007199254740991)throw n(\"Maximum allowed index exceeded\");return e}},7400:e=>{\"use strict\";e.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},9296:(e,n,t)=>{\"use strict\";var r=t(4055)(\"span\").classList,o=r&&r.constructor&&r.constructor.prototype;e.exports=o===Object.prototype?void 0:o},8727:e=>{\"use strict\";e.exports=[\"constructor\",\"hasOwnProperty\",\"isPrototypeOf\",\"propertyIsEnumerable\",\"toLocaleString\",\"toString\",\"valueOf\"]},6090:(e,n,t)=>{\"use strict\";var r=t(2839).match(/firefox\\/(\\d+)/i);e.exports=!!r&&+r[1]},3763:(e,n,t)=>{\"use strict\";var r=t(2839);e.exports=/MSIE|Trident/.test(r)},6193:(e,n,t)=>{\"use strict\";var r=t(4215);e.exports=\"NODE\"===r},2839:(e,n,t)=>{\"use strict\";var r=t(4576).navigator,o=r&&r.userAgent;e.exports=o?String(o):\"\"},9519:(e,n,t)=>{\"use strict\";var r,o,i=t(4576),a=t(2839),l=i.process,c=i.Deno,s=l&&l.versions||c&&c.version,u=s&&s.v8;u&&(o=(r=u.split(\".\"))[0]>0&&r[0]<4?1:+(r[0]+r[1])),!o&&a&&(!(r=a.match(/Edge\\/(\\d+)/))||r[1]>=74)&&(r=a.match(/Chrome\\/(\\d+)/))&&(o=+r[1]),e.exports=o},3607:(e,n,t)=>{\"use strict\";var r=t(2839).match(/AppleWebKit\\/(\\d+)\\./);e.exports=!!r&&+r[1]},4215:(e,n,t)=>{\"use strict\";var r=t(4576),o=t(2839),i=t(2195),a=function(e){return o.slice(0,e.length)===e};e.exports=a(\"Bun/\")?\"BUN\":a(\"Cloudflare-Workers\")?\"CLOUDFLARE\":a(\"Deno/\")?\"DENO\":a(\"Node.js/\")?\"NODE\":r.Bun&&\"string\"==typeof Bun.version?\"BUN\":r.Deno&&\"object\"==typeof Deno.version?\"DENO\":\"process\"===i(r.process)?\"NODE\":r.window&&r.document?\"BROWSER\":\"REST\"},6518:(e,n,t)=>{\"use strict\";var r=t(4576),o=t(7347).f,i=t(6699),a=t(6840),l=t(9433),c=t(7740),s=t(2796);e.exports=function(e,n){var t,u,p,f,d,g=e.target,h=e.global,A=e.stat;if(t=h?r:A?r[g]||l(g,{}):r[g]&&r[g].prototype)for(u in n){if(f=n[u],p=e.dontCallGetSet?(d=o(t,u))&&d.value:t[u],!s(h?u:g+(A?\".\":\"#\")+u,e.forced)&&void 0!==p){if(typeof f==typeof p)continue;c(f,p)}(e.sham||p&&p.sham)&&i(f,\"sham\",!0),a(t,u,f,e)}}},9039:e=>{\"use strict\";e.exports=function(e){try{return!!e()}catch(e){return!0}}},9228:(e,n,t)=>{\"use strict\";t(7495);var r=t(9565),o=t(6840),i=t(7323),a=t(9039),l=t(8227),c=t(6699),s=l(\"species\"),u=RegExp.prototype;e.exports=function(e,n,t,p){var f=l(e),d=!a((function(){var n={};return n[f]=function(){return 7},7!==\"\"[e](n)})),g=d&&!a((function(){var n=!1,t=/a/;return\"split\"===e&&((t={}).constructor={},t.constructor[s]=function(){return t},t.flags=\"\",t[f]=/./[f]),t.exec=function(){return n=!0,null},t[f](\"\"),!n}));if(!d||!g||t){var h=/./[f],A=n(f,\"\"[e],(function(e,n,t,o,a){var l=n.exec;return l===i||l===u.exec?d&&!a?{done:!0,value:r(h,n,t,o)}:{done:!0,value:r(e,t,n,o)}:{done:!1}}));o(String.prototype,e,A[0]),o(u,f,A[1])}p&&c(u[f],\"sham\",!0)}},2744:(e,n,t)=>{\"use strict\";var r=t(9039);e.exports=!r((function(){return Object.isExtensible(Object.preventExtensions({}))}))},8745:(e,n,t)=>{\"use strict\";var r=t(616),o=Function.prototype,i=o.apply,a=o.call;e.exports=\"object\"==typeof Reflect&&Reflect.apply||(r?a.bind(i):function(){return a.apply(i,arguments)})},6080:(e,n,t)=>{\"use strict\";var r=t(7476),o=t(9306),i=t(616),a=r(r.bind);e.exports=function(e,n){return o(e),void 0===n?e:i?a(e,n):function(){return e.apply(n,arguments)}}},616:(e,n,t)=>{\"use strict\";var r=t(9039);e.exports=!r((function(){var e=function(){}.bind();return\"function\"!=typeof e||e.hasOwnProperty(\"prototype\")}))},566:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(9306),i=t(34),a=t(9297),l=t(7680),c=t(616),s=Function,u=r([].concat),p=r([].join),f={};e.exports=c?s.bind:function(e){var n=o(this),t=n.prototype,r=l(arguments,1),c=function(){var t=u(r,l(arguments));return this instanceof c?function(e,n,t){if(!a(f,n)){for(var r=[],o=0;o<n;o++)r[o]=\"a[\"+o+\"]\";f[n]=s(\"C,a\",\"return new C(\"+p(r,\",\")+\")\")}return f[n](e,t)}(n,t.length,t):n.apply(e,t)};return i(t)&&(c.prototype=t),c}},9565:(e,n,t)=>{\"use strict\";var r=t(616),o=Function.prototype.call;e.exports=r?o.bind(o):function(){return o.apply(o,arguments)}},350:(e,n,t)=>{\"use strict\";var r=t(3724),o=t(9297),i=Function.prototype,a=r&&Object.getOwnPropertyDescriptor,l=o(i,\"name\"),c=l&&\"something\"===function(){}.name,s=l&&(!r||r&&a(i,\"name\").configurable);e.exports={EXISTS:l,PROPER:c,CONFIGURABLE:s}},6706:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(9306);e.exports=function(e,n,t){try{return r(o(Object.getOwnPropertyDescriptor(e,n)[t]))}catch(e){}}},7476:(e,n,t)=>{\"use strict\";var r=t(2195),o=t(9504);e.exports=function(e){if(\"Function\"===r(e))return o(e)}},9504:(e,n,t)=>{\"use strict\";var r=t(616),o=Function.prototype,i=o.call,a=r&&o.bind.bind(i,i);e.exports=r?a:function(e){return function(){return i.apply(e,arguments)}}},7751:(e,n,t)=>{\"use strict\";var r=t(4576),o=t(4901);e.exports=function(e,n){return arguments.length<2?(t=r[e],o(t)?t:void 0):r[e]&&r[e][n];var t}},851:(e,n,t)=>{\"use strict\";var r=t(6955),o=t(5966),i=t(4117),a=t(6269),l=t(8227)(\"iterator\");e.exports=function(e){if(!i(e))return o(e,l)||o(e,\"@@iterator\")||a[r(e)]}},81:(e,n,t)=>{\"use strict\";var r=t(9565),o=t(9306),i=t(8551),a=t(6823),l=t(851),c=TypeError;e.exports=function(e,n){var t=arguments.length<2?l(e):n;if(o(t))return i(r(t,e));throw new c(a(e)+\" is not iterable\")}},6933:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(4376),i=t(4901),a=t(2195),l=t(655),c=r([].push);e.exports=function(e){if(i(e))return e;if(o(e)){for(var n=e.length,t=[],r=0;r<n;r++){var s=e[r];\"string\"==typeof s?c(t,s):\"number\"!=typeof s&&\"Number\"!==a(s)&&\"String\"!==a(s)||c(t,l(s))}var u=t.length,p=!0;return function(e,n){if(p)return p=!1,n;if(o(this))return n;for(var r=0;r<u;r++)if(t[r]===e)return n}}}},5966:(e,n,t)=>{\"use strict\";var r=t(9306),o=t(4117);e.exports=function(e,n){var t=e[n];return o(t)?void 0:r(t)}},2478:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(8981),i=Math.floor,a=r(\"\".charAt),l=r(\"\".replace),c=r(\"\".slice),s=/\\$([$&'`]|\\d{1,2}|<[^>]*>)/g,u=/\\$([$&'`]|\\d{1,2})/g;e.exports=function(e,n,t,r,p,f){var d=t+e.length,g=r.length,h=u;return void 0!==p&&(p=o(p),h=s),l(f,h,(function(o,l){var s;switch(a(l,0)){case\"$\":return\"$\";case\"&\":return e;case\"`\":return c(n,0,t);case\"'\":return c(n,d);case\"<\":s=p[c(l,1,-1)];break;default:var u=+l;if(0===u)return o;if(u>g){var f=i(u/10);return 0===f?o:f<=g?void 0===r[f-1]?a(l,1):r[f-1]+a(l,1):o}s=r[u-1]}return void 0===s?\"\":s}))}},4576:function(e,n,t){\"use strict\";var r=function(e){return e&&e.Math===Math&&e};e.exports=r(\"object\"==typeof globalThis&&globalThis)||r(\"object\"==typeof window&&window)||r(\"object\"==typeof self&&self)||r(\"object\"==typeof t.g&&t.g)||r(\"object\"==typeof this&&this)||function(){return this}()||Function(\"return this\")()},9297:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(8981),i=r({}.hasOwnProperty);e.exports=Object.hasOwn||function(e,n){return i(o(e),n)}},421:e=>{\"use strict\";e.exports={}},397:(e,n,t)=>{\"use strict\";var r=t(7751);e.exports=r(\"document\",\"documentElement\")},5917:(e,n,t)=>{\"use strict\";var r=t(3724),o=t(9039),i=t(4055);e.exports=!r&&!o((function(){return 7!==Object.defineProperty(i(\"div\"),\"a\",{get:function(){return 7}}).a}))},7055:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(9039),i=t(2195),a=Object,l=r(\"\".split);e.exports=o((function(){return!a(\"z\").propertyIsEnumerable(0)}))?function(e){return\"String\"===i(e)?l(e,\"\"):a(e)}:a},3167:(e,n,t)=>{\"use strict\";var r=t(4901),o=t(34),i=t(2967);e.exports=function(e,n,t){var a,l;return i&&r(a=n.constructor)&&a!==t&&o(l=a.prototype)&&l!==t.prototype&&i(e,l),e}},3706:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(4901),i=t(7629),a=r(Function.toString);o(i.inspectSource)||(i.inspectSource=function(e){return a(e)}),e.exports=i.inspectSource},3451:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9504),i=t(421),a=t(34),l=t(9297),c=t(4913).f,s=t(8480),u=t(298),p=t(4124),f=t(3392),d=t(2744),g=!1,h=f(\"meta\"),A=0,b=function(e){c(e,h,{value:{objectID:\"O\"+A++,weakData:{}}})},v=e.exports={enable:function(){v.enable=function(){},g=!0;var e=s.f,n=o([].splice),t={};t[h]=1,e(t).length&&(s.f=function(t){for(var r=e(t),o=0,i=r.length;o<i;o++)if(r[o]===h){n(r,o,1);break}return r},r({target:\"Object\",stat:!0,forced:!0},{getOwnPropertyNames:u.f}))},fastKey:function(e,n){if(!a(e))return\"symbol\"==typeof e?e:(\"string\"==typeof e?\"S\":\"P\")+e;if(!l(e,h)){if(!p(e))return\"F\";if(!n)return\"E\";b(e)}return e[h].objectID},getWeakData:function(e,n){if(!l(e,h)){if(!p(e))return!0;if(!n)return!1;b(e)}return e[h].weakData},onFreeze:function(e){return d&&g&&p(e)&&!l(e,h)&&b(e),e}};i[h]=!0},1181:(e,n,t)=>{\"use strict\";var r,o,i,a=t(8622),l=t(4576),c=t(34),s=t(6699),u=t(9297),p=t(7629),f=t(6119),d=t(421),g=\"Object already initialized\",h=l.TypeError,A=l.WeakMap;if(a||p.state){var b=p.state||(p.state=new A);b.get=b.get,b.has=b.has,b.set=b.set,r=function(e,n){if(b.has(e))throw new h(g);return n.facade=e,b.set(e,n),n},o=function(e){return b.get(e)||{}},i=function(e){return b.has(e)}}else{var v=f(\"state\");d[v]=!0,r=function(e,n){if(u(e,v))throw new h(g);return n.facade=e,s(e,v,n),n},o=function(e){return u(e,v)?e[v]:{}},i=function(e){return u(e,v)}}e.exports={set:r,get:o,has:i,enforce:function(e){return i(e)?o(e):r(e,{})},getterFor:function(e){return function(n){var t;if(!c(n)||(t=o(n)).type!==e)throw new h(\"Incompatible receiver, \"+e+\" required\");return t}}}},4209:(e,n,t)=>{\"use strict\";var r=t(8227),o=t(6269),i=r(\"iterator\"),a=Array.prototype;e.exports=function(e){return void 0!==e&&(o.Array===e||a[i]===e)}},4376:(e,n,t)=>{\"use strict\";var r=t(2195);e.exports=Array.isArray||function(e){return\"Array\"===r(e)}},4901:e=>{\"use strict\";var n=\"object\"==typeof document&&document.all;e.exports=void 0===n&&void 0!==n?function(e){return\"function\"==typeof e||e===n}:function(e){return\"function\"==typeof e}},3517:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(9039),i=t(4901),a=t(6955),l=t(7751),c=t(3706),s=function(){},u=l(\"Reflect\",\"construct\"),p=/^\\s*(?:class|function)\\b/,f=r(p.exec),d=!p.test(s),g=function(e){if(!i(e))return!1;try{return u(s,[],e),!0}catch(e){return!1}},h=function(e){if(!i(e))return!1;switch(a(e)){case\"AsyncFunction\":case\"GeneratorFunction\":case\"AsyncGeneratorFunction\":return!1}try{return d||!!f(p,c(e))}catch(e){return!0}};h.sham=!0,e.exports=!u||o((function(){var e;return g(g.call)||!g(Object)||!g((function(){e=!0}))||e}))?h:g},2796:(e,n,t)=>{\"use strict\";var r=t(9039),o=t(4901),i=/#|\\.prototype\\./,a=function(e,n){var t=c[l(e)];return t===u||t!==s&&(o(n)?r(n):!!n)},l=a.normalize=function(e){return String(e).replace(i,\".\").toLowerCase()},c=a.data={},s=a.NATIVE=\"N\",u=a.POLYFILL=\"P\";e.exports=a},4117:e=>{\"use strict\";e.exports=function(e){return null==e}},34:(e,n,t)=>{\"use strict\";var r=t(4901);e.exports=function(e){return\"object\"==typeof e?null!==e:r(e)}},3925:(e,n,t)=>{\"use strict\";var r=t(34);e.exports=function(e){return r(e)||null===e}},6395:e=>{\"use strict\";e.exports=!1},788:(e,n,t)=>{\"use strict\";var r=t(34),o=t(2195),i=t(8227)(\"match\");e.exports=function(e){var n;return r(e)&&(void 0!==(n=e[i])?!!n:\"RegExp\"===o(e))}},757:(e,n,t)=>{\"use strict\";var r=t(7751),o=t(4901),i=t(1625),a=t(7040),l=Object;e.exports=a?function(e){return\"symbol\"==typeof e}:function(e){var n=r(\"Symbol\");return o(n)&&i(n.prototype,l(e))}},2652:(e,n,t)=>{\"use strict\";var r=t(6080),o=t(9565),i=t(8551),a=t(6823),l=t(4209),c=t(6198),s=t(1625),u=t(81),p=t(851),f=t(9539),d=TypeError,g=function(e,n){this.stopped=e,this.result=n},h=g.prototype;e.exports=function(e,n,t){var A,b,v,m,y,E,C,w=t&&t.that,x=!(!t||!t.AS_ENTRIES),S=!(!t||!t.IS_RECORD),_=!(!t||!t.IS_ITERATOR),k=!(!t||!t.INTERRUPTED),O=r(n,w),B=function(e){return A&&f(A,\"normal\",e),new g(!0,e)},P=function(e){return x?(i(e),k?O(e[0],e[1],B):O(e[0],e[1])):k?O(e,B):O(e)};if(S)A=e.iterator;else if(_)A=e;else{if(!(b=p(e)))throw new d(a(e)+\" is not iterable\");if(l(b)){for(v=0,m=c(e);m>v;v++)if((y=P(e[v]))&&s(h,y))return y;return new g(!1)}A=u(e,b)}for(E=S?e.next:A.next;!(C=o(E,A)).done;){try{y=P(C.value)}catch(e){f(A,\"throw\",e)}if(\"object\"==typeof y&&y&&s(h,y))return y}return new g(!1)}},9539:(e,n,t)=>{\"use strict\";var r=t(9565),o=t(8551),i=t(5966);e.exports=function(e,n,t){var a,l;o(e);try{if(!(a=i(e,\"return\"))){if(\"throw\"===n)throw t;return t}a=r(a,e)}catch(e){l=!0,a=e}if(\"throw\"===n)throw t;if(l)throw a;return o(a),t}},3994:(e,n,t)=>{\"use strict\";var r=t(7657).IteratorPrototype,o=t(2360),i=t(6980),a=t(687),l=t(6269),c=function(){return this};e.exports=function(e,n,t,s){var u=n+\" Iterator\";return e.prototype=o(r,{next:i(+!s,t)}),a(e,u,!1,!0),l[u]=c,e}},1088:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9565),i=t(6395),a=t(350),l=t(4901),c=t(3994),s=t(2787),u=t(2967),p=t(687),f=t(6699),d=t(6840),g=t(8227),h=t(6269),A=t(7657),b=a.PROPER,v=a.CONFIGURABLE,m=A.IteratorPrototype,y=A.BUGGY_SAFARI_ITERATORS,E=g(\"iterator\"),C=\"keys\",w=\"values\",x=\"entries\",S=function(){return this};e.exports=function(e,n,t,a,g,A,_){c(t,n,a);var k,O,B,P=function(e){if(e===g&&D)return D;if(!y&&e&&e in j)return j[e];switch(e){case C:case w:case x:return function(){return new t(this,e)}}return function(){return new t(this)}},T=n+\" Iterator\",I=!1,j=e.prototype,z=j[E]||j[\"@@iterator\"]||g&&j[g],D=!y&&z||P(g),R=\"Array\"===n&&j.entries||z;if(R&&(k=s(R.call(new e)))!==Object.prototype&&k.next&&(i||s(k)===m||(u?u(k,m):l(k[E])||d(k,E,S)),p(k,T,!0,!0),i&&(h[T]=S)),b&&g===w&&z&&z.name!==w&&(!i&&v?f(j,\"name\",w):(I=!0,D=function(){return o(z,this)})),g)if(O={values:P(w),keys:A?D:P(C),entries:P(x)},_)for(B in O)(y||I||!(B in j))&&d(j,B,O[B]);else r({target:n,proto:!0,forced:y||I},O);return i&&!_||j[E]===D||d(j,E,D,{name:g}),h[n]=D,O}},7657:(e,n,t)=>{\"use strict\";var r,o,i,a=t(9039),l=t(4901),c=t(34),s=t(2360),u=t(2787),p=t(6840),f=t(8227),d=t(6395),g=f(\"iterator\"),h=!1;[].keys&&(\"next\"in(i=[].keys())?(o=u(u(i)))!==Object.prototype&&(r=o):h=!0),!c(r)||a((function(){var e={};return r[g].call(e)!==e}))?r={}:d&&(r=s(r)),l(r[g])||p(r,g,(function(){return this})),e.exports={IteratorPrototype:r,BUGGY_SAFARI_ITERATORS:h}},6269:e=>{\"use strict\";e.exports={}},6198:(e,n,t)=>{\"use strict\";var r=t(8014);e.exports=function(e){return r(e.length)}},283:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(9039),i=t(4901),a=t(9297),l=t(3724),c=t(350).CONFIGURABLE,s=t(3706),u=t(1181),p=u.enforce,f=u.get,d=String,g=Object.defineProperty,h=r(\"\".slice),A=r(\"\".replace),b=r([].join),v=l&&!o((function(){return 8!==g((function(){}),\"length\",{value:8}).length})),m=String(String).split(\"String\"),y=e.exports=function(e,n,t){\"Symbol(\"===h(d(n),0,7)&&(n=\"[\"+A(d(n),/^Symbol\\(([^)]*)\\).*$/,\"$1\")+\"]\"),t&&t.getter&&(n=\"get \"+n),t&&t.setter&&(n=\"set \"+n),(!a(e,\"name\")||c&&e.name!==n)&&(l?g(e,\"name\",{value:n,configurable:!0}):e.name=n),v&&t&&a(t,\"arity\")&&e.length!==t.arity&&g(e,\"length\",{value:t.arity});try{t&&a(t,\"constructor\")&&t.constructor?l&&g(e,\"prototype\",{writable:!1}):e.prototype&&(e.prototype=void 0)}catch(e){}var r=p(e);return a(r,\"source\")||(r.source=b(m,\"string\"==typeof n?n:\"\")),e};Function.prototype.toString=y((function(){return i(this)&&f(this).source||s(this)}),\"toString\")},741:e=>{\"use strict\";var n=Math.ceil,t=Math.floor;e.exports=Math.trunc||function(e){var r=+e;return(r>0?t:n)(r)}},5749:(e,n,t)=>{\"use strict\";var r=t(788),o=TypeError;e.exports=function(e){if(r(e))throw new o(\"The method doesn't accept regular expressions\");return e}},4213:(e,n,t)=>{\"use strict\";var r=t(3724),o=t(9504),i=t(9565),a=t(9039),l=t(1072),c=t(3717),s=t(8773),u=t(8981),p=t(7055),f=Object.assign,d=Object.defineProperty,g=o([].concat);e.exports=!f||a((function(){if(r&&1!==f({b:1},f(d({},\"a\",{enumerable:!0,get:function(){d(this,\"b\",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var e={},n={},t=Symbol(\"assign detection\"),o=\"abcdefghijklmnopqrst\";return e[t]=7,o.split(\"\").forEach((function(e){n[e]=e})),7!==f({},e)[t]||l(f({},n)).join(\"\")!==o}))?function(e,n){for(var t=u(e),o=arguments.length,a=1,f=c.f,d=s.f;o>a;)for(var h,A=p(arguments[a++]),b=f?g(l(A),f(A)):l(A),v=b.length,m=0;v>m;)h=b[m++],r&&!i(d,A,h)||(t[h]=A[h]);return t}:f},2360:(e,n,t)=>{\"use strict\";var r,o=t(8551),i=t(6801),a=t(8727),l=t(421),c=t(397),s=t(4055),u=t(6119),p=\"prototype\",f=\"script\",d=u(\"IE_PROTO\"),g=function(){},h=function(e){return\"<\"+f+\">\"+e+\"</\"+f+\">\"},A=function(e){e.write(h(\"\")),e.close();var n=e.parentWindow.Object;return e=null,n},b=function(){try{r=new ActiveXObject(\"htmlfile\")}catch(e){}var e,n,t;b=\"undefined\"!=typeof document?document.domain&&r?A(r):(n=s(\"iframe\"),t=\"java\"+f+\":\",n.style.display=\"none\",c.appendChild(n),n.src=String(t),(e=n.contentWindow.document).open(),e.write(h(\"document.F=Object\")),e.close(),e.F):A(r);for(var o=a.length;o--;)delete b[p][a[o]];return b()};l[d]=!0,e.exports=Object.create||function(e,n){var t;return null!==e?(g[p]=o(e),t=new g,g[p]=null,t[d]=e):t=b(),void 0===n?t:i.f(t,n)}},6801:(e,n,t)=>{\"use strict\";var r=t(3724),o=t(8686),i=t(4913),a=t(8551),l=t(5397),c=t(1072);n.f=r&&!o?Object.defineProperties:function(e,n){a(e);for(var t,r=l(n),o=c(n),s=o.length,u=0;s>u;)i.f(e,t=o[u++],r[t]);return e}},4913:(e,n,t)=>{\"use strict\";var r=t(3724),o=t(5917),i=t(8686),a=t(8551),l=t(6969),c=TypeError,s=Object.defineProperty,u=Object.getOwnPropertyDescriptor,p=\"enumerable\",f=\"configurable\",d=\"writable\";n.f=r?i?function(e,n,t){if(a(e),n=l(n),a(t),\"function\"==typeof e&&\"prototype\"===n&&\"value\"in t&&d in t&&!t[d]){var r=u(e,n);r&&r[d]&&(e[n]=t.value,t={configurable:f in t?t[f]:r[f],enumerable:p in t?t[p]:r[p],writable:!1})}return s(e,n,t)}:s:function(e,n,t){if(a(e),n=l(n),a(t),o)try{return s(e,n,t)}catch(e){}if(\"get\"in t||\"set\"in t)throw new c(\"Accessors not supported\");return\"value\"in t&&(e[n]=t.value),e}},7347:(e,n,t)=>{\"use strict\";var r=t(3724),o=t(9565),i=t(8773),a=t(6980),l=t(5397),c=t(6969),s=t(9297),u=t(5917),p=Object.getOwnPropertyDescriptor;n.f=r?p:function(e,n){if(e=l(e),n=c(n),u)try{return p(e,n)}catch(e){}if(s(e,n))return a(!o(i.f,e,n),e[n])}},298:(e,n,t)=>{\"use strict\";var r=t(2195),o=t(5397),i=t(8480).f,a=t(7680),l=\"object\"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];e.exports.f=function(e){return l&&\"Window\"===r(e)?function(e){try{return i(e)}catch(e){return a(l)}}(e):i(o(e))}},8480:(e,n,t)=>{\"use strict\";var r=t(1828),o=t(8727).concat(\"length\",\"prototype\");n.f=Object.getOwnPropertyNames||function(e){return r(e,o)}},3717:(e,n)=>{\"use strict\";n.f=Object.getOwnPropertySymbols},2787:(e,n,t)=>{\"use strict\";var r=t(9297),o=t(4901),i=t(8981),a=t(6119),l=t(2211),c=a(\"IE_PROTO\"),s=Object,u=s.prototype;e.exports=l?s.getPrototypeOf:function(e){var n=i(e);if(r(n,c))return n[c];var t=n.constructor;return o(t)&&n instanceof t?t.prototype:n instanceof s?u:null}},4124:(e,n,t)=>{\"use strict\";var r=t(9039),o=t(34),i=t(2195),a=t(5652),l=Object.isExtensible,c=r((function(){l(1)}));e.exports=c||a?function(e){return!!o(e)&&((!a||\"ArrayBuffer\"!==i(e))&&(!l||l(e)))}:l},1625:(e,n,t)=>{\"use strict\";var r=t(9504);e.exports=r({}.isPrototypeOf)},1828:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(9297),i=t(5397),a=t(9617).indexOf,l=t(421),c=r([].push);e.exports=function(e,n){var t,r=i(e),s=0,u=[];for(t in r)!o(l,t)&&o(r,t)&&c(u,t);for(;n.length>s;)o(r,t=n[s++])&&(~a(u,t)||c(u,t));return u}},1072:(e,n,t)=>{\"use strict\";var r=t(1828),o=t(8727);e.exports=Object.keys||function(e){return r(e,o)}},8773:(e,n)=>{\"use strict\";var t={}.propertyIsEnumerable,r=Object.getOwnPropertyDescriptor,o=r&&!t.call({1:2},1);n.f=o?function(e){var n=r(this,e);return!!n&&n.enumerable}:t},2967:(e,n,t)=>{\"use strict\";var r=t(6706),o=t(34),i=t(7750),a=t(3506);e.exports=Object.setPrototypeOf||(\"__proto__\"in{}?function(){var e,n=!1,t={};try{(e=r(Object.prototype,\"__proto__\",\"set\"))(t,[]),n=t instanceof Array}catch(e){}return function(t,r){return i(t),a(r),o(t)?(n?e(t,r):t.__proto__=r,t):t}}():void 0)},2357:(e,n,t)=>{\"use strict\";var r=t(3724),o=t(9039),i=t(9504),a=t(2787),l=t(1072),c=t(5397),s=i(t(8773).f),u=i([].push),p=r&&o((function(){var e=Object.create(null);return e[2]=2,!s(e,2)})),f=function(e){return function(n){for(var t,o=c(n),i=l(o),f=p&&null===a(o),d=i.length,g=0,h=[];d>g;)t=i[g++],r&&!(f?t in o:s(o,t))||u(h,e?[t,o[t]]:o[t]);return h}};e.exports={entries:f(!0),values:f(!1)}},3179:(e,n,t)=>{\"use strict\";var r=t(2140),o=t(6955);e.exports=r?{}.toString:function(){return\"[object \"+o(this)+\"]\"}},4270:(e,n,t)=>{\"use strict\";var r=t(9565),o=t(4901),i=t(34),a=TypeError;e.exports=function(e,n){var t,l;if(\"string\"===n&&o(t=e.toString)&&!i(l=r(t,e)))return l;if(o(t=e.valueOf)&&!i(l=r(t,e)))return l;if(\"string\"!==n&&o(t=e.toString)&&!i(l=r(t,e)))return l;throw new a(\"Can't convert object to primitive value\")}},5031:(e,n,t)=>{\"use strict\";var r=t(7751),o=t(9504),i=t(8480),a=t(3717),l=t(8551),c=o([].concat);e.exports=r(\"Reflect\",\"ownKeys\")||function(e){var n=i.f(l(e)),t=a.f;return t?c(n,t(e)):n}},9167:(e,n,t)=>{\"use strict\";var r=t(4576);e.exports=r},6682:(e,n,t)=>{\"use strict\";var r=t(9565),o=t(8551),i=t(4901),a=t(2195),l=t(7323),c=TypeError;e.exports=function(e,n){var t=e.exec;if(i(t)){var s=r(t,e,n);return null!==s&&o(s),s}if(\"RegExp\"===a(e))return r(l,e,n);throw new c(\"RegExp#exec called on incompatible receiver\")}},7323:(e,n,t)=>{\"use strict\";var r,o,i=t(9565),a=t(9504),l=t(655),c=t(7979),s=t(8429),u=t(5745),p=t(2360),f=t(1181).get,d=t(3635),g=t(8814),h=u(\"native-string-replace\",String.prototype.replace),A=RegExp.prototype.exec,b=A,v=a(\"\".charAt),m=a(\"\".indexOf),y=a(\"\".replace),E=a(\"\".slice),C=(o=/b*/g,i(A,r=/a/,\"a\"),i(A,o,\"a\"),0!==r.lastIndex||0!==o.lastIndex),w=s.BROKEN_CARET,x=void 0!==/()??/.exec(\"\")[1];(C||x||w||d||g)&&(b=function(e){var n,t,r,o,a,s,u,d=this,g=f(d),S=l(e),_=g.raw;if(_)return _.lastIndex=d.lastIndex,n=i(b,_,S),d.lastIndex=_.lastIndex,n;var k=g.groups,O=w&&d.sticky,B=i(c,d),P=d.source,T=0,I=S;if(O&&(B=y(B,\"y\",\"\"),-1===m(B,\"g\")&&(B+=\"g\"),I=E(S,d.lastIndex),d.lastIndex>0&&(!d.multiline||d.multiline&&\"\\n\"!==v(S,d.lastIndex-1))&&(P=\"(?: \"+P+\")\",I=\" \"+I,T++),t=new RegExp(\"^(?:\"+P+\")\",B)),x&&(t=new RegExp(\"^\"+P+\"$(?!\\\\s)\",B)),C&&(r=d.lastIndex),o=i(A,O?t:d,I),O?o?(o.input=E(o.input,T),o[0]=E(o[0],T),o.index=d.lastIndex,d.lastIndex+=o[0].length):d.lastIndex=0:C&&o&&(d.lastIndex=d.global?o.index+o[0].length:r),x&&o&&o.length>1&&i(h,o[0],t,(function(){for(a=1;a<arguments.length-2;a++)void 0===arguments[a]&&(o[a]=void 0)})),o&&k)for(o.groups=s=p(null),a=0;a<k.length;a++)s[(u=k[a])[0]]=o[u[1]];return o}),e.exports=b},7979:(e,n,t)=>{\"use strict\";var r=t(8551);e.exports=function(){var e=r(this),n=\"\";return e.hasIndices&&(n+=\"d\"),e.global&&(n+=\"g\"),e.ignoreCase&&(n+=\"i\"),e.multiline&&(n+=\"m\"),e.dotAll&&(n+=\"s\"),e.unicode&&(n+=\"u\"),e.unicodeSets&&(n+=\"v\"),e.sticky&&(n+=\"y\"),n}},1034:(e,n,t)=>{\"use strict\";var r=t(9565),o=t(9297),i=t(1625),a=t(7979),l=RegExp.prototype;e.exports=function(e){var n=e.flags;return void 0!==n||\"flags\"in l||o(e,\"flags\")||!i(l,e)?n:r(a,e)}},8429:(e,n,t)=>{\"use strict\";var r=t(9039),o=t(4576).RegExp,i=r((function(){var e=o(\"a\",\"y\");return e.lastIndex=2,null!==e.exec(\"abcd\")})),a=i||r((function(){return!o(\"a\",\"y\").sticky})),l=i||r((function(){var e=o(\"^r\",\"gy\");return e.lastIndex=2,null!==e.exec(\"str\")}));e.exports={BROKEN_CARET:l,MISSED_STICKY:a,UNSUPPORTED_Y:i}},3635:(e,n,t)=>{\"use strict\";var r=t(9039),o=t(4576).RegExp;e.exports=r((function(){var e=o(\".\",\"s\");return!(e.dotAll&&e.test(\"\\n\")&&\"s\"===e.flags)}))},8814:(e,n,t)=>{\"use strict\";var r=t(9039),o=t(4576).RegExp;e.exports=r((function(){var e=o(\"(?<a>b)\",\"g\");return\"b\"!==e.exec(\"b\").groups.a||\"bc\"!==\"b\".replace(e,\"$<a>c\")}))},7750:(e,n,t)=>{\"use strict\";var r=t(4117),o=TypeError;e.exports=function(e){if(r(e))throw new o(\"Can't call method on \"+e);return e}},9472:(e,n,t)=>{\"use strict\";var r,o=t(4576),i=t(8745),a=t(4901),l=t(4215),c=t(2839),s=t(7680),u=t(2812),p=o.Function,f=/MSIE .\\./.test(c)||\"BUN\"===l&&((r=o.Bun.version.split(\".\")).length<3||\"0\"===r[0]&&(r[1]<3||\"3\"===r[1]&&\"0\"===r[2]));e.exports=function(e,n){var t=n?2:1;return f?function(r,o){var l=u(arguments.length,1)>t,c=a(r)?r:p(r),f=l?s(arguments,t):[],d=l?function(){i(c,this,f)}:c;return n?e(d,o):e(d)}:e}},7633:(e,n,t)=>{\"use strict\";var r=t(7751),o=t(2106),i=t(8227),a=t(3724),l=i(\"species\");e.exports=function(e){var n=r(e);a&&n&&!n[l]&&o(n,l,{configurable:!0,get:function(){return this}})}},687:(e,n,t)=>{\"use strict\";var r=t(4913).f,o=t(9297),i=t(8227)(\"toStringTag\");e.exports=function(e,n,t){e&&!t&&(e=e.prototype),e&&!o(e,i)&&r(e,i,{configurable:!0,value:n})}},6119:(e,n,t)=>{\"use strict\";var r=t(5745),o=t(3392),i=r(\"keys\");e.exports=function(e){return i[e]||(i[e]=o(e))}},7629:(e,n,t)=>{\"use strict\";var r=t(6395),o=t(4576),i=t(9433),a=\"__core-js_shared__\",l=e.exports=o[a]||i(a,{});(l.versions||(l.versions=[])).push({version:\"3.42.0\",mode:r?\"pure\":\"global\",copyright:\"© 2014-2025 Denis Pushkarev (zloirock.ru)\",license:\"https://github.com/zloirock/core-js/blob/v3.42.0/LICENSE\",source:\"https://github.com/zloirock/core-js\"})},5745:(e,n,t)=>{\"use strict\";var r=t(7629);e.exports=function(e,n){return r[e]||(r[e]=n||{})}},2293:(e,n,t)=>{\"use strict\";var r=t(8551),o=t(5548),i=t(4117),a=t(8227)(\"species\");e.exports=function(e,n){var t,l=r(e).constructor;return void 0===l||i(t=r(l)[a])?n:o(t)}},3061:(e,n,t)=>{\"use strict\";var r=t(9039);e.exports=function(e){return r((function(){var n=\"\"[e]('\"');return n!==n.toLowerCase()||n.split('\"').length>3}))}},8183:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(1291),i=t(655),a=t(7750),l=r(\"\".charAt),c=r(\"\".charCodeAt),s=r(\"\".slice),u=function(e){return function(n,t){var r,u,p=i(a(n)),f=o(t),d=p.length;return f<0||f>=d?e?\"\":void 0:(r=c(p,f))<55296||r>56319||f+1===d||(u=c(p,f+1))<56320||u>57343?e?l(p,f):r:e?s(p,f,f+2):u-56320+(r-55296<<10)+65536}};e.exports={codeAt:u(!1),charAt:u(!0)}},706:(e,n,t)=>{\"use strict\";var r=t(350).PROPER,o=t(9039),i=t(7452);e.exports=function(e){return o((function(){return!!i[e]()||\"​᠎\"!==\"​᠎\"[e]()||r&&i[e].name!==e}))}},3802:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(7750),i=t(655),a=t(7452),l=r(\"\".replace),c=RegExp(\"^[\"+a+\"]+\"),s=RegExp(\"(^|[^\"+a+\"])[\"+a+\"]+$\"),u=function(e){return function(n){var t=i(o(n));return 1&e&&(t=l(t,c,\"\")),2&e&&(t=l(t,s,\"$1\")),t}};e.exports={start:u(1),end:u(2),trim:u(3)}},4495:(e,n,t)=>{\"use strict\";var r=t(9519),o=t(9039),i=t(4576).String;e.exports=!!Object.getOwnPropertySymbols&&!o((function(){var e=Symbol(\"symbol detection\");return!i(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&r&&r<41}))},8242:(e,n,t)=>{\"use strict\";var r=t(9565),o=t(7751),i=t(8227),a=t(6840);e.exports=function(){var e=o(\"Symbol\"),n=e&&e.prototype,t=n&&n.valueOf,l=i(\"toPrimitive\");n&&!n[l]&&a(n,l,(function(e){return r(t,this)}),{arity:1})}},1296:(e,n,t)=>{\"use strict\";var r=t(4495);e.exports=r&&!!Symbol.for&&!!Symbol.keyFor},1240:(e,n,t)=>{\"use strict\";var r=t(9504);e.exports=r(1..valueOf)},5610:(e,n,t)=>{\"use strict\";var r=t(1291),o=Math.max,i=Math.min;e.exports=function(e,n){var t=r(e);return t<0?o(t+n,0):i(t,n)}},5397:(e,n,t)=>{\"use strict\";var r=t(7055),o=t(7750);e.exports=function(e){return r(o(e))}},1291:(e,n,t)=>{\"use strict\";var r=t(741);e.exports=function(e){var n=+e;return n!=n||0===n?0:r(n)}},8014:(e,n,t)=>{\"use strict\";var r=t(1291),o=Math.min;e.exports=function(e){var n=r(e);return n>0?o(n,9007199254740991):0}},8981:(e,n,t)=>{\"use strict\";var r=t(7750),o=Object;e.exports=function(e){return o(r(e))}},2777:(e,n,t)=>{\"use strict\";var r=t(9565),o=t(34),i=t(757),a=t(5966),l=t(4270),c=t(8227),s=TypeError,u=c(\"toPrimitive\");e.exports=function(e,n){if(!o(e)||i(e))return e;var t,c=a(e,u);if(c){if(void 0===n&&(n=\"default\"),t=r(c,e,n),!o(t)||i(t))return t;throw new s(\"Can't convert object to primitive value\")}return void 0===n&&(n=\"number\"),l(e,n)}},6969:(e,n,t)=>{\"use strict\";var r=t(2777),o=t(757);e.exports=function(e){var n=r(e,\"string\");return o(n)?n:n+\"\"}},2140:(e,n,t)=>{\"use strict\";var r={};r[t(8227)(\"toStringTag\")]=\"z\",e.exports=\"[object z]\"===String(r)},655:(e,n,t)=>{\"use strict\";var r=t(6955),o=String;e.exports=function(e){if(\"Symbol\"===r(e))throw new TypeError(\"Cannot convert a Symbol value to a string\");return o(e)}},6823:e=>{\"use strict\";var n=String;e.exports=function(e){try{return n(e)}catch(e){return\"Object\"}}},3392:(e,n,t)=>{\"use strict\";var r=t(9504),o=0,i=Math.random(),a=r(1..toString);e.exports=function(e){return\"Symbol(\"+(void 0===e?\"\":e)+\")_\"+a(++o+i,36)}},7040:(e,n,t)=>{\"use strict\";var r=t(4495);e.exports=r&&!Symbol.sham&&\"symbol\"==typeof Symbol.iterator},8686:(e,n,t)=>{\"use strict\";var r=t(3724),o=t(9039);e.exports=r&&o((function(){return 42!==Object.defineProperty((function(){}),\"prototype\",{value:42,writable:!1}).prototype}))},2812:e=>{\"use strict\";var n=TypeError;e.exports=function(e,t){if(e<t)throw new n(\"Not enough arguments\");return e}},8622:(e,n,t)=>{\"use strict\";var r=t(4576),o=t(4901),i=r.WeakMap;e.exports=o(i)&&/native code/.test(String(i))},511:(e,n,t)=>{\"use strict\";var r=t(9167),o=t(9297),i=t(1951),a=t(4913).f;e.exports=function(e){var n=r.Symbol||(r.Symbol={});o(n,e)||a(n,e,{value:i.f(e)})}},1951:(e,n,t)=>{\"use strict\";var r=t(8227);n.f=r},8227:(e,n,t)=>{\"use strict\";var r=t(4576),o=t(5745),i=t(9297),a=t(3392),l=t(4495),c=t(7040),s=r.Symbol,u=o(\"wks\"),p=c?s.for||s:s&&s.withoutSetter||a;e.exports=function(e){return i(u,e)||(u[e]=l&&i(s,e)?s[e]:p(\"Symbol.\"+e)),u[e]}},7452:e=>{\"use strict\";e.exports=\"\\t\\n\\v\\f\\r                　\\u2028\\u2029\\ufeff\"},8706:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9039),i=t(4376),a=t(34),l=t(8981),c=t(6198),s=t(6837),u=t(4659),p=t(1469),f=t(597),d=t(8227),g=t(9519),h=d(\"isConcatSpreadable\"),A=g>=51||!o((function(){var e=[];return e[h]=!1,e.concat()[0]!==e})),b=function(e){if(!a(e))return!1;var n=e[h];return void 0!==n?!!n:i(e)};r({target:\"Array\",proto:!0,arity:1,forced:!A||!f(\"concat\")},{concat:function(e){var n,t,r,o,i,a=l(this),f=p(a,0),d=0;for(n=-1,r=arguments.length;n<r;n++)if(b(i=-1===n?a:arguments[n]))for(o=c(i),s(d+o),t=0;t<o;t++,d++)t in i&&u(f,d,i[t]);else s(d+1),u(f,d++,i);return f.length=d,f}})},8431:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9213).every;r({target:\"Array\",proto:!0,forced:!t(4598)(\"every\")},{every:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},2008:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9213).filter;r({target:\"Array\",proto:!0,forced:!t(597)(\"filter\")},{filter:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},8980:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9213).findIndex,i=t(6469),a=\"findIndex\",l=!0;a in[]&&Array(1)[a]((function(){l=!1})),r({target:\"Array\",proto:!0,forced:l},{findIndex:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}}),i(a)},113:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9213).find,i=t(6469),a=\"find\",l=!0;a in[]&&Array(1)[a]((function(){l=!1})),r({target:\"Array\",proto:!0,forced:l},{find:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}}),i(a)},1629:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(235);r({target:\"Array\",proto:!0,forced:[].forEach!==o},{forEach:o})},3418:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(7916);r({target:\"Array\",stat:!0,forced:!t(4428)((function(e){Array.from(e)}))},{from:o})},4423:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9617).includes,i=t(9039),a=t(6469);r({target:\"Array\",proto:!0,forced:i((function(){return!Array(1).includes()}))},{includes:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}}),a(\"includes\")},5276:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(7476),i=t(9617).indexOf,a=t(4598),l=o([].indexOf),c=!!l&&1/l([1],1,-0)<0;r({target:\"Array\",proto:!0,forced:c||!a(\"indexOf\")},{indexOf:function(e){var n=arguments.length>1?arguments[1]:void 0;return c?l(this,e,n)||0:i(this,e,n)}})},4346:(e,n,t)=>{\"use strict\";t(6518)({target:\"Array\",stat:!0},{isArray:t(4376)})},3792:(e,n,t)=>{\"use strict\";var r=t(5397),o=t(6469),i=t(6269),a=t(1181),l=t(4913).f,c=t(1088),s=t(2529),u=t(6395),p=t(3724),f=\"Array Iterator\",d=a.set,g=a.getterFor(f);e.exports=c(Array,\"Array\",(function(e,n){d(this,{type:f,target:r(e),index:0,kind:n})}),(function(){var e=g(this),n=e.target,t=e.index++;if(!n||t>=n.length)return e.target=null,s(void 0,!0);switch(e.kind){case\"keys\":return s(t,!1);case\"values\":return s(n[t],!1)}return s([t,n[t]],!1)}),\"values\");var h=i.Arguments=i.Array;if(o(\"keys\"),o(\"values\"),o(\"entries\"),!u&&p&&\"values\"!==h.name)try{l(h,\"name\",{value:\"values\"})}catch(e){}},8598:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9504),i=t(7055),a=t(5397),l=t(4598),c=o([].join);r({target:\"Array\",proto:!0,forced:i!==Object||!l(\"join\",\",\")},{join:function(e){return c(a(this),void 0===e?\",\":e)}})},2062:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9213).map;r({target:\"Array\",proto:!0,forced:!t(597)(\"map\")},{map:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},2712:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(926).left,i=t(4598),a=t(9519);r({target:\"Array\",proto:!0,forced:!t(6193)&&a>79&&a<83||!i(\"reduce\")},{reduce:function(e){var n=arguments.length;return o(this,e,n,n>1?arguments[1]:void 0)}})},4782:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(4376),i=t(3517),a=t(34),l=t(5610),c=t(6198),s=t(5397),u=t(4659),p=t(8227),f=t(597),d=t(7680),g=f(\"slice\"),h=p(\"species\"),A=Array,b=Math.max;r({target:\"Array\",proto:!0,forced:!g},{slice:function(e,n){var t,r,p,f=s(this),g=c(f),v=l(e,g),m=l(void 0===n?g:n,g);if(o(f)&&(t=f.constructor,(i(t)&&(t===A||o(t.prototype))||a(t)&&null===(t=t[h]))&&(t=void 0),t===A||void 0===t))return d(f,v,m);for(r=new(void 0===t?A:t)(b(m-v,0)),p=0;v<m;v++,p++)v in f&&u(r,p,f[v]);return r.length=p,r}})},5086:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9213).some;r({target:\"Array\",proto:!0,forced:!t(4598)(\"some\")},{some:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},6910:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9504),i=t(9306),a=t(8981),l=t(6198),c=t(4606),s=t(655),u=t(9039),p=t(4488),f=t(4598),d=t(6090),g=t(3763),h=t(9519),A=t(3607),b=[],v=o(b.sort),m=o(b.push),y=u((function(){b.sort(void 0)})),E=u((function(){b.sort(null)})),C=f(\"sort\"),w=!u((function(){if(h)return h<70;if(!(d&&d>3)){if(g)return!0;if(A)return A<603;var e,n,t,r,o=\"\";for(e=65;e<76;e++){switch(n=String.fromCharCode(e),e){case 66:case 69:case 70:case 72:t=3;break;case 68:case 71:t=4;break;default:t=2}for(r=0;r<47;r++)b.push({k:n+r,v:t})}for(b.sort((function(e,n){return n.v-e.v})),r=0;r<b.length;r++)n=b[r].k.charAt(0),o.charAt(o.length-1)!==n&&(o+=n);return\"DGBEFHACIJK\"!==o}}));r({target:\"Array\",proto:!0,forced:y||!E||!C||!w},{sort:function(e){void 0!==e&&i(e);var n=a(this);if(w)return void 0===e?v(n):v(n,e);var t,r,o=[],u=l(n);for(r=0;r<u;r++)r in n&&m(o,n[r]);for(p(o,function(e){return function(n,t){return void 0===t?-1:void 0===n?1:void 0!==e?+e(n,t)||0:s(n)>s(t)?1:-1}}(e)),t=l(o),r=0;r<t;)n[r]=o[r++];for(;r<u;)c(n,r++);return n}})},4554:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(8981),i=t(5610),a=t(1291),l=t(6198),c=t(4527),s=t(6837),u=t(1469),p=t(4659),f=t(4606),d=t(597)(\"splice\"),g=Math.max,h=Math.min;r({target:\"Array\",proto:!0,forced:!d},{splice:function(e,n){var t,r,d,A,b,v,m=o(this),y=l(m),E=i(e,y),C=arguments.length;for(0===C?t=r=0:1===C?(t=0,r=y-E):(t=C-2,r=h(g(a(n),0),y-E)),s(y+t-r),d=u(m,r),A=0;A<r;A++)(b=E+A)in m&&p(d,A,m[b]);if(d.length=r,t<r){for(A=E;A<y-r;A++)v=A+t,(b=A+r)in m?m[v]=m[b]:f(m,v);for(A=y;A>y-r+t;A--)f(m,A-1)}else if(t>r)for(A=y-r;A>E;A--)v=A+t-1,(b=A+r-1)in m?m[v]=m[b]:f(m,v);for(A=0;A<t;A++)m[A+E]=arguments[A+2];return c(m,y-r+t),d}})},9089:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9504),i=Date,a=o(i.prototype.getTime);r({target:\"Date\",stat:!0},{now:function(){return a(new i)}})},739:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9039),i=t(8981),a=t(2777);r({target:\"Date\",proto:!0,arity:1,forced:o((function(){return null!==new Date(NaN).toJSON()||1!==Date.prototype.toJSON.call({toISOString:function(){return 1}})}))},{toJSON:function(e){var n=i(this),t=a(n,\"number\");return\"number\"!=typeof t||isFinite(t)?n.toISOString():null}})},9572:(e,n,t)=>{\"use strict\";var r=t(9297),o=t(6840),i=t(3640),a=t(8227)(\"toPrimitive\"),l=Date.prototype;r(l,a)||o(l,a,i)},3288:(e,n,t)=>{\"use strict\";var r=t(9504),o=t(6840),i=Date.prototype,a=\"Invalid Date\",l=\"toString\",c=r(i[l]),s=r(i.getTime);String(new Date(NaN))!==a&&o(i,l,(function(){var e=s(this);return e==e?c(this):a}))},4170:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(566);r({target:\"Function\",proto:!0,forced:Function.bind!==o},{bind:o})},2010:(e,n,t)=>{\"use strict\";var r=t(3724),o=t(350).EXISTS,i=t(9504),a=t(2106),l=Function.prototype,c=i(l.toString),s=/function\\b(?:\\s|\\/\\*[\\S\\s]*?\\*\\/|\\/\\/[^\\n\\r]*[\\n\\r]+)*([^\\s(/]*)/,u=i(s.exec);r&&!o&&a(l,\"name\",{configurable:!0,get:function(){try{return u(s,c(this))[1]}catch(e){return\"\"}}})},3110:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(7751),i=t(8745),a=t(9565),l=t(9504),c=t(9039),s=t(4901),u=t(757),p=t(7680),f=t(6933),d=t(4495),g=String,h=o(\"JSON\",\"stringify\"),A=l(/./.exec),b=l(\"\".charAt),v=l(\"\".charCodeAt),m=l(\"\".replace),y=l(1..toString),E=/[\\uD800-\\uDFFF]/g,C=/^[\\uD800-\\uDBFF]$/,w=/^[\\uDC00-\\uDFFF]$/,x=!d||c((function(){var e=o(\"Symbol\")(\"stringify detection\");return\"[null]\"!==h([e])||\"{}\"!==h({a:e})||\"{}\"!==h(Object(e))})),S=c((function(){return'\"\\\\udf06\\\\ud834\"'!==h(\"\\udf06\\ud834\")||'\"\\\\udead\"'!==h(\"\\udead\")})),_=function(e,n){var t=p(arguments),r=f(n);if(s(r)||void 0!==e&&!u(e))return t[1]=function(e,n){if(s(r)&&(n=a(r,this,g(e),n)),!u(n))return n},i(h,null,t)},k=function(e,n,t){var r=b(t,n-1),o=b(t,n+1);return A(C,e)&&!A(w,o)||A(w,e)&&!A(C,r)?\"\\\\u\"+y(v(e,0),16):e};h&&r({target:\"JSON\",stat:!0,arity:3,forced:x||S},{stringify:function(e,n,t){var r=p(arguments),o=i(x?_:h,null,r);return S&&\"string\"==typeof o?m(o,E,k):o}})},8523:(e,n,t)=>{\"use strict\";t(6468)(\"Map\",(function(e){return function(){return e(this,arguments.length?arguments[0]:void 0)}}),t(6938))},6033:(e,n,t)=>{\"use strict\";t(8523)},2152:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9039),i=Math.imul;r({target:\"Math\",stat:!0,forced:o((function(){return-5!==i(4294967295,5)||2!==i.length}))},{imul:function(e,n){var t=65535,r=+e,o=+n,i=t&r,a=t&o;return 0|i*a+((t&r>>>16)*a+i*(t&o>>>16)<<16>>>0)}})},2892:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(6395),i=t(3724),a=t(4576),l=t(9167),c=t(9504),s=t(2796),u=t(9297),p=t(3167),f=t(1625),d=t(757),g=t(2777),h=t(9039),A=t(8480).f,b=t(7347).f,v=t(4913).f,m=t(1240),y=t(3802).trim,E=\"Number\",C=a[E],w=l[E],x=C.prototype,S=a.TypeError,_=c(\"\".slice),k=c(\"\".charCodeAt),O=function(e){var n,t,r,o,i,a,l,c,s=g(e,\"number\");if(d(s))throw new S(\"Cannot convert a Symbol value to a number\");if(\"string\"==typeof s&&s.length>2)if(s=y(s),43===(n=k(s,0))||45===n){if(88===(t=k(s,2))||120===t)return NaN}else if(48===n){switch(k(s,1)){case 66:case 98:r=2,o=49;break;case 79:case 111:r=8,o=55;break;default:return+s}for(a=(i=_(s,2)).length,l=0;l<a;l++)if((c=k(i,l))<48||c>o)return NaN;return parseInt(i,r)}return+s},B=s(E,!C(\" 0o1\")||!C(\"0b1\")||C(\"+0x1\")),P=function(e){var n,t=arguments.length<1?0:C(function(e){var n=g(e,\"number\");return\"bigint\"==typeof n?n:O(n)}(e));return f(x,n=this)&&h((function(){m(n)}))?p(Object(t),this,P):t};P.prototype=x,B&&!o&&(x.constructor=P),r({global:!0,constructor:!0,wrap:!0,forced:B},{Number:P});var T=function(e,n){for(var t,r=i?A(n):\"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,isFinite,isInteger,isNaN,isSafeInteger,parseFloat,parseInt,fromString,range\".split(\",\"),o=0;r.length>o;o++)u(n,t=r[o])&&!u(e,t)&&v(e,t,b(n,t))};o&&w&&T(l[E],w),(B||o)&&T(l[E],C)},9085:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(4213);r({target:\"Object\",stat:!0,arity:2,forced:Object.assign!==o},{assign:o})},9904:(e,n,t)=>{\"use strict\";t(6518)({target:\"Object\",stat:!0,sham:!t(3724)},{create:t(2360)})},7945:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(3724),i=t(6801).f;r({target:\"Object\",stat:!0,forced:Object.defineProperties!==i,sham:!o},{defineProperties:i})},4185:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(3724),i=t(4913).f;r({target:\"Object\",stat:!0,forced:Object.defineProperty!==i,sham:!o},{defineProperty:i})},5506:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(2357).entries;r({target:\"Object\",stat:!0},{entries:function(e){return o(e)}})},3851:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9039),i=t(5397),a=t(7347).f,l=t(3724);r({target:\"Object\",stat:!0,forced:!l||o((function(){a(1)})),sham:!l},{getOwnPropertyDescriptor:function(e,n){return a(i(e),n)}})},1278:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(3724),i=t(5031),a=t(5397),l=t(7347),c=t(4659);r({target:\"Object\",stat:!0,sham:!o},{getOwnPropertyDescriptors:function(e){for(var n,t,r=a(e),o=l.f,s=i(r),u={},p=0;s.length>p;)void 0!==(t=o(r,n=s[p++]))&&c(u,n,t);return u}})},9773:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(4495),i=t(9039),a=t(3717),l=t(8981);r({target:\"Object\",stat:!0,forced:!o||i((function(){a.f(1)}))},{getOwnPropertySymbols:function(e){var n=a.f;return n?n(l(e)):[]}})},875:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9039),i=t(8981),a=t(2787),l=t(2211);r({target:\"Object\",stat:!0,forced:o((function(){a(1)})),sham:!l},{getPrototypeOf:function(e){return a(i(e))}})},9432:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(8981),i=t(1072);r({target:\"Object\",stat:!0,forced:t(9039)((function(){i(1)}))},{keys:function(e){return i(o(e))}})},287:(e,n,t)=>{\"use strict\";t(6518)({target:\"Object\",stat:!0},{setPrototypeOf:t(2967)})},6099:(e,n,t)=>{\"use strict\";var r=t(2140),o=t(6840),i=t(3179);r||o(Object.prototype,\"toString\",i,{unsafe:!0})},6034:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(2357).values;r({target:\"Object\",stat:!0},{values:function(e){return o(e)}})},825:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(7751),i=t(8745),a=t(566),l=t(5548),c=t(8551),s=t(34),u=t(2360),p=t(9039),f=o(\"Reflect\",\"construct\"),d=Object.prototype,g=[].push,h=p((function(){function e(){}return!(f((function(){}),[],e)instanceof e)})),A=!p((function(){f((function(){}))})),b=h||A;r({target:\"Reflect\",stat:!0,forced:b,sham:b},{construct:function(e,n){l(e),c(n);var t=arguments.length<3?e:l(arguments[2]);if(A&&!h)return f(e,n,t);if(e===t){switch(n.length){case 0:return new e;case 1:return new e(n[0]);case 2:return new e(n[0],n[1]);case 3:return new e(n[0],n[1],n[2]);case 4:return new e(n[0],n[1],n[2],n[3])}var r=[null];return i(g,r,n),new(i(a,e,r))}var o=t.prototype,p=u(s(o)?o:d),b=i(e,p,n);return s(b)?b:p}})},7495:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(7323);r({target:\"RegExp\",proto:!0,forced:/./.exec!==o},{exec:o})},8781:(e,n,t)=>{\"use strict\";var r=t(350).PROPER,o=t(6840),i=t(8551),a=t(655),l=t(9039),c=t(1034),s=\"toString\",u=RegExp.prototype,p=u[s],f=l((function(){return\"/a/b\"!==p.call({source:\"a\",flags:\"b\"})})),d=r&&p.name!==s;(f||d)&&o(u,s,(function(){var e=i(this);return\"/\"+a(e.source)+\"/\"+a(c(e))}),{unsafe:!0})},2405:(e,n,t)=>{\"use strict\";t(6468)(\"Set\",(function(e){return function(){return e(this,arguments.length?arguments[0]:void 0)}}),t(6938))},1415:(e,n,t)=>{\"use strict\";t(2405)},9907:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(7240);r({target:\"String\",proto:!0,forced:t(3061)(\"anchor\")},{anchor:function(e){return o(this,\"a\",\"name\",e)}})},1699:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9504),i=t(5749),a=t(7750),l=t(655),c=t(1436),s=o(\"\".indexOf);r({target:\"String\",proto:!0,forced:!c(\"includes\")},{includes:function(e){return!!~s(l(a(this)),l(i(e)),arguments.length>1?arguments[1]:void 0)}})},7764:(e,n,t)=>{\"use strict\";var r=t(8183).charAt,o=t(655),i=t(1181),a=t(1088),l=t(2529),c=\"String Iterator\",s=i.set,u=i.getterFor(c);a(String,\"String\",(function(e){s(this,{type:c,string:o(e),index:0})}),(function(){var e,n=u(this),t=n.string,o=n.index;return o>=t.length?l(void 0,!0):(e=r(t,o),n.index+=e.length,l(e,!1))}))},778:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(7240);r({target:\"String\",proto:!0,forced:t(3061)(\"link\")},{link:function(e){return o(this,\"a\",\"href\",e)}})},1761:(e,n,t)=>{\"use strict\";var r=t(9565),o=t(9228),i=t(8551),a=t(34),l=t(8014),c=t(655),s=t(7750),u=t(5966),p=t(7829),f=t(6682);o(\"match\",(function(e,n,t){return[function(n){var t=s(this),o=a(n)?u(n,e):void 0;return o?r(o,n,t):new RegExp(n)[e](c(t))},function(e){var r=i(this),o=c(e),a=t(n,r,o);if(a.done)return a.value;if(!r.global)return f(r,o);var s=r.unicode;r.lastIndex=0;for(var u,d=[],g=0;null!==(u=f(r,o));){var h=c(u[0]);d[g]=h,\"\"===h&&(r.lastIndex=p(o,l(r.lastIndex),s)),g++}return 0===g?null:d}]}))},5440:(e,n,t)=>{\"use strict\";var r=t(8745),o=t(9565),i=t(9504),a=t(9228),l=t(9039),c=t(8551),s=t(4901),u=t(34),p=t(1291),f=t(8014),d=t(655),g=t(7750),h=t(7829),A=t(5966),b=t(2478),v=t(6682),m=t(8227)(\"replace\"),y=Math.max,E=Math.min,C=i([].concat),w=i([].push),x=i(\"\".indexOf),S=i(\"\".slice),_=\"$0\"===\"a\".replace(/./,\"$0\"),k=!!/./[m]&&\"\"===/./[m](\"a\",\"$0\");a(\"replace\",(function(e,n,t){var i=k?\"$\":\"$0\";return[function(e,t){var r=g(this),i=u(e)?A(e,m):void 0;return i?o(i,e,r,t):o(n,d(r),e,t)},function(e,o){var a=c(this),l=d(e);if(\"string\"==typeof o&&-1===x(o,i)&&-1===x(o,\"$<\")){var u=t(n,a,l,o);if(u.done)return u.value}var g=s(o);g||(o=d(o));var A,m=a.global;m&&(A=a.unicode,a.lastIndex=0);for(var _,k=[];null!==(_=v(a,l))&&(w(k,_),m);){\"\"===d(_[0])&&(a.lastIndex=h(l,f(a.lastIndex),A))}for(var O,B=\"\",P=0,T=0;T<k.length;T++){for(var I,j=d((_=k[T])[0]),z=y(E(p(_.index),l.length),0),D=[],R=1;R<_.length;R++)w(D,void 0===(O=_[R])?O:String(O));var M=_.groups;if(g){var N=C([j],D,z,l);void 0!==M&&w(N,M),I=d(r(o,void 0,N))}else I=b(j,l,z,D,M,o);z>=P&&(B+=S(l,P,z)+I,P=z+j.length)}return B+S(l,P)}]}),!!l((function(){var e=/./;return e.exec=function(){var e=[];return e.groups={a:\"7\"},e},\"7\"!==\"\".replace(e,\"$<a>\")}))||!_||k)},744:(e,n,t)=>{\"use strict\";var r=t(9565),o=t(9504),i=t(9228),a=t(8551),l=t(34),c=t(7750),s=t(2293),u=t(7829),p=t(8014),f=t(655),d=t(5966),g=t(6682),h=t(8429),A=t(9039),b=h.UNSUPPORTED_Y,v=Math.min,m=o([].push),y=o(\"\".slice),E=!A((function(){var e=/(?:)/,n=e.exec;e.exec=function(){return n.apply(this,arguments)};var t=\"ab\".split(e);return 2!==t.length||\"a\"!==t[0]||\"b\"!==t[1]})),C=\"c\"===\"abbc\".split(/(b)*/)[1]||4!==\"test\".split(/(?:)/,-1).length||2!==\"ab\".split(/(?:ab)*/).length||4!==\".\".split(/(.?)(.?)/).length||\".\".split(/()()/).length>1||\"\".split(/.?/).length;i(\"split\",(function(e,n,t){var o=\"0\".split(void 0,0).length?function(e,t){return void 0===e&&0===t?[]:r(n,this,e,t)}:n;return[function(n,t){var i=c(this),a=l(n)?d(n,e):void 0;return a?r(a,n,i,t):r(o,f(i),n,t)},function(e,r){var i=a(this),l=f(e);if(!C){var c=t(o,i,l,r,o!==n);if(c.done)return c.value}var d=s(i,RegExp),h=i.unicode,A=(i.ignoreCase?\"i\":\"\")+(i.multiline?\"m\":\"\")+(i.unicode?\"u\":\"\")+(b?\"g\":\"y\"),E=new d(b?\"^(?:\"+i.source+\")\":i,A),w=void 0===r?4294967295:r>>>0;if(0===w)return[];if(0===l.length)return null===g(E,l)?[l]:[];for(var x=0,S=0,_=[];S<l.length;){E.lastIndex=b?0:S;var k,O=g(E,b?y(l,S):l);if(null===O||(k=v(p(E.lastIndex+(b?S:0)),l.length))===x)S=u(l,S,h);else{if(m(_,y(l,x,S)),_.length===w)return _;for(var B=1;B<=O.length-1;B++)if(m(_,O[B]),_.length===w)return _;S=x=k}}return m(_,y(l,x)),_}]}),C||!E,b)},1392:(e,n,t)=>{\"use strict\";var r,o=t(6518),i=t(7476),a=t(7347).f,l=t(8014),c=t(655),s=t(5749),u=t(7750),p=t(1436),f=t(6395),d=i(\"\".slice),g=Math.min,h=p(\"startsWith\");o({target:\"String\",proto:!0,forced:!!(f||h||(r=a(String.prototype,\"startsWith\"),!r||r.writable))&&!h},{startsWith:function(e){var n=c(u(this));s(e);var t=l(g(arguments.length>1?arguments[1]:void 0,n.length)),r=c(e);return d(n,t,t+r.length)===r}})},2762:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(3802).trim;r({target:\"String\",proto:!0,forced:t(706)(\"trim\")},{trim:function(){return o(this)}})},6761:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(4576),i=t(9565),a=t(9504),l=t(6395),c=t(3724),s=t(4495),u=t(9039),p=t(9297),f=t(1625),d=t(8551),g=t(5397),h=t(6969),A=t(655),b=t(6980),v=t(2360),m=t(1072),y=t(8480),E=t(298),C=t(3717),w=t(7347),x=t(4913),S=t(6801),_=t(8773),k=t(6840),O=t(2106),B=t(5745),P=t(6119),T=t(421),I=t(3392),j=t(8227),z=t(1951),D=t(511),R=t(8242),M=t(687),N=t(1181),F=t(9213).forEach,L=P(\"hidden\"),H=\"Symbol\",U=\"prototype\",W=N.set,G=N.getterFor(H),Y=Object[U],q=o.Symbol,V=q&&q[U],$=o.RangeError,K=o.TypeError,Q=o.QObject,X=w.f,Z=x.f,J=E.f,ee=_.f,ne=a([].push),te=B(\"symbols\"),re=B(\"op-symbols\"),oe=B(\"wks\"),ie=!Q||!Q[U]||!Q[U].findChild,ae=function(e,n,t){var r=X(Y,n);r&&delete Y[n],Z(e,n,t),r&&e!==Y&&Z(Y,n,r)},le=c&&u((function(){return 7!==v(Z({},\"a\",{get:function(){return Z(this,\"a\",{value:7}).a}})).a}))?ae:Z,ce=function(e,n){var t=te[e]=v(V);return W(t,{type:H,tag:e,description:n}),c||(t.description=n),t},se=function(e,n,t){e===Y&&se(re,n,t),d(e);var r=h(n);return d(t),p(te,r)?(t.enumerable?(p(e,L)&&e[L][r]&&(e[L][r]=!1),t=v(t,{enumerable:b(0,!1)})):(p(e,L)||Z(e,L,b(1,v(null))),e[L][r]=!0),le(e,r,t)):Z(e,r,t)},ue=function(e,n){d(e);var t=g(n),r=m(t).concat(ge(t));return F(r,(function(n){c&&!i(pe,t,n)||se(e,n,t[n])})),e},pe=function(e){var n=h(e),t=i(ee,this,n);return!(this===Y&&p(te,n)&&!p(re,n))&&(!(t||!p(this,n)||!p(te,n)||p(this,L)&&this[L][n])||t)},fe=function(e,n){var t=g(e),r=h(n);if(t!==Y||!p(te,r)||p(re,r)){var o=X(t,r);return!o||!p(te,r)||p(t,L)&&t[L][r]||(o.enumerable=!0),o}},de=function(e){var n=J(g(e)),t=[];return F(n,(function(e){p(te,e)||p(T,e)||ne(t,e)})),t},ge=function(e){var n=e===Y,t=J(n?re:g(e)),r=[];return F(t,(function(e){!p(te,e)||n&&!p(Y,e)||ne(r,te[e])})),r};s||(k(V=(q=function(){if(f(V,this))throw new K(\"Symbol is not a constructor\");var e=arguments.length&&void 0!==arguments[0]?A(arguments[0]):void 0,n=I(e),t=function(e){var r=void 0===this?o:this;r===Y&&i(t,re,e),p(r,L)&&p(r[L],n)&&(r[L][n]=!1);var a=b(1,e);try{le(r,n,a)}catch(e){if(!(e instanceof $))throw e;ae(r,n,a)}};return c&&ie&&le(Y,n,{configurable:!0,set:t}),ce(n,e)})[U],\"toString\",(function(){return G(this).tag})),k(q,\"withoutSetter\",(function(e){return ce(I(e),e)})),_.f=pe,x.f=se,S.f=ue,w.f=fe,y.f=E.f=de,C.f=ge,z.f=function(e){return ce(j(e),e)},c&&(O(V,\"description\",{configurable:!0,get:function(){return G(this).description}}),l||k(Y,\"propertyIsEnumerable\",pe,{unsafe:!0}))),r({global:!0,constructor:!0,wrap:!0,forced:!s,sham:!s},{Symbol:q}),F(m(oe),(function(e){D(e)})),r({target:H,stat:!0,forced:!s},{useSetter:function(){ie=!0},useSimple:function(){ie=!1}}),r({target:\"Object\",stat:!0,forced:!s,sham:!c},{create:function(e,n){return void 0===n?v(e):ue(v(e),n)},defineProperty:se,defineProperties:ue,getOwnPropertyDescriptor:fe}),r({target:\"Object\",stat:!0,forced:!s},{getOwnPropertyNames:de}),R(),M(q,H),T[L]=!0},9463:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(3724),i=t(4576),a=t(9504),l=t(9297),c=t(4901),s=t(1625),u=t(655),p=t(2106),f=t(7740),d=i.Symbol,g=d&&d.prototype;if(o&&c(d)&&(!(\"description\"in g)||void 0!==d().description)){var h={},A=function(){var e=arguments.length<1||void 0===arguments[0]?void 0:u(arguments[0]),n=s(g,this)?new d(e):void 0===e?d():d(e);return\"\"===e&&(h[n]=!0),n};f(A,d),A.prototype=g,g.constructor=A;var b=\"Symbol(description detection)\"===String(d(\"description detection\")),v=a(g.valueOf),m=a(g.toString),y=/^Symbol\\((.*)\\)[^)]+$/,E=a(\"\".replace),C=a(\"\".slice);p(g,\"description\",{configurable:!0,get:function(){var e=v(this);if(l(h,e))return\"\";var n=m(e),t=b?C(n,7,-1):E(n,y,\"$1\");return\"\"===t?void 0:t}}),r({global:!0,constructor:!0,forced:!0},{Symbol:A})}},1510:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(7751),i=t(9297),a=t(655),l=t(5745),c=t(1296),s=l(\"string-to-symbol-registry\"),u=l(\"symbol-to-string-registry\");r({target:\"Symbol\",stat:!0,forced:!c},{for:function(e){var n=a(e);if(i(s,n))return s[n];var t=o(\"Symbol\")(n);return s[n]=t,u[t]=n,t}})},2259:(e,n,t)=>{\"use strict\";t(511)(\"iterator\")},2675:(e,n,t)=>{\"use strict\";t(6761),t(1510),t(7812),t(3110),t(9773)},7812:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(9297),i=t(757),a=t(6823),l=t(5745),c=t(1296),s=l(\"symbol-to-string-registry\");r({target:\"Symbol\",stat:!0,forced:!c},{keyFor:function(e){if(!i(e))throw new TypeError(a(e)+\" is not a symbol\");if(o(s,e))return s[e]}})},5700:(e,n,t)=>{\"use strict\";var r=t(511),o=t(8242);r(\"toPrimitive\"),o()},5746:(e,n,t)=>{\"use strict\";var r,o=t(2744),i=t(4576),a=t(9504),l=t(6279),c=t(3451),s=t(6468),u=t(4006),p=t(34),f=t(1181).enforce,d=t(9039),g=t(8622),h=Object,A=Array.isArray,b=h.isExtensible,v=h.isFrozen,m=h.isSealed,y=h.freeze,E=h.seal,C=!i.ActiveXObject&&\"ActiveXObject\"in i,w=function(e){return function(){return e(this,arguments.length?arguments[0]:void 0)}},x=s(\"WeakMap\",w,u),S=x.prototype,_=a(S.set);if(g)if(C){r=u.getConstructor(w,\"WeakMap\",!0),c.enable();var k=a(S.delete),O=a(S.has),B=a(S.get);l(S,{delete:function(e){if(p(e)&&!b(e)){var n=f(this);return n.frozen||(n.frozen=new r),k(this,e)||n.frozen.delete(e)}return k(this,e)},has:function(e){if(p(e)&&!b(e)){var n=f(this);return n.frozen||(n.frozen=new r),O(this,e)||n.frozen.has(e)}return O(this,e)},get:function(e){if(p(e)&&!b(e)){var n=f(this);return n.frozen||(n.frozen=new r),O(this,e)?B(this,e):n.frozen.get(e)}return B(this,e)},set:function(e,n){if(p(e)&&!b(e)){var t=f(this);t.frozen||(t.frozen=new r),O(this,e)?_(this,e,n):t.frozen.set(e,n)}else _(this,e,n);return this}})}else o&&d((function(){var e=y([]);return _(new x,e,1),!v(e)}))&&l(S,{set:function(e,n){var t;return A(e)&&(v(e)?t=y:m(e)&&(t=E)),_(this,e,n),t&&t(e),this}})},3772:(e,n,t)=>{\"use strict\";t(5746)},3500:(e,n,t)=>{\"use strict\";var r=t(4576),o=t(7400),i=t(9296),a=t(235),l=t(6699),c=function(e){if(e&&e.forEach!==a)try{l(e,\"forEach\",a)}catch(n){e.forEach=a}};for(var s in o)o[s]&&c(r[s]&&r[s].prototype);c(i)},2953:(e,n,t)=>{\"use strict\";var r=t(4576),o=t(7400),i=t(9296),a=t(3792),l=t(6699),c=t(687),s=t(8227)(\"iterator\"),u=a.values,p=function(e,n){if(e){if(e[s]!==u)try{l(e,s,u)}catch(n){e[s]=u}if(c(e,n,!0),o[n])for(var t in a)if(e[t]!==a[t])try{l(e,t,a[t])}catch(n){e[t]=a[t]}}};for(var f in o)p(r[f]&&r[f].prototype,f);p(i,\"DOMTokenList\")},5575:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(4576),i=t(9472)(o.setInterval,!0);r({global:!0,bind:!0,forced:o.setInterval!==i},{setInterval:i})},4599:(e,n,t)=>{\"use strict\";var r=t(6518),o=t(4576),i=t(9472)(o.setTimeout,!0);r({global:!0,bind:!0,forced:o.setTimeout!==i},{setTimeout:i})},6031:(e,n,t)=>{\"use strict\";t(5575),t(4599)},4552:(e,n,t)=>{\"use strict\";var r=t(7244),o=t(1820);if(t(4039)()||t(1333)()){var i=Symbol.iterator;e.exports=function(e){return null!=e&&void 0!==e[i]?e[i]():r(e)?Array.prototype[i].call(e):void 0}}else{var a=t(4634),l=t(4761),c=t(453),s=c(\"%Map%\",!0),u=c(\"%Set%\",!0),p=t(8075),f=p(\"Array.prototype.push\"),d=p(\"String.prototype.charCodeAt\"),g=p(\"String.prototype.slice\"),h=function(e){var n=0;return{next:function(){var t,r=n>=e.length;return r||(t=e[n],n+=1),{done:r,value:t}}}},A=function(e,n){if(a(e)||r(e))return h(e);if(l(e)){var t=0;return{next:function(){var n=function(e,n){if(n+1>=e.length)return n+1;var t=d(e,n);if(t<55296||t>56319)return n+1;var r=d(e,n+1);return r<56320||r>57343?n+1:n+2}(e,t),r=g(e,t,n);return t=n,{done:n>e.length,value:r}}}}return n&&void 0!==e[\"_es6-shim iterator_\"]?e[\"_es6-shim iterator_\"]():void 0};if(s||u){var b=t(1421),v=t(256),m=p(\"Map.prototype.forEach\",!0),y=p(\"Set.prototype.forEach\",!0);if(\"undefined\"==typeof process||!process.versions||!process.versions.node)var E=p(\"Map.prototype.iterator\",!0),C=p(\"Set.prototype.iterator\",!0);var w=p(\"Map.prototype.@@iterator\",!0)||p(\"Map.prototype._es6-shim iterator_\",!0),x=p(\"Set.prototype.@@iterator\",!0)||p(\"Set.prototype._es6-shim iterator_\",!0);e.exports=function(e){return function(e){if(b(e)){if(E)return o(E(e));if(w)return w(e);if(m){var n=[];return m(e,(function(e,t){f(n,[t,e])})),h(n)}}if(v(e)){if(C)return o(C(e));if(x)return x(e);if(y){var t=[];return y(e,(function(e){f(t,e)})),h(t)}}}(e)||A(e)}}else e.exports=function(e){if(null!=e)return A(e,!0)}}}},n={};function t(r){var o=n[r];if(void 0!==o)return o.exports;var i=n[r]={id:r,exports:{}};return e[r].call(i.exports,i,i.exports,t),i.exports}t.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return t.d(n,{a:n}),n},t.d=(e,n)=>{for(var r in n)t.o(n,r)&&!t.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:n[r]})},t.g=function(){if(\"object\"==typeof globalThis)return globalThis;try{return this||new Function(\"return this\")()}catch(e){if(\"object\"==typeof window)return window}}(),t.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),t.r=e=>{\"undefined\"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:\"Module\"}),Object.defineProperty(e,\"__esModule\",{value:!0})},t.nc=void 0,(()=>{\"use strict\";var e=t(4848),n=t(6540),r=t(961),o=(t(2675),t(9463),t(2259),t(5700),t(8706),t(2008),t(113),t(8980),t(1629),t(4423),t(5276),t(3792),t(8598),t(2062),t(5086),t(739),t(9085),t(7945),t(3851),t(1278),t(9432),t(9572),t(4170),t(2892),t(9904),t(4185),t(875),t(287),t(6099),t(825),t(7764),t(3500),t(2953),t(5556)),i=t.n(o),a=t(6942),l=t.n(a);function c(){return c=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},c.apply(null,arguments)}function s(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}function u(e){return u=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},u(e)}function p(e){var n=function(e,n){if(\"object\"!=u(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=u(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==u(n)?n:n+\"\"}function f(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,p(r.key),r)}}function d(e,n,t){return n&&f(e.prototype,n),t&&f(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}function g(e,n){if(n&&(\"object\"==u(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}function h(e){return h=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},h(e)}function A(e,n){return A=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},A(e,n)}function b(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&A(e,n)}function v(e,n,t){return(n=p(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function m(e){var n,t,r=\"\";if(\"string\"==typeof e||\"number\"==typeof e)r+=e;else if(\"object\"==typeof e)if(Array.isArray(e))for(n=0;n<e.length;n++)e[n]&&(t=m(e[n]))&&(r&&(r+=\" \"),r+=t);else for(n in e)e[n]&&(r&&(r+=\" \"),r+=n);return r}const y=function(){for(var e,n,t=0,r=\"\";t<arguments.length;)(e=arguments[t++])&&(n=m(e))&&(r&&(r+=\" \"),r+=n);return r};function E(e){var n=e.cellCount,t=e.cellSize,r=e.computeMetadataCallback,o=e.computeMetadataCallbackProps,i=e.nextCellsCount,a=e.nextCellSize,l=e.nextScrollToIndex,c=e.scrollToIndex,s=e.updateScrollOffsetForScrollToIndex;n===i&&(\"number\"!=typeof t&&\"number\"!=typeof a||t===a)||(r(o),c>=0&&c===l&&s())}var C=function(){return d((function e(n){var t=n.cellCount,r=n.cellSizeGetter,o=n.estimatedCellSize;s(this,e),v(this,\"_cellSizeAndPositionData\",{}),v(this,\"_lastMeasuredIndex\",-1),v(this,\"_lastBatchedIndex\",-1),v(this,\"_cellCount\",void 0),v(this,\"_cellSizeGetter\",void 0),v(this,\"_estimatedCellSize\",void 0),this._cellSizeGetter=r,this._cellCount=t,this._estimatedCellSize=o}),[{key:\"areOffsetsAdjusted\",value:function(){return!1}},{key:\"configure\",value:function(e){var n=e.cellCount,t=e.estimatedCellSize,r=e.cellSizeGetter;this._cellCount=n,this._estimatedCellSize=t,this._cellSizeGetter=r}},{key:\"getCellCount\",value:function(){return this._cellCount}},{key:\"getEstimatedCellSize\",value:function(){return this._estimatedCellSize}},{key:\"getLastMeasuredIndex\",value:function(){return this._lastMeasuredIndex}},{key:\"getOffsetAdjustment\",value:function(){return 0}},{key:\"getSizeAndPositionOfCell\",value:function(e){if(e<0||e>=this._cellCount)throw Error(\"Requested index \".concat(e,\" is outside of range 0..\").concat(this._cellCount));if(e>this._lastMeasuredIndex)for(var n=this.getSizeAndPositionOfLastMeasuredCell(),t=n.offset+n.size,r=this._lastMeasuredIndex+1;r<=e;r++){var o=this._cellSizeGetter({index:r});if(void 0===o||isNaN(o))throw Error(\"Invalid size returned for cell \".concat(r,\" of value \").concat(o));null===o?(this._cellSizeAndPositionData[r]={offset:t,size:0},this._lastBatchedIndex=e):(this._cellSizeAndPositionData[r]={offset:t,size:o},t+=o,this._lastMeasuredIndex=e)}return this._cellSizeAndPositionData[e]}},{key:\"getSizeAndPositionOfLastMeasuredCell\",value:function(){return this._lastMeasuredIndex>=0?this._cellSizeAndPositionData[this._lastMeasuredIndex]:{offset:0,size:0}}},{key:\"getTotalSize\",value:function(){var e=this.getSizeAndPositionOfLastMeasuredCell();return e.offset+e.size+(this._cellCount-this._lastMeasuredIndex-1)*this._estimatedCellSize}},{key:\"getUpdatedOffsetForIndex\",value:function(e){var n=e.align,t=void 0===n?\"auto\":n,r=e.containerSize,o=e.currentOffset,i=e.targetIndex;if(r<=0)return 0;var a,l=this.getSizeAndPositionOfCell(i),c=l.offset,s=c-r+l.size;switch(t){case\"start\":a=c;break;case\"end\":a=s;break;case\"center\":a=c-(r-l.size)/2;break;default:a=Math.max(s,Math.min(c,o))}var u=this.getTotalSize();return Math.max(0,Math.min(u-r,a))}},{key:\"getVisibleCellRange\",value:function(e){var n=e.containerSize,t=e.offset;if(0===this.getTotalSize())return{};var r=t+n,o=this._findNearestCell(t),i=this.getSizeAndPositionOfCell(o);t=i.offset+i.size;for(var a=o;t<r&&a<this._cellCount-1;)a++,t+=this.getSizeAndPositionOfCell(a).size;return{start:o,stop:a}}},{key:\"resetCell\",value:function(e){this._lastMeasuredIndex=Math.min(this._lastMeasuredIndex,e-1)}},{key:\"_binarySearch\",value:function(e,n,t){for(;n<=e;){var r=n+Math.floor((e-n)/2),o=this.getSizeAndPositionOfCell(r).offset;if(o===t)return r;o<t?n=r+1:o>t&&(e=r-1)}return n>0?n-1:0}},{key:\"_exponentialSearch\",value:function(e,n){for(var t=1;e<this._cellCount&&this.getSizeAndPositionOfCell(e).offset<n;)e+=t,t*=2;return this._binarySearch(Math.min(e,this._cellCount-1),Math.floor(e/2),n)}},{key:\"_findNearestCell\",value:function(e){if(isNaN(e))throw Error(\"Invalid offset \".concat(e,\" specified\"));e=Math.max(0,e);var n=this.getSizeAndPositionOfLastMeasuredCell(),t=Math.max(0,this._lastMeasuredIndex);return n.offset>=e?this._binarySearch(t,0,e):this._exponentialSearch(t,e)}}])}(),w=function(){return\"undefined\"!=typeof window&&window.chrome?16777100:15e5},x=[\"maxScrollSize\"],S=function(){return d((function e(n){var t=n.maxScrollSize,r=void 0===t?w():t,o=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(n,x);s(this,e),v(this,\"_cellSizeAndPositionManager\",void 0),v(this,\"_maxScrollSize\",void 0),this._cellSizeAndPositionManager=new C(o),this._maxScrollSize=r}),[{key:\"areOffsetsAdjusted\",value:function(){return this._cellSizeAndPositionManager.getTotalSize()>this._maxScrollSize}},{key:\"configure\",value:function(e){this._cellSizeAndPositionManager.configure(e)}},{key:\"getCellCount\",value:function(){return this._cellSizeAndPositionManager.getCellCount()}},{key:\"getEstimatedCellSize\",value:function(){return this._cellSizeAndPositionManager.getEstimatedCellSize()}},{key:\"getLastMeasuredIndex\",value:function(){return this._cellSizeAndPositionManager.getLastMeasuredIndex()}},{key:\"getOffsetAdjustment\",value:function(e){var n=e.containerSize,t=e.offset,r=this._cellSizeAndPositionManager.getTotalSize(),o=this.getTotalSize(),i=this._getOffsetPercentage({containerSize:n,offset:t,totalSize:o});return Math.round(i*(o-r))}},{key:\"getSizeAndPositionOfCell\",value:function(e){return this._cellSizeAndPositionManager.getSizeAndPositionOfCell(e)}},{key:\"getSizeAndPositionOfLastMeasuredCell\",value:function(){return this._cellSizeAndPositionManager.getSizeAndPositionOfLastMeasuredCell()}},{key:\"getTotalSize\",value:function(){return Math.min(this._maxScrollSize,this._cellSizeAndPositionManager.getTotalSize())}},{key:\"getUpdatedOffsetForIndex\",value:function(e){var n=e.align,t=void 0===n?\"auto\":n,r=e.containerSize,o=e.currentOffset,i=e.targetIndex;o=this._safeOffsetToOffset({containerSize:r,offset:o});var a=this._cellSizeAndPositionManager.getUpdatedOffsetForIndex({align:t,containerSize:r,currentOffset:o,targetIndex:i});return this._offsetToSafeOffset({containerSize:r,offset:a})}},{key:\"getVisibleCellRange\",value:function(e){var n=e.containerSize,t=e.offset;return t=this._safeOffsetToOffset({containerSize:n,offset:t}),this._cellSizeAndPositionManager.getVisibleCellRange({containerSize:n,offset:t})}},{key:\"resetCell\",value:function(e){this._cellSizeAndPositionManager.resetCell(e)}},{key:\"_getOffsetPercentage\",value:function(e){var n=e.containerSize,t=e.offset,r=e.totalSize;return r<=n?0:t/(r-n)}},{key:\"_offsetToSafeOffset\",value:function(e){var n=e.containerSize,t=e.offset,r=this._cellSizeAndPositionManager.getTotalSize(),o=this.getTotalSize();if(r===o)return t;var i=this._getOffsetPercentage({containerSize:n,offset:t,totalSize:r});return Math.round(i*(o-n))}},{key:\"_safeOffsetToOffset\",value:function(e){var n=e.containerSize,t=e.offset,r=this._cellSizeAndPositionManager.getTotalSize(),o=this.getTotalSize();if(r===o)return t;var i=this._getOffsetPercentage({containerSize:n,offset:t,totalSize:o});return Math.round(i*(r-n))}}])}();function _(){var e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],n={};return function(t){var r=t.callback,o=t.indices,i=Object.keys(o),a=!e||i.every((function(e){var n=o[e];return Array.isArray(n)?n.length>0:n>=0})),l=i.length!==Object.keys(n).length||i.some((function(e){var t=n[e],r=o[e];return Array.isArray(r)?t.join(\",\")!==r.join(\",\"):t!==r}));n=o,a&&l&&r(o)}}function k(e){var n=e.cellSize,t=e.cellSizeAndPositionManager,r=e.previousCellsCount,o=e.previousCellSize,i=e.previousScrollToAlignment,a=e.previousScrollToIndex,l=e.previousSize,c=e.scrollOffset,s=e.scrollToAlignment,u=e.scrollToIndex,p=e.size,f=e.sizeJustIncreasedFromZero,d=e.updateScrollIndexCallback,g=t.getCellCount(),h=u>=0&&u<g;h&&(p!==l||f||!o||\"number\"==typeof n&&n!==o||s!==i||u!==a)?d(u):!h&&g>0&&(p<l||g<r)&&c>t.getTotalSize()-p&&d(g-1)}const O=!(\"undefined\"==typeof window||!window.document||!window.document.createElement);var B,P;function T(){var e=this.constructor.getDerivedStateFromProps(this.props,this.state);null!=e&&this.setState(e)}function I(e){this.setState(function(n){var t=this.constructor.getDerivedStateFromProps(e,n);return null!=t?t:null}.bind(this))}function j(e,n){try{var t=this.props,r=this.state;this.props=e,this.state=n,this.__reactInternalSnapshotFlag=!0,this.__reactInternalSnapshot=this.getSnapshotBeforeUpdate(t,r)}finally{this.props=t,this.state=r}}T.__suppressDeprecationWarning=!0,I.__suppressDeprecationWarning=!0,j.__suppressDeprecationWarning=!0;var z=(P=\"undefined\"!=typeof window?window:\"undefined\"!=typeof self?self:{}).requestAnimationFrame||P.webkitRequestAnimationFrame||P.mozRequestAnimationFrame||P.oRequestAnimationFrame||P.msRequestAnimationFrame||function(e){return P.setTimeout(e,1e3/60)},D=P.cancelAnimationFrame||P.webkitCancelAnimationFrame||P.mozCancelAnimationFrame||P.oCancelAnimationFrame||P.msCancelAnimationFrame||function(e){P.clearTimeout(e)},R=z,M=D,N=function(e){return M(e.id)},F=function(e,n){var t;Promise.resolve().then((function(){t=Date.now()}));var r=function(){Date.now()-t>=n?e.call():o.id=R(r)},o={id:R(r)};return o};function L(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function H(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?L(Object(t),!0).forEach((function(n){v(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):L(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function U(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(U=function(){return!!e})()}var W=\"observed\",G=\"requested\",Y=function(e){function t(e){var n,r,o,i;s(this,t),r=this,i=[e],o=h(o=t),v(n=g(r,U()?Reflect.construct(o,i||[],h(r).constructor):o.apply(r,i)),\"_onGridRenderedMemoizer\",_()),v(n,\"_onScrollMemoizer\",_(!1)),v(n,\"_deferredInvalidateColumnIndex\",null),v(n,\"_deferredInvalidateRowIndex\",null),v(n,\"_recomputeScrollLeftFlag\",!1),v(n,\"_recomputeScrollTopFlag\",!1),v(n,\"_horizontalScrollBarSize\",0),v(n,\"_verticalScrollBarSize\",0),v(n,\"_scrollbarPresenceChanged\",!1),v(n,\"_scrollingContainer\",void 0),v(n,\"_childrenToDisplay\",void 0),v(n,\"_columnStartIndex\",void 0),v(n,\"_columnStopIndex\",void 0),v(n,\"_rowStartIndex\",void 0),v(n,\"_rowStopIndex\",void 0),v(n,\"_renderedColumnStartIndex\",0),v(n,\"_renderedColumnStopIndex\",0),v(n,\"_renderedRowStartIndex\",0),v(n,\"_renderedRowStopIndex\",0),v(n,\"_initialScrollTop\",void 0),v(n,\"_initialScrollLeft\",void 0),v(n,\"_disablePointerEventsTimeoutId\",void 0),v(n,\"_styleCache\",{}),v(n,\"_cellCache\",{}),v(n,\"_debounceScrollEndedCallback\",(function(){n._disablePointerEventsTimeoutId=null,n.setState({isScrolling:!1,needToResetStyleCache:!1})})),v(n,\"_invokeOnGridRenderedHelper\",(function(){var e=n.props.onSectionRendered;n._onGridRenderedMemoizer({callback:e,indices:{columnOverscanStartIndex:n._columnStartIndex,columnOverscanStopIndex:n._columnStopIndex,columnStartIndex:n._renderedColumnStartIndex,columnStopIndex:n._renderedColumnStopIndex,rowOverscanStartIndex:n._rowStartIndex,rowOverscanStopIndex:n._rowStopIndex,rowStartIndex:n._renderedRowStartIndex,rowStopIndex:n._renderedRowStopIndex}})})),v(n,\"_setScrollingContainerRef\",(function(e){n._scrollingContainer=e,\"function\"==typeof n.props.elementRef?n.props.elementRef(e):\"object\"===u(n.props.elementRef)&&(n.props.elementRef.current=e)})),v(n,\"_onScroll\",(function(e){e.target===n._scrollingContainer&&n.handleScrollEvent(e.target)}));var a=new S({cellCount:e.columnCount,cellSizeGetter:function(n){return t._wrapSizeGetter(e.columnWidth)(n)},estimatedCellSize:t._getEstimatedColumnSize(e)}),l=new S({cellCount:e.rowCount,cellSizeGetter:function(n){return t._wrapSizeGetter(e.rowHeight)(n)},estimatedCellSize:t._getEstimatedRowSize(e)});return n.state={instanceProps:{columnSizeAndPositionManager:a,rowSizeAndPositionManager:l,prevColumnWidth:e.columnWidth,prevRowHeight:e.rowHeight,prevColumnCount:e.columnCount,prevRowCount:e.rowCount,prevIsScrolling:!0===e.isScrolling,prevScrollToColumn:e.scrollToColumn,prevScrollToRow:e.scrollToRow,scrollbarSize:0,scrollbarSizeMeasured:!1},isScrolling:!1,scrollDirectionHorizontal:1,scrollDirectionVertical:1,scrollLeft:0,scrollTop:0,scrollPositionChangeReason:null,needToResetStyleCache:!1},e.scrollToRow>0&&(n._initialScrollTop=n._getCalculatedScrollTop(e,n.state)),e.scrollToColumn>0&&(n._initialScrollLeft=n._getCalculatedScrollLeft(e,n.state)),n}return b(t,e),d(t,[{key:\"getOffsetForCell\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.alignment,t=void 0===n?this.props.scrollToAlignment:n,r=e.columnIndex,o=void 0===r?this.props.scrollToColumn:r,i=e.rowIndex,a=void 0===i?this.props.scrollToRow:i,l=H(H({},this.props),{},{scrollToAlignment:t,scrollToColumn:o,scrollToRow:a});return{scrollLeft:this._getCalculatedScrollLeft(l),scrollTop:this._getCalculatedScrollTop(l)}}},{key:\"getTotalRowsHeight\",value:function(){return this.state.instanceProps.rowSizeAndPositionManager.getTotalSize()}},{key:\"getTotalColumnsWidth\",value:function(){return this.state.instanceProps.columnSizeAndPositionManager.getTotalSize()}},{key:\"handleScrollEvent\",value:function(e){var n=e.scrollLeft,t=void 0===n?0:n,r=e.scrollTop,o=void 0===r?0:r;if(!(o<0)){this._debounceScrollEnded();var i=this.props,a=i.autoHeight,l=i.autoWidth,c=i.height,s=i.width,u=this.state.instanceProps,p=u.scrollbarSize,f=u.rowSizeAndPositionManager.getTotalSize(),d=u.columnSizeAndPositionManager.getTotalSize(),g=Math.min(Math.max(0,d-s+p),t),h=Math.min(Math.max(0,f-c+p),o);if(this.state.scrollLeft!==g||this.state.scrollTop!==h){var A={isScrolling:!0,scrollDirectionHorizontal:g!==this.state.scrollLeft?g>this.state.scrollLeft?1:-1:this.state.scrollDirectionHorizontal,scrollDirectionVertical:h!==this.state.scrollTop?h>this.state.scrollTop?1:-1:this.state.scrollDirectionVertical,scrollPositionChangeReason:W};a||(A.scrollTop=h),l||(A.scrollLeft=g),A.needToResetStyleCache=!1,this.setState(A)}this._invokeOnScrollMemoizer({scrollLeft:g,scrollTop:h,totalColumnsWidth:d,totalRowsHeight:f})}}},{key:\"invalidateCellSizeAfterRender\",value:function(e){var n=e.columnIndex,t=e.rowIndex;this._deferredInvalidateColumnIndex=\"number\"==typeof this._deferredInvalidateColumnIndex?Math.min(this._deferredInvalidateColumnIndex,n):n,this._deferredInvalidateRowIndex=\"number\"==typeof this._deferredInvalidateRowIndex?Math.min(this._deferredInvalidateRowIndex,t):t}},{key:\"measureAllCells\",value:function(){var e=this.props,n=e.columnCount,t=e.rowCount,r=this.state.instanceProps;r.columnSizeAndPositionManager.getSizeAndPositionOfCell(n-1),r.rowSizeAndPositionManager.getSizeAndPositionOfCell(t-1)}},{key:\"recomputeGridSize\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.columnIndex,t=void 0===n?0:n,r=e.rowIndex,o=void 0===r?0:r,i=this.props,a=i.scrollToColumn,l=i.scrollToRow,c=this.state.instanceProps;c.columnSizeAndPositionManager.resetCell(t),c.rowSizeAndPositionManager.resetCell(o),this._recomputeScrollLeftFlag=a>=0&&(1===this.state.scrollDirectionHorizontal?t<=a:t>=a),this._recomputeScrollTopFlag=l>=0&&(1===this.state.scrollDirectionVertical?o<=l:o>=l),this._styleCache={},this._cellCache={},this.forceUpdate()}},{key:\"scrollToCell\",value:function(e){var n=e.columnIndex,t=e.rowIndex,r=this.props.columnCount,o=this.props;r>1&&void 0!==n&&this._updateScrollLeftForScrollToColumn(H(H({},o),{},{scrollToColumn:n})),void 0!==t&&this._updateScrollTopForScrollToRow(H(H({},o),{},{scrollToRow:t}))}},{key:\"componentDidMount\",value:function(){var e=this.props,n=e.getScrollbarSize,r=e.height,o=e.scrollLeft,i=e.scrollToColumn,a=e.scrollTop,l=e.scrollToRow,c=e.width,s=this.state.instanceProps;if(this._initialScrollTop=0,this._initialScrollLeft=0,this._handleInvalidatedGridSize(),s.scrollbarSizeMeasured||this.setState((function(e){var t=H(H({},e),{},{needToResetStyleCache:!1});return t.instanceProps.scrollbarSize=n(),t.instanceProps.scrollbarSizeMeasured=!0,t})),\"number\"==typeof o&&o>=0||\"number\"==typeof a&&a>=0){var u=t._getScrollToPositionStateUpdate({prevState:this.state,scrollLeft:o,scrollTop:a});u&&(u.needToResetStyleCache=!1,this.setState(u))}this._scrollingContainer&&(this._scrollingContainer.scrollLeft!==this.state.scrollLeft&&(this._scrollingContainer.scrollLeft=this.state.scrollLeft),this._scrollingContainer.scrollTop!==this.state.scrollTop&&(this._scrollingContainer.scrollTop=this.state.scrollTop));var p=r>0&&c>0;i>=0&&p&&this._updateScrollLeftForScrollToColumn(),l>=0&&p&&this._updateScrollTopForScrollToRow(),this._invokeOnGridRenderedHelper(),this._invokeOnScrollMemoizer({scrollLeft:o||0,scrollTop:a||0,totalColumnsWidth:s.columnSizeAndPositionManager.getTotalSize(),totalRowsHeight:s.rowSizeAndPositionManager.getTotalSize()}),this._maybeCallOnScrollbarPresenceChange()}},{key:\"componentDidUpdate\",value:function(e,n){var t=this,r=this.props,o=r.autoHeight,i=r.autoWidth,a=r.columnCount,l=r.height,c=r.rowCount,s=r.scrollToAlignment,u=r.scrollToColumn,p=r.scrollToRow,f=r.width,d=this.state,g=d.scrollLeft,h=d.scrollPositionChangeReason,A=d.scrollTop,b=d.instanceProps;this._handleInvalidatedGridSize();var v=a>0&&0===e.columnCount||c>0&&0===e.rowCount;h===G&&(!i&&g>=0&&(g!==this._scrollingContainer.scrollLeft||v)&&(this._scrollingContainer.scrollLeft=g),!o&&A>=0&&(A!==this._scrollingContainer.scrollTop||v)&&(this._scrollingContainer.scrollTop=A));var m=(0===e.width||0===e.height)&&l>0&&f>0;if(this._recomputeScrollLeftFlag?(this._recomputeScrollLeftFlag=!1,this._updateScrollLeftForScrollToColumn(this.props)):k({cellSizeAndPositionManager:b.columnSizeAndPositionManager,previousCellsCount:e.columnCount,previousCellSize:e.columnWidth,previousScrollToAlignment:e.scrollToAlignment,previousScrollToIndex:e.scrollToColumn,previousSize:e.width,scrollOffset:g,scrollToAlignment:s,scrollToIndex:u,size:f,sizeJustIncreasedFromZero:m,updateScrollIndexCallback:function(){return t._updateScrollLeftForScrollToColumn(t.props)}}),this._recomputeScrollTopFlag?(this._recomputeScrollTopFlag=!1,this._updateScrollTopForScrollToRow(this.props)):k({cellSizeAndPositionManager:b.rowSizeAndPositionManager,previousCellsCount:e.rowCount,previousCellSize:e.rowHeight,previousScrollToAlignment:e.scrollToAlignment,previousScrollToIndex:e.scrollToRow,previousSize:e.height,scrollOffset:A,scrollToAlignment:s,scrollToIndex:p,size:l,sizeJustIncreasedFromZero:m,updateScrollIndexCallback:function(){return t._updateScrollTopForScrollToRow(t.props)}}),this._invokeOnGridRenderedHelper(),g!==n.scrollLeft||A!==n.scrollTop){var y=b.rowSizeAndPositionManager.getTotalSize(),E=b.columnSizeAndPositionManager.getTotalSize();this._invokeOnScrollMemoizer({scrollLeft:g,scrollTop:A,totalColumnsWidth:E,totalRowsHeight:y})}this._maybeCallOnScrollbarPresenceChange()}},{key:\"componentWillUnmount\",value:function(){this._disablePointerEventsTimeoutId&&N(this._disablePointerEventsTimeoutId)}},{key:\"render\",value:function(){var e=this.props,t=e.autoContainerWidth,r=e.autoHeight,o=e.autoWidth,i=e.className,a=e.containerProps,l=e.containerRole,s=e.containerStyle,u=e.height,p=e.id,f=e.noContentRenderer,d=e.role,g=e.style,h=e.tabIndex,A=e.width,b=this.state,v=b.instanceProps,m=b.needToResetStyleCache,E=this._isScrolling(),C={boxSizing:\"border-box\",direction:\"ltr\",height:r?\"auto\":u,position:\"relative\",width:o?\"auto\":A,WebkitOverflowScrolling:\"touch\",willChange:\"transform\"};m&&(this._styleCache={}),this.state.isScrolling||this._resetStyleCache(),this._calculateChildrenToRender(this.props,this.state);var w=v.columnSizeAndPositionManager.getTotalSize(),x=v.rowSizeAndPositionManager.getTotalSize(),S=x>u?v.scrollbarSize:0,_=w>A?v.scrollbarSize:0;_===this._horizontalScrollBarSize&&S===this._verticalScrollBarSize||(this._horizontalScrollBarSize=_,this._verticalScrollBarSize=S,this._scrollbarPresenceChanged=!0),C.overflowX=w+S<=A?\"hidden\":\"auto\",C.overflowY=x+_<=u?\"hidden\":\"auto\";var k=this._childrenToDisplay,O=0===k.length&&u>0&&A>0;return n.createElement(\"div\",c({ref:this._setScrollingContainerRef},a,{\"aria-label\":this.props[\"aria-label\"],\"aria-readonly\":this.props[\"aria-readonly\"],className:y(\"ReactVirtualized__Grid\",i),id:p,onScroll:this._onScroll,role:d,style:H(H({},C),g),tabIndex:h}),k.length>0&&n.createElement(\"div\",{className:\"ReactVirtualized__Grid__innerScrollContainer\",role:l,style:H({width:t?\"auto\":w,height:x,maxWidth:w,maxHeight:x,overflow:\"hidden\",pointerEvents:E?\"none\":\"\",position:\"relative\"},s)},k),O&&f())}},{key:\"_calculateChildrenToRender\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.props,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.state,t=e.cellRenderer,r=e.cellRangeRenderer,o=e.columnCount,i=e.deferredMeasurementCache,a=e.height,l=e.overscanColumnCount,c=e.overscanIndicesGetter,s=e.overscanRowCount,u=e.rowCount,p=e.width,f=e.isScrollingOptOut,d=n.scrollDirectionHorizontal,g=n.scrollDirectionVertical,h=n.instanceProps,A=this._initialScrollTop>0?this._initialScrollTop:n.scrollTop,b=this._initialScrollLeft>0?this._initialScrollLeft:n.scrollLeft,v=this._isScrolling(e,n);if(this._childrenToDisplay=[],a>0&&p>0){var m=h.columnSizeAndPositionManager.getVisibleCellRange({containerSize:p,offset:b}),y=h.rowSizeAndPositionManager.getVisibleCellRange({containerSize:a,offset:A}),E=h.columnSizeAndPositionManager.getOffsetAdjustment({containerSize:p,offset:b}),C=h.rowSizeAndPositionManager.getOffsetAdjustment({containerSize:a,offset:A});this._renderedColumnStartIndex=m.start,this._renderedColumnStopIndex=m.stop,this._renderedRowStartIndex=y.start,this._renderedRowStopIndex=y.stop;var w=c({direction:\"horizontal\",cellCount:o,overscanCellsCount:l,scrollDirection:d,startIndex:\"number\"==typeof m.start?m.start:0,stopIndex:\"number\"==typeof m.stop?m.stop:-1}),x=c({direction:\"vertical\",cellCount:u,overscanCellsCount:s,scrollDirection:g,startIndex:\"number\"==typeof y.start?y.start:0,stopIndex:\"number\"==typeof y.stop?y.stop:-1}),S=w.overscanStartIndex,_=w.overscanStopIndex,k=x.overscanStartIndex,O=x.overscanStopIndex;if(i){if(!i.hasFixedHeight())for(var B=k;B<=O;B++)if(!i.has(B,0)){S=0,_=o-1;break}if(!i.hasFixedWidth())for(var P=S;P<=_;P++)if(!i.has(0,P)){k=0,O=u-1;break}}this._childrenToDisplay=r({cellCache:this._cellCache,cellRenderer:t,columnSizeAndPositionManager:h.columnSizeAndPositionManager,columnStartIndex:S,columnStopIndex:_,deferredMeasurementCache:i,horizontalOffsetAdjustment:E,isScrolling:v,isScrollingOptOut:f,parent:this,rowSizeAndPositionManager:h.rowSizeAndPositionManager,rowStartIndex:k,rowStopIndex:O,scrollLeft:b,scrollTop:A,styleCache:this._styleCache,verticalOffsetAdjustment:C,visibleColumnIndices:m,visibleRowIndices:y}),this._columnStartIndex=S,this._columnStopIndex=_,this._rowStartIndex=k,this._rowStopIndex=O}}},{key:\"_debounceScrollEnded\",value:function(){var e=this.props.scrollingResetTimeInterval;this._disablePointerEventsTimeoutId&&N(this._disablePointerEventsTimeoutId),this._disablePointerEventsTimeoutId=F(this._debounceScrollEndedCallback,e)}},{key:\"_handleInvalidatedGridSize\",value:function(){if(\"number\"==typeof this._deferredInvalidateColumnIndex&&\"number\"==typeof this._deferredInvalidateRowIndex){var e=this._deferredInvalidateColumnIndex,n=this._deferredInvalidateRowIndex;this._deferredInvalidateColumnIndex=null,this._deferredInvalidateRowIndex=null,this.recomputeGridSize({columnIndex:e,rowIndex:n})}}},{key:\"_invokeOnScrollMemoizer\",value:function(e){var n=this,t=e.scrollLeft,r=e.scrollTop,o=e.totalColumnsWidth,i=e.totalRowsHeight;this._onScrollMemoizer({callback:function(e){var t=e.scrollLeft,r=e.scrollTop,a=n.props,l=a.height;(0,a.onScroll)({clientHeight:l,clientWidth:a.width,scrollHeight:i,scrollLeft:t,scrollTop:r,scrollWidth:o})},indices:{scrollLeft:t,scrollTop:r}})}},{key:\"_isScrolling\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.props,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.state;return Object.hasOwnProperty.call(e,\"isScrolling\")?Boolean(e.isScrolling):Boolean(n.isScrolling)}},{key:\"_maybeCallOnScrollbarPresenceChange\",value:function(){if(this._scrollbarPresenceChanged){var e=this.props.onScrollbarPresenceChange;this._scrollbarPresenceChanged=!1,e({horizontal:this._horizontalScrollBarSize>0,size:this.state.instanceProps.scrollbarSize,vertical:this._verticalScrollBarSize>0})}}},{key:\"scrollToPosition\",value:function(e){var n=e.scrollLeft,r=e.scrollTop,o=t._getScrollToPositionStateUpdate({prevState:this.state,scrollLeft:n,scrollTop:r});o&&(o.needToResetStyleCache=!1,this.setState(o))}},{key:\"_getCalculatedScrollLeft\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.props,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.state;return t._getCalculatedScrollLeft(e,n)}},{key:\"_updateScrollLeftForScrollToColumn\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.props,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.state,r=t._getScrollLeftForScrollToColumnStateUpdate(e,n);r&&(r.needToResetStyleCache=!1,this.setState(r))}},{key:\"_getCalculatedScrollTop\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.props,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.state;return t._getCalculatedScrollTop(e,n)}},{key:\"_resetStyleCache\",value:function(){var e=this._styleCache,n=this._cellCache,t=this.props.isScrollingOptOut;this._cellCache={},this._styleCache={};for(var r=this._rowStartIndex;r<=this._rowStopIndex;r++)for(var o=this._columnStartIndex;o<=this._columnStopIndex;o++){var i=\"\".concat(r,\"-\").concat(o);this._styleCache[i]=e[i],t&&(this._cellCache[i]=n[i])}}},{key:\"_updateScrollTopForScrollToRow\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.props,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this.state,r=t._getScrollTopForScrollToRowStateUpdate(e,n);r&&(r.needToResetStyleCache=!1,this.setState(r))}}],[{key:\"getDerivedStateFromProps\",value:function(e,n){var r={};0===e.columnCount&&0!==n.scrollLeft||0===e.rowCount&&0!==n.scrollTop?(r.scrollLeft=0,r.scrollTop=0):(e.scrollLeft!==n.scrollLeft&&e.scrollToColumn<0||e.scrollTop!==n.scrollTop&&e.scrollToRow<0)&&Object.assign(r,t._getScrollToPositionStateUpdate({prevState:n,scrollLeft:e.scrollLeft,scrollTop:e.scrollTop}));var o,i,a=n.instanceProps;return r.needToResetStyleCache=!1,e.columnWidth===a.prevColumnWidth&&e.rowHeight===a.prevRowHeight||(r.needToResetStyleCache=!0),a.columnSizeAndPositionManager.configure({cellCount:e.columnCount,estimatedCellSize:t._getEstimatedColumnSize(e),cellSizeGetter:t._wrapSizeGetter(e.columnWidth)}),a.rowSizeAndPositionManager.configure({cellCount:e.rowCount,estimatedCellSize:t._getEstimatedRowSize(e),cellSizeGetter:t._wrapSizeGetter(e.rowHeight)}),0!==a.prevColumnCount&&0!==a.prevRowCount||(a.prevColumnCount=0,a.prevRowCount=0),e.autoHeight&&!1===e.isScrolling&&!0===a.prevIsScrolling&&Object.assign(r,{isScrolling:!1}),E({cellCount:a.prevColumnCount,cellSize:\"number\"==typeof a.prevColumnWidth?a.prevColumnWidth:null,computeMetadataCallback:function(){return a.columnSizeAndPositionManager.resetCell(0)},computeMetadataCallbackProps:e,nextCellsCount:e.columnCount,nextCellSize:\"number\"==typeof e.columnWidth?e.columnWidth:null,nextScrollToIndex:e.scrollToColumn,scrollToIndex:a.prevScrollToColumn,updateScrollOffsetForScrollToIndex:function(){o=t._getScrollLeftForScrollToColumnStateUpdate(e,n)}}),E({cellCount:a.prevRowCount,cellSize:\"number\"==typeof a.prevRowHeight?a.prevRowHeight:null,computeMetadataCallback:function(){return a.rowSizeAndPositionManager.resetCell(0)},computeMetadataCallbackProps:e,nextCellsCount:e.rowCount,nextCellSize:\"number\"==typeof e.rowHeight?e.rowHeight:null,nextScrollToIndex:e.scrollToRow,scrollToIndex:a.prevScrollToRow,updateScrollOffsetForScrollToIndex:function(){i=t._getScrollTopForScrollToRowStateUpdate(e,n)}}),a.prevColumnCount=e.columnCount,a.prevColumnWidth=e.columnWidth,a.prevIsScrolling=!0===e.isScrolling,a.prevRowCount=e.rowCount,a.prevRowHeight=e.rowHeight,a.prevScrollToColumn=e.scrollToColumn,a.prevScrollToRow=e.scrollToRow,a.scrollbarSize=e.getScrollbarSize(),void 0===a.scrollbarSize?(a.scrollbarSizeMeasured=!1,a.scrollbarSize=0):a.scrollbarSizeMeasured=!0,r.instanceProps=a,H(H(H({},r),o),i)}},{key:\"_getEstimatedColumnSize\",value:function(e){return\"number\"==typeof e.columnWidth?e.columnWidth:e.estimatedColumnSize}},{key:\"_getEstimatedRowSize\",value:function(e){return\"number\"==typeof e.rowHeight?e.rowHeight:e.estimatedRowSize}},{key:\"_getScrollToPositionStateUpdate\",value:function(e){var n=e.prevState,t=e.scrollLeft,r=e.scrollTop,o={scrollPositionChangeReason:G};return\"number\"==typeof t&&t>=0&&(o.scrollDirectionHorizontal=t>n.scrollLeft?1:-1,o.scrollLeft=t),\"number\"==typeof r&&r>=0&&(o.scrollDirectionVertical=r>n.scrollTop?1:-1,o.scrollTop=r),\"number\"==typeof t&&t>=0&&t!==n.scrollLeft||\"number\"==typeof r&&r>=0&&r!==n.scrollTop?o:{}}},{key:\"_wrapSizeGetter\",value:function(e){return\"function\"==typeof e?e:function(){return e}}},{key:\"_getCalculatedScrollLeft\",value:function(e,n){var t=e.columnCount,r=e.height,o=e.scrollToAlignment,i=e.scrollToColumn,a=e.width,l=n.scrollLeft,c=n.instanceProps;if(t>0){var s=t-1,u=i<0?s:Math.min(s,i),p=c.rowSizeAndPositionManager.getTotalSize(),f=c.scrollbarSizeMeasured&&p>r?c.scrollbarSize:0;return c.columnSizeAndPositionManager.getUpdatedOffsetForIndex({align:o,containerSize:a-f,currentOffset:l,targetIndex:u})}return 0}},{key:\"_getScrollLeftForScrollToColumnStateUpdate\",value:function(e,n){var r=n.scrollLeft,o=t._getCalculatedScrollLeft(e,n);return\"number\"==typeof o&&o>=0&&r!==o?t._getScrollToPositionStateUpdate({prevState:n,scrollLeft:o,scrollTop:-1}):{}}},{key:\"_getCalculatedScrollTop\",value:function(e,n){var t=e.height,r=e.rowCount,o=e.scrollToAlignment,i=e.scrollToRow,a=e.width,l=n.scrollTop,c=n.instanceProps;if(r>0){var s=r-1,u=i<0?s:Math.min(s,i),p=c.columnSizeAndPositionManager.getTotalSize(),f=c.scrollbarSizeMeasured&&p>a?c.scrollbarSize:0;return c.rowSizeAndPositionManager.getUpdatedOffsetForIndex({align:o,containerSize:t-f,currentOffset:l,targetIndex:u})}return 0}},{key:\"_getScrollTopForScrollToRowStateUpdate\",value:function(e,n){var r=n.scrollTop,o=t._getCalculatedScrollTop(e,n);return\"number\"==typeof o&&o>=0&&r!==o?t._getScrollToPositionStateUpdate({prevState:n,scrollLeft:-1,scrollTop:o}):{}}}])}(n.PureComponent);v(Y,\"defaultProps\",{\"aria-label\":\"grid\",\"aria-readonly\":!0,autoContainerWidth:!1,autoHeight:!1,autoWidth:!1,cellRangeRenderer:function(e){for(var t=e.cellCache,r=e.cellRenderer,o=e.columnSizeAndPositionManager,i=e.columnStartIndex,a=e.columnStopIndex,l=e.deferredMeasurementCache,c=e.horizontalOffsetAdjustment,s=e.isScrolling,u=e.isScrollingOptOut,p=e.parent,f=e.rowSizeAndPositionManager,d=e.rowStartIndex,g=e.rowStopIndex,h=e.styleCache,A=e.verticalOffsetAdjustment,b=e.visibleColumnIndices,v=e.visibleRowIndices,m=[],y=o.areOffsetsAdjusted()||f.areOffsetsAdjusted(),E=!s&&!y,C=d;C<=g;C++)for(var w=f.getSizeAndPositionOfCell(C),x=i;x<=a;x++){var S=o.getSizeAndPositionOfCell(x),_=x>=b.start&&x<=b.stop&&C>=v.start&&C<=v.stop,k=\"\".concat(C,\"-\").concat(x),O=void 0;E&&h[k]?O=h[k]:l&&!l.has(C,x)?O={height:\"auto\",left:0,position:\"absolute\",top:0,width:\"auto\"}:(O={height:w.size,left:S.offset+c,position:\"absolute\",top:w.offset+A,width:S.size},h[k]=O);var B={columnIndex:x,isScrolling:s,isVisible:_,key:k,parent:p,rowIndex:C,style:O},P=void 0;!u&&!s||c||A?P=r(B):(t[k]||(t[k]=r(B)),P=t[k]),null!=P&&!1!==P&&(P.props.role||(P=n.cloneElement(P,{role:\"gridcell\"})),m.push(P))}return m},containerRole:\"row\",containerStyle:{},estimatedColumnSize:100,estimatedRowSize:30,getScrollbarSize:function(e){if((!B&&0!==B||e)&&O){var n=document.createElement(\"div\");n.style.position=\"absolute\",n.style.top=\"-9999px\",n.style.width=\"50px\",n.style.height=\"50px\",n.style.overflow=\"scroll\",document.body.appendChild(n),B=n.offsetWidth-n.clientWidth,document.body.removeChild(n)}return B},noContentRenderer:function(){return null},onScroll:function(){},onScrollbarPresenceChange:function(){},onSectionRendered:function(){},overscanColumnCount:0,overscanIndicesGetter:function(e){var n=e.cellCount,t=e.overscanCellsCount,r=e.scrollDirection,o=e.startIndex,i=e.stopIndex;return 1===r?{overscanStartIndex:Math.max(0,o),overscanStopIndex:Math.min(n-1,i+t)}:{overscanStartIndex:Math.max(0,o-t),overscanStopIndex:Math.min(n-1,i)}},overscanRowCount:10,role:\"grid\",scrollingResetTimeInterval:150,scrollToAlignment:\"auto\",scrollToColumn:-1,scrollToRow:-1,style:{},tabIndex:0,isScrollingOptOut:!1}),function(e){var n=e.prototype;if(!n||!n.isReactComponent)throw new Error(\"Can only polyfill class components\");if(\"function\"!=typeof e.getDerivedStateFromProps&&\"function\"!=typeof n.getSnapshotBeforeUpdate)return e;var t=null,r=null,o=null;if(\"function\"==typeof n.componentWillMount?t=\"componentWillMount\":\"function\"==typeof n.UNSAFE_componentWillMount&&(t=\"UNSAFE_componentWillMount\"),\"function\"==typeof n.componentWillReceiveProps?r=\"componentWillReceiveProps\":\"function\"==typeof n.UNSAFE_componentWillReceiveProps&&(r=\"UNSAFE_componentWillReceiveProps\"),\"function\"==typeof n.componentWillUpdate?o=\"componentWillUpdate\":\"function\"==typeof n.UNSAFE_componentWillUpdate&&(o=\"UNSAFE_componentWillUpdate\"),null!==t||null!==r||null!==o){var i=e.displayName||e.name,a=\"function\"==typeof e.getDerivedStateFromProps?\"getDerivedStateFromProps()\":\"getSnapshotBeforeUpdate()\";throw Error(\"Unsafe legacy lifecycles will not be called for components using new component APIs.\\n\\n\"+i+\" uses \"+a+\" but also contains the following legacy lifecycles:\"+(null!==t?\"\\n  \"+t:\"\")+(null!==r?\"\\n  \"+r:\"\")+(null!==o?\"\\n  \"+o:\"\")+\"\\n\\nThe above lifecycles should be removed. Learn more about this warning here:\\nhttps://fb.me/react-async-component-lifecycle-hooks\")}if(\"function\"==typeof e.getDerivedStateFromProps&&(n.componentWillMount=T,n.componentWillReceiveProps=I),\"function\"==typeof n.getSnapshotBeforeUpdate){if(\"function\"!=typeof n.componentDidUpdate)throw new Error(\"Cannot polyfill getSnapshotBeforeUpdate() for components that do not define componentDidUpdate() on the prototype\");n.componentWillUpdate=j;var l=n.componentDidUpdate;n.componentDidUpdate=function(e,n,t){var r=this.__reactInternalSnapshotFlag?this.__reactInternalSnapshot:t;l.call(this,e,n,r)}}}(Y);const q=Y;function V(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(V=function(){return!!e})()}var $=function(e){function t(){var e,n,r,o;s(this,t);for(var i=arguments.length,a=new Array(i),l=0;l<i;l++)a[l]=arguments[l];return n=this,r=t,o=[].concat(a),r=h(r),v(e=g(n,V()?Reflect.construct(r,o||[],h(n).constructor):r.apply(n,o)),\"Grid\",void 0),v(e,\"_cellRenderer\",(function(n){var t=n.parent,r=n.rowIndex,o=n.style,i=n.isScrolling,a=n.isVisible,l=n.key,c=e.props.rowRenderer,s=Object.getOwnPropertyDescriptor(o,\"width\");return s&&s.writable&&(o.width=\"100%\"),c({index:r,style:o,isScrolling:i,isVisible:a,key:l,parent:t})})),v(e,\"_setRef\",(function(n){e.Grid=n})),v(e,\"_onScroll\",(function(n){var t=n.clientHeight,r=n.scrollHeight,o=n.scrollTop;(0,e.props.onScroll)({clientHeight:t,scrollHeight:r,scrollTop:o})})),v(e,\"_onSectionRendered\",(function(n){var t=n.rowOverscanStartIndex,r=n.rowOverscanStopIndex,o=n.rowStartIndex,i=n.rowStopIndex;(0,e.props.onRowsRendered)({overscanStartIndex:t,overscanStopIndex:r,startIndex:o,stopIndex:i})})),e}return b(t,e),d(t,[{key:\"forceUpdateGrid\",value:function(){this.Grid&&this.Grid.forceUpdate()}},{key:\"getOffsetForRow\",value:function(e){var n=e.alignment,t=e.index;return this.Grid?this.Grid.getOffsetForCell({alignment:n,rowIndex:t,columnIndex:0}).scrollTop:0}},{key:\"invalidateCellSizeAfterRender\",value:function(e){var n=e.columnIndex,t=e.rowIndex;this.Grid&&this.Grid.invalidateCellSizeAfterRender({rowIndex:t,columnIndex:n})}},{key:\"measureAllRows\",value:function(){this.Grid&&this.Grid.measureAllCells()}},{key:\"recomputeGridSize\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.columnIndex,t=void 0===n?0:n,r=e.rowIndex,o=void 0===r?0:r;this.Grid&&this.Grid.recomputeGridSize({rowIndex:o,columnIndex:t})}},{key:\"recomputeRowHeights\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;this.Grid&&this.Grid.recomputeGridSize({rowIndex:e,columnIndex:0})}},{key:\"scrollToPosition\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;this.Grid&&this.Grid.scrollToPosition({scrollTop:e})}},{key:\"scrollToRow\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0;this.Grid&&this.Grid.scrollToCell({columnIndex:0,rowIndex:e})}},{key:\"render\",value:function(){var e=this.props,t=e.className,r=e.noRowsRenderer,o=e.scrollToIndex,i=e.width,a=y(\"ReactVirtualized__List\",t);return n.createElement(q,c({},this.props,{autoContainerWidth:!0,cellRenderer:this._cellRenderer,className:a,columnWidth:i,columnCount:1,noContentRenderer:r,onScroll:this._onScroll,onSectionRendered:this._onSectionRendered,ref:this._setRef,scrollToRow:o}))}}])}(n.PureComponent);function K(e,n){var r,o=void 0!==(r=void 0!==n?n:\"undefined\"!=typeof window?window:\"undefined\"!=typeof self?self:t.g).document&&r.document.attachEvent;if(!o){var i=function(){var e=r.requestAnimationFrame||r.mozRequestAnimationFrame||r.webkitRequestAnimationFrame||function(e){return r.setTimeout(e,20)};return function(n){return e(n)}}(),a=function(){var e=r.cancelAnimationFrame||r.mozCancelAnimationFrame||r.webkitCancelAnimationFrame||r.clearTimeout;return function(n){return e(n)}}(),l=function(e){var n=e.__resizeTriggers__,t=n.firstElementChild,r=n.lastElementChild,o=t.firstElementChild;r.scrollLeft=r.scrollWidth,r.scrollTop=r.scrollHeight,o.style.width=t.offsetWidth+1+\"px\",o.style.height=t.offsetHeight+1+\"px\",t.scrollLeft=t.scrollWidth,t.scrollTop=t.scrollHeight},c=function(e){if(!(e.target.className&&\"function\"==typeof e.target.className.indexOf&&e.target.className.indexOf(\"contract-trigger\")<0&&e.target.className.indexOf(\"expand-trigger\")<0)){var n=this;l(this),this.__resizeRAF__&&a(this.__resizeRAF__),this.__resizeRAF__=i((function(){(function(e){return e.offsetWidth!=e.__resizeLast__.width||e.offsetHeight!=e.__resizeLast__.height})(n)&&(n.__resizeLast__.width=n.offsetWidth,n.__resizeLast__.height=n.offsetHeight,n.__resizeListeners__.forEach((function(t){t.call(n,e)})))}))}},s=!1,u=\"\",p=\"animationstart\",f=\"Webkit Moz O ms\".split(\" \"),d=\"webkitAnimationStart animationstart oAnimationStart MSAnimationStart\".split(\" \"),g=r.document.createElement(\"fakeelement\");if(void 0!==g.style.animationName&&(s=!0),!1===s)for(var h=0;h<f.length;h++)if(void 0!==g.style[f[h]+\"AnimationName\"]){u=\"-\"+f[h].toLowerCase()+\"-\",p=d[h],s=!0;break}var A=\"resizeanim\",b=\"@\"+u+\"keyframes \"+A+\" { from { opacity: 0; } to { opacity: 0; } } \",v=u+\"animation: 1ms \"+A+\"; \"}return{addResizeListener:function(n,t){if(o)n.attachEvent(\"onresize\",t);else{if(!n.__resizeTriggers__){var i=n.ownerDocument,a=r.getComputedStyle(n);a&&\"static\"==a.position&&(n.style.position=\"relative\"),function(n){if(!n.getElementById(\"detectElementResize\")){var t=(b||\"\")+\".resize-triggers { \"+(v||\"\")+'visibility: hidden; opacity: 0; } .resize-triggers, .resize-triggers > div, .contract-trigger:before { content: \" \"; display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; z-index: -1; } .resize-triggers > div { background: #eee; overflow: auto; } .contract-trigger:before { width: 200%; height: 200%; }',r=n.head||n.getElementsByTagName(\"head\")[0],o=n.createElement(\"style\");o.id=\"detectElementResize\",o.type=\"text/css\",null!=e&&o.setAttribute(\"nonce\",e),o.styleSheet?o.styleSheet.cssText=t:o.appendChild(n.createTextNode(t)),r.appendChild(o)}}(i),n.__resizeLast__={},n.__resizeListeners__=[],(n.__resizeTriggers__=i.createElement(\"div\")).className=\"resize-triggers\";var s=i.createElement(\"div\");s.className=\"expand-trigger\",s.appendChild(i.createElement(\"div\"));var u=i.createElement(\"div\");u.className=\"contract-trigger\",n.__resizeTriggers__.appendChild(s),n.__resizeTriggers__.appendChild(u),n.appendChild(n.__resizeTriggers__),l(n),n.addEventListener(\"scroll\",c,!0),p&&(n.__resizeTriggers__.__animationListener__=function(e){e.animationName==A&&l(n)},n.__resizeTriggers__.addEventListener(p,n.__resizeTriggers__.__animationListener__))}n.__resizeListeners__.push(t)}},removeResizeListener:function(e,n){if(o)e.detachEvent(\"onresize\",n);else if(e.__resizeListeners__.splice(e.__resizeListeners__.indexOf(n),1),!e.__resizeListeners__.length){e.removeEventListener(\"scroll\",c,!0),e.__resizeTriggers__.__animationListener__&&(e.__resizeTriggers__.removeEventListener(p,e.__resizeTriggers__.__animationListener__),e.__resizeTriggers__.__animationListener__=null);try{e.__resizeTriggers__=!e.removeChild(e.__resizeTriggers__)}catch(e){}}}}}function Q(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function X(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?Q(Object(t),!0).forEach((function(n){v(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):Q(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function Z(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Z=function(){return!!e})()}v($,\"defaultProps\",{autoHeight:!1,estimatedRowSize:30,onScroll:function(){},noRowsRenderer:function(){return null},onRowsRendered:function(){},overscanIndicesGetter:function(e){var n=e.cellCount,t=e.overscanCellsCount,r=e.scrollDirection,o=e.startIndex,i=e.stopIndex;return t=Math.max(1,t),1===r?{overscanStartIndex:Math.max(0,o-1),overscanStopIndex:Math.min(n-1,i+t)}:{overscanStartIndex:Math.max(0,o-t),overscanStopIndex:Math.min(n-1,i+1)}},overscanRowCount:10,scrollToAlignment:\"auto\",scrollToIndex:-1,style:{}});var J=function(e){function t(){var e,n,r,o;s(this,t);for(var i=arguments.length,a=new Array(i),l=0;l<i;l++)a[l]=arguments[l];return n=this,r=t,o=[].concat(a),r=h(r),v(e=g(n,Z()?Reflect.construct(r,o||[],h(n).constructor):r.apply(n,o)),\"state\",{height:e.props.defaultHeight||0,width:e.props.defaultWidth||0}),v(e,\"_parentNode\",void 0),v(e,\"_autoSizer\",void 0),v(e,\"_window\",void 0),v(e,\"_detectElementResize\",void 0),v(e,\"_onResize\",(function(){var n=e.props,t=n.disableHeight,r=n.disableWidth,o=n.onResize;if(e._parentNode){var i=e._parentNode.offsetHeight||0,a=e._parentNode.offsetWidth||0,l=(e._window||window).getComputedStyle(e._parentNode)||{},c=parseInt(l.paddingLeft,10)||0,s=parseInt(l.paddingRight,10)||0,u=parseInt(l.paddingTop,10)||0,p=parseInt(l.paddingBottom,10)||0,f=i-u-p,d=a-c-s;(!t&&e.state.height!==f||!r&&e.state.width!==d)&&(e.setState({height:i-u-p,width:a-c-s}),o({height:i,width:a}))}})),v(e,\"_setRef\",(function(n){e._autoSizer=n})),e}return b(t,e),d(t,[{key:\"componentDidMount\",value:function(){var e=this.props.nonce;this._autoSizer&&this._autoSizer.parentNode&&this._autoSizer.parentNode.ownerDocument&&this._autoSizer.parentNode.ownerDocument.defaultView&&this._autoSizer.parentNode instanceof this._autoSizer.parentNode.ownerDocument.defaultView.HTMLElement&&(this._parentNode=this._autoSizer.parentNode,this._window=this._autoSizer.parentNode.ownerDocument.defaultView,this._detectElementResize=K(e,this._window),this._detectElementResize.addResizeListener(this._parentNode,this._onResize),this._onResize())}},{key:\"componentWillUnmount\",value:function(){this._detectElementResize&&this._parentNode&&this._detectElementResize.removeResizeListener(this._parentNode,this._onResize)}},{key:\"render\",value:function(){var e=this.props,t=e.children,r=e.className,o=e.disableHeight,i=e.disableWidth,a=e.style,l=this.state,c=l.height,s=l.width,u={overflow:\"visible\"},p={};return o||(u.height=0,p.height=c),i||(u.width=0,p.width=s),n.createElement(\"div\",{className:r,ref:this._setRef,style:X(X({},u),a)},t(p))}}])}(n.Component);v(J,\"defaultProps\",{onResize:function(){},disableHeight:!1,disableWidth:!1,style:{}});var ee=[],ne=null,te=null;function re(){te&&(te=null,document.body&&null!=ne&&(document.body.style.pointerEvents=ne),ne=null)}function oe(){re(),ee.forEach((function(e){return e.__resetIsScrolling()}))}function ie(e){e.currentTarget===window&&null==ne&&document.body&&(ne=document.body.style.pointerEvents,document.body.style.pointerEvents=\"none\"),function(){te&&N(te);var e=0;ee.forEach((function(n){e=Math.max(e,n.props.scrollingResetTimeInterval)})),te=F(oe,e)}(),ee.forEach((function(n){n.props.scrollElement===e.currentTarget&&n.__handleWindowScrollEvent()}))}function ae(e,n){ee.some((function(e){return e.props.scrollElement===n}))||n.addEventListener(\"scroll\",ie),ee.push(e)}function le(e,n){(ee=ee.filter((function(n){return n!==e}))).length||(n.removeEventListener(\"scroll\",ie),te&&(N(te),re()))}var ce=function(e){return e===window},se=function(e){return e.getBoundingClientRect()};function ue(e,n){if(e){if(ce(e)){var t=window,r=t.innerHeight,o=t.innerWidth;return{height:\"number\"==typeof r?r:0,width:\"number\"==typeof o?o:0}}return se(e)}return{height:n.serverHeight,width:n.serverWidth}}function pe(e){return ce(e)&&document.documentElement?{top:\"scrollY\"in window?window.scrollY:document.documentElement.scrollTop,left:\"scrollX\"in window?window.scrollX:document.documentElement.scrollLeft}:{top:e.scrollTop,left:e.scrollLeft}}function fe(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function de(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?fe(Object(t),!0).forEach((function(n){v(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):fe(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function ge(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(ge=function(){return!!e})()}var he=function(){return\"undefined\"!=typeof window?window:void 0},Ae=function(e){function t(){var e,r,o,i;s(this,t);for(var a=arguments.length,l=new Array(a),c=0;c<a;c++)l[c]=arguments[c];return r=this,o=t,i=[].concat(l),o=h(o),v(e=g(r,ge()?Reflect.construct(o,i||[],h(r).constructor):o.apply(r,i)),\"_window\",he()),v(e,\"_isMounted\",!1),v(e,\"_positionFromTop\",0),v(e,\"_positionFromLeft\",0),v(e,\"_detectElementResize\",void 0),v(e,\"_child\",void 0),v(e,\"_windowScrollerRef\",n.createRef()),v(e,\"state\",de(de({},ue(e.props.scrollElement,e.props)),{},{isScrolling:!1,scrollLeft:0,scrollTop:0})),v(e,\"_registerChild\",(function(n){!n||n instanceof Element||console.warn(\"WindowScroller registerChild expects to be passed Element or null\"),e._child=n,e.updatePosition()})),v(e,\"_onChildScroll\",(function(n){var t=n.scrollTop;if(e.state.scrollTop!==t){var r=e.props.scrollElement;r&&(\"function\"==typeof r.scrollTo?r.scrollTo(0,t+e._positionFromTop):r.scrollTop=t+e._positionFromTop)}})),v(e,\"_registerResizeListener\",(function(n){n===window?window.addEventListener(\"resize\",e._onResize,!1):e._detectElementResize.addResizeListener(n,e._onResize)})),v(e,\"_unregisterResizeListener\",(function(n){n===window?window.removeEventListener(\"resize\",e._onResize,!1):n&&e._detectElementResize.removeResizeListener(n,e._onResize)})),v(e,\"_onResize\",(function(){e.updatePosition()})),v(e,\"__handleWindowScrollEvent\",(function(){if(e._isMounted){var n=e.props.onScroll,t=e.props.scrollElement;if(t){var r=pe(t),o=Math.max(0,r.left-e._positionFromLeft),i=Math.max(0,r.top-e._positionFromTop);e.setState({isScrolling:!0,scrollLeft:o,scrollTop:i}),n({scrollLeft:o,scrollTop:i})}}})),v(e,\"__resetIsScrolling\",(function(){e.setState({isScrolling:!1})})),e}return b(t,e),d(t,[{key:\"updatePosition\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:this.props.scrollElement,n=this.props.onResize,t=this.state,r=t.height,o=t.width,i=this._child||this._windowScrollerRef.current;if(i instanceof Element&&e){var a=function(e,n){if(ce(n)&&document.documentElement){var t=document.documentElement,r=se(e),o=se(t);return{top:r.top-o.top,left:r.left-o.left}}var i=pe(n),a=se(e),l=se(n);return{top:a.top+i.top-l.top,left:a.left+i.left-l.left}}(i,e);this._positionFromTop=a.top,this._positionFromLeft=a.left}var l=ue(e,this.props);r===l.height&&o===l.width||(this.setState({height:l.height,width:l.width}),n({height:l.height,width:l.width})),!0===this.props.updateScrollTopOnUpdatePosition&&(this.__handleWindowScrollEvent(),this.__resetIsScrolling())}},{key:\"componentDidMount\",value:function(){var e=this.props.scrollElement;this._detectElementResize=K(),this.updatePosition(e),e&&(ae(this,e),this._registerResizeListener(e)),this._isMounted=!0}},{key:\"componentDidUpdate\",value:function(e,n){var t=this.props.scrollElement,r=e.scrollElement;r!==t&&null!=r&&null!=t&&(this.updatePosition(t),le(this,r),ae(this,t),this._unregisterResizeListener(r),this._registerResizeListener(t))}},{key:\"componentWillUnmount\",value:function(){var e=this.props.scrollElement;e&&(le(this,e),this._unregisterResizeListener(e)),this._isMounted=!1}},{key:\"render\",value:function(){var e=this.props.children,t=this.state,r=t.isScrolling,o=t.scrollTop,i=t.scrollLeft,a=t.height,l=t.width;return n.createElement(\"div\",{ref:this._windowScrollerRef},e({onChildScroll:this._onChildScroll,registerChild:this._registerChild,height:a,isScrolling:r,scrollLeft:i,scrollTop:o,width:l}))}}])}(n.PureComponent);v(Ae,\"defaultProps\",{onResize:function(){},onScroll:function(){},scrollingResetTimeInterval:150,scrollElement:he(),serverHeight:0,serverWidth:0});const be=Ae;function ve(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(ve=function(){return!!e})()}var me=function(e){function t(){var e,r,o,i;s(this,t);for(var a=arguments.length,l=new Array(a),c=0;c<a;c++)l[c]=arguments[c];return r=this,o=t,i=[].concat(l),o=h(o),v(e=g(r,ve()?Reflect.construct(o,i||[],h(r).constructor):o.apply(r,i)),\"_child\",n.createRef()),v(e,\"_measure\",(function(){var n=e.props,t=n.cache,r=n.columnIndex,o=void 0===r?0:r,i=n.parent,a=n.rowIndex,l=void 0===a?e.props.index||0:a,c=e._getCellMeasurements(),s=c.height,u=c.width;s===t.getHeight(l,o)&&u===t.getWidth(l,o)||(t.set(l,o,u,s),i&&\"function\"==typeof i.recomputeGridSize&&i.recomputeGridSize({columnIndex:o,rowIndex:l}))})),v(e,\"_registerChild\",(function(n){!n||n instanceof Element||console.warn(\"CellMeasurer registerChild expects to be passed Element or null\"),e._child.current=n,n&&e._maybeMeasureCell()})),e}return b(t,e),d(t,[{key:\"componentDidMount\",value:function(){this._maybeMeasureCell()}},{key:\"componentDidUpdate\",value:function(){this._maybeMeasureCell()}},{key:\"render\",value:function(){var e=this,t=this.props.children,r=\"function\"==typeof t?t({measure:this._measure,registerChild:this._registerChild}):t;return null===r?r:(0,n.cloneElement)(r,{ref:function(n){\"function\"==typeof r.ref?r.ref(n):r.ref&&(r.ref.current=n),e._child.current=n}})}},{key:\"_getCellMeasurements\",value:function(){var e=this.props.cache,n=this._child.current;if(n&&n.ownerDocument&&n.ownerDocument.defaultView&&n instanceof n.ownerDocument.defaultView.HTMLElement){var t=n.style.width,r=n.style.height;e.hasFixedWidth()||(n.style.width=\"auto\"),e.hasFixedHeight()||(n.style.height=\"auto\");var o=Math.ceil(n.offsetHeight),i=Math.ceil(n.offsetWidth);return t&&(n.style.width=t),r&&(n.style.height=r),{height:o,width:i}}return{height:0,width:0}}},{key:\"_maybeMeasureCell\",value:function(){var e=this.props,n=e.cache,t=e.columnIndex,r=void 0===t?0:t,o=e.parent,i=e.rowIndex,a=void 0===i?this.props.index||0:i;if(!n.has(a,r)){var l=this._getCellMeasurements(),c=l.height,s=l.width;n.set(a,r,s,c),o&&\"function\"==typeof o.invalidateCellSizeAfterRender&&o.invalidateCellSizeAfterRender({columnIndex:r,rowIndex:a})}}}])}(n.PureComponent);v(me,\"__internalCellMeasurerFlag\",!1);var ye=function(){return d((function e(){var n=this,t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};s(this,e),v(this,\"_cellHeightCache\",{}),v(this,\"_cellWidthCache\",{}),v(this,\"_columnWidthCache\",{}),v(this,\"_rowHeightCache\",{}),v(this,\"_defaultHeight\",void 0),v(this,\"_defaultWidth\",void 0),v(this,\"_minHeight\",void 0),v(this,\"_minWidth\",void 0),v(this,\"_keyMapper\",void 0),v(this,\"_hasFixedHeight\",void 0),v(this,\"_hasFixedWidth\",void 0),v(this,\"_columnCount\",0),v(this,\"_rowCount\",0),v(this,\"columnWidth\",(function(e){var t=e.index,r=n._keyMapper(0,t);return void 0!==n._columnWidthCache[r]?n._columnWidthCache[r]:n._defaultWidth})),v(this,\"rowHeight\",(function(e){var t=e.index,r=n._keyMapper(t,0);return void 0!==n._rowHeightCache[r]?n._rowHeightCache[r]:n._defaultHeight}));var r=t.defaultHeight,o=t.defaultWidth,i=t.fixedHeight,a=t.fixedWidth,l=t.keyMapper,c=t.minHeight,u=t.minWidth;this._hasFixedHeight=!0===i,this._hasFixedWidth=!0===a,this._minHeight=c||0,this._minWidth=u||0,this._keyMapper=l||Ee,this._defaultHeight=Math.max(this._minHeight,\"number\"==typeof r?r:30),this._defaultWidth=Math.max(this._minWidth,\"number\"==typeof o?o:100)}),[{key:\"clear\",value:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,t=this._keyMapper(e,n);delete this._cellHeightCache[t],delete this._cellWidthCache[t],this._updateCachedColumnAndRowSizes(e,n)}},{key:\"clearAll\",value:function(){this._cellHeightCache={},this._cellWidthCache={},this._columnWidthCache={},this._rowHeightCache={},this._rowCount=0,this._columnCount=0}},{key:\"defaultHeight\",get:function(){return this._defaultHeight}},{key:\"defaultWidth\",get:function(){return this._defaultWidth}},{key:\"hasFixedHeight\",value:function(){return this._hasFixedHeight}},{key:\"hasFixedWidth\",value:function(){return this._hasFixedWidth}},{key:\"getHeight\",value:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;if(this._hasFixedHeight)return this._defaultHeight;var t=this._keyMapper(e,n);return void 0!==this._cellHeightCache[t]?Math.max(this._minHeight,this._cellHeightCache[t]):this._defaultHeight}},{key:\"getWidth\",value:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;if(this._hasFixedWidth)return this._defaultWidth;var t=this._keyMapper(e,n);return void 0!==this._cellWidthCache[t]?Math.max(this._minWidth,this._cellWidthCache[t]):this._defaultWidth}},{key:\"has\",value:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,t=this._keyMapper(e,n);return void 0!==this._cellHeightCache[t]}},{key:\"set\",value:function(e,n,t,r){var o=this._keyMapper(e,n);n>=this._columnCount&&(this._columnCount=n+1),e>=this._rowCount&&(this._rowCount=e+1),this._cellHeightCache[o]=r,this._cellWidthCache[o]=t,this._updateCachedColumnAndRowSizes(e,n)}},{key:\"_updateCachedColumnAndRowSizes\",value:function(e,n){if(!this._hasFixedWidth){for(var t=0,r=0;r<this._rowCount;r++)t=Math.max(t,this.getWidth(r,n));var o=this._keyMapper(0,n);this._columnWidthCache[o]=t}if(!this._hasFixedHeight){for(var i=0,a=0;a<this._columnCount;a++)i=Math.max(i,this.getHeight(e,a));var l=this._keyMapper(e,0);this._rowHeightCache[l]=i}}}])}();function Ee(e,n){return\"\".concat(e,\"-\").concat(n)}var Ce=t(4643),we=t.n(Ce),xe=Number.isNaN||function(e){return\"number\"==typeof e&&e!=e};function Se(e,n){if(e.length!==n.length)return!1;for(var t=0;t<e.length;t++)if(r=e[t],o=n[t],!(r===o||xe(r)&&xe(o)))return!1;var r,o;return!0}function _e(e,n){void 0===n&&(n=Se);var t=null;function r(){for(var r=[],o=0;o<arguments.length;o++)r[o]=arguments[o];if(t&&t.lastThis===this&&n(r,t.lastArgs))return t.lastResult;var i=e.apply(this,r);return t={lastResult:i,lastArgs:r,lastThis:this},i}return r.clear=function(){t=null},r}t(3418),t(4346),t(2712),t(4782),t(3288),t(2010),t(5506),t(7495),t(8781);function ke(e){return ke=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},ke(e)}function Oe(e){return function(e){if(Array.isArray(e))return Te(e)}(e)||function(e){if(\"undefined\"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e[\"@@iterator\"])return Array.from(e)}(e)||Pe(e)||function(){throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}()}function Be(e,n){return function(e){if(Array.isArray(e))return e}(e)||function(e,n){var t=null==e?null:\"undefined\"!=typeof Symbol&&e[Symbol.iterator]||e[\"@@iterator\"];if(null!=t){var r,o,i,a,l=[],c=!0,s=!1;try{if(i=(t=t.call(e)).next,0===n){if(Object(t)!==t)return;c=!1}else for(;!(c=(r=i.call(t)).done)&&(l.push(r.value),l.length!==n);c=!0);}catch(e){s=!0,o=e}finally{try{if(!c&&null!=t.return&&(a=t.return(),Object(a)!==a))return}finally{if(s)throw o}}return l}}(e,n)||Pe(e,n)||function(){throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}()}function Pe(e,n){if(e){if(\"string\"==typeof e)return Te(e,n);var t={}.toString.call(e).slice(8,-1);return\"Object\"===t&&e.constructor&&(t=e.constructor.name),\"Map\"===t||\"Set\"===t?Array.from(e):\"Arguments\"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?Te(e,n):void 0}}function Te(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=Array(n);t<n;t++)r[t]=e[t];return r}function Ie(){for(var e=arguments.length,n=new Array(e),t=0;t<e;t++)n[t]=arguments[t];return n.reduce((function(e,n){return n?\"object\"===ke(n)?[].concat(Oe(e),Oe((t=n,Object.entries(t).reduce((function(e,n){var t=Be(n,2),r=t[0];return t[1]?[].concat(Oe(e),[r]):e}),[])))):[].concat(Oe(e),[n]):e;var t}),[]).join(\" \")}t(9089);var je={};var ze=(Date.now()*Math.random()).toString(36).substring(0,4);function De(e){if(!e)throw Error('Argument \"name\" is required in getUID()');je[e]||(je[e]=0);var n=String(je[e]++);return\"\".concat(e).concat(n,\"-\").concat(ze)}function Re(e){var n,t,r=!1;function o(){t=window.requestAnimationFrame((function(){var e;null===(e=n)||void 0===e||e(),r?(r=!1,o()):(t=null,n=null)}))}return function(i){n=i,t?e&&(r=!0):o()}}t(6033),t(3772);function Me(e){var n=new Map,t=new WeakMap;return function(r){var o=null!=r?r:\"__singleValue__\",i=o instanceof Object?t:n,a=i.get(o);if(null!=a)return a;var l=e(r);return i.set(o,l),l}}t(1415),t(744);function Ne(e){return Ne=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Ne(e)}function Fe(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Le(r.key),r)}}function Le(e){var n=function(e,n){if(\"object\"!=Ne(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Ne(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Ne(n)?n:n+\"\"}var He=window.getComputedStyle.bind(window);function Ue(e){return e===document||e instanceof Node&&document.documentElement.contains(e.parentNode)}var We={top:0,right:0,bottom:0,left:0,width:0,height:0};function Ge(e){if(e instanceof Range||null!=e&&Ue(e)){var n=e.getBoundingClientRect();return{top:n.top,right:n.right,bottom:n.bottom,left:n.left,width:n.width,height:n.height}}return Object.assign({},We)}function Ye(){return window.innerHeight}function qe(e){var n=Ge(e),t=n.top,r=n.bottom,o=n.left,i=n.right;return!(r<0||i<0||Ye()-t<0||window.innerWidth-o<0)}var Ve=function(e){return function(n){(arguments.length>1&&void 0!==arguments[1]?arguments[1]:\"\").split(/\\s+/g).filter((function(e){return!!e})).forEach((function(t){return n[e](t)}))}};Ve(\"add\"),Ve(\"remove\");var $e=function(){return function(e,n,t){return n&&Fe(e.prototype,n),t&&Fe(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}((function e(){!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,e),function(e,n,t){(n=Le(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t}(this,\"_all\",new Set)}),[{key:\"add\",value:function(e,n,t,r){e.addEventListener(n,t,r);var o=function(){return e.removeEventListener(n,t,r)};return this._all.add(o),o}},{key:\"remove\",value:function(e){e(),this._all.delete(e)}},{key:\"removeAll\",value:function(){var e=this;this._all.forEach((function(n){return e.remove(n)}))}}])}();t(4554),t(1699),t(1761);var Ke=t(5888),Qe=t.n(Ke),Xe=t(7500),Ze=new(t.n(Xe)());Ze.sniff();const Je=Ze;function en(e){return en=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},en(e)}function nn(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,rn(r.key),r)}}function tn(e,n,t){return(n=rn(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function rn(e){var n=function(e,n){if(\"object\"!=en(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=en(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==en(n)?n:n+\"\"}var on=function(){return function(e,n,t){return n&&nn(e.prototype,n),t&&nn(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}((function e(){var n=this;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,e),tn(this,\"ALLOW_SHORTCUTS_SELECTOR\",\".ring-js-shortcuts\"),tn(this,\"ROOT_SCOPE\",{scopeId:\"ROOT\",options:{}}),tn(this,\"_scopes\",{}),tn(this,\"_scopeChain\",[]),tn(this,\"combokeys\",new(Qe())(document.documentElement)),tn(this,\"trigger\",(function(e){return n.combokeys.trigger(e)})),tn(this,\"_dispatcher\",(function(e,t){for(var r,o=n._scopeChain.length-1;o>=0;o--){var i=n._scopeChain[o];if((r=n._scopes[i.scopeId])&&null!=t&&r[t]){var a=r[t](e,t,i.scopeId);if(!0!==a)return a}if(i.options.modal)return!0}})),tn(this,\"_defaultFilter\",(function(e,t,r){return t!==document&&t instanceof HTMLElement&&null!=r&&!t.matches(n.ALLOW_SHORTCUTS_SELECTOR)&&!(null!=t.dataset.enabledShortcuts?t.dataset.enabledShortcuts.split(\",\").includes(r):null!=t.closest(n.ALLOW_SHORTCUTS_SELECTOR))&&(t.matches(\"input:not([type=checkbox]),select,textarea\")||\"true\"===t.contentEditable)})),this.setFilter(),this.setScope()}),[{key:\"bind\",value:function(e){if(!(e instanceof Object)||\"function\"!=typeof e.handler)throw new Error(\"Shortcut handler should exist\");if(e.scope||(e.scope=this.ROOT_SCOPE.scopeId),Array.isArray(e.key))for(var n=0;n<e.key.length;n++)this.bind(Object.assign({},e,{key:e.key[n]}));else{if(\"string\"!=typeof e.key)throw new Error(\"Shortcut key should exist\");var t=this._scopes[e.scope];t||(t=this._scopes[e.scope]={}),t[e.key]=e.handler,this.combokeys.bind(e.key,this._dispatcher,this._getKeyboardEventType(e))}}},{key:\"bindMap\",value:function(e,n){if(!(e instanceof Object))throw new Error(\"Shortcuts map shouldn't be empty\");for(var t in e)e.hasOwnProperty(t)&&this.bind(Object.assign({},n||{},{key:t,handler:e[t]}))}},{key:\"unbindScope\",value:function(e){this._scopes[e]=null}},{key:\"getScope\",value:function(){return this._scopeChain.slice(1)}},{key:\"hasScope\",value:function(e){return-1!==this.indexOfScope(e)}},{key:\"pushScope\",value:function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(e){var t=this.indexOfScope(e);-1!==t&&this._scopeChain.splice(t,1),this._scopeChain.push(this.wrapScope(e,n))}}},{key:\"popScope\",value:function(e){if(e){var n=this.indexOfScope(e);if(-1!==n)return this._scopeChain.splice(n,this._scopeChain.length-1)}}},{key:\"spliceScope\",value:function(e){if(e){var n=this.indexOfScope(e);-1!==n&&this._scopeChain.splice(n,1)}}},{key:\"setScope\",value:function(e){var n=this;if(e){var t;if(t=\"string\"==typeof e||!Array.isArray(e)&&\"object\"===en(e)&&null!==e?[e]:e,!Array.isArray(t))return;var r=t.map((function(e){return\"string\"==typeof e?n.wrapScope(e):e}));this._scopeChain=[this.ROOT_SCOPE].concat(r)}else this._scopeChain=[this.ROOT_SCOPE]}},{key:\"wrapScope\",value:function(e){return{scopeId:e,options:arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}}}},{key:\"hasKey\",value:function(e,n){var t;return!(null===(t=this._scopes[n])||void 0===t||!t[e])}},{key:\"_getKeyboardEventType\",value:function(e){if(!e.type&&\"windows\"===Je.os.name&&(\"string\"==typeof e.key&&e.key.match(/ctrl/i)&&e.key.match(/shift/i)&&e.key.match(/[0-9]/)))return\"keyup\";return e.type}},{key:\"setFilter\",value:function(e){this.combokeys.stopCallback=\"function\"==typeof e?e:this._defaultFilter}},{key:\"indexOfScope\",value:function(e){return this._scopeChain.findIndex((function(n){return n.scopeId===e}))}},{key:\"reset\",value:function(){this._scopes={},this.setScope(),this.combokeys.reset()}}])}();const an=new on;function ln(e){return ln=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},ln(e)}function cn(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,gn(r.key),r)}}function sn(e,n,t){return n=pn(n),function(e,n){if(n&&(\"object\"==ln(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,un()?Reflect.construct(n,t||[],pn(e).constructor):n.apply(e,t))}function un(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(un=function(){return!!e})()}function pn(e){return pn=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},pn(e)}function fn(e,n){return fn=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},fn(e,n)}function dn(e,n,t){return(n=gn(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function gn(e){var n=function(e,n){if(\"object\"!=ln(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=ln(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==ln(n)?n:n+\"\"}var hn=function(e){function n(){return function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,n),sn(this,n,arguments)}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&fn(e,n)}(n,e),function(e,n,t){return n&&cn(e.prototype,n),t&&cn(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(n,[{key:\"componentDidMount\",value:function(){this.props.disabled||this.turnShorcutsOn()}},{key:\"componentDidUpdate\",value:function(e){var n=this.props,t=n.disabled,r=n.map;!e.disabled&&t&&this.turnShorcutsOff(),e.disabled&&!t&&this.turnShorcutsOn(),e.map!==r&&an.bindMap(r,this.props)}},{key:\"componentWillUnmount\",value:function(){this.props.disabled||this.turnShorcutsOff()}},{key:\"turnShorcutsOn\",value:function(){var e=this.props,n=e.map,t=e.scope,r=e.options;an.bindMap(n,this.props),an.pushScope(t,r)}},{key:\"turnShorcutsOff\",value:function(){var e=this.props.scope;an.unbindScope(e),an.spliceScope(e)}},{key:\"render\",value:function(){return this.props.children||null}}])}(n.PureComponent);function An(e,n){return function(e){if(Array.isArray(e))return e}(e)||function(e,n){var t=null==e?null:\"undefined\"!=typeof Symbol&&e[Symbol.iterator]||e[\"@@iterator\"];if(null!=t){var r,o,i,a,l=[],c=!0,s=!1;try{if(i=(t=t.call(e)).next,0===n){if(Object(t)!==t)return;c=!1}else for(;!(c=(r=i.call(t)).done)&&(l.push(r.value),l.length!==n);c=!0);}catch(e){s=!0,o=e}finally{try{if(!c&&null!=t.return&&(a=t.return(),Object(a)!==a))return}finally{if(s)throw o}}return l}}(e,n)||function(e,n){if(e){if(\"string\"==typeof e)return bn(e,n);var t={}.toString.call(e).slice(8,-1);return\"Object\"===t&&e.constructor&&(t=e.constructor.name),\"Map\"===t||\"Set\"===t?Array.from(e):\"Arguments\"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?bn(e,n):void 0}}(e,n)||function(){throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}()}function bn(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=Array(n);t<n;t++)r[t]=e[t];return r}dn(hn,\"propTypes\",{map:i().object.isRequired,scope:i().string.isRequired,options:i().object,disabled:i().bool,children:i().node}),dn(hn,\"defaultProps\",{options:{}});t(778);var vn=[\"onConditionalClick\",\"onPlainLeftClick\",\"activeClassName\",\"href\",\"children\"];function mn(e){return mn=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},mn(e)}function yn(){return yn=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},yn.apply(null,arguments)}function En(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,kn(r.key),r)}}function Cn(e,n,t){return n=xn(n),function(e,n){if(n&&(\"object\"==mn(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,wn()?Reflect.construct(n,t||[],xn(e).constructor):n.apply(e,t))}function wn(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(wn=function(){return!!e})()}function xn(e){return xn=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},xn(e)}function Sn(e,n){return Sn=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},Sn(e,n)}function _n(e,n,t){return(n=kn(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function kn(e){var n=function(e,n){if(\"object\"!=mn(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=mn(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==mn(n)?n:n+\"\"}var On=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return _n(e=Cn(this,t,[].concat(r)),\"onClick\",(function(n){var t=e.props,r=t.onClick,o=t.onConditionalClick,i=t.onPlainLeftClick,a=function(e){return!(0!==e.button||e.altKey||e.ctrlKey||e.metaKey||e.shiftKey)}(n);r&&r(n),o&&o(a,n),i&&a&&(n.preventDefault(),i(n))})),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&Sn(e,n)}(t,e),function(e,n,t){return n&&En(e.prototype,n),t&&En(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"render\",value:function(){var e=this.props,t=(e.onConditionalClick,e.onPlainLeftClick,e.activeClassName,e.href),r=e.children,o=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,vn);return n.createElement(\"a\",yn({href:t},o,{onClick:this.onClick}),r)}}])}(n.PureComponent);_n(On,\"propTypes\",{onClick:i().func,onPlainLeftClick:i().func,onConditionalClick:i().func,activeClassName:i().string,href:i().string.isRequired,children:i().node.isRequired});var Bn=t(7826),Pn=t.n(Bn),Tn=[\"active\",\"inherit\",\"pseudo\",\"hover\",\"className\",\"data-test\",\"href\",\"innerClassName\",\"children\",\"onPlainLeftClick\",\"onClick\"];function In(e){return In=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},In(e)}function jn(){return jn=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},jn.apply(null,arguments)}function zn(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function Dn(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?zn(Object(t),!0).forEach((function(n){Hn(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):zn(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function Rn(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Un(r.key),r)}}function Mn(e,n,t){return n=Fn(n),function(e,n){if(n&&(\"object\"==In(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Nn()?Reflect.construct(n,t||[],Fn(e).constructor):n.apply(e,t))}function Nn(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Nn=function(){return!!e})()}function Fn(e){return Fn=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},Fn(e)}function Ln(e,n){return Ln=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},Ln(e,n)}function Hn(e,n,t){return(n=Un(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function Un(e){var n=function(e,n){if(\"object\"!=In(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=In(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==In(n)?n:n+\"\"}var Wn=!1;var Gn=Me((function(e){function t(t){var r=t.className,o=t.children,i=l()(Pn().inner,r,e);return n.createElement(\"span\",{className:i},o)}return t.propTypes={className:i().string,children:i().node},(0,n.memo)(t)}));function Yn(e){var t,r=\"string\"!=typeof e&&e!==On;return t=function(t){function o(){return function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,o),Mn(this,o,arguments)}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&Ln(e,n)}(o,t),function(e,n,t){return n&&Rn(e.prototype,n),t&&Rn(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(o,[{key:\"getChildren\",value:function(){var e=this.props,t=e.children,r=e.innerClassName,o=Gn(r);return\"function\"==typeof t?t(o):n.createElement(o,null,t)}},{key:\"render\",value:function(){var t=this.props,o=t.active,i=t.inherit,a=t.pseudo,c=t.hover,s=t.className,u=t[\"data-test\"],p=t.href,f=(t.innerClassName,t.children),d=t.onPlainLeftClick,g=t.onClick,h=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(t,Tn),A=a||!r&&null==p,b=l()(Pn().link,s,Hn(Hn(Hn(Hn(Hn(Hn({},Pn().active,o),Pn().inherit,i),Pn().hover,c),Pn().compatibilityUnderlineMode,Wn),Pn().pseudo,A),Pn().text,\"function\"!=typeof f)),v=h;return r&&!v.activeClassName&&(v=Dn(Dn({},v),{},{activeClassName:Pn().active})),A?n.createElement(\"button\",jn({type:\"button\"},v,{className:b,onClick:g||d,\"data-test\":Ie(\"ring-link\",u)}),this.getChildren()):n.createElement(e,jn({},v,{href:p,className:b,onClick:g,onPlainLeftClick:d,\"data-test\":Ie(\"ring-link\",u)}),this.getChildren())}}])}(n.PureComponent),Hn(t,\"propTypes\",{className:i().string,innerClassName:i().string,active:i().bool,inherit:i().bool,pseudo:i().bool,hover:i().bool,children:i().oneOfType([i().node,i().func]),\"data-test\":i().string,href:i().string,onPlainLeftClick:i().func,onClick:i().func}),t}const qn=Yn(On);var Vn=t(1914),$n=t.n(Vn);function Kn(e){return Kn=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Kn(e)}var Qn=[\"scrolling\",\"data-test\",\"className\",\"label\",\"hover\",\"description\",\"rgItemType\",\"url\",\"onCheckboxChange\",\"disabled\",\"LinkComponent\",\"compact\",\"hoverClassName\",\"children\"];function Xn(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function Zn(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?Xn(Object(t),!0).forEach((function(n){et(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):Xn(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function Jn(){return Jn=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},Jn.apply(null,arguments)}function et(e,n,t){return(n=tt(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function nt(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,tt(r.key),r)}}function tt(e){var n=function(e,n){if(\"object\"!=Kn(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Kn(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Kn(n)?n:n+\"\"}function rt(e,n,t){return n=it(n),function(e,n){if(n&&(\"object\"==Kn(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,ot()?Reflect.construct(n,t||[],it(e).constructor):n.apply(e,t))}function ot(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(ot=function(){return!!e})()}function it(e){return it=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},it(e)}function at(e,n){return at=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},at(e,n)}var lt=function(e){function t(){return function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t),rt(this,t,arguments)}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&at(e,n)}(t,e),function(e,n,t){return n&&nt(e.prototype,n),t&&nt(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"render\",value:function(){var e=this.props,t=e.scrolling,r=e[\"data-test\"],o=e.className,i=e.label,a=e.hover,c=(e.description,e.rgItemType,e.url,e.onCheckboxChange,e.disabled),s=e.LinkComponent,u=e.compact,p=(e.hoverClassName,e.children),f=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,Qn),d=l()($n().item,o,et(et(et({},$n().actionLink,!c),$n().compact,u),$n().scrolling,t)),g=s?Yn(s):qn;return n.createElement(g,Jn({pseudo:!this.props.href},f,{hover:a&&!c,className:d,\"data-test\":Ie(\"ring-list-link\",r)}),null!=i?i:p)}}])}(n.PureComponent);lt.propTypes=Zn(Zn({},qn.propTypes),{},{description:i().string,label:i().oneOfType([i().element,i().string,i().func]),rgItemType:i().number,scrolling:i().bool.isRequired,url:i().string,LinkComponent:i().oneOfType([i().instanceOf(n.Component),i().func,i().string]),onCheckboxChange:i().func.isRequired,compact:i().bool});t(5440);function ct(e){if(null==e)return{};var n,t=/([^&;=]+)=?([^&;]*)/g,r={};function o(e){return decodeURIComponent(e.replace(/\\+/g,\" \"))}for(;null!=(n=t.exec(e));)r[o(n[1])]=o(n[2]);return r}function st(e){return encodeURIComponent(String(e)).replace(/%2C/g,\",\")}function ut(e,n){var t,r=-1===e.indexOf(\"?\")?\"?\":\"&\",o=e,i=0;for(t in n)n.hasOwnProperty(t)&&null!=n[t]&&(o+=(0===i++?r:\"&\")+st(t)+\"=\"+st(n[t]));return o}function pt(e){return 0===e.indexOf(\"data:\")}var ft=t(4504),dt=t.n(ft);t(2152);function gt(e){return function(e){if(Array.isArray(e))return bt(e)}(e)||function(e){if(\"undefined\"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e[\"@@iterator\"])return Array.from(e)}(e)||At(e)||function(){throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}()}function ht(e,n){return function(e){if(Array.isArray(e))return e}(e)||function(e,n){var t=null==e?null:\"undefined\"!=typeof Symbol&&e[Symbol.iterator]||e[\"@@iterator\"];if(null!=t){var r,o,i,a,l=[],c=!0,s=!1;try{if(i=(t=t.call(e)).next,0===n){if(Object(t)!==t)return;c=!1}else for(;!(c=(r=i.call(t)).done)&&(l.push(r.value),l.length!==n);c=!0);}catch(e){s=!0,o=e}finally{try{if(!c&&null!=t.return&&(a=t.return(),Object(a)!==a))return}finally{if(s)throw o}}return l}}(e,n)||At(e,n)||function(){throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}()}function At(e,n){if(e){if(\"string\"==typeof e)return bt(e,n);var t={}.toString.call(e).slice(8,-1);return\"Object\"===t&&e.constructor&&(t=e.constructor.name),\"Map\"===t||\"Set\"===t?Array.from(e):\"Arguments\"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?bt(e,n):void 0}}function bt(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=Array(n);t<n;t++)r[t]=e[t];return r}var vt=[[\"#60A800\",\"#D5CA00\"],[\"#21D370\",\"#03E9E1\"],[\"#3BA1FF\",\"#36E97D\"],[\"#00C243\",\"#00FFFF\"],[\"#4BE098\",\"#627FFF\"],[\"#168BFA\",\"#26F7C7\"],[\"#9D4CFF\",\"#39D3C3\"],[\"#0A81F6\",\"#0ACFF6\"],[\"#765AF8\",\"#5A91F8\"],[\"#9E54FF\",\"#0ACFF6\"],[\"#B345F1\",\"#669DFF\"],[\"#765AF8\",\"#C059EE\"],[\"#9039D0\",\"#C239D0\"],[\"#9F2AFF\",\"#FD56FD\"],[\"#AB3AF2\",\"#E40568\"],[\"#9F2AFF\",\"#E9A80B\"],[\"#D50F6B\",\"#E73AE8\"],[\"#ED5502\",\"#E73AE8\"],[\"#ED358C\",\"#DBED18\"],[\"#ED358C\",\"#F9902E\"],[\"#FF7500\",\"#FFCA00\"]],mt={18:{radius:2,text:{x:9,y:13},fontSize:\"11px\",textAnchor:\"middle\"},24:{radius:3,text:{x:2,y:13},fontSize:\"11px\",underscore:{x:3,y:17}},32:{radius:3,text:{x:3,y:17},fontSize:\"13px\",letterSpacing:1,underscore:{x:4,y:22}},40:{radius:3,text:{x:5,y:19},fontSize:\"15px\",letterSpacing:1,underscore:{x:6,y:28}}},yt=Object.keys(mt).map(Number);function Et(e){var t,r=e.username,o=e.size,i=e.round,a=Math.abs(function(e){for(var n=0,t=0;t<e.length;t++)n=Math.imul(31,n)+e.charCodeAt(t)|0;return n}(r.toLowerCase())),l=ht(vt[a%vt.length],2),c=l[0],s=l[1],u=yt.filter((function(e){return e>=o})),p=u.length>0?Math.min.apply(Math,gt(u)):Math.max.apply(Math,gt(yt)),f=mt[p],d=i?\"50%\":f.radius,g=(0,n.useMemo)((function(){return De(\"gradient-\")}),[]);return n.createElement(\"svg\",{viewBox:\"0 0 \".concat(p,\" \").concat(p),xmlns:\"http://www.w3.org/2000/svg\"},n.createElement(\"defs\",null,n.createElement(\"linearGradient\",{id:g,x1:\"0\",y1:\"0\",x2:\"0\",y2:\"1\"},n.createElement(\"stop\",{stopColor:c,offset:\"0\"}),n.createElement(\"stop\",{stopColor:s,offset:\"1\"}))),n.createElement(\"g\",null,n.createElement(\"rect\",{fill:\"url(#\".concat(g,\")\"),x:\"0\",y:\"0\",width:p,height:p,rx:d,ry:d}),n.createElement(\"text\",{x:f.text.x,y:f.text.y,fontFamily:\"Arial, Helvetica, sans-serif\",fontSize:f.fontSize,letterSpacing:f.letterSpacing,fill:\"#FFFFFF\",textAnchor:f.textAnchor,cursor:\"default\"},n.createElement(\"tspan\",null,(t=r.split(/[\\s._]+/).filter(Boolean).map((function(e){return Array.from(e)}))).length>=2?t[0][0].toUpperCase()+t[1][0].toUpperCase():1===t.length?t[0].length>=2?t[0].slice(0,2).join(\"\").toUpperCase():\"\".concat(t[0][0].toUpperCase(),\"X\"):\"XX\"),f.underscore&&n.createElement(\"tspan\",{x:f.underscore.x,y:f.underscore.y},\"_\")),n.createElement(\"title\",null,r)))}Et.propTypes={username:i().string.isRequired,size:i().number.isRequired,round:i().bool};var Ct,wt=[\"size\",\"url\",\"dpr\",\"style\",\"round\",\"subavatar\",\"subavatarSize\",\"username\",\"skipParams\"];function xt(e){return xt=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},xt(e)}function St(e,n){return function(e){if(Array.isArray(e))return e}(e)||function(e,n){var t=null==e?null:\"undefined\"!=typeof Symbol&&e[Symbol.iterator]||e[\"@@iterator\"];if(null!=t){var r,o,i,a,l=[],c=!0,s=!1;try{if(i=(t=t.call(e)).next,0===n){if(Object(t)!==t)return;c=!1}else for(;!(c=(r=i.call(t)).done)&&(l.push(r.value),l.length!==n);c=!0);}catch(e){s=!0,o=e}finally{try{if(!c&&null!=t.return&&(a=t.return(),Object(a)!==a))return}finally{if(s)throw o}}return l}}(e,n)||function(e,n){if(e){if(\"string\"==typeof e)return _t(e,n);var t={}.toString.call(e).slice(8,-1);return\"Object\"===t&&e.constructor&&(t=e.constructor.name),\"Map\"===t||\"Set\"===t?Array.from(e):\"Arguments\"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?_t(e,n):void 0}}(e,n)||function(){throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}()}function _t(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=Array(n);t<n;t++)r[t]=e[t];return r}function kt(){return kt=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},kt.apply(null,arguments)}function Ot(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function Bt(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?Ot(Object(t),!0).forEach((function(n){Dt(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):Ot(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function Pt(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Rt(r.key),r)}}function Tt(e,n,t){return n=jt(n),function(e,n){if(n&&(\"object\"==xt(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,It()?Reflect.construct(n,t||[],jt(e).constructor):n.apply(e,t))}function It(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(It=function(){return!!e})()}function jt(e){return jt=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},jt(e)}function zt(e,n){return zt=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},zt(e,n)}function Dt(e,n,t){return(n=Rt(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function Rt(e){var n=function(e,n){if(\"object\"!=xt(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=xt(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==xt(n)?n:n+\"\"}!function(e){e[e.Size18=18]=\"Size18\",e[e.Size20=20]=\"Size20\",e[e.Size24=24]=\"Size24\",e[e.Size28=28]=\"Size28\",e[e.Size32=32]=\"Size32\",e[e.Size40=40]=\"Size40\",e[e.Size48=48]=\"Size48\",e[e.Size56=56]=\"Size56\"}(Ct||(Ct={}));var Mt=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return Dt(e=Tt(this,t,[].concat(r)),\"state\",{errorUrl:\"\"}),Dt(e,\"handleError\",(function(){e.setState({errorUrl:e.props.url})})),Dt(e,\"handleSuccess\",(function(){e.setState({errorUrl:\"\"})})),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&zt(e,n)}(t,e),function(e,n,t){return n&&Pt(e.prototype,n),t&&Pt(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"render\",value:function(){var e=this.props,t=e.size,r=e.url,o=e.dpr,i=e.style,a=e.round,c=e.subavatar,s=e.subavatarSize,u=e.username,p=e.skipParams,f=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,wt),d=\"\".concat(t,\"px\"),g=\"\".concat(s,\"px\"),h=t<=Ct.Size18?\"var(--ring-border-radius-small)\":\"var(--ring-border-radius)\",A=Bt({borderRadius:a?\"50%\":h,height:d,width:d},i),b=Bt({borderRadius:\"2px\",height:g,width:g},i);if(!r||this.state.errorUrl===r)return n.createElement(\"span\",kt({},f,{\"data-test\":\"avatar\",className:l()(dt().avatar,this.props.className,Dt({},dt().empty,null==u)),style:A}),null!=u&&n.createElement(Et,{size:t,round:a,username:u}));var v=r;if(!p&&!pt(r)){var m=St(r.split(\"?\"),2);v=ut(m[0],Bt(Bt({},ct(m[1])),{},{dpr:o,size:t}))}var y=null;if(c&&!pt(c)){var E=St(c.split(\"?\"),2),C=E[0],w=Bt(Bt({},ct(E[1])),{},{dpr:o,subavatarSizeString:g});return y=p?c:ut(C,w),n.createElement(\"div\",null,n.createElement(\"img\",kt({},f,{onError:this.handleError,onLoad:this.handleSuccess,className:l()(dt().avatar,this.props.className),style:A,src:v,alt:\"User avatar\"})),n.createElement(\"img\",kt({},f,{\"data-test\":\"avatar\",onError:this.handleError,onLoad:this.handleSuccess,className:l()(dt().subavatar),style:b,src:y,alt:\"Subavatar\"})))}return n.createElement(\"img\",kt({},f,{\"data-test\":\"avatar\",onError:this.handleError,onLoad:this.handleSuccess,className:l()(dt().avatar,this.props.className),style:A,src:v,alt:\"User avatar\"}))}}])}(n.PureComponent);Dt(Mt,\"propTypes\",{dpr:i().number,className:i().string,size:i().number,style:i().object,url:i().string,round:i().bool,subavatar:i().string,subavatarSize:i().number,username:i().string,skipParams:i().bool}),Dt(Mt,\"defaultProps\",{dpr:\"devicePixelRatio\"in window?window.devicePixelRatio:1,size:Ct.Size20,subavatarSize:Ct.Size20/2,style:{}});var Nt,Ft,Lt=t(1817),Ht=t.n(Lt),Ut=t(8420),Wt=t.n(Ut);!function(e){e.BLUE=\"blue\",e.DEFAULT=\"\",e.GRAY=\"gray\",e.GREEN=\"green\",e.MAGENTA=\"magenta\",e.RED=\"red\",e.WHITE=\"white\"}(Nt||(Nt={})),function(e){e[e.Size12=12]=\"Size12\",e[e.Size14=14]=\"Size14\",e[e.Size16=16]=\"Size16\",e[e.Size18=18]=\"Size18\",e[e.Size20=20]=\"Size20\",e[e.Size24=24]=\"Size24\",e[e.Size32=32]=\"Size32\",e[e.Size40=40]=\"Size40\",e[e.Size48=48]=\"Size48\",e[e.Size64=64]=\"Size64\",e[e.Size96=96]=\"Size96\",e[e.Size128=128]=\"Size128\"}(Ft||(Ft={}));var Gt=t(9468),Yt=t.n(Gt);t(1392);function qt(e){return qt=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},qt(e)}var Vt=[\"src\",\"className\"];function $t(){return $t=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},$t.apply(null,arguments)}function Kt(e,n,t){return(n=function(e){var n=function(e,n){if(\"object\"!=qt(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=qt(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==qt(n)?n:n+\"\"}(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}var Qt=Me((function(e){var n=document.createElement(\"div\");n.innerHTML=e;var t,r,o=n.firstElementChild;return o.remove?o.remove():n.removeChild(o),{props:(t=o,r=t.attributes,r.length>0?function(e){for(var n={},t=0;t<e.length;t++){var r=e[t].name,o=r;\"class\"===r?o=\"className\":r.startsWith(\"data-\")||(o=r.replace(/[-|:]([a-z])/g,(function(e){return e[1].toUpperCase()}))),n[o]=e[t].value}return n}(r):null),html:o.innerHTML}}));function Xt(e){var t,r,o,i=e.src,a=e.className,c=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,Vt),s=l()(Yt().glyph,Kt({},Yt().compatibilityMode,(r=/width=\"[\\d\\.]+\"/gi.test(t=i),o=/height=\"[\\d\\.]+\"/gi.test(t),!r||!o)),a),u=Qt(i),p=u.props,f=u.html;return n.createElement(\"svg\",$t({},p,c,{className:s,dangerouslySetInnerHTML:{__html:f}}))}Xt.propTypes={className:i().string,src:i().string.isRequired,style:i().object};const Zt=(0,n.memo)(Xt);var Jt=[\"className\",\"size\",\"color\",\"loading\",\"glyph\",\"width\",\"height\",\"suppressSizeWarning\"];function er(e){return er=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},er(e)}function nr(){return nr=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},nr.apply(null,arguments)}function tr(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,cr(r.key),r)}}function rr(e,n,t){return n=ir(n),function(e,n){if(n&&(\"object\"==er(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,or()?Reflect.construct(n,t||[],ir(e).constructor):n.apply(e,t))}function or(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(or=function(){return!!e})()}function ir(e){return ir=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},ir(e)}function ar(e,n){return ar=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},ar(e,n)}function lr(e,n,t){return(n=cr(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function cr(e){var n=function(e,n){if(\"object\"!=er(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=er(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==er(n)?n:n+\"\"}var sr=we()((function(){}),\"`size`, `width` and `height` props are not recommended to use in Ring UI `Icon` component. The intrinsic sizes of SVG icon (`width` and `height` SVG attributes) are used instead.\\n\\nWe strongly recommend to use icons handcrafted for particular sizes. If your icon doesn't exist in the desired size, please ask your designer to draw one. \\\"Responsive\\\" checkmark should be unchecked when exporting icon.'\"),ur=function(e){function t(){return function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t),rr(this,t,arguments)}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&ar(e,n)}(t,e),function(e,n,t){return n&&tr(e.prototype,n),t&&tr(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"warnSize\",value:function(){this.props.suppressSizeWarning||sr()}},{key:\"getStyle\",value:function(){var e=this.props,n=e.size,t=e.width,r=e.height;return t||r?(this.warnSize(),{width:t,height:r}):n?(this.warnSize(),{width:n,height:n}):void 0}},{key:\"render\",value:function(){var e=this.props,t=e.className,r=(e.size,e.color),o=e.loading,i=e.glyph,a=(e.width,e.height,e.suppressSizeWarning,function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,Jt));if(!i)return null;var c=l()(Yt().icon,lr(lr({},Yt()[r],!!r),Yt().loading,o),t);return n.createElement(\"span\",nr({},a,{className:c}),\"string\"==typeof i?n.createElement(Zt,{src:i,style:this.getStyle()}):n.createElement(i,{className:Yt().glyph,style:this.getStyle()}))}}])}(n.PureComponent);lr(ur,\"propTypes\",{className:i().string,color:i().string,glyph:i().oneOfType([i().string,i().elementType]).isRequired,height:i().number,size:i().number,width:i().number,loading:i().bool,suppressSizeWarning:i().bool}),lr(ur,\"defaultProps\",{className:\"\",color:Nt.DEFAULT,glyph:\"\"}),lr(ur,\"Color\",Nt),lr(ur,\"Size\",Ft);var pr=function(e){return i().shape({current:e})};const fr=function(){for(var e=arguments.length,n=new Array(e),t=0;t<e;t++)n[t]=arguments[t];return function(e){return n.forEach((function(n){\"function\"==typeof n?n(e):null!=n&&(n.current=e)}))}};var dr=t(6860),gr=t.n(dr),hr=[\"children\",\"label\",\"className\",\"containerClassName\",\"containerStyle\",\"cellClassName\",\"labelClassName\",\"indeterminate\",\"inputRef\"];function Ar(e){return Ar=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Ar(e)}function br(){return br=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},br.apply(null,arguments)}function vr(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,xr(r.key),r)}}function mr(e,n,t){return n=Er(n),function(e,n){if(n&&(\"object\"==Ar(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,yr()?Reflect.construct(n,t||[],Er(e).constructor):n.apply(e,t))}function yr(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(yr=function(){return!!e})()}function Er(e){return Er=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},Er(e)}function Cr(e,n){return Cr=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},Cr(e,n)}function wr(e,n,t){return(n=xr(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function xr(e){var n=function(e,n){if(\"object\"!=Ar(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Ar(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Ar(n)?n:n+\"\"}var Sr=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return wr(e=mr(this,t,[].concat(r)),\"input\",void 0),wr(e,\"inputRef\",(function(n){null!=n&&(n.indeterminate=e.props.indeterminate),e.input=n})),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&Cr(e,n)}(t,e),function(e,n,t){return n&&vr(e.prototype,n),t&&vr(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"componentDidMount\",value:function(){null!=this.input&&(this.input.indeterminate=this.props.indeterminate)}},{key:\"componentDidUpdate\",value:function(e){var n=this.props.indeterminate;null!=this.input&&n!==e.indeterminate&&(this.input.indeterminate=this.props.indeterminate)}},{key:\"render\",value:function(){var e=this.props,t=e.children,r=e.label,o=e.className,i=e.containerClassName,a=e.containerStyle,c=e.cellClassName,s=e.labelClassName,u=(e.indeterminate,e.inputRef),p=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,hr),f=l()(gr().input,o),d=l()(gr().checkbox,i),g=l()(gr().cell,c),h=l()(gr().label,s);return n.createElement(\"label\",{className:d,style:a,\"data-test\":\"ring-checkbox\"},n.createElement(\"input\",br({},p,{\"data-checked\":p.checked,ref:fr(this.inputRef,u),type:\"checkbox\",className:f})),n.createElement(\"span\",{className:g},n.createElement(ur,{glyph:Ht(),className:gr().check}),n.createElement(ur,{glyph:Wt(),className:gr().minus})),n.createElement(\"span\",{className:h},r||t))}}])}(n.PureComponent);wr(Sr,\"propTypes\",{name:i().string,label:i().string,className:i().string,containerClassName:i().string,containerStyle:i().object,cellClassName:i().string,labelClassName:i().string,defaultChecked:i().bool,checked:i().bool,indeterminate:i().bool,disabled:i().bool,onChange:i().func,children:i().node,inputRef:i().oneOfType([i().func,pr(i().instanceOf(HTMLInputElement))])}),wr(Sr,\"defaultProps\",{indeterminate:!1});var _r=t(6620),kr=t.n(_r),Or=[\"scrolling\",\"className\",\"disabled\",\"checkbox\",\"avatar\",\"subavatar\",\"glyph\",\"icon\",\"rightGlyph\",\"description\",\"label\",\"title\",\"details\",\"hover\",\"rgItemType\",\"level\",\"tabIndex\",\"compact\",\"onClick\",\"onCheckboxChange\",\"onMouseOver\",\"onMouseDown\",\"onMouseUp\",\"rightNodes\",\"leftNodes\",\"showGeneratedAvatar\",\"username\",\"labelWrapper\"];function Br(e){return Br=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Br(e)}function Pr(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Rr(r.key),r)}}function Tr(e,n,t){return n=jr(n),function(e,n){if(n&&(\"object\"==Br(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Ir()?Reflect.construct(n,t||[],jr(e).constructor):n.apply(e,t))}function Ir(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Ir=function(){return!!e})()}function jr(e){return jr=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},jr(e)}function zr(e,n){return zr=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},zr(e,n)}function Dr(e,n,t){return(n=Rr(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function Rr(e){var n=function(e,n){if(\"object\"!=Br(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Br(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Br(n)?n:n+\"\"}var Mr=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return Dr(e=Tr(this,t,[].concat(r)),\"id\",De(\"list-item-\")),Dr(e,\"stopBubbling\",(function(e){return e.stopPropagation()})),Dr(e,\"_isString\",(function(e){return\"string\"==typeof e||e instanceof String})),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&zr(e,n)}(t,e),function(e,n,t){return n&&Pr(e.prototype,n),t&&Pr(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"render\",value:function(){var e=this.props,t=e.scrolling,r=e.className,o=e.disabled,i=e.checkbox,a=e.avatar,c=e.subavatar,s=e.glyph,u=e.icon,p=e.rightGlyph,f=e.description,d=e.label,g=e.title,h=e.details,A=e.hover,b=(e.rgItemType,e.level),v=e.tabIndex,m=e.compact,y=e.onClick,E=e.onCheckboxChange,C=e.onMouseOver,w=e.onMouseDown,x=e.onMouseUp,S=e.rightNodes,_=e.leftNodes,k=e.showGeneratedAvatar,O=e.username,B=e.labelWrapper,P=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,Or),T=k&&null!=O,I=void 0!==i&&(i||!(_||s||a||T)||A&&!o),j=l()($n().item,kr().resetButton,r,Dr(Dr(Dr(Dr(Dr({},$n().action,!o),$n().hover,A&&!o),$n().compact,m),$n().scrolling,t),$n().disabled,o)),z=l()(Dr(Dr({},$n().details,h),$n().padded,void 0!==u||void 0!==i||void 0!==s)),D={paddingLeft:\"\".concat(8*(Number(b)||0)+16+(I?28:0),\"px\")},R=null;R=this._isString(g)?g:this._isString(d)?d:\"\";var M=Ie({\"ring-list-item\":-1===(P[\"data-test\"]||\"\").indexOf(\"ring-list-item\"),\"ring-list-item-action\":!o,\"ring-list-item-selected\":i},P[\"data-test\"]),N=n.createElement(\"span\",{className:$n().label,title:R,\"data-test\":\"ring-list-item-label\"},d);return n.createElement(\"div\",{className:$n().itemContainer,\"data-test\":M},I&&n.createElement(\"div\",{className:$n().checkboxContainer},n.createElement(Sr,{\"aria-labelledby\":this.id,checked:i,disabled:o,onChange:E,onClick:this.stopBubbling})),n.createElement(\"button\",{id:this.id,type:\"button\",tabIndex:v,onClick:y,onMouseOver:C,onMouseDown:w,onFocus:C,onMouseUp:x,className:j,style:D},n.createElement(\"div\",{className:$n().top,onMouseOut:this.stopBubbling,onBlur:this.stopBubbling},!I&&n.createElement(\"div\",{className:$n().left},_,s&&n.createElement(ur,{className:$n().glyph,glyph:s,size:this.props.iconSize}),(a||T)&&n.createElement(Mt,{className:$n().avatar,url:a,size:Ct.Size20,subavatar:c,username:O})),B?B(N):N,f&&n.createElement(\"span\",{className:$n().description,\"data-test\":\"ring-list-item-description\"},f),n.createElement(\"div\",{className:$n().right},p&&n.createElement(ur,{className:$n().rightGlyph,glyph:p,size:this.props.iconSize}),u&&n.createElement(\"div\",{className:$n().icon,style:{backgroundImage:'url(\"'.concat(u,'\")')}}),S)),h&&n.createElement(\"div\",{className:z},h)))}}])}(n.PureComponent);Mr.propTypes={scrolling:i().bool,hover:i().bool,details:i().string,disabled:i().bool,className:i().string,tabIndex:i().number,checkbox:i().bool,description:i().oneOfType([i().string,i().element,i().array]),showGeneratedAvatar:i().bool,username:i().string,avatar:i().string,subavatar:i().string,glyph:i().oneOfType([i().string,i().elementType]),icon:i().string,iconSize:i().number,rightNodes:i().oneOfType([i().string,i().element,i().array]),leftNodes:i().oneOfType([i().string,i().element,i().array]),label:i().oneOfType([i().string,i().element]),title:i().string,level:i().number,rgItemType:i().number,rightGlyph:i().oneOfType([i().string,i().elementType]),compact:i().bool,onClick:i().func,onCheckboxChange:i().func,onMouseOver:i().func,onMouseDown:i().func,onMouseUp:i().func,\"data-test\":i().string};var Nr={Esc:\"Escape\",Spacebar:\" \",Left:\"ArrowLeft\",Up:\"ArrowUp\",Right:\"ArrowRight\",Down:\"ArrowDown\",Del:\"Delete\",Win:\"OS\",Menu:\"ContextMenu\",Apps:\"ContextMenu\",Scroll:\"ScrollLock\",MozPrintableKey:\"Unidentified\"},Fr={8:\"Backspace\",9:\"Tab\",12:\"Clear\",13:\"Enter\",16:\"Shift\",17:\"Control\",18:\"Alt\",19:\"Pause\",20:\"CapsLock\",27:\"Escape\",32:\" \",33:\"PageUp\",34:\"PageDown\",35:\"End\",36:\"Home\",37:\"ArrowLeft\",38:\"ArrowUp\",39:\"ArrowRight\",40:\"ArrowDown\",45:\"Insert\",46:\"Delete\",112:\"F1\",113:\"F2\",114:\"F3\",115:\"F4\",116:\"F5\",117:\"F6\",118:\"F7\",119:\"F8\",120:\"F9\",121:\"F10\",122:\"F11\",123:\"F12\",144:\"NumLock\",145:\"ScrollLock\",224:\"Meta\"};var Lr=[\"scrolling\",\"hover\",\"className\",\"disabled\",\"template\",\"rgItemType\",\"tabIndex\",\"onClick\",\"onCheckboxChange\",\"onMouseOver\",\"onMouseUp\",\"role\",\"tagName\"];function Hr(e){return Hr=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Hr(e)}function Ur(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,$r(r.key),r)}}function Wr(e,n,t){return n=Yr(n),function(e,n){if(n&&(\"object\"==Hr(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Gr()?Reflect.construct(n,t||[],Yr(e).constructor):n.apply(e,t))}function Gr(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Gr=function(){return!!e})()}function Yr(e){return Yr=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},Yr(e)}function qr(e,n){return qr=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},qr(e,n)}function Vr(e,n,t){return(n=$r(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function $r(e){var n=function(e,n){if(\"object\"!=Hr(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Hr(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Hr(n)?n:n+\"\"}var Kr=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return Vr(e=Wr(this,t,[].concat(r)),\"handleKeyPress\",(function(n){var t=function(e){if(e.key){var n=Nr[e.key]||e.key;if(\"Unidentified\"!==n)return n}if(\"keypress\"===e.type){var t=function(e){var n,t=e.keyCode;return\"charCode\"in e?0===(n=e.charCode)&&13===t&&(n=13):n=t,n>=32||13===n?n:0}(e);return 32===t?\"Enter\":String.fromCharCode(t)}return\"keydown\"===e.type||\"keyup\"===e.type?Fr[e.keyCode]||\"Unidentified\":\"\"}(n);\"Enter\"!==t&&\" \"!==t||e.props.onClick(n)})),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&qr(e,n)}(t,e),function(e,n,t){return n&&Ur(e.prototype,n),t&&Ur(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"render\",value:function(){var e=this.props,t=e.scrolling,r=e.hover,o=e.className,i=e.disabled,a=e.template,c=(e.rgItemType,e.tabIndex),s=e.onClick,u=(e.onCheckboxChange,e.onMouseOver),p=e.onMouseUp,f=e.role,d=e.tagName,g=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,Lr),h=l()($n().item,o,Vr(Vr(Vr({},$n().action,!i),$n().hover,r&&!i),$n().scrolling,t)),A=Ie(\"ring-list-item-custom\",{\"ring-list-item-action\":!i},g[\"data-test\"]),b=\"function\"==typeof a?a(this.props):a,v=d||\"span\";return n.createElement(v,{role:f||\"button\",tabIndex:c,onClick:s,onKeyPress:this.handleKeyPress,onMouseOver:u,onFocus:u,onMouseUp:p,className:h,\"data-test\":A},b)}}])}(n.PureComponent);function Qr(e){return Qr=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Qr(e)}function Xr(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Zr(r.key),r)}}function Zr(e){var n=function(e,n){if(\"object\"!=Qr(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Qr(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Qr(n)?n:n+\"\"}function Jr(e,n,t){return n=no(n),function(e,n){if(n&&(\"object\"==Qr(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,eo()?Reflect.construct(n,t||[],no(e).constructor):n.apply(e,t))}function eo(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(eo=function(){return!!e})()}function no(e){return no=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},no(e)}function to(e,n){return to=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},to(e,n)}Kr.propTypes={scrolling:i().bool.isRequired,hover:i().bool.isRequired,className:i().string,disabled:i().bool,rgItemType:i().number,tabIndex:i().number.isRequired,template:i().oneOfType([i().func,i().element,i().string]),onClick:i().func.isRequired,onMouseOver:i().func.isRequired,onMouseUp:i().func,onCheckboxChange:i().func.isRequired,role:i().string,tagName:i().string,\"data-test\":i().string};var ro=function(e){function t(){return function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t),Jr(this,t,arguments)}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&to(e,n)}(t,e),function(e,n,t){return n&&Xr(e.prototype,n),t&&Xr(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"render\",value:function(){var e=this.props,t=e.className,r=e.description,o=e.label,i=e.isFirst,a=l()($n().title,t,function(e,n,t){return(n=Zr(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}({},$n().title_first,i));return n.createElement(\"span\",{className:a,\"data-test\":\"ring-list-title\"},n.createElement(\"span\",{className:l()($n().label,$n().text),\"data-test\":\"ring-list-title-label\"},o),n.createElement(\"div\",{className:$n().description,\"data-test\":\"ring-list-title-description\"},r))}}])}(n.PureComponent);function oo(e){return oo=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},oo(e)}function io(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,ao(r.key),r)}}function ao(e){var n=function(e,n){if(\"object\"!=oo(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=oo(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==oo(n)?n:n+\"\"}function lo(e,n,t){return n=so(n),function(e,n){if(n&&(\"object\"==oo(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,co()?Reflect.construct(n,t||[],so(e).constructor):n.apply(e,t))}function co(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(co=function(){return!!e})()}function so(e){return so=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},so(e)}function uo(e,n){return uo=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},uo(e,n)}ro.propTypes={className:i().string,description:i().oneOfType([i().element,i().string]),label:i().oneOfType([i().element,i().string]),isFirst:i().bool};var po=function(e){function t(){return function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t),lo(this,t,arguments)}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&uo(e,n)}(t,e),function(e,n,t){return n&&io(e.prototype,n),t&&io(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"render\",value:function(){var e=this.props,t=e.description,r=e.isFirst,o=e.className,i=l()($n().separator,o,function(e,n,t){return(n=ao(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}({},$n().separator_first,r));return n.createElement(\"span\",{className:i},t)}}])}(n.PureComponent);function fo(e){return fo=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},fo(e)}function go(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,mo(r.key),r)}}function ho(e,n,t){return n=bo(n),function(e,n){if(n&&(\"object\"==fo(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Ao()?Reflect.construct(n,t||[],bo(e).constructor):n.apply(e,t))}function Ao(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Ao=function(){return!!e})()}function bo(e){return bo=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},bo(e)}function vo(e,n){return vo=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},vo(e,n)}function mo(e){var n=function(e,n){if(\"object\"!=fo(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=fo(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==fo(n)?n:n+\"\"}po.propTypes={className:i().string,description:i().oneOfType([i().element,i().string]),isFirst:i().bool};var yo,Eo,Co=function(e){function t(){return function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t),ho(this,t,arguments)}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&vo(e,n)}(t,e),function(e,n,t){return n&&go(e.prototype,n),t&&go(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"render\",value:function(){return n.createElement(\"span\",{className:l()($n().item,$n().hint),\"data-test\":\"ring-list-hint\"},this.props.label)}}])}(n.PureComponent);!function(e,n,t){(n=mo(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t}(Co,\"propTypes\",{label:i().node}),function(e){e[e.SEPARATOR=0]=\"SEPARATOR\",e[e.LINK=1]=\"LINK\",e[e.ITEM=2]=\"ITEM\",e[e.HINT=3]=\"HINT\",e[e.CUSTOM=4]=\"CUSTOM\",e[e.TITLE=5]=\"TITLE\",e[e.MARGIN=6]=\"MARGIN\"}(yo||(yo={})),function(e){e[e.ITEM_PADDING=16]=\"ITEM_PADDING\",e[e.ITEM_HEIGHT=32]=\"ITEM_HEIGHT\",e[e.COMPACT_ITEM_HEIGHT=24]=\"COMPACT_ITEM_HEIGHT\",e[e.SEPARATOR_HEIGHT=25]=\"SEPARATOR_HEIGHT\",e[e.SEPARATOR_FIRST_HEIGHT=16]=\"SEPARATOR_FIRST_HEIGHT\",e[e.SEPARATOR_TEXT_HEIGHT=18]=\"SEPARATOR_TEXT_HEIGHT\",e[e.TITLE_HEIGHT=42]=\"TITLE_HEIGHT\",e[e.INNER_PADDING=8]=\"INNER_PADDING\",e[e.MARGIN=8]=\"MARGIN\"}(Eo||(Eo={}));var wo=yo.ITEM;function xo(e){return xo=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},xo(e)}var So=[\"selectedLabel\",\"originalModel\"];function _o(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function ko(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?_o(Object(t),!0).forEach((function(n){jo(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):_o(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function Oo(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,zo(r.key),r)}}function Bo(e,n,t){return n=To(n),function(e,n){if(n&&(\"object\"==xo(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Po()?Reflect.construct(n,t||[],To(e).constructor):n.apply(e,t))}function Po(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Po=function(){return!!e})()}function To(e){return To=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},To(e)}function Io(e,n){return Io=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},Io(e,n)}function jo(e,n,t){return(n=zo(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function zo(e){var n=function(e,n){if(\"object\"!=xo(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=xo(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==xo(n)?n:n+\"\"}function Do(){}var Ro=we()((function(){}),\"No key passed for list item with non-string label. It is considered as a bad practice and has been deprecated, please provide a key.\");var Mo=[yo.SEPARATOR,yo.TITLE,yo.MARGIN];function No(e){return null!=e&&!Mo.includes(e.rgItemType)&&!e.disabled}function Fo(e){return e.map((function(e){return\"\".concat(e.key,\"-\").concat(e.disabled)})).join(\"-\")}var Lo=function(e){return e.activateFirstItem||e.activateSingleItem&&1===e.data.length},Ho=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:\"\",r=(0,n.createContext)(e),o=(0,n.createContext)((function(){}));function a(t){var i=t.children,a=An((0,n.useState)(e),2),l=a[0],c=a[1];return n.createElement(r.Provider,{value:l},n.createElement(o.Provider,{value:c},i))}function l(e,t){var r=(0,n.useContext)(o);(0,n.useEffect)((function(){t||r(e)}),[r,e,t])}function c(e){return l(e.value,e.skipUpdate),null}return a.propTypes={children:i().node},a.displayName=\"\".concat(t,\"Provider\"),c.displayName=\"\".concat(t,\"Updater\"),{ValueContext:r,UpdateContext:o,Provider:a,useUpdate:l,Updater:(0,n.memo)(c)}}(void 0,\"ActiveItem\"),Uo=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var r=arguments.length,o=new Array(r),i=0;i<r;i++)o[i]=arguments[i];return jo(e=Bo(this,t,[].concat(o)),\"state\",{activeIndex:null,prevActiveIndex:null,prevData:[],activeItem:null,needScrollToActive:!1,scrolling:!1,hasOverflow:!1,disabledHover:!1,scrolledToBottom:!1}),jo(e,\"scheduleScrollListener\",Re()),jo(e,\"scheduleHoverListener\",Re()),jo(e,\"virtualizedList\",void 0),jo(e,\"unmounted\",void 0),jo(e,\"container\",void 0),jo(e,\"hoverHandler\",Me((function(n){return function(){return e.scheduleHoverListener((function(){e.state.disabledHover||e.container&&e.setState({activeIndex:n,activeItem:e.props.data[n],needScrollToActive:!1})}))}}))),jo(e,\"_bufferSize\",10),jo(e,\"sizeCacheKey\",(function(n){if(0===n||n===e.props.data.length+1)return yo.MARGIN;var t=e.props.data[n-1],r=1===n;switch(t.rgItemType){case yo.SEPARATOR:case yo.TITLE:return\"\".concat(t.rgItemType).concat(r?\"_first\":\"\").concat(t.description?\"_desc\":\"\");case yo.MARGIN:return yo.MARGIN;case yo.CUSTOM:return\"\".concat(yo.CUSTOM,\"_\").concat(t.key);case yo.ITEM:case yo.LINK:default:return t.details?\"\".concat(yo.ITEM,\"_\").concat(t.details):yo.ITEM}})),jo(e,\"_cache\",new ye({defaultHeight:e.defaultItemHeight(),fixedWidth:!0,keyMapper:e.sizeCacheKey})),jo(e,\"_hasActivatableItems\",_e((function(e){return e.some(No)}))),jo(e,\"activateFirst\",(function(){var n=e.props.data.findIndex(No);n>=0&&e.setState({activeIndex:n,activeItem:e.props.data[n],needScrollToActive:!0})})),jo(e,\"selectHandler\",Me((function(n){return function(t){var r=arguments.length>1&&void 0!==arguments[1]&&arguments[1],o=e.props.data[n];!e.props.useMouseUp&&o.onClick?o.onClick(o,t):e.props.useMouseUp&&o.onMouseUp&&o.onMouseUp(o,t),e.props.onSelect&&e.props.onSelect(o,t,{tryKeepOpen:r})}}))),jo(e,\"checkboxHandler\",Me((function(n){return function(t){return e.selectHandler(n)(t,!0)}}))),jo(e,\"upHandler\",(function(n){var t,r=e.props,o=r.data,i=r.disableMoveOverflow,a=e.state.activeIndex;if(null===a||0===a){if(i)return;t=o.length-1}else t=a-1;e.moveHandler(t,e.upHandler,n)})),jo(e,\"downHandler\",(function(n){var t,r=e.props,o=r.data,i=r.disableMoveOverflow,a=r.disableMoveDownOverflow,l=e.state.activeIndex;if(null===l)t=0;else if(l+1===o.length){if(i||a)return;t=0}else t=l+1;e.moveHandler(t,e.downHandler,n)})),jo(e,\"homeHandler\",(function(n){e.moveHandler(0,e.downHandler,n)})),jo(e,\"endHandler\",(function(n){e.moveHandler(e.props.data.length-1,e.upHandler,n)})),jo(e,\"onDocumentMouseMove\",(function(){e.state.disabledHover&&e.setState({disabledHover:!1})})),jo(e,\"onDocumentKeyDown\",(function(n){e.state.disabledHover||[16,17,18,19,20,91].includes(n.keyCode)||e.setState({disabledHover:!0})})),jo(e,\"mouseHandler\",(function(){e.setState({scrolling:!1})})),jo(e,\"scrollHandler\",(function(){e.setState({scrolling:!0},e.scrollEndHandler)})),jo(e,\"enterHandler\",(function(n,t){if(null!==e.state.activeIndex){var r=e.props.data[e.state.activeIndex];return e.selectHandler(e.state.activeIndex)(n),r.href&&!n.defaultPrevented&&(null!=t&&[\"command+enter\",\"ctrl+enter\"].includes(t)?window.open(r.href,\"_blank\"):\"shift+enter\"===t?window.open(r.href):window.location.href=r.href),!1}return!0})),jo(e,\"clearSelected\",(function(){e.setState({activeIndex:null,needScrollToActive:!1})})),jo(e,\"scrollEndHandler\",(function(){return e.scheduleScrollListener((function(){var n=e.inner;if(n){var t=n.scrollHeight,r=e.defaultItemHeight()/2,o=n.scrollTop+n.clientHeight+r,i=t>0&&o>=t;e.unmounted||e.setState({scrolledToBottom:i}),i&&e.props.onScrollToBottom()}}))})),jo(e,\"checkOverflow\",(function(){e.inner&&e.setState({hasOverflow:e.inner.scrollHeight-e.inner.clientHeight>1})})),jo(e,\"renderItem\",(function(t){var r,o,i=t.index,a=void 0===i?1:i,c=t.style,s=t.isScrolling,u=void 0!==s&&s,p=t.parent,f=t.key,d=a-1,g=e.props.data[d],h=e.getId(g);if(0===a||a===e.props.data.length+1||g.rgItemType===yo.MARGIN)r=f||\"\".concat(yo.MARGIN,\"_\").concat(a),o=n.createElement(\"div\",{style:{height:Eo.MARGIN}});else{g.selectedLabel,g.originalModel;var A=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(g,So),b=A;b.url&&(b.href=b.url),b.href&&(b.rgItemType=yo.LINK);var v=Object.assign({rgItemType:wo},A);r=f||h,v.hover=d===e.state.activeIndex,null!=v.hoverClassName&&v.hover&&(v.className=l()(v.className,v.hoverClassName)),v.onMouseOver=e.hoverHandler(d),v.tabIndex=-1,v.scrolling=u;var m,y=e.selectHandler(d);e.props.useMouseUp?v.onMouseUp=y:v.onClick=y,v.onCheckboxChange=e.checkboxHandler(d),null==v.compact&&(v.compact=e.props.compact);var E=1===a;switch(v.rgItemType){case yo.SEPARATOR:m=po,v.isFirst=E;break;case yo.LINK:m=lt,e.addItemDataTestToProp(v);break;case yo.ITEM:m=Mr,e.addItemDataTestToProp(v);break;case yo.CUSTOM:m=Kr,e.addItemDataTestToProp(v);break;case yo.TITLE:v.isFirst=E,m=ro;break;default:throw new Error(\"Unknown menu element type: \".concat(v.rgItemType))}o=n.createElement(m,v)}return p?n.createElement(me,{cache:e._cache,key:r,parent:p,rowIndex:a,columnIndex:0},(function(e){var t=e.registerChild;return n.createElement(\"div\",{ref:t,style:c,role:\"row\",id:h},n.createElement(\"div\",{role:\"cell\"},o))})):n.createElement(\"div\",{role:\"row\",id:h,key:r},n.createElement(\"div\",{role:\"cell\"},o))})),jo(e,\"addItemDataTestToProp\",(function(e){return e[\"data-test\"]=Ie(\"ring-list-item\",e[\"data-test\"]),e})),jo(e,\"virtualizedListRef\",(function(n){e.virtualizedList=n})),jo(e,\"containerRef\",(function(n){e.container=n})),jo(e,\"_inner\",void 0),jo(e,\"id\",De(\"list-\")),jo(e,\"shortcutsScope\",e.id),jo(e,\"shortcutsMap\",{up:e.upHandler,down:e.downHandler,home:e.homeHandler,end:e.endHandler,enter:e.enterHandler,\"meta+enter\":e.enterHandler,\"ctrl+enter\":e.enterHandler,\"command+enter\":e.enterHandler,\"shift+enter\":e.enterHandler}),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&Io(e,n)}(t,e),function(e,n,t){return n&&Oo(e.prototype,n),t&&Oo(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"componentDidMount\",value:function(){document.addEventListener(\"mousemove\",this.onDocumentMouseMove),document.addEventListener(\"keydown\",this.onDocumentKeyDown,!0),null==this.props.activeIndex&&Lo(this.props)&&this.activateFirst()}},{key:\"shouldComponentUpdate\",value:function(e,n){var t=this;return e!==this.props||Object.keys(n).some((function(e){return n[e]!==t.state[e]}))}},{key:\"componentDidUpdate\",value:function(e){this.virtualizedList&&e.data!==this.props.data&&this.virtualizedList.recomputeRowHeights(),null==this.props.activeIndex&&Fo(this.props.data)!==Fo(e.data)&&Lo(this.props)&&this.activateFirst(),this.checkOverflow()}},{key:\"componentWillUnmount\",value:function(){this.unmounted=!0,document.removeEventListener(\"mousemove\",this.onDocumentMouseMove),document.removeEventListener(\"keydown\",this.onDocumentKeyDown,!0)}},{key:\"hasActivatableItems\",value:function(){return this._hasActivatableItems(this.props.data)}},{key:\"moveHandler\",value:function(e,n,t){var r;if(0!==this.props.data.length&&this.hasActivatableItems()){r=this.props.data.length<e?0:e;var o=this.props.data[r];this.setState({activeIndex:r,activeItem:o,needScrollToActive:!0},(function(){No(o)?\"Home\"!==t.key&&\"End\"!==t.key&&function(e){e.preventDefault&&e.preventDefault()}(t):n(t)}))}}},{key:\"getFirst\",value:function(){return this.props.data.find((function(e){return e.rgItemType===yo.ITEM||e.rgItemType===yo.CUSTOM}))}},{key:\"getSelected\",value:function(){return null!=this.state.activeIndex?this.props.data[this.state.activeIndex]:null}},{key:\"defaultItemHeight\",value:function(){return this.props.compact?Eo.COMPACT_ITEM_HEIGHT:Eo.ITEM_HEIGHT}},{key:\"getVisibleListHeight\",value:function(e){return e-this.defaultItemHeight()-Eo.INNER_PADDING}},{key:\"_deprecatedGenerateKeyFromContent\",value:function(e){var n=e.label||e.description;return n&&!(\"string\"==typeof n||n instanceof String)&&(Ro(),\"\".concat(e.rgItemType,\"_\").concat(JSON.stringify(n))),\"\".concat(e.rgItemType,\"_\").concat(n)}},{key:\"getId\",value:function(e){return null!=e?\"\".concat(this.id,\":\").concat(e.key||this._deprecatedGenerateKeyFromContent(e)):void 0}},{key:\"inner\",get:function(){return this._inner||(this._inner=this.container&&this.container.querySelector(\".ring-list__i\")),this._inner}},{key:\"renderVirtualizedInner\",value:function(e){var t=this,r=e.height,o=e.maxHeight,i=e.autoHeight,a=void 0!==i&&i,l=e.rowCount,c=e.isScrolling,s=e.onChildScroll,u=void 0===s?Do:s,p=e.scrollTop,f=e.registerChild,d={direction:\"inherit\"};return n.createElement(J,{disableHeight:!0,onResize:this.props.onResize},(function(e){var i=e.width;return n.createElement(\"div\",{ref:f},n.createElement($,{\"aria-label\":t.props.ariaLabel,ref:t.virtualizedListRef,className:\"ring-list__i\",autoHeight:a,style:o?ko({maxHeight:o,height:\"auto\"},d):d,autoContainerWidth:!0,height:r,width:i,isScrolling:c,onScroll:function(e){u(e),t.scrollEndHandler()},scrollTop:p,rowCount:l,estimatedRowSize:t.defaultItemHeight(),rowHeight:t._cache.rowHeight,rowRenderer:t.renderItem,overscanRowCount:t._bufferSize,noop:function(){},scrollToIndex:!t.props.disableScrollToActive&&t.state.needScrollToActive&&null!=t.state.activeIndex?t.state.activeIndex+1:void 0,scrollToAlignment:\"center\",deferredMeasurementCache:t._cache,onRowsRendered:t.checkOverflow}))}))}},{key:\"renderVirtualized\",value:function(e,t){var r=this;return e?this.renderVirtualizedInner({height:e,maxHeight:e,rowCount:t}):n.createElement(be,null,(function(e){return r.renderVirtualizedInner(ko(ko({},e),{},{rowCount:t,autoHeight:!0}))}))}},{key:\"renderSimple\",value:function(e,t){for(var r=[],o=0;o<t;o++)r.push(this.renderItem({index:o,isScrolling:this.state.scrolling}));return n.createElement(\"div\",{className:l()(\"ring-list__i\",$n().simpleInner),onScroll:this.scrollHandler,onMouseMove:this.mouseHandler},n.createElement(\"div\",{\"aria-label\":this.props.ariaLabel,role:\"grid\",style:e?{maxHeight:this.getVisibleListHeight(e)}:void 0},r))}},{key:\"render\",value:function(){var e=this.getSelected()&&this.props.hintOnSelection||this.props.hint,t=e?{bottom:Eo.ITEM_HEIGHT}:void 0,r=this.props.data.length+2,o=this.props.maxHeight&&this.getVisibleListHeight(this.props.maxHeight),i=l()($n().list,this.props.className);return n.createElement(n.Fragment,null,n.createElement(Ho.Updater,{value:this.getId(this.state.activeItem),skipUpdate:this.props.hidden||!No(this.state.activeItem)}),n.createElement(\"div\",{id:this.props.id,ref:this.containerRef,className:i,onMouseOut:this.props.onMouseOut,onBlur:this.props.onMouseOut,onMouseLeave:this.clearSelected,\"data-test\":\"ring-list\"},this.props.shortcuts&&n.createElement(hn,{map:this.props.shortcutsMap?ko(ko({},this.shortcutsMap),this.props.shortcutsMap):this.shortcutsMap,scope:this.shortcutsScope}),this.props.renderOptimization?this.renderVirtualized(o,r):this.renderSimple(o,r),this.state.hasOverflow&&!this.state.scrolledToBottom&&n.createElement(\"div\",{className:$n().fade,style:t}),e&&n.createElement(Co,{label:e})))}}],[{key:\"getDerivedStateFromProps\",value:function(e,n){var t=n.prevActiveIndex,r=n.prevData,o=n.activeItem,i=e.data,a=e.activeIndex,l=e.restoreActiveIndex,c={prevActiveIndex:a,prevData:i};if(i!==r&&Object.assign(c,{activeIndex:null,activeItem:null}),null!=a&&a!==t&&null!=i[a])Object.assign(c,{activeIndex:a,activeItem:i[a],needScrollToActive:!0});else if(i!==r&&l&&null!=o&&null!=o.key){var s=i.findIndex((function(e){return e.key===o.key}));s>=0&&Object.assign(c,{activeIndex:s,activeItem:i[s]})}return c}}])}(n.Component);jo(Uo,\"propTypes\",{id:i().string,className:i().string,hint:i().node,hintOnSelection:i().string,data:i().array,maxHeight:i().number,activeIndex:i().number,restoreActiveIndex:i().bool,activateSingleItem:i().bool,activateFirstItem:i().bool,shortcuts:i().bool,shortcutsMap:i().object,onMouseOut:i().func,onSelect:i().func,onScrollToBottom:i().func,onResize:i().func,useMouseUp:i().bool,visible:i().bool,renderOptimization:i().bool,disableMoveOverflow:i().bool,disableMoveDownOverflow:i().bool,compact:i().bool,disableScrollToActive:i().bool,hidden:i().bool,ariaLabel:i().string}),jo(Uo,\"defaultProps\",{data:[],restoreActiveIndex:!1,activateSingleItem:!1,activateFirstItem:!1,onMouseOut:Do,onSelect:Do,onScrollToBottom:Do,onResize:Do,shortcuts:!1,renderOptimization:!0,disableMoveDownOverflow:!1,ariaLabel:\"List\"}),jo(Uo,\"isItemType\",(function(e,n){var t=n.rgItemType;return null==t&&(t=wo),t===e})),jo(Uo,\"ListHint\",Co),jo(Uo,\"ListProps\",{Type:yo,Dimension:Eo});t(8431),t(6034),t(2762),t(6031);var Wo,Go=t(5742),Yo=t.n(Go),qo=t(7112),Vo=t.n(qo),$o=t(4982),Ko=t.n($o),Qo=(t(9907),t(4811)),Xo=t.n(Qo);!function(e){e.S=\"S\",e.M=\"M\",e.L=\"L\"}(Wo||(Wo={}));var Zo=(0,n.createContext)(Wo.M);Wo.M;var Jo=t(9102),ei=t.n(Jo);function ni(e){return ni=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},ni(e)}function ti(e,n,t){return(n=function(e){var n=function(e,n){if(\"object\"!=ni(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=ni(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==ni(n)?n:n+\"\"}(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}var ri=[\"active\",\"danger\",\"delayed\",\"loader\",\"primary\",\"short\",\"text\",\"inline\",\"dropdown\",\"height\",\"icon\",\"iconSize\",\"iconClassName\",\"iconSuppressSizeWarning\",\"className\",\"children\"];function oi(e){return oi=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},oi(e)}function ii(){return ii=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},ii.apply(null,arguments)}function ai(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function li(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?ai(Object(t),!0).forEach((function(n){di(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):ai(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function ci(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,gi(r.key),r)}}function si(e,n,t){return n=pi(n),function(e,n){if(n&&(\"object\"==oi(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,ui()?Reflect.construct(n,t||[],pi(e).constructor):n.apply(e,t))}function ui(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(ui=function(){return!!e})()}function pi(e){return pi=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},pi(e)}function fi(e,n){return fi=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},fi(e,n)}function di(e,n,t){return(n=gi(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function gi(e){var n=function(e,n){if(\"object\"!=oi(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=oi(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==oi(n)?n:n+\"\"}var hi=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var r=arguments.length,o=new Array(r),i=0;i<r;i++)o[i]=arguments[i];return di(e=si(this,t,[].concat(o)),\"buttonRef\",(0,n.createRef)()),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&fi(e,n)}(t,e),function(e,n,t){return n&&ci(e.prototype,n),t&&ci(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"render\",value:function(){var e=this.props,t=e.active,r=e.danger,o=e.delayed,i=e.loader,a=e.primary,c=e.short,s=e.text,u=e.inline,p=e.dropdown,f=e.height,d=void 0===f?this.context:f,g=e.icon,h=e.iconSize,A=e.iconClassName,b=e.iconSuppressSizeWarning,v=e.className,m=e.children,y=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,ri),E=function(e){var n,t=e.className,r=e.active,o=e.disabled,i=e.loader,a=e.primary,c=e.short,s=e.text,u=e.inline,p=e.danger,f=e.delayed,d=e.icon,g=e.height,h=d&&!r&&!p&&!a&&!o;return l()(ei().button,t,ei()[\"height\".concat(g)],(ti(ti(ti(ti(ti(ti(ti(ti(ti(ti(n={},ei().active,r),ei().danger,p),ei().delayed,f),ei().withIcon,d),ei().withNormalIcon,h),ei().withDangerIcon,d&&p),ei().loader,i&&!d),ei().primary,a),ei().short,c),ei().text,s),ti(n,ei().inline,u)))}({className:v,active:t,danger:r,delayed:o,icon:g,loader:i,primary:a,short:c,text:s,inline:u,height:d}),C=n.createElement(\"span\",{className:ei().content},g&&n.createElement(\"span\",{className:l()(ei().icon,A)},n.createElement(ur,{glyph:g,size:h,loading:i,suppressSizeWarning:b})),m&&n.createElement(\"span\",null,m),p&&n.createElement(ur,{glyph:Xo(),className:ei().dropdownIcon})),w=li(li({tabIndex:i?-1:0},y),{},{className:E,children:n.createElement(n.Fragment,null,i&&!s&&!g&&n.createElement(\"div\",{className:ei().loaderBackground}),C)});return null!=w.href?n.createElement(On,w):n.createElement(\"button\",ii({ref:this.buttonRef,type:\"button\"},w))}}])}(n.PureComponent);di(hi,\"propTypes\",{active:i().bool,danger:i().bool,delayed:i().bool,loader:i().bool,primary:i().bool,short:i().bool,text:i().bool,inline:i().bool,dropdown:i().bool,href:i().string,target:i().string,icon:i().oneOfType([i().string,i().elementType]),iconSize:i().number,iconClassName:i().string,iconSuppressSizeWarning:i().bool,className:i().string,children:i().node,onClick:i().func}),di(hi,\"IconSize\",Ft),di(hi,\"contextType\",Zo);const Ai=hi;var bi=t(8764),vi=t.n(bi),mi=[\"children\",\"className\"];function yi(){return yi=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},yi.apply(null,arguments)}var Ei=function(e){var t=e.children,r=e.className,o=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,mi);return n.createElement(Ai,yi({\"data-test-ring-dropdown-anchor\":!0,text:!0,className:l()(vi().anchor,r)},o),t,n.createElement(ur,{glyph:Xo(),className:vi().chevron}))};Ei.propTypes={children:i().node,className:i().string};const Ci=(0,n.memo)(Ei);var wi=t(9344),xi=t.n(wi),Si=[\"children\",\"trapDisabled\",\"autoFocusFirst\",\"focusBackOnClose\",\"focusBackOnExit\"];function _i(e){return _i=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},_i(e)}function ki(){return ki=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},ki.apply(null,arguments)}function Oi(e){return function(e){if(Array.isArray(e))return Bi(e)}(e)||function(e){if(\"undefined\"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e[\"@@iterator\"])return Array.from(e)}(e)||function(e,n){if(e){if(\"string\"==typeof e)return Bi(e,n);var t={}.toString.call(e).slice(8,-1);return\"Object\"===t&&e.constructor&&(t=e.constructor.name),\"Map\"===t||\"Set\"===t?Array.from(e):\"Arguments\"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?Bi(e,n):void 0}}(e)||function(){throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}()}function Bi(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=Array(n);t<n;t++)r[t]=e[t];return r}function Pi(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Ri(r.key),r)}}function Ti(e,n,t){return n=ji(n),function(e,n){if(n&&(\"object\"==_i(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Ii()?Reflect.construct(n,t||[],ji(e).constructor):n.apply(e,t))}function Ii(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Ii=function(){return!!e})()}function ji(e){return ji=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},ji(e)}function zi(e,n){return zi=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},zi(e,n)}function Di(e,n,t){return(n=Ri(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function Ri(e){var n=function(e,n){if(\"object\"!=_i(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=_i(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==_i(n)?n:n+\"\"}var Mi=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return Di(e=Ti(this,t,[].concat(r)),\"previousFocusedNode\",void 0),Di(e,\"trapWithoutFocus\",void 0),Di(e,\"restoreFocus\",(function(){var n=e.previousFocusedNode;n instanceof HTMLElement&&n.focus&&qe(n)&&n.focus({preventScroll:!0})})),Di(e,\"node\",void 0),Di(e,\"containerRef\",(function(n){n&&(e.node=n)})),Di(e,\"focusElement\",(function(){var n=!(arguments.length>0&&void 0!==arguments[0])||arguments[0],t=e.node;if(t){var r=Oi(t.querySelectorAll(\"input, button, select, textarea, a[href], *[tabindex]:not([data-trap-button]):not([data-scrollable-container])\")).filter((function(e){return e.tabIndex>=0})),o=n?r[0]:r[r.length-1];o&&o.focus()}})),Di(e,\"focusFirst\",(function(){return e.focusElement(!0)})),Di(e,\"focusLast\",(function(){return e.focusElement(!1)})),Di(e,\"focusLastIfEnabled\",(function(n){if(!e.trapWithoutFocus)if(e.props.focusBackOnExit){var t=n.nativeEvent.relatedTarget;null!=t&&null!=e.node&&t instanceof Element&&e.node.contains(t)&&e.restoreFocus()}else e.focusLast()})),Di(e,\"handleBlurIfWithoutFocus\",(function(n){var t;if(e.trapWithoutFocus){e.trapWithoutFocus=!1;var r=n.nativeEvent.relatedTarget;r&&(r instanceof Element&&null!==(t=e.node)&&void 0!==t&&t.contains(r)||e.focusLast())}})),Di(e,\"trapButtonNode\",void 0),Di(e,\"trapButtonRef\",(function(n){n&&(e.trapButtonNode=n)})),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&zi(e,n)}(t,e),function(e,n,t){return n&&Pi(e.prototype,n),t&&Pi(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"componentDidMount\",value:function(){if(this.previousFocusedNode=document.activeElement,this.props.autoFocusFirst)this.focusFirst();else if(!(this.props.trapDisabled||this.node&&this.node.contains(this.previousFocusedNode))){var e;this.trapWithoutFocus=!0,null===(e=this.trapButtonNode)||void 0===e||e.focus()}}},{key:\"componentWillUnmount\",value:function(){this.props.focusBackOnClose&&this.restoreFocus()}},{key:\"render\",value:function(){var e=this.props,t=e.children,r=e.trapDisabled,o=(e.autoFocusFirst,e.focusBackOnClose,e.focusBackOnExit),i=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,Si);return r?n.createElement(\"div\",ki({ref:this.containerRef},i),t):n.createElement(\"div\",ki({ref:this.containerRef},i),n.createElement(\"div\",{tabIndex:0,ref:this.trapButtonRef,className:xi().trapButton,onFocus:this.focusLastIfEnabled,onBlur:this.handleBlurIfWithoutFocus,\"data-trap-button\":!0}),t,n.createElement(\"div\",{tabIndex:0,onFocus:o?this.restoreFocus:this.focusFirst,\"data-trap-button\":!0}))}}])}(n.Component);Di(Mi,\"propTypes\",{children:i().node.isRequired,trapDisabled:i().bool,autoFocusFirst:i().bool,focusBackOnClose:i().bool,focusBackOnExit:i().bool}),Di(Mi,\"defaultProps\",{trapDisabled:!1,autoFocusFirst:!0,focusBackOnClose:!0,focusBackOnExit:!1});var Ni;t(6910);!function(e){e.BOTTOM_RIGHT=\"BOTTOM_RIGHT\",e.BOTTOM_LEFT=\"BOTTOM_LEFT\",e.BOTTOM_CENTER=\"BOTTOM_CENTER\",e.TOP_LEFT=\"TOP_LEFT\",e.TOP_RIGHT=\"TOP_RIGHT\",e.TOP_CENTER=\"TOP_CENTER\",e.RIGHT_TOP=\"RIGHT_TOP\",e.RIGHT_BOTTOM=\"RIGHT_BOTTOM\",e.RIGHT_CENTER=\"RIGHT_CENTER\",e.LEFT_TOP=\"LEFT_TOP\",e.LEFT_BOTTOM=\"LEFT_BOTTOM\",e.LEFT_CENTER=\"LEFT_CENTER\"}(Ni||(Ni={}));var Fi,Li,Hi,Ui,Wi=[Ni.BOTTOM_RIGHT,Ni.BOTTOM_LEFT,Ni.TOP_LEFT,Ni.TOP_RIGHT,Ni.RIGHT_TOP,Ni.RIGHT_BOTTOM,Ni.LEFT_TOP,Ni.LEFT_BOTTOM];function Gi(e){return Gi=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Gi(e)}function Yi(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function qi(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?Yi(Object(t),!0).forEach((function(n){Vi(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):Yi(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function Vi(e,n,t){return(n=function(e){var n=function(e,n){if(\"object\"!=Gi(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Gi(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Gi(n)?n:n+\"\"}(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function $i(e,n,t){var r=null!==t.container?t.container.clientHeight:Ye(),o=n.top+t.sidePadding,i=n.top+r-t.sidePadding,a=Math.max(o-e.top,0),l=t.popup.clientHeight,c=e.top+l-i;return a+Math.max(c,0)}function Ki(e,n,t){var r=null!==t.container?t.container.clientWidth:window.innerWidth,o=n.left+t.sidePadding,i=n.left+r-t.sidePadding,a=Math.max(o-e.left,0),l=t.popup.clientWidth,c=e.left+l-i;return a+Math.max(c,0)}!function(e){e[e.MARGIN=16]=\"MARGIN\",e[e.BORDER_WIDTH=1]=\"BORDER_WIDTH\"}(Fi||(Fi={})),function(e){e[e.TARGET=-1]=\"TARGET\"}(Li||(Li={})),function(e){e[e.SCREEN=-1]=\"SCREEN\"}(Hi||(Hi={})),function(e){e[e.HIDDEN=0]=\"HIDDEN\",e[e.SHOWING=1]=\"SHOWING\",e[e.SHOWN=2]=\"SHOWN\"}(Ui||(Ui={}));var Qi={top:0,left:0};function Xi(e){var n,t=e.popup,r=e.anchor,o=e.container,i=e.directions,a=e.autoPositioning,l=e.sidePadding,c=e.top,s=e.left,u=e.offset,p=e.maxHeight,f=e.minWidth,d=e.autoCorrectTopOverflow,g=void 0===d||d,h={top:0,left:0},A=null,b=null!==o?Ge(o):Qi,v=null!==o?o:document.body,m=Ge(Ue(r)?r:v),y=function(e){return null!==e?{top:e.scrollTop,left:e.scrollLeft}:{top:document.documentElement&&document.documentElement.scrollTop||document.body.scrollTop,left:document.documentElement&&document.documentElement.scrollLeft||document.body.scrollLeft}}(o),E=m.left+y.left+s-b.left,C=m.top+y.top+c-b.top;if(t){var w=qi(qi({},e),{},{popup:t}),x=function(e,n,t,r,o){var i,a=e.offsetWidth,l=e.offsetHeight,c=r+n.height,s=t+n.width,u=t-a,p=r-l,f=s-a,d=t+n.width/2-a/2,g=r+n.height/2-l/2,h=c-l;return Vi(Vi(Vi(Vi(Vi(Vi(Vi(Vi(Vi(Vi(i={},Ni.BOTTOM_RIGHT,{left:t,top:c+o}),Ni.BOTTOM_LEFT,{left:f,top:c+o}),Ni.BOTTOM_CENTER,{left:d,top:c+o}),Ni.TOP_RIGHT,{left:t,top:p-o}),Ni.TOP_LEFT,{left:f,top:p-o}),Ni.TOP_CENTER,{left:d,top:p-o}),Ni.LEFT_BOTTOM,{left:u-o,top:r}),Ni.LEFT_TOP,{left:u-o,top:h}),Ni.LEFT_CENTER,{left:u-o,top:g}),Ni.RIGHT_BOTTOM,{left:s+o,top:r}),Vi(Vi(i,Ni.RIGHT_TOP,{left:s+o,top:h}),Ni.RIGHT_CENTER,{left:s+o,top:g})}(t,m,E,C,u);if(a&&1!==i.length){var S=i.concat(i[0]).filter((function(e){return x[e]})).map((function(e){return{styles:x[e],direction:e}})).sort((function(e,n){var t=e.styles,r=n.styles;return $i(t,y,w)+Ki(t,y,w)-($i(r,y,w)+Ki(r,y,w))}));h=S[0].styles,A=S[0].direction}else h=x[i[0]],A=i[0];[\"left\",\"top\"].forEach((function(e){h[e]<0&&(h[e]=0)}))}(p===Hi.SCREEN||\"screen\"===p?h.maxHeight=window.innerHeight+y.top-h.top-Fi.MARGIN:p&&(h.maxHeight=p),g)&&(h=function(e){var n=e.sidePadding,t=e.styles,r=e.anchorRect,o=e.maxHeight,i=e.popupScrollHeight,a=e.direction,l=e.scroll,c=Ni.TOP_LEFT,s=Ni.TOP_RIGHT,u=Ni.TOP_CENTER,p=Ni.RIGHT_TOP,f=Ni.LEFT_TOP;if(null==a||![c,s,u,p,f].includes(a))return t;var d=null!=a&&[c,u,s].includes(a)?r.top:r.bottom;return d-(o&&\"number\"==typeof o?Math.min(i,o):i)<=n&&(t.top=n+l.top,t.maxHeight=d-n+1),t}({sidePadding:l,styles:h,anchorRect:m,maxHeight:p,direction:A,popupScrollHeight:null!==(n=null==t?void 0:t.scrollHeight)&&void 0!==n?n:0,scroll:y}));return f===Li.TARGET||\"target\"===f?h.minWidth=m.width:f&&(h.minWidth=m.width<f?f:m.width),{styles:h,direction:A}}var Zi=t(1564),Ji=t.n(Zi),ea=[\"id\",\"children\"];function na(){return na=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},na.apply(null,arguments)}var ta=(0,n.createContext)(void 0),ra=(0,n.forwardRef)((function(e,t){var r=e.id,o=e.children,i=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,ea),a=n.createElement(\"div\",na({},i,{\"data-portaltarget\":r,ref:t}),\"function\"!=typeof o&&o);return n.createElement(ta.Provider,{value:r},\"function\"==typeof o?o(a):a)}));function oa(e){return oa=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},oa(e)}function ia(e,n){return function(e){if(Array.isArray(e))return e}(e)||function(e,n){var t=null==e?null:\"undefined\"!=typeof Symbol&&e[Symbol.iterator]||e[\"@@iterator\"];if(null!=t){var r,o,i,a,l=[],c=!0,s=!1;try{if(i=(t=t.call(e)).next,0===n){if(Object(t)!==t)return;c=!1}else for(;!(c=(r=i.call(t)).done)&&(l.push(r.value),l.length!==n);c=!0);}catch(e){s=!0,o=e}finally{try{if(!c&&null!=t.return&&(a=t.return(),Object(a)!==a))return}finally{if(s)throw o}}return l}}(e,n)||function(e,n){if(e){if(\"string\"==typeof e)return aa(e,n);var t={}.toString.call(e).slice(8,-1);return\"Object\"===t&&e.constructor&&(t=e.constructor.name),\"Map\"===t||\"Set\"===t?Array.from(e):\"Arguments\"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?aa(e,n):void 0}}(e,n)||function(){throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}()}function aa(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=Array(n);t<n;t++)r[t]=e[t];return r}function la(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function ca(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?la(Object(t),!0).forEach((function(n){ga(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):la(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function sa(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,ha(r.key),r)}}function ua(e,n,t){return n=fa(n),function(e,n){if(n&&(\"object\"==oa(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,pa()?Reflect.construct(n,t||[],fa(e).constructor):n.apply(e,t))}function pa(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(pa=function(){return!!e})()}function fa(e){return fa=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},fa(e)}function da(e,n){return da=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},da(e,n)}function ga(e,n,t){return(n=ha(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function ha(e){var n=function(e,n){if(\"object\"!=oa(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=oa(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==oa(n)?n:n+\"\"}ra.propTypes={id:i().string.isRequired,children:i().oneOfType([i().node,i().func])};var Aa=function(e){return e.stopPropagation()},ba=function(e){return\"string\"==typeof e?document.querySelector(\"[data-portaltarget=\".concat(e,\"]\")):e},va=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return ga(e=ua(this,t,[].concat(r)),\"state\",{display:Ui.SHOWING}),ga(e,\"popup\",void 0),ga(e,\"node\",void 0),ga(e,\"parent\",void 0),ga(e,\"container\",void 0),ga(e,\"ringPopupTarget\",void 0),ga(e,\"listeners\",new $e),ga(e,\"redrawScheduler\",Re(!0)),ga(e,\"uid\",De(\"popup-\")),ga(e,\"calculateDisplay\",(function(n){return ca(ca({},n),{},{display:e.props.hidden?Ui.SHOWING:Ui.SHOWN})})),ga(e,\"portalRef\",(function(n){e.node=n,e.parent=n&&n.parentElement,n&&e.getContainer()&&e._redraw()})),ga(e,\"popupRef\",(function(n){e.popup=n,e._redraw()})),ga(e,\"containerRef\",(function(n){e.container=n})),ga(e,\"_updateDirection\",(function(n){e.state.direction!==n&&(e.setState({direction:n}),e.props.onDirectionChange&&e.props.onDirectionChange(n))})),ga(e,\"_updatePosition\",(function(){var n=e.popup;if(n){if(n.style.position=\"absolute\",e.isVisible()){var t=e.position(),r=t.styles,o=t.direction;Object.entries(r).forEach((function(e){var t=ia(e,2),r=t[0],o=t[1],i=r;n.style[i]=\"number\"==typeof o?\"\".concat(o,\"px\"):o.toString()})),null!=o&&e._updateDirection(o)}e.setState(e.calculateDisplay)}})),ga(e,\"_redraw\",(function(){e.isVisible()&&e.redrawScheduler(e._updatePosition)})),ga(e,\"_listenersEnabled\",void 0),ga(e,\"_onEscPress\",(function(n){e.props.onEscPress(n),e._onCloseAttempt(n,!0)})),ga(e,\"_onDocumentClick\",(function(n){var t;e.container&&n.target instanceof Node&&e.container.contains(n.target)||!e._listenersEnabled||e.props.dontCloseOnAnchorClick&&n.target instanceof Node&&null!==(t=e._getAnchor())&&void 0!==t&&t.contains(n.target)||(e.props.onOutsideClick(n),e._onCloseAttempt(n,!1))})),ga(e,\"shortcutsScope\",e.uid),ga(e,\"shortcutsMap\",{esc:e._onEscPress}),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&da(e,n)}(t,e),function(e,n,t){return n&&sa(e.prototype,n),t&&sa(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"componentDidMount\",value:function(){this.props.client||this.setState({client:!0}),this.props.hidden||this._setListenersEnabled(!0)}},{key:\"componentDidUpdate\",value:function(e,n){var t=this.props.hidden;this.props!==e&&(e.hidden!==t&&this._setListenersEnabled(!t),this._redraw()),!this.props.onShow||t||this.state.display!==Ui.SHOWN||!e.hidden&&n.display===Ui.SHOWN||this.props.onShow()}},{key:\"componentWillUnmount\",value:function(){this._setListenersEnabled(!1)}},{key:\"shouldUseShortcuts\",value:function(){var e=this.props,n=e.shortcuts,t=e.hidden;return n&&!t}},{key:\"getContainer\",value:function(){var e=this.props.target||this.ringPopupTarget;return e&&ba(e)}},{key:\"position\",value:function(){var e=this.props,n=e.directions,t=e.autoPositioning,r=e.autoCorrectTopOverflow,o=e.sidePadding,i=e.top,a=e.left,l=e.offset,c=e.maxHeight,s=e.minWidth,u=this.getContainer();return Xi({popup:this.popup,container:u&&\"static\"!==He(u).position?u:null,anchor:this._getAnchor(),directions:n,autoPositioning:t,autoCorrectTopOverflow:r,sidePadding:o,top:i,left:a,offset:l,maxHeight:c,minWidth:s})}},{key:\"_getAnchor\",value:function(){return this.props.anchorElement||this.parent}},{key:\"_setListenersEnabled\",value:function(e){var n=this;!e||this._listenersEnabled?!e&&this._listenersEnabled&&(this.listeners.removeAll(),this._listenersEnabled=!1):setTimeout((function(){n._listenersEnabled=!0,n.listeners.add(window,\"resize\",n._redraw),n.props.autoPositioningOnScroll&&n.listeners.add(window,\"scroll\",n._redraw),n.listeners.add(document,\"pointerdown\",n._onDocumentClick,!0);for(var e=n._getAnchor();e;)n.listeners.add(e,\"scroll\",n._redraw),e=e.parentElement}),0)}},{key:\"isVisible\",value:function(){return!this.props.hidden}},{key:\"_onCloseAttempt\",value:function(e,n){this.props.onCloseAttempt(e,n)}},{key:\"getInternalContent\",value:function(){var e=this.props,t=e.trapFocus,r=e.autoFocusFirst,o=e.children;return t?n.createElement(Mi,{autoFocusFirst:r,focusBackOnExit:!0},o):o}},{key:\"render\",value:function(){var e=this,t=this.props,o=t.className,i=t.style,a=t.hidden,c=t.attached,s=t.keepMounted,u=t.client,p=t.onMouseDown,f=t.onMouseUp,d=t.onMouseOver,g=t.onMouseOut,h=t.onContextMenu,A=t[\"data-test\"],b=this.state.display===Ui.SHOWING,v=l()(o,Ji().popup,ga(ga(ga({},Ji().attached,c),Ji().hidden,a),Ji().showing,b)),m=(this.state.direction||\"\").toLowerCase().replace(/[_]/g,\"-\");return n.createElement(ta.Consumer,null,(function(t){return e.ringPopupTarget=t,n.createElement(\"span\",{onClick:Aa,role:\"presentation\",ref:e.portalRef},e.shouldUseShortcuts()&&n.createElement(hn,{map:e.shortcutsMap,scope:e.shortcutsScope}),(u||e.state.client)&&(s||!a)&&(0,r.createPortal)(n.createElement(ra,{id:e.uid,ref:e.containerRef,onMouseOver:d,onFocus:d,onMouseOut:g,onBlur:g,onContextMenu:h},n.createElement(\"div\",{\"data-test\":Ie(\"ring-popup\",A),\"data-test-shown\":!a&&!b,\"data-test-direction\":m,ref:e.popupRef,className:v,style:i,onMouseDown:p,onMouseUp:f,role:\"presentation\"},e.getInternalContent())),e.getContainer()||document.body))}))}}])}(n.PureComponent);ga(va,\"defaultProps\",{shortcuts:!0,hidden:!1,onOutsideClick:function(){},onEscPress:function(){},onCloseAttempt:function(){},dontCloseOnAnchorClick:!1,keepMounted:!1,directions:Wi,autoPositioning:!0,autoPositioningOnScroll:!0,autoCorrectTopOverflow:!0,left:0,top:0,offset:0,sidePadding:8,attached:!1,trapFocus:!1,autoFocusFirst:!1,legacy:!1}),ga(va,\"PopupProps\",{Directions:Ni,Dimension:Fi,MinWidth:Li,MaxHeight:Hi}),va.propTypes={anchorElement:i().instanceOf(Node),target:i().oneOfType([i().string,i().instanceOf(Element)]),className:i().string,style:i().object,hidden:i().bool.isRequired,onOutsideClick:i().func,onEscPress:i().func,onCloseAttempt:i().func,children:i().node.isRequired,dontCloseOnAnchorClick:i().bool,shortcuts:i().bool,keepMounted:i().bool,\"data-test\":i().string,client:i().bool,directions:i().arrayOf(i().string),autoPositioning:i().bool,autoCorrectTopOverflow:i().bool,left:i().number,top:i().number,maxHeight:i().oneOfType([i().string,i().number]),minWidth:i().number,sidePadding:i().number,attached:i().bool,onMouseDown:i().func,onMouseUp:i().func,onMouseOver:i().func,onMouseOut:i().func,onContextMenu:i().func,onDirectionChange:i().func,onShow:i().func,trapFocus:i().bool,autoFocusFirst:i().bool};const ma=JSON.parse('{\"login\":\"Log in\",\"logout\":\"Log out\",\"loginTo\":\"Log in to {{serviceName}}\",\"ok\":\"OK\",\"cancel\":\"Cancel\",\"tryAgainLabel\":\"Try again\",\"postpone\":\"Postpone\",\"youHaveLoggedInAs\":\"You have logged in as another user: {{userName}}\",\"applyChange\":\"Apply change\",\"backendIsNotAvailable\":\"Connection lost\",\"checkAgain\":\"try again\",\"nothingHappensLink\":\"Click here if nothing happens\",\"errorMessage\":\"There may be a problem with your network connection. Make sure that you are online and\",\"applyChangedUser\":\"Apply changed user\",\"profile\":\"Profile\",\"switchUser\":\"Switch user\",\"addFirstDate\":\"Add first date\",\"addSecondDate\":\"Add second date\",\"addTime\":\"Add time\",\"selectName\":\"Select {{name}}\",\"setDate\":\"Set a date\",\"setDateTime\":\"Set date and time\",\"setPeriod\":\"Set a period\",\"clear\":\"Clear input\",\"gotIt\":\"Got it\",\"dismiss\":\"Dismiss\",\"perPage\":\"per page\",\"firstPage\":\"First page\",\"lastPage\":\"Last page\",\"nextPage\":\"Next page\",\"previousPage\":\"Previous\",\"searchTitle\":\"Search\",\"clearTitle\":\"Clear search input\",\"userAgreement\":\"User Agreement\",\"accept\":\"Accept\",\"decline\":\"Decline\",\"close\":\"Close\",\"scrollToAccept\":\"View the entire agreement to continue\",\"remindLater\":\"Remind me later\",\"filterItems\":\"Filter items\",\"selectOption\":\"Select an option\",\"progress\":\"Progress\",\"loading\":\"Loading...\",\"noOptionsFound\":\"No options found\",\"banned\":\"banned\",\"online\":\"online\",\"offline\":\"offline\",\"copyToClipboard\":\"Copy email to clipboard\",\"copiedToClipboard\":\"Email was copied to clipboard\",\"copingToClipboardError\":\"Failed to copy to clipboard\",\"unverified\":\"Unverified\"}');var ya=ma,Ea=new Set;var Ca,wa=n.createContext({messages:ya,translate:function(e){var n;return e in ya||function(e){Ea.has(e)||(Ea.add(e),console.warn('Missing localisation for key \"'.concat(e,'\"')))}(e),null!==(n=ya[e])&&void 0!==n?n:ma[e]}}),xa=t(3912),Sa=t.n(xa),_a=[\"children\",\"type\",\"disabled\"];function ka(e){return ka=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},ka(e)}function Oa(){return Oa=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},Oa.apply(null,arguments)}function Ba(e,n,t){return(n=function(e){var n=function(e,n){if(\"object\"!=ka(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=ka(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==ka(n)?n:n+\"\"}(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}!function(e){e.SECONDARY=\"secondary\",e.FORM=\"form\"}(Ca||(Ca={}));var Pa=Ba(Ba({},Ca.SECONDARY,Sa().secondaryLabel),Ca.FORM,Sa().formLabel),Ta=function(e){var t=e.children,r=e.type,o=void 0===r?Ca.SECONDARY:r,i=e.disabled,a=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,_a);return n.createElement(\"label\",Oa({className:l()(Sa().label,Pa[o],Ba({},Sa().disabledLabel,i))},a),t)};Ta.propTypes={label:i().node,labelStyle:i().string,disabled:i().bool};const Ia=Ta;var ja,za=t(5924),Da=t.n(za),Ra=[\"size\",\"active\",\"multiline\",\"borderless\",\"label\",\"labelType\",\"error\",\"className\",\"inputClassName\",\"children\",\"value\",\"onClear\",\"disabled\",\"inputRef\",\"onChange\",\"enableShortcuts\",\"id\",\"placeholder\",\"icon\",\"translations\",\"height\",\"afterInput\"];function Ma(e){return Ma=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Ma(e)}function Na(){return Na=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},Na.apply(null,arguments)}function Fa(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Ya(r.key),r)}}function La(e,n,t){return n=Ua(n),function(e,n){if(n&&(\"object\"==Ma(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Ha()?Reflect.construct(n,t||[],Ua(e).constructor):n.apply(e,t))}function Ha(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Ha=function(){return!!e})()}function Ua(e){return Ua=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},Ua(e)}function Wa(e,n){return Wa=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},Wa(e,n)}function Ga(e,n,t){return(n=Ya(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function Ya(e){var n=function(e,n){if(\"object\"!=Ma(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Ma(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Ma(n)?n:n+\"\"}function qa(){}!function(e){e.AUTO=\"Auto\",e.S=\"S\",e.M=\"M\",e.L=\"L\",e.FULL=\"FULL\"}(ja||(ja={}));var Va=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return Ga(e=La(this,t,[].concat(r)),\"state\",{empty:!0}),Ga(e,\"frame\",void 0),Ga(e,\"input\",void 0),Ga(e,\"id\",De(\"ring-input-\")),Ga(e,\"inputRef\",(function(n){e.input=n})),Ga(e,\"clear\",(function(n){e.props.onClear&&e.props.onClear(n)})),Ga(e,\"handleInputChange\",(function(n){var t,r;e.props.multiline||(null===(t=(r=e.props).onChange)||void 0===t||t.call(r,n),e.checkValue())})),Ga(e,\"handleTextareaChange\",(function(n){var t,r;e.props.multiline&&(null===(t=(r=e.props).onChange)||void 0===t||t.call(r,n),e.checkValue())})),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&Wa(e,n)}(t,e),function(e,n,t){return n&&Fa(e.prototype,n),t&&Fa(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"componentDidMount\",value:function(){var e=this;this.frame=requestAnimationFrame((function(){return e.adapt()}))}},{key:\"componentDidUpdate\",value:function(){this.adapt()}},{key:\"componentWillUnmount\",value:function(){null!=this.frame&&cancelAnimationFrame(this.frame)}},{key:\"getId\",value:function(){return this.props.id||this.id}},{key:\"checkValue\",value:function(){var e;this.setState({empty:!(null!==(e=this.input)&&void 0!==e&&e.value)}),this.props.multiline&&null!=this.input&&this.input.scrollHeight>=this.input.clientHeight&&this.stretch(this.input)}},{key:\"stretch\",value:function(e){e&&e.style&&(e.style.height=\"0\",e.style.height=\"\".concat(e.scrollHeight+2,\"px\"))}},{key:\"adapt\",value:function(){this.checkValue()}},{key:\"render\",value:function(){var e=this,t=this.props,r=t.size,o=t.active,i=t.multiline,a=t.borderless,c=t.label,s=t.labelType,u=t.error,p=t.className,f=t.inputClassName,d=t.children,g=t.value,h=t.onClear,A=t.disabled,b=t.inputRef,v=(t.onChange,t.enableShortcuts),m=(t.id,t.placeholder),y=t.icon,E=t.translations,C=t.height,w=void 0===C?this.context:C,x=t.afterInput,S=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(t,Ra),_=this.state.empty,k=!!h,O=l()(p,Da().outerContainer,[Da()[\"size\".concat(r)]],[Da()[\"height\".concat(w)]],Ga(Ga(Ga(Ga(Ga(Ga(Ga({\"ring-js-shortcuts\":!0===v},Da().active,o),Da().error,null!=u),Da().empty,_),Da().noLabel,!this.props.label),Da().withIcon,null!=y),Da().clearable,k),Da().borderless,a)),B=l()(Da().input,f),P=null!=g?g:d,T={ref:fr(this.inputRef,b),className:B,value:P,disabled:A,id:this.getId(),placeholder:m,\"aria-label\":\"string\"==typeof c&&c?c:m,\"data-enabled-shortcuts\":Array.isArray(v)?v.join(\",\"):null};return n.createElement(wa.Consumer,null,(function(t){var r,o=t.translate;return n.createElement(\"div\",{className:O,\"data-test\":\"ring-input\"},c&&n.createElement(Ta,{htmlFor:e.getId(),disabled:A,type:s},c),n.createElement(\"div\",{className:Da().container},y&&n.createElement(ur,{glyph:y,className:Da().icon}),i?n.createElement(\"textarea\",Na({onChange:e.handleTextareaChange,rows:1},T,S)):n.createElement(\"input\",Na({onChange:e.handleInputChange},T,S)),k&&!A&&n.createElement(Ai,{title:null!==(r=null==E?void 0:E.clear)&&void 0!==r?r:o(\"clear\"),\"data-test\":\"ring-input-clear\",className:Da().clear,icon:Vo(),onClick:e.clear}),x),u&&n.createElement(\"div\",{className:Da().errorText},u))}))}}])}(n.PureComponent);Ga(Va,\"defaultProps\",{size:ja.M,onChange:qa,inputRef:qa,enableShortcuts:[\"esc\"]}),Ga(Va,\"contextType\",Zo),Va.propTypes={value:i().string,className:i().string,inputClassName:i().string,size:i().oneOf(Object.values(ja)).isRequired,label:i().node,active:i().bool,error:i().string,multiline:i().bool,onChange:i().func,onClear:i().func,inputRef:i().oneOfType([i().func,pr(i().instanceOf(HTMLInputElement)),pr(i().instanceOf(HTMLTextAreaElement))]),children:i().string,enableShortcuts:i().oneOfType([i().bool,i().arrayOf(i().string.isRequired)]),disabled:i().bool,id:i().string,placeholder:i().string,translations:i().object,icon:i().oneOfType([i().string,i().elementType])};const $a=Va;var Ka=r.render;function Qa(e){return\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Qa(e)}function Xa(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,tl(r.key),r)}}function Za(e,n,t){return el(n),function(e,n){if(n&&(\"object\"==Qa(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Ja()?Reflect.construct(n,t||[],el(e).constructor):n.apply(e,t))}function Ja(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return function(){return!!e}()}function el(e){return Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},el(e)}function nl(e,n){return Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},nl(e,n)}function tl(e){var n=function(e,n){if(\"object\"!=Qa(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Qa(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Qa(n)?n:n+\"\"}function rl(e,n){var t=\"undefined\"!=typeof Symbol&&e[Symbol.iterator]||e[\"@@iterator\"];if(!t){if(Array.isArray(e)||(t=function(e,n){if(e){if(\"string\"==typeof e)return ol(e,n);var t={}.toString.call(e).slice(8,-1);return\"Object\"===t&&e.constructor&&(t=e.constructor.name),\"Map\"===t||\"Set\"===t?Array.from(e):\"Arguments\"===t||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t)?ol(e,n):void 0}}(e))||n&&e&&\"number\"==typeof e.length){t&&(e=t);var r=0,o=function(){};return{s:o,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:o}}throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\")}var i,a=!0,l=!1;return{s:function(){t=t.call(e)},n:function(){var e=t.next();return a=e.done,e},e:function(e){l=!0,i=e},f:function(){try{a||null==t.return||t.return()}finally{if(l)throw i}}}}function ol(e,n){(null==n||n>e.length)&&(n=e.length);for(var t=0,r=Array(n);t<n;t++)r[t]=e[t];return r}function il(e,n){var t=arguments.length>2&&void 0!==arguments[2]&&arguments[2],r=t?e:e.toLowerCase(),o=t?n:n.toLowerCase(),i=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],r=n;if(t.length>0){r=\"\";var o,i={to:0},a=rl(t);try{for(a.s();!(o=a.n()).done;){var l=o.value;r+=\"\".concat(n.slice(i.to,l.from),\"**\").concat(n.slice(l.from,l.to),\"**\"),i=l}}catch(e){a.e(e)}finally{a.f()}r+=n.slice(i.to)}return{matched:e,matches:t,highlight:r}},a=o.length,l=r.length;if(l>a)return i(!1);if(l===a){var c=r===o;return i(c,c?[{from:0,to:n.length}]:[])}var s=!1,u=0,p=[],f=0;e:for(var d=0;d<l;d++){for(var g=r[d];u<a;){var h=o[u],A=h===g,b=A&&/\\S/.test(h);if(b&&!s?f=u:!b&&s&&p.push({from:f,to:u}),u++,s=b,A)continue e}return i(!1)}return s&&p.push({from:f,to:u}),i(!0,p)}var al=t(7004),ll=t.n(al),cl=t(8130),sl=t.n(cl),ul=[\"className\",\"data-test\",\"children\"];function pl(e){return pl=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},pl(e)}function fl(){return fl=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},fl.apply(null,arguments)}function dl(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,vl(r.key),r)}}function gl(e,n,t){return n=Al(n),function(e,n){if(n&&(\"object\"==pl(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,hl()?Reflect.construct(n,t||[],Al(e).constructor):n.apply(e,t))}function hl(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(hl=function(){return!!e})()}function Al(e){return Al=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},Al(e)}function bl(e,n){return bl=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},bl(e,n)}function vl(e){var n=function(e,n){if(\"object\"!=pl(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=pl(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==pl(n)?n:n+\"\"}var ml=function(e){function t(){return function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t),gl(this,t,arguments)}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&bl(e,n)}(t,e),function(e,n,t){return n&&dl(e.prototype,n),t&&dl(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"render\",value:function(){var e=this.props,t=e.className,r=e[\"data-test\"],o=e.children,i=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,ul),a=l()(sl().loader,t),c=n.createElement(\"div\",fl({},i,{\"data-test\":Ie(\"ring-loader-inline\",r),className:a}));return o?n.createElement(n.Fragment,null,c,n.createElement(\"span\",{className:sl().children},o)):c}}])}(n.PureComponent);!function(e,n,t){(n=vl(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t}(ml,\"propTypes\",{className:i().string,\"data-test\":i().string,children:i().node});const yl=ml;var El=[\"rgShortcutsOptions\",\"rgShortcutsMap\"];function Cl(e){return Cl=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Cl(e)}function wl(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Bl(r.key),r)}}function xl(e,n,t){return n=_l(n),function(e,n){if(n&&(\"object\"==Cl(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Sl()?Reflect.construct(n,t||[],_l(e).constructor):n.apply(e,t))}function Sl(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Sl=function(){return!!e})()}function _l(e){return _l=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},_l(e)}function kl(e,n){return kl=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},kl(e,n)}function Ol(e,n,t){return(n=Bl(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function Bl(e){var n=function(e,n){if(\"object\"!=Cl(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Cl(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Cl(n)?n:n+\"\"}var Pl=t(4512),Tl=t.n(Pl);function Il(){return Il=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},Il.apply(null,arguments)}function jl(e){return jl=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},jl(e)}function zl(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Ll(r.key),r)}}function Dl(e,n,t){return n=Ml(n),function(e,n){if(n&&(\"object\"==jl(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Rl()?Reflect.construct(n,t||[],Ml(e).constructor):n.apply(e,t))}function Rl(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Rl=function(){return!!e})()}function Ml(e){return Ml=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},Ml(e)}function Nl(e,n){return Nl=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},Nl(e,n)}function Fl(e,n,t){return(n=Ll(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function Ll(e){var n=function(e,n){if(\"object\"!=jl(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=jl(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==jl(n)?n:n+\"\"}var Hl=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return Fl(e=Dl(this,t,[].concat(r)),\"state\",{focused:!1}),Fl(e,\"onDocumentClick\",(function(n){e.tagNode&&e.setState({focused:e.tagNode===n.target})})),Fl(e,\"tagNode\",void 0),Fl(e,\"tagRef\",(function(n){e.tagNode=n})),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&Nl(e,n)}(t,e),function(e,n,t){return n&&zl(e.prototype,n),t&&zl(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"componentDidUpdate\",value:function(e){var n;(this.props.focused!==e.focused&&this.setState({focused:this.props.focused}),this.state.focused)&&(null===(n=this.tagNode)||void 0===n||n.focus());this.setDocumentClickListener(this.state.focused)}},{key:\"componentWillUnmount\",value:function(){this.setDocumentClickListener(!1),this.setState({focused:!1})}},{key:\"setDocumentClickListener\",value:function(e){e?document.addEventListener(\"click\",this.onDocumentClick):document.removeEventListener(\"click\",this.onDocumentClick)}},{key:\"renderCustomIcon\",value:function(){return this.props.rgTagIcon?n.createElement(ur,{className:Tl().icon,title:this.props.rgTagTitle,glyph:this.props.rgTagIcon}):null}},{key:\"_renderImageElement\",value:function(e){var t=l()(Fl(Fl({},Tl().customIcon,this.props.icon),Tl().avatarIcon,e));return n.createElement(\"img\",{alt:e?\"Avatar\":\"Icon\",className:t,src:e||this.props.icon})}},{key:\"renderImage\",value:function(){return this.props.icon&&!this.props.avatar?this._renderImageElement():null}},{key:\"renderAvatar\",value:function(){return this.props.avatar?n.createElement(\"span\",{className:Tl().avatarContainer},this._renderImageElement(this.props.avatar)):null}},{key:\"renderRemoveIcon\",value:function(){return this.props.readOnly?null:n.createElement(Ai,{title:\"Remove\",icon:Vo(),\"data-test\":\"ring-tag-remove\",className:Tl().remove,iconClassName:Tl().removeIcon,onClick:this.props.onRemove,style:{\"--ring-icon-secondary-color\":this.props.textColor},height:Wo.M})}},{key:\"render\",value:function(){var e=l()(\"ring-js-shortcuts\",Tl().tag,Fl(Fl(Fl(Fl({},Tl().focused,this.state.focused),Tl().disabled,this.props.disabled),Tl().tagAngled,this.props.angled),Tl().withRemove,!this.props.readOnly),this.props.className),t=this.props,r=t.backgroundColor,o=t.textColor,i=t.render;return n.createElement(\"span\",{className:Tl().container},i({\"data-test\":\"ring-tag\",className:e,ref:this.tagRef,onClick:this.props.onClick,style:{backgroundColor:r,color:o},disabled:this.props.disabled,children:n.createElement(n.Fragment,null,this.renderAvatar(),this.renderCustomIcon(),this.renderImage(),n.createElement(\"span\",{className:Tl().content},this.props.children))}),this.renderRemoveIcon())}}])}(n.PureComponent);Fl(Hl,\"propTypes\",{onRemove:i().func,onClick:i().func,rgTagIcon:i().oneOfType([i().string,i().elementType]),icon:i().string,avatar:i().string,rgTagTitle:i().string,readOnly:i().bool,disabled:i().bool,focused:i().bool,angled:i().bool,backgroundColor:i().string,textColor:i().string,children:i().node,className:i().string,render:i().func}),Fl(Hl,\"defaultProps\",{onRemove:function(){},onClick:function(){},readOnly:!1,disabled:!1,focused:!1,render:function(e){return n.createElement(\"button\",Il({type:\"button\"},e))}});var Ul=[\"children\",\"className\",\"customTagComponent\",\"canNotBeEmpty\",\"handleClick\",\"tagClassName\",\"handleRemove\",\"tags\",\"activeIndex\"];function Wl(e){return Wl=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Wl(e)}function Gl(){return Gl=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},Gl.apply(null,arguments)}function Yl(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Xl(r.key),r)}}function ql(e,n,t){return n=$l(n),function(e,n){if(n&&(\"object\"==Wl(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Vl()?Reflect.construct(n,t||[],$l(e).constructor):n.apply(e,t))}function Vl(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Vl=function(){return!!e})()}function $l(e){return $l=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},$l(e)}function Kl(e,n){return Kl=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},Kl(e,n)}function Ql(e,n,t){return(n=Xl(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function Xl(e){var n=function(e,n){if(\"object\"!=Wl(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Wl(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Wl(n)?n:n+\"\"}function Zl(){}var Jl=function(e){function t(){return function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t),ql(this,t,arguments)}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&Kl(e,n)}(t,e),function(e,n,t){return n&&Yl(e.prototype,n),t&&Yl(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"renderTag\",value:function(e,t){var r=this.props.customTagComponent||Hl,o=this.props.disabled||e.readOnly||this.props.canNotBeEmpty&&1===this.props.tags.length,i=this.props.tagClassName;return n.createElement(r,Gl({},e,{readOnly:o,disabled:this.props.disabled||e.disabled,focused:t,onClick:this.props.handleClick(e),onRemove:this.props.handleRemove(e),className:i}),e.label)}},{key:\"render\",value:function(){var e=this,t=this.props,r=t.children,o=t.className,i=(t.customTagComponent,t.canNotBeEmpty,t.handleClick,t.tagClassName,t.handleRemove,t.tags,t.activeIndex,function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(t,Ul)),a=l()(\"ring-js-shortcuts\",o),c=(this.props.tags||[]).map((function(n,t){return e.renderTag(n,e.props.activeIndex===t)}));return n.createElement(\"div\",Gl({\"data-test\":\"ring-tags-list\",className:a},i),c,r)}}])}(n.Component);function ec(e){return ec=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},ec(e)}function nc(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,rc(r.key),r)}}function tc(e,n,t){return(n=rc(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function rc(e){var n=function(e,n){if(\"object\"!=ec(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=ec(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==ec(n)?n:n+\"\"}Ql(Jl,\"propTypes\",{children:i().node,tags:i().array,customTagComponent:i().elementType,activeIndex:i().number,canNotBeEmpty:i().bool,disabled:i().bool,handleClick:i().func,handleRemove:i().func,className:i().string,tagClassName:i().string}),Ql(Jl,\"defaultProps\",{customTagComponent:null,canNotBeEmpty:!1,disabled:!1,handleClick:Zl,handleRemove:Zl});var oc=function(){function e(n){!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,e),tc(this,\"target\",void 0),this.target=n}return function(e,n,t){return n&&nc(e.prototype,n),t&&nc(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(e,[{key:\"isContentEditable\",value:function(){return\"true\"===this.target.contentEditable}},{key:\"focus\",value:function(){document.activeElement&&document.activeElement===this.target||this.target.focus()}},{key:\"getAbsolutePosition\",value:function(e){for(var n=e,t=0;null!=n&&n!==this.target;){for(;n.previousSibling;){var r,o;t+=null!==(r=null===(o=n.previousSibling.textContent)||void 0===o?void 0:o.length)&&void 0!==r?r:0,n=n.previousSibling}n=n.parentNode}return t}},{key:\"getPosition\",value:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(this.isContentEditable()){e.avoidFocus||this.focus();var n=window.getSelection();if(null==n||!n.rangeCount)return 0;var t=n.getRangeAt(0),r=t.cloneRange();r.selectNodeContents(this.target),r.setEnd(t.endContainer,t.endOffset);var o=t.startContainer;if(this.target===o)return 0===t.startOffset||null==o.textContent?0:o.textContent.length;if(!this.target.contains(o))return-1;if(!o)return\"selectionStart\"in this.target&&this.target.selectionStart||-1;var i=this.getAbsolutePosition(o);return t.startContainer===t.endContainer?t.startOffset===t.endOffset?i+t.startOffset:{startOffset:i+t.startOffset,endOffset:i+t.endOffset,position:r.toString().length}:{startOffset:i+t.startOffset,endOffset:this.getAbsolutePosition(t.endContainer)+t.endOffset,position:r.toString().length}}return\"selectionStart\"in this.target&&this.target.selectionStart||-1}},{key:\"getRelativePosition\",value:function(e,n){var t=0,r=e;if(!r)return{_curNode:this.target,_correctedPosition:n};if(0===n){for(;3!==r.nodeType;)r=r.childNodes[0];return{_curNode:r,_correctedPosition:n}}var o=-1;if(r&&void 0!==r.nodeType)for(;t<n&&3!==r.nodeType&&(o++,null!=r.childNodes[o]);){var i,a,l,c;(t+=null!==(i=null===(a=r.childNodes[o].textContent)||void 0===a?void 0:a.length)&&void 0!==i?i:0)>=n&&(t-=null!==(l=null===(c=(r=r.childNodes[o]).textContent)||void 0===c?void 0:c.length)&&void 0!==l?l:0,o=-1)}return{_curNode:r,_correctedPosition:n-t}}},{key:\"setPosition\",value:function(n){var t,r=this.isContentEditable(),o=this.target&&this.target.childNodes[0];if(void 0!==n)if(\"object\"===ec(n)){var i=new Range,a=this.getRelativePosition(o,n.startOffset);i.setStart(a._curNode,a._correctedPosition);var l=this.getRelativePosition(o,n.endOffset);i.setEnd(l._curNode,l._correctedPosition),t=i}else if(-1===n){var c,s=r?this.target.textContent:e.normalizeNewlines(\"value\"in this.target?this.target.value:void 0);t=null!==(c=null==s?void 0:s.length)&&void 0!==c?c:0}else{var u=this.getRelativePosition(o,n);o=u._curNode,t=u._correctedPosition}if(r){this.focus();try{var p,f,d;if(t instanceof Range)null===(p=window.getSelection())||void 0===p||p.removeAllRanges(),null===(f=window.getSelection())||void 0===f||f.addRange(t);else null===(d=window.getSelection())||void 0===d||d.collapse(o||this.target,t)}catch(e){}}else\"setSelectionRange\"in this.target&&\"number\"==typeof t&&this.target.setSelectionRange(t,t);return t}},{key:\"getOffset\",value:function(){var e,n=0;try{var t,r;null===(r=e=null===(t=window.getSelection())||void 0===t?void 0:t.getRangeAt(0).cloneRange())||void 0===r||r.setStart(e.startContainer,e.startOffset-1)}catch(e){return n}return e&&0!==e.endOffset&&\"\"!==e.toString()&&(n=Ge(e).right-Ge(this.target).left-(e.startContainer instanceof HTMLElement&&e.startContainer.offsetLeft||0)),n}}],[{key:\"normalizeNewlines\",value:function(e){return\"string\"==typeof e?e.replace(this.returnRE,\"\"):e}}])}();tc(oc,\"returnRE\",/\\r/g);var ic=t(6932),ac=t.n(ic),lc=[\"children\",\"className\",\"info\",\"size\"];function cc(e){return cc=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},cc(e)}function sc(){return sc=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},sc.apply(null,arguments)}function uc(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Ac(r.key),r)}}function pc(e,n,t){return n=dc(n),function(e,n){if(n&&(\"object\"==cc(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,fc()?Reflect.construct(n,t||[],dc(e).constructor):n.apply(e,t))}function fc(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(fc=function(){return!!e})()}function dc(e){return dc=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},dc(e)}function gc(e,n){return gc=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},gc(e,n)}function hc(e,n,t){return(n=Ac(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function Ac(e){var n=function(e,n){if(\"object\"!=cc(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=cc(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==cc(n)?n:n+\"\"}var bc={S:\"s\",M:\"m\",L:\"l\"},vc=function(e){function t(){return function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t),pc(this,t,arguments)}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&gc(e,n)}(t,e),function(e,n,t){return n&&uc(e.prototype,n),t&&uc(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"render\",value:function(){var e=this.props,r=e.children,o=e.className,i=e.info,a=e.size,c=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,lc),s=l()(ac().text,o,hc(hc(hc(hc({},ac().info,i),ac().sizeS,a===t.Size.S),ac().sizeM,a===t.Size.M),ac().sizeL,a===t.Size.L));return n.createElement(\"span\",sc({className:s},c),r)}}])}(n.Component);hc(vc,\"propTypes\",{children:i().node,info:i().bool,size:i().oneOf(Object.keys(bc).map((function(e){return bc[e]}))),className:i().string}),hc(vc,\"Size\",bc);var mc=t(5103),yc=t.n(mc),Ec=[\"className\",\"listId\"];function Cc(e){return Cc=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Cc(e)}function wc(){return wc=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},wc.apply(null,arguments)}function xc(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Pc(r.key),r)}}function Sc(e,n,t){return n=kc(n),function(e,n){if(n&&(\"object\"==Cc(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,_c()?Reflect.construct(n,t||[],kc(e).constructor):n.apply(e,t))}function _c(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(_c=function(){return!!e})()}function kc(e){return kc=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},kc(e)}function Oc(e,n){return Oc=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},Oc(e,n)}function Bc(e,n,t){return(n=Pc(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function Pc(e){var n=function(e,n){if(\"object\"!=Cc(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Cc(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Cc(n)?n:n+\"\"}var Tc=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return Bc(e=Sc(this,t,[].concat(r)),\"input\",void 0),Bc(e,\"inputRef\",(function(n){e.input=n,e.props.inputRef(n)})),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&Oc(e,n)}(t,e),function(e,n,t){return n&&xc(e.prototype,n),t&&xc(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"componentWillUnmount\",value:function(){this.blur()}},{key:\"focus\",value:function(){var e=this.input;e&&e!==document.activeElement&&(\"firefox\"===Je.browser.name?e.select():e.focus())}},{key:\"blur\",value:function(){this.input&&this.input===document.activeElement&&this.input.blur()}},{key:\"render\",value:function(){var e=this,t=this.props,r=t.className,o=t.listId,i=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(t,Ec),a=l()(yc().filter,r);return n.createElement(Ho.ValueContext.Consumer,null,(function(t){return n.createElement(wa.Consumer,null,(function(r){var l,c=r.translate;return n.createElement($a,wc({},i,{placeholder:null!==(l=i.placeholder)&&void 0!==l?l:c(\"filterItems\"),\"aria-owns\":o,\"aria-activedescendant\":t,autoComplete:\"off\",autoFocus:!0,borderless:!0,inputRef:e.inputRef,className:a}))}))}))}}])}(n.Component);function Ic(e){return Ic=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Ic(e)}function jc(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Fc(r.key),r)}}function zc(e,n,t){return n=Rc(n),function(e,n){if(n&&(\"object\"==Ic(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Dc()?Reflect.construct(n,t||[],Rc(e).constructor):n.apply(e,t))}function Dc(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Dc=function(){return!!e})()}function Rc(e){return Rc=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},Rc(e)}function Mc(e,n){return Mc=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},Mc(e,n)}function Nc(e,n,t){return(n=Fc(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function Fc(e){var n=function(e,n){if(\"object\"!=Ic(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Ic(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Ic(n)?n:n+\"\"}Bc(Tc,\"defaultProps\",{inputRef:function(){}}),Tc.propTypes={placeholder:i().string,className:i().string,inputRef:i().func,listId:i().string,activeItemId:i().string};function Lc(){}var Hc,Uc,Wc=(Hc=Tc,Uc=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return Ol(e=xl(this,t,[].concat(r)),\"_shortcutsScopeUid\",De(\"rg-shortcuts-\")),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&kl(e,n)}(t,e),function(e,n,t){return n&&wl(e.prototype,n),t&&wl(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"render\",value:function(){var e=this.props,t=e.rgShortcutsOptions,r=e.rgShortcutsMap,o=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,El);return n.createElement(hn,{scope:this._shortcutsScopeUid,map:r,options:t,disabled:t.disabled},n.createElement(Hc,o))}}])}(n.Component),Ol(Uc,\"propTypes\",{rgShortcutsOptions:i().object,rgShortcutsMap:i().object}),Uc),Gc=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var r=arguments.length,o=new Array(r),i=0;i<r;i++)o[i]=arguments[i];return Nc(e=zc(this,t,[].concat(o)),\"state\",{popupFilterShortcutsOptions:{modal:!0,disabled:!0},tagsActiveIndex:null}),Nc(e,\"isClickingPopup\",!1),Nc(e,\"filter\",void 0),Nc(e,\"caret\",void 0),Nc(e,\"onFilterFocus\",(function(){e._togglePopupFilterShortcuts(!1),e.setState({tagsActiveIndex:null})})),Nc(e,\"popupFilterOnBlur\",(function(){null===e.state.tagsActiveIndex&&e._togglePopupFilterShortcuts(!0)})),Nc(e,\"mouseDownHandler\",(function(){e.isClickingPopup=!0})),Nc(e,\"mouseUpHandler\",(function(){e.isClickingPopup=!1})),Nc(e,\"popup\",void 0),Nc(e,\"onListSelect\",(function(n,t,r){var o;e.props.onSelect(n,((o=document.createEvent(\"Event\")).initEvent(\"select\",!0,!1),t&&\"persist\"in t&&t.persist(),o.originalEvent=t,o),r)})),Nc(e,\"tabPress\",(function(n){e.props.onCloseAttempt(n,!0)})),Nc(e,\"onClickHandler\",(function(){var n;return null===(n=e.filter)||void 0===n?void 0:n.focus()})),Nc(e,\"handleRemoveTag\",Me((function(n){return function(t){return e.removeTag(n,t)}}))),Nc(e,\"handleTagClick\",Me((function(n){return function(){Array.isArray(e.props.selected)&&e.setState({tagsActiveIndex:e.props.selected.indexOf(n)})}}))),Nc(e,\"handleListResize\",(function(){e.forceUpdate()})),Nc(e,\"handleSelectAll\",(function(){Array.isArray(e.props.selected)&&e.props.onSelectAll(e.props.data.filter((function(e){return!e.disabled})).length!==e.props.selected.length)})),Nc(e,\"getSelectAll\",(function(){var t,r=e.props.multiple,o=e.props.data.filter((function(e){return!e.disabled}));return Array.isArray(e.props.selected)&&n.createElement(\"div\",{className:yc().selectAll},0===o.length?n.createElement(\"span\",null):n.createElement(Ai,{text:!0,inline:!0,onClick:e.handleSelectAll},o.length!==e.props.selected.length?r.selectAllLabel||\"Select all\":r.deselectAllLabel||\"Deselect all\"),(null===(t=r.renderSelectedItemsDescription)||void 0===t?void 0:t.call(r,e.props.selected,o.length))||n.createElement(vc,{info:!0},\"\".concat(e.props.selected.length,\" selected\")))})),Nc(e,\"_adjustListMaxHeight\",_e((function(n,t,r){if(n)return t;var o=e.props.directions||Wi,i=e.props.anchorElement,a=ba(r)||document.documentElement;return null!=i?Math.min(o.reduce((function(e,n){var t;return Math.max(e,null!==(t=function(e,n,t){var r=t||document.documentElement,o=n.getBoundingClientRect(),i=r.getBoundingClientRect(),a=o.top<0?i.top:Math.max(i.top,0),l=Math.max(o.top-a,0),c=Math.max(i.height,r===document.documentElement?r.clientHeight:0),s=Math.max(c-(l+o.height),0);switch(e){case Ni.TOP_LEFT:case Ni.TOP_CENTER:case Ni.TOP_RIGHT:return l;case Ni.BOTTOM_LEFT:case Ni.BOTTOM_CENTER:case Ni.BOTTOM_RIGHT:return s;case Ni.LEFT_BOTTOM:case Ni.RIGHT_BOTTOM:return o.height+s;case Ni.LEFT_TOP:case Ni.RIGHT_TOP:return o.height+l;case Ni.RIGHT_CENTER:case Ni.LEFT_CENTER:return o.height/2+Math.min(s/2,l/2);default:return null}}(n,i,\"static\"!==He(a).position?a:null))&&void 0!==t?t:0)}),100),t):t}))),Nc(e,\"popupRef\",(function(n){e.popup=n})),Nc(e,\"list\",void 0),Nc(e,\"listRef\",(function(n){e.list=n})),Nc(e,\"filterRef\",(function(n){e.filter=n,e.caret=n&&new oc(n)})),Nc(e,\"shortcutsScope\",De(\"select-popup-\")),Nc(e,\"shortcutsMap\",{tab:e.tabPress}),Nc(e,\"popupFilterShortcutsMap\",{up:function(n){return e.list&&e.list.upHandler(n)},down:function(n){return e.list&&e.list.downHandler(n)},home:function(n){return e.list&&e.list.homeHandler(n)},end:function(n){return e.list&&e.list.endHandler(n)},enter:function(n){return e.list?e.list.enterHandler(n):e.props.onEmptyPopupEnter(n)},esc:function(n){return e.props.onCloseAttempt(n,!0)},tab:function(n){return e.tabPress(n)},backspace:function(n){return e.handleBackspace(n)},del:function(){return e.removeSelectedTag()},left:function(n){return e.handleNavigation(n,!0)},right:function(n){return e.handleNavigation(n)}}),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&Mc(e,n)}(t,e),function(e,n,t){return n&&jc(e.prototype,n),t&&jc(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"componentDidMount\",value:function(){window.document.addEventListener(\"mouseup\",this.mouseUpHandler)}},{key:\"componentWillUnmount\",value:function(){window.document.removeEventListener(\"mouseup\",this.mouseUpHandler)}},{key:\"focusFilter\",value:function(){var e=this;setTimeout((function(){var n;return null===(n=e.filter)||void 0===n?void 0:n.focus()}))}},{key:\"isEventTargetFilter\",value:function(e){return e.target instanceof Element&&e.target.matches(\"input,textarea\")}},{key:\"handleNavigation\",value:function(e,n){if(!(this.isEventTargetFilter(e)&&null!=this.caret&&Number(this.caret.getPosition())>0)&&Array.isArray(this.props.selected)){var t=null;n?t=null===this.state.tagsActiveIndex?this.props.selected.length-1:this.state.tagsActiveIndex-1:null!==this.state.tagsActiveIndex&&(t=this.state.tagsActiveIndex+1),null!==t&&(t>=this.props.selected.length||t<0)&&(t=null,this.focusFilter()),this.setState({tagsActiveIndex:t})}}},{key:\"removeTag\",value:function(e,n){if(Array.isArray(this.props.selected)){var t=e||this.props.selected.slice(0)[this.props.selected.length-1];t&&(this.onListSelect(t,n,{tryKeepOpen:!0}),this.setState({tagsActiveIndex:null}),this.focusFilter())}}},{key:\"removeSelectedTag\",value:function(){return!Array.isArray(this.props.selected)||null==this.state.tagsActiveIndex||(this.removeTag(this.props.selected[this.state.tagsActiveIndex]),!1)}},{key:\"handleBackspace\",value:function(e){return!this.props.tags||(this.isEventTargetFilter(e)?!((e.target instanceof HTMLInputElement||e.target instanceof HTMLTextAreaElement)&&!e.target.value)||(this.removeTag(),!1):(this.removeSelectedTag(),!1))}},{key:\"_togglePopupFilterShortcuts\",value:function(e){this.setState({popupFilterShortcutsOptions:{modal:!0,disabled:e}})}},{key:\"isVisible\",value:function(){return this.popup&&this.popup.isVisible()}},{key:\"getFilter\",value:function(){var e;return this.props.filter||this.props.tags?n.createElement(\"div\",{className:yc().filterWrapper,\"data-test\":\"ring-select-popup-filter\"},!this.props.tags&&n.createElement(ur,{glyph:null!==(e=this.props.filterIcon)&&void 0!==e?e:ll(),className:yc().filterIcon,\"data-test-custom\":\"ring-select-popup-filter-icon\"}),n.createElement(Wc,{rgShortcutsOptions:this.state.popupFilterShortcutsOptions,rgShortcutsMap:this.popupFilterShortcutsMap,value:this.props.filterValue,inputRef:fr(this.filterRef,this.props.filterRef),onBlur:this.popupFilterOnBlur,onFocus:this.onFilterFocus,className:\"ring-js-shortcuts\",inputClassName:l()(Nc({},yc().filterWithTagsInput,this.props.tags)),placeholder:\"object\"===Ic(this.props.filter)?this.props.filter.placeholder:void 0,height:this.props.tags?Wo.S:Wo.L,onChange:this.props.onFilter,onClick:this.onClickHandler,onClear:this.props.tags?void 0:this.props.onClear,\"data-test-custom\":\"ring-select-popup-filter-input\",listId:this.props.listId,enableShortcuts:Object.keys(this.popupFilterShortcutsMap)})):null}},{key:\"getCustomTag\",value:function(e){if(null!==e&&\"boolean\"!=typeof e)return e.customTagComponent}},{key:\"getTags\",value:function(){return Array.isArray(this.props.selected)&&n.createElement(\"div\",null,n.createElement(Jl,{tags:this.props.selected,activeIndex:this.state.tagsActiveIndex,handleRemove:this.handleRemoveTag,handleClick:this.handleTagClick,disabled:this.props.disabled,customTagComponent:this.getCustomTag(this.props.tags)}))}},{key:\"getFilterWithTags\",value:function(){if(this.props.tags){var e=l()([yc().filterWithTags,Nc({},yc().filterWithTagsFocused,!this.state.popupFilterShortcutsOptions.disabled)]);return n.createElement(\"div\",{className:e},this.getTags(),this.getFilter())}return this.getFilter()}},{key:\"getBottomLine\",value:function(){var e=this.props,t=e.loading,r=e.message,o=e.data.length>1;return(t||r)&&n.createElement(\"div\",{className:l()(yc().bottomLine,Nc({},yc().bottomLineOverItem,o))},t&&n.createElement(yl,null),r&&n.createElement(\"div\",{className:yc().message},r))}},{key:\"getList\",value:function(e){if(this.props.data.length){var t=this.props.maxHeight;return this.props.anchorElement&&(t=this._adjustListMaxHeight(this.props.hidden,t,e)),this.props.filter&&(t-=35),this.props.toolbar&&(t-=49),n.createElement(Uo,{id:this.props.listId,maxHeight:t,data:this.props.data,activeIndex:this.props.activeIndex,ref:this.listRef,restoreActiveIndex:!0,activateFirstItem:!0,onSelect:this.onListSelect,onResize:this.handleListResize,onScrollToBottom:this.props.onLoadMore,hidden:this.props.hidden,shortcuts:!this.props.hidden,disableMoveOverflow:this.props.disableMoveOverflow,disableMoveDownOverflow:this.props.loading,disableScrollToActive:this.props.disableScrollToActive,compact:this.props.compact,renderOptimization:this.props.renderOptimization})}return null}},{key:\"render\",value:function(){var e=this,t=this.props,r=t.toolbar,o=t.topbar,i=t.className,a=t.multiple,c=t.hidden,s=t.isInputMode,u=t.anchorElement,p=t.minWidth,f=t.onCloseAttempt,d=t.onOutsideClick,g=t.directions,h=t.top,A=t.left,b=t.style,v=t.dir,m=t.filter,y=l()(yc().popup,i);return n.createElement(ta.Consumer,null,(function(t){var i=e.getFilterWithTags(),l=a&&\"object\"===Ic(a)&&!a.limit&&a.selectAll&&e.getSelectAll(),E=e.getList(e.props.ringPopupTarget||t),C=e.getBottomLine(),w=i||l||E||C||r||o;return n.createElement(va,{trapFocus:!1,ref:e.popupRef,hidden:c||!w,attached:s,className:y,dontCloseOnAnchorClick:!0,anchorElement:u,minWidth:p,onCloseAttempt:f,onOutsideClick:d,directions:g,top:h,left:A,onMouseDown:e.mouseDownHandler,target:e.props.ringPopupTarget,autoCorrectTopOverflow:!1,style:b},n.createElement(\"div\",{dir:v},!c&&m&&n.createElement(hn,{map:e.shortcutsMap,scope:e.shortcutsScope}),o,c?n.createElement(\"div\",null):i,l,E,C,r))}))}}])}(n.PureComponent);Nc(Gc,\"defaultProps\",{data:[],activeIndex:null,toolbar:null,topbar:null,filter:!1,filterIcon:null,filterRef:Lc,multiple:!1,message:null,anchorElement:null,maxHeight:600,minWidth:240,loading:!1,onSelect:Lc,onCloseAttempt:Lc,onOutsideClick:Lc,onFilter:Lc,onClear:Lc,onLoadMore:Lc,selected:[],tags:null,ringPopupTarget:null,onSelectAll:Lc,onEmptyPopupEnter:Lc}),Gc.propTypes={activeIndex:i().number,anchorElement:i().instanceOf(HTMLElement),className:i().string,compact:i().bool,data:i().array,dir:i().oneOf([\"ltr\",\"rtl\"]),directions:i().array,disabled:i().bool,disableMoveOverflow:i().bool,disableScrollToActive:i().bool,filter:i().oneOfType([i().bool,i().shape({value:i().string,placeholder:i().string})]),filterValue:i().string,filterIcon:i().oneOfType([i().string,i().elementType]),filterRef:i().oneOfType([i().func,pr(i().instanceOf(HTMLInputElement))]),hidden:i().bool,isInputMode:i().bool,listId:i().string,maxHeight:i().number,message:i().string,minWidth:i().number,multiple:i().oneOfType([i().bool,i().shape({label:i().string,limit:i().number,selectAll:i().bool})]),left:i().number,loading:i().bool,onClear:i().func,onCloseAttempt:i().func,onOutsideClick:i().func,onEmptyPopupEnter:i().func,onFilter:i().func,onLoadMore:i().func,onSelect:i().func,onSelectAll:i().func,renderOptimization:i().bool,ringPopupTarget:i().string,selected:i().oneOfType([i().object,i().array]),style:i().object,tags:i().object,toolbar:i().node,topbar:i().node,top:i().number};var Yc,qc=t(3006),Vc=t.n(qc);function $c(){return $c=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},$c.apply(null,arguments)}function Kc(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,rs(r.key),r)}}function Qc(e,n,t){return n=Zc(n),function(e,n){if(n&&(\"object\"==os(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,Xc()?Reflect.construct(n,t||[],Zc(e).constructor):n.apply(e,t))}function Xc(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(Xc=function(){return!!e})()}function Zc(e){return Zc=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},Zc(e)}function Jc(e,n){return Jc=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},Jc(e,n)}function es(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function ns(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?es(Object(t),!0).forEach((function(n){ts(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):es(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function ts(e,n,t){return(n=rs(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function rs(e){var n=function(e,n){if(\"object\"!=os(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=os(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==os(n)?n:n+\"\"}function os(e){return os=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},os(e)}function is(){}!function(e){e.BUTTON=\"BUTTON\",e.INPUT=\"INPUT\",e.CUSTOM=\"CUSTOM\",e.INLINE=\"INLINE\",e.INPUT_WITHOUT_CONTROLS=\"INPUT_WITHOUT_CONTROLS\"}(Yc||(Yc={}));var as=Me((function(e){return{paddingRight:5+20*e}})),ls=function(e){return e===Yc.INPUT||e===Yc.INPUT_WITHOUT_CONTROLS};function cs(e){return Uo.isItemType(Uo.ListProps.Type.SEPARATOR,e)||Uo.isItemType(Uo.ListProps.Type.HINT,e)||\"string\"!=typeof e.label?null:e.label.toLowerCase()}function ss(e,n){var t=cs(e);return null==t||n(t)}function us(e){if(\"object\"===os(e)){if(e.fn)return e.fn;if(e.fuzzy)return function(e,n){return ss(e,(function(e){return il(n,e).matched}))}}return function(e,n){return ss(e,(function(e){return e.indexOf(n)>=0}))}}function ps(e){return e.reduce((function(e,n){return e[n.key]=!0,e}),{})}function fs(e,n,t){var r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:e.data,o=t.trim();ls(e.type)&&!e.allowAny&&n.selected&&!Array.isArray(n.selected)&&o===n.selected.label&&(o=\"\");for(var i=o.toLowerCase(),a=[],l=!1,c=us(e.filter),s=function(){var t=ns({},r[u]);if(c(t,i,r)){var s,p;if(l=t.label===o,e.multiple&&(\"object\"!==os(e.multiple)||!e.multiple.removeSelectedItems))t.checkbox=!(null===(p=n.multipleMap)||void 0===p||!p[t.key]);e.multiple&&\"object\"===os(e.multiple)&&e.multiple.limit&&Array.isArray(n.selected)&&(t.disabled=e.multiple.limit===n.selected.length&&!n.selected.find((function(e){return e.key===t.key}))),e.multiple&&\"object\"===os(e.multiple)&&e.multiple.removeSelectedItems&&null!==(s=n.multipleMap)&&void 0!==s&&s[t.key]||a.push(t)}},u=0;u<r.length;u++)s();var p,f,d=null,g=e.add;(g&&o&&!l||g&&g.alwaysVisible)&&((g.regexp&&!g.regexp.test(o)||g.minlength&&o.length<+g.minlength)&&!g.alwaysVisible||(f=g.label?\"function\"==typeof g.label?g.label(o):g.label:o,d={prefix:g.prefix,label:f,delayed:null===(p=g.delayed)||void 0===p||p}));return{filteredData:a,addButton:d}}function ds(e,n){var t=Array.isArray(e)?e[0]:e;if(null==t)return null;for(var r=0;r<n.length;r++){var o=n[r];if(void 0!==o.key&&o.key===t.key)return r}return null}var gs=function(e){var n=e.selectedLabel,t=e.label;return null!=n?n:\"string\"==typeof t?t:\"\"},hs=function(e,n,t){return e&&(r=e,!Array.isArray(r))&&ls(n)?gs(e):t;var r};var As=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return ts(e=Qc(this,t,[].concat(r)),\"state\",{data:[],shownData:[],selected:e.props.multiple?[]:null,selectedIndex:null,filterValue:e.props.filter&&\"object\"===os(e.props.filter)&&e.props.filter.value||\"\",shortcutsEnabled:!1,popupShortcuts:!1,showPopup:e.props.showPopup,prevData:e.props.data,prevSelected:null,prevMultiple:e.props.multiple,multipleMap:{},addButton:null}),ts(e,\"id\",De(\"select-\")),ts(e,\"shortcutsScope\",e.id),ts(e,\"listId\",\"\".concat(e.id,\":list\")),ts(e,\"_focusHandler\",(function(n){e.props.onFocus(n),e.setState({shortcutsEnabled:!0,focused:!0})})),ts(e,\"_blurHandler\",(function(){var n;e.props.onBlur(),e._popup&&e._popup.isVisible()&&!e._popup.isClickingPopup&&window.setTimeout((function(){e.setState({showPopup:!1})})),null!==(n=e._popup)&&void 0!==n&&n.isClickingPopup||e.setState({shortcutsEnabled:!1,focused:!1})})),ts(e,\"node\",void 0),ts(e,\"nodeRef\",(function(n){e.node=n})),ts(e,\"_popup\",null),ts(e,\"onEmptyPopupEnter\",(function(){e.state.addButton&&e.addHandler()})),ts(e,\"focus\",(function(){var n,t=null===(n=e.node)||void 0===n?void 0:n.querySelector(\"[data-test~=ring-select__focus]\"),r=e.props.targetElement||t;null==r||r.focus()})),ts(e,\"_onEnter\",(function(){var n;if(e.state.addButton&&0===e.state.shownData.length&&e.addHandler(),e.props.onDone(),(null===(n=e._popup)||void 0===n||!n.isVisible())&&e.props.allowAny)return!0})),ts(e,\"_onEsc\",(function(n){var t;if(null===(t=e._popup)||void 0===t||!t.isVisible())return!0;if(e.props.multiple||!e.props.getInitial)return!1;var r={key:Math.random(),label:e.props.getInitial()};e.setState({selected:r,filterValue:e.getValueForFilter(r)},(function(){e.props.onChange(r,n),e.props.onReset()}))})),ts(e,\"_inputShortcutHandler\",(function(){e.state.focused&&e._popup&&!e._popup.isVisible()&&e._clickHandler()})),ts(e,\"popupRef\",(function(n){e._popup=n})),ts(e,\"addHandler\",(function(){var n=e.filterValue();e._hidePopup(),e.props.onAdd(n)})),ts(e,\"getLowerCaseLabel\",cs),ts(e,\"doesLabelMatch\",ss),ts(e,\"_clickHandler\",(function(){e.props.disabled||(e.state.showPopup?e._hidePopup():(e.props.onBeforeOpen(),e._showPopup()))})),ts(e,\"_openPopupIfClosed\",(function(){e.props.disabled||e.state.showPopup||(e.props.onBeforeOpen(),e._showPopup())})),ts(e,\"_filterChangeHandler\",(function(n){e._setFilter(n.currentTarget.value,n)})),ts(e,\"_setFilter\",(function(n,t){var r;if((!e.isInputMode()||e.state.focused)&&n!==e.state.filterValue){var o=n.replace(/^\\s+/g,\"\");if(e.props.onFilter(o),e.props.allowAny){var i={key:Math.random(),label:o};e.setState({selected:\"\"===o?null:i,selectedIndex:null},(function(){e.props.onSelect(i,t),e.props.onChange(i,t)}))}(null===(r=e._popup)||void 0===r||!r.isVisible())&&e.props.onBeforeOpen(),e.setState({filterValue:o},(function(){e._showPopup()}))}})),ts(e,\"_redrawPopup\",(function(){e.props.multiple&&setTimeout((function(){e.isInputMode()&&e.clearFilter(),e._showPopup()}),0)})),ts(e,\"_listSelectHandler\",(function(n,t){var r,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=t&&(\"select\"===t.type||\"keydown\"===t.type);if(i&&t.preventDefault(),a=n,(Uo.isItemType(Uo.ListProps.Type.ITEM,a)||function(e){return Uo.isItemType(Uo.ListProps.Type.CUSTOM,e)}(n))&&!n.disabled&&!n.isResetItem){var a,l=null!==(r=e.props.tryKeepOpen)&&void 0!==r?r:o.tryKeepOpen;if(e.props.multiple){if(l||e._hidePopup(i),null==n.key)throw new Error('Multiple selection requires each item to have the \"key\" property');e.setState((function(r){var o,i=r.selected;r.multipleMap[n.key]?(o=i.filter((function(e){return e.key!==n.key})),e.props.onDeselect&&e.props.onDeselect(n)):(o=i.concat(n),e.props.onSelect&&e.props.onSelect(n,t)),e.props.onChange(o,t);var a={filterValue:\"\",selected:o,selectedIndex:e._getSelectedIndex(n,e.props.data)};if(\"object\"===os(e.props.multiple)&&e.props.multiple.limit&&o.length===e.props.multiple.limit&&(a.shownData=r.shownData.map((function(e){return o.find((function(n){return n.key===e.key}))?e:ns(ns({},e),{},{disabled:!0})}))),r.multipleMap[n.key]){var l=r.multipleMap,c=n.key,s=(l[c],function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(l,[c].map(rs)));a.multipleMap=s}else a.multipleMap=ns(ns({},r.multipleMap),{},ts({},n.key,!0));return ns(ns({},r),a)}),(function(){l&&e._redrawPopup()}))}else l||e._hidePopup(i),e.setState({selected:n,selectedIndex:e._getSelectedIndex(n,e.props.data)},(function(){var r=e.isInputMode()&&!e.props.hideSelected?gs(n):\"\";e.filterValue(r),e.props.onFilter(r),e.props.onSelect(n,t),e.props.onChange(n,t)}))}})),ts(e,\"_listSelectAllHandler\",(function(){var n=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];e.setState((function(t){var r,o=t.selected;return n?(r=e.props.data.filter((function(e){return(function(e){return Uo.isItemType(Uo.ListProps.Type.ITEM,e)}(e)||function(e){return Uo.isItemType(Uo.ListProps.Type.CUSTOM,e)}(e))&&!e.disabled}))).filter((function(n){return!e.props.selected.find((function(e){return n.key===e.key}))})).forEach((function(n){e.props.onSelect&&e.props.onSelect(n)})):(r=[],o.forEach((function(n){e.props.onDeselect&&e.props.onDeselect(n)}))),e.props.onChange(r,event),{filterValue:\"\",selected:r,selectedIndex:n?e._getSelectedIndex(r,e.props.data):null,shownData:t.shownData.map((function(e){return ns(ns({},e),{},{checkbox:n})})),multipleMap:n?ps(e.props.data.filter((function(e){return!e.disabled}))):{}}}),e._redrawPopup)})),ts(e,\"_onCloseAttempt\",(function(n,t){e.isInputMode()&&(e.props.allowAny||(e.props.hideSelected||!e.state.selected||e.props.multiple?e.clearFilter():e.state.selected&&!Array.isArray(e.state.selected)&&e.filterValue(gs(e.state.selected)))),e.props.tags&&n&&n.target&&n.target instanceof Element&&n.target.matches('[data-test=\"ring-tag-remove\"]')||e._hidePopup(t)})),ts(e,\"clearFilter\",(function(n){e._setFilter(\"\",n)})),ts(e,\"clear\",(function(n){n&&n.stopPropagation();var t=e.props.multiple?[]:null;return e.setState({selected:t,selectedIndex:null,filterValue:\"\"},(function(){e.props.onChange&&e.props.onChange(t,n)})),!1})),ts(e,\"filter\",void 0),ts(e,\"filterRef\",(function(n){e.filter=n})),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&Jc(e,n)}(t,e),function(e,n,t){return n&&Kc(e.prototype,n),t&&Kc(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"componentDidUpdate\",value:function(e,n){var t=this.state,r=t.showPopup,o=t.selected,i=this.props,a=i.onClose,l=i.onOpen,c=i.onChange,s=i.multiple;n.showPopup&&!r?a(o):!n.showPopup&&r&&l(),s===e.multiple||Ko()(s,e.multiple)||c(o)}},{key:\"getValueForFilter\",value:function(e){return hs(e,this.props.type,this.state.filterValue)}},{key:\"_getSelectedIndex\",value:function(e,n){return ds(e,n)}},{key:\"_getResetOption\",value:function(){var e=this,t=Array.isArray(this.state.selected)&&this.state.selected.length,r=this.props.tags&&\"object\"===os(this.props.tags)?this.props.tags.reset:null;if(!t||!r)return null;return{isResetItem:!0,separator:r.separator,key:r.label,rgItemType:Uo.ListProps.Type.CUSTOM,template:n.createElement(Ai,{text:!0,className:Vc().button,\"data-test\":\"ring-select-reset-tags-button\",height:Wo.S},r.label),glyph:r.glyph,onClick:function(n,t){e.clear(t),e.clearFilter(),e.props.onFilter(\"\"),e.setState((function(e){return{shownData:e.shownData.slice(r.separator?2:1),multipleMap:{}}})),e._redrawPopup()}}}},{key:\"_prependResetOption\",value:function(e){var n=this._getResetOption();if(n){var t=[n];return n.separator&&t.push({rgItemType:Uo.ListProps.Type.SEPARATOR}),t.concat(e)}return e}},{key:\"_renderPopup\",value:function(){var e=this,t=this.props.targetElement||this.node,r=this.state,o=r.showPopup,i=r.shownData,a=this._prependResetOption(i);return n.createElement(wa.Consumer,null,(function(r){var l,c,s=r.translate;if(e.props.loading)l=null!==(c=e.props.loadingMessage)&&void 0!==c?c:s(\"loading\");else if(!i.length){var u;l=null!==(u=e.props.notFoundMessage)&&void 0!==u?u:s(\"noOptionsFound\")}return n.createElement(Gc,{data:a,message:l,toolbar:o&&e.getToolbar(),topbar:e.getTopbar(),loading:e.props.loading,activeIndex:e.state.selectedIndex,hidden:!o,ref:e.popupRef,maxHeight:e.props.maxHeight,minWidth:e.props.minWidth,directions:e.props.directions,className:e.props.popupClassName,style:e.props.popupStyle,top:e.props.top,left:e.props.left,filter:!e.isInputMode()&&e.props.filter,filterIcon:e.props.filterIcon,filterRef:e.props.filterRef,multiple:e.props.multiple,filterValue:e.state.filterValue,anchorElement:t,onCloseAttempt:e._onCloseAttempt,onOutsideClick:e.props.onOutsideClick,onSelect:e._listSelectHandler,onSelectAll:e._listSelectAllHandler,onFilter:e._filterChangeHandler,onClear:e.clearFilter,onLoadMore:e.props.onLoadMore,isInputMode:e.isInputMode(),selected:e.state.selected,tags:e.props.tags,compact:e.props.compact,renderOptimization:e.props.renderOptimization,ringPopupTarget:e.props.ringPopupTarget,disableMoveOverflow:e.props.disableMoveOverflow,disableScrollToActive:e.props.disableScrollToActive,dir:e.props.dir,onEmptyPopupEnter:e.onEmptyPopupEnter,listId:e.listId})}))}},{key:\"_showPopup\",value:function(){if(this.node){var e=this.getListItems(this.filterValue());this.setState({showPopup:!0,shownData:e})}}},{key:\"_hidePopup\",value:function(e){var n=this;this.node&&this.state.showPopup&&(this.setState((function(e){return{showPopup:!1,filterValue:n.props.allowAny?e.filterValue:\"\"}})),e&&this.focus())}},{key:\"getToolbar\",value:function(){var e=this.props,t=e.hint,r=e.renderBottomToolbar,o=this.state.addButton||{},i=o.prefix,a=o.label,c=o.delayed;return this.state.addButton||t||r?n.createElement(\"div\",{className:l()(ts({},Vc().toolbar,Boolean(this.state.addButton||r))),\"data-test\":\"ring-select-toolbar\"},r&&r(),this.state.addButton&&n.createElement(Ai,{text:!0,delayed:c,className:l()(Vc().button,Vc().buttonSpaced),onClick:this.addHandler,\"data-test\":\"ring-select-toolbar-button\"},i?\"\".concat(i,\" \").concat(a):a),t&&n.createElement(Uo.ListHint,{label:t,\"data-test\":\"ring-select-toolbar-hint\"})):null}},{key:\"getTopbar\",value:function(){var e,n;return null===(e=(n=this.props).renderTopToolbar)||void 0===e?void 0:e.call(n)}},{key:\"getFilterFn\",value:function(){return us(this.props.filter)}},{key:\"getListItems\",value:function(e,n){var t=fs(this.props,this.state,e,n),r=t.filteredData,o=t.addButton;return this.setState({addButton:o}),r}},{key:\"filterValue\",value:function(e){return\"string\"==typeof e||\"number\"==typeof e?void this.setState({filterValue:e}):this.state.filterValue}},{key:\"isInputMode\",value:function(){return ls(this.props.type)}},{key:\"_rebuildMultipleMap\",value:function(e){Array.isArray(e)&&this.setState({multipleMap:ps(e)})}},{key:\"_selectionIsEmpty\",value:function(){return Array.isArray(this.state.selected)&&!this.state.selected.length||!this.state.selected}},{key:\"_getLabel\",value:function(){var e,n;return null!==(e=null!==(n=this.props.label)&&void 0!==n?n:this.props.selectedLabel)&&void 0!==e?e:\"Select an option\"}},{key:\"_getPlaceholder\",value:function(){var e;return this._selectionIsEmpty()?null!==(e=this.props.label)&&void 0!==e?e:\"Select an option\":this._getSelectedString()}},{key:\"_getSelectedString\",value:function(){if(Array.isArray(this.state.selected)){for(var e=[],n=0;n<this.state.selected.length;n++)e.push(gs(this.state.selected[n]));return e.filter(Boolean).join(\", \")}return null!=this.state.selected?gs(this.state.selected):null}},{key:\"_getIcons\",value:function(){var e=this.state.selected,t=this.props,r=t.disabled,o=t.clear,i=t.hideArrow,a=[],l=this.props.height||this.context;return!Array.isArray(e)&&null!=e&&e.icon&&a.push(n.createElement(\"button\",{title:\"Toggle options popup\",type:\"button\",className:Vc().selectedIcon,key:\"selected\",disabled:this.props.disabled,onClick:this._clickHandler,style:{backgroundImage:\"url(\".concat(e.icon,\")\")}})),!o||r||this._selectionIsEmpty()||a.push(n.createElement(Ai,{title:\"Clear selection\",\"data-test\":\"ring-clear-select\",className:Vc().clearIcon,key:\"close\",disabled:this.props.disabled,onClick:this.clear,height:l,icon:Vo()})),i||a.push(n.createElement(Ai,{title:\"Toggle options popup\",className:Vc().chevron,iconClassName:Vc().chevronIcon,icon:Yo(),key:\"hide\",disabled:this.props.disabled,height:l,onClick:this._clickHandler})),a}},{key:\"_getAvatar\",value:function(){var e,t;return!Array.isArray(this.state.selected)&&((null===(e=this.state.selected)||void 0===e?void 0:e.avatar)||(null===(t=this.state.selected)||void 0===t?void 0:t.showGeneratedAvatar))&&n.createElement(Mt,{className:Vc().avatar,url:this.state.selected.avatar,username:this.state.selected.username,size:Ct.Size20})}},{key:\"getShortcutsMap\",value:function(){return{enter:this._onEnter,esc:this._onEsc,up:this._inputShortcutHandler,down:this._inputShortcutHandler,right:is,left:is,\"shift+up\":is,\"shift+down\":is,space:is}}},{key:\"renderSelect\",value:function(e){var t,r,o,i,a=this.props[\"data-test\"],c=this.props.selectedLabel,s=this.state.shortcutsEnabled,u=l()(Vc().select,\"ring-js-shortcuts\",this.props.className,Vc()[\"height\".concat(this.props.height||this.context)],ts(ts({},Vc()[\"size\".concat(this.props.size)],this.props.type!==Yc.INLINE),Vc().disabled,this.props.disabled)),p=this._getIcons(),f=as(p.length),d=n.createElement(\"div\",{className:Vc().icons},p),g=this.state.showPopup?{\"aria-owns\":this.listId,\"aria-activedescendant\":e,\"aria-label\":null!==(t=this.props.label)&&void 0!==t?t:void 0}:{\"aria-label\":null!==(r=this.props.label)&&void 0!==r?r:void 0};switch(this.props.type){case Yc.INPUT_WITHOUT_CONTROLS:case Yc.INPUT:return n.createElement(n.Fragment,null,n.createElement(\"div\",{ref:this.nodeRef,className:l()(u,Vc().inputMode),\"data-test\":Ie(\"ring-select\",a)},s&&n.createElement(hn,{map:this.getShortcutsMap(),scope:this.shortcutsScope}),n.createElement($a,$c({},g,{height:this.props.height,autoComplete:\"off\",id:this.props.id,onClick:this._clickHandler,inputRef:fr(this.filterRef,this.props.filterRef),disabled:this.props.disabled,value:this.state.filterValue,borderless:this.props.type===Yc.INPUT_WITHOUT_CONTROLS,style:f,size:ja.FULL,onChange:this._filterChangeHandler,onFocus:this._focusHandler,onBlur:this._blurHandler,error:null!=this.props.error?\"\":null,label:this.props.type===Yc.INPUT?this._getLabel():null,placeholder:this.props.inputPlaceholder,onKeyDown:this.props.onKeyDown,\"data-test\":\"ring-select__focus\",enableShortcuts:s?Object.keys(ns(ns({},this.getShortcutsMap()),null===(o=this._popup)||void 0===o||null===(o=o.list)||void 0===o?void 0:o.shortcutsMap)):void 0,icon:this.props.filterIcon,afterInput:this.props.type===Yc.INPUT&&d})),this._renderPopup()),this.props.error&&n.createElement(\"div\",{className:l()(Da().errorText,Da()[\"size\".concat(this.props.size)])},this.props.error));case Yc.BUTTON:return n.createElement(\"div\",{ref:this.nodeRef,className:l()(u,Vc().buttonMode),\"data-test\":Ie(\"ring-select\",a)},c&&n.createElement(Ia,{type:this.props.labelType,disabled:this.props.disabled,htmlFor:this.props.id},c),s&&n.createElement(hn,{map:this.getShortcutsMap(),scope:this.shortcutsScope}),n.createElement(\"div\",{className:Vc().buttonContainer},n.createElement(Ai,$c({},g,{height:this.props.height,id:this.props.id,onClick:this._clickHandler,className:l()(this.props.buttonClassName,Vc().buttonValue,ts(ts({},Vc().buttonValueOpen,this.state.showPopup),Vc().buttonValueEmpty,this._selectionIsEmpty())),disabled:this.props.disabled,style:f,\"data-test\":\"ring-select__button ring-select__focus\"}),this._getAvatar(),this._getPlaceholder()),d),this._renderPopup());case Yc.INLINE:return n.createElement(\"div\",{className:u,ref:this.nodeRef,\"data-test\":Ie(\"ring-select\",a)},s&&n.createElement(hn,{map:this.getShortcutsMap(),scope:this.shortcutsScope}),n.createElement(Ci,$c({},g,{className:null!==(i=this.props.buttonClassName)&&void 0!==i?i:void 0,id:this.props.id,onClick:this._clickHandler,\"data-test\":\"ring-select__focus\",disabled:this.props.disabled,active:this.state.showPopup}),this._getPlaceholder()),this._renderPopup());default:return this.props.customAnchor?n.createElement(n.Fragment,null,s&&n.createElement(hn,{map:this.getShortcutsMap(),scope:this.shortcutsScope}),this.props.customAnchor({wrapperProps:{ref:this.nodeRef,\"data-test\":Ie(\"ring-select\",a)},buttonProps:ns(ns({},g),{},{id:this.props.id,onClick:this._clickHandler,disabled:this.props.disabled,children:this._getPlaceholder(),\"data-test\":\"ring-select__focus\"}),popup:this._renderPopup()})):n.createElement(\"span\",{id:this.props.id,ref:this.nodeRef,\"data-test\":\"ring-select\"},this._renderPopup())}}},{key:\"render\",value:function(){var e=this;return n.createElement(Ho.Provider,null,n.createElement(Ho.ValueContext.Consumer,null,(function(n){return e.renderSelect(n)})))}}],[{key:\"getDerivedStateFromProps\",value:function(e,n){var t=e.multiple,r=e.data,o=e.type,i=n.prevSelected,a=n.prevData,l=n.prevMultiple,c=n.filterValue,s={prevData:r,prevSelected:e.selected,prevMultiple:t};if(\"data\"in e&&r!==a){var u=fs(e,n,c,r),p=u.filteredData,f=u.addButton;Object.assign(s,{shownData:p,addButton:f}),n.selected&&Object.assign(s,{selectedIndex:ds(n.selected,r),filterValue:hs(n.selected,o,c)})}if(\"selected\"in e&&e.selected!==i){var d=e.selected||(t?[]:null),g=ds(d,r||a);Object.assign(s,{selected:d,filterValue:hs(d,o,c)}),Array.isArray(i)&&Array.isArray(d)&&function(e,n){if(!e||!n||e.length!==n.length)return!1;var t=n.reduce((function(e,n){return e[n.key]=!0,e}),{});return e.every((function(e){return t[e.key]}))}(i,d)||Object.assign(s,{selectedIndex:g})}l===t||Ko()(l,t)||(s.selected=t?[]:null),t&&!s.selected&&(s.selected=n.selected);var h=ns(ns({},n),s).selected;if(h&&Array.isArray(h)){s.multipleMap=ps(h);var A=fs(e,s,c,r),b=A.filteredData,v=A.addButton;Object.assign(s,{shownData:b,addButton:v})}return s}}])}(n.Component);ts(As,\"defaultProps\",{data:[],filter:!1,filterIcon:null,filterRef:is,multiple:!1,clear:!1,loading:!1,disabled:!1,type:Yc.BUTTON,size:ja.M,targetElement:null,hideSelected:!1,allowAny:!1,hideArrow:!1,showPopup:!1,maxHeight:600,directions:[va.PopupProps.Directions.BOTTOM_RIGHT,va.PopupProps.Directions.BOTTOM_LEFT,va.PopupProps.Directions.TOP_LEFT,va.PopupProps.Directions.TOP_RIGHT],selected:null,label:null,selectedLabel:null,inputPlaceholder:\"\",hint:null,shortcutsEnabled:!1,onBeforeOpen:is,onLoadMore:is,onOpen:is,onClose:is,onFilter:is,onFocus:is,onBlur:is,onKeyDown:is,onSelect:is,onDeselect:is,onOutsideClick:is,onChange:is,onAdd:is,onDone:is,onReset:is,tags:null,ringPopupTarget:null,dir:\"ltr\"}),ts(As,\"contextType\",Zo),ts(As,\"Type\",Yc),ts(As,\"Size\",ja),As.propTypes={className:i().string,buttonClassName:i().string,id:i().string,multiple:i().oneOfType([i().bool,i().object]),allowAny:i().bool,filter:i().oneOfType([i().bool,i().object]),filterIcon:i().oneOfType([i().string,i().elementType]),filterRef:i().oneOfType([i().func,pr(i().instanceOf(HTMLInputElement))]),getInitial:i().func,onClose:i().func,onOpen:i().func,onDone:i().func,onFilter:i().func,onChange:i().func,onReset:i().func,onLoadMore:i().func,onAdd:i().func,onBeforeOpen:i().func,onSelect:i().func,onDeselect:i().func,onOutsideClick:i().func,onFocus:i().func,onBlur:i().func,onKeyDown:i().func,selected:i().oneOfType([i().object,i().array]),data:i().array,tags:i().object,targetElement:i().object,loading:i().bool,loadingMessage:i().string,notFoundMessage:i().string,maxHeight:i().number,minWidth:i().number,directions:i().array,popupClassName:i().string,popupStyle:i().object,top:i().number,left:i().number,renderOptimization:i().bool,ringPopupTarget:i().string,error:i().string,hint:Uo.ListHint.propTypes.label,add:i().object,type:i().oneOf(Object.values(Yc)),disabled:i().bool,hideSelected:i().bool,label:i().string,selectedLabel:i().oneOfType([i().string,i().arrayOf(i().node),i().node]),inputPlaceholder:i().string,clear:i().bool,hideArrow:i().bool,showPopup:i().bool,tryKeepOpen:i().bool,compact:i().bool,size:i().oneOf(Object.values(ja)),customAnchor:i().func,disableMoveOverflow:i().bool,disableScrollToActive:i().bool,dir:i().oneOf([\"ltr\",\"rtl\"]),\"data-test\":i().string};t(274);function bs(e){var n=e;if(-1===n.tabIndex)return!1;for(;n;){var t=getComputedStyle(n);if(\"none\"===t.display||\"hidden\"===t.visibility)return!1;n=n.parentElement}return!0}var vs=function(){function e(e){var n=e.trapElement,t=e.navigationKeys,r=e.interactiveElementsSelector;this.getInteractiveElementsSelector=function(){return'button, a, input, textarea, select, [tabindex]:not([tabindex=\"-1\"])'},this.navigationKeys=[\"Tab\"],this.trapElement=n,t&&(this.navigationKeys=t),r&&(this.getInteractiveElementsSelector=r),this.handleKeyDown=this.handleKeyDown.bind(this),this.trapElement.addEventListener(\"keydown\",this.handleKeyDown)}return e.prototype.handleKeyDown=function(e){var n=Array.from(this.trapElement.querySelectorAll(this.getInteractiveElementsSelector())).filter(bs);if(this.navigationKeys.includes(e.key)&&0!==n.length){var t=Array.from(this.trapElement.querySelectorAll('[data-role=\"dropdown-toggle\"]')).filter(bs),r=window.innerWidth>=900||1===t.length?t[0]:t[1];r&&n.unshift(r);var o=n[0],i=n[n.length-1];if(\"ArrowUp\"===e.key)if(document.activeElement===o)i.focus();else{var a=n.indexOf(document.activeElement);n[a-1].focus()}if(\"ArrowDown\"===e.key)if(document.activeElement===i)o.focus();else{a=n.indexOf(document.activeElement);n[a+1].focus()}if(\"Tab\"===e.key){var l=n.findIndex((function(e){return e&&document.activeElement===e}));if(-1!==l)n[e.shiftKey?(l-1+n.length)%n.length:(l+1)%n.length].focus(),e.preventDefault()}}},e.prototype.destroy=function(){this.trapElement.removeEventListener(\"keydown\",this.handleKeyDown)},e}();var ms,ys=function(){return ys=Object.assign||function(e){for(var n,t=1,r=arguments.length;t<r;t++)for(var o in n=arguments[t])Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o]);return e},ys.apply(this,arguments)},Es=function(e,n){var t=\"function\"==typeof Symbol&&e[Symbol.iterator];if(!t)return e;var r,o,i=t.call(e),a=[];try{for(;(void 0===n||n-- >0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(t=i.return)&&t.call(i)}finally{if(o)throw o.error}}return a},Cs=function(n){var t=n.label;return(0,e.jsx)(\"strong\",{children:t})},ws=function(n){var t=n.searchResult,r=function(e,n){if(!e)return[];for(var t=[],r=Math.max(null!=n?n:0,1),o=0,i=0;o<e.length;)t[i]=e.slice(o,o+r),i++,o+=r;return t}(function(e){return e.name.replace(e.searchKeys[e.rank],e.highlight)}(t).split(\"**\"),2).flatMap((function(n,t){var r=Es(n,2),o=r[0],i=r[1];return[o,i?(0,e.jsx)(Cs,{label:i},t):null]}));return(0,e.jsxs)(\"div\",ys({className:\"template-wrapper\"},{children:[(0,e.jsx)(\"div\",ys({className:\"template-title\"},{children:r})),(0,e.jsx)(\"span\",ys({className:\"template-description\"},{children:t.description}))]}))},xs=(ms=function(e,n){return ms=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,n){e.__proto__=n}||function(e,n){for(var t in n)Object.prototype.hasOwnProperty.call(n,t)&&(e[t]=n[t])},ms(e,n)},function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Class extends value \"+String(n)+\" is not a constructor or null\");function t(){this.constructor=e}ms(e,n),e.prototype=null===n?Object.create(n):(t.prototype=n.prototype,new t)}),Ss=function(){return Ss=Object.assign||function(e){for(var n,t=1,r=arguments.length;t<r;t++)for(var o in n=arguments[t])Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o]);return e},Ss.apply(this,arguments)},_s=function(n){function t(){return null!==n&&n.apply(this,arguments)||this}return xs(t,n),t.prototype.componentDidUpdate=function(e,t){n.prototype.componentDidUpdate.call(this,e,t),this.props.filter&&\"boolean\"!=typeof this.props.filter&&this.state.filterValue!=this.props.filter.value&&this.setState({filterValue:this.props.filter.value})},t.prototype.getListItems=function(n){var t,r=(n||\"\").trim(),o=this.props.data.map((function(e){var n=e.searchKeys.map((function(n,t){return Ss(Ss(Ss({},il(r,n,!1)),e),{rank:t})})).filter((function(e){return e.matched}))[0];return n||Ss({matched:!1},e)})).filter((function(e){return e.matched}));return this.props.onFilter(r),function(n){return n.map((function(n){return Ss(Ss({},n),{template:(0,e.jsx)(ws,{searchResult:n})})}))}((t=r,o.sort((function(e,n){var r=e.rank-n.rank;if(0!==r)return r;var o=e.name.toLowerCase().includes(t.toLowerCase())?1:0,i=(n.name.toLowerCase().includes(t.toLowerCase())?1:0)-o;if(0!=i)return i;var a=e.highlight.indexOf(\"**\")-n.highlight.indexOf(\"**\");return 0==a?e.name.toLowerCase().localeCompare(n.name.toLowerCase()):a}))))},t}(As),ks=t(8132),Os=t.n(ks),Bs=[\"children\",\"data-test\",\"title\",\"delay\",\"selfOverflowOnly\",\"popupProps\",\"long\"];function Ps(e){return Ps=\"function\"==typeof Symbol&&\"symbol\"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&\"function\"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?\"symbol\":typeof e},Ps(e)}function Ts(){return Ts=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},Ts.apply(null,arguments)}function Is(e,n){for(var t=0;t<n.length;t++){var r=n[t];r.enumerable=r.enumerable||!1,r.configurable=!0,\"value\"in r&&(r.writable=!0),Object.defineProperty(e,Ns(r.key),r)}}function js(e,n,t){return n=Ds(n),function(e,n){if(n&&(\"object\"==Ps(n)||\"function\"==typeof n))return n;if(void 0!==n)throw new TypeError(\"Derived constructors may only return object or undefined\");return function(e){if(void 0===e)throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");return e}(e)}(e,zs()?Reflect.construct(n,t||[],Ds(e).constructor):n.apply(e,t))}function zs(){try{var e=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){})))}catch(e){}return(zs=function(){return!!e})()}function Ds(e){return Ds=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(e){return e.__proto__||Object.getPrototypeOf(e)},Ds(e)}function Rs(e,n){return Rs=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(e,n){return e.__proto__=n,e},Rs(e,n)}function Ms(e,n,t){return(n=Ns(n))in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function Ns(e){var n=function(e,n){if(\"object\"!=Ps(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var r=t.call(e,n||\"default\");if(\"object\"!=Ps(r))return r;throw new TypeError(\"@@toPrimitive must return a primitive value.\")}return(\"string\"===n?String:Number)(e)}(e,\"string\");return\"symbol\"==Ps(n)?n:n+\"\"}var Fs=Re(),Ls=(0,n.createContext)(void 0),Hs=function(e){function t(){var e;!function(e,n){if(!(e instanceof n))throw new TypeError(\"Cannot call a class as a function\")}(this,t);for(var n=arguments.length,r=new Array(n),o=0;o<n;o++)r[o]=arguments[o];return Ms(e=js(this,t,[].concat(r)),\"state\",{showPopup:!1,showNestedPopup:!1}),Ms(e,\"timeout\",void 0),Ms(e,\"listeners\",new $e),Ms(e,\"containerNode\",void 0),Ms(e,\"containerRef\",(function(n){e.containerNode=n})),Ms(e,\"tryToShowPopup\",(function(){var n=e.props,t=n.delay;n.title&&(t?e.timeout=window.setTimeout(e.showPopup,t):e.showPopup())})),Ms(e,\"showPopup\",(function(){var n;if(e.props.selfOverflowOnly){var t=e.containerNode;if(!t)return;if(0===t.clientWidth&&0===t.clientHeight)return;if(t.scrollWidth<=t.clientWidth&&t.scrollHeight<=t.clientHeight)return}null===(n=e.context)||void 0===n||n.onNestedTooltipShow(),e.setState({showPopup:!0})})),Ms(e,\"hidePopup\",(function(){var n;clearTimeout(e.timeout),null===(n=e.context)||void 0===n||n.onNestedTooltipHide(),e.setState({showPopup:!1})})),Ms(e,\"popup\",void 0),Ms(e,\"popupRef\",(function(n){e.popup=n})),Ms(e,\"onNestedTooltipShow\",(function(){e.setState({showNestedPopup:!0})})),Ms(e,\"onNestedTooltipHide\",(function(){e.setState({showNestedPopup:!1})})),e}return function(e,n){if(\"function\"!=typeof n&&null!==n)throw new TypeError(\"Super expression must either be null or a function\");e.prototype=Object.create(n&&n.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,\"prototype\",{writable:!1}),n&&Rs(e,n)}(t,e),function(e,n,t){return n&&Is(e.prototype,n),t&&Is(e,t),Object.defineProperty(e,\"prototype\",{writable:!1}),e}(t,[{key:\"componentDidMount\",value:function(){this.props.title&&this.addListeners()}},{key:\"componentDidUpdate\",value:function(e){!e.title&&this.props.title?this.addListeners():e.title&&!this.props.title&&this.listeners.removeAll()}},{key:\"componentWillUnmount\",value:function(){clearTimeout(this.timeout),this.listeners.removeAll()}},{key:\"addListeners\",value:function(){var e=this;null!=this.containerNode&&(this.listeners.add(this.containerNode,\"mouseover\",this.tryToShowPopup),this.listeners.add(this.containerNode,\"mouseout\",this.hidePopup)),this.listeners.add(document,\"scroll\",(function(){return Fs(e.hidePopup)}),{passive:!0})}},{key:\"render\",value:function(){var e=this.props,t=e.children,r=e[\"data-test\"],o=e.title,i=(e.delay,e.selfOverflowOnly,e.popupProps),a=e.long,c=function(e,n){if(null==e)return{};var t,r,o=function(e,n){if(null==e)return{};var t={};for(var r in e)if({}.hasOwnProperty.call(e,r)){if(-1!==n.indexOf(r))continue;t[r]=e[r]}return t}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r<i.length;r++)t=i[r],-1===n.indexOf(t)&&{}.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}(e,Bs),s=\"string\"==typeof o&&o?{\"aria-label\":o,role:\"tooltip\"}:{},u=this.onNestedTooltipShow,p=this.onNestedTooltipHide;return n.createElement(Ls.Provider,{value:{onNestedTooltipShow:u,onNestedTooltipHide:p}},n.createElement(\"span\",Ts({},s,c,{ref:this.containerRef,\"data-test\":Ie(\"ring-tooltip\",r),\"data-test-title\":\"string\"==typeof o?o:void 0}),t,n.createElement(va,Ts({trapFocus:!1,hidden:!this.state.showPopup||this.state.showNestedPopup,onCloseAttempt:this.hidePopup,maxHeight:400,className:l()(Os().tooltip,Ms({},Os().long,a)),attached:!1,top:4,dontCloseOnAnchorClick:!0,ref:this.popupRef},i),o)))}}])}(n.Component);function Us(){return Us=Object.assign?Object.assign.bind():function(e){for(var n=1;n<arguments.length;n++){var t=arguments[n];for(var r in t)({}).hasOwnProperty.call(t,r)&&(e[r]=t[r])}return e},Us.apply(null,arguments)}Ms(Hs,\"propTypes\",{delay:i().number,selfOverflowOnly:i().bool,popupProps:i().object,title:i().node,children:i().node,\"data-test\":i().string}),Ms(Hs,\"defaultProps\",{title:\"\",selfOverflowOnly:!1,popupProps:{}}),Ms(Hs,\"PopupProps\",va.PopupProps),Ms(Hs,\"contextType\",Ls);const Ws=({styles:e={},...t})=>n.createElement(\"svg\",Us({width:\"24\",height:\"24\",fill:\"none\",xmlns:\"http://www.w3.org/2000/svg\"},t),n.createElement(\"path\",{d:\"M15.142 6.28a6.497 6.497 0 10-2.421 8.866c.207-.122.409-.256.602-.4L19.587 21 21 19.586l-6.261-6.251a6.51 6.51 0 00.402-7.055zm-3.413 7.129a4.5 4.5 0 11-4.463-7.814 4.5 4.5 0 014.463 7.814z\",fill:\"#fff\"}));var Gs;!function(e){e[e.WINDOWS=0]=\"WINDOWS\",e[e.MACOS=1]=\"MACOS\",e[e.LINUX=2]=\"LINUX\",e[e.OTHER=3]=\"OTHER\"}(Gs||(Gs={}));var Ys=function(){function e(){}return e.metaKey={name:\"Command\",keyArg:\"Meta\"},e.ctrlKey={name:\"Ctrl\",keyArg:\"Control\"},e.altKey={name:\"Alt\",keyArg:\"Alt\"},e.shiftKey={name:\"Shift\",keyArg:\"Shift\"},e}(),qs=[Ys.altKey,Ys.shiftKey,Ys.ctrlKey,Ys.metaKey],Vs=function(){function e(){var e,n=this;this.registerHotkeyWithAccel=function(e,t){var r=n.getOsAccelKey();document.onkeydown=function(n){var o=n.getModifierState(r.keyArg),i=qs.filter((function(e){return e!==r})).map((function(e){return n.getModifierState(e.keyArg)})).some((function(e){return e}));o&&!i&&n.key===t&&(n.preventDefault(),e())}},this.osKind=(e=navigator.userAgent).includes(\"Mac\")?Gs.MACOS:e.includes(\"Win\")?Gs.WINDOWS:e.includes(\"Linux\")?Gs.LINUX:Gs.OTHER}return e.prototype.getOsAccelKeyName=function(){return this.getOsAccelKey().name},e.prototype.getOsAccelKey=function(){return this.osKind===Gs.MACOS?Ys.metaKey:Ys.ctrlKey},e}(),$s=function(){return $s=Object.assign||function(e){for(var n,t=1,r=arguments.length;t<r;t++)for(var o in n=arguments[t])Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o]);return e},$s.apply(this,arguments)},Ks=function(n){var t=n.wrapperProps,r=n.buttonProps,o=n.popup,i=new Vs;return i.registerHotkeyWithAccel(r.onClick,\"k\"),(0,e.jsxs)(\"span\",$s({},t,{children:[(0,e.jsx)(Hs,$s({title:\"\".concat(i.getOsAccelKeyName(),\" + \").concat(\"k\".toUpperCase()),delay:500,popupProps:{className:\"search-hotkey-popup\"}},{children:(0,e.jsx)(\"button\",$s({type:\"button\"},r,{children:(0,e.jsx)(Ws,{})}))})),o]}))},Qs=function(){return Qs=Object.assign||function(e){for(var n,t=1,r=arguments.length;t<r;t++)for(var o in n=arguments[t])Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o]);return e},Qs.apply(this,arguments)},Xs=function(e,n){var t=\"function\"==typeof Symbol&&e[Symbol.iterator];if(!t)return e;var r,o,i=t.call(e),a=[];try{for(;(void 0===n||n-- >0)&&!(r=i.next()).done;)a.push(r.value)}catch(e){o={error:e}}finally{try{r&&!r.done&&(t=i.return)&&t.call(i)}finally{if(o)throw o.error}}return a},Zs=function(e,n,t){if(t||2===arguments.length)for(var r,o=0,i=n.length;o<i;o++)!r&&o in n||(r||(r=Array.prototype.slice.call(n,0,o)),r[o]=n[o]);return e.concat(r||Array.prototype.slice.call(n))},Js=function(t){var r=t.data,o=Xs((0,n.useState)(r[0]),2),i=o[0],a=o[1],l=(0,n.useCallback)((function(e){if(e){var n=e;window.location.replace(\"\".concat(window.pathToRoot).concat(n.location,\"?query=\").concat(n.name)),a(n)}}),[]);return(0,e.jsx)(\"div\",Qs({className:\"search-container\"},{children:(0,e.jsx)(\"div\",Qs({className:\"search\"},{children:(0,e.jsx)(_s,{id:\"pages-search\",selectedLabel:\"Search\",label:\"Search\",filter:!0,type:As.Type.CUSTOM,clear:!0,renderOptimization:!0,disableScrollToActive:!0,selected:i,data:r,popupClassName:\"popup-wrapper\",onSelect:l,maxHeight:510,customAnchor:function(n){var t=n.wrapperProps,r=n.buttonProps,o=n.popup;return(0,e.jsx)(Ks,{wrapperProps:t,buttonProps:r,popup:o})},onOpen:tu,onClose:ru,onFilter:su})}))}))},eu=function(){var t=Xs((0,n.useState)([]),2),r=t[0],o=t[1];return(0,n.useEffect)((function(){var e,n,t;fetch((e=\"scripts/pages.json\",n=window.pathToRoot,t=\"\"==n?\".\":n,t.endsWith(\"/\")?\"\".concat(t).concat(e):\"\".concat(t,\"/\").concat(e))).then((function(e){return e.json()})).then((function(e){o(e.map((function(e,n){return Qs(Qs({},e),{label:e.name,key:n,type:e.kind,rgItemType:Uo.ListProps.Type.CUSTOM})})))}),(function(e){console.error(\"failed to fetch pages data\",e),o([])}))}),[]),(0,e.jsx)(Js,{data:r})},nu=null;function tu(){var e=document.querySelector('[data-test=\"ring-input-clear\"]');if(e){var n=function(){var e=document.createElement(\"button\");return e.id=\"search-close-button\",e.className=\"button button_dropdown button_dropdown_active search--close-button\",e.setAttribute(\"aria-label\",\"Close search popup\"),e}();e.after(n),n.addEventListener(\"click\",au),e.addEventListener(\"click\",iu)}var t=document.querySelector('[data-test=\"ring-input\"]');t&&(t.addEventListener(\"keydown\",ou),nu=new vs({trapElement:t,interactiveElementsSelector:function(){return'[data-test-custom=\"ring-select-popup-filter-input\"], [data-test=\"ring-input-clear\"], #search-close-button'}})),document.body.style.overflow=\"hidden\",function(){cu(),lu=new MutationObserver((function(e){e.forEach((function(e){var n=e.target;Zs([],Xs(n.classList),!1).some((function(e){return e.includes(\"hover\")}))&&!function(e){var n=e.closest(\".ReactVirtualized__Grid\");if(!n)return!1;var t=n.getBoundingClientRect(),r=e.getBoundingClientRect();return r.top>=t.top&&r.bottom<=t.bottom}(n)&&n.scrollIntoView({behavior:\"smooth\",block:\"center\",inline:\"center\"})}))}));var e=document.querySelector(\".ReactVirtualized__Grid\");if(!e||!lu)return;lu.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[\"class\"]})}()}function ru(){document.body.style.overflow=\"\",cu()}function ou(e){var n=e.key;\"Tab\"===n&&(e.preventDefault(),e.stopPropagation()),\"Enter\"===n&&\"input\"!==e.target.tagName.toLowerCase()&&e.stopPropagation()}function iu(){var e=document.querySelector('[data-test-custom=\"ring-select-popup-filter-input\"]');e&&e.focus()}function au(e){var n=e.target;if(\"search-close-button\"===(null==n?void 0:n.id)){var t=document.querySelector('[data-test=\"ring-input\"]');t&&t.removeEventListener(\"keydown\",ou);var r=document.querySelector('[data-test=\"ring-input-clear\"]');r&&r.removeEventListener(\"click\",iu);var o=document.getElementById(\"search-close-button\");o&&o.removeEventListener(\"click\",au),nu&&(nu.destroy(),nu=null);var i=document.getElementById(\"pages-search\");i&&(i.focus(),i.click())}}var lu=null;function cu(){null!==lu&&(lu.disconnect(),lu=null)}function su(){var e=document.querySelector(\".ReactVirtualized__Grid\");e&&(e.scrollTop=0)}var uu=function(){return uu=Object.assign||function(e){for(var n,t=1,r=arguments.length;t<r;t++)for(var o in n=arguments[t])Object.prototype.hasOwnProperty.call(n,o)&&(e[o]=n[o]);return e},uu.apply(this,arguments)};const pu=function(){return(0,e.jsx)(\"div\",uu({className:\"search-content\"},{children:(0,e.jsx)(eu,{})}))};var fu=function(){(0,r.render)((0,e.jsx)(n.StrictMode,{children:(0,e.jsx)(pu,{})}),document.getElementById(\"searchBar\")),document.removeEventListener(\"DOMContentLoaded\",fu)};document.addEventListener(\"DOMContentLoaded\",fu)})()})();\n//# sourceMappingURL=main.js.map"
  },
  {
    "path": "docs/scripts/navigation-loader.js",
    "content": "/*\n * Copyright 2014-2025 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n */\nconst TOC_STATE_KEY_PREFIX = 'TOC_STATE::';\nconst TOC_CONTAINER_ID = 'sideMenu';\nconst TOC_SCROLL_CONTAINER_ID = 'leftColumn';\nconst TOC_PART_CLASS = 'toc--part';\nconst TOC_PART_HIDDEN_CLASS = 'toc--part_hidden';\nconst TOC_LINK_CLASS = 'toc--link';\nconst TOC_SKIP_LINK_CLASS = 'toc--skip-link';\n\n(function () {\n  function displayToc() {\n    fetch(pathToRoot + 'navigation.html')\n      .then((response) => response.text())\n      .then((tocHTML) => {\n        renderToc(tocHTML);\n        updateTocLinks();\n        collapseTocParts();\n        expandTocPathToCurrentPage();\n        restoreTocExpandedState();\n        restoreTocScrollTop();\n      });\n  }\n\n  function renderToc(tocHTML) {\n    const containerElement = document.getElementById(TOC_CONTAINER_ID);\n    if (containerElement) {\n      containerElement.innerHTML = tocHTML;\n    }\n  }\n\n  function updateTocLinks() {\n    document.querySelectorAll(`.${TOC_LINK_CLASS}`).forEach((tocLink) => {\n      tocLink.setAttribute('href', `${pathToRoot}${tocLink.getAttribute('href')}`);\n      tocLink.addEventListener('keydown', preventScrollBySpaceKey);\n    });\n    document.querySelectorAll(`.${TOC_SKIP_LINK_CLASS}`).forEach((skipLink) => {\n      skipLink.setAttribute('href', `#main`);\n      skipLink.addEventListener('keydown', preventScrollBySpaceKey);\n    })\n  }\n\n  function collapseTocParts() {\n    document.querySelectorAll(`.${TOC_PART_CLASS}`).forEach((tocPart) => {\n      if (!tocPart.classList.contains(TOC_PART_HIDDEN_CLASS)) {\n        tocPart.classList.add(TOC_PART_HIDDEN_CLASS);\n        const tocToggleButton = tocPart.querySelector('button');\n        if (tocToggleButton) {\n          tocToggleButton.setAttribute(\"aria-expanded\", \"false\");\n        }\n      }\n    });\n  }\n\n  const expandTocPathToCurrentPage = () => {\n    const tocParts = [...document.querySelectorAll(`.${TOC_PART_CLASS}`)];\n    const currentPageId = document.getElementById('content')?.getAttribute('pageIds');\n    if (!currentPageId) {\n      return;\n    }\n\n    let isPartFound = false;\n    let currentPageIdPrefix = currentPageId;\n    while (!isPartFound && currentPageIdPrefix !== '') {\n      tocParts.forEach((part) => {\n        const partId = part.getAttribute('pageId');\n        if (!isPartFound && partId?.includes(currentPageIdPrefix)) {\n          isPartFound = true;\n          expandTocPart(part);\n          expandTocPathToParent(part);\n          part.dataset.active = 'true';\n        }\n      });\n      currentPageIdPrefix = currentPageIdPrefix.substring(0, currentPageIdPrefix.lastIndexOf('/'));\n    }\n  };\n\n  const expandTocPathToParent = (part) => {\n    if (part.classList.contains(TOC_PART_CLASS)) {\n      expandTocPart(part);\n      expandTocPathToParent(part.parentNode);\n    }\n  };\n\n  const expandTocPart = (tocPart) => {\n    if (tocPart.classList.contains(TOC_PART_HIDDEN_CLASS)) {\n      tocPart.classList.remove(TOC_PART_HIDDEN_CLASS);\n      const tocToggleButton = tocPart.querySelector('button');\n      if (tocToggleButton) {\n        tocToggleButton.setAttribute(\"aria-expanded\", \"true\");\n      }\n      const tocPartId = tocPart.getAttribute('id');\n      safeSessionStorage.setItem(`${TOC_STATE_KEY_PREFIX}${tocPartId}`, 'true');\n    }\n  };\n\n  /**\n   * Restores the state of the navigation tree from the local storage.\n   * LocalStorage keys are in the format of `TOC_STATE::${id}` where `id` is the id of the part\n   */\n  const restoreTocExpandedState = () => {\n    const allLocalStorageKeys = safeSessionStorage.getKeys();\n    const tocStateKeys = allLocalStorageKeys.filter((key) => key.startsWith(TOC_STATE_KEY_PREFIX));\n    tocStateKeys.forEach((key) => {\n      const isExpandedTOCPart = safeSessionStorage.getItem(key) === 'true';\n      const tocPartId = key.substring(TOC_STATE_KEY_PREFIX.length);\n      const tocPart = document.querySelector(`.toc--part[id=\"${tocPartId}\"]`);\n      if (tocPart !== null && isExpandedTOCPart) {\n        tocPart.classList.remove(TOC_PART_HIDDEN_CLASS);\n        const tocToggleButton = tocPart.querySelector('button');\n        if (tocToggleButton) {\n          tocToggleButton.setAttribute(\"aria-expanded\", \"true\");\n        }\n      }\n    });\n  };\n\n  function saveTocScrollTop() {\n    const container = document.getElementById(TOC_SCROLL_CONTAINER_ID);\n    if (container) {\n      const currentScrollTop = container.scrollTop;\n      safeSessionStorage.setItem(`${TOC_STATE_KEY_PREFIX}SCROLL_TOP`, `${currentScrollTop}`);\n    }\n  }\n\n  function restoreTocScrollTop() {\n    const container = document.getElementById(TOC_SCROLL_CONTAINER_ID);\n    if (container) {\n      const storedScrollTop = safeSessionStorage.getItem(`${TOC_STATE_KEY_PREFIX}SCROLL_TOP`);\n      if (storedScrollTop) {\n        container.scrollTop = Number(storedScrollTop);\n      }\n    }\n  }\n\n  function initTocScrollListener() {\n    const container = document.getElementById(TOC_SCROLL_CONTAINER_ID);\n    if (container) {\n      container.addEventListener('scroll', saveTocScrollTop);\n    }\n  }\n\n  function preventScrollBySpaceKey(event) {\n    if (event.key === ' ') {\n      event.preventDefault();\n      event.stopPropagation();\n    }\n  }\n\n  function resetTocState() {\n    const tocKeys = safeSessionStorage.getKeys();\n    tocKeys.forEach((key) => {\n      if (key.startsWith(TOC_STATE_KEY_PREFIX)) {\n        safeSessionStorage.removeItem(key);\n      }\n    });\n  }\n\n  function initLogoClickListener() {\n    const logo = document.querySelector('.library-name--link');\n    if (logo) {\n      logo.addEventListener('click', resetTocState);\n    }\n  }\n\n  /*\n    This is a work-around for safari being IE of our times.\n    It doesn't fire a DOMContentLoaded, presumably because eventListener is added after it wants to do it\n*/\n  if (document.readyState === 'loading') {\n    window.addEventListener('DOMContentLoaded', () => {\n      displayToc();\n      initTocScrollListener();\n      initLogoClickListener();\n    })\n  } else {\n    displayToc();\n    initTocScrollListener();\n    initLogoClickListener();\n  }\n})();\n\n\nfunction handleTocButtonClick(event, navId) {\n  const tocPart = document.getElementById(navId);\n  if (!tocPart) {\n    return;\n  }\n  tocPart.classList.toggle(TOC_PART_HIDDEN_CLASS);\n  const isExpandedTOCPart = !tocPart.classList.contains(TOC_PART_HIDDEN_CLASS);\n  const button = tocPart.querySelector('button');\n  button?.setAttribute(\"aria-expanded\", `${isExpandedTOCPart}`);\n  safeSessionStorage.setItem(`${TOC_STATE_KEY_PREFIX}${navId}`, `${isExpandedTOCPart}`);\n}\n"
  },
  {
    "path": "docs/scripts/pages.json",
    "content": "[{\"name\":\"BOTTOM\",\"description\":\"com.pushpal.jetlime.HorizontalAlignment.BOTTOM\",\"location\":\"jetlime/com.pushpal.jetlime/-horizontal-alignment/-b-o-t-t-o-m/index.html\",\"searchKeys\":[\"BOTTOM\",\"BOTTOM\",\"com.pushpal.jetlime.HorizontalAlignment.BOTTOM\"]},{\"name\":\"CENTER\",\"description\":\"com.pushpal.jetlime.PointPlacement.CENTER\",\"location\":\"jetlime/com.pushpal.jetlime/-point-placement/-c-e-n-t-e-r/index.html\",\"searchKeys\":[\"CENTER\",\"CENTER\",\"com.pushpal.jetlime.PointPlacement.CENTER\"]},{\"name\":\"END\",\"description\":\"com.pushpal.jetlime.PointPlacement.END\",\"location\":\"jetlime/com.pushpal.jetlime/-point-placement/-e-n-d/index.html\",\"searchKeys\":[\"END\",\"END\",\"com.pushpal.jetlime.PointPlacement.END\"]},{\"name\":\"LEFT\",\"description\":\"com.pushpal.jetlime.VerticalAlignment.LEFT\",\"location\":\"jetlime/com.pushpal.jetlime/-vertical-alignment/-l-e-f-t/index.html\",\"searchKeys\":[\"LEFT\",\"LEFT\",\"com.pushpal.jetlime.VerticalAlignment.LEFT\"]},{\"name\":\"RIGHT\",\"description\":\"com.pushpal.jetlime.VerticalAlignment.RIGHT\",\"location\":\"jetlime/com.pushpal.jetlime/-vertical-alignment/-r-i-g-h-t/index.html\",\"searchKeys\":[\"RIGHT\",\"RIGHT\",\"com.pushpal.jetlime.VerticalAlignment.RIGHT\"]},{\"name\":\"START\",\"description\":\"com.pushpal.jetlime.PointPlacement.START\",\"location\":\"jetlime/com.pushpal.jetlime/-point-placement/-s-t-a-r-t/index.html\",\"searchKeys\":[\"START\",\"START\",\"com.pushpal.jetlime.PointPlacement.START\"]},{\"name\":\"TOP\",\"description\":\"com.pushpal.jetlime.HorizontalAlignment.TOP\",\"location\":\"jetlime/com.pushpal.jetlime/-horizontal-alignment/-t-o-p/index.html\",\"searchKeys\":[\"TOP\",\"TOP\",\"com.pushpal.jetlime.HorizontalAlignment.TOP\"]},{\"name\":\"class EventPointAnimation\",\"description\":\"com.pushpal.jetlime.EventPointAnimation\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-animation/index.html\",\"searchKeys\":[\"EventPointAnimation\",\"class EventPointAnimation\",\"com.pushpal.jetlime.EventPointAnimation\"]},{\"name\":\"class EventPointType\",\"description\":\"com.pushpal.jetlime.EventPointType\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/index.html\",\"searchKeys\":[\"EventPointType\",\"class EventPointType\",\"com.pushpal.jetlime.EventPointType\"]},{\"name\":\"class EventPosition\",\"description\":\"com.pushpal.jetlime.EventPosition\",\"location\":\"jetlime/com.pushpal.jetlime/-event-position/index.html\",\"searchKeys\":[\"EventPosition\",\"class EventPosition\",\"com.pushpal.jetlime.EventPosition\"]},{\"name\":\"class ItemsList<T>(val items: List<T>)\",\"description\":\"com.pushpal.jetlime.ItemsList\",\"location\":\"jetlime/com.pushpal.jetlime/-items-list/index.html\",\"searchKeys\":[\"ItemsList\",\"class ItemsList<T>(val items: List<T>)\",\"com.pushpal.jetlime.ItemsList\"]},{\"name\":\"class JetLimeEventStyle\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/index.html\",\"searchKeys\":[\"JetLimeEventStyle\",\"class JetLimeEventStyle\",\"com.pushpal.jetlime.JetLimeEventStyle\"]},{\"name\":\"class JetLimeStyle\",\"description\":\"com.pushpal.jetlime.JetLimeStyle\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-style/index.html\",\"searchKeys\":[\"JetLimeStyle\",\"class JetLimeStyle\",\"com.pushpal.jetlime.JetLimeStyle\"]},{\"name\":\"constructor(items: List<T>)\",\"description\":\"com.pushpal.jetlime.ItemsList.ItemsList\",\"location\":\"jetlime/com.pushpal.jetlime/-items-list/-items-list.html\",\"searchKeys\":[\"ItemsList\",\"constructor(items: List<T>)\",\"com.pushpal.jetlime.ItemsList.ItemsList\"]},{\"name\":\"enum HorizontalAlignment : Enum<HorizontalAlignment> \",\"description\":\"com.pushpal.jetlime.HorizontalAlignment\",\"location\":\"jetlime/com.pushpal.jetlime/-horizontal-alignment/index.html\",\"searchKeys\":[\"HorizontalAlignment\",\"enum HorizontalAlignment : Enum<HorizontalAlignment> \",\"com.pushpal.jetlime.HorizontalAlignment\"]},{\"name\":\"enum PointPlacement : Enum<PointPlacement> \",\"description\":\"com.pushpal.jetlime.PointPlacement\",\"location\":\"jetlime/com.pushpal.jetlime/-point-placement/index.html\",\"searchKeys\":[\"PointPlacement\",\"enum PointPlacement : Enum<PointPlacement> \",\"com.pushpal.jetlime.PointPlacement\"]},{\"name\":\"enum VerticalAlignment : Enum<VerticalAlignment> \",\"description\":\"com.pushpal.jetlime.VerticalAlignment\",\"location\":\"jetlime/com.pushpal.jetlime/-vertical-alignment/index.html\",\"searchKeys\":[\"VerticalAlignment\",\"enum VerticalAlignment : Enum<VerticalAlignment> \",\"com.pushpal.jetlime.VerticalAlignment\"]},{\"name\":\"fun <T> JetLimeColumn(itemsList: ItemsList<T>, modifier: Modifier = Modifier, style: JetLimeStyle = JetLimeDefaults.columnStyle(), listState: LazyListState = rememberLazyListState(), contentPadding: PaddingValues = PaddingValues(0.dp), key: (index: Int, item: T) -> Any? = null, itemContent: (index: Int, T, EventPosition) -> Unit)\",\"description\":\"com.pushpal.jetlime.JetLimeColumn\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-column.html\",\"searchKeys\":[\"JetLimeColumn\",\"fun <T> JetLimeColumn(itemsList: ItemsList<T>, modifier: Modifier = Modifier, style: JetLimeStyle = JetLimeDefaults.columnStyle(), listState: LazyListState = rememberLazyListState(), contentPadding: PaddingValues = PaddingValues(0.dp), key: (index: Int, item: T) -> Any? = null, itemContent: (index: Int, T, EventPosition) -> Unit)\",\"com.pushpal.jetlime.JetLimeColumn\"]},{\"name\":\"fun <T> JetLimeRow(itemsList: ItemsList<T>, modifier: Modifier = Modifier, style: JetLimeStyle = JetLimeDefaults.rowStyle(), listState: LazyListState = rememberLazyListState(), contentPadding: PaddingValues = PaddingValues(0.dp), key: (index: Int, item: T) -> Any? = null, itemContent: (index: Int, T, EventPosition) -> Unit)\",\"description\":\"com.pushpal.jetlime.JetLimeRow\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-row.html\",\"searchKeys\":[\"JetLimeRow\",\"fun <T> JetLimeRow(itemsList: ItemsList<T>, modifier: Modifier = Modifier, style: JetLimeStyle = JetLimeDefaults.rowStyle(), listState: LazyListState = rememberLazyListState(), contentPadding: PaddingValues = PaddingValues(0.dp), key: (index: Int, item: T) -> Any? = null, itemContent: (index: Int, T, EventPosition) -> Unit)\",\"com.pushpal.jetlime.JetLimeRow\"]},{\"name\":\"fun JetLimeEvent(modifier: Modifier = Modifier, style: JetLimeEventStyle = JetLimeEventDefaults.eventStyle(EventPosition.END), content: () -> Unit)\",\"description\":\"com.pushpal.jetlime.JetLimeEvent\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event.html\",\"searchKeys\":[\"JetLimeEvent\",\"fun JetLimeEvent(modifier: Modifier = Modifier, style: JetLimeEventStyle = JetLimeEventDefaults.eventStyle(EventPosition.END), content: () -> Unit)\",\"com.pushpal.jetlime.JetLimeEvent\"]},{\"name\":\"fun JetLimeExtendedEvent(modifier: Modifier = Modifier, style: JetLimeEventStyle = JetLimeEventDefaults.eventStyle(EventPosition.END), additionalContent: BoxScope.() -> Unit = { }, additionalContentMaxWidth: Dp = AdditionalContentMaxWidth, content: () -> Unit)\",\"description\":\"com.pushpal.jetlime.JetLimeExtendedEvent\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-extended-event.html\",\"searchKeys\":[\"JetLimeExtendedEvent\",\"fun JetLimeExtendedEvent(modifier: Modifier = Modifier, style: JetLimeEventStyle = JetLimeEventDefaults.eventStyle(EventPosition.END), additionalContent: BoxScope.() -> Unit = { }, additionalContentMaxWidth: Dp = AdditionalContentMaxWidth, content: () -> Unit)\",\"com.pushpal.jetlime.JetLimeExtendedEvent\"]},{\"name\":\"fun columnStyle(contentDistance: Dp = ContentDistance, itemSpacing: Dp = ItemSpacing, lineThickness: Dp = LineThickness, lineBrush: Brush = lineSolidBrush(), pathEffect: PathEffect? = null, lineVerticalAlignment: VerticalAlignment = LEFT): JetLimeStyle\",\"description\":\"com.pushpal.jetlime.JetLimeDefaults.columnStyle\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-defaults/column-style.html\",\"searchKeys\":[\"columnStyle\",\"fun columnStyle(contentDistance: Dp = ContentDistance, itemSpacing: Dp = ItemSpacing, lineThickness: Dp = LineThickness, lineBrush: Brush = lineSolidBrush(), pathEffect: PathEffect? = null, lineVerticalAlignment: VerticalAlignment = LEFT): JetLimeStyle\",\"com.pushpal.jetlime.JetLimeDefaults.columnStyle\"]},{\"name\":\"fun custom(icon: Painter, tint: Color? = null): EventPointType\",\"description\":\"com.pushpal.jetlime.EventPointType.Companion.custom\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/-companion/custom.html\",\"searchKeys\":[\"custom\",\"fun custom(icon: Painter, tint: Color? = null): EventPointType\",\"com.pushpal.jetlime.EventPointType.Companion.custom\"]},{\"name\":\"fun dynamic(index: Int, listSize: Int): EventPosition\",\"description\":\"com.pushpal.jetlime.EventPosition.Companion.dynamic\",\"location\":\"jetlime/com.pushpal.jetlime/-event-position/-companion/dynamic.html\",\"searchKeys\":[\"dynamic\",\"fun dynamic(index: Int, listSize: Int): EventPosition\",\"com.pushpal.jetlime.EventPosition.Companion.dynamic\"]},{\"name\":\"fun eventStyle(position: EventPosition, pointPlacement: PointPlacement = PointPlacement.START, pointType: EventPointType = PointType, pointColor: Color = MaterialTheme.colorScheme.onPrimary, pointFillColor: Color = MaterialTheme.colorScheme.primary, pointRadius: Dp = PointRadius, pointAnimation: EventPointAnimation? = null, pointStrokeWidth: Dp = PointStrokeWidth, pointStrokeColor: Color = MaterialTheme.colorScheme.primary): JetLimeEventStyle\",\"description\":\"com.pushpal.jetlime.JetLimeEventDefaults.eventStyle\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-defaults/event-style.html\",\"searchKeys\":[\"eventStyle\",\"fun eventStyle(position: EventPosition, pointPlacement: PointPlacement = PointPlacement.START, pointType: EventPointType = PointType, pointColor: Color = MaterialTheme.colorScheme.onPrimary, pointFillColor: Color = MaterialTheme.colorScheme.primary, pointRadius: Dp = PointRadius, pointAnimation: EventPointAnimation? = null, pointStrokeWidth: Dp = PointStrokeWidth, pointStrokeColor: Color = MaterialTheme.colorScheme.primary): JetLimeEventStyle\",\"com.pushpal.jetlime.JetLimeEventDefaults.eventStyle\"]},{\"name\":\"fun filled(fillPercent: Float = 0.5f): EventPointType\",\"description\":\"com.pushpal.jetlime.EventPointType.Companion.filled\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/-companion/filled.html\",\"searchKeys\":[\"filled\",\"fun filled(fillPercent: Float = 0.5f): EventPointType\",\"com.pushpal.jetlime.EventPointType.Companion.filled\"]},{\"name\":\"fun isCustom(): Boolean\",\"description\":\"com.pushpal.jetlime.EventPointType.isCustom\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/is-custom.html\",\"searchKeys\":[\"isCustom\",\"fun isCustom(): Boolean\",\"com.pushpal.jetlime.EventPointType.isCustom\"]},{\"name\":\"fun isEmptyOrFilled(): Boolean\",\"description\":\"com.pushpal.jetlime.EventPointType.isEmptyOrFilled\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/is-empty-or-filled.html\",\"searchKeys\":[\"isEmptyOrFilled\",\"fun isEmptyOrFilled(): Boolean\",\"com.pushpal.jetlime.EventPointType.isEmptyOrFilled\"]},{\"name\":\"fun isFilled(): Boolean\",\"description\":\"com.pushpal.jetlime.EventPointType.isFilled\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/is-filled.html\",\"searchKeys\":[\"isFilled\",\"fun isFilled(): Boolean\",\"com.pushpal.jetlime.EventPointType.isFilled\"]},{\"name\":\"fun isNotEnd(): Boolean\",\"description\":\"com.pushpal.jetlime.EventPosition.isNotEnd\",\"location\":\"jetlime/com.pushpal.jetlime/-event-position/is-not-end.html\",\"searchKeys\":[\"isNotEnd\",\"fun isNotEnd(): Boolean\",\"com.pushpal.jetlime.EventPosition.isNotEnd\"]},{\"name\":\"fun isNotStart(): Boolean\",\"description\":\"com.pushpal.jetlime.EventPosition.isNotStart\",\"location\":\"jetlime/com.pushpal.jetlime/-event-position/is-not-start.html\",\"searchKeys\":[\"isNotStart\",\"fun isNotStart(): Boolean\",\"com.pushpal.jetlime.EventPosition.isNotStart\"]},{\"name\":\"fun lineGradientBrush(colors: ImmutableList<Color> = persistentListOf(\\n      MaterialTheme.colorScheme.primary,\\n      MaterialTheme.colorScheme.secondary,\\n      MaterialTheme.colorScheme.tertiary,\\n    ), start: Offset = Offset.Zero, end: Offset = Offset.Infinite, tileMode: TileMode = TileMode.Clamp): Brush\",\"description\":\"com.pushpal.jetlime.JetLimeDefaults.lineGradientBrush\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-defaults/line-gradient-brush.html\",\"searchKeys\":[\"lineGradientBrush\",\"fun lineGradientBrush(colors: ImmutableList<Color> = persistentListOf(\\n      MaterialTheme.colorScheme.primary,\\n      MaterialTheme.colorScheme.secondary,\\n      MaterialTheme.colorScheme.tertiary,\\n    ), start: Offset = Offset.Zero, end: Offset = Offset.Infinite, tileMode: TileMode = TileMode.Clamp): Brush\",\"com.pushpal.jetlime.JetLimeDefaults.lineGradientBrush\"]},{\"name\":\"fun lineSolidBrush(color: Color = MaterialTheme.colorScheme.primary): Brush\",\"description\":\"com.pushpal.jetlime.JetLimeDefaults.lineSolidBrush\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-defaults/line-solid-brush.html\",\"searchKeys\":[\"lineSolidBrush\",\"fun lineSolidBrush(color: Color = MaterialTheme.colorScheme.primary): Brush\",\"com.pushpal.jetlime.JetLimeDefaults.lineSolidBrush\"]},{\"name\":\"fun pointAnimation(initialValue: Float = 1.0f, targetValue: Float = 1.2f, animationSpec: InfiniteRepeatableSpec<Float> = PointAnimation): EventPointAnimation\",\"description\":\"com.pushpal.jetlime.JetLimeEventDefaults.pointAnimation\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-defaults/point-animation.html\",\"searchKeys\":[\"pointAnimation\",\"fun pointAnimation(initialValue: Float = 1.0f, targetValue: Float = 1.2f, animationSpec: InfiniteRepeatableSpec<Float> = PointAnimation): EventPointAnimation\",\"com.pushpal.jetlime.JetLimeEventDefaults.pointAnimation\"]},{\"name\":\"fun rowStyle(contentDistance: Dp = ContentDistance, itemSpacing: Dp = ItemSpacing, lineThickness: Dp = LineThickness, lineBrush: Brush = lineSolidBrush(), pathEffect: PathEffect? = null, lineHorizontalAlignment: HorizontalAlignment = TOP): JetLimeStyle\",\"description\":\"com.pushpal.jetlime.JetLimeDefaults.rowStyle\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-defaults/row-style.html\",\"searchKeys\":[\"rowStyle\",\"fun rowStyle(contentDistance: Dp = ContentDistance, itemSpacing: Dp = ItemSpacing, lineThickness: Dp = LineThickness, lineBrush: Brush = lineSolidBrush(), pathEffect: PathEffect? = null, lineHorizontalAlignment: HorizontalAlignment = TOP): JetLimeStyle\",\"com.pushpal.jetlime.JetLimeDefaults.rowStyle\"]},{\"name\":\"fun setPointPlacement(pointPlacement: PointPlacement): JetLimeEventStyle\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.setPointPlacement\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/set-point-placement.html\",\"searchKeys\":[\"setPointPlacement\",\"fun setPointPlacement(pointPlacement: PointPlacement): JetLimeEventStyle\",\"com.pushpal.jetlime.JetLimeEventStyle.setPointPlacement\"]},{\"name\":\"fun setPosition(position: EventPosition): JetLimeEventStyle\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.setPosition\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/set-position.html\",\"searchKeys\":[\"setPosition\",\"fun setPosition(position: EventPosition): JetLimeEventStyle\",\"com.pushpal.jetlime.JetLimeEventStyle.setPosition\"]},{\"name\":\"fun valueOf(value: String): HorizontalAlignment\",\"description\":\"com.pushpal.jetlime.HorizontalAlignment.valueOf\",\"location\":\"jetlime/com.pushpal.jetlime/-horizontal-alignment/value-of.html\",\"searchKeys\":[\"valueOf\",\"fun valueOf(value: String): HorizontalAlignment\",\"com.pushpal.jetlime.HorizontalAlignment.valueOf\"]},{\"name\":\"fun valueOf(value: String): PointPlacement\",\"description\":\"com.pushpal.jetlime.PointPlacement.valueOf\",\"location\":\"jetlime/com.pushpal.jetlime/-point-placement/value-of.html\",\"searchKeys\":[\"valueOf\",\"fun valueOf(value: String): PointPlacement\",\"com.pushpal.jetlime.PointPlacement.valueOf\"]},{\"name\":\"fun valueOf(value: String): VerticalAlignment\",\"description\":\"com.pushpal.jetlime.VerticalAlignment.valueOf\",\"location\":\"jetlime/com.pushpal.jetlime/-vertical-alignment/value-of.html\",\"searchKeys\":[\"valueOf\",\"fun valueOf(value: String): VerticalAlignment\",\"com.pushpal.jetlime.VerticalAlignment.valueOf\"]},{\"name\":\"fun values(): Array<HorizontalAlignment>\",\"description\":\"com.pushpal.jetlime.HorizontalAlignment.values\",\"location\":\"jetlime/com.pushpal.jetlime/-horizontal-alignment/values.html\",\"searchKeys\":[\"values\",\"fun values(): Array<HorizontalAlignment>\",\"com.pushpal.jetlime.HorizontalAlignment.values\"]},{\"name\":\"fun values(): Array<PointPlacement>\",\"description\":\"com.pushpal.jetlime.PointPlacement.values\",\"location\":\"jetlime/com.pushpal.jetlime/-point-placement/values.html\",\"searchKeys\":[\"values\",\"fun values(): Array<PointPlacement>\",\"com.pushpal.jetlime.PointPlacement.values\"]},{\"name\":\"fun values(): Array<VerticalAlignment>\",\"description\":\"com.pushpal.jetlime.VerticalAlignment.values\",\"location\":\"jetlime/com.pushpal.jetlime/-vertical-alignment/values.html\",\"searchKeys\":[\"values\",\"fun values(): Array<VerticalAlignment>\",\"com.pushpal.jetlime.VerticalAlignment.values\"]},{\"name\":\"object Companion\",\"description\":\"com.pushpal.jetlime.EventPointType.Companion\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/-companion/index.html\",\"searchKeys\":[\"Companion\",\"object Companion\",\"com.pushpal.jetlime.EventPointType.Companion\"]},{\"name\":\"object Companion\",\"description\":\"com.pushpal.jetlime.EventPosition.Companion\",\"location\":\"jetlime/com.pushpal.jetlime/-event-position/-companion/index.html\",\"searchKeys\":[\"Companion\",\"object Companion\",\"com.pushpal.jetlime.EventPosition.Companion\"]},{\"name\":\"object JetLimeDefaults\",\"description\":\"com.pushpal.jetlime.JetLimeDefaults\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-defaults/index.html\",\"searchKeys\":[\"JetLimeDefaults\",\"object JetLimeDefaults\",\"com.pushpal.jetlime.JetLimeDefaults\"]},{\"name\":\"object JetLimeEventDefaults\",\"description\":\"com.pushpal.jetlime.JetLimeEventDefaults\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-defaults/index.html\",\"searchKeys\":[\"JetLimeEventDefaults\",\"object JetLimeEventDefaults\",\"com.pushpal.jetlime.JetLimeEventDefaults\"]},{\"name\":\"open operator override fun equals(other: Any?): Boolean\",\"description\":\"com.pushpal.jetlime.EventPointAnimation.equals\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-animation/equals.html\",\"searchKeys\":[\"equals\",\"open operator override fun equals(other: Any?): Boolean\",\"com.pushpal.jetlime.EventPointAnimation.equals\"]},{\"name\":\"open operator override fun equals(other: Any?): Boolean\",\"description\":\"com.pushpal.jetlime.EventPointType.equals\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/equals.html\",\"searchKeys\":[\"equals\",\"open operator override fun equals(other: Any?): Boolean\",\"com.pushpal.jetlime.EventPointType.equals\"]},{\"name\":\"open operator override fun equals(other: Any?): Boolean\",\"description\":\"com.pushpal.jetlime.EventPosition.equals\",\"location\":\"jetlime/com.pushpal.jetlime/-event-position/equals.html\",\"searchKeys\":[\"equals\",\"open operator override fun equals(other: Any?): Boolean\",\"com.pushpal.jetlime.EventPosition.equals\"]},{\"name\":\"open operator override fun equals(other: Any?): Boolean\",\"description\":\"com.pushpal.jetlime.ItemsList.equals\",\"location\":\"jetlime/com.pushpal.jetlime/-items-list/equals.html\",\"searchKeys\":[\"equals\",\"open operator override fun equals(other: Any?): Boolean\",\"com.pushpal.jetlime.ItemsList.equals\"]},{\"name\":\"open operator override fun equals(other: Any?): Boolean\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.equals\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/equals.html\",\"searchKeys\":[\"equals\",\"open operator override fun equals(other: Any?): Boolean\",\"com.pushpal.jetlime.JetLimeEventStyle.equals\"]},{\"name\":\"open operator override fun equals(other: Any?): Boolean\",\"description\":\"com.pushpal.jetlime.JetLimeStyle.equals\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-style/equals.html\",\"searchKeys\":[\"equals\",\"open operator override fun equals(other: Any?): Boolean\",\"com.pushpal.jetlime.JetLimeStyle.equals\"]},{\"name\":\"open override fun hashCode(): Int\",\"description\":\"com.pushpal.jetlime.EventPointAnimation.hashCode\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-animation/hash-code.html\",\"searchKeys\":[\"hashCode\",\"open override fun hashCode(): Int\",\"com.pushpal.jetlime.EventPointAnimation.hashCode\"]},{\"name\":\"open override fun hashCode(): Int\",\"description\":\"com.pushpal.jetlime.EventPointType.hashCode\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/hash-code.html\",\"searchKeys\":[\"hashCode\",\"open override fun hashCode(): Int\",\"com.pushpal.jetlime.EventPointType.hashCode\"]},{\"name\":\"open override fun hashCode(): Int\",\"description\":\"com.pushpal.jetlime.EventPosition.hashCode\",\"location\":\"jetlime/com.pushpal.jetlime/-event-position/hash-code.html\",\"searchKeys\":[\"hashCode\",\"open override fun hashCode(): Int\",\"com.pushpal.jetlime.EventPosition.hashCode\"]},{\"name\":\"open override fun hashCode(): Int\",\"description\":\"com.pushpal.jetlime.ItemsList.hashCode\",\"location\":\"jetlime/com.pushpal.jetlime/-items-list/hash-code.html\",\"searchKeys\":[\"hashCode\",\"open override fun hashCode(): Int\",\"com.pushpal.jetlime.ItemsList.hashCode\"]},{\"name\":\"open override fun hashCode(): Int\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.hashCode\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/hash-code.html\",\"searchKeys\":[\"hashCode\",\"open override fun hashCode(): Int\",\"com.pushpal.jetlime.JetLimeEventStyle.hashCode\"]},{\"name\":\"open override fun hashCode(): Int\",\"description\":\"com.pushpal.jetlime.JetLimeStyle.hashCode\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-style/hash-code.html\",\"searchKeys\":[\"hashCode\",\"open override fun hashCode(): Int\",\"com.pushpal.jetlime.JetLimeStyle.hashCode\"]},{\"name\":\"val Default: EventPointType\",\"description\":\"com.pushpal.jetlime.EventPointType.Companion.Default\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/-companion/-default.html\",\"searchKeys\":[\"Default\",\"val Default: EventPointType\",\"com.pushpal.jetlime.EventPointType.Companion.Default\"]},{\"name\":\"val EMPTY: EventPointType\",\"description\":\"com.pushpal.jetlime.EventPointType.Companion.EMPTY\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/-companion/-e-m-p-t-y.html\",\"searchKeys\":[\"EMPTY\",\"val EMPTY: EventPointType\",\"com.pushpal.jetlime.EventPointType.Companion.EMPTY\"]},{\"name\":\"val LocalJetLimeStyle: ProvidableCompositionLocal<JetLimeStyle>\",\"description\":\"com.pushpal.jetlime.LocalJetLimeStyle\",\"location\":\"jetlime/com.pushpal.jetlime/-local-jet-lime-style.html\",\"searchKeys\":[\"LocalJetLimeStyle\",\"val LocalJetLimeStyle: ProvidableCompositionLocal<JetLimeStyle>\",\"com.pushpal.jetlime.LocalJetLimeStyle\"]},{\"name\":\"val animationSpec: InfiniteRepeatableSpec<Float>\",\"description\":\"com.pushpal.jetlime.EventPointAnimation.animationSpec\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-animation/animation-spec.html\",\"searchKeys\":[\"animationSpec\",\"val animationSpec: InfiniteRepeatableSpec<Float>\",\"com.pushpal.jetlime.EventPointAnimation.animationSpec\"]},{\"name\":\"val contentDistance: Dp\",\"description\":\"com.pushpal.jetlime.JetLimeStyle.contentDistance\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-style/content-distance.html\",\"searchKeys\":[\"contentDistance\",\"val contentDistance: Dp\",\"com.pushpal.jetlime.JetLimeStyle.contentDistance\"]},{\"name\":\"val entries: EnumEntries<HorizontalAlignment>\",\"description\":\"com.pushpal.jetlime.HorizontalAlignment.entries\",\"location\":\"jetlime/com.pushpal.jetlime/-horizontal-alignment/entries.html\",\"searchKeys\":[\"entries\",\"val entries: EnumEntries<HorizontalAlignment>\",\"com.pushpal.jetlime.HorizontalAlignment.entries\"]},{\"name\":\"val entries: EnumEntries<PointPlacement>\",\"description\":\"com.pushpal.jetlime.PointPlacement.entries\",\"location\":\"jetlime/com.pushpal.jetlime/-point-placement/entries.html\",\"searchKeys\":[\"entries\",\"val entries: EnumEntries<PointPlacement>\",\"com.pushpal.jetlime.PointPlacement.entries\"]},{\"name\":\"val entries: EnumEntries<VerticalAlignment>\",\"description\":\"com.pushpal.jetlime.VerticalAlignment.entries\",\"location\":\"jetlime/com.pushpal.jetlime/-vertical-alignment/entries.html\",\"searchKeys\":[\"entries\",\"val entries: EnumEntries<VerticalAlignment>\",\"com.pushpal.jetlime.VerticalAlignment.entries\"]},{\"name\":\"val fillPercent: Float?\",\"description\":\"com.pushpal.jetlime.EventPointType.fillPercent\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/fill-percent.html\",\"searchKeys\":[\"fillPercent\",\"val fillPercent: Float?\",\"com.pushpal.jetlime.EventPointType.fillPercent\"]},{\"name\":\"val icon: Painter?\",\"description\":\"com.pushpal.jetlime.EventPointType.icon\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/icon.html\",\"searchKeys\":[\"icon\",\"val icon: Painter?\",\"com.pushpal.jetlime.EventPointType.icon\"]},{\"name\":\"val initialValue: Float\",\"description\":\"com.pushpal.jetlime.EventPointAnimation.initialValue\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-animation/initial-value.html\",\"searchKeys\":[\"initialValue\",\"val initialValue: Float\",\"com.pushpal.jetlime.EventPointAnimation.initialValue\"]},{\"name\":\"val itemSpacing: Dp\",\"description\":\"com.pushpal.jetlime.JetLimeStyle.itemSpacing\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-style/item-spacing.html\",\"searchKeys\":[\"itemSpacing\",\"val itemSpacing: Dp\",\"com.pushpal.jetlime.JetLimeStyle.itemSpacing\"]},{\"name\":\"val items: List<T>\",\"description\":\"com.pushpal.jetlime.ItemsList.items\",\"location\":\"jetlime/com.pushpal.jetlime/-items-list/items.html\",\"searchKeys\":[\"items\",\"val items: List<T>\",\"com.pushpal.jetlime.ItemsList.items\"]},{\"name\":\"val lineBrush: Brush\",\"description\":\"com.pushpal.jetlime.JetLimeStyle.lineBrush\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-style/line-brush.html\",\"searchKeys\":[\"lineBrush\",\"val lineBrush: Brush\",\"com.pushpal.jetlime.JetLimeStyle.lineBrush\"]},{\"name\":\"val lineHorizontalAlignment: HorizontalAlignment\",\"description\":\"com.pushpal.jetlime.JetLimeStyle.lineHorizontalAlignment\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-style/line-horizontal-alignment.html\",\"searchKeys\":[\"lineHorizontalAlignment\",\"val lineHorizontalAlignment: HorizontalAlignment\",\"com.pushpal.jetlime.JetLimeStyle.lineHorizontalAlignment\"]},{\"name\":\"val lineThickness: Dp\",\"description\":\"com.pushpal.jetlime.JetLimeStyle.lineThickness\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-style/line-thickness.html\",\"searchKeys\":[\"lineThickness\",\"val lineThickness: Dp\",\"com.pushpal.jetlime.JetLimeStyle.lineThickness\"]},{\"name\":\"val lineVerticalAlignment: VerticalAlignment\",\"description\":\"com.pushpal.jetlime.JetLimeStyle.lineVerticalAlignment\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-style/line-vertical-alignment.html\",\"searchKeys\":[\"lineVerticalAlignment\",\"val lineVerticalAlignment: VerticalAlignment\",\"com.pushpal.jetlime.JetLimeStyle.lineVerticalAlignment\"]},{\"name\":\"val name: String\",\"description\":\"com.pushpal.jetlime.EventPosition.name\",\"location\":\"jetlime/com.pushpal.jetlime/-event-position/name.html\",\"searchKeys\":[\"name\",\"val name: String\",\"com.pushpal.jetlime.EventPosition.name\"]},{\"name\":\"val pathEffect: PathEffect?\",\"description\":\"com.pushpal.jetlime.JetLimeStyle.pathEffect\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-style/path-effect.html\",\"searchKeys\":[\"pathEffect\",\"val pathEffect: PathEffect?\",\"com.pushpal.jetlime.JetLimeStyle.pathEffect\"]},{\"name\":\"val pointAnimation: EventPointAnimation?\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.pointAnimation\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-animation.html\",\"searchKeys\":[\"pointAnimation\",\"val pointAnimation: EventPointAnimation?\",\"com.pushpal.jetlime.JetLimeEventStyle.pointAnimation\"]},{\"name\":\"val pointColor: Color\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.pointColor\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-color.html\",\"searchKeys\":[\"pointColor\",\"val pointColor: Color\",\"com.pushpal.jetlime.JetLimeEventStyle.pointColor\"]},{\"name\":\"val pointFillColor: Color\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.pointFillColor\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-fill-color.html\",\"searchKeys\":[\"pointFillColor\",\"val pointFillColor: Color\",\"com.pushpal.jetlime.JetLimeEventStyle.pointFillColor\"]},{\"name\":\"val pointRadius: Dp\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.pointRadius\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-radius.html\",\"searchKeys\":[\"pointRadius\",\"val pointRadius: Dp\",\"com.pushpal.jetlime.JetLimeEventStyle.pointRadius\"]},{\"name\":\"val pointStrokeColor: Color\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.pointStrokeColor\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-stroke-color.html\",\"searchKeys\":[\"pointStrokeColor\",\"val pointStrokeColor: Color\",\"com.pushpal.jetlime.JetLimeEventStyle.pointStrokeColor\"]},{\"name\":\"val pointStrokeWidth: Dp\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.pointStrokeWidth\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-stroke-width.html\",\"searchKeys\":[\"pointStrokeWidth\",\"val pointStrokeWidth: Dp\",\"com.pushpal.jetlime.JetLimeEventStyle.pointStrokeWidth\"]},{\"name\":\"val pointType: EventPointType\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.pointType\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-type.html\",\"searchKeys\":[\"pointType\",\"val pointType: EventPointType\",\"com.pushpal.jetlime.JetLimeEventStyle.pointType\"]},{\"name\":\"val targetValue: Float\",\"description\":\"com.pushpal.jetlime.EventPointAnimation.targetValue\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-animation/target-value.html\",\"searchKeys\":[\"targetValue\",\"val targetValue: Float\",\"com.pushpal.jetlime.EventPointAnimation.targetValue\"]},{\"name\":\"val tint: Color?\",\"description\":\"com.pushpal.jetlime.EventPointType.tint\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/tint.html\",\"searchKeys\":[\"tint\",\"val tint: Color?\",\"com.pushpal.jetlime.EventPointType.tint\"]},{\"name\":\"val type: String\",\"description\":\"com.pushpal.jetlime.EventPointType.type\",\"location\":\"jetlime/com.pushpal.jetlime/-event-point-type/type.html\",\"searchKeys\":[\"type\",\"val type: String\",\"com.pushpal.jetlime.EventPointType.type\"]},{\"name\":\"var pointPlacement: PointPlacement\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.pointPlacement\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/point-placement.html\",\"searchKeys\":[\"pointPlacement\",\"var pointPlacement: PointPlacement\",\"com.pushpal.jetlime.JetLimeEventStyle.pointPlacement\"]},{\"name\":\"var position: EventPosition\",\"description\":\"com.pushpal.jetlime.JetLimeEventStyle.position\",\"location\":\"jetlime/com.pushpal.jetlime/-jet-lime-event-style/position.html\",\"searchKeys\":[\"position\",\"var position: EventPosition\",\"com.pushpal.jetlime.JetLimeEventStyle.position\"]}]"
  },
  {
    "path": "docs/scripts/platform-content-handler.js",
    "content": "/*\n * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n */\n\nfilteringContext = {\n    dependencies: {},\n    restrictedDependencies: [],\n    activeFilters: []\n}\nlet highlightedAnchor;\nlet topNavbarOffset;\nlet sourcesetNotification;\n\nwindow.addEventListener('load', () => {\n    document.querySelectorAll(\"div[data-platform-hinted]\")\n        .forEach(elem => elem.addEventListener('click', (event) => togglePlatformDependent(event, elem)))\n    const filterSection = document.getElementById('filter-section')\n    if (filterSection) {\n        filterSection.addEventListener('click', (event) => filterButtonHandler(event))\n        initializeFiltering()\n    }\n    if (typeof initTabs === 'function') {\n        initTabs() // initTabs comes from ui-kit/tabs\n    }\n    handleAnchor()\n    topNavbarOffset = document.getElementById('navigation-wrapper')\n    darkModeSwitch()\n})\n\nconst darkModeSwitch = () => {\n    const localStorageKey = \"dokka-dark-mode\"\n    const storage = safeLocalStorage.getItem(localStorageKey)\n    const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches\n    const darkModeEnabled = storage ? JSON.parse(storage) : osDarkSchemePreferred\n    const element = document.getElementById(\"theme-toggle-button\")\n\n    // Notify external scripts about changing dark mode, runnable samples plugin depends on this\n    if (window.onDarkModeChanged) {\n        window.onDarkModeChanged(darkModeEnabled)\n    }\n\n    element.addEventListener('click', () => {\n        const enabledClasses = document.getElementsByTagName(\"html\")[0].classList\n        enabledClasses.toggle(\"theme-dark\")\n\n        //if previously we had saved dark theme then we set it to light as this is what we save in local storage\n        const darkModeEnabled = enabledClasses.contains(\"theme-dark\")\n        // Notify external scripts about changing dark mode, runnable samples plugin depends on this\n        if (window.onDarkModeChanged) {\n            window.onDarkModeChanged(darkModeEnabled)\n        }\n        safeLocalStorage.setItem(localStorageKey, JSON.stringify(darkModeEnabled))\n    })\n}\n\n// Hash change is needed in order to allow for linking inside the same page with anchors\n// If this is not present user is forced to refresh the site in order to use an anchor\nwindow.onhashchange = handleAnchor\n\nfunction scrollToElementInContent(element) {\n    const scrollToElement = () => document.getElementById('main').scrollTo({\n        top: element.offsetTop - topNavbarOffset.offsetHeight,\n        behavior: \"smooth\"\n    })\n\n    const waitAndScroll = () => {\n        setTimeout(() => {\n            if (topNavbarOffset) {\n                scrollToElement()\n            } else {\n                waitForScroll()\n            }\n        }, 50)\n    }\n\n    if (topNavbarOffset) {\n        scrollToElement()\n    } else {\n        waitAndScroll()\n    }\n}\n\n\nfunction handleAnchor() {\n    if (highlightedAnchor) {\n        highlightedAnchor.classList.remove('anchor-highlight')\n        highlightedAnchor = null;\n    }\n\n    let searchForContentTarget = function (element) {\n        if (element && element.hasAttribute) {\n            if (element.hasAttribute(\"data-togglable\")) return element.getAttribute(\"data-togglable\");\n            else return searchForContentTarget(element.parentNode)\n        } else return null\n    }\n\n    let findAnyTab = function (target) {\n    \tlet result = null\n        document.querySelectorAll('div[tabs-section] > button[data-togglable]')\n        .forEach(node => {\n            if(node.getAttribute(\"data-togglable\").split(\",\").includes(target)) {\n            \tresult = node\n            }\n        })\n        return result\n    }\n\n    let anchor = window.location.hash\n    if (anchor !== \"\") {\n        anchor = anchor.substring(1)\n        let element = document.querySelector('a[data-name=\"' + anchor + '\"]')\n\n        if (element) {\n            const content = element.nextElementSibling\n            const contentStyle = window.getComputedStyle(content)\n            if(contentStyle.display === 'none') {\n\t\t let tab = findAnyTab(searchForContentTarget(content))\n\t\t if (tab) {\n\t\t     toggleSections(tab) // toggleSections comes from ui-kit/tabs\n\t\t }\n            }\n\n            if (content) {\n                content.classList.add('anchor-highlight')\n                highlightedAnchor = content\n            }\n\n            scrollToElementInContent(element)\n        }\n    }\n}\n\nfunction filterButtonHandler(event) {\n    if (event.target.tagName === \"BUTTON\" && event.target.hasAttribute(\"data-filter\")) {\n        let sourceset = event.target.getAttribute(\"data-filter\")\n        if (filteringContext.activeFilters.indexOf(sourceset) !== -1) {\n            filterSourceset(sourceset)\n        } else {\n            unfilterSourceset(sourceset)\n        }\n    }\n}\n\nfunction initializeFiltering() {\n    filteringContext.dependencies = JSON.parse(sourceset_dependencies)\n    document.querySelectorAll(\"#filter-section > button\")\n        .forEach(p => filteringContext.restrictedDependencies.push(p.getAttribute(\"data-filter\")))\n    Object.keys(filteringContext.dependencies).forEach(p => {\n        filteringContext.dependencies[p] = filteringContext.dependencies[p]\n            .filter(q => -1 !== filteringContext.restrictedDependencies.indexOf(q))\n    })\n    let cached = safeLocalStorage.getItem('inactive-filters')\n    if (cached) {\n        let parsed = JSON.parse(cached)\n        filteringContext.activeFilters = filteringContext.restrictedDependencies\n            .filter(q => parsed.indexOf(q) === -1)\n    } else {\n        filteringContext.activeFilters = filteringContext.restrictedDependencies\n    }\n    refreshFiltering()\n}\n\nfunction filterSourceset(sourceset) {\n    filteringContext.activeFilters = filteringContext.activeFilters.filter(p => p !== sourceset)\n    refreshFiltering()\n    addSourcesetFilterToCache(sourceset)\n}\n\nfunction unfilterSourceset(sourceset) {\n    if (filteringContext.activeFilters.length === 0) {\n        filteringContext.activeFilters = filteringContext.dependencies[sourceset].concat([sourceset])\n        refreshFiltering()\n        filteringContext.dependencies[sourceset].concat([sourceset]).forEach(p => removeSourcesetFilterFromCache(p))\n    } else {\n        filteringContext.activeFilters.push(sourceset)\n        refreshFiltering()\n        removeSourcesetFilterFromCache(sourceset)\n    }\n\n}\n\nfunction addSourcesetFilterToCache(sourceset) {\n    let cached = safeLocalStorage.getItem('inactive-filters')\n    if (cached) {\n        let parsed = JSON.parse(cached)\n        safeLocalStorage.setItem('inactive-filters', JSON.stringify(parsed.concat([sourceset])))\n    } else {\n        safeLocalStorage.setItem('inactive-filters', JSON.stringify([sourceset]))\n    }\n}\n\nfunction removeSourcesetFilterFromCache(sourceset) {\n    let cached = safeLocalStorage.getItem('inactive-filters')\n    if (cached) {\n        let parsed = JSON.parse(cached)\n        safeLocalStorage.setItem('inactive-filters', JSON.stringify(parsed.filter(p => p !== sourceset)))\n    }\n}\n\nfunction refreshSourcesetsCache() {\n    safeLocalStorage.setItem('inactive-filters', JSON.stringify(filteringContext.restrictedDependencies.filter(p => -1 === filteringContext.activeFilters.indexOf(p))))\n}\n\n\nfunction togglePlatformDependent(e, container) {\n    let target = e.target\n    if (target.tagName !== 'BUTTON') return;\n    let index = target.getAttribute('data-toggle')\n\n    for (let child of container.children) {\n        if (child.hasAttribute('data-toggle-list')) {\n            for (let bm of child.children) {\n                if (bm === target) {\n                    bm.setAttribute('data-active', \"\")\n                    bm.setAttribute('aria-pressed', \"true\")\n                } else if (bm !== target) {\n                    bm.removeAttribute('data-active')\n                    bm.removeAttribute('aria-pressed')\n                }\n            }\n        } else if (child.getAttribute('data-togglable') === index) {\n            child.setAttribute('data-active', \"\")\n            child.setAttribute('aria-pressed', \"true\")\n        } else {\n            child.removeAttribute('data-active')\n            child.removeAttribute('aria-pressed')\n        }\n    }\n}\n\nfunction refreshFiltering() {\n    let sourcesetList = filteringContext.activeFilters\n    document.querySelectorAll(\"[data-filterable-set]\")\n        .forEach(\n            elem => {\n                let platformList = elem.getAttribute(\"data-filterable-set\").split(',').filter(v => -1 !== sourcesetList.indexOf(v))\n                elem.setAttribute(\"data-filterable-current\", platformList.join(','))\n            }\n        )\n    refreshFilterButtons()\n    refreshPlatformTabs()\n    refreshNoContentNotification()\n}\n\nfunction refreshNoContentNotification() {\n    const element = document.getElementsByClassName(\"main-content\")[0]\n    const filteredMessage = document.querySelector(\".filtered-message\")\n\n    if(filteringContext.activeFilters.length === 0){\n        element.style.display = \"none\";\n\n        if (!filteredMessage) {\n            const appended = document.createElement(\"div\")\n            appended.className = \"filtered-message\"\n            appended.innerText = \"All documentation is filtered, please adjust your source set filters in top-right corner of the screen\"\n            sourcesetNotification = appended\n            element.parentNode.prepend(appended)\n        }\n    } else {\n        if(sourcesetNotification) sourcesetNotification.remove()\n        element.style.display = \"block\"\n    }\n}\n\nfunction refreshPlatformTabs() {\n    document.querySelectorAll(\".platform-hinted > .platform-bookmarks-row\").forEach(\n        p => {\n            let active = false;\n            let firstAvailable = null\n            p.childNodes.forEach(\n                element => {\n                    if (element.getAttribute(\"data-filterable-current\") !== '') {\n                        if (firstAvailable === null) {\n                            firstAvailable = element\n                        }\n                        if (element.hasAttribute(\"data-active\")) {\n                            active = true;\n                        }\n                    }\n                }\n            )\n            if (active === false && firstAvailable) {\n                firstAvailable.click()\n            }\n        }\n    )\n}\n\nfunction refreshFilterButtons() {\n    document.querySelectorAll(\"#filter-section > button\")\n        .forEach(f => {\n            if (filteringContext.activeFilters.indexOf(f.getAttribute(\"data-filter\")) !== -1) {\n                f.setAttribute(\"data-active\", \"\")\n                f.setAttribute(\"aria-pressed\", \"true\")\n            } else {\n                f.removeAttribute(\"data-active\")\n                f.removeAttribute(\"aria-pressed\")\n            }\n        })\n    document.querySelectorAll(\"#filter-section .checkbox--input\")\n        .forEach(f => {\n            const isChecked = filteringContext.activeFilters.indexOf(f.getAttribute(\"data-filter\")) !== -1\n            f.checked = isChecked;\n            if (isChecked) {\n                f.setAttribute(\"aria-pressed\", \"true\")\n            } else {\n                f.removeAttribute(\"aria-pressed\");\n            }\n        })\n}\n"
  },
  {
    "path": "docs/scripts/prism.js",
    "content": "/* PrismJS 1.29.0\nhttps://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript+java+javadoc+javadoclike+kotlin&plugins=keep-markup */\nvar _self=\"undefined\"!=typeof window?window:\"undefined\"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var n=/(?:^|\\s)lang(?:uage)?-([\\w-]+)(?=\\s|$)/i,t=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof i?new i(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/\\u00a0/g,\" \")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,\"__id\",{value:++t}),e.__id},clone:function e(n,t){var r,i;switch(t=t||{},a.util.type(n)){case\"Object\":if(i=a.util.objId(n),t[i])return t[i];for(var l in r={},t[i]=r,n)n.hasOwnProperty(l)&&(r[l]=e(n[l],t));return r;case\"Array\":return i=a.util.objId(n),t[i]?t[i]:(r=[],t[i]=r,n.forEach((function(n,a){r[a]=e(n,t)})),r);default:return n}},getLanguage:function(e){for(;e;){var t=n.exec(e.className);if(t)return t[1].toLowerCase();e=e.parentElement}return\"none\"},setLanguage:function(e,t){e.className=e.className.replace(RegExp(n,\"gi\"),\"\"),e.classList.add(\"language-\"+t)},currentScript:function(){if(\"undefined\"==typeof document)return null;if(\"currentScript\"in document)return document.currentScript;try{throw new Error}catch(r){var e=(/at [^(\\r\\n]*\\((.*):[^:]+:[^:]+\\)$/i.exec(r.stack)||[])[1];if(e){var n=document.getElementsByTagName(\"script\");for(var t in n)if(n[t].src==e)return n[t]}return null}},isActive:function(e,n,t){for(var r=\"no-\"+n;e;){var a=e.classList;if(a.contains(n))return!0;if(a.contains(r))return!1;e=e.parentElement}return!!t}},languages:{plain:r,plaintext:r,text:r,txt:r,extend:function(e,n){var t=a.util.clone(a.languages[e]);for(var r in n)t[r]=n[r];return t},insertBefore:function(e,n,t,r){var i=(r=r||a.languages)[e],l={};for(var o in i)if(i.hasOwnProperty(o)){if(o==n)for(var s in t)t.hasOwnProperty(s)&&(l[s]=t[s]);t.hasOwnProperty(o)||(l[o]=i[o])}var u=r[e];return r[e]=l,a.languages.DFS(a.languages,(function(n,t){t===u&&n!=e&&(this[n]=l)})),l},DFS:function e(n,t,r,i){i=i||{};var l=a.util.objId;for(var o in n)if(n.hasOwnProperty(o)){t.call(n,o,n[o],r||o);var s=n[o],u=a.util.type(s);\"Object\"!==u||i[l(s)]?\"Array\"!==u||i[l(s)]||(i[l(s)]=!0,e(s,t,o,i)):(i[l(s)]=!0,e(s,t,null,i))}}},plugins:{},highlightAll:function(e,n){a.highlightAllUnder(document,e,n)},highlightAllUnder:function(e,n,t){var r={callback:t,container:e,selector:'code[class*=\"language-\"], [class*=\"language-\"] code, code[class*=\"lang-\"], [class*=\"lang-\"] code'};a.hooks.run(\"before-highlightall\",r),r.elements=Array.prototype.slice.apply(r.container.querySelectorAll(r.selector)),a.hooks.run(\"before-all-elements-highlight\",r);for(var i,l=0;i=r.elements[l++];)a.highlightElement(i,!0===n,r.callback)},highlightElement:function(n,t,r){var i=a.util.getLanguage(n),l=a.languages[i];a.util.setLanguage(n,i);var o=n.parentElement;o&&\"pre\"===o.nodeName.toLowerCase()&&a.util.setLanguage(o,i);var s={element:n,language:i,grammar:l,code:n.textContent};function u(e){s.highlightedCode=e,a.hooks.run(\"before-insert\",s),s.element.innerHTML=s.highlightedCode,a.hooks.run(\"after-highlight\",s),a.hooks.run(\"complete\",s),r&&r.call(s.element)}if(a.hooks.run(\"before-sanity-check\",s),(o=s.element.parentElement)&&\"pre\"===o.nodeName.toLowerCase()&&!o.hasAttribute(\"tabindex\")&&o.setAttribute(\"tabindex\",\"0\"),!s.code)return a.hooks.run(\"complete\",s),void(r&&r.call(s.element));if(a.hooks.run(\"before-highlight\",s),s.grammar)if(t&&e.Worker){var c=new Worker(a.filename);c.onmessage=function(e){u(e.data)},c.postMessage(JSON.stringify({language:s.language,code:s.code,immediateClose:!0}))}else u(a.highlight(s.code,s.grammar,s.language));else u(a.util.encode(s.code))},highlight:function(e,n,t){var r={code:e,grammar:n,language:t};if(a.hooks.run(\"before-tokenize\",r),!r.grammar)throw new Error('The language \"'+r.language+'\" has no grammar.');return r.tokens=a.tokenize(r.code,r.grammar),a.hooks.run(\"after-tokenize\",r),i.stringify(a.util.encode(r.tokens),r.language)},tokenize:function(e,n){var t=n.rest;if(t){for(var r in t)n[r]=t[r];delete n.rest}var a=new s;return u(a,a.head,e),o(e,a,n,a.head,0),function(e){for(var n=[],t=e.head.next;t!==e.tail;)n.push(t.value),t=t.next;return n}(a)},hooks:{all:{},add:function(e,n){var t=a.hooks.all;t[e]=t[e]||[],t[e].push(n)},run:function(e,n){var t=a.hooks.all[e];if(t&&t.length)for(var r,i=0;r=t[i++];)r(n)}},Token:i};function i(e,n,t,r){this.type=e,this.content=n,this.alias=t,this.length=0|(r||\"\").length}function l(e,n,t,r){e.lastIndex=n;var a=e.exec(t);if(a&&r&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function o(e,n,t,r,s,g){for(var f in t)if(t.hasOwnProperty(f)&&t[f]){var h=t[f];h=Array.isArray(h)?h:[h];for(var d=0;d<h.length;++d){if(g&&g.cause==f+\",\"+d)return;var v=h[d],p=v.inside,m=!!v.lookbehind,y=!!v.greedy,k=v.alias;if(y&&!v.pattern.global){var x=v.pattern.toString().match(/[imsuy]*$/)[0];v.pattern=RegExp(v.pattern.source,x+\"g\")}for(var b=v.pattern||v,w=r.next,A=s;w!==n.tail&&!(g&&A>=g.reach);A+=w.value.length,w=w.next){var E=w.value;if(n.length>e.length)return;if(!(E instanceof i)){var P,L=1;if(y){if(!(P=l(b,A,e,m))||P.index>=e.length)break;var S=P.index,O=P.index+P[0].length,j=A;for(j+=w.value.length;S>=j;)j+=(w=w.next).value.length;if(A=j-=w.value.length,w.value instanceof i)continue;for(var C=w;C!==n.tail&&(j<O||\"string\"==typeof C.value);C=C.next)L++,j+=C.value.length;L--,E=e.slice(A,j),P.index-=A}else if(!(P=l(b,0,E,m)))continue;S=P.index;var N=P[0],_=E.slice(0,S),M=E.slice(S+N.length),W=A+E.length;g&&W>g.reach&&(g.reach=W);var z=w.prev;if(_&&(z=u(n,z,_),A+=_.length),c(n,z,L),w=u(n,z,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),L>1){var I={cause:f+\",\"+d,reach:W};o(e,n,t,w.prev,A,I),g&&I.reach>g.reach&&(g.reach=I.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a<t&&r!==e.tail;a++)r=r.next;n.next=r,r.prev=n,e.length-=a}if(e.Prism=a,i.stringify=function e(n,t){if(\"string\"==typeof n)return n;if(Array.isArray(n)){var r=\"\";return n.forEach((function(n){r+=e(n,t)})),r}var i={type:n.type,content:e(n.content,t),tag:\"span\",classes:[\"token\",n.type],attributes:{},language:t},l=n.alias;l&&(Array.isArray(l)?Array.prototype.push.apply(i.classes,l):i.classes.push(l)),a.hooks.run(\"wrap\",i);var o=\"\";for(var s in i.attributes)o+=\" \"+s+'=\"'+(i.attributes[s]||\"\").replace(/\"/g,\"&quot;\")+'\"';return\"<\"+i.tag+' class=\"'+i.classes.join(\" \")+'\"'+o+\">\"+i.content+\"</\"+i.tag+\">\"},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener(\"message\",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute(\"data-manual\")&&(a.manual=!0)),!a.manual){var h=document.readyState;\"loading\"===h||\"interactive\"===h&&g&&g.defer?document.addEventListener(\"DOMContentLoaded\",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);\"undefined\"!=typeof module&&module.exports&&(module.exports=Prism),\"undefined\"!=typeof global&&(global.Prism=Prism);\nPrism.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\\s\\S])*?-->/,greedy:!0},prolog:{pattern:/<\\?[\\s\\S]+?\\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>\"'[\\]]|\"[^\"]*\"|'[^']*')+(?:\\[(?:[^<\"'\\]]|\"[^\"]*\"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\\]\\s*)?>/i,greedy:!0,inside:{\"internal-subset\":{pattern:/(^[^\\[]*\\[)[\\s\\S]+(?=\\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/\"[^\"]*\"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\\]]/,\"doctype-tag\":/^DOCTYPE/i,name:/[^\\s<>'\"]+/}},cdata:{pattern:/<!\\[CDATA\\[[\\s\\S]*?\\]\\]>/i,greedy:!0},tag:{pattern:/<\\/?(?!\\d)[^\\s>\\/=$<%]+(?:\\s(?:\\s*[^\\s>\\/=]+(?:\\s*=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+(?=[\\s>]))|(?=[\\s/>])))+)?\\s*\\/?>/,greedy:!0,inside:{tag:{pattern:/^<\\/?[^\\s>\\/]+/,inside:{punctuation:/^<\\/?/,namespace:/^[^\\s>\\/:]+:/}},\"special-attr\":[],\"attr-value\":{pattern:/=\\s*(?:\"[^\"]*\"|'[^']*'|[^\\s'\">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:\"attr-equals\"},{pattern:/^(\\s*)[\"']|[\"']$/,lookbehind:!0}]}},punctuation:/\\/?>/,\"attr-name\":{pattern:/[^\\s>\\/]+/,inside:{namespace:/^[^\\s>\\/:]+:/}}}},entity:[{pattern:/&[\\da-z]{1,8};/i,alias:\"named-entity\"},/&#x?[\\da-f]{1,8};/i]},Prism.languages.markup.tag.inside[\"attr-value\"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside[\"internal-subset\"].inside=Prism.languages.markup,Prism.hooks.add(\"wrap\",(function(a){\"entity\"===a.type&&(a.attributes.title=a.content.replace(/&amp;/,\"&\"))})),Object.defineProperty(Prism.languages.markup.tag,\"addInlined\",{value:function(a,e){var s={};s[\"language-\"+e]={pattern:/(^<!\\[CDATA\\[)[\\s\\S]+?(?=\\]\\]>$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^<!\\[CDATA\\[|\\]\\]>$/i;var t={\"included-cdata\":{pattern:/<!\\[CDATA\\[[\\s\\S]*?\\]\\]>/i,inside:s}};t[\"language-\"+e]={pattern:/[\\s\\S]+/,inside:Prism.languages[e]};var n={};n[a]={pattern:RegExp(\"(<__[^>]*>)(?:<!\\\\[CDATA\\\\[(?:[^\\\\]]|\\\\](?!\\\\]>))*\\\\]\\\\]>|(?!<!\\\\[CDATA\\\\[)[^])*?(?=</__>)\".replace(/__/g,(function(){return a})),\"i\"),lookbehind:!0,greedy:!0,inside:t},Prism.languages.insertBefore(\"markup\",\"cdata\",n)}}),Object.defineProperty(Prism.languages.markup.tag,\"addAttribute\",{value:function(a,e){Prism.languages.markup.tag.inside[\"special-attr\"].push({pattern:RegExp(\"(^|[\\\"'\\\\s])(?:\"+a+\")\\\\s*=\\\\s*(?:\\\"[^\\\"]*\\\"|'[^']*'|[^\\\\s'\\\">=]+(?=[\\\\s>]))\",\"i\"),lookbehind:!0,inside:{\"attr-name\":/^[^\\s=]+/,\"attr-value\":{pattern:/=[\\s\\S]+/,inside:{value:{pattern:/(^=\\s*([\"']|(?![\"'])))\\S[\\s\\S]*(?=\\2$)/,lookbehind:!0,alias:[e,\"language-\"+e],inside:Prism.languages[e]},punctuation:[{pattern:/^=/,alias:\"attr-equals\"},/\"|'/]}}}})}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend(\"markup\",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml;\n!function(s){var e=/(?:\"(?:\\\\(?:\\r\\n|[\\s\\S])|[^\"\\\\\\r\\n])*\"|'(?:\\\\(?:\\r\\n|[\\s\\S])|[^'\\\\\\r\\n])*')/;s.languages.css={comment:/\\/\\*[\\s\\S]*?\\*\\//,atrule:{pattern:RegExp(\"@[\\\\w-](?:[^;{\\\\s\\\"']|\\\\s+(?!\\\\s)|\"+e.source+\")*?(?:;|(?=\\\\s*\\\\{))\"),inside:{rule:/^@[\\w-]+/,\"selector-function-argument\":{pattern:/(\\bselector\\s*\\(\\s*(?![\\s)]))(?:[^()\\s]|\\s+(?![\\s)])|\\((?:[^()]|\\([^()]*\\))*\\))+(?=\\s*\\))/,lookbehind:!0,alias:\"selector\"},keyword:{pattern:/(^|[^\\w-])(?:and|not|only|or)(?![\\w-])/,lookbehind:!0}}},url:{pattern:RegExp(\"\\\\burl\\\\((?:\"+e.source+\"|(?:[^\\\\\\\\\\r\\n()\\\"']|\\\\\\\\[^])*)\\\\)\",\"i\"),greedy:!0,inside:{function:/^url/i,punctuation:/^\\(|\\)$/,string:{pattern:RegExp(\"^\"+e.source+\"$\"),alias:\"url\"}}},selector:{pattern:RegExp(\"(^|[{}\\\\s])[^{}\\\\s](?:[^{};\\\"'\\\\s]|\\\\s+(?![\\\\s{])|\"+e.source+\")*(?=\\\\s*\\\\{)\"),lookbehind:!0},string:{pattern:e,greedy:!0},property:{pattern:/(^|[^-\\w\\xA0-\\uFFFF])(?!\\s)[-_a-z\\xA0-\\uFFFF](?:(?!\\s)[-\\w\\xA0-\\uFFFF])*(?=\\s*:)/i,lookbehind:!0},important:/!important\\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\\()/i,lookbehind:!0},punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined(\"style\",\"css\"),t.tag.addAttribute(\"style\",\"css\"))}(Prism);\nPrism.languages.clike={comment:[{pattern:/(^|[^\\\\])\\/\\*[\\s\\S]*?(?:\\*\\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\\\:])\\/\\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/([\"'])(?:\\\\(?:\\r\\n|[\\s\\S])|(?!\\1)[^\\\\\\r\\n])*\\1/,greedy:!0},\"class-name\":{pattern:/(\\b(?:class|extends|implements|instanceof|interface|new|trait)\\s+|\\bcatch\\s+\\()[\\w.\\\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\\\]/}},keyword:/\\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\\b/,boolean:/\\b(?:false|true)\\b/,function:/\\b\\w+(?=\\()/,number:/\\b0x[\\da-f]+\\b|(?:\\b\\d+(?:\\.\\d*)?|\\B\\.\\d+)(?:e[+-]?\\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\\+\\+?|&&?|\\|\\|?|[?*/~^%]/,punctuation:/[{}[\\];(),.:]/};\nPrism.languages.javascript=Prism.languages.extend(\"clike\",{\"class-name\":[Prism.languages.clike[\"class-name\"],{pattern:/(^|[^$\\w\\xA0-\\uFFFF])(?!\\s)[_$A-Z\\xA0-\\uFFFF](?:(?!\\s)[$\\w\\xA0-\\uFFFF])*(?=\\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\\})\\s*)catch\\b/,lookbehind:!0},{pattern:/(^|[^.]|\\.\\.\\.\\s*)\\b(?:as|assert(?=\\s*\\{)|async(?=\\s*(?:function\\b|\\(|[$\\w\\xA0-\\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\\s*(?:\\{|$))|for|from(?=\\s*(?:['\"]|$))|function|(?:get|set)(?=\\s*(?:[#\\[$\\w\\xA0-\\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\\b/,lookbehind:!0}],function:/#?(?!\\s)[_$a-zA-Z\\xA0-\\uFFFF](?:(?!\\s)[$\\w\\xA0-\\uFFFF])*(?=\\s*(?:\\.\\s*(?:apply|bind|call)\\s*)?\\()/,number:{pattern:RegExp(\"(^|[^\\\\w$])(?:NaN|Infinity|0[bB][01]+(?:_[01]+)*n?|0[oO][0-7]+(?:_[0-7]+)*n?|0[xX][\\\\dA-Fa-f]+(?:_[\\\\dA-Fa-f]+)*n?|\\\\d+(?:_\\\\d+)*n|(?:\\\\d+(?:_\\\\d+)*(?:\\\\.(?:\\\\d+(?:_\\\\d+)*)?)?|\\\\.\\\\d+(?:_\\\\d+)*)(?:[Ee][+-]?\\\\d+(?:_\\\\d+)*)?)(?![\\\\w$])\"),lookbehind:!0},operator:/--|\\+\\+|\\*\\*=?|=>|&&=?|\\|\\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\\.{3}|\\?\\?=?|\\?\\.?|[~:]/}),Prism.languages.javascript[\"class-name\"][0].pattern=/(\\b(?:class|extends|implements|instanceof|interface|new)\\s+)[\\w.\\\\]+/,Prism.languages.insertBefore(\"javascript\",\"keyword\",{regex:{pattern:RegExp(\"((?:^|[^$\\\\w\\\\xA0-\\\\uFFFF.\\\"'\\\\])\\\\s]|\\\\b(?:return|yield))\\\\s*)/(?:(?:\\\\[(?:[^\\\\]\\\\\\\\\\r\\n]|\\\\\\\\.)*\\\\]|\\\\\\\\.|[^/\\\\\\\\\\\\[\\r\\n])+/[dgimyus]{0,7}|(?:\\\\[(?:[^[\\\\]\\\\\\\\\\r\\n]|\\\\\\\\.|\\\\[(?:[^[\\\\]\\\\\\\\\\r\\n]|\\\\\\\\.|\\\\[(?:[^[\\\\]\\\\\\\\\\r\\n]|\\\\\\\\.)*\\\\])*\\\\])*\\\\]|\\\\\\\\.|[^/\\\\\\\\\\\\[\\r\\n])+/[dgimyus]{0,7}v[dgimyus]{0,7})(?=(?:\\\\s|/\\\\*(?:[^*]|\\\\*(?!/))*\\\\*/)*(?:$|[\\r\\n,.;:})\\\\]]|//))\"),lookbehind:!0,greedy:!0,inside:{\"regex-source\":{pattern:/^(\\/)[\\s\\S]+(?=\\/[a-z]*$)/,lookbehind:!0,alias:\"language-regex\",inside:Prism.languages.regex},\"regex-delimiter\":/^\\/|\\/$/,\"regex-flags\":/^[a-z]+$/}},\"function-variable\":{pattern:/#?(?!\\s)[_$a-zA-Z\\xA0-\\uFFFF](?:(?!\\s)[$\\w\\xA0-\\uFFFF])*(?=\\s*[=:]\\s*(?:async\\s*)?(?:\\bfunction\\b|(?:\\((?:[^()]|\\([^()]*\\))*\\)|(?!\\s)[_$a-zA-Z\\xA0-\\uFFFF](?:(?!\\s)[$\\w\\xA0-\\uFFFF])*)\\s*=>))/,alias:\"function\"},parameter:[{pattern:/(function(?:\\s+(?!\\s)[_$a-zA-Z\\xA0-\\uFFFF](?:(?!\\s)[$\\w\\xA0-\\uFFFF])*)?\\s*\\(\\s*)(?!\\s)(?:[^()\\s]|\\s+(?![\\s)])|\\([^()]*\\))+(?=\\s*\\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(^|[^$\\w\\xA0-\\uFFFF])(?!\\s)[_$a-z\\xA0-\\uFFFF](?:(?!\\s)[$\\w\\xA0-\\uFFFF])*(?=\\s*=>)/i,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(\\(\\s*)(?!\\s)(?:[^()\\s]|\\s+(?![\\s)])|\\([^()]*\\))+(?=\\s*\\)\\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\\b|\\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\\w\\xA0-\\uFFFF]))(?:(?!\\s)[_$a-zA-Z\\xA0-\\uFFFF](?:(?!\\s)[$\\w\\xA0-\\uFFFF])*\\s*)\\(\\s*|\\]\\s*\\(\\s*)(?!\\s)(?:[^()\\s]|\\s+(?![\\s)])|\\([^()]*\\))+(?=\\s*\\)\\s*\\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\\b[A-Z](?:[A-Z_]|\\dx?)*\\b/}),Prism.languages.insertBefore(\"javascript\",\"string\",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:\"comment\"},\"template-string\":{pattern:/`(?:\\\\[\\s\\S]|\\$\\{(?:[^{}]|\\{(?:[^{}]|\\{[^}]*\\})*\\})+\\}|(?!\\$\\{)[^\\\\`])*`/,greedy:!0,inside:{\"template-punctuation\":{pattern:/^`|`$/,alias:\"string\"},interpolation:{pattern:/((?:^|[^\\\\])(?:\\\\{2})*)\\$\\{(?:[^{}]|\\{(?:[^{}]|\\{[^}]*\\})*\\})+\\}/,lookbehind:!0,inside:{\"interpolation-punctuation\":{pattern:/^\\$\\{|\\}$/,alias:\"punctuation\"},rest:Prism.languages.javascript}},string:/[\\s\\S]+/}},\"string-property\":{pattern:/((?:^|[,{])[ \\t]*)([\"'])(?:\\\\(?:\\r\\n|[\\s\\S])|(?!\\2)[^\\\\\\r\\n])*\\2(?=\\s*:)/m,lookbehind:!0,greedy:!0,alias:\"property\"}}),Prism.languages.insertBefore(\"javascript\",\"operator\",{\"literal-property\":{pattern:/((?:^|[,{])[ \\t]*)(?!\\s)[_$a-zA-Z\\xA0-\\uFFFF](?:(?!\\s)[$\\w\\xA0-\\uFFFF])*(?=\\s*:)/m,lookbehind:!0,alias:\"property\"}}),Prism.languages.markup&&(Prism.languages.markup.tag.addInlined(\"script\",\"javascript\"),Prism.languages.markup.tag.addAttribute(\"on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)\",\"javascript\")),Prism.languages.js=Prism.languages.javascript;\n!function(e){var n=/\\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\\s*[(){}[\\]<>=%~.:,;?+\\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\\b/,t=\"(?:[a-z]\\\\w*\\\\s*\\\\.\\\\s*)*(?:[A-Z]\\\\w*\\\\s*\\\\.\\\\s*)*\",s={pattern:RegExp(\"(^|[^\\\\w.])\"+t+\"[A-Z](?:[\\\\d_A-Z]*[a-z]\\\\w*)?\\\\b\"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\\w*(?:\\s*\\.\\s*[a-z]\\w*)*(?:\\s*\\.)?/,inside:{punctuation:/\\./}},punctuation:/\\./}};e.languages.java=e.languages.extend(\"clike\",{string:{pattern:/(^|[^\\\\])\"(?:\\\\.|[^\"\\\\\\r\\n])*\"/,lookbehind:!0,greedy:!0},\"class-name\":[s,{pattern:RegExp(\"(^|[^\\\\w.])\"+t+\"[A-Z]\\\\w*(?=\\\\s+\\\\w+\\\\s*[;,=()]|\\\\s*(?:\\\\[[\\\\s,]*\\\\]\\\\s*)?::\\\\s*new\\\\b)\"),lookbehind:!0,inside:s.inside},{pattern:RegExp(\"(\\\\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\\\\s+)\"+t+\"[A-Z]\\\\w*\\\\b\"),lookbehind:!0,inside:s.inside}],keyword:n,function:[e.languages.clike.function,{pattern:/(::\\s*)[a-z_]\\w*/,lookbehind:!0}],number:/\\b0b[01][01_]*L?\\b|\\b0x(?:\\.[\\da-f_p+-]+|[\\da-f_]+(?:\\.[\\da-f_p+-]+)?)\\b|(?:\\b\\d[\\d_]*(?:\\.[\\d_]*)?|\\B\\.\\d[\\d_]*)(?:e[+-]?\\d[\\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\\+\\+|&&|\\|\\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\\b[A-Z][A-Z_\\d]+\\b/}),e.languages.insertBefore(\"java\",\"string\",{\"triple-quoted-string\":{pattern:/\"\"\"[ \\t]*[\\r\\n](?:(?:\"|\"\")?(?:\\\\.|[^\"\\\\]))*\"\"\"/,greedy:!0,alias:\"string\"},char:{pattern:/'(?:\\\\.|[^'\\\\\\r\\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore(\"java\",\"class-name\",{annotation:{pattern:/(^|[^.])@\\w+(?:\\s*\\.\\s*\\w+)*/,lookbehind:!0,alias:\"punctuation\"},generics:{pattern:/<(?:[\\w\\s,.?]|&(?!&)|<(?:[\\w\\s,.?]|&(?!&)|<(?:[\\w\\s,.?]|&(?!&)|<(?:[\\w\\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{\"class-name\":s,keyword:n,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(\"(\\\\bimport\\\\s+)\"+t+\"(?:[A-Z]\\\\w*|\\\\*)(?=\\\\s*;)\"),lookbehind:!0,inside:{namespace:s.inside.namespace,punctuation:/\\./,operator:/\\*/,\"class-name\":/\\w+/}},{pattern:RegExp(\"(\\\\bimport\\\\s+static\\\\s+)\"+t+\"(?:\\\\w+|\\\\*)(?=\\\\s*;)\"),lookbehind:!0,alias:\"static\",inside:{namespace:s.inside.namespace,static:/\\b\\w+$/,punctuation:/\\./,operator:/\\*/,\"class-name\":/\\w+/}}],namespace:{pattern:RegExp(\"(\\\\b(?:exports|import(?:\\\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\\\s+)(?!<keyword>)[a-z]\\\\w*(?:\\\\.[a-z]\\\\w*)*\\\\.?\".replace(/<keyword>/g,(function(){return n.source}))),lookbehind:!0,inside:{punctuation:/\\./}}})}(Prism);\n!function(a){var e=a.languages.javadoclike={parameter:{pattern:/(^[\\t ]*(?:\\/{3}|\\*|\\/\\*\\*)\\s*@(?:arg|arguments|param)\\s+)\\w+/m,lookbehind:!0},keyword:{pattern:/(^[\\t ]*(?:\\/{3}|\\*|\\/\\*\\*)\\s*|\\{)@[a-z][a-zA-Z-]+\\b/m,lookbehind:!0},punctuation:/[{}]/};Object.defineProperty(e,\"addSupport\",{value:function(e,n){\"string\"==typeof e&&(e=[e]),e.forEach((function(e){!function(e,n){var t=\"doc-comment\",r=a.languages[e];if(r){var o=r[t];if(o||(o=(r=a.languages.insertBefore(e,\"comment\",{\"doc-comment\":{pattern:/(^|[^\\\\])\\/\\*\\*[^/][\\s\\S]*?(?:\\*\\/|$)/,lookbehind:!0,alias:\"comment\"}}))[t]),o instanceof RegExp&&(o=r[t]={pattern:o}),Array.isArray(o))for(var i=0,s=o.length;i<s;i++)o[i]instanceof RegExp&&(o[i]={pattern:o[i]}),n(o[i]);else n(o)}}(e,(function(a){a.inside||(a.inside={}),a.inside.rest=n}))}))}}),e.addSupport([\"java\",\"javascript\",\"php\"],e)}(Prism);\n!function(a){var e=/(^(?:[\\t ]*(?:\\*\\s*)*))[^*\\s].*$/m,n=\"(?:\\\\b[a-zA-Z]\\\\w+\\\\s*\\\\.\\\\s*)*\\\\b[A-Z]\\\\w*(?:\\\\s*<mem>)?|<mem>\".replace(/<mem>/g,(function(){return\"#\\\\s*\\\\w+(?:\\\\s*\\\\([^()]*\\\\))?\"}));a.languages.javadoc=a.languages.extend(\"javadoclike\",{}),a.languages.insertBefore(\"javadoc\",\"keyword\",{reference:{pattern:RegExp(\"(@(?:exception|link|linkplain|see|throws|value)\\\\s+(?:\\\\*\\\\s*)?)(?:\"+n+\")\"),lookbehind:!0,inside:{function:{pattern:/(#\\s*)\\w+(?=\\s*\\()/,lookbehind:!0},field:{pattern:/(#\\s*)\\w+/,lookbehind:!0},namespace:{pattern:/\\b(?:[a-z]\\w*\\s*\\.\\s*)+/,inside:{punctuation:/\\./}},\"class-name\":/\\b[A-Z]\\w*/,keyword:a.languages.java.keyword,punctuation:/[#()[\\],.]/}},\"class-name\":{pattern:/(@param\\s+)<[A-Z]\\w*>/,lookbehind:!0,inside:{punctuation:/[.<>]/}},\"code-section\":[{pattern:/(\\{@code\\s+(?!\\s))(?:[^\\s{}]|\\s+(?![\\s}])|\\{(?:[^{}]|\\{(?:[^{}]|\\{(?:[^{}]|\\{[^{}]*\\})*\\})*\\})*\\})+(?=\\s*\\})/,lookbehind:!0,inside:{code:{pattern:e,lookbehind:!0,inside:a.languages.java,alias:\"language-java\"}}},{pattern:/(<(code|pre|tt)>(?!<code>)\\s*)\\S(?:\\S|\\s+\\S)*?(?=\\s*<\\/\\2>)/,lookbehind:!0,inside:{line:{pattern:e,lookbehind:!0,inside:{tag:a.languages.markup.tag,entity:a.languages.markup.entity,code:{pattern:/.+/,inside:a.languages.java,alias:\"language-java\"}}}}}],tag:a.languages.markup.tag,entity:a.languages.markup.entity}),a.languages.javadoclike.addSupport(\"java\",a.languages.javadoc)}(Prism);\n!function(n){n.languages.kotlin=n.languages.extend(\"clike\",{keyword:{pattern:/(^|[^.])\\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\\b/,lookbehind:!0},function:[{pattern:/(?:`[^\\r\\n`]+`|\\b\\w+)(?=\\s*\\()/,greedy:!0},{pattern:/(\\.)(?:`[^\\r\\n`]+`|\\w+)(?=\\s*\\{)/,lookbehind:!0,greedy:!0}],number:/\\b(?:0[xX][\\da-fA-F]+(?:_[\\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\\d+(?:_\\d+)*(?:\\.\\d+(?:_\\d+)*)?(?:[eE][+-]?\\d+(?:_\\d+)*)?[fFL]?)\\b/,operator:/\\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\\/*%<>]=?|[?:]:?|\\.\\.|&&|\\|\\||\\b(?:and|inv|or|shl|shr|ushr|xor)\\b/}),delete n.languages.kotlin[\"class-name\"];var e={\"interpolation-punctuation\":{pattern:/^\\$\\{?|\\}$/,alias:\"punctuation\"},expression:{pattern:/[\\s\\S]+/,inside:n.languages.kotlin}};n.languages.insertBefore(\"kotlin\",\"string\",{\"string-literal\":[{pattern:/\"\"\"(?:[^$]|\\$(?:(?!\\{)|\\{[^{}]*\\}))*?\"\"\"/,alias:\"multiline\",inside:{interpolation:{pattern:/\\$(?:[a-z_]\\w*|\\{[^{}]*\\})/i,inside:e},string:/[\\s\\S]+/}},{pattern:/\"(?:[^\"\\\\\\r\\n$]|\\\\.|\\$(?:(?!\\{)|\\{[^{}]*\\}))*\"/,alias:\"singleline\",inside:{interpolation:{pattern:/((?:^|[^\\\\])(?:\\\\{2})*)\\$(?:[a-z_]\\w*|\\{[^{}]*\\})/i,lookbehind:!0,inside:e},string:/[\\s\\S]+/}}],char:{pattern:/'(?:[^'\\\\\\r\\n]|\\\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete n.languages.kotlin.string,n.languages.insertBefore(\"kotlin\",\"keyword\",{annotation:{pattern:/\\B@(?:\\w+:)?(?:[A-Z]\\w*|\\[[^\\]]+\\])/,alias:\"builtin\"}}),n.languages.insertBefore(\"kotlin\",\"function\",{label:{pattern:/\\b\\w+@|@\\w+\\b/,alias:\"symbol\"}}),n.languages.kt=n.languages.kotlin,n.languages.kts=n.languages.kotlin}(Prism);\n\"undefined\"!=typeof Prism&&\"undefined\"!=typeof document&&document.createRange&&(Prism.plugins.KeepMarkup=!0,Prism.hooks.add(\"before-highlight\",(function(e){if(e.element.children.length&&Prism.util.isActive(e.element,\"keep-markup\",!0)){var n=Prism.util.isActive(e.element,\"drop-tokens\",!1),t=0,o=[];r(e.element),o.length&&(e.keepMarkup=o)}function d(e){if(function(e){return!n||\"span\"!==e.nodeName.toLowerCase()||!e.classList.contains(\"token\")}(e)){var d={element:e,posOpen:t};o.push(d),r(e),d.posClose=t}else r(e)}function r(e){for(var n=0,o=e.childNodes.length;n<o;n++){var r=e.childNodes[n];1===r.nodeType?d(r):3===r.nodeType&&(t+=r.data.length)}}})),Prism.hooks.add(\"after-highlight\",(function(e){if(e.keepMarkup&&e.keepMarkup.length){var n=function(e,t){for(var o=0,d=e.childNodes.length;o<d;o++){var r=e.childNodes[o];if(1===r.nodeType){if(!n(r,t))return!1}else 3===r.nodeType&&(!t.nodeStart&&t.pos+r.data.length>t.node.posOpen&&(t.nodeStart=r,t.nodeStartPos=t.node.posOpen-t.pos),t.nodeStart&&t.pos+r.data.length>=t.node.posClose&&(t.nodeEnd=r,t.nodeEndPos=t.node.posClose-t.pos),t.pos+=r.data.length);if(t.nodeStart&&t.nodeEnd){var s=document.createRange();return s.setStart(t.nodeStart,t.nodeStartPos),s.setEnd(t.nodeEnd,t.nodeEndPos),t.node.element.innerHTML=\"\",t.node.element.appendChild(s.extractContents()),s.insertNode(t.node.element),s.detach(),!1}}return!0};e.keepMarkup.forEach((function(t){n(e.element,{node:t,pos:0})})),e.highlightedCode=e.element.innerHTML}})));\n\n/*\n * This is NOT part of the prism.js main script, it's specific to Dokka.\n * Dokka generates <br> tags for new lines inside <pre> blocks and it works visually,\n * but it causes prism.js to incorrectly parse some tags (such as inline comments)\n *\n * This can be removed if there are no `<br>` tags inside `<pre>` anymore, but\n * if there still are - DO NOT remove this hook when upading prism.js to a newer version\n */\nPrism.hooks.add('before-sanity-check', function (env){env.element.innerHTML = env.element.innerHTML.replace(/<br>/g, '\\n');env.code = env.element.textContent;});\n"
  },
  {
    "path": "docs/scripts/safe-local-storage_blocking.js",
    "content": "/*\n * Copyright 2014-2025 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n */\n/** When Dokka is viewed via iframe, local storage could be inaccessible (see https://github.com/Kotlin/dokka/issues/3323)\n * This is a wrapper around local storage to prevent errors in such cases\n * */\nconst safeLocalStorage = (() => {\n  let isLocalStorageAvailable = false;\n  try {\n    const testKey = '__testLocalStorageKey__';\n    localStorage.setItem(testKey, testKey);\n    localStorage.removeItem(testKey);\n    isLocalStorageAvailable = true;\n  } catch (e) {\n    console.error('Local storage is not available', e);\n  }\n\n  return {\n    getItem: (key) => {\n      if (!isLocalStorageAvailable) {\n        return null;\n      }\n      return localStorage.getItem(key);\n    },\n    setItem: (key, value) => {\n      if (!isLocalStorageAvailable) {\n        return;\n      }\n      localStorage.setItem(key, value);\n    },\n    removeItem: (key) => {\n      if (!isLocalStorageAvailable) {\n        return;\n      }\n      localStorage.removeItem(key);\n    },\n    getKeys: () => {\n      if (!isLocalStorageAvailable) {\n        return [];\n      }\n      return Object.keys(localStorage);\n    },\n  };\n})();\n\n/** When Dokka is viewed via iframe, session storage could be inaccessible (see https://github.com/Kotlin/dokka/issues/3323)\n * This is a wrapper around session storage to prevent errors in such cases\n * */\nconst safeSessionStorage = (() => {\n  let isSessionStorageAvailable = false;\n  try {\n    const testKey = '__testSessionStorageKey__';\n    sessionStorage.setItem(testKey, testKey);\n    sessionStorage.removeItem(testKey);\n    isSessionStorageAvailable = true;\n  } catch (e) {\n    console.error('Session storage is not available', e);\n  }\n\n  return {\n    getItem: (key) => {\n      if (!isSessionStorageAvailable) {\n        return null;\n      }\n      return sessionStorage.getItem(key);\n    },\n    setItem: (key, value) => {\n      if (!isSessionStorageAvailable) {\n        return;\n      }\n      sessionStorage.setItem(key, value);\n    },\n    removeItem: (key) => {\n      if (!isSessionStorageAvailable) {\n        return;\n      }\n      sessionStorage.removeItem(key);\n    },\n    getKeys: () => {\n      if (!isSessionStorageAvailable) {\n        return [];\n      }\n      return Object.keys(sessionStorage);\n    },\n  };\n})();\n"
  },
  {
    "path": "docs/scripts/sourceset_dependencies.js",
    "content": "sourceset_dependencies='{\":jetlime/androidMain\":[\":jetlime/commonMain\"],\":jetlime/androidRelease\":[\":jetlime/commonMain\"],\":jetlime/appleMain\":[\":jetlime/nativeMain\"],\":jetlime/commonMain\":[],\":jetlime/desktopMain\":[\":jetlime/commonMain\"],\":jetlime/iosArm64Main\":[\":jetlime/iosMain\"],\":jetlime/iosMain\":[\":jetlime/appleMain\"],\":jetlime/iosSimulatorArm64Main\":[\":jetlime/iosMain\"],\":jetlime/iosX64Main\":[\":jetlime/iosMain\"],\":jetlime/jsMain\":[\":jetlime/webMain\"],\":jetlime/nativeMain\":[\":jetlime/commonMain\"],\":jetlime/wasmJsMain\":[\":jetlime/webMain\"],\":jetlime/webMain\":[\":jetlime/commonMain\"]}'"
  },
  {
    "path": "docs/styles/logo-styles.css",
    "content": "/*\n * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n */\n\n:root {\n    --dokka-logo-image-url: url('../images/logo-icon.svg');\n    --dokka-logo-height: 28px;\n    --dokka-logo-width: 28px;\n}\n"
  },
  {
    "path": "docs/styles/main.css",
    "content": "/*!\n * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n *//*!\n * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n *//*!\n * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n */:root{--breakpoint-desktop-min: 900px;--breakpoint-tablet-max: 899px;--breakpoint-tablet-min: 440px;--breakpoint-mobile-max: 439px;--breakpoint-mobile-min: 360px}/*!\n * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n */:root{--color-key-blue: rgb(48, 127, 255);--color-key-blue-hover: rgb(69, 140, 255);--color-key-blue-50: rgb(48, 127, 255, 0.5);--color-background-nav: rgb(39, 40, 44);--color-background-nav-dt: rgb(50, 50, 55);--color-background-page: rgb(255, 255, 255);--color-background-page-dt: rgba(38, 38, 40, 1);--color-background-footer: rgb(235, 235, 235);--color-background-footer-dt: rgb(50, 50, 55);--color-text: rgb(0, 0, 0);--color-text-dt: rgba(255, 255, 255, 0.96);--color-text-light: rgba(0, 0, 0, 0.7);--color-text-light-dt: rgba(255, 255, 255, 0.7);--color-w05: rgba(255, 255, 255, 0.05);--color-w08: rgba(255, 255, 255, 0.08);--color-w10: rgba(255, 255, 255, 0.1);--color-w16: rgba(255, 255, 255, 0.16);--color-w21: rgba(255, 255, 255, 0.21);--color-w50: rgba(255, 255, 255, 0.5);--color-w70: rgba(255, 255, 255, 0.7);--color-w80: rgba(255, 255, 255, 0.8);--color-w100: rgba(255, 255, 255, 1);--color-b05: rgba(0, 0, 0, 0.05);--color-b08: rgba(0, 0, 0, 0.08);--color-b20: rgba(0, 0, 0, 0.2);--color-b50: rgba(0, 0, 0, 0.5);--color-b70: rgba(0, 0, 0, 0.7);--color-b100: rgba(0, 0, 0, 1);--color-background-inline-code: var(--color-b08);--color-background-code-block: rgba(25, 25, 28, 0.05);--color-cd-punctuation: rgb(153, 153, 153);--color-cd-keyword: rgb(0, 51, 179);--color-cd-keyword-alternative: rgba(204, 120, 50);--color-cd-builtin: rgb(6, 125, 23);--color-cd-builtin-alternative: rgb(231, 191, 106);--color-cd-function: rgb(0, 98, 122);--color-cd-function-alternative: rgb(255, 198, 109);--color-cd-operator: rgb(154, 110, 58);--color-cd-operator-alternative: rgb(169, 183, 198);--color-cd-number: rgba(135, 16, 148, 1);--color-cd-number-alternative: rgba(109, 185, 243, 1);--color-generic: rgb(83, 157, 243);--color-jvm: rgb(77, 187, 95);--color-js: rgb(255, 199, 0);--color-wasm: rgb(255, 255, 255);--copy-icon-color: var(--color-b50);--copy-icon-hover-color: var(--color-b70)}/*!\n * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n */:root{--size-s1: 4px;--size-s2: 8px;--size-s3: 16px;--size-m1: 24px;--size-m2: 32px;--size-m3: 48px;--size-l1: 64px;--size-l2: 72px;--size-ta1: 40px;--size-ta2: 52px}/*!\n * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n */:root{--font-family-default: Inter, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Droid Sans, Helvetica Neue, Arial, sans-serif;--font-family-mono: JetBrains Mono, SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;--font-h1: 600 44px/44px var(--font-family-default);--font-h2: 600 32px/32px var(--font-family-default);--font-h3: 600 24px/24px var(--font-family-default);--font-h4: 600 16px/24px var(--font-family-default);--font-text-m: 400 16px/24px var(--font-family-default);--font-text-s: 400 14px/20px var(--font-family-default);--font-code: 400 15.5px/24px var(--font-family-mono)}/*!\n * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n */:root{--hover-transition: background-color 200ms ease-in-out;--rotate-transition: transform 200ms ease-in-out}#pages-search{width:40px;height:40px;padding:0;cursor:pointer;border:none;border-radius:var(--size-s1);background:rgba(0,0,0,0);font-size:0}#pages-search:focus-visible{outline:var(--focus-outline)}@media(width < 900px){#pages-search{width:52px;height:52px;border-radius:0;outline-offset:-4px}}.search,.search [data-test=ring-select],.search [data-test=ring-tooltip],.search [data-test=ring-select_focus]{display:inline-block;margin:0;padding:0;font-size:0;line-height:0}.search-hotkey-popup{padding:4px;background-color:var(--background-color) !important}span[data-test-custom=ring-select-popup-filter-icon]{top:10px;left:11px}@media(width < 900px){span[data-test-custom=ring-select-popup-filter-icon]{top:16px;left:11px}}span[data-test-custom=ring-select-popup-filter-icon] svg{width:20px !important;height:20px !important}.popup-wrapper{min-width:636px !important;margin-top:-42px;color:rgba(255,255,255,.96);border:1px solid rgba(255,255,255,.2) !important;background-color:#262628 !important}@media(width < 900px){.popup-wrapper{top:-1px !important;right:-1px !important;bottom:-1px !important;left:-1px !important;overflow-y:hidden !important;margin-top:0}}.popup-wrapper [class^=filterWrapper]{margin-bottom:4px;padding-right:0;border-bottom:1px solid rgba(255,255,255,.2)}.popup-wrapper input{--outline-width: 4px;width:calc(100% - var(--outline-width));height:39px;margin-left:-40px;padding-right:52px;padding-left:40px;color:#fff;border-radius:0;font-size:16px;font-weight:normal !important}.popup-wrapper input::placeholder{color:rgba(0,0,0,0)}@media(width < 900px){.popup-wrapper input{height:51px}}.popup-wrapper span[data-test-custom=ring-select-popup-filter-icon]{color:#fff}@media(width < 900px){.popup-wrapper div[data-test=ring-input]{overflow:hidden}}.popup-wrapper button[data-test=ring-input-clear]{top:0;right:40px;height:39px;padding:9px 12px;transition:none;color:#fff !important;border-radius:0;line-height:21px}@media(width < 900px){.popup-wrapper button[data-test=ring-input-clear]{right:52px;height:52px}}.popup-wrapper button[data-test=ring-input-clear]:focus-visible{box-shadow:inset 4px 0 0 var(--color-key-blue-50),inset -4px 0 0 var(--color-key-blue-50),0 -4px 0 var(--color-key-blue-50),0 4px 0 var(--color-key-blue-50)}@media(width < 900px){.popup-wrapper button[data-test=ring-input-clear]:focus-visible{outline:var(--focus-outline);outline-offset:-4px;box-shadow:none}}.popup-wrapper button[data-test=ring-input-clear]:hover{background-color:var(--color-w10)}@media(width < 900px){.popup-wrapper button[data-test=ring-input-clear]{padding:15.5px 12px}}.popup-wrapper button[data-test=ring-input-clear] span{display:none}.popup-wrapper button[data-test=ring-input-clear]::after{content:\"Clear\"}@media screen and (width <= 759px){.popup-wrapper{min-width:100% !important}.search-hotkey-popup{display:none}}.search--close-button{position:absolute;top:-1px;right:-1px;width:41px;height:41px !important;border-radius:0 !important}@media(width < 900px){.search--close-button{width:52px;height:52px !important;background-color:rgba(0,0,0,0) !important}.search--close-button:hover{background-color:var(--color-w10) !important}.search--close-button:active{background-color:var(--color-w16) !important}.search--close-button:focus-visible{outline:var(--focus-outline);outline-offset:-4px}}.template-wrapper{display:flex;overflow:hidden;flex-direction:column;height:auto;padding:4px 24px;grid-template-columns:auto auto}.template-wrapper strong{color:rgba(255,255,255,.96);background:rgba(48,127,255,.3)}.template-title{display:-webkit-box;overflow:hidden;white-space:normal;word-break:break-all;color:#fff;font-size:16px;font-weight:600;line-height:24px;-webkit-box-orient:vertical;-webkit-line-clamp:2}.template-description{display:block;display:-webkit-box;overflow:hidden;white-space:normal;word-break:break-all;color:rgba(255,255,255,.7);font-size:14px;font-weight:normal;line-height:20px;justify-self:end;-webkit-box-orient:vertical;-webkit-line-clamp:2}@media screen and (width <= 759px){.template-wrapper{display:flex;flex-direction:column;height:auto}.template-wrapper span{line-height:unset}.template-title{font-size:14px;line-height:20px}.template-description{font-size:14px;line-height:20px}}.template-name{justify-self:start}[class^=fade]{display:none}[class*=hover]{background-color:rgba(255,255,255,.1) !important}div[data-test=ring-select-popup-filter]{padding-left:40px}div[data-test=ring-popup]{overflow:visible;border-radius:0}div[data-test=ring-popup] .ReactVirtualized__List{max-height:412px !important}div[data-test=ring-popup] .ReactVirtualized__List:focus-visible{outline:var(--focus-outline)}@media(width < 900px){div[data-test=ring-popup] .ReactVirtualized__List{max-height:calc(100vh - 51px) !important}}\n/* stylelint-disable color-no-hex */\n\n.light,\n:root {\n  --ring-unit: 8px;\n\n  /* Element */\n  --ring-line-components: 223, 229, 235;\n  --ring-line-color: rgb(var(--ring-line-components)); /* #dfe5eb */\n  --ring-borders-components: 197, 209, 219;\n  --ring-borders-color: rgb(var(--ring-borders-components)); /* #c5d1db */\n  --ring-icon-components: 184, 209, 229;\n  --ring-icon-color: rgb(var(--ring-icon-components)); /* #b8d1e5 */\n  --ring-icon-secondary-components: 153, 153, 153;\n  --ring-icon-secondary-color: rgb(var(--ring-icon-secondary-components)); /* #999 */\n  --ring-border-disabled-components: 232, 232, 232;\n  --ring-border-disabled-color: rgb(var(--ring-border-disabled-components)); /* #e8e8e8 */\n  --ring-border-selected-disabled-components: 212, 212, 212;\n  --ring-border-selected-disabled-color: rgb(var(--ring-border-selected-disabled-components)); /* #d4d4d4 */\n  --ring-border-unselected-disabled-components: 232, 232, 232;\n  --ring-border-unselected-disabled-color: rgb(var(--ring-border-unselected-disabled-components)); /* #e8e8e8 */ /* TODO remove in 6.0 */\n  --ring-icon-disabled-components: 212, 212, 212;\n  --ring-icon-disabled-color: rgb(var(--ring-icon-disabled-components)); /* #d4d4d4 */\n  --ring-border-hover-components: 128, 198, 255;\n  --ring-border-hover-color: rgb(var(--ring-border-hover-components)); /* #80c6ff */\n  --ring-icon-hover-components: var(--ring-link-hover-color);\n  --ring-icon-hover-color: var(--ring-link-hover-color);\n  --ring-main-components: 0, 128, 229;\n  --ring-main-color: rgb(var(--ring-main-components)); /* #0080e5 */\n  --ring-action-link-components: var(--ring-main-components);\n  --ring-action-link-color: rgb(var(--ring-main-components)); /* #0080e5 */\n  --ring-main-hover-components: 0, 112, 204;\n  --ring-main-hover-color: rgb(var(--ring-main-hover-components)); /* #0070cc */\n  --ring-icon-error-components: 219, 88, 96;\n  --ring-icon-error-color: rgb(var(--ring-icon-error-components)); /* #db5860 */\n  --ring-icon-warning-components: 237, 162, 0;\n  --ring-icon-warning-color: rgb(var(--ring-icon-warning-components)); /* #eda200 */\n  --ring-icon-success-components: 89, 168, 105;\n  --ring-icon-success-color: rgb(var(--ring-icon-success-components)); /* #59a869 */\n  --ring-pale-control-components: 207, 219, 229;\n  --ring-pale-control-color: rgb(var(--ring-pale-control-components)); /* #cfdbe5 */\n  --ring-popup-border-components: 0, 28, 54;\n  --ring-popup-border-color: var(--ring-line-color);\n  --ring-popup-shadow-components: rgba(var(--ring-popup-border-components), 0.1);\n  --ring-popup-shadow-color: rgba(var(--ring-popup-border-components), 0.1);\n  --ring-popup-secondary-shadow-color: rgba(var(--ring-popup-border-components), 0.04);\n  --ring-message-shadow-color: rgba(var(--ring-popup-border-components), 0.3);\n  --ring-pinned-shadow-components: 115, 117, 119;\n  --ring-pinned-shadow-color: rgb(var(--ring-pinned-shadow-components)); /* #737577 */\n  --ring-button-danger-hover-components: var(--ring-icon-error-color);\n  --ring-button-danger-hover-color: var(--ring-icon-error-color);\n  --ring-button-primary-border-components: 0, 98, 178;\n  --ring-button-primary-border-color: rgb(var(--ring-button-primary-border-components)); /* #0062b2 */\n  --ring-popup-shadow: 0 2px 8px var(--ring-popup-shadow-color), 0 1px 2px var(--ring-popup-secondary-shadow-color);\n  --ring-dialog-shadow: 0 4px 24px var(--ring-popup-shadow-color), 0 2px 6px var(--ring-popup-secondary-shadow-color);\n\n  /* Text */\n  --ring-search-components: 102, 158, 204;\n  --ring-search-color: rgb(var(--ring-search-components)); /* #669ecc */\n  --ring-hint-components: 64, 99, 128;\n  --ring-hint-color: rgb(var(--ring-hint-components)); /* #406380 */\n  --ring-link-components: 15, 91, 153;\n  --ring-link-color: rgb(var(--ring-link-components)); /* #0f5b99 */\n  --ring-link-hover-components: 255, 0, 140;\n  --ring-link-hover-color: rgb(var(--ring-link-hover-components)); /* #ff008c */\n  --ring-error-components: 169, 15, 26;\n  --ring-error-color: rgb(var(--ring-error-components)); /* #a90f1a */\n  --ring-warning-components: 178, 92, 0;\n  --ring-warning-color: rgb(var(--ring-warning-components)); /* #b25c00 */\n  --ring-success-components: 12, 117, 35;\n  --ring-success-color: rgb(var(--ring-success-components)); /* #0c7523 */\n  --ring-text-components: 31, 35, 38;\n  --ring-text-color: rgb(var(--ring-text-components)); /* #1f2326 */\n  --ring-active-text-color: var(--ring-text-color);\n  --ring-white-text-components: 255, 255, 255;\n  --ring-white-text-color: rgb(var(--ring-white-text-components)); /* #fff */\n  --ring-heading-color: var(--ring-text-color);\n  --ring-secondary-components: 115, 117, 119;\n  --ring-secondary-color: rgb(var(--ring-secondary-components)); /* #737577 */\n  --ring-disabled-components: 153, 153, 153;\n  --ring-disabled-color: rgb(var(--ring-disabled-components)); /* #999 */\n\n  /* Background */\n  --ring-content-background-components: 255, 255, 255;\n  --ring-content-background-color: rgb(var(--ring-content-background-components)); /* #fff */\n  --ring-popup-background-components: 255, 255, 255;\n  --ring-popup-background-color: rgb(var(--ring-popup-background-components)); /* #fff */\n  --ring-sidebar-background-components: 247, 249, 250;\n  --ring-sidebar-background-color: rgb(var(--ring-sidebar-background-components)); /* #f7f9fa */\n  --ring-selected-background-components: 212, 237, 255;\n  --ring-selected-background-color: rgb(var(--ring-selected-background-components)); /* #d4edff */\n  --ring-hover-background-components: 235, 246, 255;\n  --ring-hover-background-color: rgb(var(--ring-hover-background-components)); /* #ebf6ff */\n  --ring-navigation-background-components: 255, 255, 255;\n  --ring-navigation-background-color: rgb(var(--ring-navigation-background-components)); /* #fff */\n  --ring-tag-background-components: 230, 236, 242;\n  --ring-tag-background-color: rgb(var(--ring-tag-background-components)); /* #e6ecf2 */\n  --ring-tag-hover-background-components: 211, 218, 224;\n  --ring-tag-hover-background-color: rgb(var(--ring-tag-hover-background-components)); /* #d3dae0 */\n  --ring-removed-background-components: 255, 213, 203;\n  --ring-removed-background-color: rgb(var(--ring-removed-background-components)); /* #ffd5cb */\n  --ring-warning-background-components: 250, 236, 205;\n  --ring-warning-background-color: rgb(var(--ring-warning-background-components)); /* #faeccd */\n  --ring-added-background-components: 216, 240, 216;\n  --ring-added-background-color: rgb(var(--ring-added-background-components)); /* #d8f0d8 */\n  --ring-disabled-background-components: 245, 245, 245;\n  --ring-disabled-background-color: rgb(var(--ring-disabled-background-components)); /* #f5f5f5 */\n  --ring-disabled-selected-background-components: 232, 232, 232;\n  --ring-disabled-selected-background-color: rgb(var(--ring-disabled-selected-background-components)); /* #e8e8e8 */\n  --ring-button-danger-active-components: 255, 231, 232;\n  --ring-button-danger-active-color: rgb(var(--ring-button-danger-active-components)); /* #ffe7e8 */\n  --ring-button-loader-background-components: 51, 163, 255;\n  --ring-button-loader-background: rgb(var(--ring-button-loader-background-components)); /* #33a3ff */\n  --ring-button-primary-background-components: 26, 152, 255;\n  --ring-button-primary-background-color: rgb(var(--ring-button-primary-background-components)); /* #1a98ff */\n  --ring-table-loader-background-color: rgba(var(--ring-content-background-components), 0.5); /* #ffffff80 */\n\n  /* Code */\n  --ring-code-background-color: var(--ring-content-background-color);\n  --ring-code-components: 0, 0, 0;\n  --ring-code-color: rgb(var(--ring-code-components)); /* #000 */\n  --ring-code-comment-components: 112, 112, 112;\n  --ring-code-comment-color: rgb(var(--ring-code-comment-components)); /* #707070 */\n  --ring-code-meta-components: 112, 112, 112;\n  --ring-code-meta-color: rgb(var(--ring-code-meta-components)); /* #707070 */\n  --ring-code-keyword-components: 0, 0, 128;\n  --ring-code-keyword-color: rgb(var(--ring-code-keyword-components)); /* #000080 */\n  --ring-code-tag-background-components: 239, 239, 239;\n  --ring-code-tag-background-color: rgb(var(--ring-code-tag-background-components)); /* #efefef */\n  --ring-code-tag-color: var(--ring-code-keyword-color);\n  --ring-code-tag-font-weight: bold;\n  --ring-code-field-components: 102, 14, 122;\n  --ring-code-field-color: rgb(var(--ring-code-field-components)); /* #660e7a */\n  --ring-code-attribute-components: 0, 0, 255;\n  --ring-code-attribute-color: rgb(var(--ring-code-attribute-components)); /* #00f */\n  --ring-code-number-color: var(--ring-code-attribute-color);\n  --ring-code-string-components: 0, 122, 0;\n  --ring-code-string-color: rgb(var(--ring-code-string-components)); /* #007a00 */\n  --ring-code-addition-components: 170, 222, 170;\n  --ring-code-addition-color: rgb(var(--ring-code-addition-components)); /* #aadeaa */\n  --ring-code-deletion-components: 200, 200, 200;\n  --ring-code-deletion-color: rgb(var(--ring-code-deletion-components)); /* #c8c8c8 */\n\n  /* Metrics */\n  --ring-border-radius: 4px;\n  --ring-border-radius-small: 2px;\n  --ring-font-size-larger: 15px;\n  --ring-font-size: 14px;\n  --ring-font-size-smaller: 12px;\n  --ring-line-height-taller: 21px;\n  --ring-line-height: 20px;\n  --ring-line-height-lower: 18px;\n  --ring-line-height-lowest: 16px;\n  --ring-ease: 0.3s ease-out;\n  --ring-fast-ease: 0.15s ease-out;\n  --ring-font-family: system-ui, Arial, sans-serif;\n  --ring-font-family-monospace:\n    Menlo,\n    \"Bitstream Vera Sans Mono\",\n    \"Ubuntu Mono\",\n    Consolas,\n    \"Courier New\",\n    Courier,\n    monospace;\n\n  /* Common z-index-values */\n\n  /* Invisible element is an absolutely positioned element which should be below */\n  /* all other elements on the page */\n  --ring-invisible-element-z-index: -1;\n\n  /* z-index for position: fixed elements */\n  --ring-fixed-z-index: 1;\n\n  /* Elements that should overlay all other elements on the page */\n  --ring-overlay-z-index: 5;\n\n  /* Alerts should de displayed above overlays */\n  --ring-alert-z-index: 6;\n}\n\n/*!\n * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n *//*!\n * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n */html,.app-root{height:100%}.search-root{margin:0;padding:0;background:var(--ring-content-background-color);font-family:var(--ring-font-family);font-size:var(--ring-font-size);line-height:var(--ring-line-height)}.search-content{z-index:8}\n\n/*# sourceMappingURL=main.css.map*/"
  },
  {
    "path": "docs/styles/prism.css",
    "content": "/*\n * Custom Dokka styles\n */\ncode .token {\n    white-space: pre;\n}\n\n/**\n * Styles based on webhelp's prism.js styles\n * Changes:\n * - Since webhelp's styles are in .pcss, they use nesting which is not achievable in native CSS\n *   so nested css blocks have been unrolled (like dark theme).\n * - Webhelp uses \"Custom Class\" prism.js plugin, so all of their prism classes are prefixed with \"--prism\".\n *   Dokka doesn't seem to need this plugin at the moment, so all \"--prism\" prefixes have been removed.\n * - Removed all styles related to `pre` and `code` tags. Kotlinlang's resulting styles are so spread out and complicated\n *   that it's difficult to gather in one place. Instead use code styles defined in the main Dokka styles,\n *   which at the moment looks fairly similar.\n *\n * Based on prism.js default theme\n * Based on dabblet (http://dabblet.com)\n * @author Lea Verou\n */\n\n:root {\n\t--code-area-punctuation: var(--color-cd-punctuation);\n\t--code-area-string: var(--color-cd-builtin);\n\t--code-area-keyword: var(--color-cd-keyword);\n\t--code-area-function: var(--color-cd-function);\n\t--code-area-operator: var(--color-cd-operator);\n\t--code-area-number: var(--color-cd-number);\n}\n\n:root.theme-dark {\n\t--code-area-string: var(--color-cd-builtin-alternative);\n\t--code-area-keyword: var(--color-cd-keyword-alternative);\n\t--code-area-function: var(--color-cd-function-alternative);\n\t--code-area-operator: var(--color-cd-operator-alternative);\n\t--code-area-number: var(--color-cd-number-alternative);\n}\n\n.token.comment,\n.token.prolog,\n.token.doctype,\n.token.cdata,\n.token.punctuation {\n\tcolor: var(--code-area-punctuation);\n}\n\n.token.property,\n.token.tag,\n.token.boolean,\n.token.number,\n.token.constant,\n.token.symbol,\n.token.deleted {\n\tcolor: var(--code-area-number);\n}\n\n.token.selector,\n.token.attr-name,\n.token.string,\n.token.char,\n.token.builtin,\n.token.inserted {\n\tcolor: var(--code-area-string);\n}\n\n.token.operator,\n.token.entity,\n.token.url,\n.language-css .token.string,\n.style .token.string {\n\tcolor: var(--code-area-operator);\n\tbackground: none;\n}\n\n.token.interpolation-punctuation {\n\tcolor: var(--code-area-keyword);\n}\n\n.token.atrule,\n.token.attr-value,\n.token.keyword,\n.token.interpolation-punctuation {\n\tcolor: var(--code-area-keyword);\n}\n\n.token.function {\n\tcolor: var(--code-area-function);\n}\n\n.token.regex,\n.token.important,\n.token.variable {\n\tcolor: var(--code-area-number);\n}\n\n.token.important,\n.token.bold {\n\tfont-weight: bold;\n}\n\n.token.italic {\n\tfont-style: italic;\n}\n\n.token.entity {\n\tcursor: help;\n}\n\n:root.theme-dark .language-plaintext .token {\n\t/* plaintext code should be colored as article text */\n\tcolor: inherit !important;\n}\n"
  },
  {
    "path": "docs/styles/style.css",
    "content": "/*\n * Copyright 2014-2024 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.\n */\n\n/* --- root styles --- */\n:root {\n    --default-gray: #f4f4f4;\n    --default-font-color: rgb(0, 0, 0);\n    --header-font-color: var(--default-font-color);\n\n    --hover-link-color: #5B5DEF;\n\n    --color-scrollbar: rgba(39, 40, 44, 0.40);\n    --color-scrollbar-track: var(--default-gray);\n    --default-white: #fff;\n    --background-color: var(--default-white);\n    --dark-mode-and-search-icon-color: var(--default-white);\n    --color-dark: #27282c;\n    --default-font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Droid Sans, Helvetica Neue, Arial, sans-serif;\n    --default-monospace-font-family: JetBrains Mono, SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace;\n    --default-font-size: 16px;\n    --blockquote-background: rgba(39, 40, 44, .05);\n    --border-color: rgba(39, 40, 44, .2);\n    --navigation-highlight-color: rgba(39, 40, 44, 0.05);\n    --top-navigation-height: 73px;\n    --white-10: hsla(0, 0%, 100%, .1);\n\n    --active-tab-border-color: var(--color-key-blue);\n    --inactive-tab-border-color: rgba(164, 164, 170, 0.7);\n\n    --active-section-color: #7F52FF;\n    --inactive-section-color: rgba(25, 25, 28, .7);\n\n    --sidemenu-section-active-color: #7F52FF;\n}\n\nhtml {\n    height: 100%;\n    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n    scrollbar-color: rgba(39, 40, 44, 0.40) #F4F4F4;\n    scrollbar-color: var(--color-scrollbar) var(--color-scrollbar-track);\n    text-rendering: optimizeLegibility;\n    -webkit-font-smoothing: antialiased;\n    color: var(--default-font-color);\n}\n\nhtml ::-webkit-scrollbar {\n    width: 8px;\n    height: 8px;\n}\n\nhtml ::-webkit-scrollbar-track {\n    background-color: var(--color-scrollbar-track);\n}\n\nhtml ::-webkit-scrollbar-thumb {\n    width: 8px;\n    border-radius: 6px;\n    background: rgba(39, 40, 44, 0.40);\n    background: var(--color-scrollbar);\n}\n\nhtml, body {\n    margin: 0;\n    padding: 0;\n    height: 100%;\n    width: 100%;\n}\n\n/* /--- root styles --- */\n\n/* --- global tags styles --- */\n\nh1 {\n    font-size: 44px;\n    line-height: 44px;\n    margin-bottom: 24px;\n    margin-top: 48px;\n}\n\nh2 {\n    font-size: 32px;\n    line-height: 32px;\n    margin-bottom: 24px;\n    margin-top: 48px;\n}\n\nh3 {\n    font-size: 24px;\n    line-height: 24px;\n    margin-bottom: 24px;\n    margin-top: 48px;\n}\n\nh4, h5 {\n    font-size: 16px;\n    line-height: 24px;\n    margin-bottom: 24px;\n    margin-top: 24px;\n}\n\np, ul, ol, table, pre, dl {\n    margin: 0;\n}\n\nu {\n    text-decoration: none;\n    padding-bottom: 2px;\n    border-bottom: 1px solid var(--border-color);\n}\n\nblockquote {\n    border-left: 1ch solid var(--default-gray);\n    margin: 0;\n    padding-left: 1ch;\n    font-style: italic;\n    color: var(--color-dark);\n}\n\n.theme-dark blockquote {\n    color: var(--default-font-color);\n    border-left-color: var(--blockquote-background);\n}\n\npre {\n    display: block;\n}\n\ndt {\n    color: #444;\n}\n\nimg {\n    max-width: 100%;\n}\n\n/* /---  global tags styles --- */\n\n/* ---  utils classes --- */\n.w-100 {\n    width: 100%;\n}\n\n.no-gutters {\n    margin: 0;\n    padding: 0;\n}\n\n.d-flex {\n    display: flex;\n}\n\n.floating-right {\n    float: right;\n}\n\n.pull-right {\n    float: right;\n    margin-left: auto\n}\n\n.clearfix::after {\n    display: block;\n    content: '';\n    clear: both;\n    height: 0;\n}\n\n/* /---  utils classes --- */\n\n/* ---dark theme --- */\n.theme-dark {\n    --background-color: #262628;\n    --color-dark: #3d3d41;\n    --default-font-color: rgba(255, 255, 255, 0.96);\n    --border-color: hsla(0, 0%, 100%, 0.2);\n    --blockquote-background: hsla(0, 0%, 100%, 0.05);\n    --copy-icon-color: hsla(0, 0%, 100%, 0.6);\n    --copy-icon-hover-color: #fff;\n\n    --active-tab-border-color: var(--color-key-blue);\n    --inactive-tab-border-color: hsla(0, 0%, 100%, 0.4);\n\n    --active-section-color: var(--default-font-color);\n    --inactive-section-color: hsla(0, 0%, 100%, 0.4);\n\n    --navigation-highlight-color: rgba(255, 255, 255, 0.05);\n    --footer-background: hsla(0, 0%, 100%, 0.05);\n    --footer-font-color: hsla(0, 0%, 100%, 0.6);\n    --footer-go-to-top-color: var(--footer-font-color);\n\n    --sidemenu-section-active-color: var(--color-dark);\n}\n\n/* /---dark theme --- */\n\n.main-content :is(h1, h2) {\n    font-weight: 600;\n}\n\n.cover > .platform-hinted {\n    margin-bottom: 24px;\n}\n\n.cover {\n    display: flex;\n    flex-direction: column;\n}\n\n.cover .sourceset-dependent-content > .block {\n    padding: 16px 0;\n    font-size: 18px;\n    line-height: 28px;\n}\n\n.cover .platform-hinted.with-platform-tabs .sourceset-dependent-content > .block {\n    padding: 0;\n    font-size: var(--default-font-size);\n}\n\n.cover ~ .divergent-group {\n    margin-top: 24px;\n    padding: 24px 8px 8px 8px;\n}\n\n.cover ~ .divergent-group .main-subrow .symbol {\n    width: 100%;\n}\n\n.main-content p.paragraph,\n.sample-container, blockquote,\n.content > .symbol {\n    margin-top: 8px;\n}\n\n/**\nfirst block on a page\nhttp://localhost:8001/jvm/org.jetbrains.dokka.uitest.internal/function-to-be-used-as-sample.html\n */\nblockquote,\n.content > .symbol:first-of-type,\np.paragraph:first-child,\n.brief p.paragraph {\n    margin-top: 0;\n}\n\n.content .kdoc-tag > p.paragraph {\n    margin-top: 0;\n}\n\n.divergent-group {\n    background-color: var(--color-background);\n    padding: 16px 0 8px 0;\n    margin-bottom: 2px;\n}\n\n.divergent-group .table-row, tbody > tr {\n    border-bottom: 1px solid var(--border-color);\n}\n\n.divergent-group .table-row:last-of-type, tbody > tr:last-of-type {\n    border-bottom: none;\n}\n\n.title > .divergent-group:first-of-type {\n    padding-top: 0;\n}\n\n.strikethrough {\n    text-decoration: line-through;\n}\n\n/* Workaround for Firefox  https://github.com/Kotlin/dokka/issues/3156 */\n@-moz-document url-prefix() {\n    .strikethrough {\n        position: relative;\n        text-decoration: none;\n    }\n\n    /* complex selectors here are required to handle multiline cases */\n    .strikethrough::after, .strikethrough span:after  {\n        content: '';\n        position: absolute;\n        top: 7px;\n        left: 0;\n        right: 0;\n        height: 1px;\n        background-color: currentColor;\n        z-index: 1;\n    }\n}\n\n.symbol:empty {\n    padding: 0;\n}\n\n.brief {\n    white-space: pre-wrap;\n    overflow: hidden;\n}\n\nh1.cover {\n    margin-bottom: 24px;\n    display: block;\n}\n\n@media (max-width: 899px) {\n    h1.cover {\n        font-size: 32px;\n        line-height: 32px;\n        margin-bottom: 24px;\n    }\n}\n\n.UnderCoverText table {\n    margin: 8px 0 8px 0;\n    word-break: break-word;\n}\n\n@media (max-width: 960px) {\n    .UnderCoverText table {\n        display: block;\n        word-break: normal;\n        overflow: auto;\n    }\n}\n\np.paragraph img {\n    display: block;\n}\n\n.deprecation-content {\n    margin: 16px 0;\n    border: 1px solid var(--border-color);\n    padding: 16px;\n}\n\n.deprecation-content > h3 {\n    margin-top: 0;\n    margin-bottom: 0;\n}\n\n.deprecation-content > h4 {\n    font-size: 16px;\n    margin-top: 16px;\n    margin-bottom: 0;\n}\n\n/** https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.native.concurrent/atomic-lazy.html **/\n.deprecation-content .footnote {\n    display: block;\n}\n\n.deprecation-content .footnote > p {\n    margin: 0;\n}\n\n[data-filterable-current=''] {\n    display: none !important;\n}\n\n.inline-flex {\n    display: inline-flex;\n}\n\n/* Work around an issue: https://github.com/JetBrains/kotlin-playground/issues/91\nApplies for main description blocks with platform tabs.\nJust in case of possible performance degradation it excluding tabs with briefs on classlike page */\n#content > div:not(.tabbedcontent) .sourceset-dependent-content:not([data-active]) {\n    display: block !important;\n    visibility: hidden;\n    height: 0;\n    position: fixed;\n    top: 0;\n}\n\n.with-platform-tags {\n    display: flex;\n}\n\n.with-platform-tags ~ .main-subrow {\n    padding-top: 8px;\n}\n\n.cover .with-platform-tabs {\n    font-size: var(--default-font-size);\n}\n\n.cover > .block {\n    padding-top: 48px;\n    padding-bottom: 24px;\n    font-size: 18px;\n    line-height: 28px;\n}\n\n.cover > .block:empty {\n    padding-bottom: 0;\n}\n\n.parameters.wrapped > .parameter {\n    display: block;\n}\n\n.platform-dependent-row {\n    display: grid;\n    padding-top: 8px;\n}\n\n@media print, (max-width: 960px) {\n    div.wrapper {\n        width: auto;\n        margin: 0;\n    }\n\n    header, section, footer {\n        float: none;\n        position: static;\n        width: auto;\n    }\n\n    header {\n        padding-right: 320px;\n    }\n\n    section {\n        border: 1px solid #e5e5e5;\n        border-width: 1px 0;\n        padding: 20px 0;\n        margin: 0 0 20px;\n    }\n\n    header a small {\n        display: inline;\n    }\n\n    header ul {\n        position: absolute;\n        right: 50px;\n        top: 52px;\n    }\n}\n\n.anchor-highlight {\n    border: 1px solid var(--hover-link-color) !important;\n    box-shadow: 0 0 0 0.2em #c8e1ff;\n    margin-top: 0.2em;\n    margin-bottom: 0.2em;\n}\n\n.filtered-message {\n    margin: 25px;\n    font-size: 20px;\n    font-weight: 600;\n}\n"
  },
  {
    "path": "dokkaModule.md",
    "content": "Module jetlime\n\n# JetLime Module Documentation\nJetLime is a Kotlin Multiplatform timeline UI library for Compose.\n\n## Overview\nJetLime provides composables for vertical and horizontal timelines, customizable points (START, CENTER, END), and extended events with dual content areas.\n\nRefer to the project README for installation and quick start examples.\n"
  },
  {
    "path": "dokkaPackage.md",
    "content": "Package com.pushpal.jetlime\n\n# JetLime Core Package\nContains composables, styles, timeline rendering, and helper utilities.\n\n## Main Types\n- JetLimeEvent, JetLimeExtendedEvent\n- JetLimeColumn, JetLimeRow\n- JetLimeEventStyle, JetLimeStyle\n- EventPosition, PointPlacement\n\nSee README for detailed usage samples.\n"
  },
  {
    "path": "gradle/libs.versions.toml",
    "content": "[versions]\nkotlin = \"2.3.20\"\nagp = \"8.13.1\"\nactivityCompose = \"1.13.0\"\ncompose-plugin = \"1.10.3\"\nkotlinxCollectionsImmutable = \"0.4.0\"\ntruth = \"1.4.5\"\nvanniktech = \"0.36.0\"\ndokka = \"2.2.0\"\nspotless = \"8.4.0\"\nreport = \"1.5.0\"\njunitVersion = \"1.3.0\"\nandroidxTest = \"1.7.0\"\ncomposeBom = \"2026.04.00\"\n\n[libraries]\nandroidx-junit = { module = \"androidx.test.ext:junit\", version.ref = \"junitVersion\" }\nandroidx-test-runner = { module = \"androidx.test:runner\", version.ref = \"androidxTest\" }\nandroidx-compose-ui-test = { module = \"androidx.compose.ui:ui-test-junit4\" }\nandroidx-ui-test-manifest = { module = \"androidx.compose.ui:ui-test-manifest\" }\nandroidx-compose-bom = { module = \"androidx.compose:compose-bom\", version.ref = \"composeBom\" }\nandroidx-activity-compose = { module = \"androidx.activity:activity-compose\", version.ref = \"activityCompose\" }\ntruth = { module = \"com.google.truth:truth\", version.ref = \"truth\" }\n\nkotlinx-collections-immutable = { module = \"org.jetbrains.kotlinx:kotlinx-collections-immutable\", version.ref = \"kotlinxCollectionsImmutable\" }\njunit = { module = \"junit:junit\", version = \"4.13.2\" }\n\n[plugins]\nandroid-application = { id = \"com.android.application\", version.ref = \"agp\" }\nandroid-library = { id = \"com.android.library\", version.ref = \"agp\" }\njetbrains-compose = { id = \"org.jetbrains.compose\", version.ref = \"compose-plugin\" }\ncompose-compiler = { id = \"org.jetbrains.kotlin.plugin.compose\", version.ref = \"kotlin\" }\ncompose-compiler-report-generator = { id = \"dev.shreyaspatil.compose-compiler-report-generator\", version.ref = \"report\" }\nkotlin-multiplatform = { id = \"org.jetbrains.kotlin.multiplatform\", version.ref = \"kotlin\" }\nkotlin-cocoapods = { id = \"org.jetbrains.kotlin.native.cocoapods\", version.ref = \"kotlin\" }\nnexus-vanniktech-publish = { id = \"com.vanniktech.maven.publish\", version.ref = \"vanniktech\" }\ndokka = { id = \"org.jetbrains.dokka\", version.ref = \"dokka\" }\nspotless = { id = \"com.diffplug.spotless\", version.ref = \"spotless\" }"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Thu Feb 29 20:52:44 CST 2024\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-9.4.1-bin.zip\nnetworkTimeout=10000\nvalidateDistributionUrl=true\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Code style\nkotlin.code.style=official\n# Gradle\norg.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options=\"-Xmx2048M\"\n# Android\nandroid.nonTransitiveRClass=true\nandroid.useAndroidX=true\n# Kotlin incremental + caching\nkotlin.native.ignoreDisabledTargets=true\nkotlin.incremental=true\nkotlin.incremental.js=true\nkotlin.incremental.wasm=true\n# KMP\nkotlin.mpp.enableCInteropCommonization=true\nkotlin.mpp.androidSourceSetLayoutVersion=2\norg.jetbrains.compose.experimental.jscanvas.enabled=true\n# Before publishing to central the library should be tested in local:\n# ./gradlew publishToMavenLocal. This will generate sources for our source sets\n# in the .m2 folder locally. Which can be tested by adding mavenLocal() under\n# dependencyResolutionManagement in the settings.gradle.kts file.\n# If mavenLocal does not work use:  maven(\"/Users/pushpalroy/.m2/repository\")\n# Fill these details for Maven publish and then run the command:\n# ./gradlew publishAndReleaseToMavenCentral --no-configuration-cache\n# The rest of the setup is there in build.gradle of jetlime module\n# Then login to https://central.sonatype.com to see the publication\n# Maven publication\nmavenCentralUsername=\nmavenCentralPassword=\nsigning.keyId=\nsigning.password=\nsigning.secretKeyRingFile="
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif [ \"$cygwin\" = \"true\" -o \"$msys\" = \"true\" ] ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=`expr $i + 1`\n    done\n    case $i in\n        0) set -- ;;\n        1) set -- \"$args0\" ;;\n        2) set -- \"$args0\" \"$args1\" ;;\n        3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=`save \"$@\"`\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\r\n@rem you may not use this file except in compliance with the License.\r\n@rem You may obtain a copy of the License at\r\n@rem\r\n@rem      https://www.apache.org/licenses/LICENSE-2.0\r\n@rem\r\n@rem Unless required by applicable law or agreed to in writing, software\r\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\r\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n@rem See the License for the specific language governing permissions and\r\n@rem limitations under the License.\r\n@rem\r\n\r\n@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Resolve any \".\" and \"..\" in APP_HOME to make it shorter.\r\nfor %%i in (\"%APP_HOME%\") do set APP_HOME=%%~fi\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto execute\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto execute\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n\r\n@rem Execute Gradle\r\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %*\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "jetlime/.gitignore",
    "content": "/build"
  },
  {
    "path": "jetlime/build.gradle.kts",
    "content": "plugins {\n  alias(libs.plugins.android.library)\n  alias(libs.plugins.kotlin.multiplatform)\n  alias(libs.plugins.jetbrains.compose)\n  alias(libs.plugins.compose.compiler)\n  alias(libs.plugins.kotlin.cocoapods)\n  alias(libs.plugins.nexus.vanniktech.publish)\n  alias(libs.plugins.dokka)\n}\n\n// Dokka V2 extension\n// Shared configuration without deprecated properties\ndokka {\n  moduleName.set(\"jetlime\")\n  dokkaSourceSets.configureEach {\n    enableAndroidDocumentationLink.set(true)\n    val moduleDoc = rootProject.file(\"dokkaModule.md\")\n    val packageDoc = rootProject.file(\"dokkaPackage.md\")\n    if (moduleDoc.exists()) includes.from(moduleDoc.path)\n    if (packageDoc.exists()) includes.from(packageDoc.path)\n  }\n}\n\nkotlin {\n  cocoapods {\n    version = \"4.3.0\"\n    summary = \"JetLime KMP Library\"\n    homepage = \"https://github.com/pushpalroy/JetLime\"\n    ios.deploymentTarget = \"14.0\"\n    framework {\n      baseName = \"JetLime\"\n      isStatic = true\n    }\n  }\n\n  js(IR) {\n    browser()\n    binaries.library()\n  }\n\n  @OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class)\n  wasmJs {\n    browser {\n      testTask {\n        enabled = false\n      }\n    }\n    binaries.library()\n  }\n\n  androidTarget {\n    @OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)\n    compilerOptions {\n      jvmTarget.set(org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_17)\n    }\n  }\n\n  jvm(\"desktop\")\n\n  iosX64()\n  iosArm64()\n  iosSimulatorArm64()\n\n  sourceSets {\n    val desktopMain by getting\n\n    androidMain.dependencies {\n      implementation(compose.preview)\n      implementation(libs.androidx.activity.compose)\n    }\n    commonMain.dependencies {\n      implementation(compose.runtime)\n      implementation(compose.foundation)\n      implementation(compose.material3)\n      implementation(compose.ui)\n      implementation(compose.components.uiToolingPreview)\n      api(libs.kotlinx.collections.immutable)\n    }\n    desktopMain.dependencies {\n      implementation(compose.desktop.currentOs)\n    }\n  }\n}\n\nandroid {\n  namespace = \"com.pushpal.jetlime\"\n  compileSdk = 36\n\n  sourceSets[\"main\"].manifest.srcFile(\"src/androidMain/AndroidManifest.xml\")\n  sourceSets[\"main\"].res.srcDirs(\"src/androidMain/res\")\n  sourceSets[\"main\"].resources.srcDirs(\"src/commonMain/resources\")\n\n  defaultConfig {\n    minSdk = 23\n    testOptions.targetSdk = 36\n    testInstrumentationRunner = \"androidx.test.runner.AndroidJUnitRunner\"\n    consumerProguardFiles(\"consumer-rules.pro\")\n  }\n  packaging {\n    resources {\n      excludes += \"/META-INF/{AL2.0,LGPL2.1}\"\n    }\n  }\n  buildTypes {\n    release {\n      isMinifyEnabled = false\n      proguardFiles(\n        getDefaultProguardFile(\"proguard-android-optimize.txt\"),\n        \"proguard-rules.pro\",\n      )\n    }\n  }\n  compileOptions {\n    sourceCompatibility = JavaVersion.VERSION_17\n    targetCompatibility = JavaVersion.VERSION_17\n  }\n  buildFeatures {\n    compose = true\n  }\n\n  dependencies {\n    debugApi(compose.uiTooling)\n\n    // Android UI tests\n    androidTestImplementation(platform(libs.androidx.compose.bom))\n    androidTestImplementation(libs.androidx.compose.ui.test)\n    debugImplementation(libs.androidx.ui.test.manifest)\n    // Others\n    testImplementation(libs.junit)\n    androidTestImplementation(libs.androidx.test.runner)\n    androidTestImplementation(libs.androidx.junit)\n    androidTestImplementation(libs.truth)\n  }\n}\n\n// Compose Compiler metrics/reports\ncomposeCompiler {\n  reportsDestination = layout.buildDirectory.dir(\"compose_compiler/reports\")\n  metricsDestination = layout.buildDirectory.dir(\"compose_compiler/metrics\")\n}\n\nmavenPublishing {\n  // Configure publishing to Maven Central\n  publishToMavenCentral()\n\n  // Enable GPG signing for all publications\n  signAllPublications()\n\n  val artifactId = \"jetlime\"\n\n  // Define coordinates for the published artifact\n  coordinates(\"io.github.pushpalroy\", artifactId, \"4.3.0\")\n\n  // Configure POM metadata for the published artifact\n  pom {\n    name.set(artifactId)\n    description.set(\"A simple KMP library for TimeLine view in Compose\")\n    inceptionYear.set(\"2022\")\n    packaging = \"aar\"\n    url.set(\"https://github.com/pushpalroy/jetlime/\")\n    licenses {\n      license {\n        name.set(\"MIT License\")\n        url.set(\"https://github.com/pushpalroy/jetlime/blob/main/LICENSE\")\n        distribution.set(\"repo\")\n      }\n    }\n    // Specify developer information\n    developers {\n      developer {\n        id.set(\"pushpalroy\")\n        name.set(\"Pushpal Roy\")\n        url.set(\"https://github.com/pushpalroy/\")\n      }\n    }\n    // Specify SCM information\n    scm {\n      url.set(\"https://github.com/pushpalroy/jetlime\")\n      connection.set(\"scm:git:git://github.com/pushpalroy/jetlime.git\")\n      developerConnection.set(\"scm:git:ssh://git@github.com/pushpalroy/jetlime.git\")\n    }\n  }\n}\n\n// Copy Dokka output into root docs directory (legacy location expected by project)\ntasks.register<Copy>(\"syncDokkaToDocs\") {\n  description = \"Sync Dokka HTML output to root docs directory\"\n  group = \"documentation\"\n  dependsOn(\"dokkaGenerateHtml\")\n  val srcDir = layout.buildDirectory.dir(\"dokka/html\")\n  val destDir = rootProject.layout.projectDirectory.dir(\"docs\")\n  doFirst {\n    delete(destDir)\n  }\n  from(srcDir)\n  into(destDir)\n}\n"
  },
  {
    "path": "jetlime/consumer-rules.pro",
    "content": ""
  },
  {
    "path": "jetlime/dokkaModule.md",
    "content": "Module\njetlime\n\n# JetLime\nA Kotlin Multiplatform library providing timeline UI components for Compose (Android, Desktop, JS, WASM, iOS).\n\n## Features\n- Vertical & horizontal timelines\n- START / CENTER / END point placements\n- Extended events with dual content slots\n- Custom point types (filled, empty, icon)\n- Multiplatform targets (Android, Desktop, JS, WASM, iOS)\n\n## Usage\nRefer to the root README for setup and examples.\n"
  },
  {
    "path": "jetlime/dokkaPackage.md",
    "content": "Package\ncom.pushpal.jetlime\n\n# Core Package\nContains composables, styles, event rendering logic and helper utilities for building timelines.\n\n## Key Components\n- JetLimeEvent / JetLimeExtendedEvent\n- JetLimeColumn / JetLimeRow\n- JetLimeEventStyle, JetLimeStyle, EventPosition\n\n## Notes\nSee module documentation and README for full examples.\n\n"
  },
  {
    "path": "jetlime/jetlime.podspec",
    "content": "Pod::Spec.new do |spec|\n    spec.name                     = 'jetlime'\n    spec.version                  = '4.3.0'\n    spec.homepage                 = 'https://github.com/pushpalroy/JetLime'\n    spec.source                   = { :http=> ''}\n    spec.authors                  = ''\n    spec.license                  = ''\n    spec.summary                  = 'JetLime KMP Library'\n    spec.vendored_frameworks      = 'build/cocoapods/framework/JetLime.framework'\n    spec.libraries                = 'c++'\n    spec.ios.deployment_target    = '14.0'\n    if !Dir.exist?('build/cocoapods/framework/JetLime.framework') || Dir.empty?('build/cocoapods/framework/JetLime.framework')\n        raise \"\n        Kotlin framework 'JetLime' doesn't exist yet, so a proper Xcode project can't be generated.\n        'pod install' should be executed after running ':generateDummyFramework' Gradle task:\n            ./gradlew :jetlime:generateDummyFramework\n        Alternatively, proper pod installation is performed during Gradle sync in the IDE (if Podfile location is set)\"\n    end\n    spec.xcconfig = {\n        'ENABLE_USER_SCRIPT_SANDBOXING' => 'NO',\n    }\n    spec.pod_target_xcconfig = {\n        'KOTLIN_PROJECT_PATH' => ':jetlime',\n        'PRODUCT_MODULE_NAME' => 'JetLime',\n    }\n    spec.script_phases = [\n        {\n            :name => 'Build jetlime',\n            :execution_position => :before_compile,\n            :shell_path => '/bin/sh',\n            :script => <<-SCRIPT\n                if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n                    echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n                    exit 0\n                fi\n                set -ev\n                REPO_ROOT=\"$PODS_TARGET_SRCROOT\"\n                \"$REPO_ROOT/../gradlew\" -p \"$REPO_ROOT\" $KOTLIN_PROJECT_PATH:syncFramework \\\n                    -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \\\n                    -Pkotlin.native.cocoapods.archs=\"$ARCHS\" \\\n                    -Pkotlin.native.cocoapods.configuration=\"$CONFIGURATION\"\n            SCRIPT\n        }\n    ]\n    spec.resources = ['build/compose/cocoapods/compose-resources']\nend\n"
  },
  {
    "path": "jetlime/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.kts.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile"
  },
  {
    "path": "jetlime/src/androidMain/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n</manifest>"
  },
  {
    "path": "jetlime/src/androidTest/java/com/pushpal/jetlime/ExampleInstrumentedTest.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport androidx.test.ext.junit.runners.AndroidJUnit4\nimport androidx.test.platform.app.InstrumentationRegistry\nimport org.junit.Assert.assertEquals\nimport org.junit.Test\nimport org.junit.runner.RunWith\n\n/**\n * Instrumented test, which will execute on an Android device.\n *\n * See [testing documentation](http://d.android.com/tools/testing).\n */\n@RunWith(AndroidJUnit4::class)\nclass ExampleInstrumentedTest {\n  @Test\n  fun useAppContext() {\n    // Context of the app under test.\n    val appContext = InstrumentationRegistry.getInstrumentation().targetContext\n    assertEquals(\"com.pushpal.jetlime.test\", appContext.packageName)\n  }\n}\n"
  },
  {
    "path": "jetlime/src/androidTest/java/com/pushpal/jetlime/JetLimeColumnTest.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport android.annotation.SuppressLint\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.ExperimentalComposeApi\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.platform.testTag\nimport androidx.compose.ui.test.assertIsDisplayed\nimport androidx.compose.ui.test.assertPositionInRootIsEqualTo\nimport androidx.compose.ui.test.hasText\nimport androidx.compose.ui.test.junit4.createComposeRule\nimport androidx.compose.ui.test.onNodeWithTag\nimport androidx.compose.ui.test.onNodeWithText\nimport androidx.compose.ui.test.performClick\nimport androidx.compose.ui.test.performScrollToNode\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.test.ext.junit.runners.AndroidJUnit4\nimport com.google.common.truth.Truth.assertThat\nimport com.pushpal.jetlime.JetLimeDefaults.lineSolidBrush\nimport kotlinx.collections.immutable.persistentListOf\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.runner.RunWith\n\n@SuppressLint(\"ComposableNaming\")\n@RunWith(AndroidJUnit4::class)\nclass JetLimeColumnTest {\n\n  @get:Rule\n  val composeTestRule = createComposeRule()\n\n  @Test\n  fun jetLimeColumn_displaysItems() {\n    // Prepare a list of items to display\n    val itemsList = ItemsList(persistentListOf(\"Item 1\", \"Item 2\"))\n\n    composeTestRule.setContent {\n      JetLimeColumn(\n        itemsList = itemsList,\n        itemContent = { _, item, _ ->\n          Text(text = item)\n        },\n      )\n    }\n\n    // Check if the items are displayed\n    composeTestRule.onNodeWithText(\"Item 1\").assertIsDisplayed()\n    composeTestRule.onNodeWithText(\"Item 2\").assertIsDisplayed()\n  }\n\n  @Test\n  fun jetLimeColumn_displaysJetLimeItems() {\n    // Prepare a list of items to display\n    val itemsList = ItemsList(persistentListOf(\"Item 1\", \"Item 2\"))\n\n    composeTestRule.setContent {\n      JetLimeColumn(\n        itemsList = itemsList,\n        itemContent = { _, item, _ ->\n          JetLimeEvent {\n            Text(text = item)\n          }\n        },\n      )\n    }\n\n    // Check if the items are displayed\n    composeTestRule.onNodeWithText(\"Item 1\").assertIsDisplayed()\n    composeTestRule.onNodeWithText(\"Item 2\").assertIsDisplayed()\n  }\n\n  @Test\n  fun jetLimeColumn_appliesCustomJetLimeStyle() {\n    val itemsList = ItemsList(listOf(\"Item 1\", \"Item 2\"))\n    val contentDistance = 32.dp\n    val itemSpacing = 32.dp\n    val lineThickness = 10.dp\n    val lineBrushColor = Color.Blue\n    val lineVerticalAlign = VerticalAlignment.RIGHT\n\n    composeTestRule.setContent {\n      JetLimeColumn(\n        itemsList = itemsList,\n        style = JetLimeDefaults.columnStyle(\n          contentDistance = contentDistance,\n          itemSpacing = itemSpacing,\n          lineThickness = lineThickness,\n          lineBrush = lineSolidBrush(color = lineBrushColor),\n          lineVerticalAlignment = lineVerticalAlign,\n        ),\n        itemContent = { _, item, _ ->\n          JetLimeEvent {\n            Text(text = item)\n          }\n\n          // Check if the style is applied\n          with(LocalJetLimeStyle.current) {\n            assertThat(this.contentDistance).isEqualTo(contentDistance)\n            assertThat(this.itemSpacing).isEqualTo(itemSpacing)\n            assertThat(this.lineThickness).isEqualTo(lineThickness)\n            assertThat(this.lineBrush).isEqualTo(SolidColor(lineBrushColor))\n            assertThat(this.lineVerticalAlignment).isEqualTo(lineVerticalAlign)\n          }\n        },\n      )\n    }\n  }\n\n  @Test\n  fun jetLimeColumn_appliesCustomEvenStyle() {\n    val itemsList = ItemsList(persistentListOf(\"Item 1\"))\n    val pointRadius = 12.dp\n    val paddingApplied = 16.dp\n\n    composeTestRule.setContent {\n      JetLimeColumn(\n        modifier = Modifier.padding(paddingApplied),\n        itemsList = itemsList,\n        itemContent = { _, item, pos ->\n          JetLimeEvent(\n            style = JetLimeEventDefaults.eventStyle(\n              position = pos,\n              pointType = EventPointType.filled(0.7f),\n              pointColor = Color.DarkGray,\n              pointFillColor = Color.Cyan,\n              pointRadius = pointRadius,\n              pointAnimation = JetLimeEventDefaults.pointAnimation(),\n              pointStrokeWidth = 8.dp,\n              pointStrokeColor = Color.Magenta,\n            ),\n          ) {\n            Text(text = item)\n          }\n        },\n      )\n    }\n\n    // Check if the style is applied\n    composeTestRule.onNodeWithTag(\"VerticalEventContentBox\")\n      .assertPositionInRootIsEqualTo(paddingApplied, paddingApplied)\n  }\n\n  @Test\n  fun jetLimeColumn_eventHandlesClick() {\n    val itemsList = ItemsList(persistentListOf(\"Item 1\", \"Item 2\"))\n    var clickFlag = 0\n\n    composeTestRule.setContent {\n      JetLimeColumn(\n        itemsList = itemsList,\n        itemContent = { _, item, _ ->\n          JetLimeEvent(\n            modifier = Modifier.clickable {\n              clickFlag++\n            },\n          ) {\n            Text(text = item)\n          }\n        },\n      )\n    }\n\n    assertThat(clickFlag).isEqualTo(0)\n\n    // Perform click action\n    composeTestRule.onNodeWithText(\"Item 1\").performClick()\n\n    // Assertions to verify the result of the click\n    assertThat(clickFlag).isEqualTo(1)\n  }\n\n  @Test\n  fun jetLimeColumn_handlesScrolling() {\n    val longItemList = ItemsList((1..100).map { \"Item $it\" })\n\n    composeTestRule.setContent {\n      JetLimeColumn(\n        modifier = Modifier.testTag(\"JetLimeColumn\"),\n        itemsList = longItemList,\n        key = { _, item -> item },\n        itemContent = { _, item, _ ->\n          JetLimeEvent {\n            Text(text = item)\n          }\n        },\n      )\n    }\n\n    // Perform scroll action\n    composeTestRule.onNodeWithTag(\"JetLimeColumn\")\n      .performScrollToNode(hasText(\"Item 80\"))\n\n    // Assertions to check if the scrolling occurred\n    composeTestRule.onNodeWithText(\"Item 80\")\n      .assertIsDisplayed()\n  }\n\n  @Test\n  fun jetLimeColumn_handlesDynamicContent() {\n    val items = mutableStateListOf(\"Initial Item\")\n    composeTestRule.setContent {\n      JetLimeColumn(\n        itemsList = ItemsList(items),\n        itemContent = { _, item, _ ->\n          JetLimeEvent {\n            Text(text = item)\n          }\n        },\n      )\n    }\n    composeTestRule.onNodeWithText(\"Initial Item\").assertIsDisplayed()\n\n    items.add(\"Next Item\")\n    composeTestRule.onNodeWithText(\"Next Item\").assertIsDisplayed()\n\n    items.add(\"Another Item\")\n    composeTestRule.onNodeWithText(\"Another Item\").assertIsDisplayed()\n  }\n\n  @Test\n  fun jetLimeColumn_ltr_contentIsVisible() {\n    val itemsList = ItemsList(persistentListOf(\"Item 1\", \"Item 2\", \"Item 3\"))\n\n    composeTestRule.setContent {\n      CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {\n        JetLimeColumn(\n          itemsList = itemsList,\n          itemContent = { _, item, pos ->\n            JetLimeEvent(\n              style = JetLimeEventDefaults.eventStyle(position = pos),\n            ) {\n              Text(text = item, modifier = Modifier.testTag(\"ColumnItem_$item\"))\n            }\n          },\n        )\n      }\n    }\n\n    composeTestRule.onNodeWithTag(\"ColumnItem_Item 1\").assertIsDisplayed()\n    composeTestRule.onNodeWithTag(\"ColumnItem_Item 3\").assertIsDisplayed()\n  }\n\n  @OptIn(ExperimentalComposeApi::class)\n  @Test\n  fun jetLimeColumn_extendedEvent_rtl_contentsAreVisible() {\n    val itemsList = ItemsList(persistentListOf(\"Item 1\"))\n\n    composeTestRule.setContent {\n      CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {\n        JetLimeColumn(\n          itemsList = itemsList,\n          itemContent = { _, item, pos ->\n            JetLimeExtendedEvent(\n              style = JetLimeEventDefaults.eventStyle(position = pos),\n              additionalContent = {\n                Text(text = \"Additional\", modifier = Modifier.testTag(\"ExtendedAdditional\"))\n              },\n            ) {\n              Text(text = item, modifier = Modifier.testTag(\"ExtendedMain\"))\n            }\n          },\n        )\n      }\n    }\n\n    composeTestRule.onNodeWithTag(\"ExtendedAdditional\").assertIsDisplayed()\n    composeTestRule.onNodeWithTag(\"ExtendedMain\").assertIsDisplayed()\n  }\n}\n"
  },
  {
    "path": "jetlime/src/androidTest/java/com/pushpal/jetlime/JetLimeRowTest.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport android.annotation.SuppressLint\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.ExperimentalComposeApi\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.platform.testTag\nimport androidx.compose.ui.test.assertIsDisplayed\nimport androidx.compose.ui.test.assertPositionInRootIsEqualTo\nimport androidx.compose.ui.test.hasText\nimport androidx.compose.ui.test.junit4.createComposeRule\nimport androidx.compose.ui.test.onNodeWithTag\nimport androidx.compose.ui.test.onNodeWithText\nimport androidx.compose.ui.test.performClick\nimport androidx.compose.ui.test.performScrollToNode\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport androidx.test.ext.junit.runners.AndroidJUnit4\nimport com.google.common.truth.Truth.assertThat\nimport com.pushpal.jetlime.JetLimeDefaults.lineSolidBrush\nimport kotlinx.collections.immutable.persistentListOf\nimport org.junit.Rule\nimport org.junit.Test\nimport org.junit.runner.RunWith\n\n@SuppressLint(\"ComposableNaming\")\n@RunWith(AndroidJUnit4::class)\nclass JetLimeRowTest {\n\n  @get:Rule\n  val composeTestRule = createComposeRule()\n\n  @Test\n  fun jetLimeRow_displaysItems() {\n    // Prepare a list of items to display\n    val itemsList = ItemsList(persistentListOf(\"Item 1\", \"Item 2\"))\n\n    composeTestRule.setContent {\n      JetLimeRow(\n        itemsList = itemsList,\n        itemContent = { _, item, _ ->\n          Text(text = item)\n        },\n      )\n    }\n\n    // Check if the items are displayed\n    composeTestRule.onNodeWithText(\"Item 1\").assertIsDisplayed()\n    composeTestRule.onNodeWithText(\"Item 2\").assertIsDisplayed()\n  }\n\n  @Test\n  fun jetLimeRow_displaysJetLimeItems() {\n    // Prepare a list of items to display\n    val itemsList = ItemsList(persistentListOf(\"Item 1\", \"Item 2\"))\n\n    composeTestRule.setContent {\n      JetLimeRow(\n        itemsList = itemsList,\n        itemContent = { _, item, _ ->\n          JetLimeEvent {\n            Text(text = item)\n          }\n        },\n      )\n    }\n\n    // Check if the items are displayed\n    composeTestRule.onNodeWithText(\"Item 1\").assertIsDisplayed()\n    composeTestRule.onNodeWithText(\"Item 2\").assertIsDisplayed()\n  }\n\n  @Test\n  fun jetLimeRow_appliesCustomJetLimeStyle() {\n    val itemsList = ItemsList(listOf(\"Item 1\", \"Item 2\"))\n    val contentDistance = 32.dp\n    val itemSpacing = 32.dp\n    val lineThickness = 10.dp\n    val lineBrushColor = Color.Blue\n    val lineHorizontalAlign = HorizontalAlignment.BOTTOM\n\n    composeTestRule.setContent {\n      JetLimeRow(\n        itemsList = itemsList,\n        style = JetLimeDefaults.rowStyle(\n          contentDistance = contentDistance,\n          itemSpacing = itemSpacing,\n          lineThickness = lineThickness,\n          lineBrush = lineSolidBrush(color = lineBrushColor),\n          lineHorizontalAlignment = lineHorizontalAlign,\n        ),\n        itemContent = { _, item, _ ->\n          JetLimeEvent {\n            Text(text = item)\n          }\n\n          // Check if the style is applied\n          with(LocalJetLimeStyle.current) {\n            assertThat(this.contentDistance).isEqualTo(contentDistance)\n            assertThat(this.itemSpacing).isEqualTo(itemSpacing)\n            assertThat(this.lineThickness).isEqualTo(lineThickness)\n            assertThat(this.lineBrush).isEqualTo(SolidColor(lineBrushColor))\n            assertThat(this.lineHorizontalAlignment).isEqualTo(lineHorizontalAlign)\n          }\n        },\n      )\n    }\n  }\n\n  @Test\n  fun jetLimeRow_appliesCustomEvenStyle() {\n    val itemsList = ItemsList(persistentListOf(\"Item 1\"))\n    val pointRadius = 12.dp\n    val paddingApplied = 16.dp\n\n    composeTestRule.setContent {\n      JetLimeRow(\n        modifier = Modifier.padding(paddingApplied),\n        itemsList = itemsList,\n        itemContent = { _, item, pos ->\n          JetLimeEvent(\n            style = JetLimeEventDefaults.eventStyle(\n              position = pos,\n              pointType = EventPointType.filled(0.7f),\n              pointColor = Color.DarkGray,\n              pointFillColor = Color.Cyan,\n              pointRadius = pointRadius,\n              pointAnimation = JetLimeEventDefaults.pointAnimation(),\n              pointStrokeWidth = 8.dp,\n              pointStrokeColor = Color.Magenta,\n            ),\n          ) {\n            Text(text = item)\n          }\n        },\n      )\n    }\n\n    // Check if the style is applied\n    composeTestRule.onNodeWithTag(\"HorizontalEventContentBox\")\n      .assertPositionInRootIsEqualTo(paddingApplied, paddingApplied)\n  }\n\n  @Test\n  fun jetLimeRow_eventHandlesClick() {\n    val itemsList = ItemsList(persistentListOf(\"Item 1\", \"Item 2\"))\n    var clickFlag = 0\n\n    composeTestRule.setContent {\n      JetLimeRow(\n        itemsList = itemsList,\n        itemContent = { _, item, _ ->\n          JetLimeEvent(\n            modifier = Modifier.clickable {\n              clickFlag++\n            },\n          ) {\n            Text(text = item)\n          }\n        },\n      )\n    }\n\n    assertThat(clickFlag).isEqualTo(0)\n\n    // Perform click action\n    composeTestRule.onNodeWithText(\"Item 1\").performClick()\n\n    // Assertions to verify the result of the click\n    assertThat(clickFlag).isEqualTo(1)\n  }\n\n  @Test\n  fun jetLimeRow_handlesScrolling() {\n    val longItemList = ItemsList((1..100).map { \"Item $it\" })\n\n    composeTestRule.setContent {\n      JetLimeRow(\n        modifier = Modifier.testTag(\"JetLimeRow\"),\n        itemsList = longItemList,\n        key = { _, item -> item },\n        itemContent = { _, item, _ ->\n          JetLimeEvent {\n            Text(text = item)\n          }\n        },\n      )\n    }\n\n    // Perform scroll action\n    composeTestRule.onNodeWithTag(\"JetLimeRow\")\n      .performScrollToNode(hasText(\"Item 80\"))\n\n    // Assertions to check if the scrolling occurred\n    composeTestRule.onNodeWithText(\"Item 80\")\n      .assertIsDisplayed()\n  }\n\n  @Test\n  fun jetLimeRow_handlesDynamicContent() {\n    val items = mutableStateListOf(\"Initial Item\")\n    composeTestRule.setContent {\n      JetLimeRow(\n        itemsList = ItemsList(items),\n        itemContent = { _, item, _ ->\n          JetLimeEvent {\n            Text(text = item)\n          }\n        },\n      )\n    }\n    composeTestRule.onNodeWithText(\"Initial Item\").assertIsDisplayed()\n\n    items.add(\"Next Item\")\n    composeTestRule.onNodeWithText(\"Next Item\").assertIsDisplayed()\n\n    items.add(\"Another Item\")\n    composeTestRule.onNodeWithText(\"Another Item\").assertIsDisplayed()\n  }\n\n  @Test\n  fun jetLimeRow_horizontalEvent_ltr_contentIsVisible() {\n    val itemsList = ItemsList(persistentListOf(\"Item 1\", \"Item 2\", \"Item 3\"))\n\n    composeTestRule.setContent {\n      CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {\n        JetLimeRow(\n          itemsList = itemsList,\n          itemContent = { _, item, pos ->\n            JetLimeEvent(\n              style = JetLimeEventDefaults.eventStyle(\n                position = pos,\n                pointPlacement = PointPlacement.CENTER,\n              ),\n            ) {\n              Text(text = item, modifier = Modifier.testTag(\"RowItem_$item\"))\n            }\n          },\n        )\n      }\n    }\n\n    composeTestRule.onNodeWithTag(\"RowItem_Item 1\").assertIsDisplayed()\n    composeTestRule.onNodeWithTag(\"RowItem_Item 3\").assertIsDisplayed()\n  }\n\n  @Test\n  fun jetLimeRow_horizontalEvent_rtl_contentIsVisible() {\n    val itemsList = ItemsList(persistentListOf(\"Item 1\", \"Item 2\", \"Item 3\"))\n\n    composeTestRule.setContent {\n      CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {\n        JetLimeRow(\n          itemsList = itemsList,\n          itemContent = { _, item, pos ->\n            JetLimeEvent(\n              style = JetLimeEventDefaults.eventStyle(\n                position = pos,\n                pointPlacement = PointPlacement.CENTER,\n              ),\n            ) {\n              Text(text = item, modifier = Modifier.testTag(\"RowItem_$item\"))\n            }\n          },\n        )\n      }\n    }\n\n    composeTestRule.onNodeWithTag(\"RowItem_Item 1\").assertIsDisplayed()\n    composeTestRule.onNodeWithTag(\"RowItem_Item 3\").assertIsDisplayed()\n  }\n\n  @OptIn(ExperimentalComposeApi::class)\n  @Test\n  fun jetLimeExtendedEvent_ltr_contentsAreVisible() {\n    val itemsList = ItemsList(persistentListOf(\"Item 1\"))\n\n    composeTestRule.setContent {\n      CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Ltr) {\n        JetLimeColumn(\n          itemsList = itemsList,\n          itemContent = { _, item, pos ->\n            JetLimeExtendedEvent(\n              style = JetLimeEventDefaults.eventStyle(position = pos),\n              additionalContent = {\n                Text(text = \"Additional\", modifier = Modifier.testTag(\"ExtendedAdditional_LTR\"))\n              },\n            ) {\n              Text(text = item, modifier = Modifier.testTag(\"ExtendedMain_LTR\"))\n            }\n          },\n        )\n      }\n    }\n\n    composeTestRule.onNodeWithTag(\"ExtendedAdditional_LTR\").assertIsDisplayed()\n    composeTestRule.onNodeWithTag(\"ExtendedMain_LTR\").assertIsDisplayed()\n  }\n\n  @OptIn(ExperimentalComposeApi::class)\n  @Test\n  fun jetLimeExtendedEvent_rtl_contentsAreVisible() {\n    val itemsList = ItemsList(persistentListOf(\"Item 1\"))\n\n    composeTestRule.setContent {\n      CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {\n        JetLimeColumn(\n          itemsList = itemsList,\n          itemContent = { _, item, pos ->\n            JetLimeExtendedEvent(\n              style = JetLimeEventDefaults.eventStyle(position = pos),\n              additionalContent = {\n                Text(text = \"Additional\", modifier = Modifier.testTag(\"ExtendedAdditional_RTL\"))\n              },\n            ) {\n              Text(text = item, modifier = Modifier.testTag(\"ExtendedMain_RTL\"))\n            }\n          },\n        )\n      }\n    }\n\n    composeTestRule.onNodeWithTag(\"ExtendedAdditional_RTL\").assertIsDisplayed()\n    composeTestRule.onNodeWithTag(\"ExtendedMain_RTL\").assertIsDisplayed()\n  }\n}\n"
  },
  {
    "path": "jetlime/src/commonMain/kotlin/com/pushpal/jetlime/EventPointAnimation.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport androidx.compose.animation.core.InfiniteRepeatableSpec\nimport androidx.compose.runtime.Immutable\n\n/**\n * Represents an animation configuration for an event point in a UI component.\n * This animation defines how an event point (circle) should animate, including its initial value, target value, and the specification of the animation.\n *\n * - See [JetLimeEventDefaults.pointAnimation] for the default point animation used in a [JetLimeEvent].\n *\n * @property initialValue The starting value of the animation.\n * @property targetValue The ending value of the animation.\n * @property animationSpec The specification of the animation, including duration, easing, and repeat behavior.\n */\n@Immutable\nclass EventPointAnimation internal constructor(\n  val initialValue: Float,\n  val targetValue: Float,\n  val animationSpec: InfiniteRepeatableSpec<Float>,\n) {\n  /**\n   * Compares this EventPointAnimation with another object for equality.\n   * The result is `true` if and only if the argument is not `null`, is an `EventPointAnimation` object,\n   * and has the same values for `initialValue`, `targetValue`, and `animationSpec`.\n   *\n   * @param other The object to compare this `EventPointAnimation` against.\n   * @return `true` if the given object represents an `EventPointAnimation` equivalent to this instance, `false` otherwise.\n   */\n  override fun equals(other: Any?): Boolean {\n    if (this === other) return true\n    if (other !is EventPointAnimation) return false\n\n    if (initialValue != other.initialValue) return false\n    if (targetValue != other.targetValue) return false\n    return animationSpec == other.animationSpec\n  }\n\n  /**\n   * Returns a hash code value for the object, consistent with the definition of equality for the class.\n   * This method is supported for the benefit of hash tables such as those provided by `HashMap`.\n   *\n   * @return A hash code value for this object.\n   */\n  override fun hashCode(): Int {\n    var result = initialValue.hashCode()\n    result = 31 * result + targetValue.hashCode()\n    result = 31 * result + animationSpec.hashCode()\n    return result\n  }\n}\n"
  },
  {
    "path": "jetlime/src/commonMain/kotlin/com/pushpal/jetlime/EventPointType.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.painter.Painter\n\n/**\n * Represents a type of event point in a UI component with an optional icon. This class is used to define\n * different types of event points such as empty, filled, or custom types with specific icons.\n *\n * @property type The name of the event point type.\n * @property icon An optional [Painter] icon associated with the event point type.\n * @property tint An optional tint [Color] overlay for the icon.\n * @property fillPercent An optional percentage value for the [FILLED] type\n */\n@Immutable\nclass EventPointType internal constructor(\n  val type: String,\n  val icon: Painter? = null,\n  val tint: Color? = null,\n  val fillPercent: Float? = null,\n) {\n  companion object {\n    /** Represents an empty event point type. */\n    val EMPTY = EventPointType(\"Empty\")\n\n    /** Internal constant used for filled event point types. */\n    internal const val FILLED = \"Filled\"\n\n    /** Internal constant used for custom event point types. */\n    internal const val CUSTOM = \"Custom\"\n\n    /** The default value of [EventPointType] */\n    val Default = filled()\n\n    /**\n     * Creates a custom event point type with a specified [Painter] icon.\n     *\n     * @param icon The [Painter] icon for the custom event point type.\n     * @param tint The optional tint [Color] of the custom icon.\n     * @return A new instance of [EventPointType] with the custom icon.\n     */\n    @Stable\n    fun custom(icon: Painter, tint: Color? = null): EventPointType =\n      EventPointType(type = CUSTOM, icon = icon, tint = tint)\n\n    /**\n     * Creates a filled event point type with a specified fill percentage.\n     *\n     * @param fillPercent The percentage of fill for the event point.\n     * @return A new instance of [EventPointType] with the filled icon.\n     */\n    @Stable\n    fun filled(fillPercent: Float = 0.5f): EventPointType =\n      EventPointType(type = FILLED, fillPercent = fillPercent)\n  }\n\n  /**\n   * A helper function to check if the current [EventPointType] is [FILLED]\n   *\n   * @return `true` if the current EventPointType is filled, `false` otherwise.\n   */\n  @Stable\n  fun isFilled(): Boolean = this.type == FILLED\n\n  /**\n   * A helper function to check if the current [EventPointType] is [CUSTOM]\n   *\n   * @return `true` if the current EventPointType is custom, `false` otherwise.\n   */\n  @Stable\n  fun isCustom(): Boolean = this.type == CUSTOM\n\n  /**\n   * A helper function to check if the current [EventPointType] is [EMPTY] or [FILLED]\n   *\n   * @return `true` if the current EventPointType is empty or filled, `false` otherwise.\n   */\n  @Stable\n  fun isEmptyOrFilled(): Boolean = this == EMPTY || this.type == FILLED\n\n  /**\n   * Checks if this instance is equal to another object. Two instances of [EventPointType] are\n   * considered equal if they have the same type and icon.\n   *\n   * @param other The object to compare this instance with.\n   * @return `true` if the other object is an instance of [EventPointType] and has the same type and icon, `false` otherwise.\n   */\n  override fun equals(other: Any?): Boolean {\n    if (this === other) return true\n    if (other !is EventPointType) return false\n    if (type != other.type) return false\n    if (tint != other.tint) return false\n    if (fillPercent != other.fillPercent) return false\n    return icon == other.icon\n  }\n\n  /**\n   * Returns a hash code value for the object, which is consistent with the definition of equality for the class.\n   * This supports the use in hash tables, like those provided by `HashMap`.\n   *\n   * @return A hash code value for this object.\n   */\n  override fun hashCode(): Int {\n    var result = type.hashCode()\n    result = 31 * result + icon.hashCode()\n    result = 31 * result + tint.hashCode()\n    result = 31 * result + fillPercent.hashCode()\n    return result\n  }\n}\n"
  },
  {
    "path": "jetlime/src/commonMain/kotlin/com/pushpal/jetlime/EventPosition.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\n\n/**\n * Represents a position of an event within a sequence, such as the start, middle, or end.\n * This class encapsulates the logic for determining the position based on the index in a list.\n *\n * @property name The name of the event position.\n */\n@Immutable\nclass EventPosition internal constructor(val name: String) {\n  companion object {\n\n    /** Represents the start position in a sequence. */\n    internal val START = EventPosition(\"Start\")\n\n    /** Represents the middle position in a sequence. */\n    private val MIDDLE = EventPosition(\"Middle\")\n\n    /** Represents the end position in a sequence. */\n    internal val END = EventPosition(\"End\")\n\n    /**\n     * Determines the event position dynamically based on the index and the size of the list.\n     *\n     * @param index The index of the item in the list.\n     * @param listSize The total size of the list.\n     * @return [EventPosition] corresponding to the index in the list.\n     */\n    @Stable\n    fun dynamic(index: Int, listSize: Int) = eventPosition(index, listSize)\n\n    /**\n     * Internal function to determine the event position based on index and list size.\n     */\n    @Stable\n    private fun eventPosition(index: Int, listSize: Int) = when (index) {\n      listSize - 1 -> END\n      0 -> START\n      else -> MIDDLE\n    }\n  }\n\n  /**\n   * A helper function to check if the current position is not the end position.\n   * This can be useful for determining layout or drawing logic based on the position of an event.\n   *\n   * @return `true` if the current position is not the end, `false` otherwise.\n   */\n  @Stable\n  fun isNotEnd(): Boolean = this != END\n\n  /** Helper to check if current position is not the start. */\n  @Stable\n  fun isNotStart(): Boolean = this != START\n\n  /**\n   * Checks if this instance is equal to another object. Two instances of [EventPosition] are\n   * considered equal if they have the same name.\n   *\n   * @param other The object to compare this instance with.\n   * @return `true` if the other object is an instance of [EventPosition] and has the same name, `false` otherwise.\n   */\n  override fun equals(other: Any?): Boolean {\n    if (this === other) return true\n    if (other !is EventPosition) return false\n    return name == other.name\n  }\n\n  /**\n   * Returns a hash code value for the object, which is consistent with the definition of equality for the class.\n   * This supports the use in hash tables, like those provided by `HashMap`.\n   *\n   * @return A hash code value for this object.\n   */\n  override fun hashCode(): Int = name.hashCode()\n}\n"
  },
  {
    "path": "jetlime/src/commonMain/kotlin/com/pushpal/jetlime/ItemsList.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport androidx.compose.runtime.Immutable\n\n/**\n * An immutable list class that holds a list of items of type [T].\n *\n * This class provides an immutable wrapper around a standard list, ensuring that the contents cannot be modified after creation.\n * It overrides `equals` and `hashCode` methods to provide proper equality checks and hash code generation based on the list contents.\n *\n * @param T The type of elements in the list.\n * @property items The list of items contained in this `ItemsList`.\n */\n@Immutable\nclass ItemsList<T>(val items: List<T>) {\n\n  /**\n   * Compares this `ItemsList` object with another object for equality.\n   * The comparison checks whether the other object is also an `ItemsList` and contains the same items in the same order.\n   *\n   * @param other The object to compare with this `ItemsList`.\n   * @return `true` if the other object is an `ItemsList` with the same items, `false` otherwise.\n   */\n  override fun equals(other: Any?): Boolean {\n    if (this === other) return true\n    if (other !is ItemsList<*>) return false\n    return items == other.items\n  }\n\n  /**\n   * Generates a hash code for this `ItemsList`.\n   * The hash code is generated based on the items in the list.\n   *\n   * @return The hash code value for this `ItemsList`.\n   */\n  override fun hashCode(): Int = items.hashCode()\n}\n"
  },
  {
    "path": "jetlime/src/commonMain/kotlin/com/pushpal/jetlime/JetLimeDefaults.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.graphics.PathEffect\nimport androidx.compose.ui.graphics.SolidColor\nimport androidx.compose.ui.graphics.TileMode\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\nimport com.pushpal.jetlime.HorizontalAlignment.BOTTOM\nimport com.pushpal.jetlime.HorizontalAlignment.TOP\nimport com.pushpal.jetlime.VerticalAlignment.LEFT\nimport com.pushpal.jetlime.VerticalAlignment.RIGHT\nimport kotlinx.collections.immutable.ImmutableList\nimport kotlinx.collections.immutable.persistentListOf\n\n/**\n * Provides default values and utility functions for [JetLimeColumn] or [JetLimeRow] styling.\n *\n * This object contains default values and composable functions that create different types of brushes and a default [JetLimeStyle].\n * It acts as a utility provider for the [JetLimeColumn] or [JetLimeRow] component styling, allowing for consistent default styling across the application.\n */\nobject JetLimeDefaults {\n  private val LineThickness: Dp = 4.dp\n  private val ContentDistance: Dp = 16.dp\n  private val ItemSpacing: Dp = 8.dp\n\n  /**\n   * Creates a linear gradient brush for lines in [JetLimeColumn] or [JetLimeRow] components.\n   *\n   * @param colors The colors to be used in the gradient. Defaults to primary, secondary, and tertiary colors from MaterialTheme's color scheme.\n   * @param start The start offset for the gradient.\n   * @param end The end offset for the gradient.\n   * @param tileMode The tile mode for the gradient.\n   * @return A [Brush] object representing a linear gradient.\n   */\n  @Composable\n  fun lineGradientBrush(\n    colors: ImmutableList<Color> = persistentListOf(\n      MaterialTheme.colorScheme.primary,\n      MaterialTheme.colorScheme.secondary,\n      MaterialTheme.colorScheme.tertiary,\n    ),\n    start: Offset = Offset.Zero,\n    end: Offset = Offset.Infinite,\n    tileMode: TileMode = TileMode.Clamp,\n  ): Brush = Brush.linearGradient(\n    colors = colors,\n    start = start,\n    end = end,\n    tileMode = tileMode,\n  )\n\n  /**\n   * Creates a solid color brush for lines in [JetLimeColumn] or [JetLimeRow] components.\n   *\n   * @param color The color to be used for the brush. Defaults to the primary color from MaterialTheme's color scheme.\n   * @return A [Brush] object representing a solid color.\n   */\n  @Composable\n  fun lineSolidBrush(color: Color = MaterialTheme.colorScheme.primary): Brush = SolidColor(color)\n\n  /**\n   * Creates a default [JetLimeStyle] object with specified parameters.\n   *\n   * @param contentDistance The distance of content from the start of the JetLime component.\n   * @param itemSpacing The spacing between items in the JetLime component.\n   * @param lineThickness The thickness of the line in the JetLime component.\n   * @param lineBrush The brush used for the line in the JetLime component.\n   * @param pathEffect the effect applied to the geometry of the timeline to obtain a dashed pattern.\n   * @param lineHorizontalAlignment The horizontal alignment of the line in the JetLime component.\n   * @param lineVerticalAlignment The vertical alignment of the line in the JetLime component.\n   * @return A [JetLimeStyle] object configured with the given parameters.\n   */\n  @Composable\n  internal fun jetLimeStyle(\n    contentDistance: Dp,\n    itemSpacing: Dp,\n    lineThickness: Dp,\n    lineBrush: Brush,\n    pathEffect: PathEffect?,\n    lineHorizontalAlignment: HorizontalAlignment = TOP,\n    lineVerticalAlignment: VerticalAlignment = LEFT,\n  ): JetLimeStyle = JetLimeStyle(\n    contentDistance = contentDistance,\n    itemSpacing = itemSpacing,\n    lineThickness = lineThickness,\n    lineBrush = lineBrush,\n    pathEffect = pathEffect,\n    lineHorizontalAlignment = lineHorizontalAlignment,\n    lineVerticalAlignment = lineVerticalAlignment,\n  )\n\n  /**\n   * Creates a column style configuration for [JetLimeColumn].\n   *\n   * @param contentDistance The distance of content from the JetLime component's start.\n   * @param itemSpacing The spacing between items in the JetLime component.\n   * @param lineThickness The thickness of the line in the JetLime component.\n   * @param lineBrush The brush used for the line in the JetLime component.\n   * @param pathEffect the effect applied to the geometry of the timeline to obtain a dashed pattern.\n   * @param lineVerticalAlignment The vertical alignment of the line: [LEFT] or [RIGHT]\n   * @return A [JetLimeStyle] instance configured for column arrangement.\n   */\n  @Composable\n  fun columnStyle(\n    contentDistance: Dp = ContentDistance,\n    itemSpacing: Dp = ItemSpacing,\n    lineThickness: Dp = LineThickness,\n    lineBrush: Brush = lineSolidBrush(),\n    pathEffect: PathEffect? = null,\n    lineVerticalAlignment: VerticalAlignment = LEFT,\n  ) = jetLimeStyle(\n    contentDistance,\n    itemSpacing,\n    lineThickness,\n    lineBrush,\n    pathEffect,\n    lineVerticalAlignment = lineVerticalAlignment,\n  )\n\n  /**\n   * Creates a row style configuration for [JetLimeRow].\n   *\n   * @param contentDistance The distance of content from the JetLime component's start.\n   * @param itemSpacing The spacing between items in the JetLime component.\n   * @param lineThickness The thickness of the line in the JetLime component.\n   * @param lineBrush The brush used for the line in the JetLime component.\n   * @param pathEffect the effect applied to the geometry of the timeline to obtain a dashed pattern.\n   * @param lineHorizontalAlignment The horizontal alignment of the line: [TOP] or [BOTTOM]\n   * @return A [JetLimeStyle] instance configured for row arrangement.\n   */\n  @Composable\n  fun rowStyle(\n    contentDistance: Dp = ContentDistance,\n    itemSpacing: Dp = ItemSpacing,\n    lineThickness: Dp = LineThickness,\n    lineBrush: Brush = lineSolidBrush(),\n    pathEffect: PathEffect? = null,\n    lineHorizontalAlignment: HorizontalAlignment = TOP,\n  ) = jetLimeStyle(\n    contentDistance,\n    itemSpacing,\n    lineThickness,\n    lineBrush,\n    pathEffect,\n    lineHorizontalAlignment = lineHorizontalAlignment,\n  )\n}\n"
  },
  {
    "path": "jetlime/src/commonMain/kotlin/com/pushpal/jetlime/JetLimeEvent.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport androidx.compose.animation.core.animateFloat\nimport androidx.compose.animation.core.rememberInfiniteTransition\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.absolutePadding\nimport androidx.compose.foundation.layout.defaultMinSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.wrapContentSize\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.State\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.drawBehind\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.drawscope.drawIntoCanvas\nimport androidx.compose.ui.graphics.drawscope.withTransform\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.platform.testTag\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport com.pushpal.jetlime.Arrangement.HORIZONTAL\nimport com.pushpal.jetlime.Arrangement.VERTICAL\n\n/**\n * Composable function for creating a [JetLimeColumn] or [JetLimeRow] event.\n *\n * Example usage:\n *\n * ```\n *  val items = remember { getItemsList() }\n *\n *  JetLimeColumn(\n *   itemsList = ItemsList(items),\n *   key = { _, item -> item.id },\n *   style = JetLimeDefaults.columnStyle(),\n *  ) { index, item, position ->\n *     JetLimeEvent(\n *      style = JetLimeEventDefaults.eventStyle(position = position)\n *     ) {\n *        ComposableContent(item = item)\n *       }\n *    }\n * ```\n *\n * @param modifier The modifier to be applied to the event.\n * @param style The style of the [JetLimeColumn] or [JetLimeRow] event, defaulting to [JetLimeEventDefaults.eventStyle].\n * @param content The composable content inside the event.\n */\n@Composable\nfun JetLimeEvent(\n  modifier: Modifier = Modifier,\n  style: JetLimeEventStyle = JetLimeEventDefaults.eventStyle(EventPosition.END),\n  content: @Composable () -> Unit,\n) {\n  val jetLimeStyle = LocalJetLimeStyle.current\n\n  when (jetLimeStyle.arrangement) {\n    VERTICAL -> VerticalEvent(\n      style,\n      jetLimeStyle,\n      modifier,\n      content,\n    )\n\n    HORIZONTAL -> HorizontalEvent(\n      style,\n      jetLimeStyle,\n      modifier,\n      content,\n    )\n  }\n}\n\n/**\n * Composable function for creating a vertical layout for the JetLime event.\n * This composable is used internally for a [JetLimeColumn].\n *\n * @param style The style of the [JetLimeEvent].\n * @param jetLimeStyle The [JetLimeEvent] style configuration.\n * @param modifier The modifier to be applied to the event.\n * @param content The composable content inside the event.\n */\n@Composable\ninternal fun VerticalEvent(\n  style: JetLimeEventStyle,\n  jetLimeStyle: JetLimeStyle,\n  modifier: Modifier = Modifier,\n  content: @Composable () -> Unit,\n) {\n  val verticalAlignment = jetLimeStyle.lineVerticalAlignment\n  val radiusAnimFactor by calculateRadiusAnimFactor(style)\n  Box(\n    modifier = modifier\n      .wrapContentSize()\n      .drawBehind {\n        val xOffset = when (verticalAlignment) {\n          VerticalAlignment.LEFT -> style.pointRadius.toPx()\n          VerticalAlignment.RIGHT -> this.size.width - style.pointRadius.toPx()\n        }\n        val yOffset = when (style.pointPlacement) {\n          PointPlacement.START -> style.pointRadius.toPx() * jetLimeStyle.pointStartFactor\n\n          PointPlacement.CENTER -> {\n            val effectiveHeight =\n              this.size.height -\n                if (style.position.isNotEnd()) jetLimeStyle.itemSpacing.toPx() else 0f\n            effectiveHeight / 2f\n          }\n\n          PointPlacement.END -> {\n            // Place at bottom minus radius (visual anchor). If not last, subtract spacing from height computation\n            val effectiveHeight =\n              this.size.height -\n                if (style.position.isNotEnd()) jetLimeStyle.itemSpacing.toPx() else 0f\n            effectiveHeight - style.pointRadius.toPx() * jetLimeStyle.pointStartFactor\n          }\n        }\n        val radius = style.pointRadius.toPx() * radiusAnimFactor\n        val strokeWidth = style.pointStrokeWidth.toPx()\n\n        // Line logic for CENTER placement: keep continuity through centers\n        if (style.pointPlacement == PointPlacement.CENTER) {\n          // Upward segment (skip for first item)\n          if (style.position.isNotStart()) {\n            drawLine(\n              brush = jetLimeStyle.lineBrush,\n              start = Offset(x = xOffset, y = 0f),\n              end = Offset(x = xOffset, y = yOffset),\n              strokeWidth = jetLimeStyle.lineThickness.toPx(),\n              pathEffect = jetLimeStyle.pathEffect,\n            )\n          }\n          // Downward segment (skip for last item)\n          if (style.position.isNotEnd()) {\n            drawLine(\n              brush = jetLimeStyle.lineBrush,\n              start = Offset(x = xOffset, y = yOffset),\n              end = Offset(x = xOffset, y = this.size.height),\n              strokeWidth = jetLimeStyle.lineThickness.toPx(),\n              pathEffect = jetLimeStyle.pathEffect,\n            )\n          }\n        } else if (style.pointPlacement == PointPlacement.END) {\n          // END placement: draw upward segment (skip first) from top to end point; draw downward only if not last (from point to bottom)\n          if (style.position.isNotStart()) {\n            drawLine(\n              brush = jetLimeStyle.lineBrush,\n              start = Offset(x = xOffset, y = 0f),\n              end = Offset(x = xOffset, y = yOffset),\n              strokeWidth = jetLimeStyle.lineThickness.toPx(),\n              pathEffect = jetLimeStyle.pathEffect,\n            )\n          }\n          if (style.position.isNotEnd()) {\n            drawLine(\n              brush = jetLimeStyle.lineBrush,\n              start = Offset(x = xOffset, y = yOffset),\n              end = Offset(x = xOffset, y = this.size.height),\n              strokeWidth = jetLimeStyle.lineThickness.toPx(),\n              pathEffect = jetLimeStyle.pathEffect,\n            )\n          }\n        } else {\n          // START placement logic (unchanged)\n          if (style.position.isNotEnd()) {\n            val endY = run {\n              val yShift = yOffset * (jetLimeStyle.pointStartFactor - 1)\n              this.size.height + yShift\n            }\n            drawLine(\n              brush = jetLimeStyle.lineBrush,\n              start = Offset(x = xOffset, y = yOffset),\n              end = Offset(x = xOffset, y = endY),\n              strokeWidth = jetLimeStyle.lineThickness.toPx(),\n              pathEffect = jetLimeStyle.pathEffect,\n            )\n          }\n        }\n\n        // Point background\n        drawCircle(\n          color = style.pointColor,\n          radius = radius,\n          center = Offset(x = xOffset, y = yOffset),\n        )\n\n        // Point center fill\n        if (style.pointType.isFilled()) {\n          drawCircle(\n            color = style.pointFillColor,\n            radius = radius - radius * (1 - (style.pointType.fillPercent ?: 1f)),\n            center = Offset(x = xOffset, y = yOffset),\n          )\n        }\n        // Point custom icon\n        if (style.pointType.isCustom()) {\n          style.pointType.icon?.let { painter ->\n            val pointSizeInPixels = style.pointRadius.toPx() * 2.4f * radiusAnimFactor\n            val iconSize = Size(pointSizeInPixels, pointSizeInPixels)\n            this.withTransform(\n              transformBlock = {\n                translate(\n                  left = xOffset - iconSize.width / 2f,\n                  top = yOffset - iconSize.height / 2f,\n                )\n              },\n              drawBlock = {\n                this.drawIntoCanvas {\n                  with(painter) {\n                    val tint = style.pointType.tint?.let { ColorFilter.tint(it) }\n                    draw(size = iconSize, colorFilter = tint)\n                  }\n                }\n              },\n            )\n          }\n        }\n\n        // Point border\n        if (strokeWidth > 0f) {\n          drawCircle(\n            color = style.pointStrokeColor,\n            radius = radius - strokeWidth / 2,\n            center = Offset(x = xOffset, y = yOffset),\n            style = Stroke(width = strokeWidth),\n          )\n        }\n      },\n  ) {\n    PlaceVerticalEventContent(style, jetLimeStyle, verticalAlignment, content)\n  }\n}\n\n/**\n * Composable function to place the content within a [VerticalEvent].\n *\n * @param style The style of the [JetLimeEvent].\n * @param jetLimeStyle The JetLime style configuration.\n * @param alignment The vertical alignment for the event.\n * @param content The composable content to be placed.\n */\n@Composable\nprivate fun PlaceVerticalEventContent(\n  style: JetLimeEventStyle,\n  jetLimeStyle: JetLimeStyle,\n  alignment: VerticalAlignment,\n  content: @Composable () -> Unit,\n) {\n  val leftPad = if (alignment == VerticalAlignment.LEFT) {\n    // Physical left side padding irrespective of layout direction\n    style.pointRadius * 2 + jetLimeStyle.contentDistance\n  } else {\n    0.dp\n  }\n  val rightPad = if (alignment == VerticalAlignment.RIGHT) {\n    style.pointRadius * 2 + jetLimeStyle.contentDistance\n  } else {\n    0.dp\n  }\n  Box(\n    modifier = Modifier\n      .testTag(\"VerticalEventContentBox\")\n      .defaultMinSize(minHeight = style.pointRadius * 2)\n      // Use absolutePadding so LEFT/RIGHT alignment refers to physical sides, not start/end semantics.\n      .absolutePadding(\n        left = leftPad,\n        right = rightPad,\n        top = 0.dp,\n        bottom = if (style.position.isNotEnd()) jetLimeStyle.itemSpacing else 0.dp,\n      ),\n  ) {\n    content()\n  }\n}\n\n/**\n * Composable function for creating a horizontal layout for the [JetLimeEvent].\n * This composable is used internally for a [JetLimeRow].\n *\n * @param style The style of the [JetLimeEvent].\n * @param jetLimeStyle The [JetLimeEvent] style configuration.\n * @param modifier The modifier to be applied to the event.\n * @param content The composable content inside the event.\n */\n@Composable\ninternal fun HorizontalEvent(\n  style: JetLimeEventStyle,\n  jetLimeStyle: JetLimeStyle,\n  modifier: Modifier = Modifier,\n  content: @Composable () -> Unit,\n) {\n  val horizontalAlignment = jetLimeStyle.lineHorizontalAlignment\n  val radiusAnimFactor by calculateRadiusAnimFactor(style)\n  val layoutDirection = LocalLayoutDirection.current\n  val isRtl = layoutDirection == LayoutDirection.Rtl\n  Box(\n    modifier = modifier\n      .wrapContentSize()\n      .drawBehind {\n        val yOffset = when (horizontalAlignment) {\n          HorizontalAlignment.TOP -> style.pointRadius.toPx()\n          HorizontalAlignment.BOTTOM -> this.size.height - style.pointRadius.toPx()\n        }\n        val logicalXOffset = when (style.pointPlacement) {\n          PointPlacement.START -> style.pointRadius.toPx() * jetLimeStyle.pointStartFactor\n\n          PointPlacement.CENTER -> {\n            val effectiveWidth =\n              this.size.width -\n                if (style.position.isNotEnd()) jetLimeStyle.itemSpacing.toPx() else 0f\n            effectiveWidth / 2f\n          }\n\n          PointPlacement.END -> {\n            val effectiveWidth =\n              this.size.width -\n                if (style.position.isNotEnd()) jetLimeStyle.itemSpacing.toPx() else 0f\n            effectiveWidth - style.pointRadius.toPx() * jetLimeStyle.pointStartFactor\n          }\n        }\n        // Mirror logical offset for RTL so that timeline direction flips horizontally\n        val xOffset = if (isRtl) size.width - logicalXOffset else logicalXOffset\n        val radius = style.pointRadius.toPx() * radiusAnimFactor\n        val strokeWidth = style.pointStrokeWidth.toPx()\n\n        // Line\n        if (style.pointPlacement == PointPlacement.CENTER) {\n          // Segment towards the \"start\" of the timeline (left in LTR, right in RTL)\n          if (style.position.isNotStart()) {\n            val startX = if (isRtl) this.size.width else 0f\n            val endX = xOffset\n            drawLine(\n              brush = jetLimeStyle.lineBrush,\n              start = Offset(x = startX, y = yOffset),\n              end = Offset(x = endX, y = yOffset),\n              strokeWidth = jetLimeStyle.lineThickness.toPx(),\n              pathEffect = jetLimeStyle.pathEffect,\n            )\n          }\n          // Segment towards the \"end\" of the timeline (right in LTR, left in RTL)\n          if (style.position.isNotEnd()) {\n            val startX = xOffset\n            val endX = if (isRtl) 0f else this.size.width\n            drawLine(\n              brush = jetLimeStyle.lineBrush,\n              start = Offset(x = startX, y = yOffset),\n              end = Offset(x = endX, y = yOffset),\n              strokeWidth = jetLimeStyle.lineThickness.toPx(),\n              pathEffect = jetLimeStyle.pathEffect,\n            )\n          }\n        } else if (style.pointPlacement == PointPlacement.END) {\n          // END placement behaves like CENTER w.r.t connection, but anchored near item edge\n          if (style.position.isNotStart()) {\n            val startX = if (isRtl) this.size.width else 0f\n            val endX = xOffset\n            drawLine(\n              brush = jetLimeStyle.lineBrush,\n              start = Offset(x = startX, y = yOffset),\n              end = Offset(x = endX, y = yOffset),\n              strokeWidth = jetLimeStyle.lineThickness.toPx(),\n              pathEffect = jetLimeStyle.pathEffect,\n            )\n          }\n          if (style.position.isNotEnd()) {\n            val startX = xOffset\n            val endX = if (isRtl) 0f else this.size.width\n            drawLine(\n              brush = jetLimeStyle.lineBrush,\n              start = Offset(x = startX, y = yOffset),\n              end = Offset(x = endX, y = yOffset),\n              strokeWidth = jetLimeStyle.lineThickness.toPx(),\n              pathEffect = jetLimeStyle.pathEffect,\n            )\n          }\n        } else {\n          // START placement original behavior, but mirrored for RTL so connectors flow with layout direction\n          if (style.position.isNotEnd()) {\n            val xShift = xOffset * (jetLimeStyle.pointStartFactor - 1)\n            val startX = xOffset\n            val endX = if (isRtl) 0f - xShift else this.size.width + xShift\n            drawLine(\n              brush = jetLimeStyle.lineBrush,\n              start = Offset(x = startX, y = yOffset),\n              end = Offset(x = endX, y = yOffset),\n              strokeWidth = jetLimeStyle.lineThickness.toPx(),\n              pathEffect = jetLimeStyle.pathEffect,\n            )\n          }\n        }\n\n        // Point background\n        drawCircle(\n          color = style.pointColor,\n          radius = radius,\n          center = Offset(x = xOffset, y = yOffset),\n        )\n\n        // Point center fill\n        if (style.pointType.isFilled()) {\n          drawCircle(\n            color = style.pointFillColor,\n            radius = radius - radius * (1 - (style.pointType.fillPercent ?: 1f)),\n            center = Offset(x = xOffset, y = yOffset),\n          )\n        }\n\n        // Point custom icon\n        if (style.pointType.isCustom()) {\n          style.pointType.icon?.let { painter ->\n            val pointSizeInPixels = style.pointRadius.toPx() * 2.4f * radiusAnimFactor\n            val iconSize = Size(pointSizeInPixels, pointSizeInPixels)\n            this.withTransform(\n              transformBlock = {\n                translate(\n                  left = xOffset - iconSize.width / 2f,\n                  top = yOffset - iconSize.height / 2f,\n                )\n              },\n              drawBlock = {\n                this.drawIntoCanvas {\n                  with(painter) {\n                    val tint = style.pointType.tint?.let { ColorFilter.tint(it) }\n                    draw(size = iconSize, colorFilter = tint)\n                  }\n                }\n              },\n            )\n          }\n        }\n\n        // Point border\n        if (strokeWidth > 0f) {\n          drawCircle(\n            color = style.pointStrokeColor,\n            radius = radius - strokeWidth / 2,\n            center = Offset(x = xOffset, y = yOffset),\n            style = Stroke(width = strokeWidth),\n          )\n        }\n      },\n  ) {\n    PlaceHorizontalEventContent(style, jetLimeStyle, horizontalAlignment, content)\n  }\n}\n\n/**\n * Composable function to place the content within a [HorizontalEvent].\n *\n * @param style The style of the [JetLimeEvent].\n * @param jetLimeStyle The JetLime style configuration.\n * @param alignment The vertical alignment for the event.\n * @param content The composable content to be placed.\n */\n@Composable\nprivate fun PlaceHorizontalEventContent(\n  style: JetLimeEventStyle,\n  jetLimeStyle: JetLimeStyle,\n  alignment: HorizontalAlignment,\n  content: @Composable () -> Unit,\n) {\n  Box(\n    modifier = Modifier\n      .testTag(\"HorizontalEventContentBox\")\n      .defaultMinSize(minWidth = style.pointRadius * 2)\n      .padding(\n        top = if (alignment == HorizontalAlignment.TOP) {\n          style.pointRadius * 2 + jetLimeStyle.contentDistance\n        } else {\n          0.dp\n        },\n        bottom = if (alignment == HorizontalAlignment.BOTTOM) {\n          style.pointRadius * 2 + jetLimeStyle.contentDistance\n        } else {\n          0.dp\n        },\n        end = if (style.position.isNotEnd()) {\n          jetLimeStyle.itemSpacing\n        } else {\n          0.dp\n        },\n      ),\n  ) {\n    content()\n  }\n}\n\n/**\n * Calculates and returns the radius animation factor for a given [JetLimeEventStyle].\n * The result defaults to 1.0f if [JetLimeEventStyle.pointAnimation] is not set or null.\n *\n * @param style The style of the [JetLimeEvent].\n * @return The calculated radius animation factor as a [Float].\n */\n@Composable\ninternal fun calculateRadiusAnimFactor(style: JetLimeEventStyle): State<Float> {\n  val animation = style.pointAnimation ?: return remember { mutableFloatStateOf(1.0f) }\n  val infiniteTransition = rememberInfiniteTransition(label = \"RadiusInfiniteTransition\")\n  return infiniteTransition.animateFloat(\n    initialValue = animation.initialValue,\n    targetValue = animation.targetValue,\n    animationSpec = animation.animationSpec,\n    label = \"RadiusFloatAnimation\",\n  )\n}\n"
  },
  {
    "path": "jetlime/src/commonMain/kotlin/com/pushpal/jetlime/JetLimeEventDefaults.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport androidx.compose.animation.core.FastOutLinearInEasing\nimport androidx.compose.animation.core.InfiniteRepeatableSpec\nimport androidx.compose.animation.core.RepeatMode.Reverse\nimport androidx.compose.animation.core.infiniteRepeatable\nimport androidx.compose.animation.core.tween\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.dp\n\n/**\n * Provides default values and utility functions for [JetLimeEvent] styling.\n *\n * This object contains default values and composable functions for creating event styles and point animations in [JetLimeColumn] or [JetLimeRow] components.\n * It offers a convenient way to access standard styling options and animations for JetLime events.\n */\nobject JetLimeEventDefaults {\n  private val PointType: EventPointType = EventPointType.filled(0.5f)\n  private val PointRadius: Dp = 12.dp\n  private val PointStrokeWidth: Dp = 2.dp\n  private val PointAnimation: InfiniteRepeatableSpec<Float> = infiniteRepeatable(\n    animation = tween(800, easing = FastOutLinearInEasing),\n    repeatMode = Reverse,\n  )\n\n  /**\n   * Maximum width allowed to for the additional content composable used in [JetLimeExtendedEvent],\n   * that will be drawn on the left side of the timeline. As the content is thought to have more\n   * preference than additional content, it is assumed that additional content will be used for\n   * drawing ui that will consume relatively lesser space.\n   */\n  internal val AdditionalContentMaxWidth = 72.dp\n\n  /**\n   * Creates a default [JetLimeEventStyle] object with specified parameters.\n   *\n   * @param position The position of the event relative to the timeline.\n   * @param pointPlacement Controls where the point renders within the item. One of [PointPlacement.START], [PointPlacement.CENTER], or [PointPlacement.END]. Defaults to START.\n   * @param pointType The type of point used in the event. Defaults to a filled point.\n   * @param pointColor The color of the point. Defaults to the 'onPrimary' color from MaterialTheme's color scheme.\n   * @param pointFillColor The fill color of the point. Defaults to the primary color from MaterialTheme's color scheme.\n   * @param pointRadius The radius of the point. Defaults to [PointRadius].\n   * @param pointAnimation The animation for the point, if any.\n   * @param pointStrokeWidth The stroke width of the point. Defaults to [PointStrokeWidth].\n   * @param pointStrokeColor The stroke color of the point. Defaults to the primary color from MaterialTheme's color scheme.\n   * @return A [JetLimeEventStyle] object configured with the given parameters.\n   */\n  @Composable\n  fun eventStyle(\n    position: EventPosition,\n    pointPlacement: PointPlacement = PointPlacement.START,\n    pointType: EventPointType = PointType,\n    pointColor: Color = MaterialTheme.colorScheme.onPrimary,\n    pointFillColor: Color = MaterialTheme.colorScheme.primary,\n    pointRadius: Dp = PointRadius,\n    pointAnimation: EventPointAnimation? = null,\n    pointStrokeWidth: Dp = PointStrokeWidth,\n    pointStrokeColor: Color = MaterialTheme.colorScheme.primary,\n  ): JetLimeEventStyle = JetLimeEventStyle(\n    pointPlacement = pointPlacement,\n    pointType = pointType,\n    pointColor = pointColor,\n    pointFillColor = pointFillColor,\n    pointRadius = pointRadius,\n    pointAnimation = pointAnimation,\n    pointStrokeWidth = pointStrokeWidth,\n    pointStrokeColor = pointStrokeColor,\n  ).apply {\n    this.position = position\n  }\n\n  /**\n   * Creates an [EventPointAnimation] object to define animations for event points.\n   *\n   * @param initialValue The initial value of the animation. Defaults to 1.0f.\n   * @param targetValue The target value of the animation. Defaults to 1.2f.\n   * @param animationSpec The specification for the animation. Defaults to [PointAnimation].\n   * @return An [EventPointAnimation] object configured with the given parameters.\n   */\n  @Composable\n  fun pointAnimation(\n    initialValue: Float = 1.0f,\n    targetValue: Float = 1.2f,\n    animationSpec: InfiniteRepeatableSpec<Float> = PointAnimation,\n  ): EventPointAnimation = EventPointAnimation(\n    initialValue = initialValue,\n    targetValue = targetValue,\n    animationSpec = animationSpec,\n  )\n}\n"
  },
  {
    "path": "jetlime/src/commonMain/kotlin/com/pushpal/jetlime/JetLimeEventStyle.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.unit.Dp\n\n/**\n * Represents the style configuration for an event in a [JetLimeEvent] UI component.\n * This class encapsulates various styling properties such as position, point type, colors, radius, animation, and stroke attributes for an event point.\n *\n * @property pointType The type of the event point: Empty, Filled or Custom.\n * @property pointColor The color of the event point.\n * @property pointFillColor The fill color of the event point.\n * @property pointRadius The radius of the event point.\n * @property pointAnimation Optional animation for the event point.\n * @property pointStrokeWidth The stroke width of the event point.\n * @property pointStrokeColor The stroke color of the event point.\n * @property pointPlacement The placement of the point relative to the event content (START, CENTER, or END).\n */\n@Immutable\nclass JetLimeEventStyle internal constructor(\n  var pointPlacement: PointPlacement,\n  val pointType: EventPointType,\n  val pointColor: Color,\n  val pointFillColor: Color,\n  val pointRadius: Dp,\n  val pointAnimation: EventPointAnimation?,\n  val pointStrokeWidth: Dp,\n  val pointStrokeColor: Color,\n) {\n\n  /** The position of the event in the UI component. */\n  var position: EventPosition = EventPosition.END\n\n  /**\n   * Sets the position of the [JetLimeEvent].\n   *\n   * This function allows for changing the position of a JetLime event. It modifies the current\n   * instance of [JetLimeEventStyle], setting its position property to the specified [EventPosition].\n   *\n   * @param position The [EventPosition] to set for the JetLime event.\n   * @return A [JetLimeEventStyle] instance with the updated position.\n   */\n  @Stable\n  fun setPosition(position: EventPosition): JetLimeEventStyle = this.apply {\n    this.position = position\n  }\n\n  /**\n   * Sets the placement of the point relative to the event content.\n   *\n   * @param pointPlacement The [PointPlacement] to use for drawing the point.\n   * @return A [JetLimeEventStyle] instance with the updated point placement.\n   */\n  @Stable\n  fun setPointPlacement(pointPlacement: PointPlacement): JetLimeEventStyle = this.apply {\n    this.pointPlacement = pointPlacement\n  }\n\n  /**\n   * Checks if this instance is equal to another object. Two instances of [JetLimeEventStyle] are\n   * considered equal if they have the same values for all properties.\n   *\n   * @param other The object to compare this instance with.\n   * @return `true` if the other object is an instance of [JetLimeEventStyle] and has the same property values, `false` otherwise.\n   */\n  override fun equals(other: Any?): Boolean {\n    if (this === other) return true\n    if (other == null || other !is JetLimeEventStyle) return false\n    if (position != other.position) return false\n    if (pointPlacement != other.pointPlacement) return false\n    if (pointType != other.pointType) return false\n    if (pointColor != other.pointColor) return false\n    if (pointFillColor != other.pointFillColor) return false\n    if (pointRadius != other.pointRadius) return false\n    if (pointAnimation != other.pointAnimation) return false\n    if (pointStrokeWidth != other.pointStrokeWidth) return false\n    return pointStrokeColor == other.pointStrokeColor\n  }\n\n  /**\n   * Returns a hash code value for the object, consistent with the definition of equality for the class.\n   * This supports the use in hash tables, like those provided by `HashMap`.\n   *\n   * @return A hash code value for this object.\n   */\n  override fun hashCode(): Int {\n    var result = position.hashCode()\n    result = 31 * result + pointPlacement.hashCode()\n    result = 31 * result + pointType.hashCode()\n    result = 31 * result + pointColor.hashCode()\n    result = 31 * result + pointFillColor.hashCode()\n    result = 31 * result + pointRadius.hashCode()\n    result = 31 * result + pointAnimation.hashCode()\n    result = 31 * result + pointStrokeWidth.hashCode()\n    result = 31 * result + pointStrokeColor.hashCode()\n\n    return result\n  }\n}\n\n/**\n * Defines the placement of the timeline point relative to the event content.\n */\nenum class PointPlacement {\n  /** Point drawn at the start edge (existing default behaviour). */\n  START,\n\n  /** Point drawn centered relative to the event content box. */\n  CENTER,\n\n  /** Point drawn at the end edge (bottom for vertical, right for horizontal). */\n  END,\n}\n"
  },
  {
    "path": "jetlime/src/commonMain/kotlin/com/pushpal/jetlime/JetLimeExtendedEvent.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport androidx.compose.foundation.layout.Box\nimport androidx.compose.foundation.layout.BoxScope\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.ExperimentalComposeApi\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableFloatStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.drawBehind\nimport androidx.compose.ui.geometry.Offset\nimport androidx.compose.ui.geometry.Size\nimport androidx.compose.ui.graphics.ColorFilter\nimport androidx.compose.ui.graphics.drawscope.Stroke\nimport androidx.compose.ui.graphics.drawscope.drawIntoCanvas\nimport androidx.compose.ui.graphics.drawscope.withTransform\nimport androidx.compose.ui.layout.Layout\nimport androidx.compose.ui.platform.LocalDensity\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.unit.Dp\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport com.pushpal.jetlime.JetLimeEventDefaults.AdditionalContentMaxWidth\n\n/**\n * Should only be used with a [JetLimeColumn] for a vertical arrangement of events.\n *\n * Composable function for creating a [JetLimeColumn] event which has 2 slots for content.\n * The main content will be drawn on the right side of the timeline and the additional content\n * will be drawn on the left side of the timeline. The additional content is optional, and has\n * a maximum width constraint defined by the [JetLimeEventDefaults.AdditionalContentMaxWidth].\n *\n * Example usage:\n *\n * ```\n *  val items = remember { getItemsList() }\n *\n *  JetLimeColumn(\n *   itemsList = ItemsList(items),\n *   key = { _, item -> item.id },\n *   style = JetLimeDefaults.columnStyle(),\n *  ) { index, item, position ->\n *     JetLimeExtendedEvent(\n *      style = JetLimeEventDefaults.eventStyle(position = position),\n *      additionalContent = { ComposableAdditionalContent(item.icon) }\n *     ) {\n *        ComposableMainContent(item = item.content)\n *       }\n *    }\n * ```\n *\n * @param modifier The modifier to be applied to the event.\n * @param style The style of the [JetLimeColumn] event, defaulting to [JetLimeEventDefaults.eventStyle].\n * @param additionalContent The optional additional content of the event, placed on the left side of timeline.\n * @param additionalContentMaxWidth The maximum width allowed for [additionalContent]\n * @param content The main content of the event, placed on the right side of timeline.\n */\n@ExperimentalComposeApi\n@Composable\nfun JetLimeExtendedEvent(\n  modifier: Modifier = Modifier,\n  style: JetLimeEventStyle = JetLimeEventDefaults.eventStyle(EventPosition.END),\n  additionalContent: @Composable (BoxScope.() -> Unit) = { },\n  additionalContentMaxWidth: Dp = AdditionalContentMaxWidth,\n  content: @Composable () -> Unit,\n) {\n  val jetLimeStyle = LocalJetLimeStyle.current\n  val density = LocalDensity.current\n  val strokeWidth = with(density) { style.pointStrokeWidth.toPx() }\n  val radiusAnimFactor by calculateRadiusAnimFactor(style)\n  val layoutDirection = LocalLayoutDirection.current\n  val isRtl = layoutDirection == LayoutDirection.Rtl\n\n  val timelineXState = remember { mutableFloatStateOf(0f) }\n  val maxAdditionalContentWidth = with(density) { additionalContentMaxWidth.toPx() }\n\n  Layout(\n    modifier = modifier.drawBehind {\n      // Line and point are drawn here so a state write from the measure phase only\n      // invalidates the draw phase (not composition) and stays in the same frame.\n      val timelineXOffset = timelineXState.floatValue\n\n      val yOffset = when (style.pointPlacement) {\n        PointPlacement.START -> style.pointRadius.toPx() * jetLimeStyle.pointStartFactor\n\n        PointPlacement.CENTER -> (\n          this.size.height -\n            if (style.position.isNotEnd()) jetLimeStyle.itemSpacing.toPx() else 0f\n          ) /\n          2f\n\n        PointPlacement.END -> {\n          val effectiveHeight =\n            this.size.height -\n              if (style.position.isNotEnd()) jetLimeStyle.itemSpacing.toPx() else 0f\n          effectiveHeight - style.pointRadius.toPx() * jetLimeStyle.pointStartFactor\n        }\n      }\n      val radius = style.pointRadius.toPx() * radiusAnimFactor\n\n      if (style.pointPlacement == PointPlacement.START) {\n        if (style.position.isNotEnd()) {\n          drawLine(\n            brush = jetLimeStyle.lineBrush,\n            start = Offset(x = timelineXOffset, y = yOffset),\n            end = Offset(\n              x = timelineXOffset,\n              y = this.size.height + yOffset * (jetLimeStyle.pointStartFactor - 1),\n            ),\n            strokeWidth = jetLimeStyle.lineThickness.toPx(),\n            pathEffect = jetLimeStyle.pathEffect,\n          )\n        }\n      } else {\n        // CENTER or END: draw upward (except first) and downward (except last) segments\n        if (style.position.isNotStart()) {\n          drawLine(\n            brush = jetLimeStyle.lineBrush,\n            start = Offset(x = timelineXOffset, y = 0f),\n            end = Offset(x = timelineXOffset, y = yOffset),\n            strokeWidth = jetLimeStyle.lineThickness.toPx(),\n            pathEffect = jetLimeStyle.pathEffect,\n          )\n        }\n        if (style.position.isNotEnd()) {\n          drawLine(\n            brush = jetLimeStyle.lineBrush,\n            start = Offset(x = timelineXOffset, y = yOffset),\n            end = Offset(x = timelineXOffset, y = this.size.height),\n            strokeWidth = jetLimeStyle.lineThickness.toPx(),\n            pathEffect = jetLimeStyle.pathEffect,\n          )\n        }\n      }\n\n      drawCircle(\n        color = style.pointColor,\n        radius = radius,\n        center = Offset(x = timelineXOffset, y = yOffset),\n      )\n\n      if (style.pointType.isFilled()) {\n        val fillPercent = style.pointType.fillPercent?.coerceIn(0f, 1f) ?: 1f\n        drawCircle(\n          color = style.pointFillColor,\n          radius = radius * fillPercent,\n          center = Offset(x = timelineXOffset, y = yOffset),\n        )\n      }\n      if (style.pointType.isCustom()) {\n        val pointSizeInPixels = style.pointRadius.toPx() * 2.4f * radiusAnimFactor\n        val iconSize = Size(pointSizeInPixels, pointSizeInPixels)\n        style.pointType.icon?.let { painter ->\n          this.withTransform(\n            transformBlock = {\n              translate(\n                left = timelineXOffset - iconSize.width / 2f,\n                top = yOffset - iconSize.height / 2f,\n              )\n            },\n            drawBlock = {\n              this.drawIntoCanvas {\n                with(painter) {\n                  val tint = style.pointType.tint?.let { ColorFilter.tint(it) }\n                  draw(size = iconSize, colorFilter = tint)\n                }\n              }\n            },\n          )\n        }\n      }\n      if (strokeWidth > 0f) {\n        drawCircle(\n          color = style.pointStrokeColor,\n          radius = radius - strokeWidth / 2,\n          center = Offset(x = timelineXOffset, y = yOffset),\n          style = Stroke(width = strokeWidth),\n        )\n      }\n    },\n    content = {\n      // Box for main content with optional padding at the bottom\n      Box(\n        modifier = Modifier.padding(\n          bottom = if (style.position.isNotEnd()) {\n            jetLimeStyle.itemSpacing\n          } else {\n            0.dp\n          },\n        ),\n      ) {\n        content()\n      }\n      // Additional content wrapped in a Box to provide the expected BoxScope receiver.\n      Box {\n        additionalContent()\n      }\n    },\n  ) { measurables, constraints ->\n    // Ensuring that there is at least one child in the layout\n    require(measurables.isNotEmpty()) {\n      \"JetLimeExtendedEvent should have at-least one child for content\"\n    }\n    // Thickness of the line drawn for the timeline\n    val timelineThickness = jetLimeStyle.lineThickness.toPx()\n    // Distance between the content/additional content and the timeline\n    val contentDistance = jetLimeStyle.contentDistance.toPx()\n\n    // Extracting the first and potentially second child for layout\n    val contentMeasurable = measurables.first()\n    val additionalContentMeasurable = measurables.getOrNull(1)\n\n    // Measuring the additional content if it exists\n    val additionalContentPlaceable = additionalContentMeasurable?.let { measurable ->\n      // Calculating intrinsic width and adjusting it according to the maximum allowed width\n      val intrinsicWidth = measurable.minIntrinsicWidth(constraints.maxHeight)\n      val adjustedMinWidth = intrinsicWidth.coerceAtMost(maxAdditionalContentWidth.toInt())\n      // Ensure we do not exceed available width\n      val maxWidthForAdditional =\n        maxAdditionalContentWidth.coerceAtMost(constraints.maxWidth.toFloat()).toInt()\n      val newConstraints = constraints.copy(\n        minWidth = adjustedMinWidth.coerceAtMost(maxWidthForAdditional),\n        maxWidth = maxWidthForAdditional,\n      )\n      // Measuring the additional content with the new constraints\n      measurable.measure(newConstraints)\n    }\n\n    // Calculating the logical X offset for the timeline based on the width of the additional content\n    val logicalTimelineXOffset =\n      (additionalContentPlaceable?.width?.toFloat() ?: 0f) + contentDistance\n    // Publish for the drawBehind modifier. Only the draw phase observes this state,\n    // so the write does not trigger recomposition.\n    timelineXState.floatValue = logicalTimelineXOffset\n\n    // Calculating the X offset and width available for the main content in logical LTR space\n    val logicalContentXOffset = logicalTimelineXOffset + timelineThickness + contentDistance\n    val contentWidth = constraints.maxWidth - logicalContentXOffset\n\n    // Measuring the main content with the calculated width\n    val contentPlaceable = contentMeasurable.measure(\n      constraints.copy(minWidth = 0, maxWidth = contentWidth.toInt()),\n    )\n\n    // Determining the height of the layout based on the measured content\n    val contentHeight = contentPlaceable.height\n    val layoutHeight = additionalContentPlaceable?.let { additional ->\n      maxOf(contentHeight, additional.height)\n    } ?: contentHeight\n\n    val totalWidth = constraints.maxWidth\n\n    // Placing the measured composables in the layout, mirroring in RTL so that\n    // additional content is always on the logical \"left\" of the timeline and main\n    // content on the \"right\", but visually flipped when isRtl is true.\n    layout(totalWidth, layoutHeight) {\n      if (isRtl) {\n        // In RTL, place additional content flush to the right so it stays visible\n        additionalContentPlaceable?.placeRelative(\n          x = totalWidth - additionalContentPlaceable.width,\n          y = 0,\n        )\n      } else {\n        // LTR: original behavior, additional content starts from left\n        additionalContentPlaceable?.placeRelative(x = 0, y = 0)\n      }\n\n      // Place main content on the opposite side of the timeline depending on direction\n      val contentX = if (isRtl) {\n        // In RTL, main content should be left of the timeline, but still within bounds\n        (logicalTimelineXOffset - contentPlaceable.width - jetLimeStyle.contentDistance.toPx())\n          .coerceAtLeast(0f)\n          .toInt()\n      } else {\n        logicalContentXOffset.toInt()\n      }\n      contentPlaceable.placeRelative(x = contentX, y = 0)\n    }\n  }\n}\n"
  },
  {
    "path": "jetlime/src/commonMain/kotlin/com/pushpal/jetlime/JetLimeList.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport androidx.compose.foundation.gestures.ScrollableDefaults\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.PaddingValues\nimport androidx.compose.foundation.lazy.LazyColumn\nimport androidx.compose.foundation.lazy.LazyListState\nimport androidx.compose.foundation.lazy.LazyRow\nimport androidx.compose.foundation.lazy.itemsIndexed\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.staticCompositionLocalOf\nimport androidx.compose.ui.Alignment\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.pushpal.jetlime.Arrangement.HORIZONTAL\nimport com.pushpal.jetlime.Arrangement.VERTICAL\n\n/**\n * A composable function that creates a vertical timeline interface with a list of items.\n *\n * This function sets up a LazyColumn layout for displaying items in a vertical timeline format. It allows for customization\n * of its appearance and behavior through various parameters.\n *\n * Example usage:\n *\n * ```\n *  val items = remember { getItemsList() }\n *\n *  JetLimeColumn(\n *   itemsList = ItemsList(items),\n *   key = { _, item -> item.id },\n *   style = JetLimeDefaults.columnStyle(),\n *  ) { index, item, position ->\n *     JetLimeEvent(\n *      style = JetLimeEventDefaults.eventStyle(position = position)\n *     ) {\n *        ComposableContent(item = item)\n *       }\n *    }\n * ```\n *\n * @param T The type of items in the items list.\n * @param itemsList A list of items to be displayed in the JetLimeColumn.\n * @param modifier A modifier to be applied to the LazyColumn.\n * @param style The JetLime style configuration. Defaults to a predefined column style.\n * @param listState The state object to be used for the LazyColumn.\n * @param contentPadding The padding to apply to the content inside the LazyColumn.\n * @param key A factory of stable and unique keys representing the item. Using the same key for multiple items in the list is not allowed. Type of the key should be saveable via Bundle on Android. If null is passed the position in the list will represent the key.\n * @param itemContent A composable lambda that takes an index, an item of type [T], and an [EventPosition] to build each item's content.\n */\n@Composable\nfun <T> JetLimeColumn(\n  itemsList: ItemsList<T>,\n  modifier: Modifier = Modifier,\n  style: JetLimeStyle = JetLimeDefaults.columnStyle(),\n  listState: LazyListState = rememberLazyListState(),\n  contentPadding: PaddingValues = PaddingValues(0.dp),\n  key: ((index: Int, item: T) -> Any)? = null,\n  itemContent: @Composable (index: Int, T, EventPosition) -> Unit,\n) {\n  val providedStyle = remember(style) { style.alignment(VERTICAL) }\n  CompositionLocalProvider(LocalJetLimeStyle provides providedStyle) {\n    LazyColumn(\n      modifier = modifier,\n      state = listState,\n      reverseLayout = false,\n      verticalArrangement = Arrangement.Top,\n      horizontalAlignment = Alignment.Start,\n      flingBehavior = ScrollableDefaults.flingBehavior(),\n      userScrollEnabled = true,\n      contentPadding = contentPadding,\n    ) {\n      itemsIndexed(\n        items = itemsList.items,\n        key = key,\n      ) { index, item ->\n        val eventPosition = EventPosition.dynamic(index, itemsList.items.size)\n        itemContent(index, item, eventPosition)\n      }\n    }\n  }\n}\n\n/**\n * A composable function that creates a horizontal timeline interface with a list of items.\n *\n * This function sets up a LazyRow layout for displaying items in a horizontal timeline format. It allows for customization\n * of its appearance and behavior through various parameters.\n *\n * Example usage:\n *\n * ```\n *  val items = remember { getItemsList() }\n *\n *  JetLimeRow(\n *   itemsList = ItemsList(items),\n *   key = { _, item -> item.id },\n *   style = JetLimeDefaults.rowStyle(),\n *  ) { index, item, position ->\n *     JetLimeEvent(\n *      style = JetLimeEventDefaults.eventStyle(position = position)\n *     ) {\n *        ComposableContent(item = item)\n *       }\n *    }\n * ```\n *\n * @param T The type of items in the items list.\n * @param itemsList A list of items to be displayed in the JetLimeRow.\n * @param modifier A modifier to be applied to the LazyRow.\n * @param style The JetLime style configuration. Defaults to a predefined row style.\n * @param listState The state object to be used for the LazyRow.\n * @param contentPadding The padding to apply to the content inside the LazyRow.\n * @param key A factory of stable and unique keys representing the item. Using the same key for multiple items in the list is not allowed. Type of the key should be saveable via Bundle on Android. If null is passed the position in the list will represent the key.\n * @param itemContent A composable lambda that takes an index, an item of type [T], and an [EventPosition] to build each item's content.\n */\n@Composable\nfun <T> JetLimeRow(\n  itemsList: ItemsList<T>,\n  modifier: Modifier = Modifier,\n  style: JetLimeStyle = JetLimeDefaults.rowStyle(),\n  listState: LazyListState = rememberLazyListState(),\n  contentPadding: PaddingValues = PaddingValues(0.dp),\n  key: ((index: Int, item: T) -> Any)? = null,\n  itemContent: @Composable (index: Int, T, EventPosition) -> Unit,\n) {\n  val providedStyle = remember(style) { style.alignment(HORIZONTAL) }\n  CompositionLocalProvider(LocalJetLimeStyle provides providedStyle) {\n    LazyRow(\n      modifier = modifier,\n      state = listState,\n      reverseLayout = false,\n      horizontalArrangement = Arrangement.Start,\n      verticalAlignment = Alignment.Top,\n      flingBehavior = ScrollableDefaults.flingBehavior(),\n      userScrollEnabled = true,\n      contentPadding = contentPadding,\n    ) {\n      itemsIndexed(\n        items = itemsList.items,\n        key = key,\n      ) { index, item ->\n        val eventPosition = EventPosition.dynamic(index, itemsList.items.size)\n        itemContent(index, item, eventPosition)\n      }\n    }\n  }\n}\n\n/**\n * A CompositionLocal providing the current [JetLimeStyle].\n *\n * This is used to provide a default or overridden style configuration down the composition tree. Accessing this without a provider\n * will result in an error, ensuring that the style is always defined when used within a composable context.\n */\nval LocalJetLimeStyle = staticCompositionLocalOf<JetLimeStyle> { error(\"No JetLimeStyle provided\") }\n"
  },
  {
    "path": "jetlime/src/commonMain/kotlin/com/pushpal/jetlime/JetLimeStyle.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport androidx.compose.runtime.Immutable\nimport androidx.compose.runtime.Stable\nimport androidx.compose.ui.graphics.Brush\nimport androidx.compose.ui.graphics.PathEffect\nimport androidx.compose.ui.unit.Dp\nimport com.pushpal.jetlime.Arrangement.VERTICAL\n\n/**\n * Represents the styling configuration for [JetLimeColumn] and [JetLimeRow] components.\n *\n * This class encapsulates various properties that define the appearance and layout of [JetLimeColumn] and [JetLimeRow] components,\n * such as content distance, item spacing, line thickness, and alignment properties. It provides a fluent API\n * for modifying these properties.\n *\n * - See [JetLimeDefaults.columnStyle] for the default style in a [JetLimeColumn].\n * - See [JetLimeDefaults.rowStyle] for the default style in a [JetLimeRow].\n *\n * @param contentDistance The distance of content from the start of the JetLime component.\n * @param itemSpacing The spacing between items in the JetLime component.\n * @param lineThickness The thickness of the line in the JetLime component.\n * @param lineBrush The brush used for the line in the JetLime component.\n * @param pathEffect the effect applied to the geometry of the timeline to obtain a dashed pattern.\n * @param lineHorizontalAlignment The horizontal alignment of the line in the JetLime component.\n * @param lineVerticalAlignment The vertical alignment of the line in the JetLime component.\n */\n@Immutable\nclass JetLimeStyle internal constructor(\n  val contentDistance: Dp,\n  val itemSpacing: Dp,\n  val lineThickness: Dp,\n  val lineBrush: Brush,\n  val pathEffect: PathEffect?,\n  val lineHorizontalAlignment: HorizontalAlignment,\n  val lineVerticalAlignment: VerticalAlignment,\n  internal val arrangement: Arrangement = VERTICAL,\n) {\n\n  internal val pointStartFactor: Float = 1.1f\n\n  /**\n   * Returns a [JetLimeStyle] with its [arrangement] set to the specified value.\n   *\n   * This returns a new [JetLimeStyle] instance if the current arrangement differs from the\n   * requested one, so the original instance is never mutated and can be safely shared across\n   * multiple [JetLimeColumn] / [JetLimeRow] usages.\n   *\n   * @param arrangement The [Arrangement] to set for the JetLime list component.\n   * @return A [JetLimeStyle] instance with the requested arrangement.\n   */\n  @Stable\n  internal fun alignment(arrangement: Arrangement): JetLimeStyle =\n    if (this.arrangement == arrangement) {\n      this\n    } else {\n      JetLimeStyle(\n        contentDistance = contentDistance,\n        itemSpacing = itemSpacing,\n        lineThickness = lineThickness,\n        lineBrush = lineBrush,\n        pathEffect = pathEffect,\n        lineHorizontalAlignment = lineHorizontalAlignment,\n        lineVerticalAlignment = lineVerticalAlignment,\n        arrangement = arrangement,\n      )\n    }\n\n  /**\n   * Checks if this [JetLimeStyle] is equal to another object.\n   *\n   * Equality is determined based on the equality of content distance, item spacing, line thickness,\n   * line brush, and both horizontal and vertical alignment properties.\n   *\n   * @param other The object to compare with this instance.\n   * @return `true` if the specified object is equal to this [JetLimeStyle], `false` otherwise.\n   */\n  override fun equals(other: Any?): Boolean {\n    if (this === other) return true\n    if (other !is JetLimeStyle) return false\n    if (contentDistance != other.contentDistance) return false\n    if (itemSpacing != other.itemSpacing) return false\n    if (lineThickness != other.lineThickness) return false\n    if (lineBrush != other.lineBrush) return false\n    if (pathEffect != other.pathEffect) return false\n    if (lineHorizontalAlignment != other.lineHorizontalAlignment) return false\n    if (lineVerticalAlignment != other.lineVerticalAlignment) return false\n    return arrangement == other.arrangement\n  }\n\n  /**\n   * Generates a hash code for this [JetLimeStyle].\n   *\n   * The hash code is a combination of content distance, item spacing, line thickness, line brush,\n   * and alignment properties.\n   *\n   * @return The hash code value for this [JetLimeStyle].\n   */\n  override fun hashCode(): Int {\n    var result = contentDistance.hashCode()\n    result = 31 * result + itemSpacing.hashCode()\n    result = 31 * result + lineThickness.hashCode()\n    result = 31 * result + lineBrush.hashCode()\n    result = 31 * result + pathEffect.hashCode()\n    result = 31 * result + lineHorizontalAlignment.hashCode()\n    result = 31 * result + lineVerticalAlignment.hashCode()\n    result = 31 * result + arrangement.hashCode()\n    return result\n  }\n}\n\n/**\n * Enum representing the possible arrangements for JetLime list components.\n */\n@Stable\ninternal enum class Arrangement {\n  VERTICAL,\n  HORIZONTAL,\n}\n\n/**\n * Enum representing the alignment of the timeline line and points for [JetLimeRow].\n */\n@Stable\nenum class HorizontalAlignment {\n  TOP,\n  BOTTOM,\n}\n\n/**\n * Enum representing the alignment of the timeline line and points for [JetLimeColumn].\n */\n@Stable\nenum class VerticalAlignment {\n  LEFT,\n  RIGHT,\n}\n"
  },
  {
    "path": "jetlime/src/test/java/com/pushpal/jetlime/ExampleUnitTest.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime\n\nimport org.junit.Assert.assertEquals\nimport org.junit.Test\n\n/**\n * Example local unit test, which will execute on the development machine (host).\n *\n * See [testing documentation](http://d.android.com/tools/testing).\n */\nclass ExampleUnitTest {\n  @Test\n  fun addition_isCorrect() {\n    assertEquals(4, 2 + 2)\n  }\n}\n"
  },
  {
    "path": "public-key.asc",
    "content": "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nmQGNBGkiCbkBDACbV6/cBB9+cl7RsAdJw8vbZqOew3KgC33rdwluRILaCYpNBkNs\ny19NCD4jqITolSIJaZKECfViDVqF7blsTNx1YUYjt9tOdeYwpKsRzne8zzuQWcYQ\nj6kFapJVwiyrXv+MePzftPHzURciPmiNJShgByKGb6WPSfZdqzwhnTm7ObltVyOV\n1lCcKPCnbEtecOdEmEGxy6mbHO+/bUnJgYNWre4Qk1gtER6r3SK+S46gb/3GV1Xf\nLZdptdZbdIw2772S9P7NrAx2sAJoepFQ5aw+O/PjoayPsMHvv8kC5pEhXgTp5JlR\nMZx1WoZ2xutyRxXkzLM4h0VzAfxpK4MEJ+RPTAQqEEaNeFK8vlJDKhGqODeioXmD\nIJuvmAJsMV/XMgoVpIApWTStZZ29j63uhxWbjcIKhs0afqKlx5qYMZQP9lMq8sFk\nA6MW4NkLJKjCUJP2efsurz6J+/wNngcOIAUWmKk6/mxDccaEarLEFI2NFNkbwFAW\nIKrPvaOf1dze+A8AEQEAAbRHUHVzaHBhbCBSb3kgKE5ldyBrZXkgdG8gcHVibGlz\naCBLTVAgbGlicmFyeSkgPHB1c2hwYWxyb3kyMDA3QGdtYWlsLmNvbT6JAdEEEwEI\nADsWIQTBup0Pe5Qk7CB39SOb3vovZ+kLnAUCaSIJuQIbAwULCQgHAgIiAgYVCgkI\nCwIEFgIDAQIeBwIXgAAKCRCb3vovZ+kLnJlZC/46g/WWXBRPHarJZM5WLgDTgEMt\n3MHltHy6Yz5jn5EN24qP7uBXxHDP2LX7+z8ToN+UzhpzVdmXNsX4BPjVJQ1y1i43\ndG+50K82MsHxd2xaJrXZ1g1oW4A4JszuH3n+X+mL0fimbPkDpCj910hgddBJ98W0\nHbc+zYyKQG3M4r3Vu7LVdiD8dlx6V2NilbjYfVaMXtmx35QEl2cSCGqauO4InjC/\neiSCgcUTodsoMfGECRfTxrSGWYM4hlpnhLeJgZOuz8QUfw4VItxmx28D4+rxaSUG\njsOZXHiubr6J8XV7aqmX5VCC3QMauAOZh5idNalG4QzdSRddNPKTnDsp/pdAcEqv\nmXkcx/nBbmeR8buLGQf8/6Ii/UKCPl446IZ2v8o8wsWpxBUrngFMBNv5RxOPaaxK\nuSN+Dy0laCMCc1PzeyEIb3Dl9hytu2ehKPhyxIKfpAOtiFWduhTne2tOmUGwZvB6\nfZTJATuA+SGz30iuxoqPYELWDPxqDphTknsIq6S5AY0EaSIJuQEMAJjXyWIKHCE0\nwiCl7hOFwMCYuSaOuEnd3XK1ddN9+81ZCzbTuj/MYqqPHO4vU60cV6TA87U06i3N\nn8Pt+JfT96N+ouRPcW+ixCQqIf92HVlPFegLEjBT3xyVvIPJhGqOS/pXy19joBiN\n1fpud+OW9On0MjIRv/zpUr4eaNLwmO1YO16S+3QMqnm7izzTLCS7NhuuhLU8TCr7\nQZ0XdRBMm+Ms+JICVTwcbhka1AZhhnvRvHD3b1+v8WDoFCgWlTrFP91oVVSTw/Tq\n2PZFC+fXvUaM5P2mVLiOfrfWSH9d/R8XybteVb4ljj+os1K0E1RgLfly+LejwMuJ\nX4GpIRCxYjFyAvFWlaKmggEqvkUgt1Hx7JTezEhFdH1xyMPk/eOf2xgj4/wWes87\nL8F3tOJNfPw1GvboquwOO/x6rU4PO8mjZcSKOu3pMoxQf6Hk2tD/6ZSNB9sCNqdR\naK++g2qA9A92u1U/a7R3U0ZuXjWvwCxpUj12ujPHTzvyu0toqlB7ZwARAQABiQG2\nBBgBCAAgFiEEwbqdD3uUJOwgd/Ujm976L2fpC5wFAmkiCbkCGwwACgkQm976L2fp\nC5wkjAv+NS1T1JQ4FIMwMjQTRVaY1eFxyy4SLEY00KP0Rbi2GgIVGL8oJgZjscWK\n/haAIMrIeXqaTk2PFdmSaXtGv2XGU3mCb5dFxAYABXlaJtdE2wOu4W7rCDwybZeN\nnvoWwHJwZqRpp/NxLLS5G9mnnVmj3pOOnhi1ihM5z9e2ujLTfPWKVhC5i9B3Teyj\nHys+9Xz/4OQ79mQPGgItVseUivNabirIvZFoPGJlfePgNl98hFy0JiSkkM0RoetQ\nn6T/BUU40uG8Un/kP0uAMvpt1NvvDbplazlthS2+dl6o2dmx1DWyL/F7tzVJ78x7\n+42MPzBxSKEA4u5MjQ5BkoHHbJ6K9rkdEoSSTd0Kx5L0+62jEOit0PzjzCpgASl+\ni9aswpCThKaDtuOwLQoqtIFqiZ9c6wY4gznKKn+bYBXrON3VctpKWydWOtLCnspN\ns2YVHnOjrzwRuK9UzYAXpNIOLKDt7eHvBhUc80O2TL9hS3MV5r5gK0M5y1i+n2xo\nEK/i6arJ\n=2GgY\n-----END PGP PUBLIC KEY BLOCK-----\n"
  },
  {
    "path": "sample/composeApp/build.gradle.kts",
    "content": "import org.jetbrains.compose.desktop.application.dsl.TargetFormat\nimport org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi\nimport org.jetbrains.kotlin.gradle.dsl.JvmTarget\nimport org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig\n\nplugins {\n  alias(libs.plugins.kotlin.multiplatform)\n  alias(libs.plugins.android.application)\n  alias(libs.plugins.jetbrains.compose)\n  alias(libs.plugins.compose.compiler)\n  alias(libs.plugins.kotlin.cocoapods)\n  alias(libs.plugins.compose.compiler.report.generator)\n}\n\nkotlin {\n  js(IR) {\n    browser()\n    binaries.executable()\n  }\n\n  @OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class)\n  wasmJs {\n    browser {\n      commonWebpackConfig {\n        // Keep the legacy prop for now (it still exists in KGP 2.2)\n        // (When tooling surfaces the new API, switch to: mainOutputFileName.set(\"composeApp.js\"))\n        outputFileName = \"composeApp.js\"\n        devServer =\n          (devServer ?: KotlinWebpackConfig.DevServer()).apply {\n            static =\n              (static ?: mutableListOf()).apply {\n                // Serve sources to debug inside browser\n                add(project.projectDir.path)\n              }\n          }\n      }\n    }\n    binaries.executable()\n  }\n\n  androidTarget {\n    @OptIn(ExperimentalKotlinGradlePluginApi::class)\n    compilerOptions {\n      jvmTarget.set(JvmTarget.JVM_17)\n    }\n  }\n\n  jvm(\"desktop\")\n\n  listOf(\n    iosX64(),\n    iosArm64(),\n    iosSimulatorArm64(),\n  ).forEach { iosTarget ->\n    iosTarget.binaries.framework {\n      baseName = \"ComposeApp\"\n      isStatic = true\n    }\n  }\n\n  cocoapods {\n    version = \"1.0.0\"\n    summary = \"JetLime Sample App\"\n    homepage = \"empty\"\n    ios.deploymentTarget = \"14.0\"\n    podfile = project.file(\"../iosApp/Podfile\")\n    framework {\n      baseName = \"ComposeApp\"\n      isStatic = true\n    }\n  }\n\n  sourceSets {\n    val desktopMain by getting\n\n    androidMain.dependencies {\n      implementation(compose.preview)\n      implementation(libs.androidx.activity.compose)\n    }\n    commonMain.dependencies {\n      implementation(compose.runtime)\n      implementation(compose.foundation)\n      implementation(compose.material3)\n      implementation(compose.ui)\n      implementation(compose.components.resources)\n      implementation(compose.materialIconsExtended)\n      implementation(compose.components.uiToolingPreview)\n\n      // Local library\n      implementation(project(\":jetlime\"))\n\n      // Uncomment for maven testing\n      // implementation(\"io.github.pushpalroy:jetlime:4.3.0\")\n    }\n    desktopMain.dependencies {\n      implementation(compose.desktop.currentOs)\n    }\n    jsMain.dependencies {\n      implementation(compose.html.core)\n    }\n  }\n}\n\nandroid {\n  namespace = \"com.pushpal.jetlime.sample\"\n  compileSdk = 36\n\n  sourceSets[\"main\"].manifest.srcFile(\"src/androidMain/AndroidManifest.xml\")\n  sourceSets[\"main\"].res.srcDirs(\"src/androidMain/res\")\n  sourceSets[\"main\"].resources.srcDirs(\"src/commonMain/resources\")\n\n  defaultConfig {\n    applicationId = \"com.pushpal.jetlime.sample\"\n    minSdk = 23\n    targetSdk = 36\n    versionCode = 1\n    versionName = \"1.0\"\n\n    testInstrumentationRunner = \"androidx.test.runner.AndroidJUnitRunner\"\n  }\n  packaging {\n    resources {\n      excludes += \"/META-INF/{AL2.0,LGPL2.1}\"\n    }\n  }\n\n  signingConfigs {\n    // Uncomment this line if we are generating a release build manually from IDE\n    // Not needed while build is generated from CI/CD\n    //    maybeCreate(\"release\").apply {\n    //        val keystorePropertiesFile = rootProject.file(\"keystore_release.properties\")\n    //        val keystoreProperties = Properties()\n    //        if (keystorePropertiesFile.exists()) {\n    //            keystoreProperties.load(FileInputStream(keystorePropertiesFile))\n    //        }\n    //        storeFile = file(path = keystoreProperties[\"storeFile\"] as String)\n    //        storePassword = keystoreProperties[\"storePassword\"] as String\n    //        keyAlias = keystoreProperties[\"keyAlias\"] as String\n    //        keyPassword = keystoreProperties[\"keyPassword\"] as String\n    //    }\n  }\n\n  buildTypes {\n    getByName(\"release\") {\n      isDebuggable = false\n      isMinifyEnabled = false\n      isShrinkResources = false\n      proguardFiles(\n        getDefaultProguardFile(\"proguard-android-optimize.txt\"),\n        \"proguard-rules.pro\",\n      )\n      // signingConfig = signingConfigs.getByName(\"release\")\n    }\n    getByName(\"debug\") {\n      isDebuggable = true\n      versionNameSuffix = \"-debug\"\n      signingConfig = signingConfigs.getByName(\"debug\")\n    }\n  }\n\n  compileOptions {\n    sourceCompatibility = JavaVersion.VERSION_17\n    targetCompatibility = JavaVersion.VERSION_17\n  }\n  buildFeatures {\n    compose = true\n  }\n  dependencies {\n    debugImplementation(compose.uiTooling)\n  }\n}\n\ncompose.desktop {\n  application {\n    mainClass = \"MainKt\"\n\n    nativeDistributions {\n      targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)\n      packageName = \"JetLime Samples\"\n      packageVersion = \"1.0.0\"\n\n      windows {\n        // Automatically create a desktop shortcut on windows\n        shortcut = true\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "sample/composeApp/composeApp.podspec",
    "content": "Pod::Spec.new do |spec|\n    spec.name                     = 'composeApp'\n    spec.version                  = '1.0.0'\n    spec.homepage                 = 'empty'\n    spec.source                   = { :http=> ''}\n    spec.authors                  = ''\n    spec.license                  = ''\n    spec.summary                  = 'JetLime Sample App'\n    spec.vendored_frameworks      = 'build/cocoapods/framework/ComposeApp.framework'\n    spec.libraries                = 'c++'\n    spec.ios.deployment_target    = '14.0'\n    if !Dir.exist?('build/cocoapods/framework/ComposeApp.framework') || Dir.empty?('build/cocoapods/framework/ComposeApp.framework')\n        raise \"\n        Kotlin framework 'ComposeApp' doesn't exist yet, so a proper Xcode project can't be generated.\n        'pod install' should be executed after running ':generateDummyFramework' Gradle task:\n            ./gradlew :sample:composeApp:generateDummyFramework\n        Alternatively, proper pod installation is performed during Gradle sync in the IDE (if Podfile location is set)\"\n    end\n    spec.xcconfig = {\n        'ENABLE_USER_SCRIPT_SANDBOXING' => 'NO',\n    }\n    spec.pod_target_xcconfig = {\n        'KOTLIN_PROJECT_PATH' => ':sample:composeApp',\n        'PRODUCT_MODULE_NAME' => 'ComposeApp',\n    }\n    spec.script_phases = [\n        {\n            :name => 'Build composeApp',\n            :execution_position => :before_compile,\n            :shell_path => '/bin/sh',\n            :script => <<-SCRIPT\n                if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n                    echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n                    exit 0\n                fi\n                set -ev\n                REPO_ROOT=\"$PODS_TARGET_SRCROOT\"\n                \"$REPO_ROOT/../../gradlew\" -p \"$REPO_ROOT\" $KOTLIN_PROJECT_PATH:syncFramework \\\n                    -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \\\n                    -Pkotlin.native.cocoapods.archs=\"$ARCHS\" \\\n                    -Pkotlin.native.cocoapods.configuration=\"$CONFIGURATION\"\n            SCRIPT\n        }\n    ]\n    spec.resources = ['build/compose/cocoapods/compose-resources']\nend\n"
  },
  {
    "path": "sample/composeApp/src/androidMain/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\">\n\n  <application\n    android:allowBackup=\"true\"\n    android:icon=\"@mipmap/ic_launcher\"\n    android:label=\"@string/app_name\"\n    android:roundIcon=\"@mipmap/ic_launcher_round\"\n    android:supportsRtl=\"true\"\n    android:theme=\"@style/Theme.JetLime\">\n    <activity\n      android:exported=\"true\"\n      android:configChanges=\"orientation|screenSize|screenLayout|keyboardHidden|mnc|colorMode|density|fontScale|fontWeightAdjustment|keyboard|layoutDirection|locale|mcc|navigation|smallestScreenSize|touchscreen|uiMode\"\n      android:name=\".MainActivity\">\n      <intent-filter>\n        <action android:name=\"android.intent.action.MAIN\" />\n\n        <category android:name=\"android.intent.category.LAUNCHER\" />\n      </intent-filter>\n    </activity>\n  </application>\n\n</manifest>"
  },
  {
    "path": "sample/composeApp/src/androidMain/kotlin/com/pushpal/jetlime/sample/JetLimePreviews.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime.sample\n\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.CompositionLocalProvider\nimport androidx.compose.runtime.ExperimentalComposeApi\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.platform.LocalLayoutDirection\nimport androidx.compose.ui.tooling.preview.Preview\nimport androidx.compose.ui.unit.LayoutDirection\nimport androidx.compose.ui.unit.dp\nimport com.pushpal.jetlime.ItemsList\nimport com.pushpal.jetlime.JetLimeColumn\nimport com.pushpal.jetlime.JetLimeDefaults\nimport com.pushpal.jetlime.JetLimeEvent\nimport com.pushpal.jetlime.JetLimeEventDefaults\nimport com.pushpal.jetlime.JetLimeExtendedEvent\nimport com.pushpal.jetlime.JetLimeRow\nimport com.pushpal.jetlime.PointPlacement\n\n@Preview(name = \"JetLimeEvent Horizontal LTR\", showBackground = true, widthDp = 360)\n@Composable\nprivate fun JetLimeEventHorizontalLtrPreview() {\n  MaterialTheme {\n    Surface {\n      Row(modifier = Modifier.padding(16.dp)) {\n        JetLimeRow(\n          itemsList = ItemsList(listOf(\"One\", \"Two\", \"Three\")),\n          style = JetLimeDefaults.rowStyle(),\n        ) { index, item, position ->\n          JetLimeEvent(\n            style = JetLimeEventDefaults.eventStyle(\n              position = position,\n              pointPlacement = when (index) {\n                0 -> PointPlacement.START\n                1 -> PointPlacement.CENTER\n                else -> PointPlacement.END\n              },\n            ),\n          ) {\n            Text(text = item, modifier = Modifier.padding(8.dp))\n          }\n        }\n      }\n    }\n  }\n}\n\n@Preview(name = \"JetLimeEvent Horizontal RTL\", showBackground = true, widthDp = 360)\n@Composable\nprivate fun JetLimeEventHorizontalRtlPreview() {\n  MaterialTheme {\n    Surface {\n      CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {\n        Row(modifier = Modifier.padding(16.dp)) {\n          JetLimeRow(\n            itemsList = ItemsList(listOf(\"One\", \"Two\", \"Three\")),\n            style = JetLimeDefaults.rowStyle(),\n          ) { index, item, position ->\n            JetLimeEvent(\n              style = JetLimeEventDefaults.eventStyle(\n                position = position,\n                pointPlacement = when (index) {\n                  0 -> PointPlacement.START\n                  1 -> PointPlacement.CENTER\n                  else -> PointPlacement.END\n                },\n              ),\n            ) {\n              Text(text = item, modifier = Modifier.padding(8.dp))\n            }\n          }\n        }\n      }\n    }\n  }\n}\n\n@OptIn(ExperimentalComposeApi::class)\n@Preview(name = \"JetLimeExtendedEvent LTR\", showBackground = true, widthDp = 360)\n@Composable\nprivate fun JetLimeExtendedEventLtrPreview() {\n  MaterialTheme {\n    Surface {\n      Column(modifier = Modifier.padding(16.dp)) {\n        JetLimeColumn(\n          itemsList = ItemsList(listOf(\"A\", \"B\", \"C\")),\n          style = JetLimeDefaults.columnStyle(),\n        ) { index, item, position ->\n          JetLimeExtendedEvent(\n            style = JetLimeEventDefaults.eventStyle(position = position),\n            additionalContent = {\n              Text(text = \"Left $index\", modifier = Modifier.padding(4.dp))\n            },\n          ) {\n            Text(text = \"Right $item\", modifier = Modifier.padding(4.dp))\n          }\n        }\n      }\n    }\n  }\n}\n\n@OptIn(ExperimentalComposeApi::class)\n@Preview(name = \"JetLimeExtendedEvent RTL\", showBackground = true, widthDp = 360)\n@Composable\nprivate fun JetLimeExtendedEventRtlPreview() {\n  MaterialTheme {\n    Surface {\n      CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) {\n        Column(modifier = Modifier.padding(16.dp)) {\n          JetLimeColumn(\n            itemsList = ItemsList(listOf(\"A\", \"B\", \"C\")),\n            style = JetLimeDefaults.columnStyle(),\n          ) { index, item, position ->\n            JetLimeExtendedEvent(\n              style = JetLimeEventDefaults.eventStyle(position = position),\n              additionalContent = {\n                Text(text = \"Left $index\", modifier = Modifier.padding(4.dp))\n              },\n            ) {\n              Text(text = \"Right $item\", modifier = Modifier.padding(4.dp))\n            }\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "sample/composeApp/src/androidMain/kotlin/com/pushpal/jetlime/sample/MainActivity.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage com.pushpal.jetlime.sample\n\nimport App\nimport android.os.Bundle\nimport androidx.activity.ComponentActivity\nimport androidx.activity.compose.setContent\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.tooling.preview.Preview\n\nclass MainActivity : ComponentActivity() {\n  override fun onCreate(savedInstanceState: Bundle?) {\n    super.onCreate(savedInstanceState)\n\n    setContent {\n      App()\n    }\n  }\n}\n\n@Preview\n@Composable\nprivate fun AppAndroidPreview() {\n  App()\n}\n"
  },
  {
    "path": "sample/composeApp/src/androidMain/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path\n        android:fillColor=\"#3DDC84\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeWidth=\"0.8\"\n        android:strokeColor=\"#33FFFFFF\" />\n</vector>"
  },
  {
    "path": "sample/composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportWidth=\"108\"\n    android:viewportHeight=\"108\">\n    <path android:pathData=\"M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"85.84757\"\n                android:endY=\"92.4963\"\n                android:startX=\"42.9492\"\n                android:startY=\"49.59793\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z\"\n        android:strokeWidth=\"1\"\n        android:strokeColor=\"#00000000\" />\n</vector>"
  },
  {
    "path": "sample/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "sample/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "sample/composeApp/src/androidMain/res/values/strings.xml",
    "content": "<resources>\n    <string name=\"app_name\">JetLime Samples</string>\n</resources>"
  },
  {
    "path": "sample/composeApp/src/androidMain/res/values/themes.xml",
    "content": "<resources>\n  <style name=\"Theme.JetLime\" parent=\"android:Theme.Material.Light.NoActionBar\" />\n</resources>"
  },
  {
    "path": "sample/composeApp/src/androidMain/res/values-night/themes.xml",
    "content": "<resources>\n  <style name=\"Theme.JetLime\" parent=\"android:Theme.Material.NoActionBar\" />\n</resources>"
  },
  {
    "path": "sample/composeApp/src/commonMain/composeResources/drawable/icon_change.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:width=\"32dp\"\n  android:height=\"32dp\"\n  android:tint=\"#484848\"\n  android:viewportWidth=\"24\"\n  android:viewportHeight=\"24\">\n\n  <path\n    android:fillColor=\"#fff\"\n    android:pathData=\"M12,2C6.48,2 2,6.48 2,12c0,5.52 4.48,10 10,10s10,-4.48 10,-10C22,6.48 17.52,2 12,2zM12.06,19v-2.01c-0.02,0 -0.04,0 -0.06,0c-1.28,0 -2.56,-0.49 -3.54,-1.46c-1.71,-1.71 -1.92,-4.35 -0.64,-6.29l1.1,1.1c-0.71,1.33 -0.53,3.01 0.59,4.13c0.7,0.7 1.62,1.03 2.54,1.01v-2.14l2.83,2.83L12.06,19zM16.17,14.76l-1.1,-1.1c0.71,-1.33 0.53,-3.01 -0.59,-4.13C13.79,8.84 12.9,8.5 12,8.5c-0.02,0 -0.04,0 -0.06,0v2.15L9.11,7.83L11.94,5v2.02c1.3,-0.02 2.61,0.45 3.6,1.45C17.24,10.17 17.45,12.82 16.17,14.76z\" />\n\n</vector>\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/composeResources/drawable/icon_check.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n  android:width=\"32dp\"\n  android:height=\"32dp\"\n  android:viewportWidth=\"24\"\n  android:viewportHeight=\"24\">\n  <path\n    android:fillColor=\"#4CAF50\"\n    android:pathData=\"M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z\" />\n</vector>\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/App.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.setValue\nimport org.jetbrains.compose.ui.tooling.preview.Preview\nimport theme.JetLimeTheme\n\n@Composable\nfun App() {\n  var darkTheme by remember { mutableStateOf(true) }\n  JetLimeTheme(darkTheme = darkTheme) {\n    HomeScreen(\n      isDarkTheme = darkTheme,\n      onThemeChange = {\n        darkTheme = it\n      },\n    )\n  }\n}\n\n@Composable\n@Preview\nprivate fun AppPreview() {\n  App()\n}\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/Home.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\nimport androidx.compose.animation.ExperimentalAnimationApi\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.ExperimentalMaterial3Api\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.ScrollableTabRow\nimport androidx.compose.material3.SnackbarHost\nimport androidx.compose.material3.SnackbarHostState\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Switch\nimport androidx.compose.material3.Tab\nimport androidx.compose.material3.Text\nimport androidx.compose.material3.TopAppBar\nimport androidx.compose.material3.TopAppBarDefaults\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.getValue\nimport androidx.compose.runtime.mutableIntStateOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.rememberCoroutineScope\nimport androidx.compose.runtime.setValue\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport kotlinx.coroutines.launch\nimport org.jetbrains.compose.ui.tooling.preview.Preview\nimport timelines.BasicDashedTimeLine\nimport timelines.BasicHorizontalTimeLine\nimport timelines.BasicVerticalTimeLine\nimport timelines.CustomizedHorizontalTimeLine\nimport timelines.CustomizedVerticalTimeLine\nimport timelines.ExtendedVerticalTimeLine\nimport timelines.VerticalDynamicTimeLine\n\n@Composable\nfun HomeScreen(\n  modifier: Modifier = Modifier,\n  isDarkTheme: Boolean = false,\n  onThemeChange: ((Boolean) -> Unit) = {},\n) {\n  Scaffold(\n    modifier = modifier,\n    topBar = {\n      HomeAppBar(\n        isDarkTheme = isDarkTheme,\n        onThemeChange = onThemeChange,\n      )\n    },\n  ) { paddingValues ->\n    HomeContent(\n      modifier = Modifier\n        .padding(paddingValues)\n        .fillMaxSize(),\n    )\n  }\n}\n\n@OptIn(ExperimentalAnimationApi::class)\n@Composable\nfun HomeContent(modifier: Modifier = Modifier) {\n  val tabs = remember { listOf(\"Basic\", \"Dashed\", \"Dynamic\", \"Custom\", \"Extended\") }\n  var selectedIndex by remember { mutableIntStateOf(0) }\n  val snackBarState = remember { SnackbarHostState() }\n  val coroutineScope = rememberCoroutineScope()\n\n  Column(modifier = modifier) {\n    ScrollableTabRow(\n      selectedTabIndex = selectedIndex,\n      edgePadding = 16.dp,\n    ) {\n      tabs.forEachIndexed { index, title ->\n        Tab(\n          selected = index == selectedIndex,\n          onClick = { selectedIndex = tabs.indexOf(title) },\n          text = {\n            Text(\n              text = title,\n            )\n          },\n        )\n      }\n    }\n\n    Surface(\n      modifier = Modifier.fillMaxSize(),\n    ) {\n      Scaffold(\n        snackbarHost = { SnackbarHost(snackBarState) },\n        contentWindowInsets = WindowInsets(0.dp),\n      ) {\n        when (selectedIndex) {\n          0 -> {\n            Column {\n              BasicHorizontalTimeLine { coroutineScope.launch { snackBarState.showSnackbar(it) } }\n              BasicVerticalTimeLine { coroutineScope.launch { snackBarState.showSnackbar(it) } }\n            }\n          }\n\n          1 -> BasicDashedTimeLine { coroutineScope.launch { snackBarState.showSnackbar(it) } }\n\n          2 -> VerticalDynamicTimeLine { coroutineScope.launch { snackBarState.showSnackbar(it) } }\n\n          3 -> {\n            Column {\n              CustomizedHorizontalTimeLine()\n              CustomizedVerticalTimeLine()\n            }\n          }\n\n          4 -> ExtendedVerticalTimeLine { coroutineScope.launch { snackBarState.showSnackbar(it) } }\n        }\n      }\n    }\n  }\n}\n\n@OptIn(ExperimentalMaterial3Api::class)\n@Composable\nfun HomeAppBar(\n  isDarkTheme: Boolean,\n  modifier: Modifier = Modifier,\n  onThemeChange: ((Boolean) -> Unit)?,\n) {\n  TopAppBar(\n    title = {\n      Text(\n        text = \"JetLime Samples\",\n      )\n    },\n    actions = {\n      Switch(\n        checked = isDarkTheme,\n        onCheckedChange = onThemeChange,\n      )\n    },\n    colors = TopAppBarDefaults.topAppBarColors(),\n    modifier = modifier,\n  )\n}\n\n@Preview\n@Composable\nprivate fun PreviewHomeScreen() {\n  HomeScreen()\n}\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/data/Item.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage data\n\nimport kotlinx.collections.immutable.ImmutableList\nimport kotlinx.collections.immutable.persistentListOf\nimport org.jetbrains.compose.resources.DrawableResource\n\ndata class Item(\n  val id: Int = 0,\n  var name: String,\n  var info: String = \"\",\n  var images: ImmutableList<DrawableResource> = persistentListOf(),\n  var showActions: Boolean = false,\n  val description: String? = null,\n)\n\nfun getCharacters(): MutableList<Item> = mutableListOf(\n  Item(id = 0, name = \"Spider-Man\", description = \"The web-slinging hero of New York\"),\n  Item(id = 1, name = \"Iron Man\", description = \"Genius inventor in a high-tech suit\"),\n  Item(\n    id = 2,\n    name = \"Thor\",\n    description = \"Thor, the mighty Asgardian god of thunder, known for his heroic deeds and \" +\n      \"wielding the powerful hammer Mjolnir.\",\n  ),\n  Item(id = 3, name = \"Hulk\", description = \"Green-skinned, incredibly strong hero\"),\n  Item(id = 4, name = \"Black Widow\", description = \"Expert spy and combatant\"),\n  Item(id = 5, name = \"Captain America\", description = \"Super soldier with a shield\"),\n  Item(id = 6, name = \"Hawkeye\", description = \"Master archer and sharpshooter\"),\n  Item(id = 7, name = \"Doctor Strange\", description = \"Sorcerer Supreme of Mystic Arts\"),\n  Item(id = 8, name = \"Black Panther\", description = \"King of Wakanda, skilled fighter\"),\n  Item(id = 9, name = \"Captain Marvel\", description = \"One of the most powerful heroes\"),\n  Item(id = 10, name = \"Ant-Man\", description = \"Hero with size-shifting abilities\"),\n  Item(id = 11, name = \"Wasp\", description = \"Flying hero with shrinking power\"),\n  Item(id = 12, name = \"Scarlet Witch\", description = \"Wields chaos magic\"),\n  Item(id = 13, name = \"Vision\", description = \"Android with an Infinity Stone\"),\n  Item(id = 14, name = \"Falcon\", description = \"Aviator with mechanical wings\"),\n  Item(id = 15, name = \"Winter Soldier\", description = \"Enhanced soldier with a metal arm\"),\n  Item(id = 16, name = \"War Machine\", description = \"Pilot in an armored combat suit\"),\n  Item(id = 17, name = \"Star-Lord\", description = \"Leader of the Guardians\"),\n  Item(id = 18, name = \"Groot\", description = \"Tree-like being, says 'I am Groot'\"),\n  Item(id = 19, name = \"Rocket Raccoon\", description = \"Genetically altered raccoon\"),\n  Item(id = 20, name = \"Gamora\", description = \"Deadliest woman in the galaxy\"),\n  Item(id = 21, name = \"Drax\", description = \"Warrior seeking vengeance\"),\n  Item(id = 22, name = \"Mantis\", description = \"Empath with antennae\"),\n  Item(id = 23, name = \"Nebula\", description = \"Cybernetically enhanced warrior\"),\n  Item(id = 24, name = \"Loki\", description = \"The mischievous Asgardian god\"),\n  Item(id = 25, name = \"Thanos\", description = \"Titan obsessed with balance\"),\n  Item(id = 26, name = \"Daredevil\", description = \"Blind hero with heightened senses\"),\n  Item(id = 27, name = \"Jessica Jones\", description = \"Private investigator with super strength\"),\n  Item(id = 28, name = \"Luke Cage\", description = \"Hero with unbreakable skin\"),\n  Item(id = 29, name = \"Iron Fist\", description = \"Martial artist with a mystical force\"),\n)\n\nfun getPlanets(): MutableList<Item> = mutableListOf(\n  Item(id = 0, name = \"Earth\", description = \"Home to the Avengers\"),\n  Item(id = 1, name = \"Asgard\", description = \"Realm of the Norse gods\"),\n  Item(id = 2, name = \"Xandar\", description = \"Headquarters of the Nova Corps\"),\n  Item(id = 3, name = \"Sakaar\", description = \"Planet of gladiators and Hulk's arena\"),\n  Item(id = 4, name = \"Titan\", description = \"Birthplace of Thanos\"),\n  Item(id = 5, name = \"Knowhere\", description = \"Mining colony in a Celestial's head\"),\n  Item(id = 6, name = \"Ego\", description = \"Living planet and Celestial being\"),\n  Item(id = 7, name = \"Vormir\", description = \"Location of the Soul Stone\"),\n  Item(id = 8, name = \"Contraxia\", description = \"Pleasure planet with icy conditions\"),\n  Item(id = 9, name = \"Zen-Whoberi\", description = \"Gamora's homeworld\"),\n  Item(id = 10, name = \"Hala\", description = \"Capital of the Kree Empire\"),\n  Item(id = 11, name = \"Spartax\", description = \"Planet ruled by Star-Lord's father\"),\n  Item(id = 12, name = \"Maveth\", description = \"Barren and remote planet\"),\n  Item(id = 13, name = \"Olympia\", description = \"Home of the Eternals\"),\n  Item(id = 14, name = \"Nidavellir\", description = \"Dwarven realm, creators of Mjolnir\"),\n)\n\nval placeNames = listOf(\n  \"Central Park\", \"Harbor View\", \"Visited Oak Street?\", \"Maple Avenue\", \"River Road\",\n  \"Sunset Boulevard\", \"Pine Lane\", \"Elm Street\", \"Cedar Drive\", \"Willow Way\",\n)\nval activityNames = listOf(\n  \"Walking\", \"Running\", \"Cycling\", \"Hiking\", \"Swimming\",\n  \"Reading\", \"Drawing\", \"Cooking\", \"Gardening\", \"Fishing\",\n)\n\nfun String.extractFirstTime(): String? {\n  val timePattern = \"\\\\d{1,2}:\\\\d{2} [APM]{2}\".toRegex()\n  return timePattern.find(this)?.value\n}\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/theme/Color.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage theme\n\nimport androidx.compose.ui.graphics.Color\n\nobject LightColors {\n  val Primary = Color(0xFF1976D2)\n  val OnPrimary = Color.White\n  val PrimaryContainer = Color(0xFFBBDEFB)\n  val OnPrimaryContainer = Color.Black\n  val InversePrimary = Color(0xFF82B1FF)\n  val Secondary = Color(0xFF455A64)\n  val OnSecondary = Color.White\n  val SecondaryContainer = Color(0xFFCFD8DC)\n  val OnSecondaryContainer = Color.Black\n  val Tertiary = Color(0xFF00796B)\n  val OnTertiary = Color.White\n  val TertiaryContainer = Color(0xFFB2DFDB)\n  val OnTertiaryContainer = Color.Black\n  val Background = Color(0xFFE3F2FD)\n  val OnBackground = Color.Black\n  val Surface = Color.White\n  val OnSurface = Color.Black\n  val SurfaceVariant = Color(0xFFECEFF1)\n  val OnSurfaceVariant = Color.Black\n  val SurfaceTint = Primary\n  val InverseSurface = Color(0xFF121212)\n  val InverseOnSurface = Color.White\n  val Error = Color(0xFFB00020)\n  val OnError = Color.White\n  val ErrorContainer = Color(0xFFFDE7E9)\n  val OnErrorContainer = Color.Black\n  val Outline = Color(0xFFB0BEC5)\n  val OutlineVariant = Color(0xFF90A4AE)\n  val Scrim = Color(0xFF000000)\n}\n\nobject DarkColors {\n  val Primary = Color(0xFF82B1FF)\n  val OnPrimary = Color.Black\n  val PrimaryContainer = Color(0xFF005CB2)\n  val OnPrimaryContainer = Color.White\n  val InversePrimary = Color(0xFF1976D2)\n  val Secondary = Color(0xFFB0BEC5)\n  val OnSecondary = Color.Black\n  val SecondaryContainer = Color(0xFF37474F)\n  val OnSecondaryContainer = Color.White\n  val Tertiary = Color(0xFF4DB6AC)\n  val OnTertiary = Color.Black\n  val TertiaryContainer = Color(0xFF004D40)\n  val OnTertiaryContainer = Color.White\n  val Background = Color(0xFF121212)\n  val OnBackground = Color.White\n  val Surface = Color(0xFF1E1E1E)\n  val OnSurface = Color.White\n  val SurfaceVariant = Color(0xFF263238)\n  val OnSurfaceVariant = Color.White\n  val SurfaceTint = Primary\n  val InverseSurface = Color.White\n  val InverseOnSurface = Color.Black\n  val Error = Color(0xFFCF6679)\n  val OnError = Color.Black\n  val ErrorContainer = Color(0xFFB00020)\n  val OnErrorContainer = Color.White\n  val Outline = Color(0xFF37474F)\n  val OutlineVariant = Color(0xFF455A64)\n  val Scrim = Color(0xFF000000)\n}\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/theme/Shape.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage theme\n\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material3.Shapes\nimport androidx.compose.ui.unit.dp\n\nval JetLimeShapes =\n  Shapes(\n    small = RoundedCornerShape(4.dp),\n    medium = RoundedCornerShape(6.dp),\n    large = RoundedCornerShape(10.dp),\n  )\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/theme/Theme.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage theme\n\nimport androidx.compose.foundation.isSystemInDarkTheme\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.darkColorScheme\nimport androidx.compose.material3.lightColorScheme\nimport androidx.compose.runtime.Composable\n\nval DarkColorPalette = darkColorScheme(\n  primary = DarkColors.Primary,\n  onPrimary = DarkColors.OnPrimary,\n  primaryContainer = DarkColors.PrimaryContainer,\n  onPrimaryContainer = DarkColors.OnPrimaryContainer,\n  inversePrimary = DarkColors.InversePrimary,\n  secondary = DarkColors.Secondary,\n  onSecondary = DarkColors.OnSecondary,\n  secondaryContainer = DarkColors.SecondaryContainer,\n  onSecondaryContainer = DarkColors.OnSecondaryContainer,\n  tertiary = DarkColors.Tertiary,\n  onTertiary = DarkColors.OnTertiary,\n  tertiaryContainer = DarkColors.TertiaryContainer,\n  onTertiaryContainer = DarkColors.OnTertiaryContainer,\n  background = DarkColors.Background,\n  onBackground = DarkColors.OnBackground,\n  surface = DarkColors.Surface,\n  onSurface = DarkColors.OnSurface,\n  surfaceVariant = DarkColors.SurfaceVariant,\n  onSurfaceVariant = DarkColors.OnSurfaceVariant,\n  surfaceTint = DarkColors.SurfaceTint,\n  inverseSurface = DarkColors.InverseSurface,\n  inverseOnSurface = DarkColors.InverseOnSurface,\n  error = DarkColors.Error,\n  onError = DarkColors.OnError,\n  errorContainer = DarkColors.ErrorContainer,\n  onErrorContainer = DarkColors.OnErrorContainer,\n  outline = DarkColors.Outline,\n  outlineVariant = DarkColors.OutlineVariant,\n  scrim = DarkColors.Scrim,\n)\n\nval LightColorPalette = lightColorScheme(\n  primary = LightColors.Primary,\n  onPrimary = LightColors.OnPrimary,\n  primaryContainer = LightColors.PrimaryContainer,\n  onPrimaryContainer = LightColors.OnPrimaryContainer,\n  inversePrimary = LightColors.InversePrimary,\n  secondary = LightColors.Secondary,\n  onSecondary = LightColors.OnSecondary,\n  secondaryContainer = LightColors.SecondaryContainer,\n  onSecondaryContainer = LightColors.OnSecondaryContainer,\n  tertiary = LightColors.Tertiary,\n  onTertiary = LightColors.OnTertiary,\n  tertiaryContainer = LightColors.TertiaryContainer,\n  onTertiaryContainer = LightColors.OnTertiaryContainer,\n  background = LightColors.Background,\n  onBackground = LightColors.OnBackground,\n  surface = LightColors.Surface,\n  onSurface = LightColors.OnSurface,\n  surfaceVariant = LightColors.SurfaceVariant,\n  onSurfaceVariant = LightColors.OnSurfaceVariant,\n  surfaceTint = LightColors.SurfaceTint,\n  inverseSurface = LightColors.InverseSurface,\n  inverseOnSurface = LightColors.InverseOnSurface,\n  error = LightColors.Error,\n  onError = LightColors.OnError,\n  errorContainer = LightColors.ErrorContainer,\n  onErrorContainer = LightColors.OnErrorContainer,\n  outline = LightColors.Outline,\n  outlineVariant = LightColors.OutlineVariant,\n  scrim = LightColors.Scrim,\n)\n\n@Composable\nfun JetLimeTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {\n  val colors = if (darkTheme) {\n    DarkColorPalette\n  } else {\n    LightColorPalette\n  }\n\n  MaterialTheme(\n    colorScheme = colors,\n    shapes = JetLimeShapes,\n    content = content,\n  )\n}\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/timelines/BasicDashedTimeLine.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage timelines\n\nimport androidx.compose.animation.ExperimentalAnimationApi\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.PathEffect\nimport androidx.compose.ui.unit.dp\nimport com.pushpal.jetlime.EventPointType\nimport com.pushpal.jetlime.ItemsList\nimport com.pushpal.jetlime.JetLimeColumn\nimport com.pushpal.jetlime.JetLimeDefaults\nimport com.pushpal.jetlime.JetLimeEvent\nimport com.pushpal.jetlime.JetLimeEventDefaults\nimport com.pushpal.jetlime.PointPlacement\nimport data.getCharacters\nimport org.jetbrains.compose.ui.tooling.preview.Preview\nimport timelines.event.VerticalEventContent\n\n@ExperimentalAnimationApi\n@Composable\nfun BasicDashedTimeLine(modifier: Modifier = Modifier, showSnackbar: (message: String) -> Unit) {\n  val items = remember { getCharacters().subList(0, 7) }\n\n  Surface(\n    modifier = modifier.fillMaxSize(),\n  ) {\n    JetLimeColumn(\n      modifier = Modifier.padding(16.dp),\n      itemsList = ItemsList(items),\n      style = JetLimeDefaults.columnStyle(\n        pathEffect = PathEffect.dashPathEffect(\n          intervals = floatArrayOf(30f, 30f),\n          phase = 0f,\n        ),\n      ),\n      key = { _, item -> item.id },\n    ) { index, item, position ->\n      JetLimeEvent(\n        style = JetLimeEventDefaults.eventStyle(\n          position = position,\n          pointPlacement = if (index > 1) PointPlacement.CENTER else PointPlacement.START,\n          pointAnimation = if (index == 2) JetLimeEventDefaults.pointAnimation() else null,\n          pointType = if (index == 1) EventPointType.filled(0.8f) else EventPointType.Default,\n        ),\n      ) {\n        VerticalEventContent(\n          modifier = Modifier.clickable {\n            showSnackbar(\"Clicked on item: $index\")\n          },\n          item = item,\n        )\n      }\n    }\n  }\n}\n\n@ExperimentalAnimationApi\n@Preview\n@Composable\nprivate fun PreviewBasicDashedTimeLine() {\n  BasicDashedTimeLine {}\n}\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/timelines/BasicHorizontalTimeLine.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage timelines\n\nimport androidx.compose.animation.ExperimentalAnimationApi\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.pushpal.jetlime.ItemsList\nimport com.pushpal.jetlime.JetLimeEvent\nimport com.pushpal.jetlime.JetLimeEventDefaults\nimport com.pushpal.jetlime.JetLimeRow\nimport com.pushpal.jetlime.PointPlacement\nimport data.getPlanets\nimport org.jetbrains.compose.ui.tooling.preview.Preview\nimport timelines.event.HorizontalEventContent\n\n@ExperimentalAnimationApi\n@Composable\nfun BasicHorizontalTimeLine(\n  modifier: Modifier = Modifier,\n  showSnackbar: (message: String) -> Unit,\n) {\n  val items = remember { getPlanets() }\n\n  Surface(\n    modifier = modifier.fillMaxWidth(),\n  ) {\n    JetLimeRow(\n      modifier = Modifier.padding(vertical = 32.dp, horizontal = 16.dp),\n      itemsList = ItemsList(items),\n      key = { _, item -> item.id },\n    ) { index, item, position ->\n      JetLimeEvent(\n        style = JetLimeEventDefaults.eventStyle(\n          position = position,\n          pointPlacement = if (index > 1) PointPlacement.CENTER else PointPlacement.START,\n          pointAnimation = if (index == 1) JetLimeEventDefaults.pointAnimation() else null,\n        ),\n      ) {\n        HorizontalEventContent(\n          modifier = Modifier.clickable {\n            showSnackbar(\"Clicked on item: $index\")\n          },\n          item = item,\n        )\n      }\n    }\n  }\n}\n\n@ExperimentalAnimationApi\n@Preview\n@Composable\nprivate fun PreviewBasicHorizontalTimeLine() {\n  BasicHorizontalTimeLine {}\n}\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/timelines/BasicVerticalTimeLine.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage timelines\n\nimport androidx.compose.animation.ExperimentalAnimationApi\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.pushpal.jetlime.EventPointType\nimport com.pushpal.jetlime.ItemsList\nimport com.pushpal.jetlime.JetLimeColumn\nimport com.pushpal.jetlime.JetLimeEvent\nimport com.pushpal.jetlime.JetLimeEventDefaults\nimport com.pushpal.jetlime.PointPlacement\nimport data.getCharacters\nimport org.jetbrains.compose.ui.tooling.preview.Preview\nimport timelines.event.VerticalEventContent\n\n@ExperimentalAnimationApi\n@Composable\nfun BasicVerticalTimeLine(modifier: Modifier = Modifier, showSnackbar: (message: String) -> Unit) {\n  val items = remember { getCharacters().subList(0, 4) }\n\n  Surface(\n    modifier = modifier.fillMaxSize(),\n  ) {\n    JetLimeColumn(\n      modifier = Modifier.padding(16.dp),\n      itemsList = ItemsList(items),\n      key = { _, item -> item.id },\n    ) { index, item, position ->\n      JetLimeEvent(\n        style = JetLimeEventDefaults.eventStyle(\n          position = position,\n          pointPlacement = if (index > 1) PointPlacement.CENTER else PointPlacement.START,\n          pointAnimation = if (index == 2) JetLimeEventDefaults.pointAnimation() else null,\n          pointType = if (index == 1) EventPointType.filled(0.8f) else EventPointType.Default,\n        ),\n      ) {\n        VerticalEventContent(\n          modifier = Modifier.clickable {\n            showSnackbar(\"Clicked on item: $index\")\n          },\n          item = item,\n        )\n      }\n    }\n  }\n}\n\n@ExperimentalAnimationApi\n@Preview\n@Composable\nprivate fun BasicVerticalTimeLinePreview() {\n  BasicVerticalTimeLine {}\n}\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/timelines/CustomizedHorizontalTimeLine.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage timelines\n\nimport androidx.compose.animation.ExperimentalAnimationApi\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.unit.dp\nimport com.pushpal.jetlime.EventPointType\nimport com.pushpal.jetlime.HorizontalAlignment.BOTTOM\nimport com.pushpal.jetlime.ItemsList\nimport com.pushpal.jetlime.JetLimeDefaults\nimport com.pushpal.jetlime.JetLimeEvent\nimport com.pushpal.jetlime.JetLimeEventDefaults\nimport com.pushpal.jetlime.JetLimeRow\nimport com.pushpal.jetlime.PointPlacement\nimport data.getPlanets\nimport jetlime.sample.composeapp.generated.resources.Res\nimport jetlime.sample.composeapp.generated.resources.icon_check\nimport org.jetbrains.compose.resources.painterResource\nimport org.jetbrains.compose.ui.tooling.preview.Preview\nimport timelines.event.HorizontalEventContent\n\n@ExperimentalAnimationApi\n@Composable\nfun CustomizedHorizontalTimeLine(modifier: Modifier = Modifier) {\n  val items = remember { getPlanets() }\n\n  Surface(\n    modifier = modifier.fillMaxWidth(),\n  ) {\n    JetLimeRow(\n      modifier = Modifier.padding(vertical = 32.dp, horizontal = 16.dp),\n      itemsList = ItemsList(items),\n      key = { _, item -> item.id },\n      style = JetLimeDefaults.rowStyle(\n        contentDistance = 16.dp,\n        itemSpacing = 16.dp,\n        lineThickness = 2.dp,\n        lineBrush = JetLimeDefaults.lineSolidBrush(color = Color(0xFF2196F3)),\n        lineHorizontalAlignment = BOTTOM,\n      ),\n    ) { index, item, position ->\n      JetLimeEvent(\n        style = JetLimeEventDefaults.eventStyle(\n          position = position,\n          pointRadius = 12.dp,\n          pointFillColor = Color(0xFFD5F2FF),\n          pointColor = when (index) {\n            2 -> Color.White\n            else -> Color(0xFF2889D6)\n          },\n          pointPlacement = if (index > 2) PointPlacement.CENTER else PointPlacement.START,\n          pointAnimation = if (index == 3) JetLimeEventDefaults.pointAnimation() else null,\n          pointType = when (index) {\n            1 -> EventPointType.filled(0.7f)\n\n            // 70% fill\n            2 -> EventPointType.custom(\n              icon = painterResource(Res.drawable.icon_check),\n              tint = Color(0xFF00BCD4),\n            )\n\n            else -> EventPointType.Default\n          },\n          pointStrokeWidth = when (index) {\n            2 -> 0.dp\n            else -> 2.dp\n          },\n          pointStrokeColor = MaterialTheme.colorScheme.onBackground,\n        ),\n      ) {\n        HorizontalEventContent(item = item)\n      }\n    }\n  }\n}\n\n@ExperimentalAnimationApi\n@Preview\n@Composable\nprivate fun PreviewCustomizedHorizontalTimeLine() {\n  CustomizedHorizontalTimeLine()\n}\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/timelines/CustomizedVerticalTimeLine.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage timelines\n\nimport androidx.compose.animation.ExperimentalAnimationApi\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.unit.dp\nimport com.pushpal.jetlime.EventPointType\nimport com.pushpal.jetlime.ItemsList\nimport com.pushpal.jetlime.JetLimeColumn\nimport com.pushpal.jetlime.JetLimeDefaults\nimport com.pushpal.jetlime.JetLimeEvent\nimport com.pushpal.jetlime.JetLimeEventDefaults\nimport com.pushpal.jetlime.PointPlacement\nimport com.pushpal.jetlime.VerticalAlignment.RIGHT\nimport data.getCharacters\nimport jetlime.sample.composeapp.generated.resources.Res\nimport jetlime.sample.composeapp.generated.resources.icon_change\nimport jetlime.sample.composeapp.generated.resources.icon_check\nimport org.jetbrains.compose.resources.painterResource\nimport org.jetbrains.compose.ui.tooling.preview.Preview\nimport timelines.event.VerticalEventContent\n\n@ExperimentalAnimationApi\n@Composable\nfun CustomizedVerticalTimeLine(modifier: Modifier = Modifier) {\n  val items = remember { getCharacters().subList(0, 5) }\n\n  Surface(\n    modifier = modifier.fillMaxSize(),\n  ) {\n    JetLimeColumn(\n      modifier = Modifier.padding(horizontal = 16.dp),\n      itemsList = ItemsList(items),\n      key = { _, item -> item.id },\n      style = JetLimeDefaults.columnStyle(\n        contentDistance = 24.dp,\n        itemSpacing = 16.dp,\n        lineThickness = 2.dp,\n        lineBrush = JetLimeDefaults.lineSolidBrush(color = Color(0xFF2196F3)),\n        lineVerticalAlignment = RIGHT,\n      ),\n    ) { index, item, position ->\n      JetLimeEvent(\n        style = JetLimeEventDefaults.eventStyle(\n          position = position,\n          pointFillColor = Color(0xFFCCEFFF),\n          pointRadius = 12.dp,\n          pointColor = when (index) {\n            3, 4 -> Color.White\n            else -> Color(0xFF2889D6)\n          },\n          pointPlacement = if (index > 3) PointPlacement.CENTER else PointPlacement.START,\n          pointAnimation = when (index) {\n            1, 4 -> JetLimeEventDefaults.pointAnimation()\n            else -> null\n          },\n          pointType = when (index) {\n            1 -> EventPointType.filled(0.7f)\n\n            // 70% fill\n            3 -> EventPointType.custom(\n              icon = painterResource(Res.drawable.icon_check),\n              tint = Color(0xFF649228),\n            )\n\n            4 -> EventPointType.custom(\n              icon = painterResource(Res.drawable.icon_change),\n              tint = Color(0xFFFF5722),\n            )\n\n            else -> EventPointType.Default // Default style for rest\n          },\n          pointStrokeWidth = when (index) {\n            2, 4 -> 0.dp\n            3 -> 1.dp\n            else -> 2.dp\n          },\n          pointStrokeColor = MaterialTheme.colorScheme.onBackground,\n        ),\n      ) {\n        VerticalEventContent(item = item)\n      }\n    }\n  }\n}\n\n@ExperimentalAnimationApi\n@Preview\n@Composable\nprivate fun PreviewCustomizedVerticalTimeLine() {\n  CustomizedVerticalTimeLine()\n}\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/timelines/ExtendedVerticalTimeLine.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage timelines\n\nimport androidx.compose.animation.ExperimentalAnimationApi\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.ExperimentalComposeApi\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.runtime.snapshots.SnapshotStateList\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.graphics.Color\nimport androidx.compose.ui.unit.dp\nimport com.pushpal.jetlime.ItemsList\nimport com.pushpal.jetlime.JetLimeColumn\nimport com.pushpal.jetlime.JetLimeDefaults\nimport com.pushpal.jetlime.JetLimeEventDefaults\nimport com.pushpal.jetlime.JetLimeExtendedEvent\nimport data.Item\nimport data.activityNames\nimport data.placeNames\nimport org.jetbrains.compose.ui.tooling.preview.Preview\nimport timelines.event.ExtendedEventAdditionalContent\nimport timelines.event.ExtendedEventContent\nimport timelines.event.activityDescription\nimport timelines.event.activityInfo\nimport timelines.event.decidePointAnimation\nimport timelines.event.decidePointType\nimport timelines.event.placeDescription\nimport timelines.event.placeImages\nimport timelines.event.placeInfo\n\n@OptIn(ExperimentalComposeApi::class)\n@ExperimentalAnimationApi\n@Composable\nfun ExtendedVerticalTimeLine(\n  modifier: Modifier = Modifier,\n  showSnackbar: (message: String) -> Unit,\n) {\n  val items = remember { mutableStateListOf<Item>() }\n\n  // Generate sample data to populate in the list\n  GenerateDataEffect(items)\n\n  Surface(\n    modifier = modifier.fillMaxSize(),\n  ) {\n    JetLimeColumn(\n      modifier = Modifier.padding(top = 16.dp, start = 16.dp, end = 16.dp),\n      itemsList = ItemsList(items),\n      key = { _, item -> item.id },\n      style = JetLimeDefaults.columnStyle(contentDistance = 24.dp),\n    ) { index, item, position ->\n      JetLimeExtendedEvent(\n        style = JetLimeEventDefaults.eventStyle(\n          position = position,\n          pointAnimation = index.decidePointAnimation(),\n          pointRadius = 14.dp,\n          pointColor = Color.White,\n          pointStrokeColor = MaterialTheme.colorScheme.onPrimaryContainer,\n          pointType = index.decidePointType(),\n        ),\n        additionalContentMaxWidth = 88.dp,\n        additionalContent = {\n          ExtendedEventAdditionalContent(\n            modifier = Modifier\n              .fillMaxWidth()\n              .clickable {\n                showSnackbar(\"Clicked on additional content: $index\")\n              },\n            item = item,\n          )\n        },\n      ) {\n        ExtendedEventContent(\n          modifier = Modifier\n            .clickable {\n              showSnackbar(\"Clicked on content: $index\")\n            },\n          item = item,\n        )\n      }\n    }\n  }\n}\n\n@Composable\nprivate fun GenerateDataEffect(items: SnapshotStateList<Item>) {\n  LaunchedEffect(Unit) {\n    for (i in 0 until 15) {\n      items.add(\n        Item(\n          id = i,\n          name = placeNames[i % placeNames.size],\n          info = placeInfo(i),\n          description = placeDescription(i),\n          images = placeImages(i),\n          showActions = i == 2,\n        ),\n      )\n      items.add(\n        Item(\n          id = i + 15,\n          name = activityNames[i % activityNames.size],\n          info = activityInfo(i),\n          description = activityDescription(i),\n        ),\n      )\n    }\n  }\n}\n\n@ExperimentalAnimationApi\n@Preview\n@Composable\nprivate fun PreviewExtendedVerticalTimeLine() {\n  ExtendedVerticalTimeLine {}\n}\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/timelines/VerticalDynamicTimeLine.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage timelines\n\nimport androidx.compose.animation.ExperimentalAnimationApi\nimport androidx.compose.foundation.clickable\nimport androidx.compose.foundation.layout.Arrangement\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.WindowInsets\nimport androidx.compose.foundation.layout.fillMaxSize\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.lazy.rememberLazyListState\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.Add\nimport androidx.compose.material.icons.filled.Delete\nimport androidx.compose.material3.ExtendedFloatingActionButton\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Scaffold\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.runtime.LaunchedEffect\nimport androidx.compose.runtime.mutableStateListOf\nimport androidx.compose.runtime.remember\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.unit.dp\nimport com.pushpal.jetlime.ItemsList\nimport com.pushpal.jetlime.JetLimeColumn\nimport com.pushpal.jetlime.JetLimeDefaults\nimport com.pushpal.jetlime.JetLimeEvent\nimport com.pushpal.jetlime.JetLimeEventDefaults\nimport com.pushpal.jetlime.PointPlacement\nimport data.Item\nimport data.getCharacters\nimport org.jetbrains.compose.ui.tooling.preview.Preview\nimport timelines.event.VerticalEventContent\n\n@ExperimentalAnimationApi\n@Composable\nfun VerticalDynamicTimeLine(\n  modifier: Modifier = Modifier,\n  showSnackbar: (message: String) -> Unit,\n) {\n  val listState = rememberLazyListState()\n  val items = remember { mutableStateListOf<Item>() }\n  val allCharacters = getCharacters().distinct()\n\n  LaunchedEffect(Unit) {\n    items.add(allCharacters.first())\n  }\n\n  Scaffold(\n    modifier = modifier,\n    contentWindowInsets = WindowInsets(0.dp),\n    floatingActionButton = {\n      Column(\n        verticalArrangement = Arrangement.spacedBy(8.dp),\n      ) {\n        ExtendedFloatingActionButton(\n          onClick = {\n            if (items.size < allCharacters.size) {\n              val newItem = allCharacters[items.size]\n              if (!items.contains(newItem)) {\n                items.add(newItem)\n              }\n            }\n          },\n          containerColor = MaterialTheme.colorScheme.secondaryContainer,\n          contentColor = MaterialTheme.colorScheme.secondary,\n        ) {\n          Icon(Icons.Filled.Add, \"Add item\")\n          Spacer(modifier = Modifier.width(4.dp))\n          Text(text = \"Add Item\")\n        }\n        ExtendedFloatingActionButton(\n          onClick = {\n            if (items.isNotEmpty()) {\n              items.removeAt(items.size - 1)\n            }\n          },\n          containerColor = MaterialTheme.colorScheme.secondaryContainer,\n          contentColor = MaterialTheme.colorScheme.secondary,\n        ) {\n          Icon(Icons.Filled.Delete, \"Remove\")\n          Spacer(modifier = Modifier.width(4.dp))\n          Text(text = \"Remove Item\")\n        }\n      }\n    },\n  ) { paddingValues ->\n    Surface(\n      modifier = Modifier\n        .padding(paddingValues)\n        .fillMaxSize(),\n    ) {\n      JetLimeColumn(\n        modifier = Modifier.padding(32.dp),\n        listState = listState,\n        style = JetLimeDefaults.columnStyle(\n          lineBrush = JetLimeDefaults.lineGradientBrush(),\n        ),\n        itemsList = ItemsList(items),\n        key = { _, item -> item.id },\n      ) { index, item, position ->\n        JetLimeEvent(\n          modifier = Modifier.clickable {\n            showSnackbar(\"Clicked on item: $index\")\n          },\n          style = JetLimeEventDefaults.eventStyle(\n            position = position,\n            pointPlacement = if (index == 3 ||\n              index == 5\n            ) {\n              PointPlacement.CENTER\n            } else {\n              PointPlacement.START\n            },\n          ),\n        ) {\n          VerticalEventContent(item = item)\n        }\n      }\n    }\n  }\n}\n\n@ExperimentalAnimationApi\n@Preview\n@Composable\nprivate fun PreviewSimpleVerticalDynamicTimeLine() {\n  VerticalDynamicTimeLine {}\n}\n"
  },
  {
    "path": "sample/composeApp/src/commonMain/kotlin/timelines/event/EventContent.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\npackage timelines.event\n\nimport androidx.compose.foundation.Image\nimport androidx.compose.foundation.layout.Column\nimport androidx.compose.foundation.layout.Row\nimport androidx.compose.foundation.layout.Spacer\nimport androidx.compose.foundation.layout.fillMaxWidth\nimport androidx.compose.foundation.layout.height\nimport androidx.compose.foundation.layout.padding\nimport androidx.compose.foundation.layout.size\nimport androidx.compose.foundation.layout.width\nimport androidx.compose.foundation.layout.wrapContentHeight\nimport androidx.compose.foundation.shape.RoundedCornerShape\nimport androidx.compose.material.icons.Icons\nimport androidx.compose.material.icons.filled.Check\nimport androidx.compose.material.icons.filled.Edit\nimport androidx.compose.material3.Button\nimport androidx.compose.material3.Card\nimport androidx.compose.material3.Icon\nimport androidx.compose.material3.MaterialTheme\nimport androidx.compose.material3.Surface\nimport androidx.compose.material3.Text\nimport androidx.compose.runtime.Composable\nimport androidx.compose.ui.Modifier\nimport androidx.compose.ui.draw.clip\nimport androidx.compose.ui.layout.ContentScale\nimport androidx.compose.ui.text.font.FontWeight\nimport androidx.compose.ui.text.style.TextAlign\nimport androidx.compose.ui.unit.dp\nimport androidx.compose.ui.unit.sp\nimport com.pushpal.jetlime.EventPointAnimation\nimport com.pushpal.jetlime.EventPointType\nimport com.pushpal.jetlime.JetLimeEventDefaults\nimport data.Item\nimport data.extractFirstTime\nimport jetlime.sample.composeapp.generated.resources.Res\nimport jetlime.sample.composeapp.generated.resources.icon_check\nimport jetlime.sample.composeapp.generated.resources.image_1\nimport jetlime.sample.composeapp.generated.resources.image_2\nimport kotlinx.collections.immutable.persistentListOf\nimport org.jetbrains.compose.resources.painterResource\n\n@Composable\nfun VerticalEventContent(item: Item, modifier: Modifier = Modifier) {\n  Card(\n    modifier = modifier,\n  ) {\n    Text(\n      modifier = Modifier\n        .fillMaxWidth()\n        .wrapContentHeight()\n        .padding(horizontal = 12.dp, vertical = 8.dp),\n      fontSize = 16.sp,\n      fontWeight = FontWeight.SemiBold,\n      text = item.name,\n    )\n    item.description?.let {\n      Text(\n        modifier = Modifier\n          .fillMaxWidth()\n          .wrapContentHeight()\n          .padding(horizontal = 12.dp, vertical = 8.dp),\n        fontSize = 14.sp,\n        text = it,\n      )\n    }\n  }\n}\n\n@Composable\nfun HorizontalEventContent(item: Item, modifier: Modifier = Modifier) {\n  Card(\n    modifier = modifier\n      .fillMaxWidth()\n      .height(120.dp)\n      .width(160.dp),\n  ) {\n    Text(\n      modifier = Modifier\n        .fillMaxWidth()\n        .wrapContentHeight()\n        .padding(12.dp),\n      fontSize = 16.sp,\n      fontWeight = FontWeight.SemiBold,\n      text = item.name,\n    )\n    item.description?.let {\n      Text(\n        modifier = Modifier\n          .fillMaxWidth()\n          .wrapContentHeight()\n          .padding(horizontal = 12.dp, vertical = 8.dp),\n        fontSize = 14.sp,\n        text = it,\n      )\n    }\n  }\n}\n\n@Composable\nfun ExtendedEventAdditionalContent(item: Item, modifier: Modifier = Modifier) {\n  Card(modifier = modifier) {\n    Text(\n      modifier = Modifier\n        .fillMaxWidth()\n        .padding(vertical = 8.dp, horizontal = 16.dp),\n      fontSize = 12.sp,\n      text = item.description?.extractFirstTime() ?: \"\",\n      textAlign = TextAlign.Center,\n    )\n  }\n}\n\n@Composable\nfun ExtendedEventContent(item: Item, modifier: Modifier = Modifier) {\n  Surface(\n    modifier = modifier\n      .wrapContentHeight(),\n  ) {\n    Column(\n      modifier = Modifier.padding(bottom = 8.dp),\n    ) {\n      Text(\n        modifier = Modifier\n          .fillMaxWidth()\n          .wrapContentHeight()\n          .padding(bottom = 4.dp),\n        fontSize = 14.sp,\n        fontWeight = FontWeight.SemiBold,\n        text = item.name,\n      )\n      Text(\n        modifier = Modifier\n          .fillMaxWidth()\n          .wrapContentHeight()\n          .padding(bottom = 2.dp),\n        color = MaterialTheme.colorScheme.secondary,\n        fontSize = 12.sp,\n        text = item.info,\n      )\n      item.description?.let {\n        Text(\n          modifier = Modifier\n            .fillMaxWidth()\n            .wrapContentHeight(),\n          color = MaterialTheme.colorScheme.secondary,\n          fontSize = 12.sp,\n          text = it,\n        )\n      }\n      if (item.images.isNotEmpty()) {\n        Column {\n          Row {\n            item.images.forEach {\n              Image(\n                modifier = Modifier\n                  .size(100.dp)\n                  .padding(top = 12.dp, end = 8.dp)\n                  .clip(\n                    RoundedCornerShape(5),\n                  ),\n                contentScale = ContentScale.Crop,\n                painter = painterResource(resource = it),\n                contentDescription = null,\n              )\n            }\n          }\n          Spacer(modifier = Modifier.height(10.dp))\n          Text(\n            modifier = Modifier.fillMaxWidth(),\n            color = MaterialTheme.colorScheme.secondary,\n            fontSize = 12.sp,\n            text = \"From Google Photos\",\n          )\n          Spacer(modifier = Modifier.height(8.dp))\n        }\n      }\n\n      if (item.showActions) {\n        Row(modifier = Modifier.padding(top = 8.dp)) {\n          Button(onClick = {}) {\n            Icon(Icons.Filled.Check, \"Add item\")\n            Spacer(modifier = Modifier.width(4.dp))\n            Text(text = \"Yes\")\n          }\n          Spacer(modifier = Modifier.width(8.dp))\n          Button(onClick = {}) {\n            Icon(Icons.Filled.Edit, \"Edit item\")\n            Spacer(modifier = Modifier.width(4.dp))\n            Text(text = \"Edit\")\n          }\n        }\n      }\n    }\n  }\n}\n\n@Composable\nfun Int.decidePointAnimation(): EventPointAnimation? =\n  if (this == 3) JetLimeEventDefaults.pointAnimation() else null\n\nfun placeImages(i: Int) = if (i == 1) {\n  persistentListOf(\n    Res.drawable.image_1,\n    Res.drawable.image_2,\n  )\n} else {\n  persistentListOf()\n}\n\nfun placeInfo(i: Int) = \"Address ${i + 1}, City, Country\"\n\nfun placeDescription(i: Int) = \"Visited at ${10 + i % 12}:${\n  if (i % 2 == 0) {\n    \"00\"\n  } else {\n    \"30\"\n  }\n} AM\"\n\nfun activityInfo(i: Int) = \"${1 + i / 2} mi . ${15 + i * 2} min\"\n\nfun activityDescription(i: Int) = \"${1 + i % 12}:${if (i % 2 == 0) \"00\" else \"30\"} PM - \" +\n  \"${1 + (i + 1) % 12}:${if ((i + 1) % 2 == 0) \"00\" else \"30\"} PM\"\n\n@Composable\nfun Int.decidePointType(): EventPointType = when (this) {\n  1 -> EventPointType.filled(\n    0.8f,\n  )\n\n  2, 3 -> EventPointType.custom(\n    icon = painterResource(Res.drawable.icon_check),\n  )\n\n  4 -> EventPointType.filled(\n    0.4f,\n  )\n\n  5 -> EventPointType.Default\n\n  else -> EventPointType.Default\n}\n"
  },
  {
    "path": "sample/composeApp/src/desktopMain/kotlin/Main.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\nimport androidx.compose.ui.window.Window\nimport androidx.compose.ui.window.application\n\nfun main() = application {\n  Window(\n    onCloseRequest = ::exitApplication,\n    title = \"JetLime Samples\",\n  ) {\n    App()\n  }\n}\n"
  },
  {
    "path": "sample/composeApp/src/iosMain/kotlin/MainViewController.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\nimport androidx.compose.ui.window.ComposeUIViewController\n\nfun mainViewController() = ComposeUIViewController { App() }\n"
  },
  {
    "path": "sample/composeApp/src/jsMain/kotlin/Main.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\nimport androidx.compose.ui.ExperimentalComposeUiApi\nimport androidx.compose.ui.window.ComposeViewport\nimport kotlinx.browser.document\nimport org.jetbrains.skiko.wasm.onWasmReady\n\n@OptIn(ExperimentalComposeUiApi::class)\nfun main() {\n  onWasmReady {\n    val root = document.getElementById(\"root\") ?: error(\"Missing #root container\")\n    ComposeViewport(root) {\n      App()\n    }\n  }\n}\n"
  },
  {
    "path": "sample/composeApp/src/jsMain/resources/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n  <meta charset=\"UTF-8\"/>\n  <title>JetLime Sample</title>\n  <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"/>\n  <link rel=\"stylesheet\" href=\"styles.css\"/>\n</head>\n<body>\n<div id=\"root\"></div>\n<script type=\"application/javascript\" src=\"skiko.js\"></script>\n<script type=\"application/javascript\" src=\"composeApp.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "sample/composeApp/src/jsMain/resources/styles.css",
    "content": "html, body, #root {\nwidth: 100%;\nheight: 100%;\nmargin: 0;\npadding: 0;\n}\n#root {\n/* Ensures children using fillMaxSize() can expand */\nmin-height: 100vh;\ndisplay: flex;\n}\ncanvas {\n/* If a canvas is still used internally, force it to fill */\nwidth: 100% !important;\nheight: 100% !important;\n}"
  },
  {
    "path": "sample/composeApp/src/wasmJsMain/kotlin/Main.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/\nimport androidx.compose.ui.ExperimentalComposeUiApi\nimport androidx.compose.ui.window.ComposeViewport\nimport kotlinx.browser.document\n\n@OptIn(ExperimentalComposeUiApi::class)\nfun main() {\n  ComposeViewport(document.body!!) {\n    App()\n  }\n}\n"
  },
  {
    "path": "sample/composeApp/src/wasmJsMain/resources/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>JetLime Samples</title>\n    <link type=\"text/css\" rel=\"stylesheet\" href=\"styles.css\">\n    <script type=\"application/javascript\" src=\"composeApp.js\"></script>\n</head>\n<body>\n</body>\n</html>"
  },
  {
    "path": "sample/composeApp/src/wasmJsMain/resources/styles.css",
    "content": "html, body {\n    width: 100%;\n    height: 100%;\n    margin: 0;\n    padding: 0;\n    overflow: hidden;\n}"
  },
  {
    "path": "sample/iosApp/Configuration/Config.xcconfig",
    "content": "TEAM_ID=\nBUNDLE_ID=com.pushpal.jetlime.sample\nAPP_NAME=JetLime Samples\n"
  },
  {
    "path": "sample/iosApp/Podfile",
    "content": "# Uncomment the next line to define a global platform for your project\n# platform :ios, '9.0'\n\ntarget 'iosApp' do\n  # Comment the next line if you don't want to use dynamic frameworks\n  use_frameworks!\n\n  # Pods for iosApp\n\nend\n"
  },
  {
    "path": "sample/iosApp/Pods/Pods.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 56;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t4A616F3470D7B33397D58685086EC6E5 /* Pods-iosApp-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3A2475209BEE7612101900020629C625 /* Pods-iosApp-dummy.m */; };\n\t\tDA8E4A3F5946393DB1D4E098D51FD304 /* Pods-iosApp-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 42DE4C0106600A5B6D599285368F3270 /* Pods-iosApp-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; };\n\t\tFA95DAC84949941C95CBBB985FCBF6FD /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 384DDA2CB25005BD6479B5987C619DD4 /* Foundation.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t0011AEE22E8296B3D9E0B0B2CDCAB2EE /* Pods-iosApp-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"Pods-iosApp-acknowledgements.plist\"; sourceTree = \"<group>\"; };\n\t\t1A2FB55B5C37861BC78ECD1420D818C3 /* Pods-iosApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = \"Pods-iosApp.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t384DDA2CB25005BD6479B5987C619DD4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };\n\t\t3A2475209BEE7612101900020629C625 /* Pods-iosApp-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = \"Pods-iosApp-dummy.m\"; sourceTree = \"<group>\"; };\n\t\t42DE4C0106600A5B6D599285368F3270 /* Pods-iosApp-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = \"Pods-iosApp-umbrella.h\"; sourceTree = \"<group>\"; };\n\t\t482384ADFE4EF692B16FACB8C2021970 /* Pods-iosApp.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = \"Pods-iosApp.modulemap\"; sourceTree = \"<group>\"; };\n\t\t9D940727FF8FB9C785EB98E56350EF41 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };\n\t\tA43877303056397968EC90C7AAFE17E8 /* Pods-iosApp-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = \"Pods-iosApp-acknowledgements.markdown\"; sourceTree = \"<group>\"; };\n\t\tA79C2AA5C063914B2D1BD80187FDF6DE /* Pods-iosApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = \"Pods-iosApp.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tB097DD7534E741D5C41838011D755842 /* Pods-iosApp */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = \"Pods-iosApp\"; path = Pods_iosApp.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tBCAED803D074E2E9C3B1327F049C8C2A /* Pods-iosApp-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = \"Pods-iosApp-Info.plist\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t220636D6C490503310AF748ECEB4B93F /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tFA95DAC84949941C95CBBB985FCBF6FD /* Foundation.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t1F86AA6785DF34AFD5A71790761717DE /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tB097DD7534E741D5C41838011D755842 /* Pods-iosApp */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t310087C345B86EEF25A054485E0BB5CB /* Pods-iosApp */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t482384ADFE4EF692B16FACB8C2021970 /* Pods-iosApp.modulemap */,\n\t\t\t\tA43877303056397968EC90C7AAFE17E8 /* Pods-iosApp-acknowledgements.markdown */,\n\t\t\t\t0011AEE22E8296B3D9E0B0B2CDCAB2EE /* Pods-iosApp-acknowledgements.plist */,\n\t\t\t\t3A2475209BEE7612101900020629C625 /* Pods-iosApp-dummy.m */,\n\t\t\t\tBCAED803D074E2E9C3B1327F049C8C2A /* Pods-iosApp-Info.plist */,\n\t\t\t\t42DE4C0106600A5B6D599285368F3270 /* Pods-iosApp-umbrella.h */,\n\t\t\t\tA79C2AA5C063914B2D1BD80187FDF6DE /* Pods-iosApp.debug.xcconfig */,\n\t\t\t\t1A2FB55B5C37861BC78ECD1420D818C3 /* Pods-iosApp.release.xcconfig */,\n\t\t\t);\n\t\t\tname = \"Pods-iosApp\";\n\t\t\tpath = \"Target Support Files/Pods-iosApp\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tC9F6DDEE5D76F65BB478A349731F54F4 /* Targets Support Files */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t310087C345B86EEF25A054485E0BB5CB /* Pods-iosApp */,\n\t\t\t);\n\t\t\tname = \"Targets Support Files\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tCF1408CF629C7361332E53B88F7BD30C = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t9D940727FF8FB9C785EB98E56350EF41 /* Podfile */,\n\t\t\t\tD210D550F4EA176C3123ED886F8F87F5 /* Frameworks */,\n\t\t\t\t1F86AA6785DF34AFD5A71790761717DE /* Products */,\n\t\t\t\tC9F6DDEE5D76F65BB478A349731F54F4 /* Targets Support Files */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tD210D550F4EA176C3123ED886F8F87F5 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tE4801F62A6B08CD9B5410329F1A18FDE /* iOS */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tE4801F62A6B08CD9B5410329F1A18FDE /* iOS */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t384DDA2CB25005BD6479B5987C619DD4 /* Foundation.framework */,\n\t\t\t);\n\t\t\tname = iOS;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXHeadersBuildPhase section */\n\t\tBD4FAC4583DE690DD87D9C439830F388 /* Headers */ = {\n\t\t\tisa = PBXHeadersBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tDA8E4A3F5946393DB1D4E098D51FD304 /* Pods-iosApp-umbrella.h in Headers */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXHeadersBuildPhase section */\n\n/* Begin PBXNativeTarget section */\n\t\tED39C638569286489CD697A6C8964146 /* Pods-iosApp */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 9E3255597A60D1C57891D0F10A4DA27F /* Build configuration list for PBXNativeTarget \"Pods-iosApp\" */;\n\t\t\tbuildPhases = (\n\t\t\t\tBD4FAC4583DE690DD87D9C439830F388 /* Headers */,\n\t\t\t\t8A03D6FF47351D94021D1FD831B77FCE /* Sources */,\n\t\t\t\t220636D6C490503310AF748ECEB4B93F /* Frameworks */,\n\t\t\t\t45C341735E088ED0DA853C0538F8B794 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"Pods-iosApp\";\n\t\t\tproductName = Pods_iosApp;\n\t\t\tproductReference = B097DD7534E741D5C41838011D755842 /* Pods-iosApp */;\n\t\t\tproductType = \"com.apple.product-type.framework\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\tBFDFE7DC352907FC980B868725387E98 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tLastSwiftUpdateCheck = 1600;\n\t\t\t\tLastUpgradeCheck = 1600;\n\t\t\t};\n\t\t\tbuildConfigurationList = 4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject \"Pods\" */;\n\t\t\tcompatibilityVersion = \"Xcode 14.0\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\tBase,\n\t\t\t\ten,\n\t\t\t);\n\t\t\tmainGroup = CF1408CF629C7361332E53B88F7BD30C;\n\t\t\tminimizedProjectReferenceProxies = 0;\n\t\t\tpreferredProjectObjectVersion = 77;\n\t\t\tproductRefGroup = 1F86AA6785DF34AFD5A71790761717DE /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\tED39C638569286489CD697A6C8964146 /* Pods-iosApp */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t45C341735E088ED0DA853C0538F8B794 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t8A03D6FF47351D94021D1FD831B77FCE /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t4A616F3470D7B33397D58685086EC6E5 /* Pods-iosApp-dummy.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\t31B82BCEB37CFE5029A7E40217311E0F /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 1A2FB55B5C37861BC78ECD1420D818C3 /* Pods-iosApp.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = NO;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tENABLE_MODULE_VERIFIER = NO;\n\t\t\t\tENABLE_USER_SCRIPT_SANDBOXING = NO;\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/Pods-iosApp/Pods-iosApp-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.3;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACH_O_TYPE = staticlib;\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/Pods-iosApp/Pods-iosApp.modulemap\";\n\t\t\t\tOTHER_LDFLAGS = \"\";\n\t\t\t\tOTHER_LIBTOOLFLAGS = \"\";\n\t\t\t\tPODS_ROOT = \"$(SRCROOT)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME:c99extidentifier)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tA6046EC2625847907E13D89E5C077134 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"POD_CONFIGURATION_RELEASE=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.3;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSTRIP_INSTALLED_PRODUCT = NO;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tSYMROOT = \"${SRCROOT}/../build\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tE5F5378EB2C0097CB36731205FD2E7C8 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = A79C2AA5C063914B2D1BD80187FDF6DE /* Pods-iosApp.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = NO;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=appletvos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=watchos*]\" = \"\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEFINES_MODULE = YES;\n\t\t\t\tDYLIB_COMPATIBILITY_VERSION = 1;\n\t\t\t\tDYLIB_CURRENT_VERSION = 1;\n\t\t\t\tDYLIB_INSTALL_NAME_BASE = \"@rpath\";\n\t\t\t\tENABLE_MODULE_VERIFIER = NO;\n\t\t\t\tENABLE_USER_SCRIPT_SANDBOXING = NO;\n\t\t\t\tINFOPLIST_FILE = \"Target Support Files/Pods-iosApp/Pods-iosApp-Info.plist\";\n\t\t\t\tINSTALL_PATH = \"$(LOCAL_LIBRARY_DIR)/Frameworks\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.3;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t\t\"@loader_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACH_O_TYPE = staticlib;\n\t\t\t\tMODULEMAP_FILE = \"Target Support Files/Pods-iosApp/Pods-iosApp.modulemap\";\n\t\t\t\tOTHER_LDFLAGS = \"\";\n\t\t\t\tOTHER_LIBTOOLFLAGS = \"\";\n\t\t\t\tPODS_ROOT = \"$(SRCROOT)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.cocoapods.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME:c99extidentifier)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t\tVERSION_INFO_PREFIX = \"\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tF105DEC13C0AF4AD6927D5D40AF85A30 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"POD_CONFIGURATION_DEBUG=1\",\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.3;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSTRIP_INSTALLED_PRODUCT = NO;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tSYMROOT = \"${SRCROOT}/../build\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t4821239608C13582E20E6DA73FD5F1F9 /* Build configuration list for PBXProject \"Pods\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tF105DEC13C0AF4AD6927D5D40AF85A30 /* Debug */,\n\t\t\t\tA6046EC2625847907E13D89E5C077134 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t9E3255597A60D1C57891D0F10A4DA27F /* Build configuration list for PBXNativeTarget \"Pods-iosApp\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tE5F5378EB2C0097CB36731205FD2E7C8 /* Debug */,\n\t\t\t\t31B82BCEB37CFE5029A7E40217311E0F /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = BFDFE7DC352907FC980B868725387E98 /* Project object */;\n}\n"
  },
  {
    "path": "sample/iosApp/Pods/Pods.xcodeproj/xcuserdata/pushpalroy.xcuserdatad/xcschemes/Pods-iosApp.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1600\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"ED39C638569286489CD697A6C8964146\"\n               BuildableName = \"Pods_iosApp.framework\"\n               BlueprintName = \"Pods-iosApp\"\n               ReferencedContainer = \"container:Pods.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "sample/iosApp/Pods/Pods.xcodeproj/xcuserdata/pushpalroy.xcuserdatad/xcschemes/xcschememanagement.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>SchemeUserState</key>\n\t<dict>\n\t\t<key>Pods-iosApp.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>isShown</key>\n\t\t\t<false />\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>1</integer>\n\t\t</dict>\n\t</dict>\n\t<key>SuppressBuildableAutocreation</key>\n\t<dict />\n</dict>\n</plist>\n"
  },
  {
    "path": "sample/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp-Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n  <key>CFBundleDevelopmentRegion</key>\n  <string>${PODS_DEVELOPMENT_LANGUAGE}</string>\n  <key>CFBundleExecutable</key>\n  <string>${EXECUTABLE_NAME}</string>\n  <key>CFBundleIdentifier</key>\n  <string>${PRODUCT_BUNDLE_IDENTIFIER}</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>${PRODUCT_NAME}</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>1.0.0</string>\n  <key>CFBundleSignature</key>\n  <string>????</string>\n  <key>CFBundleVersion</key>\n  <string>${CURRENT_PROJECT_VERSION}</string>\n  <key>NSPrincipalClass</key>\n  <string></string>\n</dict>\n</plist>\n"
  },
  {
    "path": "sample/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp-acknowledgements.markdown",
    "content": "# Acknowledgements\nThis application makes use of the following third party libraries:\nGenerated by CocoaPods - https://cocoapods.org\n"
  },
  {
    "path": "sample/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp-acknowledgements.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>PreferenceSpecifiers</key>\n\t<array>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>This application makes use of the following third party libraries:</string>\n\t\t\t<key>Title</key>\n\t\t\t<string>Acknowledgements</string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t\t<dict>\n\t\t\t<key>FooterText</key>\n\t\t\t<string>Generated by CocoaPods - https://cocoapods.org</string>\n\t\t\t<key>Title</key>\n\t\t\t<string></string>\n\t\t\t<key>Type</key>\n\t\t\t<string>PSGroupSpecifier</string>\n\t\t</dict>\n\t</array>\n\t<key>StringsTable</key>\n\t<string>Acknowledgements</string>\n\t<key>Title</key>\n\t<string>Acknowledgements</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "sample/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp-dummy.m",
    "content": "#import <Foundation/Foundation.h>\n@interface PodsDummy_Pods_iosApp : NSObject\n@end\n@implementation PodsDummy_Pods_iosApp\n@end\n"
  },
  {
    "path": "sample/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp-umbrella.h",
    "content": "#ifdef __OBJC__\n#import <UIKit/UIKit.h>\n#else\n#ifndef FOUNDATION_EXPORT\n#if defined(__cplusplus)\n#define FOUNDATION_EXPORT extern \"C\"\n#else\n#define FOUNDATION_EXPORT extern\n#endif\n#endif\n#endif\n\n\nFOUNDATION_EXPORT double Pods_iosAppVersionNumber;\nFOUNDATION_EXPORT const unsigned char Pods_iosAppVersionString[];\n\n"
  },
  {
    "path": "sample/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp.debug.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_PODFILE_DIR_PATH = ${SRCROOT}/.\nPODS_ROOT = ${SRCROOT}/Pods\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "sample/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp.modulemap",
    "content": "framework module Pods_iosApp {\n  umbrella header \"Pods-iosApp-umbrella.h\"\n\n  export *\n  module * { export * }\n}\n"
  },
  {
    "path": "sample/iosApp/Pods/Target Support Files/Pods-iosApp/Pods-iosApp.release.xcconfig",
    "content": "CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO\nGCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1\nPODS_BUILD_DIR = ${BUILD_DIR}\nPODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)\nPODS_PODFILE_DIR_PATH = ${SRCROOT}/.\nPODS_ROOT = ${SRCROOT}/Pods\nPODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates\nUSE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES\n"
  },
  {
    "path": "sample/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json",
    "content": "{\n  \"colors\" : [\n    {\n      \"idiom\" : \"universal\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}"
  },
  {
    "path": "sample/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"filename\" : \"app-icon-1024.png\",\n      \"idiom\" : \"universal\",\n      \"platform\" : \"ios\",\n      \"size\" : \"1024x1024\"\n    }\n  ],\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "sample/iosApp/iosApp/Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}"
  },
  {
    "path": "sample/iosApp/iosApp/ContentView.swift",
    "content": "import UIKit\nimport SwiftUI\nimport ComposeApp\n\nstruct ComposeView: UIViewControllerRepresentable {\n    func makeUIViewController(context: Context) -> UIViewController {\n        MainViewControllerKt.mainViewController()\n    }\n\n    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {}\n}\n\nstruct ContentView: View {\n    var body: some View {\n        ComposeView().ignoresSafeArea()\n    }\n}\n\n\n\n"
  },
  {
    "path": "sample/iosApp/iosApp/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>$(DEVELOPMENT_LANGUAGE)</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>CADisableMinimumFrameDurationOnPhone</key>\n\t<true/>\n\t<key>UIApplicationSceneManifest</key>\n\t<dict>\n\t\t<key>UIApplicationSupportsMultipleScenes</key>\n\t\t<false/>\n\t</dict>\n\t<key>UILaunchScreen</key>\n\t<dict/>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "sample/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}"
  },
  {
    "path": "sample/iosApp/iosApp/iOSApp.swift",
    "content": "import SwiftUI\n\n@main\nstruct iOSApp: App {\n\tvar body: some Scene {\n\t\tWindowGroup {\n\t\t\tContentView()\n\t\t}\n\t}\n}"
  },
  {
    "path": "sample/iosApp/iosApp.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 56;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; };\n\t\t058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; };\n\t\t2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; };\n\t\t7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; };\n\t\t7F833A27FEA826D7F25D7D8B /* Pods_iosApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC9DD1024C7C92432FE44E34 /* Pods_iosApp.framework */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXFileReference section */\n\t\t058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = \"<group>\"; };\n\t\t058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = \"Preview Assets.xcassets\"; sourceTree = \"<group>\"; };\n\t\t2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = \"<group>\"; };\n\t\t6E17A001C25F4C48AE67729D /* Pods-iosApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-iosApp.release.xcconfig\"; path = \"Target Support Files/Pods-iosApp/Pods-iosApp.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t7555FF7B242A565900829871 /* JetLime Samples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = \"JetLime Samples.app\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = \"<group>\"; };\n\t\t7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\tAB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = \"<group>\"; };\n\t\tCC9DD1024C7C92432FE44E34 /* Pods_iosApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_iosApp.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tD584059B8EC700A90BC2EBD2 /* Pods-iosApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-iosApp.debug.xcconfig\"; path = \"Target Support Files/Pods-iosApp/Pods-iosApp.debug.xcconfig\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\tB92378962B6B1156000C7307 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t7F833A27FEA826D7F25D7D8B /* Pods_iosApp.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t058557D7273AAEEB004C7B11 /* Preview Content */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */,\n\t\t\t);\n\t\t\tpath = \"Preview Content\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t42799AB246E5F90AF97AA0EF /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tCC9DD1024C7C92432FE44E34 /* Pods_iosApp.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t7555FF72242A565900829871 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tAB1DB47929225F7C00F7AF9C /* Configuration */,\n\t\t\t\t7555FF7D242A565900829871 /* iosApp */,\n\t\t\t\t7555FF7C242A565900829871 /* Products */,\n\t\t\t\t42799AB246E5F90AF97AA0EF /* Frameworks */,\n\t\t\t\t7ED8F2734BD6F763F95E6CEB /* Pods */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t7555FF7C242A565900829871 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t7555FF7B242A565900829871 /* JetLime Samples.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t7555FF7D242A565900829871 /* iosApp */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t058557BA273AAA24004C7B11 /* Assets.xcassets */,\n\t\t\t\t7555FF82242A565900829871 /* ContentView.swift */,\n\t\t\t\t7555FF8C242A565B00829871 /* Info.plist */,\n\t\t\t\t2152FB032600AC8F00CF470E /* iOSApp.swift */,\n\t\t\t\t058557D7273AAEEB004C7B11 /* Preview Content */,\n\t\t\t);\n\t\t\tpath = iosApp;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t7ED8F2734BD6F763F95E6CEB /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tD584059B8EC700A90BC2EBD2 /* Pods-iosApp.debug.xcconfig */,\n\t\t\t\t6E17A001C25F4C48AE67729D /* Pods-iosApp.release.xcconfig */,\n\t\t\t);\n\t\t\tname = Pods;\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tAB1DB47929225F7C00F7AF9C /* Configuration */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tAB3632DC29227652001CCB65 /* Config.xcconfig */,\n\t\t\t);\n\t\t\tpath = Configuration;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t7555FF7A242A565900829871 /* iosApp */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget \"iosApp\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t8621F011E21D022A0E058E9C /* [CP] Check Pods Manifest.lock */,\n\t\t\t\tF36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */,\n\t\t\t\t7555FF77242A565900829871 /* Sources */,\n\t\t\t\tB92378962B6B1156000C7307 /* Frameworks */,\n\t\t\t\t7555FF79242A565900829871 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = iosApp;\n\t\t\tproductName = iosApp;\n\t\t\tproductReference = 7555FF7B242A565900829871 /* JetLime Samples.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t7555FF73242A565900829871 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tBuildIndependentTargetsInParallel = YES;\n\t\t\t\tLastSwiftUpdateCheck = 1130;\n\t\t\t\tLastUpgradeCheck = 1540;\n\t\t\t\tORGANIZATIONNAME = orgName;\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t7555FF7A242A565900829871 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 11.3.1;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject \"iosApp\" */;\n\t\t\tcompatibilityVersion = \"Xcode 14.0\";\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 7555FF72242A565900829871;\n\t\t\tproductRefGroup = 7555FF7C242A565900829871 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t7555FF7A242A565900829871 /* iosApp */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t7555FF79242A565900829871 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */,\n\t\t\t\t058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t8621F011E21D022A0E058E9C /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-iosApp-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tF36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"Compile Kotlin Framework\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"if [ \\\"YES\\\" = \\\"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\\\" ]; then\\n  echo \\\"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\\\\\"YES\\\\\\\"\\\"\\n  exit 0\\nfi\\ncd \\\"$SRCROOT/../..\\\"\\n./gradlew :sample:composeApp:embedAndSignAppleFrameworkForXcode\\n\";\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t7555FF77242A565900829871 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */,\n\t\t\t\t7555FF83242A565900829871 /* ContentView.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin XCBuildConfiguration section */\n\t\t7555FFA3242A565B00829871 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tENABLE_USER_SCRIPT_SANDBOXING = NO;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.3;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t7555FFA4242A565B00829871 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++14\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_USER_SCRIPT_SANDBOXING = NO;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.3;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t7555FFA6242A565B00829871 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = D584059B8EC700A90BC2EBD2 /* Pods-iosApp.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_IDENTITY = \"Apple Development\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tDEVELOPMENT_ASSET_PATHS = \"\\\"iosApp/Preview Content\\\"\";\n\t\t\t\tDEVELOPMENT_TEAM = \"${TEAM_ID}\";\n\t\t\t\tENABLE_PREVIEWS = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = iosApp/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.3;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"-framework\",\n\t\t\t\t\tComposeApp,\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"${BUNDLE_ID}${TEAM_ID}\";\n\t\t\t\tPRODUCT_NAME = \"${APP_NAME}\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t7555FFA7242A565B00829871 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 6E17A001C25F4C48AE67729D /* Pods-iosApp.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCODE_SIGN_IDENTITY = \"Apple Development\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tDEVELOPMENT_ASSET_PATHS = \"\\\"iosApp/Preview Content\\\"\";\n\t\t\t\tDEVELOPMENT_TEAM = \"${TEAM_ID}\";\n\t\t\t\tENABLE_PREVIEWS = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = iosApp/Info.plist;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.3;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tOTHER_LDFLAGS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"-framework\",\n\t\t\t\t\tComposeApp,\n\t\t\t\t);\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"${BUNDLE_ID}${TEAM_ID}\";\n\t\t\t\tPRODUCT_NAME = \"${APP_NAME}\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSWIFT_VERSION = 5.0;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t7555FF76242A565900829871 /* Build configuration list for PBXProject \"iosApp\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t7555FFA3242A565B00829871 /* Debug */,\n\t\t\t\t7555FFA4242A565B00829871 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget \"iosApp\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t7555FFA6242A565B00829871 /* Debug */,\n\t\t\t\t7555FFA7242A565B00829871 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 7555FF73242A565900829871 /* Project object */;\n}\n"
  },
  {
    "path": "sample/iosApp/iosApp.xcodeproj/xcuserdata/pushpalroy.xcuserdatad/xcschemes/iosApp.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   version = \"1.7\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"7555FF7A242A565900829871\"\n               BuildableName = \"JetLime Samples.app\"\n               BlueprintName = \"iosApp\"\n               ReferencedContainer = \"container:iosApp.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      shouldAutocreateTestPlan = \"YES\">\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"7555FF7A242A565900829871\"\n            BuildableName = \"JetLime Samples.app\"\n            BlueprintName = \"iosApp\"\n            ReferencedContainer = \"container:iosApp.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n      <LocationScenarioReference\n         identifier = \"com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier\"\n         referenceType = \"1\">\n      </LocationScenarioReference>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "sample/iosApp/iosApp.xcodeproj/xcuserdata/pushpalroy.xcuserdatad/xcschemes/xcschememanagement.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>SchemeUserState</key>\n\t<dict>\n\t\t<key>iosApp.xcscheme</key>\n\t\t<dict>\n\t\t\t<key>orderHint</key>\n\t\t\t<integer>0</integer>\n\t\t</dict>\n\t</dict>\n</dict>\n</plist>\n"
  },
  {
    "path": "sample/iosApp/iosApp.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:iosApp.xcodeproj\">\n   </FileRef>\n   <FileRef\n      location = \"group:Pods/Pods.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "sample/iosApp/iosApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "sample/iosApp/iosApp.xcworkspace/xcuserdata/pushpalroy.xcuserdatad/xcschemes/xcschememanagement.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict />\n</plist>\n"
  },
  {
    "path": "scripts/add_git_tag.sh",
    "content": "#!/bin/bash\n\n# Script to add annotated tag with version number to the main branch\n# This script should be executed with the correct version number after every release to MavenCentral\nTAG=\"4.3.0\"\nCOMMENT=\"Release $TAG\"\nBRANCH=\"main\"\n\n# Fetch the latest changes in the repository\ngit fetch\n\n# Check if the main branch exists and switch to it\nif git rev-parse --verify $BRANCH; then\n    git checkout $BRANCH\n    git pull origin $BRANCH\nelse\n    echo \"Branch '$BRANCH' does not exist.\"\n    exit 1\nfi\n\n# Add the annotated tag\ngit tag -a $TAG -m \"$COMMENT\"\n\n# Push the tag to remote repository\ngit push origin $TAG"
  },
  {
    "path": "scripts/build_android.sh",
    "content": "#!/bin/bash\n\n# Exit the script on any error\nset -e\n\n# Navigate to the root directory of the project\ncd \"$(dirname \"$0\")/..\" || exit\n\n# Create distributions folder in the root directory (if not already present)\nmkdir -p distributions/android\n\n# Build Android App\necho \"Building Android App 📱\"\n./gradlew :sample:composeApp:assembleDebug --console=plain --stacktrace\n\n# Check if the build was successful\nif [ $? -eq 0 ]; then\n    echo \"Android build successful.\"\n\n    # Verify and copy the APK to the distributions folder\n    APK_PATH=\"sample/composeApp/build/outputs/apk/debug/composeApp-debug.apk\"\n\n    if [ -f \"$APK_PATH\" ]; then\n        cp \"$APK_PATH\" distributions/android/jetlime-sample-android.apk\n        echo \"Android APK copied to distributions/android/jetlime-sample-android.apk\"\n    else\n        echo \"APK not found at expected path: $APK_PATH\"\n        exit 1\n    fi\nelse\n    echo \"Android build failed.\"\n    exit 1\nfi"
  },
  {
    "path": "scripts/build_ios.sh",
    "content": "#!/bin/bash\n\n# Navigate to the root directory of the project\ncd \"$(dirname \"$0\")/..\" || exit\n\n# Build iOS app using xcodebuild\nxcodebuild build \\\n  -workspace sample/iosApp/iosApp.xcworkspace \\\n  -configuration Debug \\\n  -scheme iosApp \\\n  -sdk iphonesimulator \\\n  -verbose\n\n# Check if the build was successful\nif [ $? -eq 0 ]; then\n    echo \"iOS build successful.\"\n\n    # Create distributions directory if it doesn't exist\n    mkdir -p distributions/ios\n\n    # Copy the generated iOS build products to the distributions/ directory\n    BUILD_DIR=$(xcodebuild -workspace sample/iosApp/iosApp.xcworkspace \\\n                -scheme iosApp -configuration Debug -sdk iphonesimulator -showBuildSettings | grep -m1 \" BUILT_PRODUCTS_DIR\" | awk '{print $3}')\n\n    if [ -d \"$BUILD_DIR\" ]; then\n        cp -R \"$BUILD_DIR\"/* distributions/ios/\n        echo \"iOS build copied to distributions/ios/ directory.\"\n    else\n        echo \"Build directory not found!\"\n        exit 1\n    fi\nelse\n    echo \"iOS build failed.\"\n    exit 1\nfi\n"
  },
  {
    "path": "scripts/build_macos.sh",
    "content": "#!/bin/bash\n\n# Exit the script on any error\nset -e\n\n# Navigate to the root directory of the project\ncd \"$(dirname \"$0\")/..\" || exit\n\n# Create distributions folder in the root directory (if not already present)\nmkdir -p distributions/macos\n\n# Build Mac Desktop App\necho \"Building Mac Desktop App 🖥️\"\n./gradlew :sample:composeApp:packageUberJarForCurrentOS --console=plain --stacktrace\n\n# Check if the build was successful\nif [ $? -eq 0 ]; then\n    echo \"Mac Desktop build successful.\"\n\n    # Verify and copy the JAR to the distributions folder\n    JAR_PATH=\"sample/composeApp/build/compose/jars/JetLime Samples-macos-arm64-1.0.0.jar\"\n\n    if [ -f \"$JAR_PATH\" ]; then\n        cp \"$JAR_PATH\" distributions/macos/jetlime-sample-macos-x64.jar\n        echo \"Mac Desktop app copied to distributions/macos/jetlime-sample-macos-x64.jar\"\n    else\n        echo \"JAR not found at expected path: $JAR_PATH\"\n        exit 1\n    fi\nelse\n    echo \"Mac Desktop build failed.\"\n    exit 1\nfi"
  },
  {
    "path": "scripts/build_web_js.sh",
    "content": "#!/bin/bash\n\n# Exit the script on any error\nset -e\n\n# Navigate to the root directory of the project\ncd \"$(dirname \"$0\")/..\" || exit\n\n# Build Web JS App\necho \"Building Web JS App 🌎\"\n./gradlew :sample:composeApp:jsBrowserDistribution --console=plain --stacktrace\n\n# Check if the build was successful\nif [ $? -eq 0 ]; then\n    echo \"Web JS build successful.\"\n\n    # Create the distributions/jetlime-web folder in the root directory\n    mkdir -p distributions/web-js\n\n    # Path to the production executable\n    WEB_EXECUTABLE_PATH=\"sample/composeApp/build/dist/js/productionExecutable/\"\n\n    # Verify and copy the production executable to the distributions folder\n    if [ -d \"$WEB_EXECUTABLE_PATH\" ]; then\n        cp -r \"$WEB_EXECUTABLE_PATH\" distributions/web-js/\n        echo \"Web JS app copied to distributions/web-js\"\n    else\n        echo \"Web JS build output not found at expected path: $WEB_EXECUTABLE_PATH\"\n        exit 1\n    fi\nelse\n    echo \"Web JS build failed.\"\n    exit 1\nfi"
  },
  {
    "path": "scripts/build_web_wasm.sh",
    "content": "#!/bin/bash\n\n# Exit the script on any error\nset -e\n\n# Navigate to the root directory of the project\ncd \"$(dirname \"$0\")/..\" || exit\n\n# Build Web WASM App\necho \"Building Web WASM App 🌎\"\n./gradlew :sample:composeApp:wasmJsBrowserDistribution --console=plain --stacktrace\n\n# Check if the build was successful\nif [ $? -eq 0 ]; then\n    echo \"Web WASM build successful.\"\n\n    # Create the distributions/jetlime-web folder in the root directory\n    mkdir -p distributions/web-wasm\n\n    # Path to the production executable\n    WEB_EXECUTABLE_PATH=\"sample/composeApp/build/dist/wasmJs/productionExecutable/\"\n\n    # Verify and copy the production executable to the distributions folder\n    if [ -d \"$WEB_EXECUTABLE_PATH\" ]; then\n        cp -r \"$WEB_EXECUTABLE_PATH\" distributions/web-wasm/\n        echo \"Web WASM app copied to distributions/web-wasm\"\n    else\n        echo \"Web WASM build output not found at expected path: $WEB_EXECUTABLE_PATH\"\n        exit 1\n    fi\nelse\n    echo \"Web WASM build failed.\"\n    exit 1\nfi"
  },
  {
    "path": "scripts/run_dokka.sh",
    "content": "#!/bin/bash\n\n# Navigate to the root directory of the project\ncd \"$(dirname \"$0\")/..\" || exit\n\necho \"Running Dokka V2 HTML generation + sync\"\n./gradlew :jetlime:syncDokkaToDocs --no-configuration-cache \"$@\" || {\n  echo \"Dokka generation failed. Run with --stacktrace for details.\" >&2\n  exit 1\n}\n"
  },
  {
    "path": "scripts/run_spotless.sh",
    "content": "#!/bin/bash\n\n# Navigate to the root directory of the project\ncd \"$(dirname \"$0\")/..\" || exit\n\necho \"Running spotless\"\n./gradlew clean spotlessApply\ngit add .\n"
  },
  {
    "path": "settings.gradle.kts",
    "content": "pluginManagement {\n  repositories {\n    gradlePluginPortal()\n    google()\n    mavenCentral()\n    maven(\"https://plugins.gradle.org/m2/\")\n  }\n}\ndependencyResolutionManagement {\n  repositories {\n    google()\n    mavenCentral()\n  }\n}\nrootProject.name = \"JetLime\"\ninclude(\":sample:composeApp\")\ninclude(\":jetlime\")\n"
  },
  {
    "path": "spotless/copyright.kt",
    "content": "/*\n* MIT License\n*\n* Copyright (c) 2024 Pushpal Roy\n*\n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n*\n* The above copyright notice and this permission notice shall be included in all\n* copies or substantial portions of the Software.\n*\n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n* SOFTWARE.\n*\n*/"
  }
]