{"version":3,"sources":["../src/index.ts","../src/core/controllers/CursorController.ts","../src/core/managers/EventManager.ts","../src/core/managers/ModuleManager.ts","../src/objects/StringMirrorObject.ts","../src/objects/StringObject.ts","../src/core/managers/DOMBatcher.ts","../src/models/IModuleLifecyclePermissions.ts","../src/core/StringModule.ts","../src/core/managers/ObjectManager.ts","../src/models/scroll/ScrollHTMLClass.ts","../src/core/controllers/ScrollController.ts","../src/core/controllers/StringScrollDefault.ts","../src/core/controllers/StringScrollDisable.ts","../src/core/controllers/StringScrollSmooth.ts","../src/core/managers/ScrollManager.ts","../src/states/CursorState.ts","../src/states/RenderState.ts","../src/states/ScrollState.ts","../src/states/SystemState.ts","../src/states/TimeState.ts","../src/states/ViewportState.ts","../src/core/StringData.ts","../src/tools/BoundingClientRectTool.ts","../src/tools/DOMAttributeTool.ts","../src/tools/RecordAttributeTool.ts","../src/tools/TransformNullifyTool.ts","../src/tools/RelativePositionTool.ts","../src/tools/LerpTool.ts","../src/tools/UnitParserTool.ts","../src/tools/AdaptiveLerpTool.ts","../src/tools/OriginParserTool.ts","../src/tools/ColorParserTool.ts","../src/tools/EasingFunctionTool.ts","../src/tools/MagneticPullTool.ts","../src/tools/LerpColorTool.ts","../src/tools/LerpVector2Tool.ts","../src/tools/TransformScaleParserTool.ts","../src/tools/SplitOptionsParserTool.ts","../src/tools/RuleParserTool.ts","../src/tools/ValidationTool.ts","../src/utils/style-txn.ts","../src/core/StringToolsContainer.ts","../src/utils/isCoarsePointer.ts","../src/modules/cursor/StringCursor.ts","../src/modules/cursor/StringImpulse.ts","../src/utils/frame-dom.ts","../src/modules/layout/StringMasonry.ts","../src/modules/cursor/StringMagnetic.ts","../src/modules/cursor/CursorReactiveModule.ts","../src/modules/cursor/StringSpotlight.ts","../src/modules/loading/StringLazy.ts","../src/modules/loading/StringLoading.ts","../src/modules/screen/StringInview.ts","../src/modules/screen/StringResponsive.ts","../src/modules/scroll/StringAnchor.ts","../src/modules/scroll/StringGlide.ts","../src/modules/scroll/StringLerp.ts","../src/modules/scroll/StringProgress.ts","../src/modules/scroll/StringParallax.ts","../src/modules/scrollbar/StringScrollbarHorizontal.ts","../src/modules/scrollbar/StringScrollbarVertical.ts","../src/modules/scrollbar/StringScrollbar.ts","../src/models/text/SplitElementClass.ts","../src/utils/text/BuildDOMTree.ts","../src/utils/text/BuildTokens.ts","../src/utils/text/CanvasKerningApplier.ts","../src/utils/text/layout-measure/FlexMeasureAdapter.ts","../src/utils/text/layout-measure/InlineFlowMeasureAdapter.ts","../src/utils/text/layout-measure/LayoutMeasureRouter.ts","../src/utils/text/layout-measure/measureTokens.ts","../src/utils/text/LayoutMeasurer.ts","../src/utils/text/SplitMeasuredTokens.ts","../src/modules/text/StringSplit.ts","../src/modules/tracker/StringDelayLerpTracker.ts","../src/modules/tracker/StringFPSTracker.ts","../src/modules/tracker/StringLerpTracker.ts","../src/modules/tracker/StringPositionTracker.ts","../src/utils/Debounce.ts","../src/utils/StringFPS.ts","../src/modules/loading/StringVideoAutoplay.ts","../src/models/slider/SequenceState.ts","../src/modules/slider/StringSequence.ts","../src/modules/input/StringForm.ts","../src/core/managers/CenterCache.ts","../src/core/managers/HoverTracker.ts","../src/modules/dev-tools/core/StringDevtoolsIcons.ts","../src/modules/dev-tools/core/StringDevIconRegistry.ts","../src/modules/dev-tools/core/StringDevElements.ts","../src/modules/dev-tools/core/StringDevCoreStyles.css.ts","../src/modules/dev-tools/core/StringDevStyleSystem.ts","../src/modules/dev-tools/core/StringDevViewportPolicy.ts","../src/modules/dev-tools/core/StringDevStorageScope.ts","../src/modules/dev-tools/core/StringDevtoolsDock.ts","../src/core/managers/DevtoolsManager.ts","../src/modules/scroll/StringScroller.ts","../src/modules/scroll/StringScrollContainer.ts","../src/utils/ParsePartOf.ts","../src/modules/scroll/StringProgressPart.ts","../src/modules/random/StringRandom.ts","../src/modules/dev-tools/core/StringDevViewportLayer.ts","../src/modules/dev-tools/core/StringDevOverlayRegistry.ts","../src/modules/dev-tools/core/StringDevModule.ts","../src/modules/dev-tools/layout/models/GridInstance.ts","../src/modules/dev-tools/layout/GridManager.ts","../src/modules/dev-tools/layout/GridOverlay.ts","../src/modules/dev-tools/core/ui/fields/StringDevUIField.ts","../src/modules/dev-tools/core/ui/fields/StringDevFieldNumber.ts","../src/modules/dev-tools/core/ui/fields/StringDevFieldRange.ts","../src/modules/dev-tools/core/ui/fields/StringDevFieldColor.ts","../src/modules/dev-tools/core/ui/fields/StringDevFieldSelect.ts","../src/modules/dev-tools/core/ui/fields/StringDevFieldToggle.ts","../src/modules/dev-tools/core/ui/StringDevUIBuilder.ts","../src/modules/dev-tools/layout/GridHUD.ts","../src/modules/dev-tools/layout/GridSerializer.ts","../src/modules/dev-tools/layout/adapters/GridAdapter.ts","../src/modules/dev-tools/layout/adapters/ColumnsAdapter.ts","../src/modules/dev-tools/layout/adapters/RowsAdapter.ts","../src/modules/dev-tools/layout/adapters/CenterAdapter.ts","../src/modules/dev-tools/layout/adapters/RuleOfThirdsAdapter.ts","../src/modules/dev-tools/layout/adapters/GoldenRectangleAdapter.ts","../src/modules/dev-tools/layout/adapters/DotGridAdapter.ts","../src/modules/dev-tools/core/StringDevtoolsOverlayLayout.ts","../src/modules/dev-tools/layout/StringGrid.css.ts","../src/modules/dev-tools/layout/StringGrid.ts","../src/modules/dev-tools/rulers/StringRulers.css.ts","../src/modules/dev-tools/rulers/models/RulerLine.ts","../src/modules/dev-tools/rulers/RulersManager.ts","../src/modules/dev-tools/rulers/SnapEngine.ts","../src/modules/dev-tools/rulers/models/RulerMode.ts","../src/modules/dev-tools/core/startPointerDrag.ts","../src/utils/interaction-lock.ts","../src/modules/dev-tools/rulers/RulersOverlay.ts","../src/modules/dev-tools/core/StringDevPersistedState.ts","../src/modules/dev-tools/rulers/StringRulers.ts","../src/modules/dev-tools/core/StringDevOverlayModule.ts","../src/modules/dev-tools/core/StringDevBadgeOverlayModule.ts","../src/modules/dev-tools/inview/StringDevInview.css.ts","../src/modules/dev-tools/inview/StringDevInview.ts","../src/modules/dev-tools/core/bindOutsideClick.ts","../src/modules/dev-tools/progress/StringDevProgress.css.ts","../src/modules/dev-tools/progress/StringDevProgress.ts","../src/models/devtools/StringDevtool.ts"],"sourcesContent":["import { CursorController } from \"./core/controllers/CursorController\";\r\nimport { IStringModule } from \"./core/IStringModule\";\r\nimport { EventManager } from \"./core/managers/EventManager\";\r\nimport { ModuleManager } from \"./core/managers/ModuleManager\";\r\nimport { ObjectManager } from \"./core/managers/ObjectManager\";\r\nimport { ScrollManager } from \"./core/managers/ScrollManager\";\r\nimport { StringContext } from \"./core/StringContext\";\r\nimport { StringData } from \"./core/StringData\";\r\nimport { StringModule } from \"./core/StringModule\";\r\nimport { DefaultToolsContainer } from \"./core/StringToolsContainer\";\r\nimport { StringCursor } from \"./modules/cursor/StringCursor\";\r\nimport { StringImpulse } from \"./modules/cursor/StringImpulse\";\r\nimport { StringAttractor } from \"./modules/cursor/StringAttractor\";\r\nimport { StringMarquee } from \"./modules/layout/StringMarquee\";\r\nimport { StringMasonry } from \"./modules/layout/StringMasonry\";\r\nimport { StringMagnetic } from \"./modules/cursor/StringMagnetic\";\r\nimport { StringSpotlight } from \"./modules/cursor/StringSpotlight\";\r\nimport { StringTilt } from \"./modules/cursor/StringTilt\";\r\nimport { StringVelocity } from \"./modules/cursor/StringVelocity\";\r\nimport { StringLazy } from \"./modules/loading/StringLazy\";\r\nimport { StringLoading } from \"./modules/loading/StringLoading\";\r\nimport { StringInview } from \"./modules/screen/StringInview\";\r\nimport { StringResponsive } from \"./modules/screen/StringResponsive\";\r\nimport { StringAnchor } from \"./modules/scroll/StringAnchor\";\r\nimport { StringGlide } from \"./modules/scroll/StringGlide\";\r\nimport { StringLerp } from \"./modules/scroll/StringLerp\";\r\nimport { StringParallax } from \"./modules/scroll/StringParallax\";\r\nimport { StringProgress } from \"./modules/scroll/StringProgress\";\r\nimport { StringScrollbar } from \"./modules/scrollbar/StringScrollbar\";\r\nimport { StringCircularText } from \"./modules/text/StringCircularText\";\r\nimport { StringSplit } from \"./modules/text/StringSplit\";\r\nimport { StringDelayLerpTracker } from \"./modules/tracker/StringDelayLerpTracker\";\r\nimport { StringFPSTracker } from \"./modules/tracker/StringFPSTracker\";\r\nimport { StringLerpTracker } from \"./modules/tracker/StringLerpTracker\";\r\nimport { StringPositionTracker } from \"./modules/tracker/StringPositionTracker\";\r\nimport { StringObject } from \"./objects/StringObject\";\r\nimport { ScrollMode } from \"./states/ScrollState\";\r\nimport { Debounce } from \"./utils/Debounce\";\r\nimport { EventCallback } from \"./models/event/EventCallback\";\r\nimport { StringFPS } from \"./utils/StringFPS\";\r\nimport { StringSettings } from \"./utils/StringSettings\";\r\nimport { StringVideoAutoplay } from \"./modules/loading/StringVideoAutoplay\";\r\nimport { ScrollMarkRule } from \"./models/scroll/ScrollTriggerRule\";\r\nimport { StringSequence } from \"./modules/slider/StringSequence\";\r\nimport { StringForm } from \"./modules/input/StringForm\";\r\nimport { ISettingsChangeData } from \"./models/event/ISettingsChangeData\";\r\nimport { CenterCache } from \"./core/managers/CenterCache\";\r\nimport { HoverTracker } from \"./core/managers/HoverTracker\";\r\nimport { DevtoolsManager } from \"./core/managers/DevtoolsManager\";\r\nimport { CursorReactiveModule } from \"./modules/cursor/CursorReactiveModule\";\r\nimport { StringScroller } from \"./modules/scroll/StringScroller\";\r\nimport { StringScrollContainer } from \"./modules/scroll/StringScrollContainer\";\r\nimport { parsePartOf } from \"./utils/ParsePartOf\";\r\nimport { StringProgressPart } from \"./modules/scroll/StringProgressPart\";\r\nimport { frameDOM } from \"./utils/frame-dom\";\r\nimport { styleTxn } from \"./utils/style-txn\";\r\nimport { StringRandom } from \"./modules/random/StringRandom\";\r\nimport { ScrollController } from \"./core/controllers/ScrollController\";\r\nimport { StringDevLayout } from \"./modules/dev-tools/layout/StringGrid\";\r\nimport { GridAdapter } from \"./modules/dev-tools/layout/adapters/GridAdapter\";\r\nimport { StringDevRulers } from \"./modules/dev-tools/rulers/StringRulers\";\r\nimport { StringDevInview } from \"./modules/dev-tools/inview/StringDevInview\";\r\nimport { StringDevProgress } from \"./modules/dev-tools/progress/StringDevProgress\";\r\nimport { StringDevModule } from \"./modules/dev-tools/core/StringDevModule\";\r\nimport { StringDevOverlayRegistry } from \"./modules/dev-tools/core/StringDevOverlayRegistry\";\r\nimport { setStringDevStorageScopeToken } from \"./modules/dev-tools/core/StringDevStorageScope\";\r\nimport {\r\n  StringDevIconRegistry,\r\n  resolveDevtoolsIcon,\r\n} from \"./modules/dev-tools/core/StringDevIconRegistry\";\r\nimport {\r\n  buildDevtoolsThemeBlock,\r\n  ensureStringDevtoolsSharedStyles,\r\n  type StringDevStyleTokens,\r\n} from \"./modules/dev-tools/core/StringDevStyleSystem\";\r\n// import {\r\n//   StringInfiniteVirtual,\r\n//   StringInfiniteVirtualOptions,\r\n//   StringInfiniteVirtualReachEvent,\r\n//   StringInfiniteVirtualSnapshot,\r\n//   StringVirtualAlign,\r\n//   StringVirtualAxis,\r\n//   StringVirtualItem,\r\n//   StringVirtualKey,\r\n//   StringVirtualRange,\r\n// } from \"./modules/virtual-scroll/StringInfiniteVirtual\";\r\n// import {\r\n//   StringInfiniteVirtualDOM,\r\n//   StringInfiniteVirtualDOMOptions,\r\n// } from \"./modules/virtual-scroll/StringInfiniteVirtualDOM\";\r\n// import {\r\n//   StringVirtualScroll,\r\n//   StringVirtualScrollItemEventPayload,\r\n//   StringVirtualScrollSetDataPayload,\r\n//   StringVirtualScrollSetFilterPayload,\r\n// } from \"./modules/virtual-scroll/StringVirtualScroll\";\r\n// import {\r\n//   StringFilterEngine,\r\n//   StringFilterExpression,\r\n//   StringFilterResult,\r\n// } from \"./modules/virtual-scroll/filter/StringFilterEngine\";\r\n// import {\r\n//   createFilterSchema,\r\n//   StringFilterFieldDefinition,\r\n//   StringFilterFieldKind,\r\n//   StringFilterIndexKind,\r\n//   StringFilterPrimitive,\r\n//   StringFilterSchema,\r\n// } from \"./modules/virtual-scroll/filter/StringFilterSchema\";\r\n// import {\r\n//   createFilteredVirtualDataset,\r\n//   StringFilteredVirtualDataset,\r\n//   StringFilteredVirtualDatasetItem,\r\n//   StringFilteredVirtualDatasetOptions,\r\n// } from \"./modules/virtual-scroll/filter/StringFilteredVirtualDataset\";\r\n// import { StringBitset } from \"./modules/virtual-scroll/filter/StringBitset\";\r\nimport type {\r\n  StringRulersTrigger,\r\n  RulersTriggerAction,\r\n} from \"./modules/dev-tools/rulers/models/StringRulersTrigger\";\r\nimport type { RulersLayoutGrid } from \"./modules/dev-tools/rulers/models/RulersLayoutGrid\";\r\nimport { isStringDevtoolProvider } from \"./models/devtools/StringDevtool\";\r\nimport type {\r\n  StringDevtoolDefinition,\r\n  StringDevtoolProvider,\r\n  StringDevtoolState,\r\n} from \"./models/devtools/StringDevtool\";\r\n\r\nfunction isTouchDevice() {\r\n  return \"ontouchstart\" in window || navigator.maxTouchPoints > 0;\r\n}\r\nfunction isSafari(): boolean {\r\n  let ua = navigator.userAgent.toLowerCase();\r\n  if (ua.indexOf(\"safari\") != -1) {\r\n    if (ua.indexOf(\"chrome\") > -1) {\r\n      return false;\r\n    } else {\r\n      return true;\r\n    }\r\n  } else {\r\n    return false;\r\n  }\r\n}\r\n\r\nclass StringTune {\n  private static readonly DEVTOOLS_ACCESS_URL = \"https://access.fiddle.digital/\";\n  private static readonly DEVTOOLS_LOG_PREFIX = \"[StringTune Devtools]\";\n  private static readonly DEVTOOLS_ARTIFACT_SELECTORS = [\n    \"[data-string-dev-viewport-layer]\",\n    \"[data-string-dev-viewport-world]\",\n    \"[data-stdg-dock]\",\n    \"[data-stdg-dock-sub-badges]\",\n  ];\n\r\n  /** Bound handler for the scroll start event */\r\n  private onScrollStartBind: any;\r\n\r\n  /** Bound handler for the scroll stop event */\r\n  private onScrollStopBind: any;\r\n\r\n  /** Bound handler for the scroll direction change event */\r\n  private onDirectionChangeBind: any;\r\n\r\n  /** Bound handler for scroll mode/config changes */\r\n  private onScrollConfigChangeBind: any;\r\n\r\n  /** Bound wheel event handler */\r\n  private onWheelBind: any;\r\n\r\n  /** Bound scroll event handler */\r\n  private onScrollBind: any;\r\n\r\n  /** Bound resize event handler */\r\n  private onResizeBind: any;\r\n\r\n  /** Bound mouse move handler */\r\n  private onMouseMoveBind: any;\r\n\r\n  /** Bound scroll to handler */\r\n  private onScrollToBind: (value: any) => void;\r\n  private onDOMChangedBind: () => void;\r\n\r\n  private onContainerTransitionEndBind: any;\r\n  private onResizeObserverBind: any;\r\n  private pendingScroll: boolean = false;\r\n  private lastScrollEmitted: number = NaN;\r\n  private observerContainerMutation: MutationObserver | null = null;\r\n  private pendingResizeRaf: number | null = null;\r\n  private pendingResizeForce: boolean = false;\r\n\r\n  /** Singleton instance of StringTune */\r\n  private static i: StringTune;\r\n\r\n  /** Root scrollable element (typically <body>) */\r\n  private root: any;\r\n\r\n  /** Window object (used for event bindings and dimensions) */\r\n  private window: any;\r\n\r\n  /** Previous window width for resize diff check */\r\n  private prevWidth: number = 0;\r\n\r\n  /** Previous window height for resize diff check */\r\n  private prevHeight: number = 0;\r\n\r\n  /** Manages all modules registered in the system */\r\n  private moduleManager: ModuleManager;\r\n\r\n  /** Manages scroll modes and active scroll engine */\r\n  private scrollManager: ScrollManager;\r\n\r\n  /** Manages all interactive objects (elements with `string-*` attributes) */\r\n  private objectManager: ObjectManager;\r\n\r\n  /** Central event manager for internal pub-sub logic */\r\n  private eventManager: EventManager;\r\n\r\n  /** Handles custom cursor logic (if enabled) */\r\n  private cursorController: CursorController;\r\n\r\n  /** Provides default utility tools (parsers, interpolation, etc.) */\r\n  private tools: DefaultToolsContainer;\r\n\r\n  /** Main loop used for frame updates (with fixed FPS) */\r\n  private loop: StringFPS = new StringFPS();\r\n\r\n  /** Global reactive data store (scroll, viewport, etc.) */\r\n  private data: StringData;\r\n\r\n  /** Context shared across all modules (events, data, tools, settings) */\r\n  private context: StringContext;\r\n\r\n  /** Caches the center positions of string objects. */\r\n  private centers: CenterCache;\r\n\r\n  /** Tracks hover states of string objects. */\r\n  private hoverManager: HoverTracker;\r\n  private devtools: DevtoolsManager;\r\n  private devtoolsFpsLastSampleTime: number = 0;\r\n  private devtoolsFpsFrameCount: number = 0;\r\n\r\n  private observerContainerResize: ResizeObserver | null = null;\r\n  private devtoolsAccessToken: string = \"\";\r\n  private devtoolsAccessState: \"unknown\" | \"pending\" | \"granted\" | \"denied\" = \"unknown\";\r\n  private devtoolsAccessRequestId: number = 0;\r\n  private pendingDevtoolUses: Array<{ objectClass: typeof StringModule; settings: any }> = [];\r\n  private hasStarted: boolean = false;\r\n  private devtoolsAccessLastMessage: \"none\" | \"granted\" | \"denied\" | \"error\" = \"none\";\r\n\r\n  public canRebuild: boolean = true;\r\n\r\n  /**\r\n   * Sets the scroll position manually.\r\n   * This overrides all internal scroll states including target and lerped values.\r\n   * Useful for programmatic jumps or syncing scroll externally.\r\n   *\r\n   * @param value The new scroll position in pixels.\r\n   */\r\n  public set scrollPosition(value: number) {\r\n    this.data.scroll.current = value;\r\n    this.data.scroll.target = value;\r\n    this.data.scroll.transformedCurrent =\r\n      this.data.scroll.current * this.data.viewport.transformScale;\r\n    this.data.scroll.delta = 0;\r\n    this.data.scroll.lerped = 0;\r\n    this.scrollManager.updatePosition();\r\n    this.moduleManager.onScroll();\r\n    this.objectManager.checkInview();\r\n  }\r\n\r\n  public set accessDevtoolToken(value: string) {\r\n    const normalized = value.trim();\r\n    const isSameToken = normalized === this.devtoolsAccessToken;\r\n\r\n    if (\r\n      isSameToken &&\r\n      (this.devtoolsAccessState === \"granted\" || this.devtoolsAccessState === \"pending\")\r\n    ) {\r\n      return;\r\n    }\r\n\r\n    this.devtoolsAccessToken = normalized;\r\n\r\n    if (normalized.length === 0) {\r\n      this.devtoolsAccessState = \"unknown\";\r\n      return;\r\n    }\r\n\r\n    this.validateDevtoolsAccess(normalized);\r\n  }\r\n\r\n  /**\r\n   * Configures the container element(s) used for scroll tracking.\r\n   * Accepts either the `Window` object or an `HTMLElement`.\r\n   * Determines the appropriate internal element references based on the input type\r\n   * and triggers a resize calculation.\r\n   *\r\n   * @param {Window | HTMLElement | any} container The target window or HTML element to associate with scrolling.\r\n   * Handles `Window`, `HTMLElement`, and potentially other types via fallback.\r\n   */\r\n  public set scrollContainer(container: any) {\r\n    this.observerContainerResize?.unobserve(this.context.data.scroll.container);\r\n\r\n    this.data.scroll.elementContainer.removeEventListener(\r\n      \"transitionend\",\r\n      this.onContainerTransitionEndBind,\r\n    );\r\n    if (container instanceof Window) {\r\n      this.data.scroll.container = document.body;\r\n      this.data.scroll.elementContainer = document.documentElement;\r\n      this.data.scroll.scrollContainer = container;\r\n    } else if (container instanceof HTMLElement) {\r\n      this.data.scroll.container = container;\r\n      this.data.scroll.elementContainer = container;\r\n      this.data.scroll.scrollContainer = container;\r\n    } else {\r\n      // Fallback case\r\n      this.data.scroll.container = document.body;\r\n      this.data.scroll.elementContainer = document.documentElement;\r\n      this.data.scroll.scrollContainer = container;\r\n    }\r\n    this.data.scroll.elementContainer.addEventListener(\r\n      \"transitionend\",\r\n      this.onContainerTransitionEndBind,\r\n    );\r\n    this.observerContainerResize?.observe(this.context.data.scroll.container);\r\n    this.observeContainerMutations();\r\n    this.queueResize(true);\r\n  }\r\n\r\n  /**\r\n   * Gets the current scroll position in pixels.\r\n   * This is typically updated every frame.\r\n   */\r\n  public get scrollPosition() {\r\n    return this.data.scroll.current;\r\n  }\r\n\r\n  public get scrollHeight() {\r\n    return this.data.viewport.contentHeight;\r\n  }\r\n\r\n  public get containerHeight() {\r\n    return this.data.viewport.windowHeight;\r\n  }\r\n\r\n  /**\r\n   * Sets the base scroll speed for smooth scrolling.\r\n   * Typically a value between 0 and 1.\r\n   */\r\n  public set speed(value: number) {\r\n    this.data.scroll.speed = value;\r\n  }\r\n\r\n  /**\r\n   * Sets the scroll acceleration using a normalized value from 0 to 1.\r\n   * Internally maps it to a real acceleration value between 0.1 and 0.5.\r\n   *\r\n   * @param speed A normalized acceleration factor (0 to 1).\r\n   */\r\n  public set speedAccelerate(speed: number) {\r\n    const min = 0.1;\r\n    const max = 0.5;\r\n    this.data.scroll.speedAccelerate = min + (max - min) * speed;\r\n  }\r\n\r\n  /**\r\n   * Sets the scroll mode for desktop devices.\r\n   * Can be 'smooth', 'default', or 'disable'.\r\n   */\r\n  public set scrollDesktopMode(mode: ScrollMode) {\r\n    this.scrollManager.setDesktopMode(mode);\r\n  }\r\n\r\n  /**\r\n   * Sets the scroll mode for mobile devices.\r\n   * Can be 'smooth', 'default', or 'disable'.\r\n   */\r\n  public set scrollMobileMode(mode: ScrollMode) {\r\n    this.scrollManager.setMobileMode(mode);\r\n  }\r\n\r\n  public set FPSTrackerVisible(visible: boolean) {\r\n    this.data.system.fpsTracker = visible;\r\n    this.eventManager.emit(\"tracker:fps:visible\", visible);\r\n  }\r\n\r\n  public set PositionTrackerVisible(visible: boolean) {\r\n    this.data.system.positionTracker = visible;\r\n    this.eventManager.emit(\"tracker:position:visible\", visible);\r\n  }\r\n\r\n  public set domBatcherEnabled(enabled: boolean) {\r\n    this.objectManager.setDOMBatcherEnabled(enabled);\r\n  }\r\n\r\n  public set intersectionObserverEnabled(enabled: boolean) {\r\n    this.objectManager.setIntersectionObserverEnabled(enabled);\r\n  }\r\n\r\n  private debouncedResize = Debounce(() => {\r\n    this.queueResize(false);\r\n  }, 30);\r\n\r\n  private constructor() {\n    this.cleanupExistingDevtoolsArtifacts();\n    this.root = document.body;\n    this.window = window;\n\r\n    this.tools = new DefaultToolsContainer();\r\n    this.data = new StringData();\r\n    this.eventManager = new EventManager();\r\n    this.moduleManager = new ModuleManager(this.data);\r\n    this.objectManager = new ObjectManager(\r\n      this.data,\r\n      this.moduleManager,\r\n      this.eventManager,\r\n      this.tools,\r\n    );\r\n\r\n    this.centers = new CenterCache();\r\n    this.hoverManager = new HoverTracker();\r\n    this.devtools = new DevtoolsManager();\r\n\r\n    this.context = {\r\n      events: this.eventManager,\r\n      data: this.data,\r\n      tools: this.tools,\r\n      settings: {},\r\n      centers: this.centers,\r\n      hover: this.hoverManager,\r\n      objectManager: this.objectManager,\r\n    };\r\n\r\n    this.cursorController = new CursorController(1, this.context);\r\n    this.scrollManager = new ScrollManager(this.context);\r\n\r\n    this.setupSettings({\n      \"global-class\": false,\r\n      \"offset-top\": \"0%\",\r\n      \"offset-bottom\": \"0%\",\r\n      key: \"--progress\",\r\n      \"inview-top\": \"0%\",\r\n      \"inview-bottom\": \"0%\",\r\n      \"enter-el\": \"top\",\r\n      \"enter-vp\": \"bottom\",\r\n      \"exit-el\": \"bottom\",\r\n      \"exit-vp\": \"top\",\r\n      \"parallax-bias\": \"0.0\",\r\n      parallax: \"0.2\",\r\n      lerp: \"0.2\",\r\n      \"cursor-lerp\": \"0.75\",\r\n      radius: \"150\",\r\n      strength: \"0.3\",\r\n      glide: \"1\",\r\n      anchor: \"center center\",\r\n      timeout: 900,\r\n      alignment: \"center\",\r\n      \"target-disable\": \"false\",\r\n      \"target-style-disable\": \"false\",\r\n      \"target-class\": \"\",\r\n      active: \"false\",\r\n      fixed: \"false\",\r\n      repeat: \"false\",\r\n      \"self-disable\": \"false\",\r\n      abs: \"false\",\r\n      easing: \"cubic-bezier(0.25, 0.25, 0.25, 0.25)\",\r\n      \"glide-base-velocity\": 0.00125,\r\n      \"glide-reduce-velocity\": 0.0000625,\r\n      \"glide-negative-velocity\": -0.0001,\r\n\r\n      \"position-strength\": 3,\r\n      \"position-tension\": 0.05,\r\n      \"position-friction\": 0.15,\r\n      \"position-max-velocity\": 10,\r\n      \"position-update-threshold\": 0.1,\r\n      \"rotation-strength\": 0.75,\r\n      \"rotation-tension\": 0.06,\r\n      \"rotation-friction\": 0.18,\r\n      \"rotation-max-angular-velocity\": 6,\r\n      \"rotation-max-angle\": 18,\r\n      \"rotation-update-threshold\": 0.15,\r\n      \"max-offset\": 220,\r\n      \"sleep-epsilon\": 0.01,\r\n      \"continuous-push\": true,\r\n    });\r\n\r\n    this.onContainerTransitionEndBind = this.onContainerTransitionEnd.bind(this);\r\n\r\n    this.onResizeObserverBind = this.onResizeObserverEvent.bind(this);\r\n    this.observerContainerResize = new ResizeObserver(this.onResizeObserverBind);\r\n    this.observerContainerResize.observe(this.context.data.scroll.container);\r\n\r\n    this.onWheelBind = this.onWheelEvent.bind(this);\r\n    this.onScrollBind = this.onScrollEvent.bind(this);\r\n    this.onResizeBind = () => {\r\n      this.queueResize(false);\r\n    };\r\n    this.onMouseMoveBind = this.onMouseMoveEvent.bind(this);\r\n\r\n    this.onScrollStartBind = this.onScrollStart.bind(this);\r\n    this.onScrollStopBind = this.onScrollStop.bind(this);\r\n    this.onDirectionChangeBind = this.onDirectionChange.bind(this);\r\n    this.onScrollConfigChangeBind = this.onScrollConfigChange.bind(this);\r\n    this.onScrollToBind = this.scrollTo.bind(this);\r\n    this.onDOMChangedBind = this.onDOMChanged.bind(this);\r\n\r\n    this.eventManager.on(`wheel`, this.onWheelBind);\r\n    this.eventManager.on(`resize`, this.onResizeBind);\r\n    this.eventManager.on(`scrollTo`, this.onScrollToBind);\r\n    this.eventManager.on(`dom:changed`, this.onDOMChangedBind);\r\n\r\n    this.scrollManager.bindEvents({\r\n      onScrollStart: this.onScrollStartBind,\r\n      onScrollStop: this.onScrollStopBind,\r\n      onDirectionChange: this.onDirectionChangeBind,\r\n      onModeChange: this.onScrollConfigChangeBind,\r\n    });\r\n\r\n    this.loop.setOnFrame((time: number) => {\r\n      this.data.time.delta = time - this.data.time.now;\r\n      this.data.time.previous = this.data.time.now;\r\n      this.data.time.now = time;\r\n      this.data.time.elapsed += this.data.time.delta;\r\n      this.onUpdateEvent();\r\n      this.updateDevtoolsFPS(time);\r\n    });\r\n    this.on(\"image:load:all\", () => {\r\n      this.onResize();\r\n    });\r\n    this.scrollContainer = window;\r\n  }\r\n\r\n  /**\r\n   * Returns the singleton instance of StringTune.\r\n   * If not already created, initializes it.\r\n   */\r\n  public static getInstance(): StringTune {\r\n    if (!StringTune.i) {\r\n      StringTune.i = new StringTune();\r\n    }\r\n    return StringTune.i;\r\n  }\r\n\r\n  /**\r\n   * Finds and returns an existing module by its class.\r\n   * Useful for reusing a module instance without re-registering.\r\n   *\r\n   * @template T The type of the module to retrieve.\r\n   * @param type The module class constructor.\r\n   * @returns The module instance if found, otherwise undefined.\r\n   */\r\n  public reuse<T>(type: new (...args: any[]) => T): T | undefined {\r\n    return this.moduleManager.find(type);\r\n  }\r\n\r\n  /**\r\n   * Instantiates and registers a new module.\r\n   * Accepts optional per-instance settings that override global settings.\r\n   *\r\n   * @param objectClass The module class to instantiate.\r\n   * @param settings Optional settings specific to this module.\r\n   */\r\n  public use(objectClass: typeof StringModule, settings: any = null) {\n    const existing = this.moduleManager.find(objectClass);\n    if (existing) {\n      return;\n    }\n    if (this.shouldDeferDevtoolModule(objectClass, settings)) {\n      return;\n    }\n    this.instantiateModule(objectClass, settings);\n  }\n\n  private cleanupExistingDevtoolsArtifacts(): void {\n    for (const selector of StringTune.DEVTOOLS_ARTIFACT_SELECTORS) {\n      document.querySelectorAll(selector).forEach((node) => node.remove());\n    }\n  }\n\r\n  private instantiateModule(objectClass: typeof StringModule, settings: any = null): void {\r\n    const effectiveSettings = {\r\n      ...this.context.settings,\r\n      ...settings,\r\n    };\r\n    const module = new objectClass({\r\n      events: this.eventManager,\r\n      data: this.data,\r\n      tools: this.tools,\r\n      settings: effectiveSettings,\r\n      centers: this.centers,\r\n      hover: this.hoverManager,\r\n      objectManager: this.objectManager,\r\n    });\r\n    this.moduleManager.register(module);\r\n    if (isStringDevtoolProvider(module)) {\r\n      this.devtools.register(module.getDevtoolDefinition());\r\n    }\r\n\r\n    if (this.hasStarted) {\r\n      this.objectManager.attachModule(module);\r\n      module.onInit();\r\n      module.onResize();\r\n      module.onScroll(this.data);\r\n      module.onFrame(this.data);\r\n    }\r\n  }\r\n\r\n  private shouldDeferDevtoolModule(objectClass: typeof StringModule, settings: any): boolean {\r\n    const isDevtoolModule =\r\n      objectClass === StringDevModule || objectClass.prototype instanceof StringDevModule;\r\n    if (!isDevtoolModule) {\r\n      return false;\r\n    }\r\n\r\n    if (this.devtoolsAccessState === \"granted\") {\r\n      return false;\r\n    }\r\n\r\n    this.pendingDevtoolUses.push({ objectClass, settings });\r\n    if (this.devtoolsAccessToken.length > 0 && this.devtoolsAccessState !== \"pending\") {\r\n      this.validateDevtoolsAccess(this.devtoolsAccessToken);\r\n    }\r\n    return true;\r\n  }\r\n\r\n  private async validateDevtoolsAccess(token: string): Promise<void> {\r\n    const requestId = ++this.devtoolsAccessRequestId;\r\n    this.devtoolsAccessState = \"pending\";\r\n\r\n    try {\r\n      const response = await fetch(\r\n        `${StringTune.DEVTOOLS_ACCESS_URL}?token=${encodeURIComponent(token)}`,\r\n      );\r\n      const allowed = await this.resolveDevtoolsAccessResponse(response);\r\n      if (requestId !== this.devtoolsAccessRequestId || token !== this.devtoolsAccessToken) {\r\n        return;\r\n      }\r\n\r\n      this.devtoolsAccessState = allowed ? \"granted\" : \"denied\";\r\n      if (!allowed) {\r\n        this.logDevtoolsAccess(\"denied\");\r\n        this.pendingDevtoolUses = [];\r\n        return;\r\n      }\r\n\r\n      this.logDevtoolsAccess(\"granted\");\r\n      const pending = [...this.pendingDevtoolUses];\r\n      this.pendingDevtoolUses = [];\r\n      pending.forEach(({ objectClass, settings }) => {\r\n        this.instantiateModule(objectClass, settings);\r\n      });\r\n    } catch {\r\n      if (requestId !== this.devtoolsAccessRequestId || token !== this.devtoolsAccessToken) {\r\n        return;\r\n      }\r\n      if (this.devtoolsAccessState === \"granted\") {\r\n        return;\r\n      }\r\n      this.devtoolsAccessState = \"denied\";\r\n      this.logDevtoolsAccess(\"error\");\r\n      this.pendingDevtoolUses = [];\r\n    }\r\n  }\r\n\r\n  private logDevtoolsAccess(type: \"granted\" | \"denied\" | \"error\"): void {\r\n    if (this.devtoolsAccessLastMessage === type) {\r\n      return;\r\n    }\r\n    this.devtoolsAccessLastMessage = type;\r\n\r\n    if (type === \"granted\") {\r\n      console.info(\r\n        `${StringTune.DEVTOOLS_LOG_PREFIX} Access granted. Devtools modules are enabled.`,\r\n      );\r\n      return;\r\n    }\r\n\r\n    if (type === \"denied\") {\r\n      console.warn(\r\n        `${StringTune.DEVTOOLS_LOG_PREFIX} Access denied. Devtools modules were not enabled. Check accessDevtoolToken.`,\r\n      );\r\n      return;\r\n    }\r\n\r\n    console.warn(\r\n      `${StringTune.DEVTOOLS_LOG_PREFIX} Access check failed. Devtools modules were not enabled.`,\r\n    );\r\n  }\r\n\r\n  private async resolveDevtoolsAccessResponse(response: Response): Promise<boolean> {\r\n    if (!response.ok) {\r\n      return false;\r\n    }\r\n\r\n    const contentType = response.headers.get(\"content-type\")?.toLowerCase() ?? \"\";\r\n    if (contentType.includes(\"application/json\")) {\r\n      const data = await response.json();\r\n      if (typeof data === \"boolean\") {\r\n        return data;\r\n      }\r\n      if (data && typeof data === \"object\" && \"allowed\" in data) {\r\n        return data.allowed === true;\r\n      }\r\n      return false;\r\n    }\r\n\r\n    const text = (await response.text()).trim().toLowerCase();\r\n    return text === \"true\";\r\n  }\r\n\r\n  /**\r\n   * Registers a new scroll mode (provider) to the system.\r\n   * Allows integrating custom scroll implementations (e.g. Lenis, Locomotive).\r\n   *\r\n   * @param name The unique name for this scroll mode (e.g. 'smooth', 'lenis').\r\n   * @param factory A function that receives the StringContext and returns a ScrollController instance, OR a ScrollController class constructor.\r\n   *\r\n   * Example:\r\n   * ```ts\r\n   * stringTune.registerScrollMode(\"custom\", (context) => new CustomAdapter(context));\r\n   * ```\r\n   */\r\n  public registerScrollMode(\r\n    name: string,\r\n    factory:\r\n      | ((context: StringContext) => ScrollController)\r\n      | (new (context: StringContext) => ScrollController),\r\n  ) {\r\n    let controller: ScrollController;\r\n\r\n    // Check if it's a class constructor (handles class fields too)\r\n    if (typeof factory === \"function\" && factory.prototype instanceof ScrollController) {\r\n      const Constructor = factory as new (context: StringContext) => ScrollController;\r\n      controller = new Constructor(this.context);\r\n    } else {\r\n      const func = factory as (context: StringContext) => ScrollController;\r\n      controller = func(this.context);\r\n    }\r\n\r\n    if (!controller.name) {\r\n      controller.name = name;\r\n    }\r\n\r\n    this.scrollManager.registerMode(name, controller);\r\n  }\r\n\r\n  /**\r\n   * Subscribes to a global event within the system.\r\n   *\r\n   * @param eventName The name of the event to listen for.\r\n   * @param callback The function to call when the event is triggered.\r\n   * @param id Optional subscription ID (for easier management).\r\n   */\r\n  public on(eventName: string, callback: EventCallback<any>, id: string = \"\") {\r\n    this.eventManager.on(eventName, callback, id);\r\n  }\r\n  public emit(eventName: string, data: any) {\r\n    this.eventManager.emit(eventName, data);\r\n  }\r\n\r\n  /**\r\n   * Unsubscribes from a global event.\r\n   *\r\n   * @param eventName The name of the event.\r\n   * @param callback The previously registered callback.\r\n   * @param id Optional ID used during subscription.\r\n   */\r\n  public off(eventName: string, callback: EventCallback<any>, id: string = \"\") {\r\n    this.eventManager.off(eventName, callback, id);\r\n  }\r\n\r\n  /**\r\n   * Adds a scroll trigger rule that activates when the user scrolls past a defined offset\r\n   * in a specific direction. This can be used to toggle CSS classes or execute callbacks\r\n   * when elements come into view or go out of view.\r\n   *\r\n   * @param rule - The scroll trigger configuration object.\r\n   *   - `id`: A unique identifier for this rule.\r\n   *   - `offset`: The vertical scroll offset (in pixels) where the rule should activate.\r\n   *   - `direction`: Defines the scroll direction required to activate the rule.\r\n   *                 Can be `\"forward\"`, `\"backward\"`, or `\"any\"`.\r\n   *   - `onEnter`: (Optional) A function that will be called when the scroll position enters the trigger zone\r\n   *                in the specified direction.\r\n   *   - `onLeave`: (Optional) A function that will be called when the scroll position leaves the trigger zone\r\n   *                or scrolls in the opposite direction.\r\n   *   - `toggleClass`: (Optional) An object defining a class toggle behavior.\r\n   *                    It contains a target element and a class name to be added when the trigger is active\r\n   *                    and removed when it's not.\r\n   */\r\n  public addScrollMark(rule: ScrollMarkRule) {\r\n    this.scrollManager.addScrollMark(rule);\r\n  }\r\n\r\n  /**\r\n   * Removes a scroll trigger by its unique identifier.\r\n   *\r\n   * @param id - The unique identifier of the scroll trigger to be removed.\r\n   */\r\n  public removeScrollMark(id: string) {\r\n    this.scrollManager.removeScrollMark(id);\r\n  }\r\n\r\n  /**\r\n   * Starts the scroll engine and initializes all listeners, observers, and modules.\r\n   *\r\n   * @param fps Desired frames per second for the update loop.\r\n   */\r\n  public start(fps: number) {\n    if (this.hasStarted) {\n      return;\n    }\n    this.hasStarted = true;\n    this.data.scroll.scrollContainer?.addEventListener(\"scroll\", this.onScrollBind);\r\n    this.data.scroll.container?.addEventListener(\"wheel\", this.onWheelBind, {\r\n      passive: false,\r\n    });\r\n\r\n    window.addEventListener(\"resize\", this.onResizeBind);\r\n    this.root.addEventListener(\"mousemove\", this.onMouseMoveBind);\r\n    this.observeContainerMutations();\r\n\r\n    this.use(StringInview);\r\n\r\n    const htmlFontSize = window.getComputedStyle(document.documentElement).fontSize;\r\n    const fontSizeNumber = parseFloat(htmlFontSize);\r\n    this.context.data.viewport.baseRem = fontSizeNumber;\r\n\r\n    document.documentElement.classList.add(\"-string\");\r\n    this.syncDebugScrollState();\r\n    this.moduleManager.onInit();\r\n    this.onResize();\r\n    this.initObjects();\r\n    this.objectManager.observeDOM();\r\n\r\n    this.loop.start(fps);\r\n    this.eventManager.emit(`start`, null);\r\n  }\r\n\r\n  /**\r\n   * Initializes all DOM elements with `string` or `string-copy-from` attributes.\r\n   * Registers them with the object manager and triggers resize/scroll/frame hooks.\r\n   */\r\n  private initObjects() {\r\n    document.querySelectorAll(\"[string],[data-string]\").forEach((element) => {\r\n      this.objectManager.add(element as HTMLElement);\r\n    });\r\n    document.querySelectorAll(\"[string-copy-from],[data-string-copy-from]\").forEach((element) => {\r\n      let connectTargetId = this.tools.domAttribute.process({\r\n        element: element as HTMLElement,\r\n        key: \"copy-from\",\r\n        fallback: \"\",\r\n      });\r\n\r\n      if (connectTargetId && connectTargetId.length > 0) {\r\n        this.objectManager.linkMirror(connectTargetId, element as HTMLElement);\r\n      }\r\n    });\r\n\r\n    this.moduleManager.onResize();\r\n    this.moduleManager.onScroll();\r\n    this.moduleManager.onFrame();\r\n  }\r\n\r\n  /**\r\n   * Sets global fallback settings for all modules.\r\n   * These can be overridden by module-specific settings during `use(...)`.\r\n   *\r\n   * @param settings A key-value map of default settings (e.g. 'offset-top': '-10%').\r\n   */\r\n  public setupSettings(settings: StringSettings): void {\r\n    this.context.settings = {\r\n      ...this.context.settings,\r\n      ...settings,\r\n    };\r\n    if (typeof settings[\"storageToken\"] === \"string\") {\r\n      setStringDevStorageScopeToken(settings[\"storageToken\"]);\r\n    } else if (typeof settings[\"storage-token\"] === \"string\") {\r\n      setStringDevStorageScopeToken(settings[\"storage-token\"]);\r\n    }\r\n    if (typeof settings[\"accessDevtoolToken\"] === \"string\") {\r\n      this.accessDevtoolToken = settings[\"accessDevtoolToken\"];\r\n    }\r\n    this.onSettingsChange({\r\n      isDesktop: this.data.viewport.windowWidth > 1024,\r\n      widthChanged: true,\r\n      heightChanged: true,\r\n      scrollHeightChanged: true,\r\n      isForceRebuild: false,\r\n    });\r\n  }\r\n\r\n  private onResizeObserverEvent() {\r\n    this.debouncedResize();\r\n  }\r\n\r\n  private onContainerTransitionEnd(event: TransitionEvent) {\r\n    if (event.target === this.context.data.scroll.container) {\r\n      this.queueResize(true);\r\n    }\r\n  }\r\n\r\n  private onDOMChanged() {\r\n    this.queueResize(false);\r\n    this.debouncedResize();\r\n  }\r\n\r\n  private observeContainerMutations() {\r\n    this.observerContainerMutation?.disconnect();\r\n    const container = this.context.data.scroll.container;\r\n    if (!container) return;\r\n\r\n    this.observerContainerMutation = new MutationObserver((mutationsList: MutationRecord[]) => {\r\n      for (let i = 0; i < mutationsList.length; i++) {\r\n        const mutation = mutationsList[i];\r\n        if (\r\n          mutation.type === \"attributes\" &&\r\n          (mutation.attributeName === \"style\" || mutation.attributeName === \"class\")\r\n        ) {\r\n          this.queueResize(false);\r\n          this.debouncedResize();\r\n          break;\r\n        }\r\n      }\r\n    });\r\n\r\n    this.observerContainerMutation.observe(container, {\r\n      attributes: true,\r\n      attributeFilter: [\"style\", \"class\"],\r\n    });\r\n  }\r\n\r\n  private queueResize(force: boolean = false) {\r\n    if (force) {\r\n      this.pendingResizeForce = true;\r\n    }\r\n\r\n    if (this.pendingResizeRaf != null) {\r\n      return;\r\n    }\r\n\r\n    this.pendingResizeRaf = requestAnimationFrame(() => {\r\n      this.pendingResizeRaf = null;\r\n      const shouldForce = this.pendingResizeForce;\r\n      this.pendingResizeForce = false;\r\n      this.onResize(shouldForce);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Handles mouse move event and dispatches it to cursor and modules.\r\n   * @param e Native mouse move event.\r\n   */\r\n  private onMouseMoveEvent(e: MouseEvent) {\r\n    this.cursorController.onMouseMove(e);\r\n    this.moduleManager.onMouseMove(e);\r\n    frameDOM.measure(() => {\r\n      this.moduleManager.onMouseMoveMeasure();\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Handles wheel scroll event and passes it to the scroll engine and modules.\r\n   * @param e Native wheel event.\r\n   */\r\n  private onWheelEvent(e: WheelEvent) {\r\n    const target = e.target as HTMLElement;\r\n    const isModal = target.closest(\"[string-isolation],[data-string-isolation]\");\r\n    if (isModal != null) return;\r\n    this.scrollManager.get().onWheel(e);\r\n    this.moduleManager.onWheel(e);\r\n  }\r\n\r\n  /**\r\n   * Called when scrolling begins.\r\n   * Triggers module scroll start lifecycle hook.\r\n   */\r\n  private onScrollStart() {\r\n    this.moduleManager.onScrollStart();\r\n    this.eventManager.emit(`scroll:start`, null);\r\n  }\r\n\r\n  /**\r\n   * Called when scrolling ends.\r\n   * Triggers module scroll stop lifecycle hook.\r\n   */\r\n  private onScrollStop() {\r\n    this.moduleManager.onScrollStop();\r\n    this.eventManager.emit(`scroll:stop`, null);\r\n  }\r\n\r\n  /**\r\n   * Called when scrolling ends.\r\n   * Triggers module scroll stop lifecycle hook.\r\n   */\r\n  private onDirectionChange() {\r\n    this.moduleManager.onDirectionChange();\r\n  }\r\n\r\n  private onScrollConfigChange() {\r\n    this.moduleManager.onScrollConfigChange();\r\n    this.syncDebugScrollState();\r\n    this.moduleManager.onScroll();\r\n    this.moduleManager.onScrollMeasure();\r\n    this.moduleManager.onFrame();\r\n    styleTxn.run(() => {\r\n      this.moduleManager.onMutate();\r\n    });\r\n  }\r\n\r\n  private syncDebugScrollState(): void {\r\n    const html = document.documentElement;\r\n    const isMobileBucket = window.innerWidth < 1024;\r\n    html.setAttribute(\"data-string-scroll-mode\", String(this.data.scroll.mode));\r\n    html.setAttribute(\"data-string-scroll-device\", isMobileBucket ? \"mobile\" : \"desktop\");\r\n  }\r\n\r\n  /**\r\n   * Called when global or module settings are updated.\r\n   * Notifies all managers and modules to re-read new settings.\r\n   */\r\n  private onSettingsChange(data: ISettingsChangeData) {\r\n    this.cursorController.onSettingsChange(data);\r\n    this.objectManager.onSettingsChange(data);\r\n    this.moduleManager.onSettingsChange(data);\r\n  }\r\n\r\n  /**\r\n   * Handles native scroll event.\r\n   * Prevents default behavior and triggers internal scroll logic and event emissions.\r\n   *\r\n   * @param e The native scroll event.\r\n   */\r\n  private onScrollEvent(e: Event) {\r\n    e.preventDefault();\r\n\r\n    this.context.centers.invalidateAll();\r\n\r\n    this.scrollManager.get().onScroll(e);\r\n    this.pendingScroll = true;\r\n    return false;\r\n  }\r\n\r\n  /**\r\n   * Called every frame by the update loop.\r\n   * Triggers scroll engine, modules, and global `update` event.\r\n   */\r\n  private onUpdateEvent() {\r\n    this.cursorController.onFrame();\r\n    this.scrollManager.get().onFrame();\r\n    this.moduleManager.onFrame();\r\n\r\n    if (this.pendingScroll || this.data.scroll.current !== this.lastScrollEmitted) {\r\n      this.pendingScroll = false;\r\n      this.moduleManager.onScroll();\r\n      this.objectManager.checkInview();\r\n      this.eventManager.emit(`lerp`, this.data.scroll.lerped);\r\n      this.eventManager.emit(`scroll`, this.data.scroll.current);\r\n      frameDOM.measure(() => {\r\n        this.moduleManager.onScrollMeasure();\r\n      });\r\n      this.lastScrollEmitted = this.data.scroll.current;\r\n    }\r\n\r\n    frameDOM.mutate(() => {\r\n      styleTxn.begin();\r\n      this.moduleManager.onMutate();\r\n      styleTxn.commit();\r\n    });\r\n\r\n    this.eventManager.emit(`update`, null);\r\n\r\n    frameDOM.flush();\r\n  }\r\n\r\n  private updateDevtoolsFPS(time: number): void {\r\n    if (this.devtoolsFpsLastSampleTime === 0) {\r\n      this.devtoolsFpsLastSampleTime = time;\r\n    }\r\n\r\n    this.devtoolsFpsFrameCount += 1;\r\n    const elapsed = time - this.devtoolsFpsLastSampleTime;\r\n\r\n    if (elapsed < 1000) {\r\n      return;\r\n    }\r\n\r\n    const fps = (this.devtoolsFpsFrameCount * 1000) / elapsed;\r\n    this.devtools.setFPS(fps);\r\n    this.devtoolsFpsFrameCount = 0;\r\n    this.devtoolsFpsLastSampleTime = time;\r\n  }\r\n\r\n  /**\r\n   * Handles resize events from scroll container or window.\r\n   * Ignores height-only changes on mobile to prevent layout jumps.\r\n   * Rebuilds layout and triggers module resize if size really changed.\r\n   */\r\n  public onResize(force: boolean = false): void {\r\n    if (this.canRebuild == false) {\r\n      return;\r\n    }\r\n    const container = this.data.scroll.container;\r\n    const scroll = this.context.data.scroll;\r\n    let width = 0;\r\n    let height = 0;\r\n    var newScrollHeight;\r\n    var newContainerTopPosition = 0;\r\n    const rect = container.getBoundingClientRect();\r\n\r\n    if (container.tagName == \"BODY\") {\r\n      width = document.documentElement.clientWidth || window.innerWidth || rect.width;\r\n      height = window.innerHeight;\r\n    } else {\r\n      width = rect.width;\r\n      height = rect.height;\r\n    }\r\n\r\n    newContainerTopPosition = container.tagName === \"BODY\" ? 0 : rect.top;\r\n    newScrollHeight = scroll.container.scrollHeight;\r\n    const transformScale = this.tools.transformScaleParser.process({\r\n      value: window.getComputedStyle(container).transform,\r\n    });\r\n    this.context.data.viewport.transformScale =\r\n      window.getComputedStyle(container).scale == \"none\"\r\n        ? transformScale\r\n        : Number(window.getComputedStyle(container).scale);\r\n    this.context.data.scroll.transformedCurrent =\r\n      this.context.data.scroll.current * this.context.data.viewport.transformScale;\r\n    const isTouch = isTouchDevice();\r\n    const isDesktop = width > 1024;\r\n\r\n    const widthChanged = this.prevWidth !== width;\r\n    const heightChanged = this.prevHeight !== height;\r\n    const heightDiff = Math.abs(this.prevHeight - height);\r\n    const scrollHeightChanged = this.context.data.viewport.contentHeight !== newScrollHeight;\r\n\r\n    const shouldRebuild =\r\n      widthChanged ||\r\n      (!isTouch && heightChanged) ||\r\n      (isTouch && heightDiff > 150) ||\r\n      scrollHeightChanged;\r\n\r\n    this.context.data.scroll.topPosition = Math.floor(newContainerTopPosition);\r\n    this.context.data.viewport.contentWidth = width;\r\n    this.context.data.viewport.contentHeight = newScrollHeight;\r\n\r\n    this.prevWidth = width;\r\n    this.prevHeight = height;\r\n\r\n    this.context.data.viewport.windowWidth = width;\r\n    this.context.data.viewport.windowHeight = height;\r\n\r\n    const htmlFontSize = window.getComputedStyle(document.documentElement).fontSize;\r\n    const fontSizeNumber = parseFloat(htmlFontSize);\r\n    this.context.data.viewport.baseRem = fontSizeNumber * transformScale;\r\n    this.syncDebugScrollState();\r\n\r\n    scroll.bottomPosition = this.context.data.viewport.contentHeight - height;\r\n\r\n    if (widthChanged || (typeof force === \"boolean\" && force)) {\r\n      this.moduleManager.onResizeWidth();\r\n    }\r\n    if (shouldRebuild || (typeof force === \"boolean\" && force)) {\r\n      const elementScrollTop = this.context.data.scroll.elementContainer.scrollTop;\r\n      if (elementScrollTop > 0) {\r\n        this.context.data.scroll.current = elementScrollTop;\r\n        this.context.data.scroll.target = elementScrollTop;\r\n      }\r\n\r\n      this.moduleManager.onResize();\r\n      if (this.scrollManager) {\r\n        this.scrollManager.updateResponsiveMode();\r\n      }\r\n      this.onSettingsChange({\r\n        isDesktop,\r\n        widthChanged,\r\n        heightChanged,\r\n        scrollHeightChanged,\r\n        isForceRebuild: force === true,\r\n      });\r\n      this.objectManager.invalidateInviewIndex();\r\n      this.moduleManager.onScroll();\r\n      this.moduleManager.onScrollMeasure();\r\n      this.moduleManager.onFrame();\r\n    }\r\n\r\n    this.objectManager.checkInview();\r\n  }\r\n\r\n  public invalidateCenter(id: string) {\r\n    this.objectManager.all.get(id) && this.centers.invalidate(id);\r\n  }\r\n\r\n  public scrollTo(position: number): void;\r\n  public scrollTo(selector: string): void;\r\n  public scrollTo(element: HTMLElement): void;\r\n  public scrollTo(\r\n    options:\r\n      | { position: number; immediate?: boolean; offset?: number }\r\n      | { selector: string; immediate?: boolean; offset?: number }\r\n      | { element: HTMLElement; immediate?: boolean; offset?: number },\r\n  ): void;\r\n  public scrollTo(\r\n    value:\r\n      | number\r\n      | string\r\n      | HTMLElement\r\n      | { position: number; immediate?: boolean; offset?: number }\r\n      | { selector: string; immediate?: boolean; offset?: number }\r\n      | { element: HTMLElement; immediate?: boolean; offset?: number },\r\n  ): void {\r\n    const resolved = this.resolveScrollToValue(value);\r\n    if (resolved == null) {\r\n      return;\r\n    }\r\n\r\n    this.scrollManager.get().scrollTo(resolved.position, resolved.immediate);\r\n  }\r\n\r\n  private resolveScrollToValue(\r\n    value:\r\n      | number\r\n      | string\r\n      | HTMLElement\r\n      | { position: number; immediate?: boolean; offset?: number }\r\n      | { selector: string; immediate?: boolean; offset?: number }\r\n      | { element: HTMLElement; immediate?: boolean; offset?: number },\r\n  ): { position: number; immediate: boolean } | null {\r\n    if (typeof value === \"number\") {\r\n      return { position: value, immediate: false };\r\n    }\r\n\r\n    if (typeof value === \"string\" || value instanceof HTMLElement) {\r\n      const position = this.resolveElementScrollPosition(value);\r\n      if (position == null) {\r\n        return null;\r\n      }\r\n      return { position, immediate: false };\r\n    }\r\n\r\n    const immediate = value.immediate === true;\r\n    const offset = value.offset ?? 0;\r\n\r\n    if (\"position\" in value) {\r\n      return {\r\n        position: value.position + offset,\r\n        immediate,\r\n      };\r\n    }\r\n\r\n    const target = \"selector\" in value ? value.selector : value.element;\r\n    const position = this.resolveElementScrollPosition(target);\r\n    if (position == null) {\r\n      return null;\r\n    }\r\n\r\n    return {\r\n      position: position + offset,\r\n      immediate,\r\n    };\r\n  }\r\n\r\n  private resolveElementScrollPosition(target: string | HTMLElement): number | null {\r\n    const element = typeof target === \"string\" ? document.querySelector(target) : target;\r\n\r\n    if (!(element instanceof HTMLElement)) {\r\n      return null;\r\n    }\r\n\r\n    const host = this.data.scroll.container ?? document.body ?? document.documentElement;\r\n    const scroller = this.data.scroll.elementContainer ?? document.documentElement;\r\n    const rect = this.tools.transformNullify.process({ element });\r\n\r\n    if (host === document.body || host === document.documentElement) {\r\n      return rect.top + scroller.scrollTop;\r\n    }\r\n\r\n    const hostRect = host.getBoundingClientRect();\r\n    return rect.top - hostRect.top + host.scrollTop;\r\n  }\r\n\r\n  public destroy() {\r\n    this.hasStarted = false;\r\n    this.data.scroll.scrollContainer?.removeEventListener(\"scroll\", this.onScrollBind);\r\n    this.data.scroll.container?.removeEventListener(\"wheel\", this.onWheelBind);\r\n\r\n    window.removeEventListener(\"resize\", this.onResizeBind);\r\n    this.root.removeEventListener(\"mousemove\", this.onMouseMoveBind);\r\n    this.eventManager.off(\"dom:changed\", this.onDOMChangedBind);\r\n    this.observerContainerMutation?.disconnect();\r\n    this.observerContainerMutation = null;\r\n    if (this.pendingResizeRaf != null) {\r\n      cancelAnimationFrame(this.pendingResizeRaf);\r\n      this.pendingResizeRaf = null;\r\n    }\r\n\r\n    this.objectManager.destroy();\r\n    this.scrollManager.destroy();\r\n    this.devtools.destroy();\r\n  }\r\n}\r\n\r\nexport {\r\n  StringTune as default,\r\n  StringCursor,\r\n  StringDelayLerpTracker,\r\n  StringFPSTracker,\r\n  StringGlide,\r\n  StringLazy,\r\n  StringLerp,\r\n  StringLerpTracker,\r\n  StringLoading,\r\n  StringForm,\r\n  StringImpulse,\r\n  // StringAttractor,\r\n  // StringMarquee,\r\n  StringMagnetic,\r\n  StringMasonry,\r\n  StringParallax,\r\n  StringPositionTracker,\r\n  StringProgress,\r\n  StringResponsive,\r\n  StringSpotlight,\r\n  // StringTilt,\r\n  // StringVelocity,\r\n  StringScrollbar,\r\n  // StringCircularText,\r\n  StringSplit,\r\n  StringAnchor,\r\n  StringTune as StringTune,\r\n  StringVideoAutoplay,\r\n  StringModule,\r\n  StringObject,\r\n  StringData,\r\n  StringSequence,\r\n  StringScroller,\r\n  StringProgressPart,\r\n  StringRandom,\r\n  CursorReactiveModule,\r\n  ScrollController,\r\n  StringScrollContainer,\r\n  StringDevLayout,\r\n  StringDevInview,\r\n  StringDevProgress,\r\n  StringDevModule,\r\n  StringDevOverlayRegistry,\r\n  StringDevIconRegistry,\r\n  StringDevRulers,\r\n  GridAdapter,\r\n  // StringInfiniteVirtual,\r\n  // StringInfiniteVirtualDOM,\r\n  // StringVirtualScroll,\r\n  // StringBitset,\r\n  // StringFilterEngine,\r\n  // StringFilterResult,\r\n  // StringFilterSchema,\r\n  // StringFilteredVirtualDataset,\r\n  // createFilterSchema,\r\n  // createFilteredVirtualDataset,\r\n  frameDOM,\r\n  styleTxn,\r\n  buildDevtoolsThemeBlock,\r\n  ensureStringDevtoolsSharedStyles,\r\n  resolveDevtoolsIcon,\r\n  type StringRulersTrigger,\r\n  type RulersTriggerAction,\r\n  type RulersLayoutGrid,\r\n  type StringDevStyleTokens,\r\n  type ScrollMarkRule as ScrollTriggerRule,\r\n  // type StringInfiniteVirtualDOMOptions,\r\n  // type StringVirtualScrollSetDataPayload,\r\n  // type StringVirtualScrollItemEventPayload,\r\n  // type StringVirtualScrollSetFilterPayload,\r\n  // type StringFilterExpression,\r\n  // type StringFilterFieldDefinition,\r\n  // type StringFilterFieldKind,\r\n  // type StringFilterIndexKind,\r\n  // type StringFilterPrimitive,\r\n  // type StringFilteredVirtualDatasetItem,\r\n  // type StringFilteredVirtualDatasetOptions,\r\n  // type StringInfiniteVirtualOptions,\r\n  // type StringInfiniteVirtualReachEvent,\r\n  // type StringInfiniteVirtualSnapshot,\r\n  type StringContext,\r\n  type StringDevtoolDefinition,\r\n  type StringDevtoolProvider,\r\n  type StringDevtoolState,\r\n  // type StringVirtualAlign,\r\n  // type StringVirtualAxis,\r\n  // type StringVirtualItem,\r\n  // type StringVirtualKey,\r\n  // type StringVirtualRange,\r\n};\r\n\r\n// Export performance utilities\r\nexport { DOMBatcher } from \"./core/managers/DOMBatcher\";\r\n","import { ISettingsChangeData } from \"../../models/event/ISettingsChangeData\";\r\nimport { CursorState } from \"../../states/CursorState\";\r\nimport { EventManager } from \"../managers/EventManager\";\r\nimport { StringContext } from \"../StringContext\";\r\nimport { StringData } from \"../StringData\";\r\nimport { StringToolsContainer } from \"../StringToolsContainer\";\r\n\r\nexport class CursorController {\r\n  protected context: StringContext;\r\n\r\n  private readonly SETTLE_THRESHOLD_SQ = 0.01;\r\n\r\n  private smoothingFactor: number;\r\n\r\n  private lastMouseX: number = 0;\r\n  private lastMouseY: number = 0;\r\n  private lastMouseTime: number = 0;\r\n\r\n  private _lerpStepXArgs = { from: 0, to: 0, progress: 0 };\r\n  private _lerpStepYArgs = { from: 0, to: 0, progress: 0 };\r\n\r\n  constructor(smoothing: number = 0.1, context: StringContext) {\r\n    this.smoothingFactor = smoothing;\r\n    this.context = context;\r\n\r\n    this.onSettingsChange({\r\n      isDesktop: context.data.viewport.windowWidth > 1024,\r\n      isForceRebuild: false,\r\n      widthChanged: true,\r\n      heightChanged: true,\r\n      scrollHeightChanged: true,\r\n    });\r\n  }\r\n\r\n  public onMouseMove(e: MouseEvent): void {\r\n    const cursorData = this.context.data.cursor;\r\n\r\n    cursorData.targetX = e.clientX;\r\n    cursorData.targetY = e.clientY;\r\n\r\n    const now = performance.now();\r\n\r\n    const dt = Math.max(1, now - this.lastMouseTime);\r\n\r\n    cursorData.velocityX = (e.clientX - this.lastMouseX) / dt;\r\n    cursorData.velocityY = (e.clientY - this.lastMouseY) / dt;\r\n\r\n    this.lastMouseX = e.clientX;\r\n    this.lastMouseY = e.clientY;\r\n    this.lastMouseTime = now;\r\n  }\r\n\r\n  public onFrame(): void {\r\n    const cursorData = this.context.data.cursor;\r\n\r\n    const tX = cursorData.targetX;\r\n    const tY = cursorData.targetY;\r\n    const sX = cursorData.smoothedX;\r\n    const sY = cursorData.smoothedY;\r\n\r\n    this._lerpStepXArgs.from = sX;\r\n    this._lerpStepXArgs.to = tX;\r\n    this._lerpStepXArgs.progress = this.smoothingFactor;\r\n\r\n    this._lerpStepYArgs.from = sY;\r\n    this._lerpStepYArgs.to = tY;\r\n    this._lerpStepYArgs.progress = this.smoothingFactor;\r\n\r\n    const stepX = this.context.tools.lerp.process(this._lerpStepXArgs);\r\n    const stepY = this.context.tools.lerp.process(this._lerpStepYArgs);\r\n    const distSq = stepX * stepX + stepY * stepY;\r\n    if (distSq < this.SETTLE_THRESHOLD_SQ) {\r\n      cursorData.smoothedX = tX;\r\n      cursorData.smoothedY = tY;\r\n      cursorData.stepX = 0;\r\n      cursorData.stepY = 0;\r\n    } else {\r\n      cursorData.smoothedX += stepX;\r\n      cursorData.smoothedY += stepY;\r\n      cursorData.stepX = stepX;\r\n      cursorData.stepY = stepY;\r\n    }\r\n  }\r\n\r\n  public onSettingsChange(data: ISettingsChangeData): void {\r\n    let lerp = Number(this.context.settings[\"cursor-lerp\"]);\r\n    this.setLerpFactor(lerp);\r\n  }\r\n\r\n  public setLerpFactor(t: number): void {\r\n    this.smoothingFactor = this.context.tools.adaptiveLerp.process({\r\n      value: t,\r\n      inMin: 0.1,\r\n      inMax: 1.0,\r\n      outMin: 0.05,\r\n      outMax: 0.65,\r\n    });\r\n  }\r\n}\r\n","import { EventCallback } from \"../../models/event/EventCallback\";\r\n\r\n/**\r\n * Manages custom event subscriptions and dispatching.\r\n * Allows multiple listeners per event and supports optional `id` suffixing.\r\n */\r\nexport class EventManager {\r\n  private listeners: Record<string, Set<EventCallback<any>>> = {};\r\n  private stateEvents: Set<string> = new Set();\r\n  private lastPayloads: Record<string, any> = {};\r\n\r\n  constructor() {\r\n    this.stateEvents.add(\"screen:mobile\");\r\n    this.stateEvents.add(\"screen:tablet\");\r\n    this.stateEvents.add(\"screen:laptop\");\r\n    this.stateEvents.add(\"screen:desktop\");\r\n    this.stateEvents.add(\"start\");\r\n  }\r\n\r\n  /**\r\n   * Marks an event as stateful so the last payload is cached and replayed to new listeners.\r\n   * Optionally seeds the initial payload.\r\n   */\r\n  registerStateEvent(eventName: string, initialPayload?: any): void {\r\n    this.stateEvents.add(eventName);\r\n    if (initialPayload !== undefined) {\r\n      this.lastPayloads[eventName] = initialPayload;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Subscribes to an event.\r\n   * Optionally appends an `id` to the event name for namespacing.\r\n   *\r\n   * @param eventName The base event name (e.g. \"scroll\", \"update\").\r\n   * @param callback The function to call when the event is emitted.\r\n   * @param id Optional unique identifier to scope the event (e.g. element ID).\r\n   */\r\n  on<T = any>(eventName: string, callback: EventCallback<T>, id?: string | null): void {\r\n    const fullEvent = id ? `${eventName}:${id}` : eventName;\r\n\r\n    if (!this.listeners[fullEvent]) {\r\n      this.listeners[fullEvent] = new Set();\r\n    }\r\n    this.listeners[fullEvent].add(callback);\r\n    if (this.stateEvents.has(fullEvent) && this.lastPayloads[fullEvent] !== undefined) {\r\n      callback(this.lastPayloads[fullEvent]);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Unsubscribes from a specific event listener.\r\n   * Must match the original `eventName`, `callback`, and optional `id`.\r\n   *\r\n   * @param eventName The base event name to unsubscribe from.\r\n   * @param callback The callback function to remove.\r\n   * @param id Optional identifier used when subscribing.\r\n   */\r\n  off<T = any>(eventName: string, callback: EventCallback<T>, id?: string): void {\r\n    const fullEvent = id ? `${eventName}:${id}` : eventName;\r\n\r\n    if (this.listeners[fullEvent]) {\r\n      this.listeners[fullEvent].delete(callback);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Emits an event with an optional payload.\r\n   * All matching listeners will be called.\r\n   *\r\n   * @param eventName The full event name (must include `id` if used).\r\n   * @param payload Optional data passed to event listeners.\r\n   */\r\n  emit<T = any>(eventName: string, payload?: T): void {\r\n    if (this.stateEvents.has(eventName)) {\r\n      this.lastPayloads[eventName] = payload;\r\n    }\r\n    const set = this.listeners[eventName];\r\n    if (!set) return;\r\n    for (const callback of set) {\r\n      callback(payload as T);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Subscribes to a per-object progress event.\r\n   * @param id The object ID.\r\n   * @param callback The callback to handle progress value.\r\n   */\r\n  onProgress(id: string, callback: EventCallback<number>): void {\r\n    this.on(`progress:${id}`, callback);\r\n  }\r\n\r\n  /**\r\n   * Emits a per-object progress event.\r\n   * @param id The object ID.\r\n   * @param value The progress value.\r\n   */\r\n  emitProgress(id: string, value: number): void {\r\n    this.emit(`progress:${id}`, value);\r\n  }\r\n\r\n  /**\r\n   * Subscribes to a per-object in-view event.\r\n   * @param id The object ID.\r\n   * @param callback The callback to handle visibility.\r\n   */\r\n  onInview(id: string, callback: EventCallback<boolean>): void {\r\n    this.on(`object:inview:${id}`, callback);\r\n  }\r\n\r\n  /**\r\n   * Emits a per-object in-view event.\r\n   * @param id The object ID.\r\n   * @param visible Whether the object is visible.\r\n   */\r\n  emitInview(id: string, visible: boolean): void {\r\n    this.emit(`object:inview:${id}`, visible);\r\n  }\r\n\r\n  /**\r\n   * Subscribes to the global scroll event.\r\n   * @param callback The callback to handle scroll value.\r\n   */\r\n  onScroll(callback: EventCallback<number>): void {\r\n    this.on(`scroll`, callback);\r\n  }\r\n\r\n  /**\r\n   * Emits the global scroll event.\r\n   * @param value The scroll value.\r\n   */\r\n  emitScroll(value: number): void {\r\n    this.emit(`scroll`, value);\r\n  }\r\n\r\n  /**\r\n   * Subscribes to the global update event.\r\n   * @param callback The callback to handle update.\r\n   */\r\n  onUpdate(callback: EventCallback<void>): void {\r\n    this.on(`update`, callback);\r\n  }\r\n\r\n  /**\r\n   * Emits the global update event.\r\n   */\r\n  emitUpdate(): void {\r\n    this.emit(`update`);\r\n  }\r\n\r\n  /**\r\n   * Clears all listeners for a specific event.\r\n   *\r\n   * @param eventName The full event name (including optional `id`).\r\n   */\r\n  clear(eventName: string): void {\r\n    delete this.listeners[eventName];\r\n  }\r\n\r\n  /**\r\n   * Clears all registered events.\r\n   */\r\n  clearAll(): void {\r\n    this.listeners = {};\r\n  }\r\n}\r\n","import { StringData } from \"../..\";\r\nimport { ISettingsChangeData } from \"../../models/event/ISettingsChangeData\";\r\nimport { IStringModule } from \"../IStringModule\";\r\nimport { StringModule } from \"../StringModule\";\r\n\r\ntype LifecycleName =\r\n  | \"destroy\"\r\n  | \"onSubscribe\"\r\n  | \"onUnsubscribe\"\r\n  | \"onInit\"\r\n  | \"onFrame\"\r\n  | \"onMutate\"\r\n  | \"onScrollMeasure\"\r\n  | \"onMouseMoveMeasure\"\r\n  | \"onScroll\"\r\n  | \"onResizeWidth\"\r\n  | \"onResize\"\r\n  | \"onMouseMove\"\r\n  | \"onWheel\"\r\n  | \"onDirectionChange\"\r\n  | \"onScrollStart\"\r\n  | \"onScrollStop\"\r\n  | \"onScrollMeasure\"\r\n  | \"onMouseMoveMeasure\"\r\n  | \"onScroll\"\r\n  | \"onResizeWidth\"\r\n  | \"onResize\"\r\n  | \"onMouseMove\"\r\n  | \"onWheel\"\r\n  | \"onDirectionChange\"\r\n  | \"onScrollStart\"\r\n  | \"onScrollStop\"\r\n  | \"onAxisChange\"\r\n  | \"onDeviceChange\"\r\n  | \"onScrollConfigChange\"\r\n  | \"onSettingsChange\"\r\n  | \"onDOMMutate\";\r\n\r\nexport class ModuleManager {\r\n  private modules: StringModule[] = [];\r\n  private uiModules: StringModule[] = [];\r\n  private allModules: StringModule[] = [];\r\n\r\n  constructor(private data: StringData) { }\r\n\r\n  register(module: StringModule): void {\r\n    if (module.type === 1) {\r\n      this.modules.push(module);\r\n    } else if (module.type === 2) {\r\n      this.uiModules.push(module);\r\n    }\r\n\r\n    if (module.cssProperties && module.cssProperties.length > 0) {\r\n      if (typeof window.CSS !== \"undefined\" && \"registerProperty\" in window.CSS) {\r\n        for (let i = 0; i < module.cssProperties.length; i++) {\r\n          try {\r\n            (window.CSS as any).registerProperty(module.cssProperties[i]);\r\n          } catch (e) {\r\n            // Property might already be registered by another instance of the same module type\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    module.onSubscribe();\r\n    this.rebuildAllModules();\r\n  }\r\n\r\n  find<T>(type: new (...args: any[]) => T): T | undefined {\n    for (let i = 0; i < this.allModules.length; i++) {\n      const module = this.allModules[i];\n      if (module instanceof type) {\n        return module as T;\n      }\n    }\n    return undefined;\n  }\r\n\r\n  onInit(): void {\r\n    this.callAll(\"onInit\");\r\n  }\r\n\r\n  onFrame(): void {\r\n    this.callAll(\"onFrame\");\r\n  }\r\n\r\n  onMutate(): void {\r\n    this.callAll(\"onMutate\");\r\n  }\r\n\r\n  onScrollMeasure(): void {\r\n    this.callAll(\"onScrollMeasure\");\r\n  }\r\n\r\n  onMouseMoveMeasure(): void {\r\n    this.callAll(\"onMouseMoveMeasure\");\r\n  }\r\n\r\n  onScroll(): void {\r\n    this.callAll(\"onScroll\");\r\n  }\r\n\r\n  onResizeWidth(): void {\r\n    this.callAll(\"onResizeWidth\");\r\n  }\r\n\r\n  onResize(): void {\r\n    this.callAll(\"onResize\");\r\n  }\r\n\r\n  onMouseMove(e: MouseEvent): void {\r\n    this.callAll(\"onMouseMove\", e);\r\n  }\r\n\r\n  onWheel(e: WheelEvent): void {\r\n    this.callAll(\"onWheel\", e);\r\n  }\r\n\r\n  onDirectionChange(): void {\r\n    this.callAll(\"onDirectionChange\");\r\n  }\r\n\r\n  onScrollStart(): void {\r\n    this.callAll(\"onScrollStart\");\r\n  }\r\n\r\n  onScrollStop(): void {\r\n    this.callAll(\"onScrollStop\");\r\n  }\r\n\r\n  onAxisChange(): void {\r\n    this.callAll(\"onAxisChange\");\r\n  }\r\n\r\n  onDeviceChange(): void {\r\n    this.callAll(\"onDeviceChange\");\r\n  }\r\n\r\n  onScrollConfigChange(): void {\r\n    this.callAll(\"onScrollConfigChange\");\r\n  }\r\n\r\n  onSettingsChange(_data: ISettingsChangeData): void {\r\n    this.callAll(\"onSettingsChange\");\r\n  }\r\n\r\n  onDOMMutate(added: NodeList, removed: NodeList): void {\r\n    this.callAll(\"onDOMMutate\", added, removed);\r\n  }\r\n\r\n  destroy(): void {\r\n    this.callAll(\"onUnsubscribe\");\r\n    this.callAll(\"destroy\");\r\n    this.modules = [];\r\n    this.uiModules = [];\r\n    this.allModules = [];\r\n  }\r\n\r\n  get all(): IStringModule[] {\r\n    return this.allModules;\r\n  }\r\n\r\n  get core(): IStringModule[] {\r\n    return this.modules;\r\n  }\r\n\r\n  get ui(): IStringModule[] {\r\n    return this.uiModules;\r\n  }\r\n\r\n  private callAll(lifecycle: LifecycleName, arg?: unknown, arg2?: unknown): void {\r\n    if (this.modules.length > 0) {\r\n      this.callLifecycleStrict(this.modules, lifecycle, arg, arg2);\r\n    }\r\n    if (this.uiModules.length > 0) {\r\n      this.callLifecycleStrict(this.uiModules, lifecycle, arg, arg2);\r\n    }\r\n  }\r\n\r\n  private callLifecycleStrict(\r\n    modules: StringModule[],\r\n    lifecycle: LifecycleName,\r\n    arg?: unknown,\r\n    arg2?: unknown\r\n  ): void {\r\n    const len = modules.length;\r\n\r\n    switch (lifecycle) {\r\n      case \"onFrame\":\r\n      case \"onMutate\":\r\n      case \"onScrollMeasure\":\r\n      case \"onMouseMoveMeasure\":\r\n      case \"onScroll\":\r\n        // Single argument: StringData\r\n        for (let i = 0; i < len; i++) {\r\n          const mod = modules[i];\r\n          if (mod) (mod as any)[lifecycle](this.data);\r\n        }\r\n        break;\r\n\r\n      case \"onDOMMutate\":\r\n        // Two arguments: addedNodes, removedNodes\r\n        for (let i = 0; i < len; i++) {\r\n          const mod = modules[i];\r\n          if (mod) (mod as any)[lifecycle](arg, arg2);\r\n        }\r\n        break;\r\n\r\n      case \"onMouseMove\":\r\n      case \"onWheel\":\r\n        // Single argument: Event\r\n        for (let i = 0; i < len; i++) {\r\n          const mod = modules[i];\r\n          if (mod) (mod as any)[lifecycle](arg);\r\n        }\r\n        break;\r\n\r\n      default:\r\n        // No arguments\r\n        for (let i = 0; i < len; i++) {\r\n          const mod = modules[i];\r\n          if (mod) (mod as any)[lifecycle]();\r\n        }\r\n        break;\r\n    }\r\n  }\r\n\r\n  private rebuildAllModules(): void {\r\n    this.allModules.length = 0;\r\n    for (let i = 0; i < this.modules.length; i++) {\r\n      this.allModules.push(this.modules[i]);\r\n    }\r\n    for (let i = 0; i < this.uiModules.length; i++) {\r\n      this.allModules.push(this.uiModules[i]);\r\n    }\r\n  }\r\n}\r\n","import type { StringObject } from \"./StringObject\";\r\n\r\nexport type MirrorEasingFn = (value: number) => number;\r\n\r\n/**\r\n * Lightweight wrapper that mirrors a primary StringObject while keeping\r\n * its own easing and state. Intended for elements linked via\r\n * `[string-copy-from]`.\r\n */\r\nexport class StringMirrorObject {\r\n  public readonly id: string;\r\n  public readonly htmlElement: HTMLElement;\r\n\r\n  private properties = new Map<string, any>();\r\n  private easingFn?: MirrorEasingFn;\r\n\r\n  constructor(id: string, element: HTMLElement, private parent: StringObject) {\r\n    this.id = id;\r\n    this.htmlElement = element;\r\n  }\r\n\r\n  public get parentObject(): StringObject {\r\n    return this.parent;\r\n  }\r\n\r\n  public setProperty<T>(key: string, value: T): void {\r\n    this.properties.set(key, value);\r\n  }\r\n\r\n  public getProperty<T>(key: string): T {\r\n    return this.properties.get(key) ?? null;\r\n  }\r\n\r\n  public setEasing(easing: MirrorEasingFn | null | undefined): void {\r\n    this.easingFn = easing ?? undefined;\r\n  }\r\n\r\n  public getEasing(): MirrorEasingFn | undefined {\r\n    return this.easingFn;\r\n  }\r\n\r\n  /**\r\n   * Returns eased progress using mirror easing (if set) or fallback.\r\n   */\r\n  public applyProgress(rawProgress: number, fallback?: MirrorEasingFn): number {\r\n    const easing = this.easingFn ?? fallback;\r\n    return easing ? easing(rawProgress) : rawProgress;\r\n  }\r\n}\r\n","import { IStringModule } from \"../core/IStringModule\";\r\nimport { EventManager } from \"../core/managers/EventManager\";\r\nimport { StringToken } from \"../models/string/StringToken\";\r\nimport { StringMirrorObject } from \"./StringMirrorObject\";\r\n\r\n/**\r\n * Internal class representing a DOM-bound interactive object.\r\n * Connected to modules and holds its own internal state.\r\n */\r\nexport class StringObject {\r\n  /**\r\n   * The DOM element this object wraps.\r\n   */\r\n  public htmlElement: HTMLElement;\r\n\r\n  /**\r\n   * Unique global ID assigned by the system.\r\n   */\r\n  public id: string = \"\";\r\n\r\n  /**\r\n   * Space-separated list of all attribute keys associated with this object.\r\n   */\r\n  public keys: string[] = [];\r\n  public tokens: StringToken[] = [];\r\n\r\n  /**\r\n   * Mirror objects linked via `string-copy-from`.\r\n   */\r\n  private mirrors = new Map<string, StringMirrorObject>();\r\n  private _cachedMirrorObjects: StringMirrorObject[] = [];\r\n  private _cachedConnects: HTMLElement[] = [];\r\n  private _mirrorsDirty: boolean = false;\r\n\r\n  /**\r\n   * Internal key-value store of dynamic object properties (like offsets, progress, etc.).\r\n   */\r\n  private properties: Map<string, any> = new Map();\r\n\r\n  /**\r\n   * Modules currently connected to this object.\r\n   */\r\n  private modules: IStringModule[] = [];\r\n\r\n  /**\r\n   * Manages and handles events for the object.\r\n   * Provides functionality to register, trigger, and manage event listeners.\r\n   */\r\n  events: EventManager = new EventManager();\r\n  private eventNameCache: Map<string, string> = new Map();\r\n  private eventNameSuffixCache: Map<string, Map<string, string>> = new Map();\r\n\r\n  constructor(id: string, element: HTMLElement) {\r\n    this.htmlElement = element;\r\n    this.id = id;\r\n  }\r\n\r\n  /**\r\n   * Returns a cached event name in one of these forms:\r\n   * - `${prefix}:${id}`\r\n   * - `${prefix}:${id}:${suffix}`\r\n   */\r\n  public getScopedEventName(prefix: string, suffix?: string): string {\r\n    if (suffix == null) {\r\n      const cached = this.eventNameCache.get(prefix);\r\n      if (cached) {\r\n        return cached;\r\n      }\r\n\r\n      const eventName = `${prefix}:${this.id}`;\r\n      this.eventNameCache.set(prefix, eventName);\r\n      return eventName;\r\n    }\r\n\r\n    let suffixMap = this.eventNameSuffixCache.get(prefix);\r\n    if (!suffixMap) {\r\n      suffixMap = new Map<string, string>();\r\n      this.eventNameSuffixCache.set(prefix, suffixMap);\r\n    }\r\n\r\n    const cachedWithSuffix = suffixMap.get(suffix);\r\n    if (cachedWithSuffix) {\r\n      return cachedWithSuffix;\r\n    }\r\n\r\n    const eventName = `${prefix}:${this.id}:${suffix}`;\r\n    suffixMap.set(suffix, eventName);\r\n    return eventName;\r\n  }\r\n\r\n  /**\r\n   * Stores a property value for this object.\r\n   * @param key - Property name\r\n   * @param value - Value to store\r\n   */\r\n  public setProperty<T>(key: string, value: T): void {\r\n    this.properties.set(key, value);\r\n  }\r\n\r\n  /**\r\n   * Retrieves a previously stored property value.\r\n   * @param key - Property name\r\n   * @returns The value or null if not set\r\n   */\r\n  public getProperty<T>(key: string): T {\r\n    return this.properties.get(key) ?? null;\r\n  }\r\n\r\n  /**\r\n   * Marks this object as \"active\" (usually on intersection/scroll enter).\r\n   */\r\n  public enter(): void {\r\n    this.events.emit(\"enter\", this);\r\n    this.setProperty(\"active\", true);\r\n    this.modules.forEach((module) => {\r\n      module.enterObject(this.id, this);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Marks this object as \"inactive\" (usually on intersection/scroll leave).\r\n   */\r\n  public leave(): void {\r\n    this.events.emit(\"leave\", this);\r\n    this.setProperty(\"active\", false);\r\n    this.modules.forEach((module) => {\r\n      module.exitObject(this.id);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Removes the current object by iterating through all associated modules\r\n   * and invoking their `removeObject` method with the object's ID.\r\n   *\r\n   * This method ensures that the object is properly removed from all\r\n   * modules it is associated with.\r\n   */\r\n  public remove(): void {\r\n    this.modules.forEach((module) => {\r\n      module.removeObject(this.id);\r\n    });\r\n  }\r\n\r\n  public setInviewAutoBlocked(blocked: boolean): void {\r\n    this.setProperty(\"inview-auto-blocked\", blocked);\r\n  }\r\n\r\n  public isInviewAutoBlocked(): boolean {\r\n    return this.getProperty<boolean>(\"inview-auto-blocked\") === true;\r\n  }\r\n\r\n  public setInviewManualActive(active: boolean): void {\r\n    this.setProperty(\"inview-manual-active\", active);\r\n  }\r\n\r\n  public isInviewManualActive(): boolean {\r\n    return this.getProperty<boolean>(\"inview-manual-active\") === true;\r\n  }\r\n\r\n  public syncInviewClass(): void {\r\n    if (this.isInviewAutoBlocked()) {\r\n      this.htmlElement.classList.remove(\"-inview\");\r\n      return;\r\n    }\r\n\r\n    if (this.isInviewManualActive()) {\r\n      this.htmlElement.classList.add(\"-inview\");\r\n      return;\r\n    }\r\n\r\n    const isInView = this.getProperty<boolean>(\"is-inview\") === true;\r\n    if (isInView) {\r\n      this.htmlElement.classList.add(\"-inview\");\r\n      return;\r\n    }\r\n\r\n    const shouldRepeat = this.getProperty<boolean>(\"repeat\");\r\n    if (shouldRepeat) {\r\n      this.htmlElement.classList.remove(\"-inview\");\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Shows the object, applies visual class and notifies connected modules.\r\n   */\r\n  public show(): void {\r\n    if (this.isInviewAutoBlocked()) {\r\n      return;\r\n    }\r\n    this.htmlElement.classList.add(\"-inview\");\r\n  }\r\n\r\n  /**\r\n   * Hides the object, removes visual class (if repeat is enabled), and notifies modules.\r\n   */\r\n  public hide(): void {\r\n    if (this.isInviewAutoBlocked()) {\r\n      this.htmlElement.classList.remove(\"-inview\");\r\n      return;\r\n    }\r\n\r\n    if (this.isInviewManualActive()) {\r\n      return;\r\n    }\r\n\r\n    const shouldRepeat = this.getProperty<boolean>(\"repeat\");\r\n    if (shouldRepeat) {\r\n      this.htmlElement.classList.remove(\"-inview\");\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Connects a module to this object if not already connected.\r\n   * @param module - The module to connect\r\n   */\r\n  public connect(module: IStringModule): boolean {\r\n    if (!this.modules.includes(module)) {\r\n      this.modules.push(module);\r\n      return true;\r\n    }\r\n    return false;\r\n  }\r\n\r\n  public disconnect(module: IStringModule): boolean {\r\n    const index = this.modules.indexOf(module);\r\n    if (index === -1) {\r\n      return false;\r\n    }\r\n    this.modules.splice(index, 1);\r\n    return true;\r\n  }\r\n\r\n  public isConnectedTo(module: IStringModule): boolean {\r\n    return this.modules.includes(module);\r\n  }\r\n\r\n  public setTokens(tokens: StringToken[]): void {\r\n    this.tokens = tokens;\r\n    this.keys = tokens.map((token) => token.key);\r\n  }\r\n\r\n  public getToken(key: string): StringToken | null {\r\n    for (let i = 0; i < this.tokens.length; i++) {\r\n      if (this.tokens[i].key === key) {\r\n        return this.tokens[i];\r\n      }\r\n    }\r\n    return null;\r\n  }\r\n\r\n  private updateMirrorsCache(): void {\r\n    if (this._mirrorsDirty) {\r\n      this._cachedMirrorObjects = Array.from(this.mirrors.values());\r\n      const len = this._cachedMirrorObjects.length;\r\n      this._cachedConnects = new Array(len);\r\n      for (let i = 0; i < len; i++) {\r\n        this._cachedConnects[i] = this._cachedMirrorObjects[i].htmlElement;\r\n      }\r\n      this._mirrorsDirty = false;\r\n    }\r\n  }\r\n\r\n  public addMirror(mirror: StringMirrorObject): void {\r\n    if (!this.mirrors.has(mirror.id)) {\r\n      this.mirrors.set(mirror.id, mirror);\r\n      this._mirrorsDirty = true;\r\n    }\r\n  }\r\n\r\n  public removeMirror(id: string): void {\r\n    if (this.mirrors.delete(id)) {\r\n      this._mirrorsDirty = true;\r\n    }\r\n  }\r\n\r\n  public get mirrorObjects(): StringMirrorObject[] {\r\n    this.updateMirrorsCache();\r\n    return this._cachedMirrorObjects;\r\n  }\r\n\r\n  public get connects(): HTMLElement[] {\r\n    this.updateMirrorsCache();\r\n    return this._cachedConnects;\r\n  }\r\n}\r\n","import { StringObject } from \"../../objects/StringObject\";\r\nimport { StringModule } from \"../StringModule\";\r\n\r\ninterface BatchTask {\r\n  priority: number;\r\n  execute: () => void;\r\n}\r\n\r\ninterface ModuleBatchContext {\r\n  module: StringModule;\r\n  object: StringObject;\r\n  element: HTMLElement;\r\n  attributes: Record<string, any>;\r\n  globalId: number;\r\n  windowSize: number;\r\n}\r\n\r\nexport class DOMBatcher {\r\n  private readQueue: BatchTask[] = [];\r\n  private writeQueue: BatchTask[] = [];\r\n  private computeQueue: BatchTask[] = [];\r\n  private isProcessing = false;\r\n  private pendingFrame: number | null = null;\r\n  private rectCache = new WeakMap<HTMLElement, DOMRect>();\r\n  private dimensionCache = new WeakMap<HTMLElement, { width: number; height: number }>();\r\n\r\n  public scheduleRead(task: () => void, priority: number = 0): void {\r\n    this.readQueue.push({ priority, execute: task });\r\n    this.scheduleFlush();\r\n  }\r\n\r\n  public scheduleCompute(task: () => void, priority: number = 0): void {\r\n    this.computeQueue.push({ priority, execute: task });\r\n    this.scheduleFlush();\r\n  }\r\n\r\n  public scheduleWrite(task: () => void, priority: number = 0): void {\r\n    this.writeQueue.push({ priority, execute: task });\r\n    this.scheduleFlush();\r\n  }\r\n\r\n  public batchModuleInitialization(contexts: ModuleBatchContext[]): void {\r\n    contexts.forEach(({ module, object, element, attributes, globalId }) => {\r\n      this.scheduleRead(() => {\r\n        const rect = element.getBoundingClientRect();\r\n        this.rectCache.set(element, rect);\r\n        this.dimensionCache.set(element, {\r\n          width: element.offsetWidth || element.clientWidth || rect.width,\r\n          height: element.offsetHeight || element.clientHeight || rect.height,\r\n        });\r\n        module.initializeObject(globalId, object, element, attributes);\r\n      }, 1);\r\n    });\r\n\r\n    contexts.forEach(({ module, object, windowSize }) => {\r\n      this.scheduleCompute(() => {\r\n        module.calculatePositions(object, windowSize);\r\n      }, 2);\r\n    });\r\n\r\n    contexts.forEach(({ module, object }) => {\r\n      this.scheduleWrite(() => {\r\n        module.connectObject(object);\r\n        module.addObject(object.id, object);\r\n      }, 3);\r\n    });\r\n  }\r\n\r\n  public getCachedRect(element: HTMLElement): DOMRect | undefined {\r\n    return this.rectCache.get(element);\r\n  }\r\n\r\n  public getCachedDimensions(element: HTMLElement): { width: number; height: number } | undefined {\r\n    return this.dimensionCache.get(element);\r\n  }\r\n\r\n  private scheduleFlush(): void {\r\n    if (this.pendingFrame !== null || this.isProcessing) {\r\n      return;\r\n    }\r\n    this.pendingFrame = requestAnimationFrame(() => {\r\n      this.flush();\r\n    });\r\n  }\r\n\r\n  private flush(): void {\r\n    this.isProcessing = true;\r\n    this.pendingFrame = null;\r\n    const sortByPriority = (a: BatchTask, b: BatchTask) => b.priority - a.priority;\r\n\r\n    try {\r\n      const reads = [...this.readQueue].sort(sortByPriority);\r\n      reads.forEach((task) => {\r\n        try {\r\n          task.execute();\r\n        } catch (error) {\r\n          console.error(\"[DOMBatcher] Read task error:\", error);\r\n        }\r\n      });\r\n      this.readQueue = [];\r\n\r\n      const computes = [...this.computeQueue].sort(sortByPriority);\r\n      computes.forEach((task) => {\r\n        try {\r\n          task.execute();\r\n        } catch (error) {\r\n          console.error(\"[DOMBatcher] Compute task error:\", error);\r\n        }\r\n      });\r\n      this.computeQueue = [];\r\n\r\n      const writes = [...this.writeQueue].sort(sortByPriority);\r\n      writes.forEach((task) => {\r\n        try {\r\n          task.execute();\r\n        } catch (error) {\r\n          console.error(\"[DOMBatcher] Write task error:\", error);\r\n        }\r\n      });\r\n      this.writeQueue = [];\r\n    } finally {\r\n      this.rectCache = new WeakMap();\r\n      this.dimensionCache = new WeakMap();\r\n      this.isProcessing = false;\r\n    }\r\n  }\r\n\r\n  public flushSync(): void {\r\n    if (this.pendingFrame !== null) {\r\n      cancelAnimationFrame(this.pendingFrame);\r\n      this.pendingFrame = null;\r\n    }\r\n    this.flush();\r\n  }\r\n\r\n  public clear(): void {\r\n    if (this.pendingFrame !== null) {\r\n      cancelAnimationFrame(this.pendingFrame);\r\n      this.pendingFrame = null;\r\n    }\r\n    this.readQueue = [];\r\n    this.writeQueue = [];\r\n    this.computeQueue = [];\r\n    this.rectCache = new WeakMap();\r\n    this.dimensionCache = new WeakMap();\r\n  }\r\n}\r\n","export interface ModuleLifecyclePermissionsItem {\r\n  rebuild: {\r\n    width: boolean;\r\n    height: boolean;\r\n    scrollHeight: boolean;\r\n  };\r\n}\r\nexport class ModuleLifecyclePermissions {\r\n  desktop: ModuleLifecyclePermissionsItem = {\r\n    rebuild: {\r\n      width: true,\r\n      height: true,\r\n      scrollHeight: true,\r\n    },\r\n  };\r\n  mobile: ModuleLifecyclePermissionsItem = {\r\n    rebuild: {\r\n      width: true,\r\n      height: true,\r\n      scrollHeight: true,\r\n    },\r\n  };\r\n}\r\n","import { IStringModule } from \"./IStringModule\";\r\nimport { StringObject } from \"../objects/StringObject\";\r\nimport { StringMirrorObject } from \"../objects/StringMirrorObject\";\r\nimport { StringToolsContainer } from \"./StringToolsContainer\";\r\nimport { StringData } from \"./StringData\";\r\nimport { AttributeType } from \"../models/attribute/AttributeType\";\r\nimport { StringContext } from \"./StringContext\";\r\nimport { EventManager } from \"./managers/EventManager\";\r\nimport { AttributeMapping } from \"../models/attribute/AttributeMapping\";\r\nimport { ModuleLifecyclePermissions } from \"../models/IModuleLifecyclePermissions\";\r\nimport { StringToken } from \"../models/string/StringToken\";\r\nimport { CenterCache } from \"./managers/CenterCache\";\r\nimport { HoverTracker } from \"./managers/HoverTracker\";\r\nimport { ObjectManager } from \"./managers/ObjectManager\";\r\nimport { ScrollMode } from \"../states/ScrollState\";\r\n\r\nconst EMPTY_CONTEXT = Object.freeze({});\r\n\r\ninterface ParseContext {\r\n  element?: HTMLElement;\r\n  boundingRect?: DOMRect;\r\n  viewportHeight?: number;\r\n  baseRem?: number;\r\n}\r\n\r\n/**\r\n * Base class for a module used in the string-tune system.\r\n * Extend this class to create custom modules that respond to scroll, resize, input, etc.\r\n */\r\nexport class StringModule implements IStringModule {\r\n  /**\r\n   * List of attribute names this module should automatically read\r\n   * from the DOM element and assign to the object properties.\r\n   * Example: [\"offset-top\", \"offset-bottom\"]\r\n   */\r\n  protected attributesToMap: AttributeMapping[];\r\n\r\n  /**\r\n   * Defines CSS Custom Properties (Houdini) strictly required by this module.\r\n   * ModuleManager will automatically register these properties on initialization\r\n   * for Typed Object Model hardware acceleration.\r\n   */\r\n  public cssProperties: Array<{\r\n    name: string;\r\n    syntax: string;\r\n    initialValue: string;\r\n    inherits: boolean;\r\n  }> = [];\r\n\r\n  /**\r\n   * A map that associates string keys with `StringObject` instances.\r\n   * This map is used to manage and track `StringObject` instances on a page.\r\n   */\r\n  protected objectMapOnPage: Map<string, StringObject> = new Map();\r\n  protected allObjectMapOnPage: Map<string, StringObject> = new Map();\r\n\r\n  /**\r\n   * A protected array that holds the collection of `StringObject` instances\r\n   * currently present on the page.\r\n   */\r\n  protected objectsOnPage: StringObject[] = [];\r\n  protected allObjectsOnPage: StringObject[] = [];\r\n\r\n  /**\r\n   * A map of all entered objects by their unique ID.\r\n   */\r\n  protected objectMap: Map<string, StringObject> = new Map();\r\n  protected allObjectMap: Map<string, StringObject> = new Map();\r\n\r\n  /**\r\n   * A flat array of all connected objects.\r\n   */\r\n  protected objects: StringObject[] = [];\r\n  protected allObjects: StringObject[] = [];\r\n\r\n  /**\r\n   * The HTML attribute key that identifies objects this module is responsible for.\r\n   */\r\n  protected htmlKey: string = \"\";\r\n  protected defaultModeScope: \"all\" | ScrollMode[] = \"all\";\r\n\r\n  /**\r\n   * Module type ID used internally to categorize module behavior.\r\n   */\r\n  protected _type: number = 1;\r\n\r\n  /**\r\n   * Returns the type of the module.\r\n   * Type 1 = core module, type 2 = UI module.\r\n   */\r\n  public get type(): number {\r\n    return this._type;\r\n  }\r\n\r\n  public get key(): string {\r\n    return this.htmlKey;\r\n  }\r\n\r\n  /**\r\n   * Tools container providing utilities for attribute parsing, unit conversion, etc.\r\n   * Acts as a dependency injection hub for core IStringTool implementations.\r\n   */\r\n  protected tools: StringToolsContainer;\r\n\r\n  /**\r\n   * Shared global data object containing scroll state, viewport info, cursor position, etc.\r\n   * Used for calculations within lifecycle hooks like `onScroll`, `onFrame`, and `onResize`.\r\n   */\r\n  protected data: StringData;\r\n\r\n  /**\r\n   * Configuration object specific to the current module.\r\n   * Passed in during module registration or initialization.\r\n   */\r\n  protected settings: Record<string, any>;\r\n\r\n  /**\r\n   * Event hub for communication between modules or systems.\r\n   * Supports custom event emitting, listening, and unsubscription.\r\n   */\r\n  protected events: EventManager;\r\n\r\n  /**\r\n   * Cache for storing and managing object centers.\r\n   */\r\n  protected centers: CenterCache;\r\n\r\n  /**\r\n   * Tracker for managing hover states of objects.\r\n   */\r\n  protected hover: HoverTracker;\r\n\r\n  /**\r\n   * Object manager for layout refreshes and in-view recalculation.\r\n   */\r\n  protected objectManager: ObjectManager;\r\n\r\n  public permissions: ModuleLifecyclePermissions = new ModuleLifecyclePermissions();\r\n\r\n  constructor(context: StringContext) {\r\n    this.tools = context.tools;\r\n    this.data = context.data;\r\n    this.settings = context.settings;\r\n    this.events = context.events;\r\n    this.centers = context.centers;\r\n    this.hover = context.hover;\r\n    this.objectManager = context.objectManager;\r\n\r\n    this.attributesToMap = [\r\n      { key: \"active\", type: \"boolean\", fallback: this.settings[\"active\"] },\r\n      { key: \"fixed\", type: \"boolean\", fallback: this.settings[\"fixed\"] },\r\n      { key: \"outside-container\", type: \"boolean\", fallback: this.settings[\"outside-container\"] },\r\n      { key: \"repeat\", type: \"boolean\", fallback: this.settings[\"repeat\"] },\r\n      {\r\n        key: \"self-disable\",\r\n        type: \"boolean\",\r\n        fallback: this.settings[\"self-disable\"],\r\n      },\r\n      { key: \"abs\", type: \"boolean\", fallback: this.settings[\"abs\"] },\r\n      { key: \"key\", type: \"string\", fallback: this.settings[\"key\"] },\r\n      {\r\n        key: \"offset-top\",\r\n        type: \"dimension\",\r\n        fallback: this.settings[\"offset-top\"],\r\n      },\r\n      {\r\n        key: \"offset-bottom\",\r\n        type: \"dimension\",\r\n        fallback: this.settings[\"offset-bottom\"],\r\n      },\r\n      {\r\n        key: \"offset-enter\",\r\n        type: \"dimension\",\r\n        fallback: this.settings[\"offset-enter\"],\r\n      },\r\n      {\r\n        key: \"offset-exit\",\r\n        type: \"dimension\",\r\n        fallback: this.settings[\"offset-exit\"],\r\n      },\r\n      {\r\n        key: \"inview-top\",\r\n        type: \"dimension\",\r\n        fallback: this.settings[\"inview-top\"],\r\n      },\r\n      {\r\n        key: \"inview-bottom\",\r\n        type: \"dimension\",\r\n        fallback: this.settings[\"inview-bottom\"],\r\n      },\r\n      {\r\n        key: \"start\",\r\n        type: \"number\",\r\n        fallback: (element: HTMLElement, object: StringObject, boundingRect: DOMRect) => {\r\n          const top = boundingRect.top;\r\n          return Math.floor(top) + this.data.scroll.transformedCurrent;\r\n        },\r\n      },\r\n      {\r\n        key: \"end\",\r\n        type: \"number\",\r\n        fallback: (element: HTMLElement, object: StringObject, boundingRect: DOMRect) => {\r\n          const top = boundingRect.top;\r\n          const height = boundingRect.height;\r\n          return top + height - this.data.scroll.transformedCurrent;\r\n        },\r\n      },\r\n      {\r\n        key: \"size\",\r\n        type: \"number\",\r\n        fallback: (element: HTMLElement, object: StringObject, boundingRect: DOMRect) => {\r\n          return boundingRect.height;\r\n        },\r\n      },\r\n      {\r\n        key: \"half-width\",\r\n        type: \"number\",\r\n        fallback: (element: HTMLElement, object: StringObject, boundingRect: DOMRect) => {\r\n          return boundingRect.width / 2;\r\n        },\r\n      },\r\n      {\r\n        key: \"half-height\",\r\n        type: \"number\",\r\n        fallback: (element: HTMLElement, object: StringObject, boundingRect: DOMRect) => {\r\n          return boundingRect.height / 2;\r\n        },\r\n      },\r\n      { key: \"enter-el\", type: \"string\", fallback: this.settings[\"enter-el\"] },\r\n      { key: \"enter-vp\", type: \"string\", fallback: this.settings[\"enter-vp\"] },\r\n      { key: \"exit-el\", type: \"string\", fallback: this.settings[\"exit-el\"] },\r\n      { key: \"exit-vp\", type: \"string\", fallback: this.settings[\"exit-vp\"] },\r\n    ];\r\n  }\r\n\r\n  /**\r\n   * Initializes a `StringObject` by mapping attributes from an HTML element\r\n   * and applying transformations as needed.\r\n   *\r\n   * @param globalId - A unique identifier for the object being initialized.\r\n   * @param object - The `StringObject` instance to be initialized.\r\n   * @param element - The HTML element from which attributes are extracted.\r\n   * @param attributes - A record of additional attributes to be used during initialization.\r\n   *\r\n   * The method performs the following steps:\r\n   * 1. Retrieves the bounding rectangle of the provided HTML element.\r\n   * 2. Iterates over a predefined list of attributes to map.\r\n   * 3. Resolves fallback values for attributes, either from the provided attributes,\r\n   *    settings, or a fallback function.\r\n   * 4. Processes and parses the raw attribute values based on their expected type.\r\n   * 5. Applies optional transformations to the parsed values.\r\n   * 6. Sets the processed attributes as properties on the `StringObject` instance.\r\n   */\r\n  initializeObject(\r\n    globalId: number,\r\n    object: StringObject,\r\n    element: HTMLElement,\r\n    attributes: Record<string, any>,\r\n  ): void {\r\n    let boundingRect = this.tools.boundingClientRect.process({ element });\r\n    for (const { key, type, fallback, transform } of this.attributesToMap) {\r\n      const resolvedFallback =\r\n        typeof fallback === \"function\" ? fallback(element, object, boundingRect) : fallback;\r\n      const attributeFallback =\r\n        attributes[key] ?? attributes[`string-${key}`] ?? attributes[`data-string-${key}`];\r\n      const raw = this.tools.domAttribute.process({\r\n        element,\r\n        key,\r\n        fallback: attributeFallback ?? this.settings[key] ?? resolvedFallback,\r\n      });\r\n\r\n      let parsed = this.parseAttribute(raw, type, {\r\n        element,\r\n        boundingRect,\r\n        viewportHeight: this.data.viewport.windowHeight,\r\n        baseRem: this.data.viewport.baseRem,\r\n      });\r\n\r\n      if (transform) {\r\n        parsed = transform(parsed);\r\n      }\r\n      object.setProperty(key, parsed);\r\n    }\r\n\r\n    this.cacheLayoutSnapshot(object, element);\r\n  }\r\n\r\n  protected cacheLayoutSnapshot(object: StringObject, element: HTMLElement): void {\r\n    const host = this.data.scroll.container ?? document.body ?? document.documentElement;\r\n    const scroller = this.data.scroll.elementContainer ?? document.documentElement;\r\n    const rect = this.tools.transformNullify.process({ element });\r\n    const computedStyle = window.getComputedStyle(element);\r\n    const fallbackSize = this.getOffsetSize(element, computedStyle);\r\n\r\n    let docLeft = 0;\r\n    let docTop = 0;\r\n    let width = rect.width;\r\n    let height = rect.height;\r\n\r\n    if (!Number.isFinite(width) || width <= 0) {\r\n      width = fallbackSize.width;\r\n    }\r\n    if (!Number.isFinite(height) || height <= 0) {\r\n      height = fallbackSize.height;\r\n    }\r\n\r\n    if (\r\n      Number.isFinite(rect.left) &&\r\n      Number.isFinite(rect.top) &&\r\n      rect.width > 0 &&\r\n      rect.height > 0\r\n    ) {\r\n      if (host === document.body || host === document.documentElement) {\r\n        docLeft = rect.left + scroller.scrollLeft;\r\n        docTop = rect.top + scroller.scrollTop;\r\n      } else {\r\n        const hostRect = host.getBoundingClientRect();\r\n        docLeft = rect.left - hostRect.left + host.scrollLeft;\r\n        docTop = rect.top - hostRect.top + host.scrollTop;\r\n      }\r\n    } else {\r\n      const elementOffset = this.getOffsetChainPosition(element);\r\n      if (host === document.body || host === document.documentElement) {\r\n        docLeft = elementOffset.left;\r\n        docTop = elementOffset.top;\r\n      } else {\r\n        const hostOffset = this.getOffsetChainPosition(host);\r\n        docLeft = elementOffset.left - hostOffset.left + host.scrollLeft;\r\n        docTop = elementOffset.top - hostOffset.top + host.scrollTop;\r\n      }\r\n    }\r\n\r\n    object.setProperty<number>(\"layout-doc-left\", docLeft);\r\n    object.setProperty<number>(\"layout-doc-top\", docTop);\r\n    object.setProperty<number>(\"layout-width\", width);\r\n    object.setProperty<number>(\"layout-height\", height);\r\n    object.setProperty<string>(\"layout-border-radius\", computedStyle.borderRadius || \"0px\");\r\n  }\r\n\r\n  private getOffsetSize(\r\n    element: HTMLElement,\r\n    computedStyle: CSSStyleDeclaration,\r\n  ): { width: number; height: number } {\r\n    const parsedWidth = parseFloat(computedStyle.width);\r\n    const parsedHeight = parseFloat(computedStyle.height);\r\n\r\n    return {\r\n      width:\r\n        element.offsetWidth ||\r\n        element.clientWidth ||\r\n        (Number.isFinite(parsedWidth) ? parsedWidth : 0),\r\n      height:\r\n        element.offsetHeight ||\r\n        element.clientHeight ||\r\n        (Number.isFinite(parsedHeight) ? parsedHeight : 0),\r\n    };\r\n  }\r\n\r\n  private getOffsetChainPosition(element: HTMLElement): { left: number; top: number } {\r\n    let left = 0;\r\n    let top = 0;\r\n    let current: HTMLElement | null = element;\r\n\r\n    while (current) {\r\n      left += current.offsetLeft || 0;\r\n      top += current.offsetTop || 0;\r\n      current = current.offsetParent as HTMLElement | null;\r\n    }\r\n\r\n    return { left, top };\r\n  }\r\n\r\n  /**\r\n   * Calculates object-specific positions or metrics based on the current layout or scroll state.\r\n   * This method is intended to be overridden in subclasses if the module needs to precompute\r\n   * layout-dependent values (e.g. parallax offsets, trigger zones, distances).\r\n   *\r\n   * @param object The `StringObject` instance whose positions are being calculated.\r\n   * @param windowSize The current window height or width (depending on scroll axis).\r\n   */\r\n  calculatePositions(object: StringObject, windowSize: number) {\r\n    const start = object.getProperty<number>(\"start\");\r\n    const size = object.getProperty<number>(\"size\");\r\n\r\n    const offsetStart =\r\n      object.getProperty<number>(\"offset-enter\") ??\r\n      object.getProperty<number>(\"offset-bottom\");\r\n    const offsetEnd =\r\n      object.getProperty<number>(\"offset-exit\") ??\r\n      object.getProperty<number>(\"offset-top\");\r\n\r\n    const startElement = object.getProperty(\"enter-el\");\r\n    const startViewport = object.getProperty(\"enter-vp\");\r\n    const endElement = object.getProperty(\"exit-el\");\r\n    const endViewport = object.getProperty(\"exit-vp\");\r\n\r\n    let startPosition = -0;\r\n    let endPosition = -0;\r\n    let startBias = -0;\r\n    let endBias = -0;\r\n\r\n    if (\r\n      (startElement === \"top\" && startViewport === \"top\") ||\r\n      (startElement === \"left\" && startViewport === \"left\")\r\n    ) {\r\n      startBias = -windowSize + 1;\r\n      startPosition = start - offsetStart;\r\n    } else if (\r\n      (startElement === \"top\" && startViewport === \"bottom\") ||\r\n      (startElement === \"left\" && startViewport === \"right\")\r\n    ) {\r\n      startPosition = start - windowSize - offsetStart;\r\n    } else if (\r\n      (startElement === \"bottom\" && startViewport === \"top\") ||\r\n      (startElement === \"right\" && startViewport === \"left\")\r\n    ) {\r\n      startBias = -windowSize - size + 1;\r\n      startPosition = start + size - offsetStart;\r\n    } else if (\r\n      (startElement === \"bottom\" && startViewport === \"bottom\") ||\r\n      (startElement === \"right\" && startViewport === \"right\")\r\n    ) {\r\n      startBias = -size + 1;\r\n      startPosition = start - windowSize + size - offsetStart;\r\n    }\r\n\r\n    // End position calculation\r\n    if (\r\n      (endElement === \"top\" && endViewport === \"top\") ||\r\n      (endElement === \"left\" && endViewport === \"left\")\r\n    ) {\r\n      endBias = -size + 1;\r\n      endPosition = start + offsetEnd;\r\n    } else if (\r\n      (endElement === \"top\" && endViewport === \"bottom\") ||\r\n      (endElement === \"left\" && endViewport === \"right\")\r\n    ) {\r\n      endBias = -windowSize - size + 1;\r\n      endPosition = start - windowSize + offsetEnd;\r\n    } else if (\r\n      (endElement === \"bottom\" && endViewport === \"top\") ||\r\n      (endElement === \"right\" && endViewport === \"left\")\r\n    ) {\r\n      endPosition = start + size + offsetEnd;\r\n    } else if (\r\n      (endElement === \"bottom\" && endViewport === \"bottom\") ||\r\n      (endElement === \"right\" && endViewport === \"right\")\r\n    ) {\r\n      endBias = -windowSize + 1;\r\n      endPosition = start - windowSize + size + offsetEnd;\r\n    }\r\n\r\n    object.setProperty<number>(\"start-bias\", startBias);\r\n    object.setProperty<number>(\"end-bias\", endBias);\r\n\r\n    object.setProperty<number>(\"start-position\", startPosition - this.data.scroll.topPosition);\r\n    object.setProperty<number>(\"end-position\", endPosition - this.data.scroll.topPosition);\r\n    object.setProperty<number>(\"difference-position\", endPosition - startPosition);\r\n\r\n    const inviewTop = object.getProperty<number>(\"inview-top\") ?? -0;\r\n    const inviewBottom = object.getProperty<number>(\"inview-bottom\") ?? -0;\r\n    object.setProperty<number>(\r\n      \"inview-start-position\",\r\n      object.getProperty<number>(\"start-position\") + inviewTop,\r\n    );\r\n    object.setProperty<number>(\r\n      \"inview-end-position\",\r\n      object.getProperty<number>(\"end-position\") + inviewBottom,\r\n    );\r\n  }\r\n\r\n  /**\r\n   * Parses a raw DOM attribute value into the correct type based on mapping.\r\n   * Handles fallback resolution, transformation, and special units.\r\n   *\r\n   * @param value Raw attribute string from DOM.\r\n   * @param type The expected attribute type (e.g. number, boolean, dimension).\r\n   * @param context Optional helper values like element or viewport size.\r\n   * @returns The parsed and transformed value.\r\n   */\r\n  protected parseAttribute(\r\n    value: string | null,\r\n    type: AttributeType,\r\n    context: ParseContext = EMPTY_CONTEXT,\r\n  ): any {\r\n    if (value == null) return null;\r\n\r\n    if (typeof type === \"object\" && type.type === \"enum\") {\r\n      return type.values.includes(value) ? value : type.values[0];\r\n    }\r\n\r\n    switch (type) {\r\n      case \"number\":\r\n        return typeof value === \"string\" ? +value || parseFloat(value) : value;\r\n\r\n      case \"boolean\":\r\n        return value === \"\" || value === \"true\";\r\n\r\n      case \"json\":\r\n        try {\r\n          return JSON.parse(value);\r\n        } catch {\r\n          return null;\r\n        }\r\n\r\n      case \"tuple\":\r\n        return value.trim().split(/\\s+/);\r\n\r\n      case \"easing\":\r\n        return this.tools.easingFunction.process({ easing: value });\r\n\r\n      case \"color\":\r\n        return this.tools.colorParser.process({ value: value });\r\n\r\n      case \"dimension\":\r\n        if (value == \"0\") return 0;\r\n        if (\r\n          context.element != null &&\r\n          context.viewportHeight != null &&\r\n          context.baseRem != null &&\r\n          context.boundingRect != null\r\n        ) {\r\n          return this.tools.unitParser.process({\r\n            value,\r\n            element: context.element,\r\n            viewportHeight: context.viewportHeight,\r\n            boundingRect: context.boundingRect,\r\n            baseRem: context.baseRem,\r\n          });\r\n        } else {\r\n          return 0;\r\n        }\r\n\r\n      case \"breakpoint-dimension\":\r\n        if (\r\n          context.element != null &&\r\n          context.viewportHeight != null &&\r\n          context.baseRem != null &&\r\n          context.boundingRect != null\r\n        ) {\r\n          let parsedBreakpoint = value.trim().split(\"|\");\r\n          let breakpoints: Array<{ breakpoint: number; value: number }> = [];\r\n          for (const item of parsedBreakpoint) {\r\n            if (item.includes(\":\")) {\r\n              const [key, val] = item.split(\":\");\r\n              breakpoints.push({\r\n                breakpoint: parseInt(key),\r\n                value: this.tools.unitParser.process({\r\n                  value: `${val}|`,\r\n                  element: context.element,\r\n                  viewportHeight: context.viewportHeight,\r\n                  boundingRect: context.boundingRect,\r\n                  baseRem: context.baseRem,\r\n                }),\r\n              });\r\n            } else {\r\n              breakpoints.push({\r\n                breakpoint: 0,\r\n                value: this.tools.unitParser.process({\r\n                  value: item,\r\n                  element: context.element,\r\n                  viewportHeight: context.viewportHeight,\r\n                  boundingRect: context.boundingRect,\r\n                  baseRem: context.baseRem,\r\n                }),\r\n              });\r\n            }\r\n          }\r\n          return breakpoints;\r\n        }\r\n\r\n      default:\r\n        return value;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Determines whether the module should attach to a given object,\r\n   * based on the presence of the module's `htmlKey` in the object keys.\r\n   *\r\n   * @param object The target object to test.\r\n   * @returns `true` if the module can connect, `false` otherwise.\r\n   */\r\n  canConnect(object: StringObject): boolean {\r\n    return object.keys.includes(this.htmlKey);\r\n  }\r\n\r\n  protected isTokenEnabledInCurrentMode(token: StringToken): boolean {\r\n    const mode = this.data.scroll.mode;\r\n\r\n    if (token.modeSpec.kind === \"all\") {\r\n      return true;\r\n    }\r\n\r\n    if (token.modeSpec.kind === \"include\") {\r\n      return token.modeSpec.values.includes(mode);\r\n    }\r\n\r\n    if (this.defaultModeScope === \"all\") {\r\n      return true;\r\n    }\r\n\r\n    return this.defaultModeScope.includes(mode);\r\n  }\r\n\r\n  protected isObjectEnabledInCurrentMode(object: StringObject): boolean {\r\n    const token = object.getToken(this.htmlKey);\r\n    if (!token) {\r\n      return false;\r\n    }\r\n    return this.isTokenEnabledInCurrentMode(token);\r\n  }\r\n\r\n  disconnectObject(object: StringObject): void {\r\n    object.disconnect(this);\r\n  }\r\n\r\n  /**\r\n   * Registers the module on a given object, adds the object to internal list,\r\n   * and triggers connection logic.\r\n   *\r\n   * @param object The object to connect to.\r\n   */\r\n  connectObject(object: StringObject): void {\r\n    const isNewConnection = object.connect(this);\r\n    if (isNewConnection) {\r\n      this.onObjectConnected(object);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Registers the object internally when it enters the module’s scope.\r\n   */\r\n  enterObject(id: string, object: StringObject): void {\r\n    if (!this.allObjectMap.has(id)) {\r\n      this.allObjectMap.set(id, object);\r\n      this.allObjects.push(object);\r\n    }\r\n\r\n    if (this.isObjectEnabledInCurrentMode(object) && !this.objectMap.has(id)) {\r\n      this.objectMap.set(id, object);\r\n      this.objects.push(object);\r\n    }\r\n  }\r\n\r\n  protected fastRemoveFromArray<T>(array: T[], index: number): void {\r\n    if (index === -1) return;\r\n\r\n    const lastIndex = array.length - 1;\r\n    if (index !== lastIndex) {\r\n      array[index] = array[lastIndex];\r\n    }\r\n    array.pop();\r\n  }\r\n\r\n  /**\r\n   * Unregisters the object when it leaves the module’s scope.\r\n   */\r\n  exitObject(id: string): void {\r\n    const activeObject = this.objectMap.get(id);\r\n    if (activeObject) {\r\n      this.objectMap.delete(id);\r\n      const activeIndex = this.objects.indexOf(activeObject);\r\n      this.fastRemoveFromArray(this.objects, activeIndex);\r\n    }\r\n\r\n    const object = this.allObjectMap.get(id);\r\n    if (!object) return;\r\n\r\n    this.allObjectMap.delete(id);\r\n    const index = this.allObjects.indexOf(object);\r\n    this.fastRemoveFromArray(this.allObjects, index);\r\n  }\r\n\r\n  /**\r\n   * Adds a `StringObject` to the internal collections if it does not already exist.\r\n   *\r\n   * @param id - The unique identifier for the `StringObject`.\r\n   * @param object - The `StringObject` to be added.\r\n   *\r\n   * @remarks\r\n   * This method ensures that the object is added to both `objectMapOnPage` and\r\n   * `objectsOnPage` only if the `id` is not already present in `objectMapOnPage`.\r\n   */\r\n  addObject(id: string, object: StringObject): void {\r\n    if (!this.allObjectMapOnPage.has(id)) {\r\n      this.allObjectMapOnPage.set(id, object);\r\n      this.allObjectsOnPage.push(object);\r\n    }\r\n\r\n    if (this.isObjectEnabledInCurrentMode(object) && !this.objectMapOnPage.has(id)) {\r\n      this.objectMapOnPage.set(id, object);\r\n      this.objectsOnPage.push(object);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Removes an object from the page by its unique identifier.\r\n   *\r\n   * This method performs the following steps:\r\n   * 1. Retrieves the object associated with the given `id` from `objectMapOnPage`.\r\n   * 2. If the object is not found, the method exits early.\r\n   * 3. Deletes the object from `objectMapOnPage`.\r\n   * 4. Finds the index of the object in the `objectsOnPage` array.\r\n   * 5. If the object exists in the array, it is removed using `splice`.\r\n   *\r\n   * @param id - The unique identifier of the object to be removed.\r\n   */\r\n  removeObject(id: string): void {\r\n    const activeObject = this.objectMapOnPage.get(id);\r\n    if (activeObject) {\r\n      this.objectMapOnPage.delete(id);\r\n      const activeIndex = this.objectsOnPage.indexOf(activeObject);\r\n      this.fastRemoveFromArray(this.objectsOnPage, activeIndex);\r\n    }\r\n\r\n    const object = this.allObjectMapOnPage.get(id);\r\n    if (!object) return;\r\n\r\n    this.allObjectMapOnPage.delete(id);\r\n    const index = this.allObjectsOnPage.indexOf(object);\r\n    this.fastRemoveFromArray(this.allObjectsOnPage, index);\r\n\r\n    this.exitObject(id);\r\n    this.onObjectDisconnected(object);\r\n  }\r\n\r\n  /**\r\n   * Called when an object is connected. Can be overridden to apply initial styles or logic.\r\n   * @param object The connected object.\r\n   */\r\n  onObjectConnected(object: StringObject): void {}\r\n\r\n  /**\r\n   * Called when an object is disconnected. Can be overridden to clean up styles or logic.\r\n   * @param object The disconnected object.\r\n   */\r\n  onObjectDisconnected(object: StringObject): void {}\r\n\r\n  protected get respectSelfDisable(): boolean {\r\n    return true;\r\n  }\r\n\r\n  protected isPrimaryElementEnabled(object: StringObject): boolean {\r\n    return !this.respectSelfDisable || object.getProperty(\"self-disable\") !== true;\r\n  }\r\n\r\n  /**\r\n   * Applies a style or callback to both the main element and all its connected elements.\r\n   *\r\n   * @param object The object whose elements to update.\r\n   * @param applyFn The function that receives an HTMLElement and performs any update.\r\n   */\r\n  protected applyToElementAndConnects(\r\n    object: StringObject,\r\n    applyFn: (el: HTMLElement) => void,\r\n    copyFn: (el: HTMLElement, mirror?: StringMirrorObject) => void = applyFn,\r\n  ) {\r\n    if (this.isPrimaryElementEnabled(object)) {\r\n      applyFn(object.htmlElement);\r\n    }\r\n    object.mirrorObjects.forEach((mirror) => copyFn(mirror.htmlElement, mirror));\r\n  }\r\n\r\n  /**\r\n   * Directly applies a CSS variable to the object's element without closures.\r\n   */\r\n  protected applyVarToElement(object: StringObject, key: string, value: string | number) {\r\n    if (this.isPrimaryElementEnabled(object)) {\r\n      this.tools.styleTxn.setVar(object.htmlElement, key, value);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Directly applies a standard CSS property to the object's element without closures.\r\n   */\r\n  protected applyPropToElement(object: StringObject, key: string, value: string | number) {\r\n    if (this.isPrimaryElementEnabled(object)) {\r\n      this.tools.styleTxn.setProp(object.htmlElement, key, value);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Directly applies a CSS variable to all connected mirrors without closures.\r\n   */\r\n  protected applyVarToConnects(object: StringObject, key: string, value: string | number) {\r\n    for (const mirror of object.mirrorObjects) {\r\n      this.tools.styleTxn.setVar(mirror.htmlElement, key, value);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Directly applies a standard CSS property to all connected mirrors without closures.\r\n   */\r\n  protected applyPropToConnects(object: StringObject, key: string, value: string | number) {\r\n    for (const mirror of object.mirrorObjects) {\r\n      this.tools.styleTxn.setProp(mirror.htmlElement, key, value);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Returns a cached per-object event name to avoid building strings in hot paths.\r\n   */\r\n  protected getObjectEventName(object: StringObject, prefix: string, suffix?: string): string {\r\n    return object.getScopedEventName(prefix, suffix);\r\n  }\r\n\r\n  protected clearManagedStyles(object: StringObject): void {\r\n    const clearStyles = (el: HTMLElement) => {\r\n      for (let i = 0; i < this.cssProperties.length; i++) {\r\n        el.style.removeProperty(this.cssProperties[i].name);\r\n      }\r\n\r\n      const key = object.getProperty<string>(\"key\");\r\n      if (typeof key === \"string\" && key.length > 0) {\r\n        el.style.removeProperty(key);\r\n      }\r\n    };\r\n\r\n    clearStyles(object.htmlElement);\r\n    const mirrors = object.mirrorObjects;\r\n    for (let i = 0; i < mirrors.length; i++) {\r\n      clearStyles(mirrors[i].htmlElement);\r\n    }\r\n  }\r\n\r\n  protected onObjectModeActivated(object: StringObject): void {}\r\n\r\n  protected onObjectModeDeactivated(object: StringObject): void {\r\n    this.clearManagedStyles(object);\r\n  }\r\n\r\n  protected rebuildActiveObjectsForCurrentMode(): void {\r\n    const previousActiveOnPage = new Map(this.objectMapOnPage);\r\n\r\n    this.objectMapOnPage = new Map();\r\n    this.objectsOnPage = [];\r\n    for (let i = 0; i < this.allObjectsOnPage.length; i++) {\r\n      const object = this.allObjectsOnPage[i];\r\n      if (!this.isObjectEnabledInCurrentMode(object)) {\r\n        continue;\r\n      }\r\n      this.objectMapOnPage.set(object.id, object);\r\n      this.objectsOnPage.push(object);\r\n    }\r\n\r\n    this.objectMap = new Map();\r\n    this.objects = [];\r\n    for (let i = 0; i < this.allObjects.length; i++) {\r\n      const object = this.allObjects[i];\r\n      if (!this.isObjectEnabledInCurrentMode(object)) {\r\n        continue;\r\n      }\r\n      this.objectMap.set(object.id, object);\r\n      this.objects.push(object);\r\n    }\r\n\r\n    previousActiveOnPage.forEach((object, id) => {\r\n      if (!this.objectMapOnPage.has(id)) {\r\n        this.onObjectModeDeactivated(object);\r\n      }\r\n    });\r\n\r\n    this.objectMapOnPage.forEach((object, id) => {\r\n      if (!previousActiveOnPage.has(id)) {\r\n        this.onObjectModeActivated(object);\r\n      }\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Cleans up internal state and detaches the module from the system.\r\n   */\r\n  destroy(): void {\r\n    this.objects = [];\r\n    this.allObjects = [];\r\n    this.objectMap = new Map();\r\n    this.allObjectMap = new Map();\r\n    this.objectsOnPage = [];\r\n    this.allObjectsOnPage = [];\r\n    this.objectMapOnPage = new Map();\r\n    this.allObjectMapOnPage = new Map();\r\n  }\r\n\r\n  // ───────────────────────────────\r\n  // Lifecycle Hooks\r\n  // ───────────────────────────────\r\n\r\n  /** Called once when the module is initialized. */\r\n  onInit(): void {}\r\n\r\n  /** Called once when the module is registered and can subscribe to events. */\r\n  onSubscribe(): void {}\r\n\r\n  /** Called once when the module is being removed and should unsubscribe. */\r\n  onUnsubscribe(): void {}\r\n\r\n  /** Called on each frame with current scroll and state data. */\r\n  onFrame(data: StringData): void {}\r\n\r\n  onMutate(data: StringData): void {}\r\n  onScrollMeasure(data: StringData): void {}\r\n  onMouseMoveMeasure(data: StringData): void {}\r\n  /** Called when the window or layout is resized. */\r\n  onResize(): void {}\r\n\r\n  /** Called when the layout is resized width. */\r\n  onResizeWidth(): void {}\r\n\r\n  /** Called when scroll position changes. */\r\n  onScroll(data: StringData): void {}\r\n\r\n  /** Called when user changed scroll direction. */\r\n  onDirectionChange(): void {}\r\n\r\n  /** Called when user starts scrolling. */\r\n  onScrollStart(): void {}\r\n\r\n  /** Called when user stops scrolling. */\r\n  onScrollStop(): void {}\r\n\r\n  /** Called when scroll direction changes (e.g., up ↔ down). */\r\n  onScrollDirectionChange(): void {}\r\n\r\n  /** Called when scroll axis changes (vertical ↔ horizontal). */\r\n  onAxisChange(): void {}\r\n\r\n  /** Called when device type changes (e.g., desktop ↔ mobile). */\r\n  onDeviceChange(): void {}\r\n\r\n  /** Called when scroll-related system settings or parameters change. */\r\n  onScrollConfigChange(): void {\r\n    this.rebuildActiveObjectsForCurrentMode();\r\n  }\r\n\r\n  /** Called when scroll-related system settings or parameters change. */\r\n  onSettingsChange(): void {}\r\n\r\n  /** Called when the DOM is rebuilt, such as after a major mutation. */\r\n  onDOMRebuild(): void {}\r\n\r\n  /** Called on every mouse movement. */\r\n  onMouseMove(event: MouseEvent): void {}\r\n\r\n  /** Called on wheel input (independent of scroll). */\r\n  onWheel(event: WheelEvent): void {}\r\n\r\n  /**\r\n   * Called when DOM elements are added or removed.\r\n   */\r\n  onDOMMutate(added: NodeList, removed: NodeList): void {}\r\n}\r\n","import { ModuleManager } from \"./ModuleManager\";\r\nimport { StringData } from \"../StringData\";\r\nimport { StringMirrorObject } from \"../../objects/StringMirrorObject\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { EventManager } from \"./EventManager\";\r\nimport { ISettingsChangeData } from \"../../models/event/ISettingsChangeData\";\r\nimport { StringToolsContainer } from \"../StringToolsContainer\";\r\nimport { DOMBatcher } from \"./DOMBatcher\";\r\nimport { StringModule } from \"../StringModule\";\r\nimport { StringToken } from \"../../models/string/StringToken\";\r\nimport { ScrollMode } from \"../../states/ScrollState\";\r\n\r\nexport class ObjectManager {\r\n  private objects = new Map<string, StringObject>();\r\n  private connectQueue: { id: string; element: HTMLElement }[] = [];\r\n  private connectableModulesBuffer: StringModule[] = [];\r\n  private mirrors = new Map<string, StringMirrorObject>();\r\n  private mirrorId = 1;\r\n  private globalId = 1;\r\n  private domBatcher = new DOMBatcher();\r\n  private domBatcherEnabled = false;\r\n  private inviewStarts: Array<{ pos: number; object: StringObject }> = [];\r\n  private inviewEnds: Array<{ pos: number; object: StringObject }> = [];\r\n  private inviewActive = new Set<StringObject>();\r\n  private inviewStartIdx = 0;\r\n  private inviewEndIdx = 0;\r\n  private inviewIndexDirty = true;\r\n  private lastInviewScrollPos = 0;\r\n  private intersectionObserverEnabled = true;\r\n  private domObserver: MutationObserver | null = null;\r\n\r\n  constructor(\r\n    private data: StringData,\r\n    private modules: ModuleManager,\r\n    private events: EventManager,\r\n    private tools: StringToolsContainer\r\n  ) {}\r\n\r\n  /**\r\n   * Returns the object map (read-only).\r\n   */\r\n  get all(): ReadonlyMap<string, StringObject> {\r\n    return this.objects;\r\n  }\r\n\r\n  /**\r\n   * Adds a new object from an element.\r\n   */\r\n  public add(el: HTMLElement) {\r\n    let idAttr = `string-${this.globalId++}`;\r\n    let key = \"string-id\";\r\n\r\n    if (el.getAttribute(\"string-id\")) {\r\n      idAttr = el.getAttribute(\"string-id\")!;\r\n      key = \"string-id\";\r\n    }\r\n    if (el.getAttribute(\"data-string-id\")) {\r\n      idAttr = el.getAttribute(\"data-string-id\")!;\r\n      key = \"data-string-id\";\r\n    }\r\n\r\n    const object =\r\n      idAttr && this.objects.has(idAttr) ? this.objects.get(idAttr)! : new StringObject(idAttr, el);\r\n\r\n    el.setAttribute(key, object.id);\r\n\r\n    const keysAttr = el.getAttribute(\"string\") ?? el.getAttribute(\"data-string\");\r\n\r\n    if (keysAttr) {\r\n      object.setTokens(this.parseStringTokens(keysAttr));\r\n    }\r\n\r\n    el.setAttribute(\"string-inited\", \"\");\r\n    this.objects.set(object.id, object);\r\n\r\n    const attributes = this.getAllAttributes(el);\r\n\r\n    // Delegate core setup (dimensions, offsets, key, start/end, etc.)\r\n    const coreModules = this.modules.core;\r\n    for (let i = 0; i < coreModules.length; i++) {\r\n      const m = coreModules[i] as any;\r\n      if (\"setupCoreProperties\" in m && typeof m[\"setupCoreProperties\"] === \"function\") {\r\n        m.setupCoreProperties(object, el, attributes);\r\n      }\r\n    }\r\n\r\n    // Try connecting to modules\r\n    const connectableModules = this.connectableModulesBuffer;\r\n    connectableModules.length = 0;\r\n    const allModules = this.modules.all;\r\n    let inviewFallbackModule: StringModule | null = null;\r\n    for (let i = 0; i < allModules.length; i++) {\r\n      const m = allModules[i];\r\n      if (m instanceof StringModule && m.key === \"\") {\r\n        inviewFallbackModule = m;\r\n      }\r\n      if (m instanceof StringModule && m.canConnect(object)) {\r\n        connectableModules.push(m);\r\n      }\r\n    }\r\n    if (connectableModules.length === 0 && inviewFallbackModule) {\r\n      object.setProperty(\"inview-fallback\", true);\r\n      connectableModules.push(inviewFallbackModule);\r\n    }\r\n    if (this.domBatcherEnabled && connectableModules.length > 0) {\r\n      const batchContexts = new Array(connectableModules.length);\r\n      for (let i = 0; i < connectableModules.length; i++) {\r\n        batchContexts[i] = {\r\n          module: connectableModules[i],\r\n          object,\r\n          element: el,\r\n          attributes,\r\n          globalId: this.globalId,\r\n          windowSize: this.data.viewport.windowHeight,\r\n        };\r\n      }\r\n      this.domBatcher.batchModuleInitialization(batchContexts);\r\n      this.domBatcher.scheduleWrite(() => {\r\n        this.initObservers(object, el);\r\n        this.checkInviewForObject(object);\r\n      });\r\n    } else {\r\n      for (let i = 0; i < connectableModules.length; i++) {\r\n        const m = connectableModules[i];\r\n        m.initializeObject(this.globalId, object, el, attributes);\r\n        m.calculatePositions(object, this.data.viewport.windowHeight);\r\n        m.connectObject(object);\r\n        m.addObject(object.id, object);\r\n      }\r\n      this.initObservers(object, el);\r\n      this.checkInviewForObject(object);\r\n    }\r\n\r\n    // Restore connect-from\r\n    if (this.connectQueue.length > 0) {\r\n      let write = 0;\r\n      for (let i = 0; i < this.connectQueue.length; i++) {\r\n        const item = this.connectQueue[i];\r\n        if (item.id === object.id) {\r\n          this.attachMirrorToObject(object, item.element);\r\n          continue;\r\n        }\r\n        this.connectQueue[write++] = item;\r\n      }\r\n      this.connectQueue.length = write;\r\n    }\r\n    connectableModules.length = 0;\r\n    this.inviewIndexDirty = true;\r\n  }\r\n\r\n  public setDOMBatcherEnabled(enabled: boolean): void {\r\n    this.domBatcherEnabled = enabled;\r\n    if (!enabled) {\r\n      this.domBatcher.flushSync();\r\n    }\r\n  }\r\n\r\n  public setIntersectionObserverEnabled(enabled: boolean): void {\r\n    if (this.intersectionObserverEnabled === enabled) return;\r\n    this.intersectionObserverEnabled = enabled;\r\n    for (const object of this.objects.values()) {\r\n      object.getProperty<IntersectionObserver>(\"observer-progress\")?.disconnect();\r\n      if (enabled) {\r\n        this.initObservers(object, object.htmlElement);\r\n      }\r\n    }\r\n  }\r\n\r\n  public attachModule(module: StringModule): void {\r\n    this.objects.forEach((object) => {\r\n      if (!module.canConnect(object)) {\r\n        return;\r\n      }\r\n\r\n      const element = object.htmlElement;\r\n      const attributes = this.getAllAttributes(element);\r\n      module.initializeObject(this.globalId, object, element, attributes);\r\n      module.calculatePositions(object, this.data.viewport.windowHeight);\r\n      module.connectObject(object);\r\n      module.addObject(object.id, object);\r\n      if (object.getProperty<boolean>(\"active\") === true) {\r\n        module.enterObject(object.id, object);\r\n      }\r\n    });\r\n  }\r\n\r\n  public refreshModuleConnectionsForCurrentMode(): void {\r\n    const allModules = this.modules.all;\r\n\r\n    for (const object of this.objects.values()) {\r\n      const element = object.htmlElement;\r\n      if (!element || !element.isConnected) continue;\r\n\r\n      let attributes: Record<string, any> | null = null;\r\n\r\n      for (let i = 0; i < allModules.length; i++) {\r\n        const module = allModules[i];\r\n        if (!(module instanceof StringModule)) continue;\r\n        if (!object.keys.includes(module.key)) continue;\r\n\r\n        const shouldConnect = module.canConnect(object);\r\n        const isConnected = object.isConnectedTo(module);\r\n\r\n        if (shouldConnect && !isConnected) {\r\n          if (attributes == null) {\r\n            attributes = this.getAllAttributes(element);\r\n          }\r\n          module.initializeObject(this.globalId, object, element, attributes);\r\n          module.calculatePositions(object, this.data.viewport.windowHeight);\r\n          module.connectObject(object);\r\n          module.addObject(object.id, object);\r\n          if (object.getProperty<boolean>(\"active\") === true) {\r\n            module.enterObject(object.id, object);\r\n          }\r\n          continue;\r\n        }\r\n\r\n        if (!shouldConnect && isConnected) {\r\n          module.exitObject(object.id);\r\n          module.removeObject(object.id);\r\n          module.disconnectObject(object);\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  public invalidateInviewIndex(): void {\r\n    this.inviewIndexDirty = true;\r\n  }\r\n\r\n  public refreshLayoutForRoot(root: HTMLElement): void {\r\n    if (!root) return;\r\n\r\n    const targets = new Set<StringObject>();\r\n    const maybeAdd = (el: HTMLElement) => {\r\n      const id = el.getAttribute(\"string-id\") ?? el.getAttribute(\"data-string-id\");\r\n      if (!id) return;\r\n      const obj = this.objects.get(id);\r\n      if (obj) targets.add(obj);\r\n    };\r\n\r\n    if (root instanceof HTMLElement) {\r\n      maybeAdd(root);\r\n      const nodes = root.querySelectorAll<HTMLElement>(\"[string-id],[data-string-id]\");\r\n      for (let i = 0; i < nodes.length; i++) {\r\n        maybeAdd(nodes[i]);\r\n      }\r\n    }\r\n\r\n    if (targets.size === 0) return;\r\n\r\n    const windowSize = this.data.viewport.windowHeight;\r\n    for (const object of targets) {\r\n      const element = object.htmlElement;\r\n      if (!element || !element.isConnected) continue;\r\n      const attributes = this.getAllAttributes(element);\r\n      const all = this.modules.all;\r\n      for (let i = 0; i < all.length; i++) {\r\n        const m = all[i];\r\n        if (!(m instanceof StringModule)) continue;\r\n        if (!m.canConnect(object)) continue;\r\n        m.initializeObject(this.globalId, object, element, attributes);\r\n        m.calculatePositions(object, windowSize);\r\n      }\r\n    }\r\n\r\n    this.inviewIndexDirty = true;\r\n    this.checkInview();\r\n  }\r\n\r\n  /**\r\n   * Removes an object by its id.\r\n   */\r\n  public remove(id: string) {\r\n    const obj = this.objects.get(id);\r\n    if (!obj) return;\r\n\r\n    obj.events.clearAll();\r\n    obj.getProperty<IntersectionObserver>(\"observer-progress\")?.disconnect();\r\n    obj.getProperty<IntersectionObserver>(\"observer-inview\")?.disconnect();\r\n\r\n    obj.htmlElement.removeAttribute(\"string-inited\");\r\n    obj.leave();\r\n    obj.remove();\r\n\r\n    obj.mirrorObjects.forEach((mirror) => {\r\n      const mirrorIds = this.getMirrorIds(mirror.htmlElement);\r\n      this.setMirrorIds(\r\n        mirror.htmlElement,\r\n        mirrorIds.filter((id) => id !== mirror.id)\r\n      );\r\n      this.mirrors.delete(mirror.id);\r\n\r\n      const copyFromId =\r\n        mirror.htmlElement.getAttribute(\"string-copy-from\") ??\r\n        mirror.htmlElement.getAttribute(\"data-string-copy-from\");\r\n      if (copyFromId) {\r\n        this.enqueueConnection(copyFromId, mirror.htmlElement);\r\n      }\r\n    });\r\n\r\n    this.objects.delete(id);\r\n    this.inviewActive.delete(obj);\r\n    this.inviewIndexDirty = true;\r\n  }\r\n\r\n  /**\r\n   * Add an element that will connect later.\r\n   */\r\n  public enqueueConnection(id: string, element: HTMLElement) {\r\n    // Split by | to handle multiple IDs\r\n    const ids = this.splitPipeAndTrim(id);\r\n    for (let i = 0; i < ids.length; i++) {\r\n      const singleId = ids[i];\r\n      if (this.connectQueue.some((item) => item.id === singleId && item.element === element)) {\r\n        continue;\r\n      }\r\n      this.connectQueue.push({ id: singleId, element });\r\n    }\r\n  }\r\n\r\n  public linkMirror(id: string, element: HTMLElement): void {\r\n    // Split by | to handle multiple IDs\r\n    const ids = this.splitPipeAndTrim(id);\r\n    for (let i = 0; i < ids.length; i++) {\r\n      const singleId = ids[i];\r\n      const parent = this.objects.get(singleId);\r\n      if (parent) {\r\n        this.attachMirrorToObject(parent, element);\r\n      } else {\r\n        this.enqueueConnection(singleId, element);\r\n      }\r\n    }\r\n  }\r\n\r\n  private attachMirrorToObject(object: StringObject, element: HTMLElement): StringMirrorObject {\n    const existingIds = this.getMirrorIds(element);\n    for (const id of existingIds) {\n      const existing = this.mirrors.get(id);\n      if (existing && existing.parentObject === object) {\n        return existing;\r\n      }\r\n    }\r\n\r\n    const mirrorId = `string-mirror-${this.mirrorId++}`;\r\n    const mirror = new StringMirrorObject(mirrorId, element, object);\r\n    this.setMirrorIds(element, [...existingIds, mirrorId]);\r\n    object.addMirror(mirror);\r\n    this.mirrors.set(mirrorId, mirror);\r\n\r\n    const easingAttr =\r\n      element.getAttribute(\"string-easing\") ?? element.getAttribute(\"data-string-easing\");\r\n    if (easingAttr && easingAttr.trim().length > 0) {\n      mirror.setEasing(this.tools.easingFunction.process({ easing: easingAttr }));\n      mirror.setProperty(\"easing\", easingAttr);\n    }\n\n    const key = object.getProperty<string>(\"key\");\n    const rawProgress = object.getProperty<number>(\"progress-raw\");\n    const progressValue = object.getProperty<number>(\"progress-value\");\n    if (typeof rawProgress === \"number\") {\n      const parentEasing = object.getProperty<(value: number) => number>(\"easing\") ?? undefined;\n      const mirrorProgress = mirror.applyProgress(rawProgress, parentEasing);\n      mirror.setProperty(\"progress\", mirrorProgress);\n      if (key) {\n        this.tools.styleTxn.setVar(mirror.htmlElement, key, mirrorProgress);\n      }\n    } else if (typeof progressValue === \"number\") {\n      mirror.setProperty(\"progress\", progressValue);\n      if (key) {\n        this.tools.styleTxn.setVar(mirror.htmlElement, key, progressValue);\n      }\n    }\n\n    return mirror;\n  }\n\r\n  private detachMirrorByElement(element: HTMLElement): void {\r\n    const ids = this.getMirrorIds(element);\r\n    if (ids.length === 0) return;\r\n    ids.forEach((id) => this.detachMirrorById(id));\r\n    this.clearMirrorIds(element);\r\n  }\r\n\r\n  private detachMirrorById(mirrorId: string): void {\r\n    const mirror = this.mirrors.get(mirrorId);\r\n    if (!mirror) return;\r\n    mirror.parentObject.removeMirror(mirrorId);\r\n    this.mirrors.delete(mirrorId);\r\n  }\r\n\r\n  private getMirrorIds(element: HTMLElement): string[] {\r\n    const raw =\r\n      element.getAttribute(\"string-mirror-id\") ?? element.getAttribute(\"data-string-mirror-id\");\r\n    if (!raw) return [];\r\n    return this.splitPipeAndTrim(raw);\r\n  }\r\n\r\n  private setMirrorIds(element: HTMLElement, ids: string[]): void {\r\n    if (ids.length === 0) {\r\n      this.clearMirrorIds(element);\r\n      return;\r\n    }\r\n    element.setAttribute(\"string-mirror-id\", ids.join(\"|\"));\r\n  }\r\n\r\n  private clearMirrorIds(element: HTMLElement): void {\r\n    element.removeAttribute(\"string-mirror-id\");\r\n    element.removeAttribute(\"data-string-mirror-id\");\r\n  }\r\n\r\n  /**\r\n   * Retrieves all attributes of a given HTML element and returns them as a record.\r\n   *\r\n   * @param el - The HTML element from which to extract attributes.\r\n   * @returns A record where the keys are attribute names and the values are attribute values.\r\n   */\r\n  private getAllAttributes(el: HTMLElement): Record<string, any> {\r\n    const attributes: Record<string, any> = {};\r\n    const attrList = el.attributes;\r\n    for (let i = 0; i < attrList.length; i++) {\r\n      const attr = attrList[i];\r\n      attributes[attr.name] = attr.value;\r\n    }\r\n    return attributes;\r\n  }\r\n\r\n  /**\r\n   * Initializes IntersectionObservers for a given object and its associated HTML element.\r\n   *\r\n   * This method sets up observer:\r\n   * - A \"progress\" observer to track when the object enters or leaves the viewport.\r\n   *\r\n   * The observers are configured with custom root margins and thresholds based on the object's properties.\r\n   * Existing observers, if any, are disconnected before creating new ones.\r\n   *\r\n   * @param obj - The `StringObject` instance containing properties and methods for interaction.\r\n   * @param el - The `HTMLElement` to observe for intersection changes.\r\n   */\r\n  private initObservers(obj: StringObject, el: HTMLElement) {\r\n    if (!this.intersectionObserverEnabled) {\r\n      return;\r\n    }\r\n    const start =\r\n      obj.getProperty<number>(\"offset-exit\") ??\r\n      obj.getProperty<number>(\"offset-top\") ??\r\n      0;\r\n    const end =\r\n      obj.getProperty<number>(\"offset-enter\") ??\r\n      obj.getProperty<number>(\"offset-bottom\") ??\r\n      0;\r\n    obj.getProperty<IntersectionObserver>(\"observer-progress\")?.disconnect();\r\n    const progressCallback = (entries: IntersectionObserverEntry[]) => {\r\n      entries.forEach((e) => {\r\n        this.events.emit(obj.getScopedEventName(\"object:activate\"), e.isIntersecting);\r\n        e.isIntersecting ? obj.enter() : obj.leave();\r\n      });\r\n    };\r\n    const outsideProp = obj.getProperty<boolean>(\"outside-container\");\r\n    const outsideAttrValue =\r\n      el.getAttribute(\"string-outside-container\") ??\r\n      el.getAttribute(\"data-string-outside-container\");\r\n    const outsideAttrNormalized =\r\n      outsideAttrValue != null ? outsideAttrValue.trim().toLowerCase() : null;\r\n    const outsideAttrFlag =\r\n      outsideAttrNormalized === \"\" ||\r\n      outsideAttrNormalized === \"true\" ||\r\n      outsideAttrNormalized === \"1\";\r\n    const isOutsideContainer = outsideProp != null ? outsideProp === true : outsideAttrFlag;\r\n    const observerRoot =\r\n      this.data.scroll.container === document.body || isOutsideContainer\r\n        ? null\r\n        : this.data.scroll.container;\r\n\r\n    const progressObserver = new IntersectionObserver(progressCallback, {\r\n      root: observerRoot,\r\n      rootMargin: `${end + this.data.viewport.windowHeight}px 0px ${\r\n        start + this.data.viewport.windowHeight\r\n      }px 0px`,\r\n      threshold: 0,\r\n    });\r\n    progressObserver.observe(el);\r\n    obj.setProperty(\"observer-progress\", progressObserver);\r\n  }\r\n\r\n  /**\r\n   * Observes DOM mutations to auto-add/remove elements with [string] attribute.\r\n   * Should be called once after DOM is ready.\r\n   */\r\n  public observeDOM(): void {\r\n    this.domObserver?.disconnect();\r\n\r\n    const observer = new MutationObserver((mutations) => {\r\n      let shouldNotifyDOMRebuild = false;\r\n\r\n      for (let mutationIndex = 0; mutationIndex < mutations.length; mutationIndex++) {\r\n        const mutation = mutations[mutationIndex];\r\n        if (mutation.type === \"childList\") {\r\n          let mutationHasElementNodes = false;\r\n\r\n          // Removed elements\r\n          for (let removedIndex = 0; removedIndex < mutation.removedNodes.length; removedIndex++) {\r\n            const node = mutation.removedNodes[removedIndex];\r\n            if (node.nodeType !== Node.ELEMENT_NODE) continue;\r\n            mutationHasElementNodes = true;\r\n\r\n            const element = node as HTMLElement;\r\n\r\n            this.detachMirrorByElement(element);\r\n\r\n            if (this.isFixed(element)) continue;\r\n\r\n            if (element.hasAttribute(\"string\")) {\r\n              this.handleRemoved(element);\r\n            }\r\n\r\n            const queryStringNodes = element.querySelectorAll(\"[string],[data-string]\");\r\n            for (let i = 0; i < queryStringNodes.length; i++) {\r\n              const child = queryStringNodes[i];\r\n              if (this.isFixed(child as HTMLElement)) continue;\r\n              this.handleRemoved(child as HTMLElement);\r\n            }\r\n\r\n            const queryMirrorNodes = element.querySelectorAll(\r\n              \"[string-copy-from],[data-string-copy-from]\"\r\n            );\r\n            for (let i = 0; i < queryMirrorNodes.length; i++) {\r\n              this.detachMirrorByElement(queryMirrorNodes[i] as HTMLElement);\r\n            }\r\n          }\r\n\r\n          // Added elements\r\n          for (let addedIndex = 0; addedIndex < mutation.addedNodes.length; addedIndex++) {\r\n            const node = mutation.addedNodes[addedIndex];\r\n            if (node.nodeType !== Node.ELEMENT_NODE) continue;\r\n            mutationHasElementNodes = true;\r\n\r\n            const element = node as HTMLElement;\r\n\r\n            if (this.isFixed(element)) continue;\r\n\r\n            if (element.hasAttribute(\"string\") && !element.hasAttribute(\"string-inited\")) {\r\n              this.add(element);\r\n            }\r\n\r\n            const queryAddedStringNodes = element.querySelectorAll(\r\n              \"[string]:not([string-inited]),[data-string]:not([string-inited])\"\r\n            );\r\n            for (let i = 0; i < queryAddedStringNodes.length; i++) {\r\n              this.add(queryAddedStringNodes[i] as HTMLElement);\r\n            }\r\n\r\n            // Check for connect-from logic\r\n            const copyFrom =\r\n              element.getAttribute(\"string-copy-from\") ??\r\n              element.getAttribute(\"data-string-copy-from\");\r\n\r\n            if (copyFrom) {\r\n              this.linkMirror(copyFrom, element);\r\n            }\r\n\r\n            const queryAddedMirrorNodes = element.querySelectorAll(\r\n              \"[string-copy-from],[data-string-copy-from]\"\r\n            );\r\n            for (let i = 0; i < queryAddedMirrorNodes.length; i++) {\r\n              const child = queryAddedMirrorNodes[i];\r\n              const childCopyFrom =\r\n                child.getAttribute(\"string-copy-from\") ??\r\n                child.getAttribute(\"data-string-copy-from\");\r\n              if (childCopyFrom) {\r\n                this.linkMirror(childCopyFrom, child as HTMLElement);\r\n              }\r\n            }\r\n          }\r\n\r\n          if (mutationHasElementNodes) {\r\n            this.modules.onDOMMutate(mutation.addedNodes, mutation.removedNodes);\r\n            shouldNotifyDOMRebuild = true;\r\n          }\r\n        }\r\n      }\r\n\r\n      if (shouldNotifyDOMRebuild) {\r\n        const all = this.modules.all;\r\n        for (let i = 0; i < all.length; i++) {\r\n          all[i].onDOMRebuild();\r\n        }\r\n        this.events.emit(\"dom:changed\", null);\r\n      }\r\n    });\r\n\r\n    observer.observe(document.body, {\r\n      childList: true,\r\n      subtree: true,\r\n    });\r\n    this.domObserver = observer;\r\n  }\r\n\r\n  /**\r\n   * Removes an object and its observers.\r\n   */\r\n  private handleRemoved(el: HTMLElement): void {\r\n    const id = el.getAttribute(\"string-id\") ?? el.getAttribute(\"data-string-id\");\r\n    if (!id) return;\r\n\r\n    const copyFrom =\r\n      el.getAttribute(\"string-copy-from\") ?? el.getAttribute(\"data-string-copy-from\");\r\n    if (copyFrom) {\r\n      this.connectQueue = this.connectQueue.filter((q) => q.id !== copyFrom);\r\n    }\r\n\r\n    this.remove(id);\r\n  }\r\n\r\n  /**\r\n   * Re-applies module initialization logic to all managed objects after settings change.\r\n   *\r\n   * This method should be called when `StringSettings` are updated at runtime,\r\n   * especially if the new settings affect how modules calculate offsets,\r\n   * easing, origins, or custom configuration.\r\n   *\r\n   * Internally, it re-runs `initializeObject`, `calculatePositions`, and `connectObject`\r\n   * for each core module that can connect to the object.\r\n   *\r\n   * This is useful for supporting dynamic configuration updates without requiring\r\n   * a full DOM rebuild or reinitialization.\r\n   */\r\n  public onSettingsChange(data: ISettingsChangeData) {\r\n    for (const object of this.objects.values()) {\r\n      if (!object.htmlElement || !object.htmlElement.isConnected) continue;\r\n\r\n      let attributes: Record<string, any> | null = null;\r\n      const all = this.modules.all;\r\n      for (let i = 0; i < all.length; i++) {\r\n        const m = all[i];\r\n        let isCanRebuild = false;\r\n        if (data.isDesktop) {\r\n          if (m.permissions.desktop.rebuild.scrollHeight && data.scrollHeightChanged) {\r\n            isCanRebuild = true;\r\n          }\r\n          if (m.permissions.desktop.rebuild.width && data.widthChanged) {\r\n            isCanRebuild = true;\r\n          }\r\n          if (m.permissions.desktop.rebuild.height && data.heightChanged) {\r\n            isCanRebuild = true;\r\n          }\r\n        } else {\r\n          if (m.permissions.mobile.rebuild.scrollHeight && data.scrollHeightChanged) {\r\n            isCanRebuild = true;\r\n          }\r\n          if (m.permissions.mobile.rebuild.width && data.widthChanged) {\r\n            isCanRebuild = true;\r\n          }\r\n          if (m.permissions.mobile.rebuild.height && data.heightChanged) {\r\n            isCanRebuild = true;\r\n          }\r\n        }\r\n\r\n        if (isCanRebuild || data.isForceRebuild) {\r\n          if (m.canConnect(object)) {\r\n            if (attributes == null) {\r\n              attributes = this.getAllAttributes(object.htmlElement);\r\n            }\r\n            m.initializeObject(this.globalId, object, object.htmlElement, attributes);\r\n            m.calculatePositions(object, this.data.viewport.windowHeight);\r\n            m.connectObject(object);\r\n          }\r\n        }\r\n      }\r\n    }\r\n    this.inviewIndexDirty = true;\r\n  }\r\n\r\n  /**\r\n   * Checks whether the element is marked as fixed (not managed).\r\n   */\r\n  private isFixed(el: HTMLElement): boolean {\r\n    return el.hasAttribute(\"string-fixed\");\r\n  }\r\n\r\n  public checkInview() {\r\n    const scrollPos = this.data.scroll.transformedCurrent;\r\n    this.updateInviewWindow(scrollPos);\r\n    for (const object of this.inviewActive) {\r\n      this.checkInviewForObject(object);\r\n    }\r\n  }\r\n\r\n  private checkInviewForObject(object: StringObject) {\r\n    const scrollPos = this.data.scroll.transformedCurrent;\r\n    if (!this.intersectionObserverEnabled) {\r\n      const activeStart = object.getProperty<number>(\"start-position\");\r\n      const activeEnd = object.getProperty<number>(\"end-position\");\r\n      if (activeStart != null && activeEnd != null) {\r\n        const activeMin = Math.min(activeStart, activeEnd);\r\n        const activeMax = Math.max(activeStart, activeEnd);\r\n        const wasActive = object.getProperty<boolean>(\"is-active\") ?? false;\r\n        const isActive = scrollPos >= activeMin && scrollPos <= activeMax;\r\n        if (isActive !== wasActive) {\r\n          object.setProperty(\"is-active\", isActive);\r\n          this.events.emit(object.getScopedEventName(\"object:activate\"), isActive);\r\n          isActive ? object.enter() : object.leave();\r\n        }\r\n      }\r\n    }\r\n    const inviewStart = object.getProperty<number>(\"inview-start-position\");\r\n    const inviewEnd = object.getProperty<number>(\"inview-end-position\");\r\n    const wasInView = object.getProperty<boolean>(\"is-inview\") ?? false;\r\n\r\n    const start = Math.min(inviewStart, inviewEnd);\r\n    const end = Math.max(inviewStart, inviewEnd);\r\n    const isNowInView = scrollPos >= start && scrollPos <= end;\r\n\r\n    let direction: \"enter-top\" | \"enter-bottom\" | \"exit-top\" | \"exit-bottom\" | null = null;\r\n    if (!wasInView && isNowInView) {\r\n      const distToStart = Math.abs(scrollPos - start);\r\n      const distToEnd = Math.abs(end - scrollPos);\r\n      direction = distToStart <= distToEnd ? \"enter-top\" : \"enter-bottom\";\r\n    } else if (wasInView && !isNowInView) {\r\n      direction = scrollPos < start ? \"exit-top\" : \"exit-bottom\";\r\n    }\r\n    if (isNowInView !== wasInView) {\r\n      object.setProperty(\"is-inview\", isNowInView);\r\n      object.setInviewAutoBlocked(false);\r\n      object.setInviewManualActive(false);\r\n      isNowInView ? object.show() : object.hide();\r\n      this.events.emit(object.getScopedEventName(\"object:inview\"), {\r\n        inView: isNowInView,\r\n        direction,\r\n      });\r\n    }\r\n  }\r\n\r\n  private updateInviewWindow(scrollPos: number) {\r\n    const buffer = this.data.viewport.windowHeight;\r\n    const windowMin = scrollPos - buffer;\r\n    const windowMax = scrollPos + this.data.viewport.windowHeight + buffer;\r\n\r\n    if (this.inviewIndexDirty || scrollPos < this.lastInviewScrollPos) {\r\n      this.rebuildInviewIndex(windowMin, windowMax);\r\n    }\r\n\r\n    while (\r\n      this.inviewStartIdx < this.inviewStarts.length &&\r\n      this.inviewStarts[this.inviewStartIdx].pos <= windowMax\r\n    ) {\r\n      this.inviewActive.add(this.inviewStarts[this.inviewStartIdx].object);\r\n      this.inviewStartIdx++;\r\n    }\r\n\r\n    while (\r\n      this.inviewEndIdx < this.inviewEnds.length &&\r\n      this.inviewEnds[this.inviewEndIdx].pos < windowMin\r\n    ) {\r\n      this.inviewActive.delete(this.inviewEnds[this.inviewEndIdx].object);\r\n      this.inviewEndIdx++;\r\n    }\r\n\r\n    this.lastInviewScrollPos = scrollPos;\r\n  }\r\n\r\n  private rebuildInviewIndex(windowMin: number, windowMax: number) {\r\n    this.inviewStarts = [];\r\n    this.inviewEnds = [];\r\n\r\n    for (const object of this.objects.values()) {\r\n      const start = object.getProperty<number>(\"inview-start-position\");\r\n      const end = object.getProperty<number>(\"inview-end-position\");\r\n      if (start == null || end == null) continue;\r\n      this.inviewStarts.push({ pos: Math.min(start, end), object });\r\n      this.inviewEnds.push({ pos: Math.max(start, end), object });\r\n    }\r\n\r\n    this.inviewStarts.sort((a, b) => a.pos - b.pos);\r\n    this.inviewEnds.sort((a, b) => a.pos - b.pos);\r\n\r\n    this.inviewActive.clear();\r\n\r\n    this.inviewStartIdx = this.upperBound(this.inviewStarts, windowMax);\r\n    this.inviewEndIdx = this.upperBound(this.inviewEnds, windowMin - 1);\r\n\r\n    for (let i = 0; i < this.inviewStartIdx; i++) {\r\n      this.inviewActive.add(this.inviewStarts[i].object);\r\n    }\r\n    for (let i = 0; i < this.inviewEndIdx; i++) {\r\n      this.inviewActive.delete(this.inviewEnds[i].object);\r\n    }\r\n\r\n    this.inviewIndexDirty = false;\r\n  }\r\n\r\n  private upperBound(list: Array<{ pos: number }>, value: number): number {\r\n    let low = 0;\r\n    let high = list.length;\r\n    while (low < high) {\r\n      const mid = (low + high) >>> 1;\r\n      if (list[mid].pos <= value) low = mid + 1;\r\n      else high = mid;\r\n    }\r\n    return low;\r\n  }\r\n\r\n  private splitPipeAndTrim(raw: string): string[] {\r\n    const parts = raw.split(\"|\");\r\n    const result: string[] = [];\r\n    for (let i = 0; i < parts.length; i++) {\r\n      const item = parts[i].trim();\r\n      if (item.length > 0) {\r\n        result.push(item);\r\n      }\r\n    }\r\n    return result;\r\n  }\r\n\r\n  private parseStringTokens(raw: string): StringToken[] {\r\n    const chunks = this.splitTopLevelPipe(raw);\r\n    const tokens: StringToken[] = [];\r\n\r\n    for (let i = 0; i < chunks.length; i++) {\r\n      const chunk = chunks[i].trim();\r\n      if (chunk.length === 0) continue;\r\n\r\n      const match = chunk.match(/^([^\\[\\]]+?)(?:\\[([^\\]]*)\\])?$/);\r\n      if (!match) {\r\n        tokens.push({\r\n          raw: chunk,\r\n          key: chunk,\r\n          modeSpec: { kind: \"default\", values: [] },\r\n        });\r\n        continue;\r\n      }\r\n\r\n      const key = match[1].trim();\r\n      const modeRaw = match[2];\r\n\r\n      if (!key) {\r\n        continue;\r\n      }\r\n\r\n      if (modeRaw == null) {\r\n        tokens.push({\r\n          raw: chunk,\r\n          key,\r\n          modeSpec: { kind: \"default\", values: [] },\r\n        });\r\n        continue;\r\n      }\r\n\r\n      const normalizedModeRaw = modeRaw.trim();\r\n      if (normalizedModeRaw.length === 0) {\r\n        tokens.push({\r\n          raw: chunk,\r\n          key,\r\n          modeSpec: { kind: \"all\", values: [] },\r\n        });\r\n        continue;\r\n      }\r\n\r\n      const values = this.splitTopLevelPipe(normalizedModeRaw)\r\n        .map((value) => value.trim())\r\n        .filter((value) => value.length > 0) as ScrollMode[];\r\n\r\n      tokens.push({\r\n        raw: chunk,\r\n        key,\r\n        modeSpec: values.length > 0\r\n          ? { kind: \"include\", values }\r\n          : { kind: \"all\", values: [] },\r\n      });\r\n    }\r\n\r\n    return tokens;\r\n  }\r\n\r\n  private splitTopLevelPipe(raw: string): string[] {\r\n    const result: string[] = [];\r\n    let current = \"\";\r\n    let bracketDepth = 0;\r\n\r\n    for (let i = 0; i < raw.length; i++) {\r\n      const char = raw[i];\r\n\r\n      if (char === \"[\") {\r\n        bracketDepth++;\r\n        current += char;\r\n        continue;\r\n      }\r\n\r\n      if (char === \"]\") {\r\n        bracketDepth = Math.max(0, bracketDepth - 1);\r\n        current += char;\r\n        continue;\r\n      }\r\n\r\n      if (char === \"|\" && bracketDepth === 0) {\r\n        result.push(current);\r\n        current = \"\";\r\n        continue;\r\n      }\r\n\r\n      current += char;\r\n    }\r\n\r\n    if (current.length > 0) {\r\n      result.push(current);\r\n    }\r\n\r\n    return result;\r\n  }\r\n\r\n  public destroy(): void {\r\n    this.domObserver?.disconnect();\r\n    this.domObserver = null;\r\n    this.domBatcher.clear();\r\n  }\r\n}\r\n","/**\r\n * CSS class names applied to `<html>` element based on scroll direction.\r\n */\r\nexport const SCROLL_CLASS_NAMES = {\r\n  SCROLL_FORWARD: \"-scroll-forward\",\r\n  SCROLL_BACKWARD: \"-scroll-backward\",\r\n  SCROLLING_FORWARD: \"-scrolling-forward\",\r\n  SCROLLING_BACKWARD: \"-scrolling-backward\",\r\n} as const;\r\n","import { SCROLL_CLASS_NAMES } from \"../../models/scroll/ScrollHTMLClass\";\r\nimport { ScrollMarkRule } from \"../../models/scroll/ScrollTriggerRule\";\r\nimport { StringContext } from \"../StringContext\";\r\n\r\nexport class ScrollController {\r\n  protected context: StringContext;\r\n  protected document: Document;\r\n\r\n  public name: string = \"\";\r\n  public isProg: boolean = false;\r\n  public isParallaxEnabled: boolean = false;\r\n\r\n  protected _isVertical: boolean = true;\r\n\r\n  protected _scrollDirState: number = -1;\r\n  protected _lastAppliedDirState: number = -1;\r\n  protected isLastBottomScrollDirection: boolean = true;\r\n\r\n  protected scrollTriggerRules: Array<ScrollMarkRule> = [];\r\n  protected isActive: boolean = false;\r\n\r\n  public set scrollDirection(dir: \"vertical\" | \"horizontal\") {\r\n    this._isVertical = dir === \"vertical\";\r\n  }\r\n\r\n  constructor(context: StringContext) {\r\n    this.document = document;\r\n    this.context = context;\r\n  }\r\n\r\n  public onChangeDirection = () => {};\r\n  public onScrollStart = () => {};\r\n  public onScrollStop = () => {};\r\n\r\n  public onCalcUpdate(): void {\r\n    if (!this.isActive) return;\r\n\r\n    const container = this.context.data.scroll.scrollContainer;\r\n    const current = this.context.data.scroll.current;\r\n\r\n    if (container) {\r\n      if (this._isVertical) {\r\n        container.scrollTo(0, current);\r\n      } else {\r\n        container.scrollTo(current, 0);\r\n      }\r\n    }\r\n\r\n    if (this._isVertical) {\r\n      this.triggerScrollRules();\r\n    }\r\n  }\r\n\r\n  public onFrame(): void {}\r\n  public onWheel(e: any): void {}\r\n  public onScroll(e: any): void {}\r\n  public onTouchStart(e: TouchEvent): void {}\r\n  public onTouchMove(e: TouchEvent): void {}\r\n  public onTouchEnd(e: TouchEvent): void {}\r\n  public disableScrollEvents(): void {}\r\n  public enableScrollEvents(): void {}\r\n\r\n  public activate(): void {\r\n    if (this.isActive) return;\r\n    this.isActive = true;\r\n    this.enableScrollEvents();\r\n  }\r\n\r\n  public deactivate(): void {\r\n    if (!this.isActive) return;\r\n    this.isActive = false;\r\n    this.disableScrollEvents();\r\n    this.isProg = false;\r\n\r\n    const scrollData = this.context.data.scroll;\r\n    scrollData.target = scrollData.current;\r\n    scrollData.delta = 0;\r\n    scrollData.lerped = 0;\r\n    scrollData.displacement = 0;\r\n\r\n    this.clearScrollingClasses();\r\n    this._scrollDirState = -1;\r\n    this._lastAppliedDirState = -1;\r\n    this.onScrollStop();\r\n  }\r\n\r\n  public destroy(): void {}\r\n\r\n  protected updateScrollDirection(isDown: boolean) {\r\n    this.isLastBottomScrollDirection = isDown;\r\n    const newState = isDown ? 1 : 0;\r\n\r\n    if (this._scrollDirState === -1) {\r\n      this._scrollDirState = newState;\r\n      return;\r\n    }\r\n\r\n    this._scrollDirState = newState;\r\n    this.context.data.scroll.isScrollingDown = isDown;\r\n    this.onChangeDirection();\r\n    this.context.events.emit(`scroll:direction:change`, isDown);\r\n\r\n    if (this.context.settings[\"global-class\"] && this._lastAppliedDirState !== newState) {\r\n      const rootClasses = document.documentElement.classList;\r\n\r\n      if (isDown) {\r\n        rootClasses.remove(\r\n          SCROLL_CLASS_NAMES.SCROLLING_BACKWARD,\r\n          SCROLL_CLASS_NAMES.SCROLL_BACKWARD,\r\n        );\r\n        rootClasses.add(SCROLL_CLASS_NAMES.SCROLLING_FORWARD, SCROLL_CLASS_NAMES.SCROLL_FORWARD);\r\n      } else {\r\n        rootClasses.remove(SCROLL_CLASS_NAMES.SCROLLING_FORWARD, SCROLL_CLASS_NAMES.SCROLL_FORWARD);\r\n        rootClasses.add(SCROLL_CLASS_NAMES.SCROLLING_BACKWARD, SCROLL_CLASS_NAMES.SCROLL_BACKWARD);\r\n      }\r\n\r\n      this._lastAppliedDirState = newState;\r\n    }\r\n  }\r\n\r\n  protected clearScrollingClasses() {\r\n    document.documentElement.classList.remove(\r\n      SCROLL_CLASS_NAMES.SCROLLING_BACKWARD,\r\n      SCROLL_CLASS_NAMES.SCROLLING_FORWARD,\r\n      SCROLL_CLASS_NAMES.SCROLL_BACKWARD,\r\n      SCROLL_CLASS_NAMES.SCROLL_FORWARD,\r\n    );\r\n  }\r\n\r\n  protected triggerScrollRules() {\r\n    const rules = this.scrollTriggerRules;\r\n    const len = rules.length;\r\n    const currentScroll = this.context.data.scroll.current;\r\n    const isDown = this.isLastBottomScrollDirection;\r\n\r\n    for (let i = 0; i < len; i++) {\r\n      const rule = rules[i];\r\n\r\n      const directionMatches =\r\n        rule.direction === \"any\" ||\r\n        (isDown && rule.direction === \"forward\") ||\r\n        (!isDown && rule.direction === \"backward\");\r\n\r\n      const shouldTrigger = directionMatches && currentScroll >= rule.offset;\r\n\r\n      if (shouldTrigger && !rule.isActive) {\r\n        rule.isActive = true;\r\n        rule.onEnter?.();\r\n        if (rule.toggleClass) {\r\n          rule.toggleClass.target.classList.add(rule.toggleClass.className);\r\n        }\r\n      } else if (!shouldTrigger && rule.isActive) {\r\n        rule.isActive = false;\r\n        rule.onLeave?.();\r\n        if (rule.toggleClass) {\r\n          rule.toggleClass.target.classList.remove(rule.toggleClass.className);\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  public addScrollMark(rule: ScrollMarkRule) {\r\n    this.scrollTriggerRules.push(rule);\r\n  }\r\n\r\n  public removeScrollMark(id: string) {\r\n    const rules = this.scrollTriggerRules;\r\n    for (let i = 0; i < rules.length; i++) {\r\n      if (rules[i].id === id) {\r\n        rules.splice(i, 1);\r\n        break;\r\n      }\r\n    }\r\n  }\r\n\r\n  public scrollTo(position: number, immediate?: boolean): void {}\r\n}\r\n","import { StringContext } from \"../StringContext\";\nimport { ScrollController } from \"./ScrollController\";\n\n/**\n * Default scroll controller using native browser scrolling behavior.\n * Handles `scrollTop`, easing delta over time for smooth lerped animations.\n */\nexport class StringScrollDefault extends ScrollController {\n  /** Unique name identifier for this scroll mode. */\n  public readonly name: string = \"default\";\n\n  /** Last known scroll position for direction detection */\n  private previousScrollTop: number = 0;\n\n  private previousScrollTime: number = 0;\n  private isScrolling: boolean = false;\n  private lastScrollEventTime: number = 0;\n  private nativeVelocity: number = 0;\n  private nativeVelocityTarget: number = 0;\n  private readonly scrollStopDelay = 120;\n  private readonly nativeVelocityFollow = 0.2;\n  private readonly nativeVelocityDecay = 0.84;\n  private readonly nativeVelocityBoost = 2;\n  private readonly nativeVelocityDeadzone = 0.25;\n\n  /**\n   * Constructs a new instance of the default scroll controller.\n   * @param context Shared string system context.\n   */\n  constructor(context: StringContext) {\n    super(context);\n  }\n\n  /**\n   * Called every animation frame.\n   * Applies easing to scroll delta and updates lerped value.\n   * Fires `onScrollStop` once movement has settled.\n   */\n  public onFrame(): void {\n    let lerped = 0;\n\n    if (this.context.data.scroll.delta !== 0) {\n      const delta = this.context.data.scroll.delta * this.context.data.scroll.speedAccelerate;\n      this.context.data.scroll.delta -= delta;\n      lerped = delta;\n      // this.onCalcUpdate();\n\n      if (Math.abs(lerped) < 0.1) {\n        this.context.data.scroll.delta = 0;\n        lerped = 0;\n      }\n    }\n\n    const now = performance.now();\n\n    this.nativeVelocityTarget *= this.nativeVelocityDecay;\n    if (Math.abs(this.nativeVelocityTarget) < this.nativeVelocityDeadzone) {\n      this.nativeVelocityTarget = 0;\n    }\n\n    this.nativeVelocity +=\n      (this.nativeVelocityTarget - this.nativeVelocity) * this.nativeVelocityFollow;\n\n    if (Math.abs(this.nativeVelocity) < this.nativeVelocityDeadzone) {\n      this.nativeVelocity = 0;\n    }\n\n    if (Math.abs(this.nativeVelocity) > Math.abs(lerped)) {\n      lerped = this.nativeVelocity;\n    }\n\n    this.context.data.scroll.lerped = lerped;\n\n    if (this.isScrolling) {\n      const hasSyntheticMomentum =\n        this.context.data.scroll.delta !== 0 ||\n        this.nativeVelocityTarget !== 0 ||\n        this.nativeVelocity !== 0;\n\n      if (!hasSyntheticMomentum && now - this.lastScrollEventTime > this.scrollStopDelay) {\n        this.isScrolling = false;\n        this.onScrollStop();\n        this.clearScrollingClasses();\n      }\n    }\n  }\n\n  /**\n   * Called on native scroll event.\n   * Syncs the internal scroll state with the current page scroll.\n   * @param e Scroll event object (unused).\n   */\n  public onScroll(e: any): void {\n    const now = performance.now();\n    const scrollTop = this.context.data.scroll.elementContainer.scrollTop;\n    const positionDelta = scrollTop - this.previousScrollTop;\n    this.context.data.scroll.current = scrollTop;\n    this.context.data.scroll.target = scrollTop;\n    this.context.data.scroll.transformedCurrent =\n      scrollTop * this.context.data.viewport.transformScale;\n\n    if (positionDelta !== 0) {\n      this.updateScrollDirection(positionDelta > 0);\n\n      const timeDelta = this.previousScrollTime === 0 ? 16.6667 : now - this.previousScrollTime;\n      const normalizedDelta =\n        positionDelta * (16.6667 / Math.max(8, timeDelta)) * this.nativeVelocityBoost;\n\n      this.nativeVelocityTarget = normalizedDelta;\n\n      this.previousScrollTop = scrollTop;\n      this.previousScrollTime = now;\n    }\n\n    this.triggerScrollRules();\n\n    this.lastScrollEventTime = now;\n    if (!this.isScrolling) {\n      this.isScrolling = true;\n      this.onScrollStart();\n    }\n  }\n\n  /**\n   * Handles wheel input by updating scroll delta for easing.\n   * Triggers `onScrollStart` if delta begins from zero.\n   * @param e Wheel event.\n   */\n  public onWheel(e: any): void {\n    if (e.deltaY !== 0) {\n      if (this.context.data.scroll.delta === 0 && !this.isScrolling) {\n        this.isScrolling = true;\n        this.onScrollStart();\n      }\n      this.context.data.scroll.delta += e.deltaY;\n\n      this.lastScrollEventTime = performance.now();\n    }\n  }\n\n  public deactivate(): void {\n    super.deactivate();\n    this.isScrolling = false;\n    this.lastScrollEventTime = 0;\n    this.previousScrollTop = this.context.data.scroll.current;\n    this.previousScrollTime = 0;\n    this.nativeVelocity = 0;\n    this.nativeVelocityTarget = 0;\n  }\n\n  public scrollTo(position: number, immediate?: boolean) {\n    this.context.data.scroll.target = position;\n    this.context.data.scroll.current = position;\n    this.context.data.scroll.delta = 0;\n    this.context.data.scroll.lerped = 0;\n    this.nativeVelocity = 0;\n    this.nativeVelocityTarget = 0;\n    this.previousScrollTop = position;\n    this.previousScrollTime = 0;\n    this.triggerScrollRules();\n\n    if (this._scrollDirection === \"vertical\") {\n      this.context.data.scroll.scrollContainer?.scrollTo({\n        top: position,\n        left: 0,\n        behavior: immediate ? \"auto\" : \"smooth\",\n      });\n    } else {\n      this.context.data.scroll.scrollContainer?.scrollTo({\n        left: position,\n        top: 0,\n        behavior: immediate ? \"auto\" : \"smooth\",\n      });\n    }\n  }\n}\n","import { StringContext } from \"../StringContext\";\r\nimport { ScrollController } from \"./ScrollController\";\r\n\r\n/**\r\n * Scroll controller that disables all user-initiated scrolling.\r\n * Prevents native scroll and wheel behavior, effectively locking the page.\r\n */\r\nexport class StringScrollDisable extends ScrollController {\r\n  /** Unique name identifier for this scroll mode. */\r\n  public readonly name: string = \"disable\";\r\n\r\n  /**\r\n   * Constructs the scroll disabling controller.\r\n   * @param context The shared string system context.\r\n   */\r\n\r\n  private preventScroll = (e: Event) => {\r\n    e.preventDefault();\r\n  };\r\n\r\n  private preventKeyScroll = (e: KeyboardEvent) => {\r\n    const keysThatScroll = [\r\n      \"ArrowUp\",\r\n      \"ArrowDown\",\r\n      \"PageUp\",\r\n      \"PageDown\",\r\n      \" \",\r\n      \"Home\",\r\n      \"End\",\r\n    ];\r\n    if (keysThatScroll.includes(e.key)) {\r\n      e.preventDefault();\r\n    }\r\n  };\r\n\r\n  private onPreventScroll = this.preventScroll.bind(this);\r\n  private onPreventKeyScroll = this.preventKeyScroll.bind(this);\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n  }\r\n\r\n  enableScrollEvents() {\r\n    window.addEventListener(\"touchmove\", this.onPreventScroll, {\r\n      passive: false,\r\n    });\r\n    window.addEventListener(\"keydown\", this.onPreventKeyScroll);\r\n  }\r\n\r\n  disableScrollEvents() {\r\n    window.removeEventListener(\"touchmove\", this.onPreventScroll);\r\n    window.removeEventListener(\"keydown\", this.onPreventKeyScroll);\r\n  }\r\n\r\n  /**\r\n   * Called on each animation frame.\r\n   * Not used in this controller since scrolling is disabled.\r\n   */\r\n  public onFrame(): void {}\r\n\r\n  /**\r\n   * Prevents scroll via mouse wheel.\r\n   * @param e Wheel event.\r\n   */\r\n  public onWheel(e: any): void {\r\n    e.preventDefault();\r\n  }\r\n\r\n  /**\r\n   * Prevents scroll via native scroll interaction (e.g. touch).\r\n   * @param e Scroll event.\r\n   */\r\n  public onScroll(e: any): void {\r\n    e.preventDefault();\r\n  }\r\n}\r\n","import { StringContext } from \"../StringContext\";\r\nimport { ScrollController } from \"./ScrollController\";\r\n\r\ntype SmoothComputeStepResult = {\r\n  current: number;\r\n  target: number;\r\n  delta: number;\r\n  lerped: number;\r\n  scrollForce: number;\r\n  absVelocity: number;\r\n};\r\n\r\nexport class StringScrollSmooth extends ScrollController {\r\n  public readonly name: string = \"smooth\";\r\n\r\n  private scrollForce: number = 0.0;\r\n  private wheelImpulse: number = 0.0;\r\n  private previousCurrent: number = 0.0;\r\n\r\n  private readonly velocityThreshold = 0.01;\r\n\r\n  private readonly stepResult: SmoothComputeStepResult = {\r\n    current: 0.1,\r\n    target: 0.1,\r\n    delta: 0.1,\r\n    lerped: 0.1,\r\n    scrollForce: 0.1,\r\n    absVelocity: 0.1,\r\n  };\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.stepResult.current = 0.0;\r\n    this.stepResult.target = 0.0;\r\n    this.stepResult.delta = 0.0;\r\n    this.stepResult.lerped = 0.0;\r\n    this.stepResult.scrollForce = 0.0;\r\n    this.stepResult.absVelocity = 0.0;\r\n  }\r\n\r\n  public stopScroll(): void {\r\n    const scrollData = this.context.data.scroll;\r\n    scrollData.lerped = 0.0;\r\n    scrollData.delta = 0.0;\r\n    scrollData.target = scrollData.current;\r\n    this.isProg = false;\r\n    this.onCalcUpdate();\r\n    this.clearScrollingClasses();\r\n    this._scrollDirState = -1;\r\n    this._lastAppliedDirState = -1;\r\n  }\r\n\r\n  public onFrame(): void {\r\n    const scrollData = this.context.data.scroll;\r\n\r\n    if (scrollData.delta !== 0.0) {\r\n      this.computeStep(\r\n        scrollData.current,\r\n        scrollData.target,\r\n        scrollData.delta,\r\n        scrollData.speed,\r\n        scrollData.speedAccelerate,\r\n        scrollData.bottomPosition,\r\n        this.stepResult,\r\n      );\r\n\r\n      this.scrollForce = this.stepResult.scrollForce;\r\n      scrollData.target = this.stepResult.target;\r\n      scrollData.delta = this.stepResult.delta;\r\n      scrollData.lerped = this.stepResult.lerped;\r\n      scrollData.current = this.stepResult.current;\r\n\r\n      const scale = this.context.data.viewport.transformScale;\r\n      scrollData.transformedCurrent =\r\n        scale !== 1.0 ? scrollData.current * scale : scrollData.current;\r\n\r\n      this.updateScrollDirection(scrollData.lerped > 0.0);\r\n\r\n      if (this.stepResult.absVelocity < this.velocityThreshold) {\r\n        scrollData.current = Math.round(scrollData.target);\r\n        this.previousCurrent = scrollData.current;\r\n        this.onCalcUpdate();\r\n        this.stopScroll();\r\n        this.onScrollStop();\r\n      } else {\r\n        this.isProg = true;\r\n        if (this.previousCurrent !== scrollData.current) {\r\n          this.previousCurrent = scrollData.current;\r\n          this.onCalcUpdate();\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  public onWheel(e: WheelEvent): void {\r\n    if (e.deltaY !== 0.0) {\r\n      e.preventDefault();\r\n    }\r\n\r\n    this.wheelImpulse = e.deltaY;\r\n    if (this.wheelImpulse === 0.0) return;\r\n\r\n    const scrollData = this.context.data.scroll;\r\n\r\n    if (scrollData.delta === 0.0) {\r\n      this.onScrollStart();\r\n    }\r\n\r\n    const isScrollingUp = this.wheelImpulse < 0;\r\n    const atTop = scrollData.target === 0.0 && isScrollingUp;\r\n    const atBottom = scrollData.target === scrollData.bottomPosition && !isScrollingUp;\r\n\r\n    if (!atTop && !atBottom) {\r\n      scrollData.delta += this.wheelImpulse;\r\n    }\r\n  }\r\n\r\n  public onScroll(e: Event): void {\r\n    if (!this.isProg) {\r\n      const scrollData = this.context.data.scroll;\r\n      const nativeScrollTop = scrollData.elementContainer.scrollTop;\r\n      const positionDelta = nativeScrollTop - scrollData.current;\r\n\r\n      scrollData.current = nativeScrollTop;\r\n      scrollData.target = nativeScrollTop;\r\n      scrollData.delta = 0.0;\r\n      scrollData.lerped = positionDelta;\r\n      scrollData.displacement = 0.0;\r\n\r\n      const scale = this.context.data.viewport.transformScale;\r\n      scrollData.transformedCurrent = scale !== 1.0 ? nativeScrollTop * scale : nativeScrollTop;\r\n\r\n      this.scrollForce = 0.0;\r\n      this.wheelImpulse = 0.0;\r\n      this.isProg = false;\r\n      this.previousCurrent = nativeScrollTop;\r\n\r\n      if (positionDelta !== 0.0) {\r\n        this.updateScrollDirection(positionDelta > 0.0);\r\n        this.triggerScrollRules();\r\n      }\r\n    }\r\n  }\r\n\r\n  public deactivate(): void {\r\n    super.deactivate();\r\n    this.scrollForce = 0.0;\r\n    this.wheelImpulse = 0.0;\r\n    this.previousCurrent = this.context.data.scroll.current;\r\n  }\r\n\r\n  public scrollTo(position: number, immediate?: boolean) {\r\n    const scrollData = this.context.data.scroll;\r\n\r\n    if (immediate) {\r\n      scrollData.current = position;\r\n      scrollData.target = position;\r\n      scrollData.delta = 0.0;\r\n      scrollData.lerped = 0.0;\r\n\r\n      const scale = this.context.data.viewport.transformScale;\r\n      scrollData.transformedCurrent = scale !== 1.0 ? position * scale : position;\r\n\r\n      this.onCalcUpdate();\r\n      return;\r\n    }\r\n\r\n    scrollData.target = position;\r\n    scrollData.delta = 1.0;\r\n  }\r\n\r\n  private computeStep(\r\n    current: number,\r\n    target: number,\r\n    delta: number,\r\n    speed: number,\r\n    speedAccelerate: number,\r\n    bottomPosition: number,\r\n    out: SmoothComputeStepResult,\r\n  ): void {\r\n    const scrollForce = delta * speedAccelerate;\r\n\r\n    const nextTarget = Math.min(Math.max(0.0, target + scrollForce), bottomPosition);\r\n    const lerped = (nextTarget - current) * speed;\r\n    const nextDelta = delta - scrollForce;\r\n\r\n    const nextCurrent = current + lerped;\r\n\r\n    out.current = nextCurrent;\r\n    out.target = nextTarget;\r\n    out.delta = nextDelta;\r\n    out.lerped = lerped;\r\n    out.scrollForce = scrollForce;\r\n    out.absVelocity = Math.abs(lerped);\r\n  }\r\n}\r\n","import { ScrollMarkRule } from \"../../models/scroll/ScrollTriggerRule\";\r\nimport { ScrollMode } from \"../../states/ScrollState\";\r\nimport { ScrollController } from \"../controllers/ScrollController\";\r\nimport { StringScrollDefault } from \"../controllers/StringScrollDefault\";\r\nimport { StringScrollDisable } from \"../controllers/StringScrollDisable\";\r\nimport { StringScrollSmooth } from \"../controllers/StringScrollSmooth\";\r\nimport { StringContext } from \"../StringContext\";\r\n\r\n/**\r\n * Handles scroll engine setup and switching logic.\r\n * Synchronizes scroll modes with the centralized ScrollState inside StringContext.\r\n */\r\nexport class ScrollManager {\r\n  private modes: Map<ScrollMode, ScrollController> = new Map();\r\n  private boundEvents: {\r\n    onScrollStart: () => void;\r\n    onScrollStop: () => void;\r\n    onDirectionChange: () => void;\r\n    onModeChange: () => void;\r\n  } | null = null;\r\n\r\n  private scrollMarks: ScrollMarkRule[] = [];\r\n\r\n  constructor(private context: StringContext) {\r\n    this.registerMode(\"smooth\", new StringScrollSmooth(context));\r\n    this.registerMode(\"default\", new StringScrollDefault(context));\r\n    this.registerMode(\"disable\", new StringScrollDisable(context));\r\n\r\n    // Initial mode based on screen width\r\n    this.updateResponsiveMode();\r\n  }\r\n\r\n  /**\r\n   * Registers a new scroll mode with a given name and controller.\r\n   * Can be used to overwrite existing modes or add custom ones.\r\n   *\r\n   * @param name The unique name of the scroll mode.\r\n   * @param controller The ScrollController instance.\r\n   */\r\n  public registerMode(name: ScrollMode, controller: ScrollController): void {\r\n    const isCurrentMode = this.context.data.scroll.mode === name;\r\n    const existing = this.modes.get(name);\r\n\r\n    if (existing) {\r\n      if (isCurrentMode) {\r\n        existing.deactivate();\r\n      }\r\n      existing.destroy();\r\n    }\r\n\r\n    if (!controller.name) {\r\n      controller.name = String(name);\r\n    }\r\n\r\n    this.modes.set(name, controller);\r\n\r\n    if (this.boundEvents) {\r\n      controller.onScrollStart = this.boundEvents.onScrollStart;\r\n      controller.onScrollStop = this.boundEvents.onScrollStop;\r\n      controller.onChangeDirection = this.boundEvents.onDirectionChange;\r\n    }\r\n\r\n    if (this.scrollMarks.length > 0) {\r\n      this.scrollMarks.forEach((rule) => controller.addScrollMark(rule));\r\n    }\r\n\r\n    if (isCurrentMode) {\r\n      controller.activate();\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Manually sets the scroll mode for mobile devices.\r\n   * @param mode The scroll mode: 'smooth', 'default', or 'disable'.\r\n   */\r\n  public setMobileMode(mode: ScrollMode): void {\r\n    this.context.data.scroll.modeMobile = mode;\r\n    this.updateResponsiveMode();\r\n  }\r\n\r\n  /**\r\n   * Manually sets the scroll mode for desktop devices.\r\n   * @param mode The scroll mode: 'smooth', 'default', or 'disable'.\r\n   */\r\n  public setDesktopMode(mode: ScrollMode): void {\r\n    this.context.data.scroll.modeDesktop = mode;\r\n    this.updateResponsiveMode();\r\n  }\r\n\r\n  /**\r\n   * Automatically switches scroll mode based on screen width.\r\n   * Call this inside your resize handler.\r\n   */\r\n  public updateResponsiveMode(): void {\r\n    const isMobile = window.innerWidth < 1024;\r\n    const newMode = isMobile\r\n      ? this.context.data.scroll.modeMobile\r\n      : this.context.data.scroll.modeDesktop;\r\n\r\n    this.setMode(newMode);\r\n  }\r\n\r\n  public updatePosition(): void {\r\n    this.get().onCalcUpdate();\r\n  }\r\n\r\n  /**\r\n   * Sets the current scroll mode and updates the active scroll engine.\r\n   * @param mode The scroll mode to activate.\r\n   */\r\n  public setMode(mode: ScrollMode): void {\r\n    if (!this.modes.has(mode)) {\r\n      console.warn(`[ScrollManager] Unknown scroll mode: ${mode}`);\r\n      return;\r\n    }\r\n    const currentMode = this.context.data.scroll.mode;\r\n    if (currentMode === mode) {\r\n      this.get().activate();\r\n      return;\r\n    }\r\n\r\n    this.get().deactivate();\r\n    this.context.data.scroll.mode = mode;\r\n    this.get().activate();\r\n    this.boundEvents?.onModeChange();\r\n  }\r\n\r\n  /**\r\n   * Returns the currently active scroll engine based on state.\r\n   */\r\n  public get(): ScrollController {\r\n    return this.modes.get(this.context.data.scroll.mode)!;\r\n  }\r\n\r\n  /**\r\n   * Returns all available scroll engine instances.\r\n   */\r\n  public getEngines(): Map<ScrollMode, ScrollController> {\r\n    return this.modes;\r\n  }\r\n\r\n  /**\r\n   * Calls `onFrame()` on the current scroll engine.\r\n   */\r\n  public onFrame(): void {\r\n    this.get().onFrame();\r\n  }\r\n\r\n  /**\r\n   * Forwards native scroll event to the current scroll engine.\r\n   * @param e The scroll event.\r\n   */\r\n  public onScroll(e: Event): void {\r\n    this.get().onScroll(e);\r\n  }\r\n\r\n  /**\r\n   * Forwards wheel event to the current scroll engine.\r\n   * @param e The wheel event.\r\n   */\r\n  public onWheel(e: WheelEvent): void {\r\n    this.get().onWheel(e);\r\n  }\r\n\r\n  /**\r\n   * Forwards touchstart event to the current scroll engine.\r\n   * @param e The touch event.\r\n   */\r\n  public onTouchStart(e: TouchEvent): void {\r\n    this.get().onTouchStart(e);\r\n  }\r\n\r\n  /**\r\n   * Forwards touchmove event to the current scroll engine.\r\n   * @param e The touch event.\r\n   */\r\n  public onTouchMove(e: TouchEvent): void {\r\n    this.get().onTouchMove(e);\r\n  }\r\n\r\n  /**\r\n   * Forwards touchend event to the current scroll engine.\r\n   * @param e The touch event.\r\n   */\r\n  public onTouchEnd(e: TouchEvent): void {\r\n    this.get().onTouchEnd(e);\r\n  }\r\n\r\n  /**\r\n   * Subscribes lifecycle event handlers to all scroll engines.\r\n   * @param events Scroll lifecycle callbacks.\r\n   */\r\n  public bindEvents(events: {\r\n    onScrollStart: () => void;\r\n    onScrollStop: () => void;\r\n    onDirectionChange: () => void;\r\n    onModeChange: () => void;\r\n  }) {\r\n    this.boundEvents = events;\r\n    this.modes.forEach((engine) => {\r\n      engine.onScrollStart = events.onScrollStart;\r\n      engine.onScrollStop = events.onScrollStop;\r\n      engine.onChangeDirection = events.onDirectionChange;\r\n    });\r\n  }\r\n\r\n  public addScrollMark(rule: ScrollMarkRule) {\r\n    this.scrollMarks.push(rule);\r\n    this.modes.forEach((engine) => {\r\n      engine.addScrollMark(rule);\r\n    });\r\n  }\r\n  public removeScrollMark(id: string) {\r\n    this.scrollMarks = this.scrollMarks.filter((rule) => rule.id !== id);\r\n    this.modes.forEach((engine) => {\r\n      engine.removeScrollMark(id);\r\n    });\r\n  }\r\n\r\n  public destroy(): void {\r\n    this.modes.forEach((engine) => {\r\n      engine.deactivate();\r\n      engine.destroy();\r\n    });\r\n  }\r\n}\r\n","/**\r\n * Reactive cursor data for raw, target, smoothed and step deltas.\r\n */\r\nexport class CursorState {\r\n  /**\r\n   * Target X position of the cursor (e.g., from `mousemove`)\r\n   */\r\n  targetX: number = 0;\r\n\r\n  /**\r\n   * Target Y position of the cursor.\r\n   */\r\n  targetY: number = 0;\r\n\r\n  /**\r\n   * Smoothed X position after applying lerp.\r\n   */\r\n  smoothedX: number = 0;\r\n\r\n  /**\r\n   * Smoothed Y position after applying lerp.\r\n   */\r\n  smoothedY: number = 0;\r\n\r\n  /**\r\n   * Delta step between current and target X (used internally for lerp).\r\n   */\r\n  stepX: number = 0;\r\n\r\n  /**\r\n   * Delta step between current and target Y.\r\n   */\r\n  stepY: number = 0;\r\n\r\n  /**\r\n   * Velocity in X direction, calculated from smoothed position.\r\n   */\r\n  velocityX: number = 0;\r\n\r\n  /**\r\n   * Velocity in Y direction, calculated from smoothed position.\r\n   */\r\n  velocityY: number = 0;\r\n}\r\n","/**\r\n * Global Three.js or rendering context reference.\r\n */\r\nexport class RenderState {\r\n  /** Instance of Three.js or another render context */\r\n  threeInstance: any = null\r\n}\r\n","export type ScrollDirection = 'vertical' | 'horizontal'\r\nexport type BuiltInScrollMode = 'smooth' | 'disable' | 'default'\r\nexport type ScrollMode = BuiltInScrollMode | string\r\n\r\n/**\r\n * Describes current scroll-related state for all calculations and modules.\r\n */\r\nexport class ScrollState {\r\n  /** Target scroll value — where we want to scroll to (used in smooth scroll) */\r\n  target: number = 0\r\n\r\n  /** Current scroll value (actual scroll position) */\r\n  current: number = 0\r\n\r\n  /** Transformed current scroll value (with transform by scroll container) */\r\n  transformedCurrent: number = 0\r\n\r\n  /** Delta between frames (used for animation / velocity) */\r\n  delta: number = 0\r\n\r\n  /** Interpolated scroll value for smooth transitions */\r\n  lerped: number = 0\r\n\r\n  /** Displacement value (similar to lerped, but used for other animations) */\r\n  displacement: number = 0\r\n\r\n  /** Whether scroll direction is downward */\r\n  isScrollingDown: boolean = false\r\n\r\n  /** Top screen scroll position */\r\n  topPosition: number = 0\r\n\r\n  /** Bottom screen scroll position */\r\n  bottomPosition: number = 0\r\n\r\n  /** Scroll direction (vertical / horizontal) */\r\n  direction: ScrollDirection = 'vertical'\r\n\r\n  /** Scroll container element */\r\n  elementContainer: HTMLElement = document.documentElement\r\n\r\n  /** Scroll container element */\r\n  scrollContainer: HTMLElement | Window = window\r\n\r\n  /** Scroll container element */\r\n  container: HTMLElement = document.body\r\n\r\n  /**\r\n   * Currently active scroll mode.\r\n   * Can be 'smooth', 'default', or 'disable'.\r\n   */\r\n  mode: ScrollMode = 'smooth'\r\n\r\n  /**\r\n   * Scroll mode to use on mobile devices.\r\n   * Can be 'smooth', 'default', or 'disable'.\r\n   */\r\n  modeMobile: ScrollMode = 'default'\r\n\r\n  /**\r\n   * Scroll mode to use on desktop devices.\r\n   * Can be 'smooth', 'default', or 'disable'.\r\n   */\r\n  modeDesktop: ScrollMode = 'smooth'\r\n\r\n  /**\r\n   * Base scroll speed used for calculating smooth scrolling.\r\n   * Typically a small value between 0 and 1.\r\n   */\r\n  speed: number = 0.1\r\n\r\n  /**\r\n   * Acceleration factor used for scroll easing or velocity-based animations.\r\n   * Also typically a value between 0 and 1.\r\n   */\r\n  speedAccelerate: number = 0.25\r\n}\r\n","export class SystemState {\r\n  fpsTracker: boolean = false;\r\n  positionTracker: boolean = false;\r\n  suppressMasonryResize: boolean = false;\r\n}\r\n","/**\r\n * Represents the time-related state of the current and previous animation frames.\r\n * \r\n * Useful for calculating delta time, total elapsed time, and implementing\r\n * time-based animations or physics.\r\n */\r\nexport class TimeState {\r\n  /**\r\n   * Timestamp of the current animation frame in milliseconds.\r\n   * This value is typically obtained via `performance.now()`.\r\n   */\r\n  now: number = 0;\r\n\r\n  /**\r\n   * Timestamp of the previous animation frame in milliseconds.\r\n   */\r\n  previous: number = 0;\r\n\r\n  /**\r\n   * Time difference between the current and previous frames in milliseconds.\r\n   * Commonly used to calculate animation progress.\r\n   */\r\n  delta: number = 0;\r\n\r\n  /**\r\n   * Total time elapsed since the start of the animation or system in milliseconds.\r\n   */\r\n  elapsed: number = 0;\r\n}\r\n","/**\r\n * Describes current viewport size and scaling.\r\n */\r\nexport class ViewportState {\r\n  /** Width of the visible window */\r\n  windowWidth: number = 0\r\n\r\n  /** Height of the visible window */\r\n  windowHeight: number = 0\r\n\r\n  /** Full scroll width (content width inside scroll container) */\r\n  contentWidth: number = 0\r\n\r\n  /** Full scroll height (content height inside scroll container) */\r\n  contentHeight: number = 0\r\n\r\n  /** Screen scale ratio for width (e.g. device pixel ratio or zoom level) */\r\n  scaleWidth: number = 1\r\n\r\n  /** Screen scale ratio for height */\r\n  scaleHeight: number = 1\r\n\r\n  transformScale: number = 1\r\n\r\n  baseRem: number = 16\r\n}\r\n","import { CursorState } from \"../states/CursorState\";\r\nimport { RenderState } from \"../states/RenderState\";\r\nimport { ScrollState } from \"../states/ScrollState\";\r\nimport { SystemState } from \"../states/SystemState\";\r\nimport { TimeState } from \"../states/TimeState\";\r\nimport { ViewportState } from \"../states/ViewportState\";\r\n\r\n/**\r\n * Container for global dynamic state used throughout the string-tune system.\r\n * Provides access to live scroll, viewport, cursor, and render states,\r\n * which are updated each frame and shared across modules and tools.\r\n */\r\nexport class StringData {\r\n  /**\r\n   * Scroll-related state object.\r\n   * Contains live values like `target`, `current`, `delta`, `direction`, and more.\r\n   * Used for scroll-based animations, transitions, and effects.\r\n   */\r\n  scroll = new ScrollState();\r\n\r\n  /**\r\n   * Viewport-related state object.\r\n   * Holds dimensions like window size, content size, aspect ratios, and more.\r\n   * Useful for layout calculations, unit parsing, and element positioning.\r\n   */\r\n  viewport = new ViewportState();\r\n\r\n  /**\r\n   * Cursor-related state object.\r\n   * Tracks cursor position, velocity, movement, and derived values.\r\n   * Can be used for pointer interactions, proximity effects, and hover states.\r\n   */\r\n  cursor = new CursorState();\r\n\r\n  /**\r\n   * Render-related state object.\r\n   * Stores data related to rendering context (e.g. WebGL, Three.js),\r\n   * such as shared materials, textures, or active render frame data.\r\n   */\r\n  render = new RenderState();\r\n\r\n  /**\r\n   * Time-related state object.\r\n   * Tracks frame timings, including current timestamp, delta between frames,\r\n   * and total elapsed time since animation start.\r\n   * Useful for time-based animations, easing, frame consistency, and syncing logic.\r\n   */\r\n  time = new TimeState();\r\n\r\n  system = new SystemState();\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\"\r\n\r\n/**\r\n * Input for `BoundingClientRectTool`.\r\n */\r\ninterface BoundingClientRectInput {\r\n  /** The DOM element to retrieve bounding rect from. */\r\n  element: HTMLElement\r\n}\r\n\r\n/**\r\n * Tool for accessing `getBoundingClientRect()` in a consistent, testable way.\r\n */\r\nexport default class BoundingClientRectTool\r\n  implements IStringTool<BoundingClientRectInput, DOMRect>\r\n{\r\n  /**\r\n   * @returns The bounding client rect of the provided element.\r\n   */\r\n  process({ element }: BoundingClientRectInput): DOMRect {\r\n    return element.getBoundingClientRect()\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\"\r\n\r\ninterface DOMAttributeInput {\r\n  element: HTMLElement\r\n  key: string // for example: \"offset-tom\"\r\n  fallback?: string | null\r\n}\r\n\r\nexport default class DOMAttributeTool implements IStringTool<DOMAttributeInput, string | null> {\r\n  /**\r\n   * Retrieves the value of either `string-${key}` or `data-string-${key}` attribute.\r\n   *\r\n   * @example key = \"offset-tom\" → tries:\r\n   *   - element.getAttribute(\"string-offset-tom\")\r\n   *   - element.getAttribute(\"data-string-offset-tom\")\r\n   */\r\n  process({ element, key, fallback = null }: DOMAttributeInput): string | null {\r\n    return (\r\n      element.getAttribute(`string-${key}`) ??\r\n      element.getAttribute(`data-string-${key}`) ??\r\n      fallback\r\n    )\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\"\r\n\r\n/**\r\n * Input for retrieving a value from a key-value object or dataset-like structure.\r\n */\r\ninterface RecordAttributeInput {\r\n  /** Source object to read from (e.g. dataset or plain record). */\r\n  record: Record<string, any>\r\n\r\n  /** Key to look up (without `\"data-\"` prefix). */\r\n  name: string\r\n\r\n  /** Fallback value if both keys are missing. */\r\n  fallback?: any\r\n}\r\n\r\n/**\r\n * Retrieves a value from an object or dataset-like structure.\r\n * Tries `record[name]` first, then `record[\"data-\" + name]`, or returns fallback.\r\n */\r\nexport default class RecordAttributeTool implements IStringTool<RecordAttributeInput, any> {\r\n  /**\r\n   * @returns Value from the record or fallback.\r\n   */\r\n  process({ record, name, fallback = null }: RecordAttributeInput): any {\r\n    return (\r\n      record[name] ??\r\n      record[`data-${name}`] ??\r\n      fallback\r\n    )\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\"\r\n\r\n/**\r\n * Input for removing transform effects from an element's bounding box.\r\n */\r\ninterface TransformNullifyInput {\r\n  /** The DOM element whose CSS transform should be nullified. */\r\n  element: HTMLElement\r\n}\r\n\r\n/**\r\n * Output with corrected bounding box values.\r\n */\r\ninterface TransformNullifyOutput {\r\n  /** Top position without transform effects. */\r\n  top: number\r\n\r\n  /** Left position without transform effects. */\r\n  left: number\r\n\r\n  /** Width without transform scaling. */\r\n  width: number\r\n\r\n  /** Height without transform scaling. */\r\n  height: number\r\n}\r\n\r\n/**\r\n * Computes the true bounding box of a DOM element,\r\n * nullifying CSS `transform: matrix(...)` effects.\r\n */\r\nexport default class TransformNullifyTool\r\n  implements IStringTool<TransformNullifyInput, TransformNullifyOutput>\r\n{\r\n  /**\r\n   * @returns Element position and size without transform influence.\r\n   */\r\n  process({ element }: TransformNullifyInput): TransformNullifyOutput {\r\n    const rect = element.getBoundingClientRect()\r\n    const matrix = getComputedStyle(element).transform\r\n\r\n    const values = matrix\r\n      .match(/-?[\\d.]+/g)\r\n      ?.map(parseFloat) ?? []\r\n\r\n    if (values.length === 6) {\r\n      const [a, b, c, d, e, f] = values\r\n      const det = a * d - b * c\r\n\r\n      return {\r\n        width: rect.width / (a || 1),\r\n        height: rect.height / (d || 1),\r\n        left: (rect.left * d - rect.top * c + c * f - e * d) / det,\r\n        top: (-rect.left * b + rect.top * a + e * b - a * f) / det,\r\n      }\r\n    }\r\n\r\n    return rect\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\"\r\nimport TransformNullifyTool from \"./TransformNullifyTool\"\r\n\r\n/**\r\n * Input for calculating the position of an element relative to a container.\r\n */\r\ninterface RelativePositionInput {\r\n  /** The DOM element whose position should be calculated. */\r\n  element: HTMLElement\r\n\r\n  /** Optional container to measure against. Defaults to `document.body`. */\r\n  container?: HTMLElement\r\n}\r\n\r\n/**\r\n * Output: relative position in pixels.\r\n */\r\ninterface RelativePositionOutput {\r\n  /** Distance from the top of the container. */\r\n  top: number\r\n\r\n  /** Distance from the left of the container. */\r\n  left: number\r\n}\r\n\r\n/**\r\n * Calculates an element's position relative to a container.\r\n * Uses `TransformNullifyTool` to account for CSS transforms.\r\n */\r\nexport default class RelativePositionTool\r\n  implements IStringTool<RelativePositionInput, RelativePositionOutput>\r\n{\r\n  constructor(\r\n    /** Optional tool for CSS transform-neutral measurements. */\r\n    private transformTool = new TransformNullifyTool()\r\n  ) {}\r\n\r\n  /**\r\n   * @returns Relative top/left position of element within container.\r\n   */\r\n  process({ element, container = document.body }: RelativePositionInput): RelativePositionOutput {\r\n    let containerRect: DOMRect\r\n    try {\r\n      containerRect = container.getBoundingClientRect()\r\n    } catch {\r\n      containerRect = document.body.getBoundingClientRect()\r\n    }\r\n\r\n    const elRect = this.transformTool.process({ element })\r\n\r\n    return {\r\n      top: elRect.top - containerRect.top,\r\n      left: elRect.left - containerRect.left,\r\n    }\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\"\r\n\r\ninterface LerpInput {\r\n  /** Starting value of the interpolation. */\r\n  from: number\r\n\r\n  /** Target value to interpolate towards. */\r\n  to: number\r\n\r\n  /** Interpolation progress between 0 (start) and 1 (end). */\r\n  progress: number\r\n}\r\n\r\nexport default class LerpTool implements IStringTool<LerpInput, number> {\r\n  /**\r\n   * Calculates the linear interpolation between two values.\r\n   * @returns Interpolated value.\r\n   */\r\n  process({ from, to, progress }: LerpInput): number {\r\n    return (to - from) * progress\r\n  }\r\n}\r\n\r\n","import { IStringTool } from \"../core/IStringTool\";\r\n\r\n/**\r\n * Input for parsing unit-based strings into numeric pixel values.\r\n */\r\ninterface UnitParserInput {\r\n  /** Unit string, e.g. `\"20px\"`, `\"50%\"`, `\"1.5rem\"`, or `\"selfHeight\"` */\r\n  value: string;\r\n\r\n  /** DOM element used for `\"selfHeight\"` calculation */\r\n  element: HTMLElement;\r\n\r\n  /** Viewport height in pixels (for percentage conversion) */\r\n  viewportHeight: number;\r\n\r\n  /** Root font size in pixels (for rem conversion) */\r\n  baseRem: number;\r\n\r\n  boundingRect: DOMRect;\r\n}\r\n\r\n/**\r\n * Converts unit-based strings to numeric pixel values.\r\n * Supports `px`, `%`, `rem`, and `\"selfHeight\"` keyword. Handles negatives.\r\n */\r\nexport default class UnitParserTool implements IStringTool<UnitParserInput, number> {\r\n  /**\r\n   * @returns Numeric value in pixels (positive or negative).\r\n   */\r\n  process({ value, element, viewportHeight, baseRem, boundingRect }: UnitParserInput): number {\r\n    const parts = value\r\n      .split(\"|\")\r\n      .map((s) => s.trim())\r\n      .filter(Boolean);\r\n\r\n    let sum = 0;\r\n    for (const part of parts) {\r\n      let v = part;\r\n      let isNegative = false;\r\n      if (v.startsWith(\"-\")) {\r\n        isNegative = true;\r\n        v = v.slice(1);\r\n      }\r\n      let result = 0;\r\n      if (v === \"selfHeight\") {\r\n        result = element.offsetHeight;\r\n      } else if (v.endsWith(\"px\")) {\r\n        result = parseFloat(v);\r\n      } else if (v.endsWith(\"%\")) {\r\n        result = (parseFloat(v) / 100) * viewportHeight;\r\n      } else if (v.endsWith(\"rem\")) {\r\n        result = parseFloat(v) * baseRem;\r\n      } else if (v.endsWith(\"sh\")) {\r\n        result = (parseFloat(v) * boundingRect.height) / 100;\r\n      } else {\r\n        result = parseFloat(v);\r\n      }\r\n\r\n      sum += isNegative ? -result : result;\r\n    }\r\n\r\n    return sum;\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\"\r\n\r\n/**\r\n * Input for adaptive lerp factor calculation.\r\n * Maps a speed-like value to a lerp factor, where:\r\n * - lower speed ⇒ slower smoothing (higher lerp factor)\r\n * - higher speed ⇒ faster response (lower lerp factor)\r\n */\r\ninterface AdaptiveLerpInput {\r\n  /** Current value (e.g., speed or delta). */\r\n  value: number\r\n\r\n  /** Minimum input threshold (default: 0.1) */\r\n  inMin?: number\r\n\r\n  /** Maximum input threshold (default: 1.0) */\r\n  inMax?: number\r\n\r\n  /** Output when input is at minimum (default: 0.65) */\r\n  outMax?: number\r\n\r\n  /** Output when input is at maximum (default: 0.05) */\r\n  outMin?: number\r\n}\r\n\r\n/**\r\n * Converts a numeric input (like velocity) into an adaptive lerp factor.\r\n * Useful for scroll or speed-based smoothing effects.\r\n */\r\nexport default class AdaptiveLerpTool implements IStringTool<AdaptiveLerpInput, number> {\r\n  /**\r\n   * @returns A remapped lerp factor from `outMax` to `outMin`.\r\n   */\r\n  process({\r\n    value,\r\n    inMin = 0.1,\r\n    inMax = 1.0,\r\n    outMin = 0.05,\r\n    outMax = 0.65\r\n  }: AdaptiveLerpInput): number {\r\n    if (value < inMin) return outMax\r\n    if (value > 1.0) value = 1.0\r\n\r\n    if (value <= inMax) {\r\n      const t = (value - inMin) / (inMax - inMin)\r\n      return outMax - t * (outMax - outMin)\r\n    }\r\n\r\n    return outMin\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\";\r\n\r\n/**\r\n * Input for origin parser.\r\n * Supports static values or `random(...)` expressions.\r\n */\r\ninterface OriginInput {\r\n  /** Raw origin string, e.g. `'center'` or `'random(top, bottom)'`. */\r\n  value: string;\r\n}\r\n\r\n/**\r\n * Input for parsing origin to normalized coordinates.\r\n * Supports formats like `'left top'`, `'center center'`, `'50% 50%'`, `'35% 76%'`.\r\n */\r\ninterface OriginToNormalizedInput {\r\n  /** Raw origin string, e.g. `'left top'`, `'center'`, `'50% 25%'`. */\r\n  value: string;\r\n}\r\n\r\n/**\r\n * Output: normalized origin coordinates (0-1 range).\r\n */\r\ninterface NormalizedOrigin {\r\n  /** Normalized X coordinate (0 = left, 0.5 = center, 1 = right). */\r\n  x: number;\r\n  /** Normalized Y coordinate (0 = top, 0.5 = center, 1 = bottom). */\r\n  y: number;\r\n}\r\n\r\n/** Keyword mappings for horizontal axis. */\r\nconst HORIZONTAL_KEYWORDS: Record<string, number> = {\r\n  left: 0,\r\n  center: 0.5,\r\n  right: 1,\r\n};\r\n\r\n/** Keyword mappings for vertical axis. */\r\nconst VERTICAL_KEYWORDS: Record<string, number> = {\r\n  top: 0,\r\n  center: 0.5,\r\n  bottom: 1,\r\n};\r\n\r\n/**\r\n * Tool that parses origin strings.\r\n * Allows static values like `'center'`, or expressions like `'random(...)'` to select one randomly.\r\n * Also provides `toNormalized()` method to convert origin strings to `{ x, y }` coordinates.\r\n */\r\nexport default class OriginParserTool implements IStringTool<OriginInput, string> {\r\n  /**\r\n   * @returns Parsed string value (static or randomly chosen).\r\n   */\r\n  process({ value }: OriginInput): string {\r\n    if (!value) return \"center\";\r\n    const raw = value.trim();\r\n\r\n    if (raw.startsWith(\"random(\") && raw.endsWith(\")\")) {\r\n      const options = raw\r\n        .slice(7, -1)\r\n        .split(\",\")\r\n        .map((s) => s.trim())\r\n        .filter(Boolean);\r\n\r\n      const index = Math.floor(Math.random() * options.length);\r\n      return options[index];\r\n    }\r\n\r\n    return raw;\r\n  }\r\n\r\n  /**\r\n   * Parses an origin string to normalized `{ x, y }` coordinates (0-1 range).\r\n   *\r\n   * Supported formats:\r\n   * - Single keyword: `'center'`, `'top'`, `'left'`, etc.\r\n   * - Two keywords: `'left top'`, `'right bottom'`, `'center center'`\r\n   * - Percentages: `'50% 50%'`, `'0% 100%'`, `'35% 76%'`\r\n   * - Mixed: `'left 25%'`, `'50% top'`\r\n   *\r\n   * @param input - The origin string to parse.\r\n   * @returns Normalized `{ x, y }` coordinates.\r\n   */\r\n  toNormalized({ value }: OriginToNormalizedInput): NormalizedOrigin {\r\n    const raw = this.process({ value });\r\n    const parts = raw.toLowerCase().split(/\\s+/).filter(Boolean);\r\n\r\n    if (parts.length === 0) {\r\n      return { x: 0.5, y: 0.5 };\r\n    }\r\n\r\n    if (parts.length === 1) {\r\n      const single = parts[0];\r\n      const parsed = this.parseValue(single);\r\n\r\n      // If it's a horizontal keyword, use center for Y\r\n      if (single in HORIZONTAL_KEYWORDS && !(single in VERTICAL_KEYWORDS)) {\r\n        return { x: parsed, y: 0.5 };\r\n      }\r\n      // If it's a vertical keyword, use center for X\r\n      if (single in VERTICAL_KEYWORDS && !(single in HORIZONTAL_KEYWORDS)) {\r\n        return { x: 0.5, y: parsed };\r\n      }\r\n      // 'center' or percentage applies to both\r\n      return { x: parsed, y: parsed };\r\n    }\r\n\r\n    // Two parts: determine which is X and which is Y\r\n    const [first, second] = parts;\r\n\r\n    // Check if keywords need to be swapped (e.g., \"top left\" → x=left, y=top)\r\n    const firstIsVerticalOnly = first in VERTICAL_KEYWORDS && !(first in HORIZONTAL_KEYWORDS);\r\n    const secondIsHorizontalOnly = second in HORIZONTAL_KEYWORDS && !(second in VERTICAL_KEYWORDS);\r\n\r\n    if (firstIsVerticalOnly || secondIsHorizontalOnly) {\r\n      // Swap: first is Y, second is X\r\n      return {\r\n        x: this.parseValue(second, \"horizontal\"),\r\n        y: this.parseValue(first, \"vertical\"),\r\n      };\r\n    }\r\n\r\n    // Default order: first is X, second is Y\r\n    return {\r\n      x: this.parseValue(first, \"horizontal\"),\r\n      y: this.parseValue(second, \"vertical\"),\r\n    };\r\n  }\r\n\r\n  /**\r\n   * Parses a single value (keyword or percentage) to a normalized number.\r\n   */\r\n  private parseValue(val: string, axis?: \"horizontal\" | \"vertical\"): number {\r\n    // Check keywords\r\n    if (axis === \"horizontal\" && val in HORIZONTAL_KEYWORDS) {\r\n      return HORIZONTAL_KEYWORDS[val];\r\n    }\r\n    if (axis === \"vertical\" && val in VERTICAL_KEYWORDS) {\r\n      return VERTICAL_KEYWORDS[val];\r\n    }\r\n    if (val in HORIZONTAL_KEYWORDS) {\r\n      return HORIZONTAL_KEYWORDS[val];\r\n    }\r\n    if (val in VERTICAL_KEYWORDS) {\r\n      return VERTICAL_KEYWORDS[val];\r\n    }\r\n\r\n    // Parse percentage\r\n    if (val.endsWith(\"%\")) {\r\n      const num = parseFloat(val);\r\n      if (!isNaN(num)) {\r\n        return num / 100;\r\n      }\r\n    }\r\n\r\n    // Parse plain number (treat as percentage)\r\n    const num = parseFloat(val);\r\n    if (!isNaN(num)) {\r\n      // If it's a small number (0-1), treat as normalized\r\n      // If it's larger, treat as percentage\r\n      return num > 1 ? num / 100 : num;\r\n    }\r\n\r\n    // Default to center\r\n    return 0.5;\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\"\r\nimport { StringColor } from \"../models/color/StringColor\"\r\n\r\n/**\r\n * Input for parsing color strings into RGBA format.\r\n */\r\ninterface ColorParserInput {\r\n  /** Color string in hex, rgb[a], or hsl[a] format. */\r\n  value: string\r\n}\r\n\r\n/**\r\n * Parses a CSS color string (`#fff`, `rgb(...)`, `hsl(...)`, etc.)\r\n * into an object with `r`, `g`, `b`, `a` values.\r\n */\r\nexport default class ColorParserTool\r\n  implements IStringTool<ColorParserInput, StringColor>\r\n{\r\n  /**\r\n   * @returns RGBA object parsed from color string.\r\n   */\r\n  process({ value }: ColorParserInput): StringColor {\r\n    const str = value.trim().toLowerCase()\r\n\r\n    // --- HEX ---\r\n    if (str.startsWith(\"#\")) {\r\n      let hex = str.slice(1)\r\n\r\n      if (hex.length === 3) {\r\n        hex = hex.split(\"\").map((ch) => ch + ch).join(\"\")\r\n      }\r\n\r\n      const r = parseInt(hex.slice(0, 2), 16)\r\n      const g = parseInt(hex.slice(2, 4), 16)\r\n      const b = parseInt(hex.slice(4, 6), 16)\r\n      const a = hex.length === 8 ? parseInt(hex.slice(6, 8), 16) / 255 : 1\r\n\r\n      return { r, g, b, a }\r\n    }\r\n\r\n    // --- RGB / RGBA ---\r\n    const rgbMatch = str.match(/rgba?\\(([^)]+)\\)/)\r\n    if (rgbMatch) {\r\n      const [r, g, b, a = 1] = rgbMatch[1]\r\n        .split(\",\")\r\n        .map((v) => parseFloat(v.trim()))\r\n\r\n      return { r, g, b, a }\r\n    }\r\n\r\n    // --- HSL / HSLA ---\r\n    const hslMatch = str.match(/hsla?\\(([^)]+)\\)/)\r\n    if (hslMatch) {\r\n      const [h, s, l, a = \"1\"] = hslMatch[1].split(\",\").map((v) => v.trim())\r\n      const [r, g, b] = this.hslToRgb(parseFloat(h), parseFloat(s), parseFloat(l))\r\n      return { r, g, b, a: parseFloat(a) }\r\n    }\r\n\r\n    // fallback: transparent\r\n    return { r: 0, g: 0, b: 0, a: 0 }\r\n  }\r\n\r\n  private hslToRgb(h: number, s: string | number, l: string | number): [number, number, number] {\r\n    h = h / 360\r\n    s = parseFloat(s.toString()) / 100\r\n    l = parseFloat(l.toString()) / 100\r\n\r\n    const hue2rgb = (p: number, q: number, t: number) => {\r\n      if (t < 0) t += 1\r\n      if (t > 1) t -= 1\r\n      if (t < 1 / 6) return p + (q - p) * 6 * t\r\n      if (t < 1 / 2) return q\r\n      if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6\r\n      return p\r\n    }\r\n\r\n    const q = l < 0.5 ? l * (1 + s) : l + s - l * s\r\n    const p = 2 * l - q\r\n\r\n    const r = Math.round(hue2rgb(p, q, h + 1 / 3) * 255)\r\n    const g = Math.round(hue2rgb(p, q, h) * 255)\r\n    const b = Math.round(hue2rgb(p, q, h - 1 / 3) * 255)\r\n\r\n    return [r, g, b]\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\"\n\n/**\n * Input parameters for EasingFunctionTool.\n */\ninterface EasingFunctionInput {\n  /**\n   * The easing string.\n   * Can be: 'linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', or 'cubic-bezier(...)'\n   */\n  easing: string\n}\n\n/**\n * Output of the easing function: receives t in [0,1] and returns eased value.\n */\nexport type EasingFunctionOutput = (t: number) => number\n\n/**\n * Tool for parsing easing strings into easing functions.\n * Supports standard keywords (`ease-in`, `ease-out`, etc.) and `cubic-bezier(...)` expressions.\n */\nexport default class EasingFunctionTool implements IStringTool<EasingFunctionInput, EasingFunctionOutput> {\n  private namedCurves: Record<string, [number, number, number, number]> = {\n    \"linear\": [0, 0, 1, 1],\n    \"ease\": [0.25, 0.1, 0.25, 1],\n    \"ease-in\": [0.42, 0, 1, 1],\n    \"ease-out\": [0, 0, 0.58, 1],\n    \"ease-in-out\": [0.42, 0, 0.58, 1],\n  }\n\n  /**\n   * Parses an easing string and returns a corresponding easing function.\n   */\n  process({ easing }: EasingFunctionInput): EasingFunctionOutput {\n    const def = easing.trim()\n\n    if (this.namedCurves[def]) {\n      return this.cubicBezier(...this.namedCurves[def])\n    }\n\n    const match = def.match(/^cubic-bezier\\s*\\(\\s*([-+]?\\d*\\.?\\d+)\\s*,\\s*([-+]?\\d*\\.?\\d+)\\s*,\\s*([-+]?\\d*\\.?\\d+)\\s*,\\s*([-+]?\\d*\\.?\\d+)\\s*\\)$/);\n\n    if (match) {\n      const [x1, y1, x2, y2] = match.slice(1).map(Number)\n      return this.cubicBezier(x1, y1, x2, y2)\n    }\n\n    // fallback: linear\n    return (t: number) => t\n  }\n\n  /**\n   * Generates a cubic-bezier easing function.\n   * Ported from https://github.com/gre/bezier-easing (MIT)\n   */\n  private cubicBezier(x1: number, y1: number, x2: number, y2: number): EasingFunctionOutput {\n    const cx = 3 * x1\n    const bx = 3 * (x2 - x1) - cx\n    const ax = 1 - cx - bx\n\n    const cy = 3 * y1\n    const by = 3 * (y2 - y1) - cy\n    const ay = 1 - cy - by\n\n    function sampleCurveX(t: number) {\n      return ((ax * t + bx) * t + cx) * t\n    }\n\n    function sampleCurveY(t: number) {\n      return ((ay * t + by) * t + cy) * t\n    }\n\n    function sampleCurveDerivativeX(t: number) {\n      return (3 * ax * t + 2 * bx) * t + cx\n    }\n\n    function solveCurveX(x: number, epsilon = 1e-5) {\n      let t0, t1, t2 = x, x2, d2, i\n\n      // Newton-Raphson method\n      for (i = 0; i < 8; i++) {\n        x2 = sampleCurveX(t2) - x\n        if (Math.abs(x2) < epsilon) return t2\n        d2 = sampleCurveDerivativeX(t2)\n        if (Math.abs(d2) < 1e-6) break\n        t2 = t2 - x2 / d2\n      }\n\n      // Bisection fallback\n      t0 = 0\n      t1 = 1\n      t2 = x\n\n      while (t0 < t1) {\n        x2 = sampleCurveX(t2) - x\n        if (Math.abs(x2) < epsilon) return t2\n        if (x2 > 0) t1 = t2\n        else t0 = t2\n        t2 = (t1 + t0) / 2\n      }\n\n      return t2\n    }\n\n    return function (x: number) {\n      return sampleCurveY(solveCurveX(x))\n    }\n  }\n}\n","import { IStringTool } from \"../core/IStringTool\"\r\n\r\n/**\r\n * Input parameters for calculating magnetic pull factor.\r\n */\r\ninterface MagneticPullInput {\r\n  /** Distance between pointer and element center (px). */\r\n  distance: number\r\n\r\n  /** Max distance within which magnetic pull is active. */\r\n  radius: number\r\n\r\n  /** Strength of the magnetic pull (0–1 recommended). */\r\n  strength: number\r\n}\r\n\r\n/**\r\n * Output: factor to multiply by direction vector (dx/dy) to get magnetic offset.\r\n */\r\ntype MagneticPullOutput = number\r\n\r\n/**\r\n * Tool for calculating magnetic attraction based on distance to element.\r\n * Returns a scalar value (0..strength) depending on proximity.\r\n */\r\nexport default class MagneticPullTool implements IStringTool<MagneticPullInput, MagneticPullOutput> {\r\n  /**\r\n   * Returns a pull factor based on distance to target within a radius.\r\n   * @param input - Magnetic pull parameters.\r\n   * @returns A multiplier (typically < 1) to apply to dx/dy.\r\n   */\r\n  process({ distance, radius, strength }: MagneticPullInput): number {\r\n    if (distance >= radius) return 0\r\n    const proximity = (radius - distance) / radius // 1 when close, 0 at edge\r\n    return strength * proximity\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\"\r\nimport { StringColor } from \"../models/color/StringColor\"\r\n\r\n/**\r\n * Input parameters for `LerpColorTool`.\r\n */\r\ninterface LerpColorInput {\r\n  /**\r\n   * Starting color as an object `{ r, g, b, a }` where each value is in the range `0–1`.\r\n   */\r\n  from: StringColor\r\n\r\n  /**\r\n   * Target color as an object `{ r, g, b, a }` where each value is in the range `0–1`.\r\n   */\r\n  to: StringColor\r\n\r\n  /**\r\n   * Interpolation progress from `0` (start) to `1` (end).\r\n   */\r\n  progress: number\r\n}\r\n\r\n/**\r\n * Tool for linearly interpolating between two RGBA colors using `StringColor` format.\r\n * Each channel (`r`, `g`, `b`, `a`) is interpolated independently.\r\n * Returns a new `StringColor` with the interpolated values.\r\n */\r\nexport default class LerpColorTool implements IStringTool<LerpColorInput, StringColor> {\r\n  /**\r\n   * Performs linear interpolation between two `StringColor` values.\r\n   *\r\n   * @param input.from - The starting color `{ r, g, b, a }`.\r\n   * @param input.to - The target color `{ r, g, b, a }`.\r\n   * @param input.progress - A number from `0` to `1` indicating interpolation progress.\r\n   * @returns Interpolated color as a new `StringColor`.\r\n   */\r\n  process({ from, to, progress }: LerpColorInput): StringColor {\r\n    return {\r\n      r: from.r + (to.r - from.r) * progress,\r\n      g: from.g + (to.g - from.g) * progress,\r\n      b: from.b + (to.b - from.b) * progress,\r\n      a: from.a + (to.a - from.a) * progress,\r\n    }\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\"\r\nimport { StringVector } from \"../models/vector/StringVector\"\r\n\r\n/**\r\n * Input parameters for LerpVector2Tool.\r\n */\r\ninterface LerpVector2Input {\r\n  /**\r\n   * Starting vector value `{ x, y }`.\r\n   */\r\n  from: StringVector\r\n\r\n  /**\r\n   * Target vector value `{ x, y }`.\r\n   */\r\n  to: StringVector\r\n\r\n  /**\r\n   * Interpolation progress from `0` (start) to `1` (end).\r\n   */\r\n  progress: number\r\n}\r\n\r\n/**\r\n * Tool for linearly interpolating between two 2D vectors.\r\n * Useful for cursor smoothing, UI element animations, and motion blending.\r\n */\r\nexport default class LerpVector2Tool implements IStringTool<LerpVector2Input, StringVector> {\r\n  /**\r\n   * Calculates the interpolated vector between `from` and `to`.\r\n   *\r\n   * @param input.from - The starting vector `{ x, y }`.\r\n   * @param input.to - The target vector `{ x, y }`.\r\n   * @param input.progress - Interpolation progress from `0` (start) to `1` (end).\r\n   * @returns Interpolated vector `{ x, y }`.\r\n   */\r\n  process({ from, to, progress }: LerpVector2Input): { x: number, y: number } {\r\n    return {\r\n      x: (to.x - from.x) * progress,\r\n      y: (to.y - from.y) * progress,\r\n    }\r\n  }\r\n}\r\n\r\n","import { IStringTool } from \"../core/IStringTool\"; // Переконайтесь, що шлях правильний\r\n\r\n/**\r\n * Input for parsing the transform string to extract scale.\r\n */\r\ninterface TransformParserInput {\r\n  /** CSS transform string (e.g., \"matrix(0.5, 0, 0, 0.5, 10, 20)\", \"scale(0.5)\", \"none\"). */\r\n  value: string;\r\n}\r\n\r\n/**\r\n * Parses a CSS transform string to extract the primary scale factor.\r\n * Assumes uniform scale or extracts the X-axis scale factor from matrix/scale functions.\r\n */\r\nexport default class TransformScaleParserTool\r\n  implements IStringTool<TransformParserInput, number> // Output is a number\r\n{\r\n  /**\r\n   * Processes the transform string and extracts the scale factor.\r\n   * @returns Numeric scale factor (defaults to 1 if no scale transform is found or parsing fails).\r\n   */\r\n  process({ value }: TransformParserInput): number {\r\n    const defaultScale = 1;\r\n    const str = value?.trim();\r\n\r\n    if (!str || str === 'none') {\r\n      return defaultScale;\r\n    }\r\n    try {\r\n      if (str.startsWith('matrix(')) {\r\n        const matrixValues = str.match(/matrix\\(([^)]+)\\)/);\r\n        if (matrixValues && matrixValues[1]) {\r\n          const matrixNumbers = matrixValues[1].split(',').map(s => parseFloat(s.trim()));\r\n          if (matrixNumbers.length >= 1 && !isNaN(matrixNumbers[0])) {\r\n            return matrixNumbers[0];\r\n          }\r\n        }\r\n      }\r\n\r\n      if (str.startsWith('scale(')) {\r\n        const scaleValue = str.match(/scale\\(([^)]+)\\)/);\r\n        if (scaleValue && scaleValue[1]) {\r\n          const scaleNumbers = scaleValue[1].split(',').map(s => parseFloat(s.trim()));\r\n          if (scaleNumbers.length >= 1 && !isNaN(scaleNumbers[0])) {\r\n            return scaleNumbers[0];\r\n          }\r\n        }\r\n      }\r\n\r\n       if (str.startsWith('scaleX(')) {\r\n        const scaleXValue = str.match(/scaleX\\(([^)]+)\\)/);\r\n        if (scaleXValue && scaleXValue[1]) {\r\n          const scaleNumber = parseFloat(scaleXValue[1].trim());\r\n          if (!isNaN(scaleNumber)) {\r\n            return scaleNumber;\r\n          }\r\n        }\r\n      }\r\n\r\n       if (str.startsWith('scale3d(')) {\r\n         const scale3dValue = str.match(/scale3d\\(([^)]+)\\)/);\r\n         if (scale3dValue && scale3dValue[1]) {\r\n             const scaleNumbers = scale3dValue[1].split(',').map(s => parseFloat(s.trim()));\r\n             if (scaleNumbers.length >= 1 && !isNaN(scaleNumbers[0])) {\r\n                 return scaleNumbers[0]; // Повертаємо sx\r\n             }\r\n         }\r\n       }\r\n\r\n       if (str.startsWith('matrix3d(')) {\r\n           const matrix3dValues = str.match(/matrix3d\\(([^)]+)\\)/);\r\n           if (matrix3dValues && matrix3dValues[1]) {\r\n               const matrixNumbers = matrix3dValues[1].split(',').map(s => parseFloat(s.trim()));\r\n               if (matrixNumbers.length >= 1 && !isNaN(matrixNumbers[0])) {\r\n                   return matrixNumbers[0];\r\n               }\r\n           }\r\n       }\r\n\r\n    } catch (error) {\r\n      console.error(`Error parsing transform string \"${str}\":`, error);\r\n      return defaultScale;\r\n    }\r\n\r\n    return defaultScale;\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\";\r\nimport { ISplitOptionItem } from \"../models/text/ISplitOptionItem\";\r\nimport { ISplitOptions } from \"../models/text/ISplitOptions\";\r\nimport { SplitOptionsParserInput } from \"../models/text/SplitOptionsParserInput\";\r\n\r\nexport class SplitOptionsParserTool implements IStringTool<SplitOptionsParserInput, ISplitOptions> {\r\n  process({ attributeValue }: SplitOptionsParserInput): ISplitOptions {\r\n    const options: ISplitOptions = {\n      line: [],\n      word: [],\n      char: [],\n      charLine: [],\n      charWord: [],\n      wordLine: [],\n      fit: false,\n      trimInlineGaps: false,\n    };\n\r\n    if (!attributeValue) {\r\n      return options;\r\n    }\r\n\r\n    const parts = attributeValue.split(\"|\");\r\n\r\n    parts.forEach((part) => {\r\n      const trimmedPart = part.trim();\r\n      if (!trimmedPart) return;\r\n\r\n      const match = trimmedPart.match(/^([\\w-]+)(\\[(.*?)\\])?$/);\n\n      if (match) {\n        const fullOptionKey = this.toCamelCase(match[1]);\n        const paramsString = match[3] || \"\";\n        const params = paramsString\n          .split(\";\")\n          .map((p) => p.trim())\n          .filter((p) => p.length > 0);\n\r\n        const parsedParam: ISplitOptionItem = this.parseParamsArray(params);\r\n\r\n        switch (fullOptionKey) {\r\n          case \"line\":\r\n            (options.line as ISplitOptionItem[]).push(parsedParam);\r\n            break;\r\n          case \"word\":\r\n            (options.word as ISplitOptionItem[]).push(parsedParam);\r\n            break;\r\n          case \"char\":\r\n            (options.char as ISplitOptionItem[]).push(parsedParam);\r\n            break;\r\n          case \"charLine\":\r\n            (options.charLine as ISplitOptionItem[]).push(parsedParam);\r\n            break;\r\n          case \"charWord\":\r\n            (options.charWord as ISplitOptionItem[]).push(parsedParam);\r\n            break;\r\n          case \"wordLine\":\r\n            (options.wordLine as ISplitOptionItem[]).push(parsedParam);\r\n            break;\r\n          case \"fit\":\n            options.fit = true;\n            break;\n          case \"trimInlineGaps\":\n            options.trimInlineGaps = true;\n            break;\n          default:\n            console.warn(\n              `SplitOptionsParserTool: Unrecognized option type \"${fullOptionKey}\" in part \"${trimmedPart}\"`,\n            );\n            break;\n        }\r\n      } else {\r\n        console.warn(`SplitOptionsParserTool: Could not parse part format \"${trimmedPart}\"`);\r\n      }\r\n    });\r\n\r\n    return options;\r\n  }\r\n\r\n  private toCamelCase(str: string): string {\r\n    return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());\r\n  }\r\n\r\n  private parseParamsArray(params: string[]): ISplitOptionItem {\r\n    const result: ISplitOptionItem = { align: \"start\" };\r\n\r\n    params.forEach((param) => {\r\n      if (param === \"abs\") {\r\n        result.abs = true;\r\n      } else if (param.startsWith(\"random\")) {\r\n        result.align = \"random\";\r\n        const randomMatch = param.match(/random\\(\\s*(-?\\d+)\\s*,\\s*(-?\\d+)\\s*\\)/);\r\n        if (randomMatch) {\r\n          const first = parseInt(randomMatch[1], 10);\r\n          const second = parseInt(randomMatch[2], 10);\r\n          result.random = {\r\n            min: Math.min(first, second),\r\n            max: Math.max(first, second),\r\n          };\r\n        }\r\n      } else if ([\"start\", \"center\", \"end\"].includes(param)) {\r\n        result.align = param;\r\n      }\r\n    });\r\n\r\n    return result;\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\";\r\n\r\nexport interface RuleParserInput {\r\n  value: string;\r\n}\r\n\r\nexport interface RuleParserResult {\r\n  key: string;\r\n  params?: string[];\r\n}\r\n\r\nexport default class RuleParserTool implements IStringTool<RuleParserInput, RuleParserResult[]> {\r\n  process({ value }: RuleParserInput): RuleParserResult[] {\r\n    const result: string[] = [];\r\n    let current = \"\";\r\n    let depth = 0;\r\n    for (let i = 0; i < value.length; i++) {\r\n      const c = value[i];\r\n      if (c === \"(\") depth++;\r\n      if (c === \")\") depth--;\r\n      if (c === \"|\" && depth === 0) {\r\n        if (current.trim()) result.push(current.trim());\r\n        current = \"\";\r\n      } else {\r\n        current += c;\r\n      }\r\n    }\r\n    if (current.trim()) result.push(current.trim());\r\n\r\n    return result.map((ruleStr) => {\r\n      const match = ruleStr.match(/^(\\w+)(?:\\((.*)\\))?$/);\r\n      if (match) {\r\n        const [, key, params] = match;\r\n        if (params) {\r\n          return { key, params: params.split(\",\").map((s) => s.trim()) };\r\n        }\r\n        return { key };\r\n      }\r\n\r\n      const colonIndex = ruleStr.indexOf(\":\");\r\n      if (colonIndex !== -1) {\r\n        const key = ruleStr.slice(0, colonIndex).trim();\r\n        const paramsString = ruleStr.slice(colonIndex + 1).trim();\r\n        const params = paramsString ? paramsString.split(\",\").map((s) => s.trim()) : undefined;\r\n        return { key, params };\r\n      }\r\n\r\n      return { key: ruleStr };\r\n    });\r\n  }\r\n}\r\n","import { IStringTool } from \"../core/IStringTool\";\r\nimport { RuleParserResult } from \"./RuleParserTool\";\r\n\r\nexport interface ValidationContext {\r\n  fieldKey?: string;\r\n  values?: Record<string, any>;\r\n  getValue?: (key: string) => any;\r\n}\r\n\r\nexport interface ValidateInput {\r\n  rules: RuleParserResult[];\r\n  value: any;\r\n  type?: \"input\" | \"beforeinput\";\r\n  context?: ValidationContext;\r\n}\r\n\r\nexport interface ValidationResult {\r\n  valid: boolean;\r\n  errors: string[];\r\n}\r\n\r\ntype ValidatorFn = (value: any, params?: string[], context?: ValidationContext) => boolean;\r\n\r\nexport class ValidationTool implements IStringTool<ValidateInput, ValidationResult> {\r\n  process({ rules, value, type = \"input\", context }: ValidateInput): ValidationResult {\r\n    const errors: string[] = [];\r\n    for (const rule of rules) {\r\n      var beforeInputValidatorFn: ValidatorFn | null = null;\r\n      var inputValidatorFn: ValidatorFn | null = null;\r\n      var inputValid = true;\r\n      var beforeInputValid = true;\r\n\r\n      if (type == \"input\") {\r\n        inputValidatorFn = this.inputValidators[rule.key];\r\n        if (!inputValidatorFn) continue;\r\n      }\r\n      if (type == \"beforeinput\") {\r\n        beforeInputValidatorFn = this.beforeInputValidators[rule.key];\r\n        if (!beforeInputValidatorFn) continue;\r\n      }\r\n\r\n      if (inputValidatorFn) {\r\n        inputValid = inputValidatorFn(value, rule.params, context);\r\n      }\r\n      if (beforeInputValidatorFn) {\r\n        beforeInputValid = beforeInputValidatorFn(value, rule.params, context);\r\n      }\r\n\r\n      if (!beforeInputValid) {\r\n        errors.push(this.getErrorMessage(rule.key, rule.params));\r\n      }\r\n      if (!inputValid) {\r\n        errors.push(this.getErrorMessage(rule.key, rule.params));\r\n      }\r\n    }\r\n    return { valid: errors.length === 0, errors };\r\n  }\r\n\r\n  inputValidators: Record<string, ValidatorFn> = {\r\n    required: (v) => v != null && String(v).trim() !== \"\",\r\n    min: (v, params) => typeof v === \"string\" && v.length >= Number(params?.[0] ?? 0),\r\n    max: (v, params) =>\r\n      typeof v === \"string\" && v.length <= Number(params?.[0] ?? Number.MAX_SAFE_INTEGER),\r\n    checked: (v) => {\r\n      if (Array.isArray(v)) {\r\n        return v.length > 0;\r\n      }\r\n      if (v === true || v === \"true\" || v === 1 || v === \"1\") {\r\n        return true;\r\n      }\r\n      if (typeof v === \"string\") {\r\n        const normalized = v.trim().toLowerCase();\r\n        if (normalized === \"false\" || normalized === \"0\") {\r\n          return false;\r\n        }\r\n        return normalized.length > 0;\r\n      }\r\n      return !!v;\r\n    },\r\n    email: (v) => typeof v === \"string\" && /^[^\\s@]+@([a-z0-9-]+\\.)+[a-z]{2,}$/i.test(v),\r\n    phone: (v) => {\r\n      if (typeof v !== \"string\") return false;\r\n      const normalized = v.trim();\r\n      if (normalized === \"\") return false;\r\n      if (!/^[0-9()\\s+-.]+$/.test(normalized)) return false;\r\n      const digitCount = normalized.replace(/\\D/g, \"\").length;\r\n      return digitCount >= 7 && digitCount <= 15;\r\n    },\r\n    number: (v) => typeof v === \"string\" && /^-?\\d+(\\.\\d+)?$/.test(v),\r\n    integer: (v) => typeof v === \"string\" && /^-?\\d+$/.test(v),\r\n    url: (v) =>\r\n      typeof v === \"string\" &&\r\n      /^(https?:\\/\\/)?([\\w\\-]+\\.)+[\\w\\-]+(\\/[\\w\\-._~:\\/?#[\\]@!$&'()*+,;=]*)?$/.test(v),\r\n    regex: (v, params) => this.testByRegex(v, params?.[0]),\r\n    alpha: (v) => this.testByRegex(v, \"^[A-Za-z]+$\", true),\r\n    alpha_num: (v) => this.testByRegex(v, \"^[A-Za-z0-9]+$\", true),\r\n    alpha_dash: (v) => this.testByRegex(v, \"^[A-Za-z0-9_-]+$\", true),\r\n    same: (v, params, context) => {\r\n      const targetKey = params?.[0];\r\n      const otherValue = this.getContextValue(context, targetKey);\r\n      if (targetKey && otherValue === undefined) return false;\r\n      return this.areValuesEqual(v, otherValue);\r\n    },\r\n    different: (v, params, context) => {\r\n      const targetKey = params?.[0];\r\n      const otherValue = this.getContextValue(context, targetKey);\r\n      if (targetKey && otherValue === undefined) return false;\r\n      return !this.areValuesEqual(v, otherValue);\r\n    },\r\n    range: (v, params) => {\r\n      if (v == null || v === \"\") return true;\r\n      const value = Number(v);\r\n      const min = Number(params?.[0]);\r\n      const max = Number(params?.[1]);\r\n      if (Number.isNaN(value) || Number.isNaN(min) || Number.isNaN(max)) {\r\n        return false;\r\n      }\r\n      return value >= min && value <= max;\r\n    },\r\n    digits: (v, params) => {\r\n      if (typeof v !== \"string\") return false;\r\n      const length = Number(params?.[0] ?? 0);\r\n      if (length <= 0) return false;\r\n      return new RegExp(`^\\\\d{${length}}$`).test(v);\r\n    },\r\n    ip: (v) => typeof v === \"string\" && (this.isIPv4(v) || this.isIPv6(v)),\r\n    mimes: (v, params) => this.validateMimes(v, params),\r\n    max_size: (v, params) => {\r\n      const limit = Number(params?.[0]);\r\n      if (!limit || limit <= 0) return true;\r\n      return this.validateMaxSize(v, limit);\r\n    },\r\n    after: (v, params, context) => this.compareDates(v, params, context, \"after\"),\r\n    before: (v, params, context) => this.compareDates(v, params, context, \"before\"),\r\n  };\r\n\r\n  beforeInputValidators: Record<string, ValidatorFn> = {\r\n    number: (v) => /^-?\\d*\\.?\\d*$/.test(v),\r\n    integer: (v) => /^-?\\d*$/.test(v),\r\n    email: (v) => /^[\\w@.\\-+]*$/.test(v),\r\n    phone: (v) => /^[0-9()\\s+-.]*$/.test(v),\r\n    letters: (v) => /^[a-zA-Z]*$/.test(v),\r\n    lettersSpaces: (v) => /^[a-zA-Z\\s]*$/.test(v),\r\n    lettersNumbers: (v) => /^[a-zA-Z0-9]*$/.test(v),\r\n    alpha: (v) => /^[A-Za-z]*$/.test(v),\r\n    alpha_num: (v) => /^[A-Za-z0-9]*$/.test(v),\r\n    alpha_dash: (v) => /^[A-Za-z0-9_-]*$/.test(v),\r\n    digits: (v, params) => {\r\n      const length = Number(params?.[0] ?? 0);\r\n      if (length <= 0) return /^\\d*$/.test(v);\r\n      return new RegExp(`^\\\\d{0,${length}}$`).test(v);\r\n    },\r\n    url: (v) => /^[a-zA-Z0-9\\-._~:\\/?#\\[\\]@!$&'()*+,;=%]*$/.test(v),\r\n    pattern: (v, params) => {\r\n      try {\r\n        return new RegExp(params?.[0] || \"\").test(v);\r\n      } catch {\r\n        return true;\r\n      }\r\n    },\r\n  };\r\n\r\n  getErrorMessage(key: string, params?: string[]): string {\r\n    switch (key) {\r\n      case \"required\":\r\n        return \"This field is required\";\r\n      case \"email\":\r\n        return \"Invalid email address\";\r\n      case \"min\":\r\n        return `Minimum ${params?.[0]} characters`;\r\n      case \"max\":\r\n        return `Maximum ${params?.[0]} characters`;\r\n      case \"phone\":\r\n        return \"Invalid phone number\";\r\n      case \"number\":\r\n        return \"Only numbers are allowed\";\r\n      case \"integer\":\r\n        return \"Only whole numbers are allowed\";\r\n      case \"url\":\r\n        return \"Invalid URL address\";\r\n      case \"checked\":\r\n        return \"You must accept\";\r\n      case \"regex\":\r\n        return \"Value does not match the required pattern\";\r\n      case \"alpha\":\r\n        return \"Only letters are allowed\";\r\n      case \"alpha_num\":\r\n        return \"Only letters and numbers are allowed\";\r\n      case \"alpha_dash\":\r\n        return \"Only letters, numbers, dashes, and underscores are allowed\";\r\n      case \"same\":\r\n        return \"Values do not match\";\r\n      case \"different\":\r\n        return \"Values must be different\";\r\n      case \"range\":\r\n        return `Value must be between ${params?.[0]} and ${params?.[1]}`;\r\n      case \"digits\":\r\n        return `Value must contain exactly ${params?.[0]} digits`;\r\n      case \"ip\":\r\n        return \"Invalid IP address\";\r\n      case \"mimes\":\r\n        return `Allowed file types: ${params?.join(\", \")}`;\r\n      case \"max_size\":\r\n        return `File must be smaller than ${params?.[0]} KB`;\r\n      case \"after\":\r\n        return `Date must be after ${params?.[0]}`;\r\n      case \"before\":\r\n        return `Date must be before ${params?.[0]}`;\r\n      default:\r\n        return \"Invalid value\";\r\n    }\r\n  }\r\n\r\n  private validateMimes(value: any, params?: string[]): boolean {\r\n    if (!params || params.length === 0) return true;\r\n    const files = this.extractFiles(value);\r\n    if (files.length === 0) return true;\r\n    const allowed = params.map((p) => p.trim().toLowerCase());\r\n    return files.every((file) => this.isMimeAllowed(file, allowed));\r\n  }\r\n\r\n  private validateMaxSize(value: any, limitKb: number): boolean {\r\n    const files = this.extractFiles(value);\r\n    if (files.length === 0) return true;\r\n    const maxBytes = limitKb * 1024;\r\n    return files.every((file) => {\r\n      if (typeof file.size !== \"number\") return true;\r\n      return file.size <= maxBytes;\r\n    });\r\n  }\r\n\r\n  private extractFiles(value: any): Array<{ name?: string; size?: number; type?: string }> {\r\n    if (!value) return [];\r\n    const files: Array<{ name?: string; size?: number; type?: string }> = [];\r\n\r\n    if (typeof File !== \"undefined\" && value instanceof File) {\r\n      files.push(value);\r\n      return files;\r\n    }\r\n\r\n    if (typeof FileList !== \"undefined\" && value instanceof FileList) {\r\n      return Array.from(value);\r\n    }\r\n\r\n    if (Array.isArray(value)) {\r\n      value.forEach((item) => {\r\n        files.push(...this.extractFiles(item));\r\n      });\r\n      return files;\r\n    }\r\n\r\n    if (typeof value === \"object\" && (\"name\" in value || \"size\" in value || \"type\" in value)) {\r\n      files.push(value as any);\r\n      return files;\r\n    }\r\n\r\n    if (typeof value === \"string\" && value !== \"\") {\r\n      files.push({ name: value });\r\n    }\r\n\r\n    return files;\r\n  }\r\n\r\n  private isMimeAllowed(file: { name?: string; type?: string }, allowed: string[]): boolean {\r\n    const mime = (file.type || \"\").toLowerCase();\r\n    const ext = this.getFileExtension(file.name);\r\n    return allowed.some((rule) => {\r\n      const normalized = rule.replace(/^\\./, \"\").toLowerCase();\r\n      if (!normalized) return false;\r\n      if (normalized.includes(\"/\")) {\r\n        return mime === normalized;\r\n      }\r\n      return ext === normalized;\r\n    });\r\n  }\r\n\r\n  private getFileExtension(name?: string): string {\r\n    if (!name) return \"\";\r\n    const parts = name.split(\".\");\r\n    if (parts.length <= 1) return \"\";\r\n    return (parts.pop() || \"\").toLowerCase();\r\n  }\r\n\r\n  private compareDates(\r\n    value: any,\r\n    params: string[] | undefined,\r\n    context: ValidationContext | undefined,\r\n    mode: \"before\" | \"after\",\r\n  ): boolean {\r\n    if (value == null || value === \"\") return true;\r\n    const target = params?.[0];\r\n    if (!target) return true;\r\n    const currentDate = this.toDate(value);\r\n    const referenceDate = this.resolveDateReference(target, context);\r\n    if (!currentDate || !referenceDate) return false;\r\n    return mode === \"after\"\r\n      ? currentDate.getTime() > referenceDate.getTime()\r\n      : currentDate.getTime() < referenceDate.getTime();\r\n  }\r\n\r\n  private resolveDateReference(token: string, context?: ValidationContext): Date | null {\r\n    const contextualValue = this.getContextValue(context, token);\r\n    if (contextualValue !== undefined) {\r\n      return this.toDate(contextualValue);\r\n    }\r\n    if (token.toLowerCase() === \"now\") {\r\n      return new Date();\r\n    }\r\n    if (token.toLowerCase() === \"today\") {\r\n      const today = new Date();\r\n      today.setHours(0, 0, 0, 0);\r\n      return today;\r\n    }\r\n    return this.toDate(token);\r\n  }\r\n\r\n  private toDate(value: any): Date | null {\r\n    if (value == null || value === \"\") return null;\r\n    if (value instanceof Date) {\r\n      return Number.isNaN(value.getTime()) ? null : value;\r\n    }\r\n    if (typeof value === \"number\") {\r\n      const date = new Date(value);\r\n      return Number.isNaN(date.getTime()) ? null : date;\r\n    }\r\n    if (typeof value === \"string\") {\r\n      const timestamp = Date.parse(value);\r\n      if (!Number.isNaN(timestamp)) {\r\n        return new Date(timestamp);\r\n      }\r\n    }\r\n    return null;\r\n  }\r\n\r\n  private testByRegex(value: any, pattern?: string, allowEmpty = false): boolean {\r\n    if (pattern == null || pattern === \"\") return true;\r\n    const stringValue = typeof value === \"string\" ? value : value == null ? \"\" : String(value);\r\n    if (allowEmpty && stringValue === \"\") return true;\r\n    try {\r\n      const { source, flags } = this.normalizeRegex(pattern);\r\n      return new RegExp(source, flags).test(stringValue);\r\n    } catch {\r\n      return true;\r\n    }\r\n  }\r\n\r\n  private normalizeRegex(pattern: string): { source: string; flags: string } {\r\n    const trimmed = pattern.trim();\r\n    if (trimmed.startsWith(\"/\") && trimmed.lastIndexOf(\"/\") > 0) {\r\n      const lastSlashIndex = trimmed.lastIndexOf(\"/\");\r\n      const source = trimmed.slice(1, lastSlashIndex);\r\n      const flags = trimmed.slice(lastSlashIndex + 1);\r\n      return { source, flags };\r\n    }\r\n    return { source: trimmed, flags: \"\" };\r\n  }\r\n\r\n  private getContextValue(context: ValidationContext | undefined, key?: string): any {\r\n    if (!context || !key) return undefined;\r\n    if (context.values && Object.prototype.hasOwnProperty.call(context.values, key)) {\r\n      return context.values[key];\r\n    }\r\n    if (context.getValue) {\r\n      return context.getValue(key);\r\n    }\r\n    return undefined;\r\n  }\r\n\r\n  private areValuesEqual(a: any, b: any): boolean {\r\n    if (Array.isArray(a) || Array.isArray(b)) {\r\n      return JSON.stringify(a) === JSON.stringify(b);\r\n    }\r\n    return a === b;\r\n  }\r\n\r\n  private isIPv4(value: string): boolean {\r\n    const segments = value.split(\".\");\r\n    if (segments.length !== 4) return false;\r\n    return segments.every((segment) => {\r\n      if (!/^\\d+$/.test(segment)) return false;\r\n      const num = Number(segment);\r\n      return num >= 0 && num <= 255;\r\n    });\r\n  }\r\n\r\n  private isIPv6(value: string): boolean {\r\n    if (!value) return false;\r\n    if (value === \"::\") return true;\r\n    const parts = value.split(\"::\");\r\n    if (parts.length > 2) return false;\r\n\r\n    const hextetPattern = /^[0-9a-fA-F]{1,4}$/;\r\n    const segments = value.split(\":\");\r\n    if (parts.length === 2) {\r\n      return (\r\n        segments.every((segment) => segment === \"\" || hextetPattern.test(segment)) &&\r\n        segments.length <= 8\r\n      );\r\n    }\r\n    return segments.length === 8 && segments.every((segment) => hextetPattern.test(segment));\r\n  }\r\n}\r\n","type StyleValue = string | number;\r\ntype StyleVars = Record<string, StyleValue>;\r\ntype StyleProps = Record<string, StyleValue>;\r\n\r\nexport class StyleTxn {\n  public pendingVars = new Map<Element, StyleVars>();\n  public pendingProps = new Map<Element, StyleProps>();\n  public isOpen = false;\n\n  private canUseTypedOM(el: Element): boolean {\n    return (\n      \"attributeStyleMap\" in el &&\n      typeof CSS !== \"undefined\" &&\n      typeof CSS.number === \"function\" &&\n      typeof CSS.px === \"function\"\n    );\n  }\n\n  private writeVar(el: Element, key: string, value: StyleValue): void {\n    const style = (el as HTMLElement).style;\n\n    if (this.canUseTypedOM(el) && typeof value === \"number\" && Number.isFinite(value)) {\n      try {\n        const styleMap = (el as any).attributeStyleMap;\n        styleMap.set(key, CSS.number(value));\n        return;\n      } catch {\n        // Fall back to string-based writes for unsupported value/syntax pairs.\n      }\n    }\n\n    style.setProperty(key, String(value));\n  }\n\r\n  public begin(): void {\r\n    if (this.isOpen) return;\r\n    this.isOpen = true;\r\n  }\r\n\r\n  public setVars(el: Element, vars: StyleVars): void {\r\n    if (!this.isOpen) {\r\n      console.warn(\"StyleTxn: call begin() first to set custom properties.\");\r\n      return;\r\n    }\r\n    const currentVars = this.pendingVars.get(el) ?? {};\r\n    for (const [k, v] of Object.entries(vars)) {\r\n      if (currentVars[k] === v) continue;\r\n      currentVars[k] = v;\r\n    }\r\n    this.pendingVars.set(el, currentVars);\r\n  }\r\n\r\n  public setVar(el: Element, key: string, value: StyleValue): void {\r\n    if (!this.isOpen) {\r\n      console.warn(\"StyleTxn: call begin() first to set custom properties.\");\r\n      return;\r\n    }\r\n    const currentVars = this.pendingVars.get(el) ?? {};\r\n    if (currentVars[key] === value) return;\r\n    currentVars[key] = value;\r\n    this.pendingVars.set(el, currentVars);\r\n  }\r\n\r\n  /**\r\n   * Directly sets a CSS custom property (variable) on an element using CSS Typed OM\r\n   * for improved performance. Falls back to string-based assignment if not supported.\r\n   * Note: This writes immediately. Use `begin()`, `setVar()`, `commit()` for batched writes.\r\n   */\r\n  public setVarDirect(el: Element, key: string, value: StyleValue): void {\n    this.writeVar(el, key, value);\n  }\n\r\n  public setProps(el: Element, props: StyleProps): void {\r\n    if (!this.isOpen) {\r\n      console.warn(\"StyleTxn: call begin() first to set standard properties.\");\r\n      return;\r\n    }\r\n    const currentProps = this.pendingProps.get(el) ?? {};\r\n    for (const [k, v] of Object.entries(props)) {\r\n      if (currentProps[k] === v) continue;\r\n      currentProps[k] = v;\r\n    }\r\n\r\n    this.pendingProps.set(el, currentProps);\r\n  }\r\n\r\n  public setProp(el: Element, key: string, value: StyleValue): void {\r\n    if (!this.isOpen) {\r\n      console.warn(\"StyleTxn: call begin() first to set standard properties.\");\r\n      return;\r\n    }\r\n    const currentProps = this.pendingProps.get(el) ?? {};\r\n    if (currentProps[key] === value) return;\r\n    currentProps[key] = value;\r\n    this.pendingProps.set(el, currentProps);\r\n  }\r\n\r\n  public run(fn: () => void): void {\r\n    const alreadyOpen = this.isOpen;\r\n    if (!alreadyOpen) {\r\n      this.begin();\r\n    }\r\n    try {\r\n      fn();\r\n      if (!alreadyOpen) {\r\n        this.commit();\r\n      }\r\n    } catch (error) {\r\n      if (!alreadyOpen) {\r\n        this.cancel();\r\n      }\r\n      throw error;\r\n    }\r\n  }\r\n\r\n  public commit(): void {\n    if (!this.isOpen) return;\n    this.isOpen = false;\n\n    for (const [el, vars] of this.pendingVars) {\n      for (const [k, v] of Object.entries(vars)) {\n        this.writeVar(el, k, v);\n      }\n    }\n    this.pendingVars.clear();\n\r\n    for (const [el, props] of this.pendingProps) {\r\n      const style = (el as HTMLElement).style;\r\n      for (const [k, v] of Object.entries(props)) {\r\n        (style as any)[k] = String(v);\r\n      }\r\n    }\r\n    this.pendingProps.clear();\r\n  }\r\n\r\n  public cancel(): void {\r\n    this.pendingVars.clear();\r\n    this.pendingProps.clear();\r\n    this.isOpen = false;\r\n  }\r\n}\r\n\r\nexport const styleTxn = new StyleTxn();\r\n","import BoundingClientRectTool from \"../tools/BoundingClientRectTool\";\r\nimport DOMAttributeTool from \"../tools/DOMAttributeTool\";\r\nimport RecordAttributeTool from \"../tools/RecordAttributeTool\";\r\nimport RelativePositionTool from \"../tools/RelativePositionTool\";\r\nimport LerpTool from \"../tools/LerpTool\";\r\nimport TransformNullifyTool from \"../tools/TransformNullifyTool\";\r\nimport UnitParserTool from \"../tools/UnitParserTool\";\r\nimport AdaptiveLerpTool from \"../tools/AdaptiveLerpTool\";\r\nimport OriginParserTool from \"../tools/OriginParserTool\";\r\nimport ColorParserTool from \"../tools/ColorParserTool\";\r\nimport EasingFunctionTool from \"../tools/EasingFunctionTool\";\r\nimport MagneticPullTool from \"../tools/MagneticPullTool\";\r\nimport LerpColorTool from \"../tools/LerpColorTool\";\r\nimport LerpVector2Tool from \"../tools/LerpVector2Tool\";\r\nimport TransformScaleParserTool from \"../tools/TransformScaleParserTool\";\r\nimport { SplitOptionsParserTool } from \"../tools/SplitOptionsParserTool\";\r\nimport RuleParserTool from \"../tools/RuleParserTool\";\r\nimport { ValidationTool } from \"../tools/ValidationTool\";\r\nimport { frameDOM } from \"../utils/frame-dom\";\r\nimport { styleTxn } from \"../utils/style-txn\";\r\n\r\n/**\r\n * Container holding references to all essential tools used within the library.\r\n * Dependency injection.\r\n */\r\nexport interface StringToolsContainer {\r\n  /** Tool for reading DOM attributes (including data-*). */\r\n  domAttribute: DOMAttributeTool;\r\n\r\n  /** Tool for reading attributes from a plain JS object or dataset. */\r\n  recordAttribute: RecordAttributeTool;\r\n\r\n  /** Tool for calculating the relative position between two elements. */\r\n  relativePosition: RelativePositionTool;\r\n\r\n  /** Tool that nullifies the effect of CSS transform matrix. */\r\n  transformNullify: TransformNullifyTool;\r\n\r\n  /** Tool that wraps getBoundingClientRect with consistent output. */\r\n  boundingClientRect: BoundingClientRectTool;\r\n\r\n  /** Tool for parsing string-based values like '50%', '2rem', 'selfHeight'. */\r\n  unitParser: UnitParserTool;\r\n\r\n  /** Tool for performing linear interpolation (lerp). */\r\n  lerp: LerpTool;\r\n\r\n  /**\r\n   * Tool for adaptive interpolation based on dynamic input value.\r\n   * Useful when smoothing cursor speed, scroll velocity, etc.\r\n   */\r\n  adaptiveLerp: AdaptiveLerpTool;\r\n\r\n  /**\r\n   * Tool for parsing origin strings.\r\n   * Supports values like `'top'`, `'center'`, or random expressions like `'random(top, bottom)'`.\r\n   */\r\n  originParser: OriginParserTool;\r\n\r\n  /**\r\n   * Tool for parsing CSS color strings into { r, g, b, a } format.\r\n   * Supports `#hex`, `rgb[a](...)`, `hsl[a](...)` inputs.\r\n   */\r\n  colorParser: ColorParserTool;\r\n\r\n  /**\r\n   * Tool for validating strings using rules like `required`, `minLength`, `email`, etc.\r\n   * Returns validation status, error code, and optional message.\r\n   */\r\n  validation: ValidationTool;\r\n\r\n  /**\r\n   * Tool for parsing CSS-like easing strings into easing functions.\r\n   * Supports keywords like `'ease'`, `'linear'`, and full `cubic-bezier(...)` expressions.\r\n   */\r\n  easingFunction: EasingFunctionTool;\r\n\r\n  /**\r\n   * Tool for calculating magnetic offset strength based on proximity to pointer.\r\n   */\r\n  magneticPull: MagneticPullTool;\r\n\r\n  /**\r\n   * Tool for interpolating between two RGBA colors.\r\n   * Accepts `from` and `to` colors as `{ r, g, b, a }`, and a `progress` value from `0` to `1`.\r\n   * Returns an interpolated `StringColor` object.\r\n   */\r\n  lerpColor: LerpColorTool;\r\n\r\n  /**\r\n   * Tool for interpolating between two 2D vectors.\r\n   * Accepts `{ x, y }` objects and a `progress` value between `0` and `1`.\r\n   * Returns a new `{ x, y }` vector.\r\n   */\r\n  lerpVector: LerpVector2Tool;\r\n\r\n  transformScaleParser: TransformScaleParserTool;\r\n\r\n  optionsParser: SplitOptionsParserTool;\r\n\r\n  ruleParser: RuleParserTool;\r\n  styleTxn: typeof styleTxn;\r\n}\r\n\r\n/**\r\n * Default container holding references to internally implemented tools.\r\n * Modules can replace these with custom instances via setter methods.\r\n */\r\nexport class DefaultToolsContainer implements StringToolsContainer {\r\n  public domAttribute = new DOMAttributeTool();\r\n  public recordAttribute = new RecordAttributeTool();\r\n  public transformNullify = new TransformNullifyTool();\r\n  public boundingClientRect = new BoundingClientRectTool();\r\n  public relativePosition = new RelativePositionTool(this.transformNullify);\r\n  public unitParser = new UnitParserTool();\r\n  public lerp = new LerpTool();\r\n  public adaptiveLerp = new AdaptiveLerpTool();\r\n  public originParser = new OriginParserTool();\r\n  public colorParser = new ColorParserTool();\r\n  public validation = new ValidationTool();\r\n  public easingFunction = new EasingFunctionTool();\r\n  public magneticPull = new MagneticPullTool();\r\n  public lerpColor = new LerpColorTool();\r\n  public lerpVector = new LerpVector2Tool();\r\n  public transformScaleParser = new TransformScaleParserTool();\r\n  public optionsParser = new SplitOptionsParserTool();\r\n  public ruleParser = new RuleParserTool();\r\n  public styleTxn = styleTxn;\r\n}\r\n","export function isCoarsePointer(): boolean {\r\n  const mm =\r\n    typeof window !== \"undefined\" && typeof window.matchMedia === \"function\"\r\n      ? window.matchMedia(\"(pointer: coarse)\").matches\r\n      : false;\r\n  const touch = typeof navigator !== \"undefined\" ? (navigator.maxTouchPoints || 0) > 0 : false;\r\n  const narrow = typeof window !== \"undefined\" ? window.innerWidth <= 768 : false;\r\n  return mm || touch || narrow;\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringData } from \"../../core/StringData\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { isCoarsePointer } from \"../../utils/isCoarsePointer\";\r\nimport { styleTxn } from \"../../utils/style-txn\";\r\n\r\ntype CursorTargetState = {\r\n  prevX: number;\r\n  prevY: number;\r\n};\r\n\r\ntype CursorObjectDimensions = {\r\n  width: number;\r\n  height: number;\r\n  halfWidth: number;\r\n  halfHeight: number;\r\n};\r\n\r\ntype CursorPrevSnapshot = {\r\n  x: number;\r\n  y: number;\r\n  stepX: number;\r\n  stepY: number;\r\n};\r\n\r\ntype CursorPortal = {\r\n  id: string;\r\n  element: HTMLElement;\r\n  content: HTMLElement | null;\r\n  prev: CursorPrevSnapshot;\r\n  hoverCount: number;\r\n  showTimer: ReturnType<typeof setTimeout> | null;\r\n  lerp: number | null;\r\n};\r\n\r\nconst targetStates = new WeakMap<StringObject, CursorTargetState>();\r\nconst CURSOR_EPSILON = 0.0005;\r\nconst DEFAULT_CURSOR_ID = \"default\";\r\nconst CURSOR_PORTAL_SELECTOR = \"[string-cursor],[data-string-cursor]\";\r\nconst CURSOR_PORTAL_CONTENT_SELECTOR = \"[string-cursor-content],[data-string-cursor-content]\";\r\nconst MIN_FRAME_DELTA = 1 / 240;\r\nconst roundTo = (value: number, precision: number) => {\r\n  const scale = Math.pow(10, precision);\r\n  return Math.round(value * scale) / scale;\r\n};\r\n\r\nfunction getTargetState(object: StringObject): CursorTargetState {\r\n  let state = targetStates.get(object);\r\n  if (!state) {\r\n    state = { prevX: Number.NaN, prevY: Number.NaN };\r\n    targetStates.set(object, state);\r\n  }\r\n  return state;\r\n}\r\n\r\n/**\r\n * StringCursor Module\r\n *\r\n * Handles cursor tracking and hover states for StringTune objects.\r\n *\r\n * Safari Navigation Fix:\r\n * Safari has an issue where mouseleave events are not fired when navigation occurs\r\n * (especially with NuxtLink/router navigation). This module includes several\r\n * workarounds to ensure proper cleanup:\r\n *\r\n * 1. MutationObserver - detects when elements are removed from DOM\r\n * 2. beforeunload/pagehide - captures traditional navigation\r\n * 3. visibilitychange - captures modern SPA navigation\r\n * 4. DOM existence checks - prevents operations on removed elements\r\n */\r\nexport class StringCursor extends StringModule {\r\n  private cursorPrev: CursorPrevSnapshot = {\r\n    x: Number.NaN,\r\n    y: Number.NaN,\r\n    stepX: Number.NaN,\r\n    stepY: Number.NaN,\r\n  };\r\n  private cursorPortals: Map<string, CursorPortal[]> = new Map();\r\n  private hoveredObjects: Set<StringObject> = new Set();\r\n  private globalListenersBound = false;\r\n  private boundBeforeUnload = () => this.cleanupHoverTargets();\r\n  private boundPageHide = () => this.cleanupHoverTargets();\r\n  private boundVisibilityChange = () => {\r\n    if (document.hidden) {\r\n      this.cleanupHoverTargets();\r\n    }\r\n  };\r\n  protected enabled = true;\r\n\r\n  private lastFrameTime: number = 0;\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"cursor\";\r\n    this.cssProperties = [\r\n      { name: \"--x\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--y\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--x-lerp\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--y-lerp\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--x-px\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--y-px\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--dx\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--dy\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--angle\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--angle-deg\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n    ];\r\n\r\n    this.permissions.mobile.rebuild.height = false;\r\n    this.permissions.mobile.rebuild.width = false;\r\n    this.permissions.mobile.rebuild.scrollHeight = false;\r\n\r\n    this.attributesToMap = [\r\n      ...this.attributesToMap,\r\n      {\r\n        key: \"target-disable\",\r\n        type: \"boolean\",\r\n        fallback: this.settings[\"target-disable\"],\r\n      },\r\n      {\r\n        key: \"target-style-disable\",\r\n        type: \"boolean\",\r\n        fallback: this.settings[\"target-style-disable\"],\r\n      },\r\n      {\r\n        key: \"cursor-target\",\r\n        type: \"string\",\r\n        fallback: this.settings[\"cursor-target\"] ?? DEFAULT_CURSOR_ID,\r\n      },\r\n      {\r\n        key: \"target-class\",\r\n        type: \"string\",\r\n        fallback: this.settings[\"target-class\"],\r\n      },\r\n      {\r\n        key: \"cursor-class\",\r\n        type: \"string\",\r\n        fallback: this.settings[\"cursor-class\"],\r\n      },\r\n      {\r\n        key: \"alignment\",\r\n        type: { type: \"enum\", values: [\"start\", \"center\", \"end\"] },\r\n        fallback: this.settings[\"alignment\"],\r\n      },\r\n      {\r\n        key: \"cursor-enter\",\r\n        type: { type: \"enum\", values: [\"snap\", \"smooth\"] },\r\n        fallback: \"snap\",\r\n      },\r\n      {\r\n        key: \"cursor-leave\",\r\n        type: { type: \"enum\", values: [\"snap\", \"smooth\"] },\r\n        fallback: \"smooth\",\r\n      },\r\n      {\r\n        key: \"cursor-leave-hold\",\r\n        type: \"boolean\",\r\n        fallback: false,\r\n      },\r\n      {\r\n        key: \"lerp\",\r\n        type: \"number\",\r\n        fallback: this.settings[\"lerp\"],\r\n        transform: (value: number) => {\r\n          return this.tools.adaptiveLerp.process({\r\n            value,\r\n            inMin: 0.1,\r\n            inMax: 1.0,\r\n            outMin: 0.05,\r\n            outMax: 0.65,\r\n          });\r\n        },\r\n      },\r\n      {\r\n        key: \"cursor-float\",\r\n        type: \"number\",\r\n        fallback: 2,\r\n      },\r\n      {\r\n        key: \"cursor-vars\",\r\n        type: \"string\",\r\n        fallback: \"\",\r\n      },\r\n    ];\r\n\r\n    if (isCoarsePointer()) {\r\n      this.enabled = false;\r\n    }\r\n\r\n    this.collectCursorPortals();\r\n    if (this.enabled) {\r\n      this.bindGlobalLifecycleListeners();\r\n    }\r\n  }\r\n\r\n  initializeObject(\r\n    globalId: number,\r\n    object: StringObject,\r\n    element: HTMLElement,\r\n    attributes: Record<string, any>,\r\n  ): void {\r\n    super.initializeObject(globalId, object, element, attributes);\r\n    object.setProperty(\"mouse-x\", 0);\r\n    object.setProperty(\"mouse-y\", 0);\r\n    object.setProperty(\"mouse-pixel-x\", 0);\r\n    object.setProperty(\"mouse-pixel-y\", 0);\r\n    object.setProperty(\"is-mouse-over\", false);\r\n    object.setProperty(\"is-mouse-move\", false);\r\n    object.setProperty(\"__cursor-vars\", this.parseCursorVars(object.getProperty(\"cursor-vars\")));\r\n\r\n    const rect = element.getBoundingClientRect();\r\n    object.setProperty(\"cached-width\", rect.width || element.offsetWidth || 1);\r\n    object.setProperty(\"cached-height\", rect.height || element.offsetHeight || 1);\r\n  }\r\n\r\n  onResize(): void {\r\n    super.onResize();\r\n\r\n    this.objects.forEach((object) => {\r\n      const rect = object.htmlElement.getBoundingClientRect();\r\n      object.setProperty(\"cached-width\", rect.width || object.htmlElement.offsetWidth || 1);\r\n      object.setProperty(\"cached-height\", rect.height || object.htmlElement.offsetHeight || 1);\r\n    });\r\n  }\r\n\r\n  onMutate(data: StringData): void {\r\n    if (!this.enabled) return;\r\n\r\n    const now = performance.now();\r\n\r\n    let dt = this.lastFrameTime ? (now - this.lastFrameTime) / 1000 : 0.016;\r\n    this.lastFrameTime = now;\r\n    if (dt > 0.1) dt = 0.1;\r\n    if (dt < MIN_FRAME_DELTA) dt = MIN_FRAME_DELTA;\r\n\r\n    const cursorX = this.data.cursor.targetX;\r\n    const cursorY = this.data.cursor.targetY;\r\n\r\n    this.objects.forEach((object) => {\r\n      const isOver = object.getProperty<boolean>(\"is-mouse-over\");\r\n      const isDisabled = object.getProperty<boolean>(\"cursor-target-disable\");\r\n      const baseLerp = object.getProperty<number>(\"lerp\") ?? 0.15;\r\n\r\n      const frameLerp = this.getFrameAdjustedLerp(baseLerp, dt);\r\n\r\n      const dimensions = this.getObjectDimensions(object);\r\n      const { halfWidth, halfHeight, width, height } = dimensions;\r\n\r\n      if (isOver && !isDisabled) {\r\n        const { cx, cy } = this.centers.getCenter(object);\r\n        const elementX = cursorX - (cx - halfWidth);\r\n        const elementY = cursorY - (cy - halfHeight);\r\n\r\n        let px = object.getProperty<number>(\"mouse-pixel-x\") ?? 0;\r\n        let py = object.getProperty<number>(\"mouse-pixel-y\") ?? 0;\r\n\r\n        const dx = px - elementX;\r\n        const dy = py - elementY;\r\n        const distSquared = dx * dx + dy * dy;\r\n\r\n        if (distSquared > 0.0001) {\r\n          const isMoving = object.getProperty<boolean>(\"is-mouse-move\") ?? false;\r\n          const enterMode = object.getProperty<string>(\"cursor-enter\") ?? \"snap\";\r\n          const alignment = object.getProperty<string>(\"alignment\") ?? \"center\";\r\n          if (!isMoving) {\r\n            object.setProperty(\"is-mouse-move\", true);\r\n            if (enterMode === \"snap\") {\r\n              object.setProperty(\"mouse-pixel-x\", elementX);\r\n              object.setProperty(\"mouse-pixel-y\", elementY);\r\n              object.setProperty(\"mouse-x\", elementX);\r\n              object.setProperty(\"mouse-y\", elementY);\r\n              px = elementX;\r\n              py = elementY;\r\n            } else {\r\n              const visualX = object.getProperty<number>(\"mouse-x\") ?? 0;\r\n              const visualY = object.getProperty<number>(\"mouse-y\") ?? 0;\r\n              px = this.reverseOffset(alignment, visualX, width);\r\n              py = this.reverseOffset(alignment, visualY, height);\r\n              object.setProperty(\"mouse-pixel-x\", px);\r\n              object.setProperty(\"mouse-pixel-y\", py);\r\n            }\r\n            this.events.emit(this.getObjectEventName(object, \"cursor:start\"), null);\r\n          }\r\n\r\n          const lerpedX = this.tools.lerp.process({\r\n            from: px,\r\n            to: elementX,\r\n            progress: frameLerp,\r\n          });\r\n          const lerpedY = this.tools.lerp.process({\r\n            from: py,\r\n            to: elementY,\r\n            progress: frameLerp,\r\n          });\r\n\r\n          const updatedX = px + lerpedX;\r\n          const updatedY = py + lerpedY;\r\n          const pixelChanged =\r\n            Math.abs(updatedX - px) > CURSOR_EPSILON || Math.abs(updatedY - py) > CURSOR_EPSILON;\r\n\r\n          object.setProperty(\"mouse-pixel-x\", updatedX);\r\n          object.setProperty(\"mouse-pixel-y\", updatedY);\r\n\r\n          const offsetX = this.calculateOffset(alignment, updatedX, width);\r\n          const offsetY = this.calculateOffset(alignment, updatedY, height);\r\n\r\n          object.setProperty(\"mouse-x\", offsetX);\r\n          object.setProperty(\"mouse-y\", offsetY);\r\n\r\n          const coordsChanged = this.setMouseCoordinates(\r\n            object,\r\n            offsetX,\r\n            offsetY,\r\n            updatedX,\r\n            updatedY,\r\n          );\r\n\r\n          if (coordsChanged) {\r\n            this.events.emit(this.getObjectEventName(object, \"cursor:move\"), {\r\n              x: offsetX,\r\n              y: offsetY,\r\n            });\r\n          }\r\n          if (pixelChanged) {\r\n            this.events.emit(this.getObjectEventName(object, \"cursor:pixel\"), {\r\n              x: updatedX,\r\n              y: updatedY,\r\n            });\r\n          }\r\n        } else {\r\n          object.setProperty(\"mouse-pixel-x\", elementX);\r\n          object.setProperty(\"mouse-pixel-y\", elementY);\r\n          if (object.getProperty<boolean>(\"is-mouse-move\")) {\r\n            object.setProperty(\"is-mouse-move\", false);\r\n            this.events.emit(this.getObjectEventName(object, \"cursor:end\"), null);\r\n          }\r\n          const alignment = object.getProperty<string>(\"alignment\") ?? \"center\";\r\n          const offsetX = this.calculateOffset(alignment, elementX, width);\r\n          const offsetY = this.calculateOffset(alignment, elementY, height);\r\n          this.setMouseCoordinates(object, offsetX, offsetY, elementX, elementY);\r\n        }\r\n      } else {\r\n        const holdOnLeave = object.getProperty<boolean>(\"cursor-leave-hold\") ?? false;\r\n        if (holdOnLeave) {\r\n          if (object.getProperty<boolean>(\"is-mouse-move\")) {\r\n            object.setProperty(\"is-mouse-move\", false);\r\n            this.events.emit(this.getObjectEventName(object, \"cursor:end\"), null);\r\n          }\r\n          return;\r\n        }\r\n\r\n        const leaveMode = object.getProperty<string>(\"cursor-leave\") ?? \"smooth\";\r\n        if (leaveMode === \"snap\") {\r\n          object.setProperty(\"is-mouse-move\", false);\r\n          object.setProperty(\"mouse-x\", 0);\r\n          object.setProperty(\"mouse-y\", 0);\r\n          object.setProperty(\"mouse-pixel-x\", 0);\r\n          object.setProperty(\"mouse-pixel-y\", 0);\r\n          this.setMouseCoordinates(object, 0, 0, 0, 0);\r\n          return;\r\n        }\r\n\r\n        const mouseX = object.getProperty<number>(\"mouse-x\") ?? 0;\r\n        const mouseY = object.getProperty<number>(\"mouse-y\") ?? 0;\r\n        if (mouseX !== 0 || mouseY !== 0) {\r\n          object.setProperty(\"is-mouse-move\", false);\r\n\r\n          const targetX = this.calculateOffset(\"center\", halfWidth, width);\r\n          const targetY = this.calculateOffset(\"center\", halfHeight, height);\r\n\r\n          const newMouseX =\r\n            mouseX +\r\n            this.tools.lerp.process({\r\n              from: mouseX,\r\n              to: targetX,\r\n              progress: frameLerp,\r\n            });\r\n          const newMouseY =\r\n            mouseY +\r\n            this.tools.lerp.process({\r\n              from: mouseY,\r\n              to: targetY,\r\n              progress: frameLerp,\r\n            });\r\n\r\n          object.setProperty(\"mouse-x\", newMouseX);\r\n          object.setProperty(\"mouse-y\", newMouseY);\r\n\r\n          if (Math.abs(newMouseX) < 0.001 && Math.abs(newMouseY) < 0.001) {\r\n            object.setProperty(\"mouse-x\", 0);\r\n            object.setProperty(\"mouse-y\", 0);\r\n            object.setProperty(\"mouse-pixel-x\", 0);\r\n            object.setProperty(\"mouse-pixel-y\", 0);\r\n            this.setMouseCoordinates(object, 0, 0, 0, 0);\r\n          } else {\r\n            this.setMouseCoordinates(object, newMouseX, newMouseY);\r\n          }\r\n        }\r\n      }\r\n    });\r\n\r\n    if (this.cursorPortals.size > 0) {\r\n      const { stepX, stepY, smoothedX, smoothedY } = this.data.cursor;\r\n      const prev = this.cursorPrev;\r\n      const cursorChanged =\r\n        !Number.isFinite(prev.x) ||\r\n        Math.abs(smoothedX - prev.x) > CURSOR_EPSILON ||\r\n        Math.abs(smoothedY - prev.y) > CURSOR_EPSILON ||\r\n        Math.abs(stepX - prev.stepX) > CURSOR_EPSILON ||\r\n        Math.abs(stepY - prev.stepY) > CURSOR_EPSILON;\r\n\r\n      if (cursorChanged) {\r\n        this.events.emit(\"cursor\", {\r\n          stepX,\r\n          stepY,\r\n          x: smoothedX,\r\n          y: smoothedY,\r\n        });\r\n\r\n        this.cursorPrev = { x: smoothedX, y: smoothedY, stepX, stepY };\r\n      }\r\n\r\n      const targetX = this.data.cursor.targetX;\r\n      const targetY = this.data.cursor.targetY;\r\n\r\n      this.cursorPortals.forEach((bucket) => {\r\n        bucket.forEach((portal) => {\r\n          this.updatePortalPosition(portal, targetX, targetY, dt);\r\n        });\r\n      });\r\n    }\r\n  }\r\n\r\n  onObjectConnected(object: StringObject) {\r\n    const element = object.htmlElement;\r\n    this.centers.attach(object);\r\n\r\n    object.setProperty(\"mouseleave\", () => {\r\n      this.onMouseLeave(object);\r\n    });\r\n    object.setProperty(\"mouseenter\", () => {\r\n      this.onMouseEnter(object);\r\n    });\r\n\r\n    object.setProperty(\"onEnterEvent\", this.onEnterObject.bind(this));\r\n    object.events.on(\"enter\", object.getProperty<(object: StringObject) => void>(\"onEnterEvent\"));\r\n    object.setProperty(\"onLeaveEvent\", this.onLeaveObject.bind(this));\r\n    object.events.on(\"leave\", object.getProperty<(object: StringObject) => void>(\"onLeaveEvent\"));\r\n  }\r\n\r\n  getCursorClass(object: StringObject) {\r\n    const value = object.getProperty<string>(\"cursor-class\");\r\n    return value != null && value.length > 0 ? value : null;\r\n  }\r\n\r\n  onMouseEnter(object: StringObject) {\r\n    if (!document.contains(object.htmlElement)) {\r\n      return;\r\n    }\r\n\r\n    object.setProperty(\"is-mouse-over\", true);\r\n    this.hoveredObjects.add(object);\r\n\r\n    const cursorClass = this.getCursorClass(object);\r\n\r\n    this.withPortalsForObject(object, (portal) => {\r\n      if (cursorClass) {\r\n        portal.element.classList.add(cursorClass);\r\n      }\r\n      this.incrementPortalHover(portal);\r\n    });\r\n\r\n    object.htmlElement.addEventListener(\"mouseleave\", object.getProperty(\"mouseleave\"));\r\n  }\r\n\r\n  onMouseLeave(object: StringObject) {\r\n    object.setProperty(\"is-mouse-over\", false);\r\n    this.hoveredObjects.delete(object);\r\n\r\n    const cursorClass = this.getCursorClass(object);\r\n\r\n    this.withPortalsForObject(object, (portal) => {\r\n      if (cursorClass) {\r\n        portal.element.classList.remove(cursorClass);\r\n      }\r\n      this.decrementPortalHover(portal);\r\n    });\r\n\r\n    if (document.contains(object.htmlElement)) {\r\n      object.htmlElement.removeEventListener(\"mouseleave\", object.getProperty(\"mouseleave\"));\r\n    }\r\n  }\r\n\r\n  private onEnterObject(object: StringObject) {\r\n    object.htmlElement.addEventListener(\"mouseenter\", object.getProperty(\"mouseenter\"));\r\n  }\r\n\r\n  private onLeaveObject(object: StringObject) {\r\n    object.htmlElement.removeEventListener(\"mouseenter\", object.getProperty(\"mouseenter\"));\r\n    object.htmlElement.removeEventListener(\"mouseleave\", object.getProperty(\"mouseleave\"));\r\n  }\r\n\r\n  private safariNavigationCleanup(object: StringObject): void {\r\n    if (object.getProperty<boolean>(\"is-mouse-over\")) {\r\n      this.onMouseLeave(object);\r\n    }\r\n  }\r\n\r\n  private onElementRemovedFromDOM(object: StringObject): void {\r\n    if (object.getProperty<boolean>(\"is-mouse-over\")) {\r\n      this.onMouseLeave(object);\r\n    }\r\n  }\r\n\r\n  onObjectDisconnected(object: StringObject): void {\r\n    if (object.getProperty<boolean>(\"is-mouse-over\")) {\r\n      this.onMouseLeave(object);\r\n    }\r\n  }\r\n\r\n  onDOMRebuild(): void {\r\n    if (!this.enabled) return;\r\n    this.collectCursorPortals();\r\n  }\r\n\r\n  onDOMMutate(added: NodeList, removed: NodeList): void {\r\n    if (!this.enabled) return;\r\n    if (this.shouldRefreshPortals(added) || this.shouldRefreshPortals(removed)) {\r\n      this.collectCursorPortals();\r\n    }\r\n    if (removed.length > 0) {\r\n      this.handleRemovedNodes(removed);\r\n    }\r\n  }\r\n\r\n  private collectCursorPortals(): void {\r\n    this.cursorPortals.clear();\r\n    const nodes = document.querySelectorAll(CURSOR_PORTAL_SELECTOR);\r\n    nodes.forEach((node) => {\r\n      if (!(node instanceof HTMLElement)) return;\r\n      const id = this.resolvePortalId(node);\r\n      const customLerp = this.resolvePortalLerp(node);\r\n      const content = node.matches(CURSOR_PORTAL_CONTENT_SELECTOR)\r\n        ? node\r\n        : (node.querySelector(CURSOR_PORTAL_CONTENT_SELECTOR) as HTMLElement | null);\r\n\r\n      const targetX = this.data.cursor.targetX;\r\n      const targetY = this.data.cursor.targetY;\r\n      const portal: CursorPortal = {\r\n        id,\r\n        element: node,\r\n        content,\r\n        prev: { x: targetX, y: targetY, stepX: 0, stepY: 0 },\r\n        hoverCount: 0,\r\n        showTimer: null,\r\n        lerp: customLerp,\r\n      };\r\n\r\n      const existing = this.cursorPortals.get(id);\r\n      if (existing) {\r\n        existing.push(portal);\r\n      } else {\r\n        this.cursorPortals.set(id, [portal]);\r\n      }\r\n    });\r\n  }\r\n\r\n  private resolvePortalId(element: HTMLElement): string {\r\n    const attrSources = [\r\n      element.getAttribute(\"data-string-cursor\"),\r\n      element.getAttribute(\"string-cursor\"),\r\n      element.getAttribute(\"data-string-cursor-id\"),\r\n      element.getAttribute(\"string-cursor-id\"),\r\n    ];\r\n\r\n    for (const source of attrSources) {\r\n      if (source && source.trim().length > 0) {\r\n        return source.trim();\r\n      }\r\n    }\r\n\r\n    return DEFAULT_CURSOR_ID;\r\n  }\r\n\r\n  private resolvePortalLerp(element: HTMLElement): number | null {\r\n    const raw =\r\n      element.getAttribute(\"data-string-cursor-lerp\") ??\r\n      element.getAttribute(\"string-cursor-lerp\") ??\r\n      this.settings[\"cursor-lerp\"];\r\n    if (!raw) {\r\n      return null;\r\n    }\r\n\r\n    const value = parseFloat(raw);\r\n    if (!Number.isFinite(value)) {\r\n      return null;\r\n    }\r\n\r\n    const clamped = Math.min(1, Math.max(0.01, value));\r\n    return this.tools.adaptiveLerp.process({\r\n      value: clamped,\r\n      inMin: 0.1,\r\n      inMax: 1.0,\r\n      outMin: 0.05,\r\n      outMax: 0.65,\r\n    });\r\n  }\r\n\r\n  private shouldRefreshPortals(nodes: NodeList): boolean {\r\n    for (const node of Array.from(nodes)) {\r\n      if (!(node instanceof Element)) continue;\r\n      if (node.matches(CURSOR_PORTAL_SELECTOR)) {\r\n        return true;\r\n      }\r\n      if (node.querySelector(CURSOR_PORTAL_SELECTOR)) {\r\n        return true;\r\n      }\r\n    }\r\n    return false;\r\n  }\r\n\r\n  private withPortalsForObject(\r\n    object: StringObject | null,\r\n    cb: (portal: CursorPortal) => void,\r\n  ): void {\r\n    const portals = this.getPortalsForObject(object);\r\n    portals.forEach((portal) => cb(portal));\r\n  }\r\n\r\n  private getPortalsForObject(object: StringObject | null): CursorPortal[] {\r\n    if (this.cursorPortals.size === 0) {\r\n      return [];\r\n    }\r\n\r\n    const ids = this.extractPortalIds(object);\r\n    const selected: CursorPortal[] = [];\r\n\r\n    ids.forEach((id) => {\r\n      if (id === \"*\") {\r\n        this.cursorPortals.forEach((bucket) => {\r\n          bucket.forEach((portal) => selected.push(portal));\r\n        });\r\n        return;\r\n      }\r\n\r\n      const normalized = id.length > 0 ? id : DEFAULT_CURSOR_ID;\r\n      const portals = this.cursorPortals.get(normalized);\r\n      if (portals) {\r\n        portals.forEach((portal) => selected.push(portal));\r\n      }\r\n    });\r\n\r\n    if (selected.length === 0) {\r\n      const fallbackBucket =\r\n        this.cursorPortals.get(DEFAULT_CURSOR_ID) ?? this.cursorPortals.values().next().value;\r\n      if (fallbackBucket && fallbackBucket.length > 0) {\r\n        fallbackBucket.forEach((portal: any) => selected.push(portal));\r\n      }\r\n    }\r\n\r\n    return selected;\r\n  }\r\n\r\n  private extractPortalIds(object: StringObject | null): string[] {\r\n    if (!object) return [DEFAULT_CURSOR_ID];\r\n    const raw = object.getProperty<string>(\"cursor-target\");\r\n    if (typeof raw !== \"string\" || raw.trim().length === 0) {\r\n      return [DEFAULT_CURSOR_ID];\r\n    }\r\n\r\n    return raw\r\n      .split(/[,|]/)\r\n      .map((value) => value.trim())\r\n      .filter(Boolean);\r\n  }\r\n\r\n  private incrementPortalHover(portal: CursorPortal): void {\r\n    portal.hoverCount++;\r\n    portal.element.classList.remove(\"-show\");\r\n    this.restartPortalShowTimer(portal);\r\n  }\r\n\r\n  private decrementPortalHover(portal: CursorPortal): void {\r\n    portal.hoverCount = Math.max(0, portal.hoverCount - 1);\r\n    if (portal.hoverCount === 0) {\r\n      this.clearPortalShowTimer(portal);\r\n      portal.element.classList.remove(\"-show\");\r\n    }\r\n  }\r\n\r\n  private restartPortalShowTimer(portal: CursorPortal): void {\r\n    this.clearPortalShowTimer(portal);\r\n    if (!portal.element.isConnected) {\r\n      portal.showTimer = null;\r\n      return;\r\n    }\r\n    portal.element.classList.add(\"-show\");\r\n    portal.showTimer = null;\r\n  }\r\n\r\n  private clearPortalShowTimer(portal: CursorPortal): void {\r\n    if (portal.showTimer) {\r\n      clearTimeout(portal.showTimer);\r\n      portal.showTimer = null;\r\n    }\r\n  }\r\n\r\n  private updatePortalPosition(\r\n    portal: CursorPortal,\r\n    targetX: number,\r\n    targetY: number,\r\n    dt: number,\r\n  ): void {\r\n    if (!portal.element.isConnected) return;\r\n\r\n    const prev = portal.prev;\r\n\r\n    const currentX = Number.isFinite(prev.x) ? prev.x : targetX;\r\n    const currentY = Number.isFinite(prev.y) ? prev.y : targetY;\r\n\r\n    const factor = portal.lerp ?? 0.1;\r\n    const fpsAdjustedLerp = this.getFrameAdjustedLerp(factor, dt);\r\n\r\n    const stepX = (targetX - currentX) * fpsAdjustedLerp;\r\n    const stepY = (targetY - currentY) * fpsAdjustedLerp;\r\n\r\n    const safeDt = dt > 1e-4 ? dt : 1 / 60;\r\n    const normalizedVelocityX = stepX / (safeDt * 60);\r\n    const normalizedVelocityY = stepY / (safeDt * 60);\r\n\r\n    if (Math.abs(stepX) < CURSOR_EPSILON && Math.abs(stepY) < CURSOR_EPSILON) {\r\n      return;\r\n    }\r\n\r\n    const nextX = currentX + stepX;\r\n    const nextY = currentY + stepY;\r\n\r\n    this.writePortalVars(portal.element, {\r\n      \"--x\": roundTo(nextX, 2),\r\n      \"--y\": roundTo(nextY, 2),\r\n      \"--x-lerp\": roundTo(normalizedVelocityX, 3),\r\n      \"--y-lerp\": roundTo(normalizedVelocityY, 3),\r\n    });\r\n\r\n    prev.x = nextX;\r\n    prev.y = nextY;\r\n    prev.stepX = stepX;\r\n    prev.stepY = stepY;\r\n  }\r\n\r\n  private handleRemovedNodes(nodes: NodeList): void {\r\n    if (this.hoveredObjects.size === 0) {\r\n      return;\r\n    }\r\n    Array.from(this.hoveredObjects).forEach((object) => {\r\n      if (!object.htmlElement.isConnected) {\r\n        this.onElementRemovedFromDOM(object);\r\n      }\r\n    });\r\n  }\r\n\r\n  private cleanupHoverTargets(): void {\r\n    if (this.hoveredObjects.size === 0) {\r\n      return;\r\n    }\r\n    Array.from(this.hoveredObjects).forEach((object) => this.safariNavigationCleanup(object));\r\n  }\r\n\r\n  private bindGlobalLifecycleListeners(): void {\r\n    if (this.globalListenersBound) {\r\n      return;\r\n    }\r\n    window.addEventListener(\"beforeunload\", this.boundBeforeUnload);\r\n    window.addEventListener(\"pagehide\", this.boundPageHide);\r\n    document.addEventListener(\"visibilitychange\", this.boundVisibilityChange);\r\n    this.globalListenersBound = true;\r\n  }\r\n\r\n  private unbindGlobalLifecycleListeners(): void {\r\n    if (!this.globalListenersBound) {\r\n      return;\r\n    }\r\n    window.removeEventListener(\"beforeunload\", this.boundBeforeUnload);\r\n    window.removeEventListener(\"pagehide\", this.boundPageHide);\r\n    document.removeEventListener(\"visibilitychange\", this.boundVisibilityChange);\r\n    this.globalListenersBound = false;\r\n  }\r\n\r\n  private setMouseCoordinates(\r\n    object: StringObject,\r\n    x: number,\r\n    y: number,\r\n    pixelX?: number,\r\n    pixelY?: number,\r\n  ): boolean {\r\n    if (object.getProperty(\"cursor-target-style-disable\")) {\r\n      return false;\r\n    }\r\n\r\n    const state = getTargetState(object);\r\n    const floatNum = object.getProperty<number>(\"cursor-float\") ?? 2;\r\n    const scale = Math.pow(10, floatNum);\r\n    const roundedX =\r\n      Math.abs(x) < CURSOR_EPSILON &&\r\n      Number.isFinite(state.prevX) &&\r\n      Math.abs(state.prevX) < CURSOR_EPSILON\r\n        ? state.prevX\r\n        : Math.round(x * scale) / scale;\r\n    const roundedY =\r\n      Math.abs(y) < CURSOR_EPSILON &&\r\n      Number.isFinite(state.prevY) &&\r\n      Math.abs(state.prevY) < CURSOR_EPSILON\r\n        ? state.prevY\r\n        : Math.round(y * scale) / scale;\r\n\r\n    if (\r\n      Number.isFinite(state.prevX) &&\r\n      Math.abs(roundedX - state.prevX) <= CURSOR_EPSILON &&\r\n      Number.isFinite(state.prevY) &&\r\n      Math.abs(roundedY - state.prevY) <= CURSOR_EPSILON\r\n    ) {\r\n      return false;\r\n    }\r\n\r\n    state.prevX = roundedX;\r\n    state.prevY = roundedY;\r\n    const vars = object.getProperty<Set<string>>(\"__cursor-vars\");\r\n    const extraVars: Record<string, number> = {\r\n      \"--x\": roundTo(roundedX, floatNum),\r\n      \"--y\": roundTo(roundedY, floatNum),\r\n    };\r\n\r\n    if (vars && vars.size > 0) {\r\n      const px = Number.isFinite(pixelX)\r\n        ? (pixelX as number)\r\n        : object.getProperty<number>(\"mouse-pixel-x\");\r\n      const py = Number.isFinite(pixelY)\r\n        ? (pixelY as number)\r\n        : object.getProperty<number>(\"mouse-pixel-y\");\r\n      const prevPx = object.getProperty<number>(\"__prev-x-px\");\r\n      const prevPy = object.getProperty<number>(\"__prev-y-px\");\r\n\r\n      const dx = Number.isFinite(prevPx) ? px - prevPx : 0;\r\n      const dy = Number.isFinite(prevPy) ? py - prevPy : 0;\r\n\r\n      object.setProperty(\"__prev-x-px\", px);\r\n      object.setProperty(\"__prev-y-px\", py);\r\n\r\n      const angle = dx === 0 && dy === 0 ? 0 : Math.atan2(dy, dx);\r\n      const angleDeg = (angle * 180) / Math.PI;\r\n\r\n      if (vars.has(\"xpx\")) extraVars[\"--x-px\"] = roundTo(px, 2);\r\n      if (vars.has(\"ypx\")) extraVars[\"--y-px\"] = roundTo(py, 2);\r\n      if (vars.has(\"dx\")) extraVars[\"--dx\"] = roundTo(dx, 3);\r\n      if (vars.has(\"dy\")) extraVars[\"--dy\"] = roundTo(dy, 3);\r\n      if (vars.has(\"angle\")) extraVars[\"--angle\"] = roundTo(angle, 4);\r\n      if (vars.has(\"angle-deg\")) extraVars[\"--angle-deg\"] = roundTo(angleDeg, 2);\r\n    }\r\n\r\n    const apply = () => {\r\n      this.applyToElementAndConnects(object, (el) => {\r\n        styleTxn.setVars(el, extraVars);\r\n      });\r\n    };\r\n    if (styleTxn.isOpen) {\r\n      apply();\r\n    } else {\r\n      styleTxn.run(apply);\r\n    }\r\n\r\n    return true;\r\n  }\r\n\r\n  private writePortalVars(el: HTMLElement, vars: Record<string, number>): void {\r\n    if (styleTxn.isOpen) {\r\n      styleTxn.setVars(el, vars);\r\n      return;\r\n    }\r\n    styleTxn.run(() => {\r\n      styleTxn.setVars(el, vars);\r\n    });\r\n  }\r\n\r\n  private parseCursorVars(value: string | null | undefined): Set<string> {\r\n    if (!value) return new Set();\r\n    return new Set(\r\n      value\r\n        .split(/[|,]/)\r\n        .map((v) => v.trim().toLowerCase())\r\n        .filter((v) => v.length > 0),\r\n    );\r\n  }\r\n\r\n  private getFrameAdjustedLerp(base: number, dt: number): number {\r\n    const clampedBase = Math.min(0.99, Math.max(0.001, base));\r\n    if (!Number.isFinite(dt) || dt <= 0) {\r\n      return clampedBase;\r\n    }\r\n\r\n    const normalizedDt = Math.max(dt, MIN_FRAME_DELTA);\r\n    const frames = normalizedDt * 60;\r\n    const adjusted = 1 - Math.pow(1 - clampedBase, frames);\r\n    return Math.min(0.999, Math.max(0.0001, adjusted));\r\n  }\r\n\r\n  private getObjectDimensions(object: StringObject): CursorObjectDimensions {\r\n    const cachedWidth = object.getProperty<number>(\"cached-width\");\r\n    const cachedHeight = object.getProperty<number>(\"cached-height\");\r\n\r\n    if (\r\n      typeof cachedWidth === \"number\" &&\r\n      typeof cachedHeight === \"number\" &&\r\n      cachedWidth > 0 &&\r\n      cachedHeight > 0\r\n    ) {\r\n      const halfWidth = cachedWidth / 2;\r\n      const halfHeight = cachedHeight / 2;\r\n      return {\r\n        width: cachedWidth,\r\n        height: cachedHeight,\r\n        halfWidth,\r\n        halfHeight,\r\n      };\r\n    }\r\n\r\n    const element = object.htmlElement;\r\n    const fallbackWidth = element.offsetWidth || element.clientWidth || element.scrollWidth || 1;\r\n    const fallbackHeight =\r\n      element.offsetHeight || element.clientHeight || element.scrollHeight || 1;\r\n\r\n    const rawHalfWidth = object.getProperty<number>(\"half-width\");\r\n    const rawHalfHeight = object.getProperty<number>(\"half-height\");\r\n\r\n    const halfWidth =\r\n      typeof rawHalfWidth === \"number\" && Number.isFinite(rawHalfWidth)\r\n        ? rawHalfWidth\r\n        : fallbackWidth / 2;\r\n    const halfHeight =\r\n      typeof rawHalfHeight === \"number\" && Number.isFinite(rawHalfHeight)\r\n        ? rawHalfHeight\r\n        : fallbackHeight / 2;\r\n\r\n    const width = halfWidth > 0 ? halfWidth * 2 : fallbackWidth;\r\n    const height = halfHeight > 0 ? halfHeight * 2 : fallbackHeight;\r\n\r\n    object.setProperty(\"cached-width\", width);\r\n    object.setProperty(\"cached-height\", height);\r\n\r\n    return { width, height, halfWidth, halfHeight };\r\n  }\r\n\r\n  private calculateOffset(alignment: string, mousePos: number, size: number): number {\r\n    switch (alignment) {\r\n      case \"start\":\r\n        return mousePos / size;\r\n      case \"end\":\r\n        return (mousePos - size) / size;\r\n      case \"center\":\r\n      default:\r\n        return (mousePos - size / 2) / (size / 2);\r\n    }\r\n  }\r\n\r\n  private reverseOffset(alignment: string, offset: number, size: number): number {\r\n    switch (alignment) {\r\n      case \"start\":\r\n        return offset * size;\r\n      case \"end\":\r\n        return offset * size + size;\r\n      case \"center\":\r\n      default:\r\n        return offset * (size / 2) + size / 2;\r\n    }\r\n  }\r\n\r\n  override removeObject(id: string): void {\r\n    if (!this.enabled) return super.removeObject(id);\r\n    const obj = this.objectMapOnPage.get(id);\r\n    if (obj) {\r\n      this.centers.detach(obj);\r\n    }\r\n    super.removeObject(id);\r\n  }\r\n\r\n  override destroy(): void {\r\n    this.unbindGlobalLifecycleListeners();\r\n    this.hoveredObjects.clear();\r\n    super.destroy();\r\n  }\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringData } from \"../../core/StringData\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { styleTxn } from \"../../utils/style-txn\";\r\n\r\nexport class StringImpulse extends StringModule {\r\n  private originObservers = new WeakMap<StringObject, MutationObserver>();\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"impulse\";\r\n    this.cssProperties = [\r\n      { name: \"--push-x\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--push-y\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--push-rotation\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n    ];\r\n\r\n    this.attributesToMap.push(\r\n      { key: \"position-strength\", type: \"number\", fallback: this.settings[\"position-strength\"] },\r\n      { key: \"position-tension\", type: \"number\", fallback: this.settings[\"position-tension\"] },\r\n      { key: \"position-friction\", type: \"number\", fallback: this.settings[\"position-friction\"] },\r\n      {\r\n        key: \"position-max-velocity\",\r\n        type: \"number\",\r\n        fallback: this.settings[\"position-max-velocity\"],\r\n      },\r\n      {\r\n        key: \"position-update-threshold\",\r\n        type: \"number\",\r\n        fallback: this.settings[\"position-update-threshold\"],\r\n      },\r\n\r\n      // rotate\r\n      { key: \"rotation-strength\", type: \"number\", fallback: this.settings[\"rotation-strength\"] },\r\n      { key: \"rotation-tension\", type: \"number\", fallback: this.settings[\"rotation-tension\"] },\r\n      { key: \"rotation-friction\", type: \"number\", fallback: this.settings[\"rotation-friction\"] },\r\n      {\r\n        key: \"rotation-max-angular-velocity\",\r\n        type: \"number\",\r\n        fallback: this.settings[\"rotation-max-angular-velocity\"],\r\n      },\r\n      { key: \"rotation-max-angle\", type: \"number\", fallback: this.settings[\"rotation-max-angle\"] },\r\n      {\r\n        key: \"rotation-update-threshold\",\r\n        type: \"number\",\r\n        fallback: this.settings[\"rotation-update-threshold\"],\r\n      },\r\n\r\n      { key: \"max-offset\", type: \"number\", fallback: this.settings[\"max-offset\"] },\r\n      { key: \"sleep-epsilon\", type: \"number\", fallback: this.settings[\"sleep-epsilon\"] },\r\n      { key: \"continuous-push\", type: \"boolean\", fallback: this.settings[\"continuous-push\"] },\r\n      {\r\n        key: \"rotation-origin\",\r\n        type: \"string\",\r\n        fallback: this.settings[\"rotation-origin\"] ?? \"center center\",\r\n      }\r\n    );\r\n  }\r\n\r\n  override onObjectConnected(object: StringObject): void {\r\n    super.onObjectConnected(object);\r\n\r\n    object.setProperty(\"offset-x\", 0);\r\n    object.setProperty(\"offset-y\", 0);\r\n    object.setProperty(\"velocity-x\", 0);\r\n    object.setProperty(\"velocity-y\", 0);\r\n\r\n    object.setProperty(\"angle-deg\", 0);\r\n    object.setProperty(\"ang-vel-deg\", 0);\r\n\r\n    object.setProperty(\"__prev-css-x\", 0);\r\n    object.setProperty(\"__prev-css-y\", 0);\r\n    object.setProperty(\"__prev-css-rot\", 0);\r\n\r\n    object.setProperty(\"__push-latch\", false);\r\n    object.setProperty(\"__rotate-latch\", false);\r\n\r\n    // Cache parsed rotation origin\r\n    this.cacheRotationOrigin(object);\r\n\r\n    // Watch for rotation-origin attribute changes\r\n    this.observeRotationOrigin(object);\r\n\r\n    this.hover.track(object);\r\n    this.centers.attach(object);\r\n  }\r\n\r\n  override onObjectDisconnected(object: StringObject): void {\r\n    this.hover.untrack(object);\r\n    this.centers.detach(object);\r\n\r\n    // Cleanup rotation-origin observer\r\n    const observer = this.originObservers.get(object);\r\n    if (observer) {\r\n      observer.disconnect();\r\n      this.originObservers.delete(object);\r\n    }\r\n  }\r\n\r\n  override onMouseMove(_e?: MouseEvent): void {\r\n    if (!_e) return;\r\n\r\n    const cursorVelocityX = this.data.cursor.velocityX;\r\n    const cursorVelocityY = this.data.cursor.velocityY;\r\n    if (cursorVelocityX === 0 && cursorVelocityY === 0) return;\r\n\r\n    const mouseX = this.data.cursor.targetX;\r\n    const mouseY = this.data.cursor.targetY;\r\n\r\n    for (const object of this.objects) {\r\n      const rect = object.htmlElement.getBoundingClientRect();\r\n      const isUnderCursor =\r\n        mouseX >= rect.left && mouseX <= rect.right && mouseY >= rect.top && mouseY <= rect.bottom;\r\n\r\n      if (isUnderCursor) {\r\n        {\r\n          const w = rect.width || 1;\r\n          const side01 = Math.max(0, Math.min(1, (this.data.cursor.targetX - rect.left) / w));\r\n          this.events.emit(this.getObjectEventName(object, \"object:impulse\", \"side\"), {\r\n            value: side01\r\n          });\r\n        }\r\n\r\n        const positionStrength = object.getProperty<number>(\"position-strength\") || 0;\r\n        if (positionStrength !== 0) {\r\n          const isContinuousPush = object.getProperty<boolean>(\"continuous-push\") ?? true;\r\n          const isLatched = object.getProperty<boolean>(\"__push-latch\") === true;\r\n          if (isContinuousPush || !isLatched) {\r\n            let objectVelocityX = object.getProperty<number>(\"velocity-x\") || 0;\r\n            let objectVelocityY = object.getProperty<number>(\"velocity-y\") || 0;\r\n            objectVelocityX += cursorVelocityX * positionStrength;\r\n            objectVelocityY += cursorVelocityY * positionStrength;\r\n            object.setProperty(\"velocity-x\", objectVelocityX);\r\n            object.setProperty(\"velocity-y\", objectVelocityY);\r\n            if (!isContinuousPush) object.setProperty(\"__push-latch\", true);\r\n          }\r\n        }\r\n\r\n        const rotationStrength = object.getProperty<number>(\"rotation-strength\") ?? 0.75;\r\n        if (rotationStrength !== 0) {\r\n          const isContinuousPush = object.getProperty<boolean>(\"continuous-push\") ?? true;\r\n          const isLatched = object.getProperty<boolean>(\"__rotate-latch\") === true;\r\n\r\n          if (isContinuousPush || !isLatched) {\r\n            const { centerX, centerY } = this.getRotationOriginFromRect(object, rect);\r\n            const relativeX = mouseX - centerX;\r\n            const relativeY = mouseY - centerY;\r\n            const torque = relativeX * cursorVelocityY - relativeY * cursorVelocityX;\r\n\r\n            let angularVelocityDeg = object.getProperty<number>(\"ang-vel-deg\") || 0;\r\n            angularVelocityDeg += torque * rotationStrength * 0.02;\r\n            object.setProperty(\"ang-vel-deg\", angularVelocityDeg);\r\n            if (!isContinuousPush) object.setProperty(\"__rotate-latch\", true);\r\n          }\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Parses and caches the rotation origin for an object.\r\n   * Called once on object connection and when attribute changes.\r\n   */\r\n  private cacheRotationOrigin(object: StringObject): void {\r\n    const originValue = object.getProperty<string>(\"rotation-origin\") ?? \"center center\";\r\n    const { x, y } = this.tools.originParser.toNormalized({ value: originValue });\r\n    object.setProperty(\"__rotation-origin-x\", x);\r\n    object.setProperty(\"__rotation-origin-y\", y);\r\n  }\r\n\r\n  /**\r\n   * Observes changes to the rotation-origin attribute and re-caches when changed.\r\n   */\r\n  private observeRotationOrigin(object: StringObject): void {\r\n    const attrName = \"string-rotation-origin\";\r\n    const dataAttrName = \"data-string-rotation-origin\";\r\n\r\n    const observer = new MutationObserver((mutations) => {\r\n      for (const mutation of mutations) {\r\n        if (\r\n          mutation.type === \"attributes\" &&\r\n          (mutation.attributeName === attrName || mutation.attributeName === dataAttrName)\r\n        ) {\r\n          // Re-read attribute and update cache\r\n          const newValue =\r\n            object.htmlElement.getAttribute(attrName) ??\r\n            object.htmlElement.getAttribute(dataAttrName);\r\n          if (newValue !== null) {\r\n            object.setProperty(\"rotation-origin\", newValue);\r\n          }\r\n          this.cacheRotationOrigin(object);\r\n          break;\r\n        }\r\n      }\r\n    });\r\n\r\n    observer.observe(object.htmlElement, {\r\n      attributes: true,\r\n      attributeFilter: [attrName, dataAttrName],\r\n    });\r\n\r\n    this.originObservers.set(object, observer);\r\n  }\r\n\r\n  /**\r\n   * Calculates the rotation origin point using cached normalized values and provided rect.\r\n   * Avoids re-parsing origin string and extra getBoundingClientRect calls.\r\n   */\r\n  private getRotationOriginFromRect(\r\n    object: StringObject,\r\n    rect: DOMRect\r\n  ): { centerX: number; centerY: number } {\r\n    const normalizedX = object.getProperty<number>(\"__rotation-origin-x\") ?? 0.5;\r\n    const normalizedY = object.getProperty<number>(\"__rotation-origin-y\") ?? 0.5;\r\n\r\n    return {\r\n      centerX: rect.left + rect.width * normalizedX,\r\n      centerY: rect.top + rect.height * normalizedY,\r\n    };\r\n  }\r\n\r\n  onFrame(_: StringData): void {\r\n    const mouseX = this.data.cursor.targetX;\r\n    const mouseY = this.data.cursor.targetY;\r\n\r\n    for (const objectItem of this.objects) {\r\n      const rect = objectItem.htmlElement.getBoundingClientRect();\r\n      const isUnderCursor =\r\n        mouseX >= rect.left && mouseX <= rect.right && mouseY >= rect.top && mouseY <= rect.bottom;\r\n\r\n      if (!isUnderCursor && objectItem.getProperty<boolean>(\"__push-latch\") === true) {\r\n        objectItem.setProperty(\"__push-latch\", false);\r\n      }\r\n      if (!isUnderCursor && objectItem.getProperty<boolean>(\"__rotate-latch\") === true) {\r\n        objectItem.setProperty(\"__rotate-latch\", false);\r\n      }\r\n    }\r\n\r\n    for (let i = 0; i < this.objects.length; i++) {\r\n      const object = this.objects[i];\r\n\r\n      let offsetX = object.getProperty<number>(\"offset-x\") || 0;\r\n      let offsetY = object.getProperty<number>(\"offset-y\") || 0;\r\n      let velocityX = object.getProperty<number>(\"velocity-x\") || 0;\r\n      let velocityY = object.getProperty<number>(\"velocity-y\") || 0;\r\n\r\n      const positionTension = object.getProperty<number>(\"position-tension\") ?? 0.05;\r\n      const positionFriction = object.getProperty<number>(\"position-friction\") ?? 0.15;\r\n      const maxVelocity = object.getProperty<number>(\"position-max-velocity\") ?? 120;\r\n      const maxOffset = object.getProperty<number>(\"max-offset\") ?? 220;\r\n\r\n      velocityX -= positionTension * offsetX;\r\n      velocityY -= positionTension * offsetY;\r\n\r\n      const velocityDecay = 1 - positionFriction;\r\n      velocityX *= velocityDecay;\r\n      velocityY *= velocityDecay;\r\n\r\n      if (velocityX > maxVelocity) velocityX = maxVelocity;\r\n      else if (velocityX < -maxVelocity) velocityX = -maxVelocity;\r\n      if (velocityY > maxVelocity) velocityY = maxVelocity;\r\n      else if (velocityY < -maxVelocity) velocityY = -maxVelocity;\r\n\r\n      offsetX += velocityX;\r\n      offsetY += velocityY;\r\n\r\n      if (offsetX > maxOffset) offsetX = maxOffset;\r\n      else if (offsetX < -maxOffset) offsetX = -maxOffset;\r\n      if (offsetY > maxOffset) offsetY = maxOffset;\r\n      else if (offsetY < -maxOffset) offsetY = -maxOffset;\r\n\r\n      let angleDeg = object.getProperty<number>(\"angle-deg\") || 0;\r\n      let angularVelocityDeg = object.getProperty<number>(\"ang-vel-deg\") || 0;\r\n\r\n      const rotationTension = object.getProperty<number>(\"rotation-tension\") ?? 0.06;\r\n      const rotationFriction = object.getProperty<number>(\"rotation-friction\") ?? 0.18;\r\n      const maxAngularVelocityDeg =\r\n        object.getProperty<number>(\"rotation-max-angular-velocity\") ?? 6;\r\n      const maxRotationAngleDeg = object.getProperty<number>(\"rotation-max-angle\") ?? 18;\r\n\r\n      angularVelocityDeg -= rotationTension * angleDeg;\r\n      angularVelocityDeg *= 1 - rotationFriction;\r\n\r\n      if (angularVelocityDeg > maxAngularVelocityDeg) angularVelocityDeg = maxAngularVelocityDeg;\r\n      else if (angularVelocityDeg < -maxAngularVelocityDeg)\r\n        angularVelocityDeg = -maxAngularVelocityDeg;\r\n\r\n      angleDeg += angularVelocityDeg;\r\n\r\n      if (angleDeg > maxRotationAngleDeg) {\r\n        angleDeg = maxRotationAngleDeg;\r\n        angularVelocityDeg *= 0.35;\r\n      } else if (angleDeg < -maxRotationAngleDeg) {\r\n        angleDeg = -maxRotationAngleDeg;\r\n        angularVelocityDeg *= 0.35;\r\n      }\r\n\r\n      const sleepEpsilon = object.getProperty<number>(\"sleep-epsilon\") ?? 0.01;\r\n      const isPositionAsleep =\r\n        velocityX * velocityX + velocityY * velocityY < sleepEpsilon * sleepEpsilon &&\r\n        offsetX * offsetX + offsetY * offsetY < sleepEpsilon * sleepEpsilon;\r\n\r\n      const isRotationAsleep =\r\n        Math.abs(angularVelocityDeg) < sleepEpsilon && Math.abs(angleDeg) < sleepEpsilon;\r\n\r\n      if (isPositionAsleep) {\r\n        if (velocityX || velocityY || offsetX || offsetY) {\r\n          object.setProperty(\"offset-x\", 0);\r\n          object.setProperty(\"offset-y\", 0);\r\n          object.setProperty(\"velocity-x\", 0);\r\n          object.setProperty(\"velocity-y\", 0);\r\n          offsetX = offsetY = velocityX = velocityY = 0;\r\n        }\r\n      } else {\r\n        object.setProperty(\"offset-x\", offsetX);\r\n        object.setProperty(\"offset-y\", offsetY);\r\n        object.setProperty(\"velocity-x\", velocityX);\r\n        object.setProperty(\"velocity-y\", velocityY);\r\n      }\r\n\r\n      if (isRotationAsleep) {\r\n        if (angleDeg || angularVelocityDeg) {\r\n          object.setProperty(\"angle-deg\", 0);\r\n          object.setProperty(\"ang-vel-deg\", 0);\r\n          angleDeg = angularVelocityDeg = 0;\r\n        }\r\n      } else {\r\n        object.setProperty(\"angle-deg\", angleDeg);\r\n        object.setProperty(\"ang-vel-deg\", angularVelocityDeg);\r\n      }\r\n\r\n      const positionUpdateThreshold =\r\n        object.getProperty<number>(\"position-update-threshold\") ?? 0.1;\r\n      const rotationUpdateThreshold =\r\n        object.getProperty<number>(\"rotation-update-threshold\") ?? 0.15;\r\n\r\n      const prevCssX = object.getProperty<number>(\"__prev-css-x\") || 0;\r\n      const prevCssY = object.getProperty<number>(\"__prev-css-y\") || 0;\r\n      const prevCssRot = object.getProperty<number>(\"__prev-css-rot\") || 0;\r\n\r\n      const cssTranslateX = Math.round(offsetX * 10) / 10;\r\n      const cssTranslateY = Math.round(offsetY * 10) / 10;\r\n      const cssRotateDeg = Math.round(angleDeg * 10) / 10;\r\n\r\n      const needsPositionUpdate =\r\n        Math.abs(cssTranslateX - prevCssX) > positionUpdateThreshold ||\r\n        Math.abs(cssTranslateY - prevCssY) > positionUpdateThreshold;\r\n\r\n      const needsRotationUpdate = Math.abs(cssRotateDeg - prevCssRot) > rotationUpdateThreshold;\r\n\r\n      if (needsPositionUpdate || needsRotationUpdate) {\r\n        object.setProperty(\"__next-css-x\", cssTranslateX);\r\n        object.setProperty(\"__next-css-y\", cssTranslateY);\r\n        object.setProperty(\"__next-css-rot\", cssRotateDeg);\r\n      }\r\n\r\n      object.setProperty(\"__needs-position-update\", needsPositionUpdate);\r\n      object.setProperty(\"__needs-rotation-update\", needsRotationUpdate);\r\n    }\r\n  }\r\n\r\n  override onMutate(): void {\r\n    for (let i = 0; i < this.objects.length; i++) {\r\n      const object = this.objects[i];\r\n      const needsPositionUpdate = object.getProperty<boolean>(\"__needs-position-update\") === true;\r\n      const needsRotationUpdate = object.getProperty<boolean>(\"__needs-rotation-update\") === true;\r\n\r\n      if (!needsPositionUpdate && !needsRotationUpdate) {\r\n        continue;\r\n      }\r\n\r\n      const cssTranslateX = object.getProperty<number>(\"__next-css-x\") || 0;\r\n      const cssTranslateY = object.getProperty<number>(\"__next-css-y\") || 0;\r\n      const cssRotateDeg = object.getProperty<number>(\"__next-css-rot\") || 0;\r\n\r\n      this.applyToElementAndConnects(object, (el) => {\r\n        if (needsPositionUpdate) {\r\n          styleTxn.setVar(el, \"--push-x\", cssTranslateX);\r\n          styleTxn.setVar(el, \"--push-y\", cssTranslateY);\r\n        }\r\n        if (needsRotationUpdate) {\r\n          styleTxn.setVar(el, \"--push-rotation\", cssRotateDeg);\r\n        }\r\n      });\r\n\r\n      if (needsPositionUpdate) {\r\n        object.setProperty(\"__prev-css-x\", cssTranslateX);\r\n        object.setProperty(\"__prev-css-y\", cssTranslateY);\r\n        this.events.emit(this.getObjectEventName(object, \"object:impulse\", \"move\"), {\r\n          x: cssTranslateX,\r\n          y: cssTranslateY,\r\n        });\r\n      }\r\n      if (needsRotationUpdate) {\r\n        object.setProperty(\"__prev-css-rot\", cssRotateDeg);\r\n        this.events.emit(this.getObjectEventName(object, \"object:impulse\", \"rotate\"), {\r\n          rotation: cssRotateDeg\r\n        });\r\n      }\r\n\r\n      object.setProperty(\"__needs-position-update\", false);\r\n      object.setProperty(\"__needs-rotation-update\", false);\r\n    }\r\n  }\r\n}\r\n","type Job = () => void;\r\n\r\nclass FrameDOM {\r\n  private measureQueue: Job[] = [];\r\n  private mutateQueue: Job[] = [];\r\n  private scheduled = false;\r\n\r\n  public measure(fn: Job): void {\r\n    this.measureQueue.push(fn);\r\n    this.schedule();\r\n  }\r\n\r\n  public mutate(fn: Job): void {\r\n    this.mutateQueue.push(fn);\r\n    this.schedule();\r\n  }\r\n\r\n  public schedule(): void {\r\n    if (!this.scheduled) {\r\n      this.scheduled = true;\r\n    }\r\n  }\r\n\r\n  public flush(): void {\r\n    if (!this.scheduled) return;\r\n\r\n    const mQueue = this.measureQueue;\r\n    this.measureQueue = [];\r\n    for (let i = 0; i < mQueue.length; i++) {\r\n      try {\r\n        mQueue[i]();\r\n      } catch (e) {\r\n        console.error(\"Error in frameDOM measure task:\", e);\r\n      }\r\n    }\r\n\r\n    const wQueue = this.mutateQueue;\r\n    this.mutateQueue = [];\r\n    for (let i = 0; i < wQueue.length; i++) {\r\n      try {\r\n        wQueue[i]();\r\n      } catch (e) {\r\n        console.error(\"Error in frameDOM mutate task:\", e);\r\n      }\r\n    }\r\n\r\n    this.scheduled = false;\r\n  }\r\n}\r\n\r\nexport const frameDOM = new FrameDOM();\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { StringData } from \"../../core/StringData\";\r\nimport { frameDOM } from \"../../utils/frame-dom\";\r\nimport { styleTxn } from \"../../utils/style-txn\";\r\nimport { EasingFunctionOutput } from \"../../tools/EasingFunctionTool\";\r\n\r\nconst RESIZE_DEBOUNCE_MS = 20;\r\nconst CONSTANTS = {\r\n  MANUAL_COLS_KEY: \"masonry-manual-cols\",\r\n  MANUAL_GAP_KEY: \"masonry-manual-gap\",\r\n  DEFAULT_DURATION: 600,\r\n  DEFAULT_EASING: \"cubic-bezier(0.25, 1, 0.5, 1)\",\r\n} as const;\r\n\r\ninterface MasonryItemState {\r\n  sx: number;\r\n  sy: number;\r\n  sw: number;\r\n\r\n  tx: number;\r\n  ty: number;\r\n  tw: number;\r\n\r\n  cx: number;\r\n  cy: number;\r\n  cw: number;\r\n\r\n  dx: number;\r\n  dy: number;\r\n  dw: number;\r\n\r\n  startTime: number;\r\n\r\n  posEase: EasingFunctionOutput;\r\n  invPosDur: number;\r\n\r\n  sizeEase: EasingFunctionOutput;\r\n  invSizeDur: number;\r\n\r\n  isMoving: boolean;\r\n}\r\n\r\ninterface MasonryState {\r\n  ro: ResizeObserver;\r\n  mo: MutationObserver;\r\n  resizeDebounceId?: number;\r\n  isResizing: boolean;\r\n\r\n  lastObservedWidth: number;\r\n  lastObservedHeight: number;\r\n  lastLayoutColumns: number;\r\n  lastLayoutGap: number;\r\n  lastLayoutColumnWidth: number;\r\n  lastChildrenHash: number;\r\n  lastHeightsHash: number;\r\n\r\n  childIds: WeakMap<HTMLElement, number>;\r\n  nextChildId: number;\r\n\r\n  imgUnsubs: WeakMap<HTMLElement, () => void>;\r\n  items: Map<HTMLElement, MasonryItemState>;\r\n\r\n  startHeight: number;\r\n  targetHeight: number;\r\n  heightStartTime: number;\r\n  heightDuration: number;\r\n  heightEase: EasingFunctionOutput;\r\n  isAnimatingHeight: boolean;\r\n\r\n  isAnimating: boolean;\r\n  layoutScheduled: boolean;\r\n\r\n  pendingHeight?: number;\r\n  pendingHeightAnimate: boolean;\r\n\r\n  expectedEndTime: number;\r\n  endTimerId?: number;\r\n}\r\n\r\ninterface ResponsiveValue<T> {\r\n  breakpoint: number;\r\n  value: T;\r\n}\r\n\r\ninterface GridSettings {\r\n  columns: number;\r\n  gap: number;\r\n}\r\n\r\nfunction parseTime(val: string | null): number {\r\n  if (!val) return CONSTANTS.DEFAULT_DURATION;\r\n  const n = parseFloat(val);\r\n  return isNaN(n) ? CONSTANTS.DEFAULT_DURATION : n;\r\n}\r\n\r\nfunction getResponsiveValue<T>(data: Array<ResponsiveValue<T>>, windowWidth: number): T {\r\n  const sorted = [...data].sort((a, b) => b.breakpoint - a.breakpoint);\r\n  const matched = sorted.find((e) => windowWidth >= e.breakpoint);\r\n  return matched ? matched.value : sorted[sorted.length - 1]?.value;\r\n}\r\n\r\nexport class StringMasonry extends StringModule {\r\n  private states = new WeakMap<StringObject, MasonryState>();\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"masonry\";\r\n    this.attributesToMap.push(\r\n      { key: \"masonry-cols\", type: \"breakpoint-dimension\", fallback: \"2|640:3|1024:4\" },\r\n      { key: \"masonry-gap\", type: \"breakpoint-dimension\", fallback: \"16|640:24|1024:32\" },\r\n      { key: \"masonry-mode\", type: \"string\", fallback: \"auto\" },\r\n    );\r\n  }\r\n\r\n  private parseEasing(val: string | null): EasingFunctionOutput {\r\n    return this.tools.easingFunction.process({ easing: val || CONSTANTS.DEFAULT_EASING });\r\n  }\r\n\r\n  override onObjectConnected(object: StringObject): void {\r\n    super.onObjectConnected(object);\r\n    const el = object.htmlElement as HTMLElement;\r\n\r\n    styleTxn.begin();\r\n    styleTxn.setProps(el, {\r\n      position: \"relative\",\r\n      boxSizing: \"border-box\",\r\n    });\r\n    styleTxn.commit();\r\n\r\n    const state = this.createState(object, el);\r\n    this.states.set(object, state);\r\n\r\n    this.attachImgLoaders(object, state, el);\r\n    this.scheduleLayout(object, false, \"init\");\r\n\r\n    const id = object.id;\r\n    this.events.on(\r\n      `masonry:update:${id}`,\r\n      (data: { mode?: string; cols?: number; gap?: number }) => {\r\n        if (data.mode) object.setProperty(\"masonry-mode\", data.mode);\r\n        if (data.cols !== undefined)\r\n          object.setProperty(CONSTANTS.MANUAL_COLS_KEY, Number(data.cols));\r\n        if (data.gap !== undefined) object.setProperty(CONSTANTS.MANUAL_GAP_KEY, Number(data.gap));\r\n        this.scheduleLayout(object, true, \"external-event\");\r\n      },\r\n    );\r\n  }\r\n\r\n  override onFrame(data: StringData): void {\r\n    const timeNow = data.time.now;\r\n\r\n    this.objectsOnPage.forEach((object) => {\r\n      const state = this.states.get(object);\r\n      if (!state || !state.isAnimating) return;\r\n\r\n      let activeAnimations = 0;\r\n\r\n      styleTxn.run(() => {\r\n        if (state.isAnimatingHeight) {\r\n          const elapsed = timeNow - state.heightStartTime;\r\n          const progress = Math.min(1, elapsed / state.heightDuration);\r\n          const ease = state.heightEase(progress);\r\n          const currentH = state.startHeight + (state.targetHeight - state.startHeight) * ease;\r\n\r\n          styleTxn.setProps(object.htmlElement, { height: `${currentH}px` });\r\n\r\n          if (progress < 1) activeAnimations++;\r\n          else state.isAnimatingHeight = false;\r\n        }\r\n\r\n        state.items.forEach((item, el) => {\r\n          if (!item.isMoving) return;\r\n\r\n          const elapsed = timeNow - item.startTime;\r\n\r\n          const pProgressRaw = elapsed * item.invPosDur;\r\n          const pProgress = pProgressRaw > 1 ? 1 : pProgressRaw;\r\n          const pEaseVal = item.posEase(pProgress);\r\n          item.cx = item.sx + item.dx * pEaseVal;\r\n          item.cy = item.sy + item.dy * pEaseVal;\r\n\r\n          const sProgressRaw = elapsed * item.invSizeDur;\r\n          const sProgress = sProgressRaw > 1 ? 1 : sProgressRaw;\r\n          const sEaseVal = item.sizeEase(sProgress);\r\n          item.cw = item.sw + item.dw * sEaseVal;\r\n\r\n          styleTxn.setProps(el, {\r\n            transform: `translate3d(${item.cx}px, ${item.cy}px, 0)`,\r\n            ...(Math.abs(item.dw) > 0.05 ? { width: `${item.cw}px` } : {}),\r\n            willChange: \"transform, width\",\r\n          });\r\n\r\n          if (pProgress < 1 || sProgress < 1) {\r\n            activeAnimations++;\r\n          } else {\r\n            item.isMoving = false;\r\n            styleTxn.setProps(el, {\r\n              transform: `translate3d(${item.tx}px, ${item.ty}px, 0)`,\r\n              width: `${item.tw}px`,\r\n              willChange: \"auto\",\r\n            });\r\n            item.cx = item.tx;\r\n            item.cy = item.ty;\r\n            item.cw = item.tw;\r\n          }\r\n        });\r\n      });\r\n\r\n      if (activeAnimations === 0) {\r\n        this.handleAnimationEnd(object, state, timeNow);\r\n      }\r\n    });\r\n  }\r\n\r\n  override onResize(): void {\r\n    if (this.data.system.suppressMasonryResize) return;\r\n    this.objectsOnPage.forEach((o) => {\r\n      if (this.states.has(o)) this.scheduleLayout(o, true, \"window-resize\");\r\n    });\r\n  }\r\n\r\n  cleanupObject(object: StringObject): void {\r\n    const state = this.states.get(object);\r\n    if (!state) return;\r\n    state.ro.disconnect();\r\n    state.mo.disconnect();\r\n    if (state.resizeDebounceId) clearTimeout(state.resizeDebounceId);\r\n    this.states.delete(object);\r\n  }\r\n\r\n  private createState(object: StringObject, el: HTMLElement): MasonryState {\r\n    const initialRect = el.getBoundingClientRect();\r\n\r\n    const roCallback: ResizeObserverCallback = (entries) => {\r\n      if (!entries.length) return;\r\n      const rect = entries[0].contentRect;\r\n      const state = this.states.get(object);\r\n      if (!state) return;\r\n\r\n      if (\r\n        Math.abs(rect.width - state.lastObservedWidth) <= 0.5 &&\r\n        Math.abs(rect.height - state.lastObservedHeight) <= 0.5\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      state.lastObservedWidth = rect.width;\r\n      state.lastObservedHeight = rect.height;\r\n\r\n      const containerStyle = getComputedStyle(el);\r\n      const padL = parseFloat(containerStyle.paddingLeft) || 0;\r\n      const padR = parseFloat(containerStyle.paddingRight) || 0;\r\n      const contentWidth = rect.width - padL - padR;\r\n      if (contentWidth <= 0) return;\r\n\r\n      const { columns, gap } = this.getGridSettings(object);\r\n      const columnWidth = (contentWidth - gap * (columns - 1)) / columns;\r\n\r\n      const layoutUnchanged =\r\n        columns === state.lastLayoutColumns &&\r\n        gap === state.lastLayoutGap &&\r\n        Math.abs(columnWidth - state.lastLayoutColumnWidth) <= 0.5;\r\n\r\n      if (layoutUnchanged) return;\r\n\r\n      if (state.resizeDebounceId) window.clearTimeout(state.resizeDebounceId);\r\n      state.resizeDebounceId = window.setTimeout(() => {\r\n        state.isResizing = true;\r\n        this.scheduleLayout(object, true, \"resize-observer\");\r\n        state.isResizing = false;\r\n      }, RESIZE_DEBOUNCE_MS);\r\n    };\r\n\r\n    const moCallback: MutationCallback = (muts) => {\r\n      const state = this.states.get(object);\r\n      if (!state) return;\r\n      let needsLayout = false;\r\n\r\n      for (const m of muts) {\r\n        if (m.removedNodes.length) {\r\n          m.removedNodes.forEach((n) => {\r\n            if (n.nodeType === 1) {\r\n              const htmlEl = n as HTMLElement;\r\n              this.cleanupImgListeners(state, htmlEl);\r\n              state.items.delete(htmlEl);\r\n              needsLayout = true;\r\n            }\r\n          });\r\n        }\r\n        if (m.addedNodes.length) {\r\n          m.addedNodes.forEach((n) => {\r\n            if (n.nodeType === 1) {\r\n              this.attachImgLoaders(object, state, n as HTMLElement);\r\n              needsLayout = true;\r\n            }\r\n          });\r\n        }\r\n      }\r\n      if (needsLayout) this.scheduleLayout(object, true, \"mutation-observer\");\r\n    };\r\n\r\n    const state: MasonryState = {\r\n      ro: new ResizeObserver(roCallback),\r\n      mo: new MutationObserver(moCallback),\r\n      isResizing: false,\r\n      lastObservedWidth: initialRect.width,\r\n      lastObservedHeight: initialRect.height,\r\n      lastLayoutColumns: 0,\r\n      lastLayoutGap: 0,\r\n      lastLayoutColumnWidth: -1,\r\n      lastChildrenHash: 0,\r\n      lastHeightsHash: 0,\r\n      childIds: new WeakMap(),\r\n      nextChildId: 1,\r\n      imgUnsubs: new WeakMap(),\r\n      layoutScheduled: false,\r\n      items: new Map(),\r\n      startHeight: el.offsetHeight,\r\n      targetHeight: el.offsetHeight,\r\n      heightStartTime: 0,\r\n      heightDuration: CONSTANTS.DEFAULT_DURATION,\r\n      heightEase: this.parseEasing(null),\r\n      isAnimatingHeight: false,\r\n      isAnimating: false,\r\n      pendingHeight: undefined,\r\n      pendingHeightAnimate: false,\r\n      expectedEndTime: 0,\r\n    };\r\n\r\n    state.ro.observe(el);\r\n    state.mo.observe(el, { childList: true });\r\n\r\n    return state;\r\n  }\r\n\r\n  private handleAnimationEnd(object: StringObject, state: MasonryState, timeNow: number) {\r\n    if (state.pendingHeight !== undefined) {\r\n      const height = state.pendingHeight;\r\n      const animateHeight = state.pendingHeightAnimate;\r\n      state.pendingHeight = undefined;\r\n      state.pendingHeightAnimate = false;\r\n\r\n      if (animateHeight) {\r\n        state.startHeight = object.htmlElement.offsetHeight;\r\n        state.targetHeight = height;\r\n        state.heightStartTime = timeNow;\r\n        state.heightDuration = CONSTANTS.DEFAULT_DURATION;\r\n        state.heightEase = this.parseEasing(null);\r\n        state.isAnimatingHeight = true;\r\n        state.isAnimating = true;\r\n        return;\r\n      }\r\n      styleTxn.run(() => {\r\n        styleTxn.setProps(object.htmlElement, { height: `${height}px` });\r\n      });\r\n    }\r\n\r\n    if (state.isAnimating) {\r\n      this.events.emit(\"masonry:shuffle:end\", { object });\r\n    }\r\n    state.isAnimating = false;\r\n\r\n    this.objectManager.refreshLayoutForRoot(object.htmlElement);\r\n\r\n    if (state.endTimerId) {\r\n      window.clearTimeout(state.endTimerId);\r\n      state.endTimerId = undefined;\r\n    }\r\n    requestAnimationFrame(() => {\r\n      this.events.emit(\"resize\", true);\r\n    });\r\n  }\r\n\r\n  private scheduleLayout(object: StringObject, animate: boolean, reason: string): void {\r\n    const state = this.states.get(object);\r\n    if (!state || state.layoutScheduled) return;\r\n\r\n    state.layoutScheduled = true;\r\n\r\n    frameDOM.measure(() => {\r\n      state.layoutScheduled = false;\r\n      this.performSyncLayout(object, state, animate, reason);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Performs the layout calculation and application synchronously.\r\n   * Optimizes for batched DOM reads and writes via `styleTxn`.\r\n   */\r\n  private performSyncLayout(\r\n    object: StringObject,\r\n    state: MasonryState,\r\n    animate: boolean,\r\n    reason: string,\r\n  ): void {\r\n    const container = object.htmlElement as HTMLElement;\r\n    const children = Array.from(container.children) as HTMLElement[];\r\n    if (children.length === 0) return;\r\n\r\n    const containerRect = container.getBoundingClientRect();\r\n    const containerStyle = getComputedStyle(container);\r\n    const padL = parseFloat(containerStyle.paddingLeft) || 0;\r\n    const padR = parseFloat(containerStyle.paddingRight) || 0;\r\n    const padT = parseFloat(containerStyle.paddingTop) || 0;\r\n    const contentWidth = containerRect.width - padL - padR;\r\n\r\n    if (contentWidth <= 0) return;\r\n\r\n    const { columns, gap } = this.getGridSettings(object);\r\n    const columnWidth = (contentWidth - gap * (columns - 1)) / columns;\r\n    const mode = object.getProperty<string>(\"masonry-mode\") || \"auto\";\r\n    const allowHeightAnim =\r\n      mode === \"auto\" &&\r\n      animate &&\r\n      !state.isResizing &&\r\n      reason !== \"window-resize\" &&\r\n      reason !== \"resize-observer\";\r\n\r\n    const layoutParamsSame =\r\n      columns === state.lastLayoutColumns &&\r\n      gap === state.lastLayoutGap &&\r\n      Math.abs(columnWidth - state.lastLayoutColumnWidth) <= 0.5;\r\n\r\n    let childrenHash = 0;\r\n    children.forEach((item) => {\r\n      let id = state.childIds.get(item);\r\n      if (!id) {\r\n        id = state.nextChildId++;\r\n        state.childIds.set(item, id);\r\n      }\r\n      childrenHash = (childrenHash * 31 + id) >>> 0;\r\n    });\r\n\r\n    state.lastLayoutColumns = columns;\r\n    state.lastLayoutGap = gap;\r\n    state.lastLayoutColumnWidth = columnWidth;\r\n    state.lastChildrenHash = childrenHash;\r\n\r\n    const prevWidths = new Map<HTMLElement, number>();\r\n    if (animate) {\r\n      children.forEach((item) => {\r\n        const s = state.items.get(item);\r\n        if (s) prevWidths.set(item, s.cw);\r\n      });\r\n    }\r\n\r\n    styleTxn.begin();\r\n    children.forEach((item) => {\r\n      styleTxn.setProps(item, {\r\n        position: \"absolute\",\r\n        top: \"0\",\r\n        left: \"0\",\r\n        width: `${columnWidth}px`,\r\n      });\r\n    });\r\n    styleTxn.commit();\r\n\r\n    const itemHeights = children.map((item) => item.offsetHeight);\r\n    let heightsHash = 0;\r\n    itemHeights.forEach((h) => (heightsHash = (heightsHash * 31 + Math.round(h * 2)) >>> 0));\r\n\r\n    state.lastHeightsHash = heightsHash;\r\n\r\n    if (animate && prevWidths.size > 0) {\r\n      styleTxn.run(() => {\r\n        prevWidths.forEach((width, item) => {\r\n          styleTxn.setProps(item, { width: `${width}px` });\r\n        });\r\n      });\r\n    }\r\n\r\n    const colHeights = new Array(columns).fill(0);\r\n    const now = performance.now();\r\n    let hasMovement = false;\r\n    let maxMoveDuration = 0;\r\n\r\n    children.forEach((item, index) => {\r\n      const h = itemHeights[index];\r\n\r\n      let colIndex = 0;\r\n      let minH = colHeights[0];\r\n      for (let i = 1; i < columns; i++) {\r\n        if (colHeights[i] < minH) {\r\n          minH = colHeights[i];\r\n          colIndex = i;\r\n        }\r\n      }\r\n\r\n      const targetX = colIndex * (columnWidth + gap) + padL;\r\n      const targetY = minH + padT;\r\n      const targetW = columnWidth;\r\n\r\n      colHeights[colIndex] = minH + h + gap;\r\n\r\n      const posDuration = parseTime(item.getAttribute(\"string-masonry-position-time\"));\r\n      const sizeDuration = parseTime(item.getAttribute(\"string-masonry-size-time\"));\r\n\r\n      const invPosDur = posDuration > 0 ? 1 / posDuration : 1000;\r\n      const invSizeDur = sizeDuration > 0 ? 1 / sizeDuration : 1000;\r\n\r\n      const posEase = this.parseEasing(item.getAttribute(\"string-masonry-position-easing\"));\r\n      const sizeEase = this.parseEasing(item.getAttribute(\"string-masonry-size-easing\"));\r\n\r\n      let itemState = state.items.get(item);\r\n\r\n      if (!itemState) {\r\n        const startX = animate ? targetX : targetX;\r\n        const startY = animate ? targetY + 30 : targetY;\r\n\r\n        itemState = {\r\n          sx: startX,\r\n          sy: startY,\r\n          sw: targetW,\r\n          tx: targetX,\r\n          ty: targetY,\r\n          tw: targetW,\r\n          dx: 0,\r\n          dy: 0,\r\n          dw: 0,\r\n          cx: startX,\r\n          cy: startY,\r\n          cw: targetW,\r\n          startTime: now,\r\n          posEase,\r\n          invPosDur,\r\n          sizeEase,\r\n          invSizeDur,\r\n          isMoving: animate,\r\n        };\r\n        state.items.set(item, itemState);\r\n\r\n        if (!animate) {\r\n          styleTxn.run(() => {\r\n            styleTxn.setProps(item, {\r\n              transform: `translate3d(${targetX}px, ${targetY}px, 0)`,\r\n              width: `${targetW}px`,\r\n              willChange: \"auto\",\r\n            });\r\n          });\r\n        } else {\r\n          itemState.dx = itemState.tx - itemState.sx;\r\n          itemState.dy = itemState.ty - itemState.sy;\r\n          itemState.dw = itemState.tw - itemState.sw;\r\n          hasMovement = true;\r\n          maxMoveDuration = Math.max(maxMoveDuration, posDuration, sizeDuration);\r\n        }\r\n      } else {\r\n        const dist =\r\n          Math.abs(itemState.tx - targetX) +\r\n          Math.abs(itemState.ty - targetY) +\r\n          Math.abs(itemState.tw - targetW);\r\n\r\n        if (dist > 0.5) {\r\n          itemState.sx = itemState.cx;\r\n          itemState.sy = itemState.cy;\r\n          itemState.sw = itemState.cw;\r\n\r\n          itemState.tx = targetX;\r\n          itemState.ty = targetY;\r\n          itemState.tw = targetW;\r\n\r\n          itemState.dx = itemState.tx - itemState.sx;\r\n          itemState.dy = itemState.ty - itemState.sy;\r\n          itemState.dw = itemState.tw - itemState.sw;\r\n\r\n          itemState.posEase = posEase;\r\n          itemState.invPosDur = invPosDur;\r\n          itemState.sizeEase = sizeEase;\r\n          itemState.invSizeDur = invSizeDur;\r\n\r\n          itemState.startTime = now;\r\n          itemState.isMoving = true;\r\n          hasMovement = true;\r\n          maxMoveDuration = Math.max(maxMoveDuration, posDuration, sizeDuration);\r\n        }\r\n      }\r\n    });\r\n\r\n    const newContainerHeight = Math.max(...colHeights);\r\n\r\n    if (Math.abs(state.targetHeight - newContainerHeight) > 1) {\r\n      if (animate) {\r\n        const rect = container.getBoundingClientRect();\r\n        const viewportHeight = this.data.viewport.windowHeight;\r\n        var isFromBottom = false;\r\n        if (rect.bottom >= -100 && rect.bottom <= viewportHeight + 100) {\r\n          const scrollAdjustment = rect.top + newContainerHeight - viewportHeight;\r\n          if (Math.abs(scrollAdjustment) > 1 && newContainerHeight < container.offsetHeight) {\r\n            const targetScroll =\r\n              rect.top + this.data.scroll.current + newContainerHeight - viewportHeight;\r\n            this.events.emit(\"scrollTo\", targetScroll);\r\n            isFromBottom = true;\r\n          }\r\n        }\r\n\r\n        if (newContainerHeight >= state.targetHeight) {\r\n          if (allowHeightAnim) {\r\n            state.startHeight = container.offsetHeight;\r\n            state.heightStartTime = now;\r\n            state.heightDuration = CONSTANTS.DEFAULT_DURATION;\r\n            state.heightEase = this.parseEasing(null);\r\n            state.isAnimatingHeight = true;\r\n          } else {\r\n            styleTxn.run(() => {\r\n              styleTxn.setProps(object.htmlElement, { height: `${newContainerHeight}px` });\r\n              requestAnimationFrame(() => {\r\n                this.events.emit(\"resize\", true);\r\n              });\r\n            });\r\n          }\r\n          state.targetHeight = newContainerHeight;\r\n          state.pendingHeight = undefined;\r\n        } else {\r\n          state.pendingHeight = newContainerHeight;\r\n          state.pendingHeightAnimate = allowHeightAnim;\r\n          state.targetHeight = newContainerHeight;\r\n\r\n          if (!isFromBottom) {\r\n            styleTxn.run(() => {\r\n              styleTxn.setProps(object.htmlElement, { height: `${newContainerHeight}px` });\r\n              requestAnimationFrame(() => {\r\n                this.events.emit(\"resize\", true);\r\n              });\r\n            });\r\n          }\r\n        }\r\n\r\n        hasMovement = true;\r\n      } else {\r\n        state.targetHeight = newContainerHeight;\r\n        state.pendingHeight = undefined;\r\n        styleTxn.run(() => {\r\n          styleTxn.setProps(object.htmlElement, { height: `${newContainerHeight}px` });\r\n        });\r\n      }\r\n    }\r\n\r\n    if (hasMovement) {\r\n      if (!state.isAnimating) {\r\n        this.events.emit(\"masonry:shuffle:start\", { object });\r\n      }\r\n      state.isAnimating = true;\r\n\r\n      if (maxMoveDuration > 0) {\r\n        state.expectedEndTime = now + maxMoveDuration + 32;\r\n        if (state.endTimerId) window.clearTimeout(state.endTimerId);\r\n\r\n        state.endTimerId = window.setTimeout(() => {\r\n          if (!state.isAnimating) return;\r\n          if (state.pendingHeight !== undefined || state.isAnimatingHeight) return;\r\n          this.events.emit(\"masonry:shuffle:end\", { object });\r\n          state.isAnimating = false;\r\n          state.endTimerId = undefined;\r\n        }, maxMoveDuration + 50);\r\n      }\r\n    }\r\n  }\r\n\r\n  private getGridSettings(object: StringObject): GridSettings {\r\n    const ww = this.data.viewport.windowWidth;\r\n    const mode = object.getProperty<string>(\"masonry-mode\") || \"auto\";\r\n\r\n    if (mode === \"manual\") {\r\n      const manualCols = object.getProperty<number>(CONSTANTS.MANUAL_COLS_KEY);\r\n      const manualGap = object.getProperty<number>(CONSTANTS.MANUAL_GAP_KEY);\r\n      const colsData = object.getProperty<any>(\"masonry-cols\") || [];\r\n      const gapData = object.getProperty<any>(\"masonry-gap\") || [];\r\n\r\n      return {\r\n        columns: Math.max(1, Math.round(manualCols ?? getResponsiveValue(colsData, ww) ?? 2)),\r\n        gap: Math.max(0, manualGap ?? getResponsiveValue(gapData, ww) ?? 16),\r\n      };\r\n    }\r\n\r\n    const colsData = object.getProperty<any>(\"masonry-cols\") || [{ breakpoint: 0, value: 2 }];\r\n    const gapData = object.getProperty<any>(\"masonry-gap\") || [{ breakpoint: 0, value: 16 }];\r\n\r\n    return {\r\n      columns: Math.max(1, Math.round(getResponsiveValue(colsData, ww) ?? 2)),\r\n      gap: Math.max(0, getResponsiveValue(gapData, ww) ?? 16),\r\n    };\r\n  }\r\n\r\n  private attachImgLoaders(object: StringObject, state: MasonryState, root: HTMLElement): void {\r\n    const imgs = root.tagName === \"IMG\" ? [root] : Array.from(root.querySelectorAll(\"img\"));\r\n    imgs.forEach((img: Element) => {\r\n      const imageEl = img as HTMLImageElement;\r\n      if (imageEl.complete) return;\r\n      if (state.imgUnsubs.has(imageEl)) return;\r\n\r\n      const handler = () => {\r\n        this.scheduleLayout(object, true, \"img-load\");\r\n        this.cleanupImgListeners(state, imageEl);\r\n      };\r\n\r\n      imageEl.addEventListener(\"load\", handler);\r\n      imageEl.addEventListener(\"error\", handler);\r\n\r\n      state.imgUnsubs.set(imageEl, () => {\r\n        imageEl.removeEventListener(\"load\", handler);\r\n        imageEl.removeEventListener(\"error\", handler);\r\n      });\r\n    });\r\n  }\r\n\r\n  private cleanupImgListeners(state: MasonryState, root: HTMLElement): void {\r\n    const cleanupSingle = (el: HTMLElement) => {\r\n      const unsub = state.imgUnsubs.get(el);\r\n      if (unsub) {\r\n        unsub();\r\n        state.imgUnsubs.delete(el);\r\n      }\r\n    };\r\n    if (root.tagName === \"IMG\") cleanupSingle(root);\r\n    else root.querySelectorAll(\"img\").forEach((img) => cleanupSingle(img as HTMLElement));\r\n  }\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\nimport { StringData } from \"../../core/StringData\";\nimport { StringModule } from \"../../core/StringModule\";\nimport { StringObject } from \"../../objects/StringObject\";\nimport { styleTxn } from \"../../utils/style-txn\";\n\nexport class StringMagnetic extends StringModule {\n  constructor(context: StringContext) {\n    super(context);\n    this.htmlKey = \"magnetic\";\n    this._type = 2; // UI Module\n\n    this.cssProperties = [\n      { name: \"--magnetic-x\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\n      { name: \"--magnetic-y\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\n      { name: \"--magnetic-target-x\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\n      { name: \"--magnetic-target-y\", syntax: \"<number>\", initialValue: \"0\", inherits: true }\n    ];\n\n    this.permissions.mobile.rebuild.height = false;\n    this.permissions.mobile.rebuild.width = false;\n    this.permissions.mobile.rebuild.scrollHeight = false;\n\n    this.attributesToMap = [\n      ...this.attributesToMap,\n      { key: \"strength\", type: \"number\", fallback: this.settings[\"strength\"] },\n      { key: \"radius\", type: \"number\", fallback: this.settings[\"radius\"] },\n    ];\n  }\n\n  override initializeObject(\n    globalId: number,\n    object: StringObject,\n    element: HTMLElement,\n    attributes: Record<string, any>\n  ): void {\n    super.initializeObject(globalId, object, element, attributes);\n    object.setProperty(\"magnetic-active\", false);\n    object.setProperty(\"magnetic-target-x\", 0);\n    object.setProperty(\"magnetic-target-y\", 0);\n    object.setProperty(\"magnetic-x\", 0);\n    object.setProperty(\"magnetic-y\", 0);\n    object.setProperty(\"magnetic-lerp\", 0.1);\n    object.setProperty(\"event-magnetic-name\", this.getObjectEventName(object, \"magnetic:move\"));\n    object.setProperty(\"__next-magnetic-x\", 0);\n    object.setProperty(\"__next-magnetic-y\", 0);\n    object.setProperty(\"__needs-magnetic-update\", false);\n  }\n\n  onMouseMove(e: MouseEvent): void {\n    for (let i = 0; i < this.objects.length; i++) {\n      const object = this.objects[i];\n      const element = object.htmlElement as HTMLElement;\n      const rect = element.getBoundingClientRect();\n      const centerX = rect.left + rect.width / 2;\n      const centerY = rect.top + rect.height / 2;\n      const dx = e.clientX - centerX;\n      const dy = e.clientY - centerY;\n      const distance = Math.sqrt(dx ** 2 + dy ** 2);\n\n      const radius = object.getProperty<number>(\"radius\") ?? 0;\n      const strength = object.getProperty<number>(\"strength\") ?? 0;\n\n      const factor = this.tools.magneticPull.process({\n        distance,\n        radius,\n        strength,\n      });\n\n      object.setProperty(\"magnetic-target-x\", dx * factor);\n      object.setProperty(\"magnetic-target-y\", dy * factor);\n      if (factor > 0) {\n        object.setProperty(\"magnetic-active\", true);\n      }\n    }\n  }\n\n  onFrame(data: StringData): void {\n    for (let i = 0; i < this.objects.length; i++) {\n      const object = this.objects[i];\n      if (object.getProperty<boolean>(\"magnetic-active\") === true) {\n        let magneticX = object.getProperty<number>(\"magnetic-x\") ?? 0;\n        let magneticY = object.getProperty<number>(\"magnetic-y\") ?? 0;\n\n        let lerp = object.getProperty<number>(\"magnetic-lerp\") ?? 0.1;\n\n        let targetMagneticX = object.getProperty<number>(\"magnetic-target-x\") ?? 0;\n        let targetMagneticY = object.getProperty<number>(\"magnetic-target-y\") ?? 0;\n\n        let lerpX = this.tools.lerp.process({\n          from: magneticX,\n          to: targetMagneticX,\n          progress: lerp,\n        });\n        let lerpY = this.tools.lerp.process({\n          from: magneticY,\n          to: targetMagneticY,\n          progress: lerp,\n        });\n\n        if (lerpX > -0.01 && lerpX < 0.01) {\n          lerpX = 0;\n          object.setProperty(\"magnetic-x\", targetMagneticX);\n        }\n        if (lerpY > -0.01 && lerpY < 0.01) {\n          lerpY = 0;\n          object.setProperty(\"magnetic-y\", targetMagneticY);\n        }\n        magneticX += lerpX;\n        magneticY += lerpY;\n        object.setProperty(\"magnetic-x\", magneticX);\n        object.setProperty(\"magnetic-y\", magneticY);\n\n        const eventName = object.getProperty<string>(\"event-magnetic-name\");\n        if (eventName) {\n          this.events.emit(eventName, {\n            x: magneticX,\n            y: magneticY,\n          });\n        }\n        object.setProperty(\"__next-magnetic-x\", magneticX);\n        object.setProperty(\"__next-magnetic-y\", magneticY);\n        object.setProperty(\"__needs-magnetic-update\", true);\n\n        if (targetMagneticX === magneticX && targetMagneticY === magneticY) {\n          object.setProperty(\"magnetic-active\", false);\n        }\n      }\n    }\n  }\n\n  override onMutate(): void {\n    for (let i = 0; i < this.objects.length; i++) {\n      const object = this.objects[i];\n      const needsUpdate = object.getProperty<boolean>(\"__needs-magnetic-update\") === true;\n      if (!needsUpdate) continue;\n\n      const x =\n        object.getProperty<number>(\"__next-magnetic-x\") ??\n        object.getProperty<number>(\"magnetic-x\") ??\n        0;\n      const y =\n        object.getProperty<number>(\"__next-magnetic-y\") ??\n        object.getProperty<number>(\"magnetic-y\") ??\n        0;\n\n      this.applyToElementAndConnects(object, (el) => {\n        styleTxn.setVar(el, \"--magnetic-x\", x);\n        styleTxn.setVar(el, \"--magnetic-y\", y);\n      });\n\n      object.setProperty(\"__needs-magnetic-update\", false);\n    }\n  }\n}\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringData } from \"../../core/StringData\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { frameDOM } from \"../../utils/frame-dom\";\r\nimport { isCoarsePointer } from \"../../utils/isCoarsePointer\";\r\nimport { styleTxn } from \"../../utils/style-txn\";\r\n\r\nexport abstract class CursorReactiveModule extends StringModule {\r\n  protected nearOnly = true;\r\n  protected useAllObjects = false;\r\n  protected maxDistanceMultiplier = 1;\r\n  protected updateThreshold = 0.1;\r\n\r\n  protected enabled = true;\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    if (isCoarsePointer()) {\r\n      this.enabled = false;\r\n    }\r\n  }\r\n\r\n  override onObjectConnected(object: StringObject): void {\r\n    if (!this.enabled) return;\r\n    super.onObjectConnected(object);\r\n    this.centers.attach(object);\r\n    this.hover.track(object);\r\n  }\r\n\r\n  override removeObject(id: string): void {\r\n    if (!this.enabled) return super.removeObject(id);\r\n    const obj = this.objectMapOnPage.get(id);\r\n    if (obj) {\r\n      this.centers.detach(obj);\r\n      this.hover.untrack(obj);\r\n    }\r\n    super.removeObject(id);\r\n  }\r\n\r\n  override onScroll(): void {\r\n    if (!this.enabled) return;\r\n    this.centers.invalidateAll();\r\n    this.scheduleCursorUpdate();\r\n  }\r\n\r\n  override onMouseMoveMeasure(data: StringData) {\r\n    if (!this.enabled) return;\r\n    super.onMouseMoveMeasure(data);\r\n    this.refreshPointerState();\r\n  }\r\n\r\n  override onScrollMeasure(data: StringData) {\r\n    if (!this.enabled) return;\r\n    super.onScrollMeasure(data);\r\n    this.refreshPointerState();\r\n  }\r\n\r\n  protected getCursorTargets(allowFallback = false): StringObject[] {\r\n    if (!this.enabled) return [];\r\n    const near = this.hover.activeObjects();\r\n    if (this.nearOnly && near.length) return near;\r\n    if (this.useAllObjects) return this.objectsOnPage;\r\n    if (this.objects.length > 0) return this.objects;\r\n    return allowFallback ? this.objectsOnPage : this.objects;\r\n  }\r\n\r\n  protected refreshPointerState(target?: StringObject, allowFallback = false): void {\r\n    if (!this.enabled) return;\r\n\r\n    const mx = this.data.cursor.targetX;\r\n    const my = this.data.cursor.targetY;\r\n    const targets = target ? [target] : this.getCursorTargets(allowFallback);\r\n\r\n    const maxDistanceSq =\r\n      !this.nearOnly && this.maxDistanceMultiplier > 0\r\n        ? Math.pow(this.data.viewport.windowWidth * this.maxDistanceMultiplier, 2)\r\n        : null;\r\n\r\n    for (const obj of targets) {\r\n      const { cx, cy } = this.centers.getCenter(obj);\r\n      const dx = mx - cx;\r\n      const dy = my - cy;\r\n      const d2 = dx * dx + dy * dy;\r\n\r\n      if (this.nearOnly) {\r\n        const far = d2 > this.data.viewport.windowWidth * this.data.viewport.windowWidth;\r\n        if (far && !this.hover.isActive(obj)) continue;\r\n      } else if (maxDistanceSq !== null && d2 > maxDistanceSq) {\r\n        continue;\r\n      }\r\n\r\n      obj.setProperty(\"dx\", dx);\r\n      obj.setProperty(\"dy\", dy);\r\n      obj.setProperty(\"dist\", Math.sqrt(d2));\r\n    }\r\n  }\r\n\r\n  private scrollUpdateScheduled = false;\r\n\r\n  protected scheduleCursorUpdate(): void {\r\n    if (!this.enabled || this.scrollUpdateScheduled) return;\r\n    this.scrollUpdateScheduled = true;\r\n\r\n    frameDOM.measure(() => {\r\n      this.refreshPointerState();\r\n      frameDOM.mutate(() => {\r\n        this.scrollUpdateScheduled = false;\r\n        styleTxn.run(() => {\r\n          this.onCursorScrollUpdate();\r\n        });\r\n      });\r\n    });\r\n  }\r\n\r\n  // eslint-disable-next-line @typescript-eslint/no-empty-function\r\n  protected onCursorScrollUpdate(): void {}\r\n}\r\n","import { StringData } from \"../../core/StringData\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { frameDOM } from \"../../utils/frame-dom\";\r\nimport { styleTxn } from \"../../utils/style-txn\";\r\nimport { CursorReactiveModule } from \"./CursorReactiveModule\";\r\n\r\ntype SpotlightComputeKernel = {\r\n  computeStep(\r\n    pointerDx: number,\r\n    pointerDy: number,\r\n    pointerDist: number,\r\n    deadzone: number,\r\n    distMax: number,\r\n    lerp: number,\r\n    currentAngle: number,\r\n    currentDist: number,\r\n    currentTargetAngle: number,\r\n    prevDeg: number,\r\n    prevDist: number,\r\n    angleEps: number,\r\n    distEps: number,\r\n    forceImmediate: number,\r\n    forceEmit: number,\r\n    bypassDeadzone: number,\r\n    out: SpotlightComputeStepResult\r\n  ): void;\r\n};\r\n\r\ntype SpotlightComputeStepResult = {\r\n  angle: number;\r\n  dist: number;\r\n  tAngle: number;\r\n  tDist: number;\r\n  degRaw: number;\r\n  cssDeg: number;\r\n  cssDist: number;\r\n  angleChanged: number;\r\n  distChanged: number;\r\n};\r\n\r\nconst TAU = Math.PI * 2;\r\nconst RAD2DEG = 180 / Math.PI;\r\nconst clamp01 = (v: number) => (v < 0 ? 0 : v > 1 ? 1 : v);\r\n\r\nconst shortestArc = (from: number, to: number) => {\r\n  let d = (to - from) % TAU;\r\n  if (d > Math.PI) d -= TAU;\r\n  if (d < -Math.PI) d += TAU;\r\n  return from + d;\r\n};\r\n\r\nconst DEFAULT_SPOTLIGHT_KERNEL: SpotlightComputeKernel = {\r\n  computeStep(\r\n    pointerDx: number,\r\n    pointerDy: number,\r\n    pointerDist: number,\r\n    deadzone: number,\r\n    distMax: number,\r\n    lerp: number,\r\n    currentAngle: number,\r\n    currentDist: number,\r\n    currentTargetAngle: number,\r\n    prevDeg: number,\r\n    prevDist: number,\r\n    angleEps: number,\r\n    distEps: number,\r\n    forceImmediate: number,\r\n    forceEmit: number,\r\n    bypassDeadzone: number,\r\n    out: SpotlightComputeStepResult\r\n  ): void {\r\n    let targetAngle = currentTargetAngle;\r\n    if (bypassDeadzone === 1 || pointerDist > deadzone) {\r\n      targetAngle = Math.atan2(pointerDy, pointerDx);\r\n    }\r\n\r\n    const targetDist = distMax > 0 ? Math.min(pointerDist, distMax) : pointerDist;\r\n\r\n    let angle = currentAngle;\r\n    let dist = currentDist;\r\n    if (forceImmediate === 1) {\r\n      angle = targetAngle;\r\n      dist = targetDist;\r\n    } else {\r\n      const nextA = shortestArc(currentAngle, targetAngle);\r\n      const factor = clamp01(lerp);\r\n      angle += (nextA - angle) * factor;\r\n      dist += (targetDist - dist) * factor;\r\n    }\r\n\r\n    const degRaw = angle * RAD2DEG - 90;\r\n    const angleChanged = forceEmit === 1 || Number.isNaN(prevDeg) || Math.abs(degRaw - prevDeg) > angleEps;\r\n    const distChanged = forceEmit === 1 || Number.isNaN(prevDist) || Math.abs(dist - prevDist) > distEps;\r\n\r\n    out.angle = angle;\r\n    out.dist = dist;\r\n    out.tAngle = targetAngle;\r\n    out.tDist = targetDist;\r\n    out.degRaw = degRaw;\r\n    out.cssDeg = Math.round(degRaw * 10) / 10;\r\n    out.cssDist = Math.round(dist * 10) / 10;\r\n    out.angleChanged = angleChanged ? 1 : 0;\r\n    out.distChanged = distChanged ? 1 : 0;\r\n  },\r\n};\r\n\r\ntype SpotlightState = {\r\n  angle: number;\r\n  dist: number;\r\n  tAngle: number;\r\n  tDist: number;\r\n  prevDeg: number;\r\n  prevDist: number;\r\n};\r\n\r\nconst SCROLL_UPDATE_OPTIONS = { bypassDeadzone: true } as const;\r\nconst INITIALIZE_OPTIONS = {\r\n  forceImmediate: true,\r\n  forceEmit: true,\r\n  bypassDeadzone: true,\r\n} as const;\r\n\r\nconst spotState = new WeakMap<StringObject, SpotlightState>();\r\nconst getSpot = (o: StringObject): SpotlightState => {\r\n  let s = spotState.get(o);\r\n  if (!s) {\r\n    s = { angle: 0, dist: 0, tAngle: 0, tDist: 0, prevDeg: NaN, prevDist: NaN };\r\n    spotState.set(o, s);\r\n  }\r\n  return s;\r\n};\r\n\r\nexport class StringSpotlight extends CursorReactiveModule {\r\n  private readonly stepResult: SpotlightComputeStepResult = {\r\n    angle: 0,\r\n    dist: 0,\r\n    tAngle: 0,\r\n    tDist: 0,\r\n    degRaw: 0,\r\n    cssDeg: 0,\r\n    cssDist: 0,\r\n    angleChanged: 0,\r\n    distChanged: 0,\r\n  };\r\n\r\n  constructor(context: any) {\r\n    super(context);\r\n    this.htmlKey = \"spotlight\";\r\n    this.cssProperties = [\r\n      { name: \"--spotlight-angle\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--spotlight-distance\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n    ];\r\n\r\n    this.nearOnly = false;\r\n    this.useAllObjects = false;\r\n    this.maxDistanceMultiplier = 1;\r\n\r\n    this.attributesToMap.push(\r\n      {\r\n        key: \"lerp\",\r\n        type: \"number\",\r\n        fallback: this.settings[\"lerp\"],\r\n        transform: (v: number) =>\r\n          clamp01(\r\n            this.tools.adaptiveLerp.process({\r\n              value: v,\r\n              inMin: 0.1,\r\n              inMax: 1.0,\r\n              outMin: 0.05,\r\n              outMax: 0.65,\r\n            })\r\n          ),\r\n      },\r\n      { key: \"angle-threshold\", type: \"number\", fallback: 0.2 },\r\n      { key: \"distance-threshold\", type: \"number\", fallback: 0.5 },\r\n      { key: \"deadzone\", type: \"number\", fallback: 4 },\r\n      { key: \"dist-max\", type: \"number\", fallback: 0 }\r\n    );\r\n  }\r\n\r\n  initializeObject(\r\n    id: number,\r\n    obj: StringObject,\r\n    el: HTMLElement,\r\n    attrs: Record<string, any>\r\n  ): void {\r\n    super.initializeObject(id, obj, el, attrs);\r\n\r\n    obj.setProperty(\"spotlight-angle-rad\", 0);\r\n    obj.setProperty(\"spotlight-distance\", 0);\r\n    obj.setProperty(\"spotlight-angle-rad-target\", 0);\r\n    obj.setProperty(\"spotlight-distance-target\", 0);\r\n\r\n    frameDOM.measure(() => {\r\n      this.refreshPointerState(obj, /*allowFallback=*/ true);\r\n      frameDOM.mutate(() => {\r\n        styleTxn.run(() => {\r\n          this.updateSpotlightState(obj, INITIALIZE_OPTIONS);\r\n        });\r\n      });\r\n    });\r\n  }\r\n\r\n  override onMutate(data: StringData): void {\r\n    if (this.enabled) {\r\n      super.onMutate(data);\r\n      const targets = this.getCursorTargets(/*allowFallback=*/ false);\r\n      const list = targets.length > 0 ? targets : this.getCursorTargets(/*allowFallback=*/ true);\r\n      for (let i = 0; i < list.length; i++) {\r\n        const object = list[i];\r\n        this.updateSpotlightState(object);\r\n      }\r\n    }\r\n  }\r\n\r\n  protected onCursorScrollUpdate(): void {\r\n    const targets = this.getCursorTargets(/*allowFallback=*/ false);\r\n    const list = targets.length > 0 ? targets : this.getCursorTargets(/*allowFallback=*/ true);\r\n\r\n    for (let i = 0; i < list.length; i++) {\r\n      const object = list[i];\r\n      this.updateSpotlightState(object, SCROLL_UPDATE_OPTIONS);\r\n    }\r\n  }\r\n\r\n  private updateSpotlightState(\r\n    object: StringObject,\r\n    options: { forceImmediate?: boolean; forceEmit?: boolean; bypassDeadzone?: boolean } = {}\r\n  ): void {\r\n    const dx = object.getProperty<number>(\"dx\");\r\n    const dy = object.getProperty<number>(\"dy\");\r\n    const dist = object.getProperty<number>(\"dist\");\r\n\r\n    if (!Number.isFinite(dx) || !Number.isFinite(dy) || !Number.isFinite(dist)) {\r\n      return;\r\n    }\r\n\r\n    const s = getSpot(object);\r\n    DEFAULT_SPOTLIGHT_KERNEL.computeStep(\r\n      dx,\r\n      dy,\r\n      dist,\r\n      object.getProperty<number>(\"deadzone\") ?? 4,\r\n      object.getProperty<number>(\"dist-max\") ?? 0,\r\n      object.getProperty<number>(\"lerp\") ?? 0.15,\r\n      s.angle,\r\n      s.dist,\r\n      s.tAngle,\r\n      s.prevDeg,\r\n      s.prevDist,\r\n      object.getProperty<number>(\"angle-threshold\") ?? 0.2,\r\n      object.getProperty<number>(\"distance-threshold\") ?? 0.5,\r\n      options.forceImmediate === true ? 1 : 0,\r\n      options.forceEmit === true ? 1 : 0,\r\n      options.bypassDeadzone === true ? 1 : 0,\r\n      this.stepResult\r\n    );\r\n\r\n    s.angle = this.stepResult.angle;\r\n    s.dist = this.stepResult.dist;\r\n    s.tAngle = this.stepResult.tAngle;\r\n    s.tDist = this.stepResult.tDist;\r\n\r\n    object.setProperty(\"spotlight-distance-target\", s.tDist);\r\n    object.setProperty(\"spotlight-angle-rad-target\", s.tAngle);\r\n    object.setProperty(\"spotlight-angle-rad\", s.angle);\r\n    object.setProperty(\"spotlight-distance\", s.dist);\r\n\r\n    if (this.stepResult.angleChanged === 1 || this.stepResult.distChanged === 1) {\r\n      this.writeSpotlightVars(object, this.stepResult.cssDeg, this.stepResult.cssDist);\r\n\r\n      s.prevDeg = this.stepResult.degRaw;\r\n      s.prevDist = s.dist;\r\n\r\n      this.events.emit(this.getObjectEventName(object, \"spotlight:update\"), {\r\n        distance: this.stepResult.cssDist,\r\n        angleDeg: this.stepResult.cssDeg,\r\n      });\r\n    }\r\n  }\r\n\r\n  private writeSpotlightVars(object: StringObject, angleDeg: number, distance: number): void {\r\n    const apply = () => {\r\n      this.applyToElementAndConnects(object, (el) => {\r\n        styleTxn.setVar(el, \"--spotlight-angle\", angleDeg);\r\n        styleTxn.setVar(el, \"--spotlight-distance\", distance);\r\n      });\r\n    };\r\n\r\n    if (styleTxn.isOpen) {\r\n      apply();\r\n      return;\r\n    }\r\n\r\n    styleTxn.run(apply);\r\n  }\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\n\r\nconst ASPECT_CLASS = \"-aspect-ready\";\r\n\r\ntype Dims = { width: number; height: number };\r\n\r\nfunction isSvgSource(src: string): boolean {\r\n  if (!src) return false;\r\n  const lower = src.toLowerCase();\r\n  if (lower.endsWith(\".svg\")) return true;\r\n  if (lower.startsWith(\"data:image/svg\")) return true;\r\n  return false;\r\n}\r\n\r\ninterface LazyImageState {\r\n  src: string;\r\n  aspectReady: boolean;\r\n  contentReady: boolean;\r\n  aspectLoading: boolean;\r\n  contentLoading: boolean;\r\n  pendingActivation: boolean;\r\n  width?: number;\r\n  height?: number;\r\n  aspectPromise?: Promise<void>;\r\n  unsubscribe?: () => void;\r\n  rangeAttempted: boolean;\r\n  blobUrl?: string;\r\n  controller?: AbortController;\r\n\r\n  fetching: boolean;\r\n  allowSrcFallback?: boolean;\r\n}\r\n\r\nfunction parsePng(b: ArrayBuffer): Dims {\r\n  const d = new DataView(b);\r\n  if (b.byteLength < 28) return { width: 0, height: 0 };\r\n  if (d.getUint32(0) !== 0x89504e47 || d.getUint32(4) !== 0x0d0a1a0a)\r\n    return { width: 0, height: 0 };\r\n  if (d.getUint32(8) !== 13 || d.getUint32(12) !== 0x49484452) return { width: 0, height: 0 };\r\n  return { width: d.getUint32(16, false), height: d.getUint32(20, false) };\r\n}\r\n\r\nfunction parseJpeg(b: ArrayBuffer): Dims {\r\n  const d = new DataView(b);\r\n  if (d.getUint16(0) !== 0xffd8) return { width: 0, height: 0 };\r\n  let o = 2;\r\n  while (o + 9 < b.byteLength) {\r\n    const m = d.getUint16(o);\r\n    o += 2;\r\n    if (m === 0xffda || m === 0xffd9) break;\r\n    const len = d.getUint16(o);\r\n    if (len < 2 || o + len > b.byteLength) break;\r\n    if (\r\n      (m >= 0xffc0 && m <= 0xffc3) ||\r\n      (m >= 0xffc5 && m <= 0xffc7) ||\r\n      (m >= 0xffc9 && m <= 0xffcb) ||\r\n      (m >= 0xffcd && m <= 0xffcf)\r\n    ) {\r\n      return { height: d.getUint16(o + 3), width: d.getUint16(o + 5) };\r\n    }\r\n    o += len;\r\n  }\r\n  return { width: 0, height: 0 };\r\n}\r\n\r\nfunction parseWebp(b: ArrayBuffer): Dims {\r\n  const d = new DataView(b);\r\n  if (b.byteLength < 16) return { width: 0, height: 0 };\r\n\r\n  if (d.getUint32(0, true) !== 0x46464952 || d.getUint32(8, true) !== 0x50424557)\r\n    return { width: 0, height: 0 };\r\n\r\n  let i = 12;\r\n  while (i + 8 <= b.byteLength) {\r\n    const chunkHeader = d.getUint32(i, false);\r\n    const chunkSize = d.getUint32(i + 4, true);\r\n    const dataOffset = i + 8;\r\n\r\n    if (chunkHeader === 0x56503858) {\r\n      const w = (d.getUint16(dataOffset + 4, true) | (d.getUint8(dataOffset + 6) << 16)) + 1;\r\n      const h = (d.getUint16(dataOffset + 7, true) | (d.getUint8(dataOffset + 9) << 16)) + 1;\r\n      return { width: w, height: h };\r\n    }\r\n\r\n    if (chunkHeader === 0x56503820) {\r\n      if (\r\n        dataOffset + 10 <= b.byteLength &&\r\n        d.getUint8(dataOffset + 3) === 0x9d &&\r\n        d.getUint8(dataOffset + 4) === 0x01 &&\r\n        d.getUint8(dataOffset + 5) === 0x2a\r\n      ) {\r\n        const w = d.getUint16(dataOffset + 6, true) & 0x3fff;\r\n        const h = d.getUint16(dataOffset + 8, true) & 0x3fff;\r\n        return { width: w, height: h };\r\n      }\r\n    }\r\n\r\n    if (chunkHeader === 0x5650384c) {\r\n      if (dataOffset + 5 <= b.byteLength && d.getUint8(dataOffset) === 0x2f) {\r\n        const b0 = d.getUint8(dataOffset + 1);\r\n        const b1 = d.getUint8(dataOffset + 2);\r\n        const b2 = d.getUint8(dataOffset + 3);\r\n        const b3 = d.getUint8(dataOffset + 4);\r\n\r\n        const w = 1 + (((b1 & 0x3f) << 8) | b0);\r\n        const h = 1 + (((b3 & 0x0f) << 10) | (b2 << 2) | ((b1 & 0xc0) >> 6));\r\n        return { width: w, height: h };\r\n      }\r\n    }\r\n\r\n    i = dataOffset + chunkSize + (chunkSize & 1);\r\n  }\r\n  return { width: 0, height: 0 };\r\n}\r\n\r\nfunction tryParseDims(buffer: ArrayBuffer, ct?: string | null): Dims {\r\n  const c = (ct || \"\").toLowerCase();\r\n  if (c.includes(\"png\")) return parsePng(buffer);\r\n  if (c.includes(\"jpeg\") || c.includes(\"jpg\")) return parseJpeg(buffer);\r\n  if (c.includes(\"webp\")) return parseWebp(buffer);\r\n  let d = parsePng(buffer);\r\n  if (d.width) return d;\r\n  d = parseJpeg(buffer);\r\n  if (d.width) return d;\r\n  d = parseWebp(buffer);\r\n  if (d.width) return d;\r\n  return { width: 0, height: 0 };\r\n}\r\n\r\nasync function fetchImageStreamWithDims(\r\n  src: string,\r\n  opts?: {\r\n    credentials?: RequestCredentials;\r\n    referrerPolicy?: ReferrerPolicy;\r\n    signal?: AbortSignal;\r\n  },\r\n  onDims?: (d: Dims) => void,\r\n): Promise<{\r\n  dims: { width: number; height: number } | null;\r\n  blobUrl: string;\r\n  contentType?: string | null;\r\n}> {\r\n  const res = await fetch(src, {\r\n    mode: \"cors\",\r\n    credentials: opts?.credentials ?? \"omit\",\r\n    referrerPolicy: opts?.referrerPolicy,\r\n    signal: opts?.signal,\r\n    cache: \"default\",\r\n  });\r\n  if (!res.ok || !res.body) throw new Error(`HTTP ${res.status}`);\r\n\r\n  const ct = res.headers.get(\"content-type\");\r\n  const reader = res.body.getReader();\r\n\r\n  const PROBE_CAP = 1048576;\r\n  const TRY_STEP = 4096;\r\n\r\n  const probe = new Uint8Array(PROBE_CAP);\r\n  let probeLen = 0;\r\n  let lastTriedLen = 0;\r\n\r\n  const chunks: ArrayBuffer[] = [];\r\n  let dims: Dims | null = null;\r\n  let announced = false;\r\n\r\n  for (;;) {\r\n    const { done, value } = await reader.read();\r\n    if (done) break;\r\n    if (!value) continue;\r\n\r\n    const part = value.buffer.slice(value.byteOffset, value.byteOffset + value.byteLength);\r\n    chunks.push(part);\r\n\r\n    if (!dims && probeLen < PROBE_CAP) {\r\n      const toCopy = Math.min(value.byteLength, PROBE_CAP - probeLen);\r\n      if (toCopy > 0) {\r\n        probe.set(value.subarray(0, toCopy), probeLen);\r\n        probeLen += toCopy;\r\n      }\r\n      if (probeLen - lastTriedLen >= TRY_STEP) {\r\n        const view = probeLen === probe.byteLength ? probe : probe.slice(0, probeLen);\r\n        const d = tryParseDims(view.buffer, ct);\r\n        if (d.width && d.height) {\r\n          dims = d;\r\n          if (!announced && onDims) {\r\n            onDims(dims);\r\n            announced = true;\r\n          }\r\n        }\r\n        lastTriedLen = probeLen;\r\n      }\r\n    }\r\n  }\r\n\r\n  if (!dims) {\r\n    const full = await new Response(new Blob(chunks)).arrayBuffer();\r\n    const d = tryParseDims(full, ct);\r\n    if (d.width && d.height) {\r\n      dims = d;\r\n      if (!announced && onDims) {\r\n        onDims(dims);\r\n        announced = true;\r\n      }\r\n    }\r\n  }\r\n\r\n  const blob = new Blob(chunks, { type: ct || \"application/octet-stream\" });\r\n  const blobUrl = URL.createObjectURL(blob);\r\n  return { dims, blobUrl, contentType: ct };\r\n}\r\n\r\nexport class StringLazy extends StringModule {\r\n  private isStartLoaded = false;\r\n  private loadingCount = 0;\r\n  private imageStates = new WeakMap<HTMLImageElement, LazyImageState>();\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"lazy\";\r\n  }\r\n\r\n  onInit(): void {\r\n    const images = document.querySelectorAll(\"img[string-lazy], img[data-string-lazy]\");\r\n    images.forEach((img) => this.ensureState(img as HTMLImageElement));\r\n    this.isStartLoaded = true;\r\n  }\r\n\r\n  onObjectConnected(object: StringObject): void {\r\n    const element = object.htmlElement;\r\n    if (!(element instanceof HTMLImageElement)) return;\r\n    if (!element.getAttribute(\"src\")) {\r\n      element.setAttribute(\r\n        \"src\",\r\n        \"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1' height='1' viewBox='0 0 1 1'%3E%3C/svg%3E\",\r\n      );\r\n    }\r\n    const state = this.ensureState(element);\r\n\r\n    if (!state.aspectReady && !state.aspectLoading) {\r\n      this.prepareAspectRatio(element);\r\n    }\r\n\r\n    const listener = (data: { inView: boolean } | undefined) => {\r\n      this.handleInView(element, state, !!data?.inView);\r\n    };\r\n    if (state.unsubscribe) state.unsubscribe();\r\n    const inviewEventName = this.getObjectEventName(object, \"object:inview\");\r\n    this.events.on(inviewEventName, listener);\r\n    state.unsubscribe = () => this.events.off(inviewEventName, listener);\r\n    if (this.isStartLoaded && (object.getProperty<boolean>(\"is-inview\") ?? false)) {\r\n      this.handleInView(element, state, true);\r\n    }\r\n  }\r\n\r\n  onObjectDisconnected(object: StringObject): void {\r\n    const element = object.htmlElement;\r\n    if (!(element instanceof HTMLImageElement)) return;\r\n    const state = this.imageStates.get(element);\r\n    if (!state) return;\r\n    state.pendingActivation = false;\r\n    if (state.controller) state.controller.abort();\r\n    if (state.blobUrl) URL.revokeObjectURL(state.blobUrl);\r\n    if (state.unsubscribe) {\r\n      state.unsubscribe();\r\n      state.unsubscribe = undefined;\r\n    }\r\n  }\r\n\r\n  private ensureState(img: HTMLImageElement): LazyImageState {\r\n    let state = this.imageStates.get(img);\r\n    if (!state) {\r\n      const src = this.readSource(img);\r\n      state = {\r\n        src,\r\n        aspectReady: false,\r\n        contentReady: false,\r\n        aspectLoading: false,\r\n        contentLoading: false,\r\n        pendingActivation: false,\r\n        rangeAttempted: false,\r\n        fetching: false,\r\n      };\r\n      this.imageStates.set(img, state);\r\n      if (!img.classList.contains(\"lazyLoad\")) img.classList.add(\"lazyLoad\");\r\n      if (img.dataset && !img.dataset.stringLazySrc && src) img.dataset.stringLazySrc = src;\r\n      return state;\r\n    }\r\n    if (!state.src) state.src = this.readSource(img);\r\n    return state;\r\n  }\r\n\r\n  private readSource(img: HTMLImageElement): string {\r\n    const raw = this.tools.domAttribute.process({ element: img, key: this.htmlKey, fallback: \"\" });\r\n    if (typeof raw === \"string\") return raw;\r\n    if (raw == null) return \"\";\r\n    return String(raw);\r\n  }\r\n\r\n  private handleInView(img: HTMLImageElement, state: LazyImageState, inView: boolean): void {\r\n    state.pendingActivation = inView;\r\n    if (!inView) return;\r\n    if (state.aspectReady) {\r\n      this.maybeActivateImage(img, state);\r\n    } else if (!state.aspectLoading) {\r\n      this.prepareAspectRatio(img);\r\n    }\r\n  }\r\n\r\n  private async prepareAspectRatio(img: HTMLImageElement): Promise<void> {\r\n    const state = this.ensureState(img);\r\n    if (!state.src || state.aspectLoading || state.aspectReady) return;\r\n\r\n    if (isSvgSource(state.src)) {\r\n      state.aspectReady = true;\r\n      state.allowSrcFallback = true;\r\n      this.maybeActivateImage(img, state);\r\n      return;\r\n    }\r\n\r\n    state.aspectLoading = true;\r\n    state.fetching = true;\r\n\r\n    const crossOrigin = img.getAttribute(\"crossorigin\");\r\n    const referrerPolicy = img.getAttribute(\"referrerpolicy\") as ReferrerPolicy | null;\r\n    const ac = new AbortController();\r\n    state.controller = ac;\r\n\r\n    try {\r\n      const { blobUrl } = await fetchImageStreamWithDims(\r\n        state.src,\r\n        {\r\n          credentials: crossOrigin === \"use-credentials\" ? \"include\" : \"omit\",\r\n          referrerPolicy: referrerPolicy || undefined,\r\n          signal: ac.signal,\r\n        },\r\n\r\n        (d) => {\r\n          if (d.width > 0 && d.height > 0 && !state.aspectReady) {\r\n            img.style.aspectRatio = `${d.width} / ${d.height}`;\r\n            img.classList.add(ASPECT_CLASS);\r\n            state.width = d.width;\r\n            state.height = d.height;\r\n            state.aspectReady = true;\r\n          }\r\n        },\r\n      );\r\n\r\n      state.blobUrl = blobUrl;\r\n\r\n      if (!state.aspectReady && state.width && state.height) {\r\n        img.style.aspectRatio = `${state.width} / ${state.height}`;\r\n        img.classList.add(ASPECT_CLASS);\r\n        state.aspectReady = true;\r\n      }\r\n    } catch {\r\n      state.allowSrcFallback = true;\r\n      state.aspectReady = true;\r\n    } finally {\r\n      state.fetching = false;\r\n      state.aspectLoading = false;\r\n\r\n      this.maybeActivateImage(img, state);\r\n    }\r\n  }\r\n\r\n  private maybeActivateImage(img: HTMLImageElement, state: LazyImageState): void {\r\n    if (!state.pendingActivation || state.contentReady || state.contentLoading) return;\r\n    if (!state.aspectReady || !state.src) return;\r\n\r\n    if (state.fetching && !state.blobUrl) return;\r\n\r\n    if (state.blobUrl || state.allowSrcFallback) {\r\n      this.activateImage(img, state);\r\n    }\r\n  }\r\n\r\n  private activateImage(img: HTMLImageElement, state: LazyImageState): void {\r\n    state.contentLoading = true;\r\n    this.loadingCount++;\r\n    const finalize = (loaded: boolean) => {\r\n      if (!state.contentLoading) return;\r\n      state.contentLoading = false;\r\n      state.pendingActivation = false;\r\n      this.loadingCount = Math.max(0, this.loadingCount - 1);\r\n      if (loaded) {\r\n        state.contentReady = true;\r\n        img.classList.add(\"-loaded\");\r\n      }\r\n      if (this.loadingCount === 0) this.events.emit(\"image:load:all\", null);\r\n    };\r\n    const onLoad = () => finalize(true);\r\n    const onError = () => finalize(false);\r\n    img.addEventListener(\"load\", onLoad, { once: true });\r\n    img.addEventListener(\"error\", onError, { once: true });\r\n    img.decoding = \"async\";\r\n    img.loading = img.loading || \"lazy\";\r\n\r\n    if (state.blobUrl) {\r\n      img.removeAttribute(\"srcset\");\r\n      img.removeAttribute(\"sizes\");\r\n      img.src = state.blobUrl;\r\n    } else {\r\n      img.src = state.src;\r\n    }\r\n\r\n    if (img.complete && img.naturalWidth > 0 && img.naturalHeight > 0) {\r\n      img.removeEventListener(\"load\", onLoad);\r\n      img.removeEventListener(\"error\", onError);\r\n      finalize(true);\r\n    }\r\n  }\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\n\r\n/**\r\n * Represents a module responsible for handling loading-related functionality.\r\n * Extends the `StringModule` class and provides additional behavior for managing\r\n * loading states and timeouts.\r\n */\r\nexport class StringLoading extends StringModule {\r\n  loadingTimeout: number = 0;\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this._type = 2;\r\n    this.loadingTimeout = this.settings[\"timeout\"];\r\n  }\r\n  onInit(): void {\r\n    setTimeout(() => {\r\n      const htmlElement = document.documentElement;\r\n      htmlElement.classList.add(\"-loaded\");\r\n    }, this.loadingTimeout);\r\n  }\r\n}\r\n","import { StringModule } from \"../../core/StringModule\";\nimport { StringObject } from \"../../objects/StringObject\";\n\nexport class StringInview extends StringModule {\n  constructor(visitor: any) {\n    super(visitor);\n    this.htmlKey = '';\n  }\n  canConnect(object: StringObject): boolean {\n    return object.keys[0] == undefined || object.getProperty<boolean>(\"inview-fallback\") === true;\n  }\n}\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\n\r\nenum DeviceType {\r\n  Mobile,\r\n  Tablet,\r\n  Laptop,\r\n  Desktop,\r\n}\r\n\r\ninterface DeviceQueryConfig {\r\n  min?: number;\r\n  max?: number;\r\n  enable?: boolean;\r\n}\r\n\r\ninterface QueryConfig {\r\n  mobile?: DeviceQueryConfig;\r\n  tablet?: DeviceQueryConfig;\r\n  laptop?: DeviceQueryConfig;\r\n  desktop?: DeviceQueryConfig;\r\n}\r\n\r\nclass StringResponsiveQueryDevice {\r\n  public min?: number = undefined;\r\n  public max?: number = undefined;\r\n  public enable: boolean = true;\r\n\r\n  constructor(config?: DeviceQueryConfig) {\r\n    this.min = config?.min;\r\n    this.max = config?.max;\r\n    this.enable = config?.enable ?? true;\r\n  }\r\n\r\n  setEnable(enable: boolean = true) {\r\n    this.enable = enable;\r\n  }\r\n  setRange(min?: number, max?: number) {\r\n    this.min = min ?? undefined;\r\n    this.max = max ?? undefined;\r\n  }\r\n\r\n  get mediaQuery(): string {\r\n    let query = \"screen\";\r\n    if (this.min) {\r\n      query += ` and (min-width: ${this.min}px)`;\r\n    }\r\n    if (this.max) {\r\n      query += ` and (max-width: ${this.max}px)`;\r\n    }\r\n    return query;\r\n  }\r\n}\r\n\r\nexport class StringResponsive extends StringModule {\r\n  private queries: { [key in DeviceType]: StringResponsiveQueryDevice } = {\r\n    [DeviceType.Mobile]: new StringResponsiveQueryDevice({ max: 359 }),\r\n    [DeviceType.Tablet]: new StringResponsiveQueryDevice({\r\n      min: 360,\r\n      max: 1023,\r\n    }),\r\n    [DeviceType.Laptop]: new StringResponsiveQueryDevice({\r\n      min: 1024,\r\n      max: 1365,\r\n    }),\r\n    [DeviceType.Desktop]: new StringResponsiveQueryDevice({ min: 1366 }),\r\n  };\r\n\r\n  private isMobileMedia: boolean = false;\r\n  private isTabletMedia: boolean = false;\r\n  private isLaptopMedia: boolean = false;\r\n  private isDesktopMedia: boolean = false;\r\n\r\n  private matchMedias: { [key in DeviceType]: MediaQueryList } = {\r\n    [DeviceType.Mobile]: window.matchMedia(this.queries[DeviceType.Mobile].mediaQuery),\r\n    [DeviceType.Tablet]: window.matchMedia(this.queries[DeviceType.Tablet].mediaQuery),\r\n    [DeviceType.Laptop]: window.matchMedia(this.queries[DeviceType.Laptop].mediaQuery),\r\n    [DeviceType.Desktop]: window.matchMedia(this.queries[DeviceType.Desktop].mediaQuery),\r\n  };\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this._type = 2;\r\n  }\r\n\r\n  onConnect() {}\r\n\r\n  onInit(): void {\r\n    if (this.settings != null) {\r\n      if (this.settings[\"settings\"] != null) {\r\n        let config = this.settings[\"settings\"];\r\n        if (config.mobile) {\r\n          this.queries[DeviceType.Mobile].enable = true;\r\n          this.queries[DeviceType.Mobile].setRange(\r\n            config.mobile.min == undefined ? null : config.mobile.min,\r\n            config.mobile.max ?? null\r\n          );\r\n          this.matchMedias[DeviceType.Mobile] = window.matchMedia(\r\n            this.queries[DeviceType.Mobile].mediaQuery\r\n          );\r\n        } else {\r\n          this.queries[DeviceType.Mobile].enable = false;\r\n        }\r\n\r\n        if (config.tablet) {\r\n          this.queries[DeviceType.Tablet].enable = true;\r\n          this.queries[DeviceType.Tablet].setRange(\r\n            config.tablet.min == undefined ? null : config.tablet.min,\r\n            config.tablet.max ?? null\r\n          );\r\n          this.matchMedias[DeviceType.Tablet] = window.matchMedia(\r\n            this.queries[DeviceType.Tablet].mediaQuery\r\n          );\r\n        } else {\r\n          this.queries[DeviceType.Tablet].enable = false;\r\n        }\r\n\r\n        if (config.laptop) {\r\n          this.queries[DeviceType.Laptop].enable = true;\r\n          this.queries[DeviceType.Laptop].setRange(\r\n            config.laptop.min == undefined ? null : config.laptop.min,\r\n            config.laptop.max ?? null\r\n          );\r\n          this.matchMedias[DeviceType.Laptop] = window.matchMedia(\r\n            this.queries[DeviceType.Laptop].mediaQuery\r\n          );\r\n        } else {\r\n          this.queries[DeviceType.Laptop].enable = false;\r\n        }\r\n\r\n        if (config.desktop) {\r\n          this.queries[DeviceType.Desktop].enable = true;\r\n          this.queries[DeviceType.Desktop].setRange(\r\n            config.desktop.min == undefined ? null : config.desktop.min,\r\n            config.desktop.max ?? null\r\n          );\r\n          this.matchMedias[DeviceType.Desktop] = window.matchMedia(\r\n            this.queries[DeviceType.Desktop].mediaQuery\r\n          );\r\n        } else {\r\n          this.queries[DeviceType.Desktop].enable = false;\r\n        }\r\n      }\r\n    }\r\n    this.updateElements();\r\n  }\r\n\r\n  onResize(): void {\r\n    this.updateElements();\r\n  }\r\n\r\n  private updateElements() {\r\n    const isMobileMedia =\r\n      this.matchMedias[DeviceType.Mobile].matches && this.queries[DeviceType.Mobile].enable;\r\n    const isTabletMedia =\r\n      this.matchMedias[DeviceType.Tablet].matches && this.queries[DeviceType.Tablet].enable;\r\n    const isLaptopMedia =\r\n      this.matchMedias[DeviceType.Laptop].matches && this.queries[DeviceType.Laptop].enable;\r\n    const isDesktopMedia =\r\n      this.matchMedias[DeviceType.Desktop].matches && this.queries[DeviceType.Desktop].enable;\r\n\r\n    if (this.isMobileMedia != isMobileMedia) {\r\n      this.events.emit(\"screen:mobile\", isMobileMedia);\r\n    }\r\n    if (this.isTabletMedia != isTabletMedia) {\r\n      this.events.emit(\"screen:tablet\", isTabletMedia);\r\n    }\r\n    if (this.isLaptopMedia != isLaptopMedia) {\r\n      this.events.emit(\"screen:laptop\", isLaptopMedia);\r\n    }\r\n    if (this.isDesktopMedia != isDesktopMedia) {\r\n      this.events.emit(\"screen:desktop\", isDesktopMedia);\r\n    }\r\n\r\n    this.isMobileMedia = isMobileMedia;\r\n    this.isTabletMedia = isTabletMedia;\r\n    this.isLaptopMedia = isLaptopMedia;\r\n    this.isDesktopMedia = isDesktopMedia;\r\n\r\n    const elements = document.querySelectorAll(\r\n      \"[string-mobile], [string-tablet], [string-laptop], [string-desktop]\"\r\n    );\r\n\r\n    elements.forEach((element: any) => {\r\n      let showElement = false;\r\n\r\n      if (element.hasAttribute(\"string-mobile\") && isMobileMedia) {\r\n        showElement = true;\r\n      }\r\n      if (element.hasAttribute(\"string-tablet\") && isTabletMedia) {\r\n        showElement = true;\r\n      }\r\n      if (element.hasAttribute(\"string-laptop\") && isLaptopMedia) {\r\n        showElement = true;\r\n      }\r\n      if (element.hasAttribute(\"string-desktop\") && isDesktopMedia) {\r\n        showElement = true;\r\n      }\r\n\r\n      if (showElement) {\r\n        element.style.display = null;\r\n      } else {\r\n        element.style.display = `none`;\r\n      }\r\n    });\r\n  }\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\n\r\n/**\r\n * The `StringAnchor` class extends the `StringModule` class and is responsible for\r\n * managing anchor-related functionality within the string module system.\r\n *\r\n * This class maps an `anchor` attribute to a tuple containing x and y coordinates,\r\n * processes these coordinates using the `originParser` tool, and applies the resulting\r\n * values to the connected object's element as a CSS `transform-origin` style.\r\n */\r\nexport class StringAnchor extends StringModule {\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"anchor\";\r\n    this.attributesToMap = [\r\n      ...this.attributesToMap,\r\n      {\r\n        key: \"anchor\",\r\n        type: \"tuple\",\r\n        fallback: this.settings[\"anchor\"],\r\n        transform: (tuple: string[]) => {\r\n          const [xRaw, yRaw] = tuple;\r\n          const x = this.tools.originParser.process({ value: xRaw });\r\n          const y = this.tools.originParser.process({ value: yRaw });\r\n          return { x, y };\r\n        },\r\n      },\r\n    ];\r\n  }\r\n  onObjectConnected(object: StringObject) {\r\n    super.onObjectConnected(object);\r\n    const anchor = object.getProperty<{ x: string; y: string }>(\"anchor\");\r\n    if (anchor) {\r\n      this.applyToElementAndConnects(object, (el) => {\r\n        el.style.transformOrigin = `${anchor.x} ${anchor.y}`;\r\n      });\r\n    }\r\n  }\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringData } from \"../../core/StringData\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { styleTxn } from \"../../utils/style-txn\";\r\n\r\nconst ACCELERATION_STEP: number = 0.05;\r\nconst MIN_DISPLACEMENT: number = 0.01;\r\nconst MAX_DISPLACEMENT: number = 1;\r\nconst MIN_VELOCITY: number = -1;\r\nconst MAX_VELOCITY: number = 1;\r\n\r\n/**\r\n * The `StringGlide` class is a module that handles the glide effect for string objects\r\n * based on scroll events. It calculates displacement, acceleration, and velocity\r\n * to create a smooth scrolling effect for objects.\r\n */\r\nexport class StringGlide extends StringModule {\r\n  protected defaultModeScope = [\"smooth\"];\r\n  private previousLerp: number = 0;\r\n  private displacement: number = 0;\r\n  private acceleration: number = 0;\r\n  private velocityMultiplier: number = 0.00125;\r\n  private isInitialScroll: boolean = true;\r\n\r\n  private baseVelocityMultiplier: number = 0.00125;\r\n  private reducedVelocityMultiplier: number = this.baseVelocityMultiplier / 20;\r\n  private negativeVelocityMultiplier: number = -0.0001;\r\n\r\n  private maxDisplacementValue: number = 0;\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"glide\";\r\n\r\n    this.cssProperties = [\r\n      { name: \"--glide\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n    ];\r\n\r\n    this.baseVelocityMultiplier =\r\n      this.settings[\"glide-base-velocity\"] ?? this.baseVelocityMultiplier;\r\n    this.reducedVelocityMultiplier =\r\n      this.settings[\"glide-reduce-velocity\"] ?? this.reducedVelocityMultiplier;\r\n    this.negativeVelocityMultiplier =\r\n      this.settings[\"glide-negative-velocity\"] ?? this.negativeVelocityMultiplier;\r\n\r\n    this.attributesToMap = [\r\n      ...this.attributesToMap,\r\n      { key: \"glide\", type: \"number\", fallback: this.settings[\"glide\"] },\r\n    ];\r\n  }\r\n\r\n  override initializeObject(\r\n    globalId: number,\r\n    object: StringObject,\r\n    element: HTMLElement,\r\n    attributes: Record<string, any>,\r\n  ): void {\r\n    super.initializeObject(globalId, object, element, attributes);\r\n    object.setProperty<number>(\"glide-value\", object.getProperty<number>(\"glide\") ?? 0);\r\n    object.setProperty<string>(\"event-glide-name\", this.getObjectEventName(object, \"object:glide\"));\r\n    object.setProperty(\"__next-glide\", 0);\r\n    object.setProperty(\"__next-glide-transform\", \"translate3d(0, 0px, 0)\");\r\n    object.setProperty(\"__needs-glide-var-update\", false);\r\n    object.setProperty(\"__needs-glide-transform-update\", false);\r\n  }\r\n\r\n  private setupItem = (object: StringObject) => {\r\n    const glideFactor = object.getProperty<number>(\"glide-value\") ?? 0;\r\n    const glideValue = -this.data.scroll.displacement * this.maxDisplacementValue * glideFactor;\r\n\r\n    const eventName = object.getProperty<string>(\"event-glide-name\");\r\n    if (eventName) {\r\n      this.events.emit(eventName, glideValue);\r\n    }\r\n\r\n    const transformCompute = `translate3d(0, ${glideValue}px, 0)`;\r\n    object.setProperty(\"__next-glide-transform\", transformCompute);\r\n    object.setProperty(\"__needs-glide-transform-update\", true);\r\n  };\r\n\r\n  private updateTransforms(): void {\r\n    for (let i = 0; i < this.objects.length; i++) {\r\n      this.setupItem(this.objects[i]);\r\n    }\r\n  }\r\n\r\n  private resetObjectStyles(objects: StringObject[]): void {\r\n    for (let i = 0; i < objects.length; i++) {\r\n      const object = objects[i];\r\n      object.setProperty(\"__next-glide-transform\", \"translate3d(0, 0px, 0)\");\r\n      object.setProperty(\"__needs-glide-transform-update\", true);\r\n      object.setProperty(\"__next-glide\", 0);\r\n      object.setProperty(\"__needs-glide-var-update\", true);\r\n    }\r\n  }\r\n\r\n  private calcExpanderFactor(isDirectionUp: boolean): void {\r\n    const isConditionMet = isDirectionUp\r\n      ? this.data.scroll.lerped < this.previousLerp\r\n      : this.data.scroll.lerped > this.previousLerp;\r\n\r\n    this.velocityMultiplier = isConditionMet\r\n      ? this.isInitialScroll\r\n        ? this.baseVelocityMultiplier\r\n        : this.reducedVelocityMultiplier\r\n      : this.negativeVelocityMultiplier;\r\n\r\n    if (!isConditionMet) {\r\n      this.isInitialScroll = false;\r\n    }\r\n  }\r\n  onStart(): void {\r\n    this.maxDisplacementValue = this.data.viewport.windowHeight * 0.1;\r\n  }\r\n\r\n  onResize(): void {\r\n    this.maxDisplacementValue = this.data.viewport.windowHeight * 0.1;\r\n  }\r\n\r\n  private resetState(): void {\r\n    this.displacement = 0;\r\n    this.acceleration = 0;\r\n    this.isInitialScroll = true;\r\n    this.velocityMultiplier = this.baseVelocityMultiplier;\r\n  }\r\n\r\n  onScrollStart(): void {\r\n    this.resetState();\r\n  }\r\n\r\n  onScrollStop(): void {\r\n    this.resetState();\r\n    this.previousLerp = 0;\r\n    this.data.scroll.displacement = 0;\r\n\r\n    this.resetObjectStyles(this.objects);\r\n    this.flushPendingGlideStyles();\r\n  }\r\n\r\n  onFrame(data: StringData): void {\r\n    this.calcExpanderFactor(this.data.scroll.isScrollingDown === false);\r\n    this.acceleration = Math.min(MAX_DISPLACEMENT, this.acceleration + ACCELERATION_STEP);\r\n    this.displacement = Math.max(\r\n      MIN_DISPLACEMENT,\r\n      Math.min(MAX_DISPLACEMENT, this.displacement + this.velocityMultiplier),\r\n    );\r\n    this.data.scroll.displacement = Math.min(\r\n      MAX_VELOCITY,\r\n      Math.max(MIN_VELOCITY, this.data.scroll.lerped * this.displacement * this.acceleration),\r\n    );\r\n\r\n    const dispNum = this.data.scroll.displacement;\r\n\r\n    for (let i = 0; i < this.objects.length; i++) {\r\n      const object = this.objects[i];\r\n      object.setProperty(\"__next-glide\", dispNum);\r\n      object.setProperty(\"__needs-glide-var-update\", true);\r\n    }\r\n    this.previousLerp = this.data.scroll.lerped;\r\n    this.updateTransforms();\r\n  }\r\n\r\n  protected override onObjectModeDeactivated(object: StringObject): void {\r\n    super.onObjectModeDeactivated(object);\r\n    this.resetObjectStyles([object]);\r\n    styleTxn.run(() => {\r\n      this.applyPendingGlideStylesForObject(object);\r\n    });\r\n  }\r\n\r\n  override onMutate(): void {\r\n    this.applyPendingGlideStyles();\r\n  }\r\n\r\n  private applyPendingGlideStylesForObject(object: StringObject): void {\r\n    const glideValue = object.getProperty<number>(\"__next-glide\") ?? 0;\r\n    const transform =\r\n      object.getProperty<string>(\"__next-glide-transform\") ?? \"translate3d(0, 0px, 0)\";\r\n\r\n    this.applyVarToElement(object, \"--glide\", glideValue);\r\n    this.applyVarToConnects(object, \"--glide\", glideValue);\r\n    this.applyPropToElement(object, \"transform\", transform);\r\n    object.setProperty(\"__needs-glide-var-update\", false);\r\n    object.setProperty(\"__needs-glide-transform-update\", false);\r\n  }\r\n\r\n  private applyPendingGlideStyles(): void {\r\n    for (let i = 0; i < this.objects.length; i++) {\r\n      const object = this.objects[i];\r\n\r\n      const needsVarUpdate = object.getProperty<boolean>(\"__needs-glide-var-update\") === true;\r\n      const needsTransformUpdate =\r\n        object.getProperty<boolean>(\"__needs-glide-transform-update\") === true;\r\n\r\n      if (!needsVarUpdate && !needsTransformUpdate) {\r\n        continue;\r\n      }\r\n\r\n      if (needsVarUpdate) {\r\n        const glideValue =\r\n          object.getProperty<number>(\"__next-glide\") ?? this.data.scroll.displacement;\r\n        this.applyVarToElement(object, \"--glide\", glideValue);\r\n        this.applyVarToConnects(object, \"--glide\", glideValue);\r\n        object.setProperty(\"__needs-glide-var-update\", false);\r\n      }\r\n\r\n      if (needsTransformUpdate) {\r\n        const transform =\r\n          object.getProperty<string>(\"__next-glide-transform\") ?? \"translate3d(0, 0px, 0)\";\r\n        this.applyPropToElement(object, \"transform\", transform);\r\n        object.setProperty(\"__needs-glide-transform-update\", false);\r\n      }\r\n    }\r\n  }\r\n\r\n  private flushPendingGlideStyles(): void {\r\n    if (styleTxn.isOpen) {\r\n      this.applyPendingGlideStyles();\r\n      return;\r\n    }\r\n    styleTxn.run(() => {\r\n      this.applyPendingGlideStyles();\r\n    });\r\n  }\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringData } from \"../../core/StringData\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringMirrorObject } from \"../../objects/StringMirrorObject\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { styleTxn } from \"../../utils/style-txn\";\r\n\r\n/**\r\n * Module that updates the `--lerp` CSS variable on elements\r\n * based on current scroll velocity.\r\n */\r\nexport class StringLerp extends StringModule {\r\n  private hasInitializedCSS = false;\r\n  protected defaultModeScope = [\"smooth\"];\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"lerp\";\r\n\r\n    this.cssProperties = [\r\n      { name: \"--lerp\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n    ];\r\n\r\n    this.attributesToMap = [];\r\n  }\r\n\r\n  /**\r\n   * Initialize lerp value when object connects.\r\n   */\r\n  onObjectConnected(object: StringObject): void {\n    super.onObjectConnected(object);\n    object.setProperty<number>(\"lerp-value\", 0);\n    object.setProperty<number>(\"lerp-applied\", 0);\n    object.setProperty<string>(\"event-lerp-name\", this.getObjectEventName(object, \"object:lerp\"));\n  }\n\r\n  /**\r\n   * Called on resize - use this to apply initial values after mirrors are created.\r\n   */\r\n  onResize(): void {\r\n    super.onResize();\r\n    // Only apply initial CSS on first resize (after mirrors are created)\r\n    if (!this.hasInitializedCSS && this.objectsOnPage.length > 0) {\r\n      this.hasInitializedCSS = true;\r\n      styleTxn.run(() => {\r\n        for (let i = 0; i < this.objectsOnPage.length; i++) {\r\n          this.updateObjectLerp(this.objectsOnPage[i], true);\r\n        }\r\n      });\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Resets the `--lerp` value to 0 when scroll stops.\r\n   */\r\n  onScrollStop(): void {\r\n    for (let i = 0; i < this.objects.length; i++) {\r\n      this.recomputeLerp(this.objects[i], 0);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Updates `--lerp` value for each connected object during scroll.\r\n   */\r\n  onFrame(data: StringData): void {\r\n    const velocity = data.scroll.lerped;\r\n    for (let i = 0; i < this.objects.length; i++) {\r\n      this.recomputeLerp(this.objects[i], velocity);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Computes the lerp value for the object.\r\n   */\r\n  private recomputeLerp(object: StringObject, velocity: number): void {\n    const prevLerp = object.getProperty<number>(\"lerp-value\") ?? 0;\n\r\n    if (prevLerp === velocity) {\r\n      return;\r\n    }\r\n\r\n    object.setProperty<number>(\"lerp-value\", velocity);\n    this.updateObjectLerp(object);\n  }\n\r\n  /**\r\n   * Applies the lerp value to the object and its mirrors.\r\n   */\r\n  onMutate(): void {\r\n    styleTxn.run(() => {\r\n      const len = this.objects.length;\r\n      for (let i = 0; i < len; i++) {\r\n        this.updateObjectLerp(this.objects[i]);\r\n      }\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Updates the CSS variable on the object and connected elements.\r\n   */\r\n  private updateObjectLerp(object: StringObject, force = false): void {\n    const lerp = object.getProperty<number>(\"lerp-value\") ?? 0;\n    const prevLerp = object.getProperty<number>(\"lerp-applied\");\r\n\r\n    if (!force && prevLerp === lerp) {\r\n      return;\r\n    }\r\n\r\n    object.setProperty<number>(\"lerp-applied\", lerp);\r\n\r\n    const lerpStr = lerp?.toString() ?? \"0\";\r\n\r\n    const eventName = object.getProperty<string>(\"event-lerp-name\");\n    if (eventName) {\n      this.events.emit(eventName, lerp);\n    }\n\r\n    styleTxn.run(() => {\r\n      this.applyVarToElement(object, \"--lerp\", lerpStr);\r\n      this.applyVarToConnects(object, \"--lerp\", lerpStr);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Cleans up the CSS variable when object is disconnected.\r\n   */\r\n  onObjectDisconnected(object: StringObject): void {\r\n    super.onObjectDisconnected(object);\r\n\r\n    const clearCustomProperty = (el: HTMLElement) => {\r\n      el.style.removeProperty(\"--lerp\");\r\n    };\r\n\r\n    clearCustomProperty(object.htmlElement);\r\n    const mirrors = object.mirrorObjects;\r\n    for (let i = 0; i < mirrors.length; i++) {\r\n      clearCustomProperty(mirrors[i].htmlElement);\r\n    }\r\n  }\r\n}\r\n","﻿import { StringContext } from \"../../core/StringContext\";\r\nimport { StringData } from \"../../core/StringData\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringMirrorObject } from \"../../objects/StringMirrorObject\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { EasingFunctionOutput } from \"../../tools/EasingFunctionTool\";\r\nimport { styleTxn } from \"../../utils/style-txn\";\r\n\r\nexport const STRING_DEV_PROGRESS_OVERRIDE_KEY = \"__string-dev-progress-override\";\r\n\r\ntype ProgressComputeKernel = {\r\n  computeRawProgress(scroll: number, start: number, difference: number): number;\r\n  computeRawProgressBatch(\r\n    scroll: number,\r\n    starts: Float64Array,\r\n    differences: Float64Array,\r\n    out: Float64Array,\r\n    length: number,\r\n  ): void;\r\n};\r\n\r\nconst DEFAULT_PROGRESS_KERNEL: ProgressComputeKernel = {\r\n  computeRawProgress(scroll: number, start: number, difference: number): number {\r\n    if (difference === 0) return 0;\r\n    const raw = (scroll - start) / difference;\r\n    if (raw <= 0) return 0;\r\n    if (raw >= 1) return 1;\r\n    return raw;\r\n  },\r\n  computeRawProgressBatch(\r\n    scroll: number,\r\n    starts: Float64Array,\r\n    differences: Float64Array,\r\n    out: Float64Array,\r\n    length: number,\r\n  ): void {\r\n    for (let i = 0; i < length; i++) {\r\n      const diff = differences[i];\r\n      if (diff === 0) {\r\n        out[i] = 0;\r\n        continue;\r\n      }\r\n      const raw = (scroll - starts[i]) / diff;\r\n      if (raw <= 0) out[i] = 0;\r\n      else if (raw >= 1) out[i] = 1;\r\n      else out[i] = raw;\r\n    }\r\n  },\r\n};\r\n\r\nexport class StringProgress extends StringModule {\r\n  protected updateScheduled = false;\r\n  private batchStarts: Float64Array = new Float64Array(0);\r\n  private batchDiffs: Float64Array = new Float64Array(0);\r\n  private batchOut: Float64Array = new Float64Array(0);\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"progress\";\r\n\r\n    this.cssProperties = [\r\n      { name: \"--progress\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n      { name: \"--progress-slice\", syntax: \"<number>\", initialValue: \"0\", inherits: true },\r\n    ];\r\n\r\n    this.attributesToMap = [\r\n      ...this.attributesToMap,\r\n      { key: \"easing\", type: \"easing\", fallback: this.settings[\"easing\"] },\r\n    ];\r\n  }\r\n\r\n  initializeObject(\r\n    globalId: number,\r\n    object: StringObject,\r\n    element: HTMLElement,\r\n    attributes: Record<string, any>,\r\n  ): void {\r\n    super.initializeObject(globalId, object, element, attributes);\r\n  }\r\n\r\n  private sanitizeRawProgress(rawProgress: number): number {\r\n    if (!Number.isFinite(rawProgress)) return 0;\r\n    if (rawProgress <= 0) return 0;\r\n    if (rawProgress >= 1) return 1;\r\n    const EPS = 1e-4;\r\n    if (rawProgress > 1 - EPS) rawProgress = 1;\r\n    else if (rawProgress < EPS) rawProgress = 0;\r\n    return rawProgress;\r\n  }\r\n\r\n  private resolveRawProgress(\r\n    object: StringObject,\r\n    scroll: number,\r\n    startPosition: number,\r\n    differencePosition: number,\r\n  ): number {\r\n    const overrideRawProgress = object.getProperty<number | null>(STRING_DEV_PROGRESS_OVERRIDE_KEY);\r\n    if (overrideRawProgress != null) {\r\n      return this.sanitizeRawProgress(overrideRawProgress);\r\n    }\r\n\r\n    return DEFAULT_PROGRESS_KERNEL.computeRawProgress(scroll, startPosition, differencePosition);\r\n  }\r\n\r\n  private applyRawProgress(object: StringObject, rawProgress: number): void {\r\n    const normalizedRaw = this.sanitizeRawProgress(rawProgress);\r\n\r\n    const prevRawProgress = object.getProperty<number>(\"progress-raw\") ?? 0;\r\n\r\n    if (prevRawProgress === normalizedRaw) {\r\n      return;\r\n    }\r\n\r\n    object.setProperty(\"progress-raw\", normalizedRaw);\r\n\r\n    const easing = object.getProperty<EasingFunctionOutput>(\"easing\");\r\n    const progress = typeof easing === \"function\" ? easing(normalizedRaw) : normalizedRaw;\r\n\r\n    object.setProperty(\"progress-value\", progress);\r\n  }\r\n\r\n  private recomputeProgress(object: StringObject): void {\r\n    const startPosition =\r\n      object.getProperty<number>(\"start-position\") ??\r\n      object.getProperty<number>(\"progress-start-position\") ??\r\n      0;\r\n    const differencePosition =\r\n      object.getProperty<number>(\"difference-position\") ??\r\n      object.getProperty<number>(\"progress-difference-position\") ??\r\n      0;\r\n\r\n    object.setProperty(\"progress-start-position\", startPosition);\r\n    object.setProperty(\"progress-difference-position\", differencePosition);\r\n\r\n    const rawProgress = this.resolveRawProgress(\r\n      object,\r\n      this.data.scroll.transformedCurrent,\r\n      startPosition,\r\n      differencePosition,\r\n    );\r\n\r\n    this.applyRawProgress(object, rawProgress);\r\n  }\r\n\r\n  private ensureBatchCapacity(length: number): void {\r\n    if (this.batchStarts.length >= length) return;\r\n    this.batchStarts = new Float64Array(length);\r\n    this.batchDiffs = new Float64Array(length);\r\n    this.batchOut = new Float64Array(length);\r\n  }\r\n\r\n  calculatePositions(object: StringObject, windowSize: number) {\r\n    super.calculatePositions(object, windowSize);\r\n    object.setProperty(\r\n      \"progress-start-position\",\r\n      object.getProperty<number>(\"start-position\") ??\r\n        object.getProperty<number>(\"progress-start-position\") ??\r\n        0,\r\n    );\r\n    object.setProperty(\r\n      \"progress-difference-position\",\r\n      object.getProperty<number>(\"difference-position\") ??\r\n        object.getProperty<number>(\"progress-difference-position\") ??\r\n        0,\r\n    );\r\n    this.recomputeProgress(object);\r\n  }\r\n\r\n  onScroll(data: StringData): void {\r\n    super.onScroll(data);\r\n  }\r\n\r\n  onObjectConnected(object: StringObject) {\r\n    super.onObjectConnected(object);\r\n  }\r\n\r\n  onScrollMeasure(data: StringData) {\r\n    const len = this.objects.length;\r\n    if (len === 0) return;\r\n\r\n    this.ensureBatchCapacity(len);\r\n    for (let i = 0; i < len; i++) {\r\n      const object = this.objects[i];\r\n      const startPosition =\r\n        object.getProperty<number>(\"start-position\") ??\r\n        object.getProperty<number>(\"progress-start-position\") ??\r\n        0;\r\n      const differencePosition =\r\n        object.getProperty<number>(\"difference-position\") ??\r\n        object.getProperty<number>(\"progress-difference-position\") ??\r\n        0;\r\n      object.setProperty(\"progress-start-position\", startPosition);\r\n      object.setProperty(\"progress-difference-position\", differencePosition);\r\n      this.batchStarts[i] = startPosition;\r\n      this.batchDiffs[i] = differencePosition;\r\n    }\r\n\r\n    DEFAULT_PROGRESS_KERNEL.computeRawProgressBatch(\r\n      this.data.scroll.transformedCurrent,\r\n      this.batchStarts,\r\n      this.batchDiffs,\r\n      this.batchOut,\r\n      len,\r\n    );\r\n\r\n    for (let i = 0; i < len; i++) {\r\n      const object = this.objects[i];\r\n      const overrideRawProgress = object.getProperty<number | null>(\r\n        STRING_DEV_PROGRESS_OVERRIDE_KEY,\r\n      );\r\n      const rawProgress =\r\n        overrideRawProgress != null\r\n          ? this.sanitizeRawProgress(overrideRawProgress)\r\n          : this.batchOut[i];\r\n      this.applyRawProgress(object, rawProgress);\r\n    }\r\n  }\r\n\r\n  onMutate() {\r\n    styleTxn.run(() => {\r\n      const len = this.objects.length;\r\n      for (let i = 0; i < len; i++) {\r\n        this.updateObjectProgress(this.objects[i]);\r\n      }\r\n    });\r\n  }\r\n\r\n  private updateObjectProgress(object: StringObject): void {\r\n    const progress = object.getProperty<number>(\"progress-value\") ?? 0;\r\n    const prevProgress = object.getProperty<number>(\"progress-applied\");\r\n\r\n    if (prevProgress === progress) {\r\n      return;\r\n    }\r\n    const key = object.getProperty<string>(\"key\");\r\n    object.setProperty<number>(\"progress-applied\", progress);\r\n    const rawProgress = object.getProperty<number>(\"progress-raw\") ?? progress;\r\n    const parentEasing = object.getProperty<EasingFunctionOutput>(\"easing\");\r\n\r\n    const eventName =\r\n      object.getProperty<string>(\"event-progress-name\") ??\r\n      object.getScopedEventName(\"object:progress\");\r\n    object.setProperty(\"event-progress-name\", eventName);\r\n    if (eventName) {\r\n      this.events.emit(eventName, progress);\r\n    }\r\n\r\n    if (key) {\r\n      this.applyVarToElement(object, key, progress);\r\n    }\r\n\r\n    // Handle mirrors\r\n    for (let i = 0; i < object.mirrorObjects.length; i++) {\r\n      const mirror = object.mirrorObjects[i];\r\n      const eased = mirror.applyProgress(\r\n        rawProgress,\r\n        typeof parentEasing === \"function\" ? parentEasing : undefined,\r\n      );\r\n      mirror.setProperty(\"progress\", eased);\r\n      if (key) {\r\n        this.tools.styleTxn.setVar(mirror.htmlElement, key, eased);\r\n      }\r\n    }\r\n  }\r\n\r\n  onObjectDisconnected(object: StringObject): void {\r\n    super.onObjectDisconnected(object);\r\n    const key = object.getProperty<string>(\"key\");\r\n    if (!key) return;\r\n\r\n    const clearCustomProperty = (el: HTMLElement) => {\r\n      el.style.removeProperty(key);\r\n    };\r\n\r\n    clearCustomProperty(object.htmlElement);\r\n    const mirrors = object.mirrorObjects;\r\n    for (let i = 0; i < mirrors.length; i++) {\r\n      clearCustomProperty(mirrors[i].htmlElement);\r\n    }\r\n  }\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringData } from \"../../core/StringData\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { frameDOM } from \"../../utils/frame-dom\";\r\nimport { styleTxn } from \"../../utils/style-txn\";\r\nimport { StringProgress } from \"./StringProgress\";\r\n\r\ntype ParallaxTransformResult = { transform: string };\r\n\r\n/**\r\n * The `StringParallax` class extends the `StringProgress` class to provide\r\n * functionality for handling parallax effects on scrollable elements.\r\n * It maps specific attributes related to parallax and calculates the\r\n * necessary transformations based on scroll progress and viewport size.\r\n */\r\nexport class StringParallax extends StringProgress {\r\n  protected defaultModeScope = [\"smooth\"];\r\n  private updateScheduledTransform = false;\r\n  private calculateParallaxForObject: (object: StringObject) => ParallaxTransformResult | null;\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"parallax\";\r\n\r\n    this.attributesToMap = [\r\n      ...this.attributesToMap,\r\n      { key: \"parallax\", type: \"number\", fallback: this.settings[\"parallax\"] },\r\n      {\r\n        key: \"parallax-bias\",\r\n        type: \"number\",\r\n        fallback: this.settings[\"parallax-bias\"],\r\n      },\r\n    ];\r\n\r\n    this.calculateParallaxForObject = this.calculateParallax;\r\n  }\r\n\r\n  /**\r\n   * Called when an object is initialized.\r\n   */\r\n  override initializeObject(\r\n    globalId: number,\r\n    object: StringObject,\r\n    element: HTMLElement,\r\n    attributes: Record<string, any>,\r\n  ): void {\r\n    super.initializeObject(globalId, object, element, attributes);\r\n    const bias = object.getProperty<number>(\"parallax-bias\") ?? 0.0;\r\n    const factor = Math.abs(object.getProperty<number>(\"parallax\") ?? 0.2);\r\n    object.setProperty(\"parallax-sign\", Math.sign(object.getProperty<number>(\"parallax\")));\r\n    object.setProperty<number>(\"parallax\", factor);\r\n    object.setProperty(\"parallax-position-start\", -0.5 + 0.5 * bias);\r\n    object.setProperty(\"parallax-position-end\", 0.5 + 0.5 * (1 - bias));\r\n\r\n    const screenSize = this.data.viewport.windowHeight;\r\n\r\n    object.setProperty(\"offset-top\", factor * screenSize);\r\n    object.setProperty(\"offset-bottom\", factor * screenSize);\r\n  }\r\n\r\n  calculatePositions(object: StringObject, windowSize: number) {\r\n    super.calculatePositions(object, windowSize);\r\n    object.setProperty(\"parallax-transform-value\", this.calculateParallaxForObject(object));\r\n  }\r\n\r\n  override onScroll(data: StringData): void {\r\n    super.onScroll(data);\r\n  }\r\n\r\n  onScrollMeasure(data: StringData) {\r\n    super.onScrollMeasure(data);\r\n\r\n    // We can avoid closures by iterating manually\r\n    for (let i = 0; i < this.objects.length; i++) {\r\n      const object = this.objects[i];\r\n      object.setProperty(\"parallax-transform-value\", this.calculateParallaxForObject(object));\r\n    }\r\n  }\r\n\r\n  onMutate() {\r\n    styleTxn.run(() => {\r\n      for (let i = 0; i < this.objects.length; i++) {\r\n        const object = this.objects[i];\r\n        const progress = object.getProperty<number>(\"progress-value\") ?? 0;\r\n        const appliedProgress = object.getProperty<number>(\"parallax-progress-applied\");\r\n        if (appliedProgress !== progress) {\r\n          object.setProperty(\"parallax-transform-value\", this.calculateParallaxForObject(object));\r\n          object.setProperty(\"parallax-progress-applied\", progress);\r\n        }\r\n\r\n        const transformData = object.getProperty<ParallaxTransformResult | null>(\r\n          \"parallax-transform-value\",\r\n        );\r\n\r\n        if (transformData) {\r\n          this.applyPropToElement(object, \"transform\", transformData.transform);\r\n          this.applyPropToConnects(object, \"transform\", transformData.transform);\r\n        }\r\n      }\r\n    });\r\n  }\r\n\r\n  private calculateParallax = (object: StringObject): ParallaxTransformResult => {\r\n    const progress = object.getProperty<number>(\"progress-value\") ?? 0;\r\n    const factor = object.getProperty<number>(\"parallax\") ?? 0;\r\n    const start = object.getProperty<number>(\"parallax-position-start\") ?? 0;\r\n    const end = object.getProperty<number>(\"parallax-position-end\") ?? 1;\r\n    const sign = object.getProperty<number>(\"parallax-sign\") ?? 1;\r\n\r\n    const screenSize = this.data.viewport.windowHeight / this.data.viewport.transformScale;\r\n    const translation = sign * factor * (screenSize * start + progress * screenSize * end);\r\n\r\n    this.events.emit(this.getObjectEventName(object, \"object:parallax\"), translation);\r\n\r\n    return { transform: `translate3d(0, ${translation}px, 0)` };\r\n  };\r\n}\r\n","import { StringData } from \"../../core/StringData\";\r\n\r\nexport class StringScrollbarHorizontal {\r\n  private scrollbar: any;\r\n  private thumb: any;\r\n  private isDragging = false;\r\n  private onScrollTo: (position: number) => void;\r\n  private startY: number = 0;\r\n  private startScrollPosition: number = 0;\r\n  data: StringData;\r\n\r\n  /**\r\n   * @param data Shared scroll/viewport data.\r\n   * @param scrollbar The scrollbar track element.\r\n   * @param thumb The scrollbar thumb element.\r\n   * @param onScrollTo Called on thumb drag with the target position in px.\r\n   *   This maps directly to `ScrollController.scrollTo()` on the active adapter —\r\n   *   custom adapters must implement `scrollTo()` to sync their internal state.\r\n   */\r\n  constructor(\r\n    data: StringData,\r\n    scrollbar: any,\r\n    thumb: any,\r\n    onScrollTo: (position: number) => void,\r\n  ) {\r\n    this.data = data;\r\n    this.scrollbar = scrollbar;\r\n    this.thumb = thumb;\r\n    this.onScrollTo = onScrollTo;\r\n  }\r\n\r\n  onResize(): void {\r\n    const contentWidth = this.data.viewport.contentWidth;\r\n    const visibleWidth = this.data.viewport.windowWidth;\r\n\r\n    const thumbSize = (visibleWidth / contentWidth) * visibleWidth;\r\n    this.thumb.style.setProperty('--size', thumbSize + 'px');\r\n\r\n    if (contentWidth <= visibleWidth) {\r\n      this.scrollbar.classList.add('-hide');\r\n    } else {\r\n      this.scrollbar.classList.remove('-hide');\r\n    }\r\n  }\r\n\r\n  updateThumb() {\r\n    const contentWidth = this.data.viewport.contentWidth;\r\n    const visibleWidth = this.data.viewport.windowWidth;\r\n    this.thumb.style.setProperty('--position', `${(this.data.scroll.current / contentWidth) * visibleWidth + 'px'}`);\r\n  }\r\n\r\n  mouseDownEvent(e: MouseEvent) {\r\n    this.startY = e.clientY;\r\n    this.startScrollPosition = this.data.scroll.current;\r\n  }\r\n\r\n  mouseMoveEvent(e: MouseEvent) {\r\n    const deltaY = e.clientY - this.startY;\r\n    const newScrollPosition = this.startScrollPosition + (deltaY / this.data.viewport.windowWidth) * this.data.viewport.contentWidth;\r\n    this.data.scroll.current = newScrollPosition;\r\n    this.data.scroll.target = newScrollPosition;\r\n    this.onScrollTo(newScrollPosition);\r\n    this.updateThumb();\r\n  }\r\n}\r\n","import { StringData } from \"../../core/StringData\";\r\n\r\nexport class StringScrollbarVertical {\r\n  private scrollbar: any;\r\n  private thumb: any;\r\n  private isDragging = false;\r\n  private onScrollTo: (position: number) => void;\r\n  private startCoordinate: number = 0;\r\n  private startScrollPosition: number = 0;\r\n  data: StringData;\r\n\r\n  /**\r\n   * @param data Shared scroll/viewport data.\r\n   * @param scrollbar The scrollbar track element.\r\n   * @param thumb The scrollbar thumb element.\r\n   * @param onScrollTo Called on thumb drag with the target position in px.\r\n   *   This maps directly to `ScrollController.scrollTo()` on the active adapter —\r\n   *   custom adapters must implement `scrollTo()` to sync their internal state.\r\n   */\r\n  constructor(\r\n    data: StringData,\r\n    scrollbar: any,\r\n    thumb: any,\r\n    onScrollTo: (position: number) => void,\r\n  ) {\r\n    this.data = data;\r\n    this.scrollbar = scrollbar;\r\n    this.thumb = thumb;\r\n    this.onScrollTo = onScrollTo;\r\n  }\r\n\r\n  onResize(): void {\r\n    const contentSize = this.data.viewport.contentHeight;\r\n    const visibleSize = this.data.viewport.windowHeight;\r\n    const thumbSize = (visibleSize / contentSize) * visibleSize;\r\n    this.thumb.style.setProperty('--height', thumbSize + 'px');\r\n    if (contentSize <= visibleSize) {\r\n      this.scrollbar.classList.add('-hide');\r\n    } else {\r\n      this.scrollbar.classList.remove('-hide');\r\n    }\r\n  }\r\n\r\n  updateThumb() {\r\n    const contentHeight = this.data.viewport.contentHeight;\r\n    const visibleHeight = this.data.viewport.windowHeight;\r\n    \r\n    this.thumb.style.setProperty('--position', `${(this.data.scroll.current / contentHeight) * visibleHeight + 'px'}`);\r\n  }\r\n\r\n  mouseDownEvent(e: MouseEvent) {\r\n    this.startCoordinate = e.clientY;\r\n    this.startScrollPosition = this.data.scroll.current;\r\n  }\r\n\r\n  mouseMoveEvent(e: MouseEvent) {\r\n    const deltaY = e.clientY - this.startCoordinate;\r\n    const newScrollPosition = this.startScrollPosition + (deltaY / this.data.viewport.windowHeight) * this.data.viewport.contentHeight;\r\n    const maxScroll = this.data.scroll.bottomPosition;\r\n    const clamped = Math.max(0, Math.min(newScrollPosition, maxScroll));\r\n    this.data.scroll.current = clamped;\r\n    this.data.scroll.target = clamped;\r\n    this.onScrollTo(clamped);\r\n    this.updateThumb();\r\n  }\r\n}\r\n","import { StringContext } from '../../core/StringContext';\r\nimport { StringData } from '../../core/StringData';\r\nimport { StringModule } from '../../core/StringModule';\r\nimport { StringScrollbarHorizontal } from './StringScrollbarHorizontal';\r\nimport { StringScrollbarVertical } from './StringScrollbarVertical';\r\n\r\nexport class StringScrollbar extends StringModule {\r\n  private scrollbar: any;\r\n  private thumb: any;\r\n  private scrollTimeout: any;\r\n\r\n  private isDragging = false;\r\n  private scrollMode: 'smooth' | 'disable' | 'default' = 'smooth';\r\n\r\n  private mouseUpEventBind: any;\r\n  private mouseDownEventBind: any;\r\n  private mouseMoveEventBind: any;\r\n\r\n  private scrollbarState: any;\r\n  private scrollbarStateHorizontal: any;\r\n  private scrollbarStateVertical: any;\n  private requestScrollTo: (position: number) => void;\n\r\n  constructor(context: StringContext) {\r\n    super(context)\r\n\r\n    this.mouseUpEventBind = this.mouseUpEvent.bind(this);\n    this.mouseDownEventBind = this.mouseDownEvent.bind(this);\n    this.mouseMoveEventBind = this.mouseMoveEvent.bind(this);\n    this.requestScrollTo = (position: number) => {\n      this.events.emit(\"scrollTo\", { position, immediate: true });\n    };\n  }\n  destructor(): void {\r\n    document.removeEventListener('mouseup', this.mouseUpEventBind);\r\n    this.thumb.removeEventListener('mousedown', this.mouseDownEventBind);\r\n    document.removeEventListener('mousemove', this.mouseMoveEventBind);\r\n  }\r\n\r\n  onInit(): void {\r\n    this.createScrollbar();\r\n    this.updateThumb();\r\n    this.addCustomStyles();\r\n    document.addEventListener('mouseup', this.mouseUpEventBind);\r\n    this.thumb.addEventListener('mousedown', this.mouseDownEventBind);\r\n    document.addEventListener('mousemove', this.mouseMoveEventBind);\r\n    document.documentElement.classList.add(`-no-scrollbar`);\r\n  }\r\n\r\n  onScroll(data: StringData): void {\r\n    this.updateThumb();\r\n    this.showScrollbar();\r\n    this.hideScrollbar();\r\n  }\r\n\r\n  onResize(): void {\r\n    this.scrollbarState.onResize();\r\n  }\r\n\r\n  private addCustomStyles() {\r\n    const style = document.createElement('style');\r\n    style.textContent = `\r\n          ::-webkit-scrollbar {\r\n            display: none;\r\n            width: 0;\r\n            height: 0;\r\n            -webkit-appearance: none;\r\n          }\r\n          body {\r\n            -ms-overflow-style: none;  /* IE and Edge */\r\n            scrollbar-width: none;  /* Firefox */\r\n          }\r\n          .-without-scrollbar::-webkit-scrollbar {\r\n            display: none;\r\n          }\r\n          .-without-scrollbar {\r\n              -ms-overflow-style: none; /* IE and Edge */\r\n              scrollbar-width: none; /* Firefox */\r\n          }\r\n      `;\r\n    document.head.appendChild(style);\r\n  }\r\n\r\n  private createScrollbar() {\r\n    this.scrollbar = document.createElement('div');\r\n    this.scrollbar.classList.add('scrollbar');\r\n    this.thumb = document.createElement('div');\r\n    this.thumb.classList.add('thumb');\r\n    this.scrollbar.appendChild(this.thumb);\r\n    document.body.appendChild(this.scrollbar);\r\n\r\n    this.scrollbarStateHorizontal = new StringScrollbarHorizontal(\n      this.data,\n      this.scrollbar,\n      this.thumb,\n      this.requestScrollTo,\n    );\n    this.scrollbarStateVertical = new StringScrollbarVertical(\n      this.data,\n      this.scrollbar,\n      this.thumb,\n      this.requestScrollTo,\n    );\n    this.scrollbarState = this.scrollbarStateVertical;\r\n  }\r\n\r\n  private updateThumb() {\r\n    this.scrollbarState.updateThumb();\r\n  }\r\n\r\n  private mouseDownEvent(e: MouseEvent) {\r\n    this.isDragging = true;\r\n    this.scrollbarState.mouseDownEvent(e);\r\n    document.body.style.userSelect = 'none';\r\n    this.scrollbar.classList.add('-touch');\r\n  }\r\n\r\n  private mouseMoveEvent(e: MouseEvent) {\r\n    if (!this.isDragging) return;\r\n\r\n    this.scrollbarState.mouseMoveEvent(e);\r\n  }\r\n\r\n  private mouseUpEvent() {\r\n    this.isDragging = false;\r\n    document.body.style.userSelect = '';\r\n    this.hideScrollbar();\r\n    this.scrollbar.classList.remove('-touch');\r\n  }\r\n\r\n  private showScrollbar() {\r\n    this.scrollbar.classList.add('-scroll');\r\n  }\r\n\r\n  private hideScrollbar() {\r\n    if (this.scrollTimeout) {\r\n      clearTimeout(this.scrollTimeout);\r\n    }\r\n    this.scrollTimeout = setTimeout(() => {\r\n      this.scrollbar.classList.remove('-scroll');\r\n    }, 1000);\r\n  }\r\n}\r\n","export const SPLIT_ELEMENT_CLASS = {\r\n  BEFORE_ELEMENT: \"-before-element\",\r\n  AFTER_ELEMENT: \"-after-element\",\r\n} as const;\r\n","import { CalculatedValue } from \"../../models/text/CalculatedValue\";\r\nimport { LayoutLine, ProcessedWord } from \"./SplitMeasuredTokens\";\r\nimport { ISplitOptions } from \"../../models/text/ISplitOptions\";\r\nimport { SPLIT_ELEMENT_CLASS } from \"../../models/text/SplitElementClass\";\r\nimport { FontMetrics } from \"./CanvasKerningApplier\";\r\nimport { WrapperInfo } from \"./BuildTokens\";\r\n\r\nfunction getWholeWordSplitClass(word: any): string[] {\r\n  if (!word || !Array.isArray(word.chars) || word.chars.length === 0) return [];\r\n  const first = (word.chars[0] as any).splitClass ?? [];\r\n  if (first.length === 0) return [];\r\n  for (const ch of word.chars) {\r\n    const cls = (ch as any).splitClass ?? [];\r\n    if (cls.length !== first.length) return [];\r\n    for (let i = 0; i < cls.length; i++) {\r\n      if (cls[i] !== first[i]) return [];\r\n    }\r\n  }\r\n  return first;\r\n}\r\n\r\nfunction getWordWrappers(word: ProcessedWord): WrapperInfo[] {\n  return (word.chars[0]?.token?.meta?.wrappers as WrapperInfo[]) ?? [];\n}\n\nfunction shouldTrimGeneratedGap(\n  currentWord: ProcessedWord,\n  nextWord: ProcessedWord | undefined,\n  options: ISplitOptions,\n): boolean {\n  if (options.trimInlineGaps !== true || !nextWord) return false;\n\n  const currentWrappers = getWordWrappers(currentWord);\n  const nextWrappers = getWordWrappers(nextWord);\n  if (currentWrappers.length === 0 || nextWrappers.length === 0) return false;\n  if (currentWrappers.length !== nextWrappers.length) return true;\n\n  for (let i = 0; i < currentWrappers.length; i++) {\n    if (currentWrappers[i].id !== nextWrappers[i].id) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\r\nexport function BuildDOMTree(\n  layoutLines: LayoutLine[],\n  options: ISplitOptions,\n  fontMetrics: FontMetrics\n): { fragment: DocumentFragment; extraProps: Map<string, string> } {\n  const fragment = document.createDocumentFragment();\n  const hasLine =\n    hasOption(options, \"line\") || hasOption(options, \"charLine\") || hasOption(options, \"wordLine\");\n  let localCharIndex = 0;\n\r\n  const hasChar =\n    hasOption(options, \"char\") || hasOption(options, \"charLine\") || hasOption(options, \"charWord\");\n\n  let totalWords = 0;\n  layoutLines.forEach((line) => (totalWords += line.words.length));\n\n  let charsCount = 0;\n  layoutLines.forEach((line) => line.words.forEach((w) => (charsCount += w.chars.length)));\n\n  const linesCount = layoutLines.length;\n  const wordsGlobalCount = totalWords;\n\n  const extraProps = new Map<string, string>();\n\n  layoutLines.forEach((line, li) => {\n    const isLastInLayout = li === layoutLines.length - 1;\r\n\r\n    let container: HTMLElement | DocumentFragment = fragment;\r\n    const wordsForLine: string[] = [];\r\n\r\n    if (hasLine) {\n      container = document.createElement(\"span\");\r\n      container.setAttribute(\"aria-hidden\", \"true\");\r\n      container.classList.add(\"-s-line\");\r\n      if (line.isBeforeElement)\r\n        (container as HTMLElement).classList.add(SPLIT_ELEMENT_CLASS.BEFORE_ELEMENT);\r\n      if (line.isAfterElement)\r\n        (container as HTMLElement).classList.add(SPLIT_ELEMENT_CLASS.AFTER_ELEMENT);\r\n      (container as HTMLElement).style.setProperty(\"--line-index\", String(line.lineIndex));\r\n      (container as HTMLElement).style.setProperty(\"--word-total\", String(line.words.length));\r\n      if (line.fitFontSize !== undefined) {\r\n        (container as HTMLElement).style.setProperty(\r\n          \"--fit-font-size\",\r\n          String(line.fitFontSize),\r\n        );\r\n      }\r\n      applyStyles(container as HTMLElement, (line as any).calculatedValues, options);\r\n    }\r\n\r\n    let wrapperStack: { info: WrapperInfo; element: HTMLElement }[] = [];\r\n    let appendTarget: HTMLElement | DocumentFragment = container;\n\n    line.words.forEach((word, wi) => {\n      const isLast = wi === line.words.length - 1;\n\r\n      const targetWrappers = getWordWrappers(word);\r\n      let commonLen = 0;\r\n      while (\r\n        commonLen < wrapperStack.length &&\r\n        commonLen < targetWrappers.length &&\r\n        wrapperStack[commonLen].info.id === targetWrappers[commonLen].id\r\n      ) {\r\n        commonLen++;\r\n      }\r\n      while (wrapperStack.length > commonLen) {\r\n        wrapperStack.pop();\r\n      }\r\n      appendTarget =\r\n        wrapperStack.length > 0\r\n          ? wrapperStack[wrapperStack.length - 1].element\r\n          : container;\r\n      for (let i = commonLen; i < targetWrappers.length; i++) {\r\n        const wInfo = targetWrappers[i];\r\n        const wEl = document.createElement(wInfo.tag);\r\n        for (const [name, value] of wInfo.attributes) {\r\n          wEl.setAttribute(name, value);\r\n        }\r\n        (appendTarget as HTMLElement).appendChild(wEl);\r\n        wrapperStack.push({ info: wInfo, element: wEl });\r\n        appendTarget = wEl;\r\n      }\r\n\r\n      const isElementWord = word.chars.length === 1 && word.chars[0].token.type === \"element\";\r\n      if (isElementWord) {\r\n        const original = word.chars[0].token.node.cloneNode(true) as HTMLElement;\r\n        (appendTarget as HTMLElement).appendChild(original);\r\n        return;\r\n      }\r\n\r\n      const wordText = word.chars.map((c) => c.char).join(\"\");\r\n      if (wordText) {\r\n        wordsForLine.push(wordText);\r\n      }\r\n\r\n      const hasWord =\r\n        hasOption(options, \"word\") ||\r\n        hasOption(options, \"charWord\") ||\r\n        hasOption(options, \"wordLine\");\r\n\r\n      const wordEl = hasWord\r\n        ? document.createElement(\"span\")\r\n        : (appendTarget as HTMLElement);\r\n\r\n      const wholeWordClass = getWholeWordSplitClass(word);\r\n\r\n      if (hasWord) {\r\n        wordEl.setAttribute(\"aria-hidden\", \"true\");\r\n        wordEl.classList.add(\"-s-word\");\r\n        if (word.isBeforeElement) wordEl.classList.add(SPLIT_ELEMENT_CLASS.BEFORE_ELEMENT);\r\n        if (word.isAfterElement) wordEl.classList.add(SPLIT_ELEMENT_CLASS.AFTER_ELEMENT);\r\n        wordEl.style.setProperty(\"--word-index\", String(word.wordIndexGlobal));\r\n        wordEl.style.setProperty(\"--char-total\", String(word.chars.length));\r\n        wordEl.setAttribute(\"data-split-content\", wordText);\r\n        applyStyles(wordEl, (word as any).calculatedValues, options);\r\n\r\n        if (wholeWordClass.length) {\r\n          wordEl.classList.add(...wholeWordClass);\r\n        }\r\n      }\r\n\r\n      if (hasChar) {\r\n        word.chars.forEach((char, charIndex) => {\r\n          if (char.char === \" \" || char.char === \"\\t\") return;\r\n\r\n          const charNode = document.createElement(\"span\");\r\n          charNode.setAttribute(\"aria-hidden\", \"true\");\r\n          const charEl = charNode as HTMLElement;\r\n\r\n          charEl.classList.add(\"-s-char\");\r\n          if (char.isBeforeElement) charEl.classList.add(SPLIT_ELEMENT_CLASS.BEFORE_ELEMENT);\r\n          if (char.isAfterElement) charEl.classList.add(SPLIT_ELEMENT_CLASS.AFTER_ELEMENT);\r\n\r\n          charEl.textContent = char.char;\r\n          charEl.setAttribute(\"data-split-content\", char.char);\r\n          charEl.style.setProperty(\"--char-index\", String(localCharIndex++));\r\n\r\n          const nextChar = word.chars[charIndex + 1];\r\n          if (nextChar) {\r\n            const kerning = fontMetrics.getKerning(char.char, nextChar.char);\r\n            if (Math.abs(kerning) > 0.01) {\r\n              charEl.style.setProperty(\"--kerning\", `${kerning.toFixed(2)}px`);\r\n              charEl.style.marginRight = `var(--kerning)`;\r\n            }\r\n          }\r\n\r\n          applyStyles(charEl, (char as any).calculatedValues, options);\r\n\r\n          const splitClassChar: string[] = (char as any).splitClass ?? [];\r\n          if (splitClassChar.length && !wholeWordClass.length) {\r\n            charEl.classList.add(...splitClassChar);\r\n          }\r\n\r\n          wordEl.appendChild(charNode);\r\n        });\r\n      } else {\r\n        const textNode = document.createTextNode(wordText);\r\n        wordEl.appendChild(textNode);\r\n      }\r\n\r\n      if (hasWord) {\r\n        (appendTarget as HTMLElement).appendChild(wordEl);\r\n      }\r\n\r\n      const nextWord = line.words[wi + 1];\n      const nextNoSpace =\n        nextWord?.noSpaceBefore || shouldTrimGeneratedGap(word, nextWord, options);\n      if (hasLine) {\n        if (!isLast) {\n          if (!nextNoSpace) {\n            wordEl.appendChild(document.createTextNode(\"\\u00a0\"));\n          }\n        } else if (!isLastInLayout) {\r\n          (container as HTMLElement).appendChild(document.createElement(\"br\"));\r\n        }\r\n      } else {\r\n        if (!isLast && !nextNoSpace) {\r\n          wordEl.appendChild(document.createTextNode(\"\\u00a0\"));\r\n        }\r\n      }\r\n    });\r\n\r\n    if (hasLine) {\n      const lineText = wordsForLine.join(\" \");\n      (container as HTMLElement).setAttribute(\"data-split-content\", lineText);\n      fragment.appendChild(container as HTMLElement);\n    }\n  });\n\n  if (hasLine) {\n    extraProps.set(\"--line-global-total\", String(linesCount));\n  }\n\n  if (hasChar) {\n    extraProps.set(\"--char-global-total\", String(charsCount));\n  }\r\n  if (\r\n    hasOption(options, \"word\") ||\r\n    hasOption(options, \"charWord\") ||\r\n    hasOption(options, \"wordLine\")\r\n  ) {\n    extraProps.set(\"--word-global-total\", String(wordsGlobalCount));\n  }\n\n  return { fragment, extraProps };\n}\n\r\nfunction applyStyles(\r\n  el: HTMLElement,\r\n  calculatedValues: CalculatedValue[] | undefined,\r\n  options: ISplitOptions\r\n) {\r\n  if (!calculatedValues) return;\r\n  for (const val of calculatedValues) {\r\n    if (!isOptionEnabled(val.type, val.align, options)) continue;\r\n    const varName = generateVariableName(val.type, val.align);\r\n    el.style.setProperty(varName, String(val.value));\r\n  }\r\n}\r\n\r\nfunction isOptionEnabled(type: string, align: string, options: ISplitOptions): boolean {\r\n  const group = options[type as keyof ISplitOptions] ?? [];\r\n  return (\r\n    Array.isArray(group) &&\r\n    group.some((item) =>\r\n      align.startsWith(\"random\") ? item.align.startsWith(\"random\") : item.align === align\r\n    )\r\n  );\r\n}\r\n\r\nfunction generateVariableName(type: string, align: string): string {\r\n  const norm = align.startsWith(\"random\") ? \"random\" : align;\r\n  return `--${type}-${norm}`;\r\n}\r\n\r\nfunction hasOption(options: ISplitOptions, key: keyof ISplitOptions): boolean {\r\n  return Array.isArray(options[key]) && options[key]!.length > 0;\r\n}\r\n","export type WrapperInfo = {\r\n  id: string;\r\n  tag: string;\r\n  attributes: [string, string][];\r\n};\r\n\r\nexport type Token =\r\n  | {\r\n      type: \"text\";\r\n      id: string;\r\n      node: Text;\r\n      content: string;\r\n      meta?: Record<string, any>;\r\n    }\r\n  | {\r\n      type: \"space\";\r\n      id: string;\r\n      node: Text;\r\n      content: string;\r\n      meta?: Record<string, any>;\r\n    }\r\n  | {\r\n      type: \"element\";\r\n      id: string;\r\n      node: HTMLElement;\r\n      tagName: string;\r\n      meta?: Record<string, any>;\r\n    }\r\n  | {\r\n      type: \"br\";\r\n      id: string;\r\n      node: HTMLElement;\r\n      tagName: \"br\";\r\n      meta?: Record<string, any>;\r\n    }\r\n  | {\r\n      type: \"other\";\r\n      id: string;\r\n      node: Node;\r\n      meta?: Record<string, any>;\r\n    };\r\n\r\nconst OPAQUE_TAGS = new Set([\r\n  \"img\", \"video\", \"audio\", \"canvas\", \"iframe\", \"object\", \"svg\",\r\n  \"input\", \"textarea\", \"select\", \"button\",\r\n  \"area\", \"base\", \"col\", \"embed\", \"hr\", \"link\", \"meta\", \"param\",\r\n  \"source\", \"track\", \"wbr\", \"picture\", \"table\",\r\n]);\r\n\r\nfunction getElementAttributes(el: HTMLElement): [string, string][] {\r\n  const attrs: [string, string][] = [];\r\n  for (let i = 0; i < el.attributes.length; i++) {\r\n    const attr = el.attributes[i];\r\n    attrs.push([attr.name, attr.value]);\r\n  }\r\n  return attrs;\r\n}\r\n\r\nlet tokenCounter = 0;\r\n\r\nexport function BuildTokens(nodes: NodeListOf<ChildNode>): Token[] {\r\n  tokenCounter = 0;\r\n  const tokens: Token[] = [];\r\n\r\n  const pushWithMeta = (t: Token, extra: Record<string, any> | undefined) => {\r\n    if (extra && Object.keys(extra).length) {\r\n      t.meta = { ...(t.meta || {}), ...extra };\r\n    }\r\n    tokens.push(t);\r\n  };\r\n\r\n  const processNode = (node: ChildNode, carryMeta?: Record<string, any>) => {\r\n    if (node.nodeType === Node.ELEMENT_NODE) {\r\n      const el = node as HTMLElement;\r\n      const tag = el.tagName.toLowerCase();\r\n\r\n      if (tag === \"split-class\") {\r\n        const classes = (el.getAttribute(\"class\") ?? \"\").split(/\\s+/).filter(Boolean);\r\n        const extraMeta = {\r\n          ...(carryMeta || {}),\r\n          splitClass: [...((carryMeta?.splitClass as string[]) ?? []), ...classes],\r\n        };\r\n        el.childNodes.forEach((child) => processNode(child as ChildNode, extraMeta));\r\n        return;\r\n      }\r\n\r\n      if (tag === \"br\") {\r\n        pushWithMeta(\r\n          {\r\n            type: \"br\",\r\n            id: `br_${tokenCounter++}`,\r\n            node: el,\r\n            tagName: \"br\",\r\n          },\r\n          carryMeta\r\n        );\r\n        return;\r\n      }\r\n\r\n      if (!OPAQUE_TAGS.has(tag) && el.childNodes.length > 0) {\r\n        const wrapperInfo: WrapperInfo = {\r\n          id: `wrapper_${tokenCounter++}`,\r\n          tag,\r\n          attributes: getElementAttributes(el),\r\n        };\r\n        const currentWrappers: WrapperInfo[] = (carryMeta?.wrappers as WrapperInfo[]) ?? [];\r\n        const extraMeta = {\r\n          ...(carryMeta || {}),\r\n          wrappers: [...currentWrappers, wrapperInfo],\r\n        };\r\n        el.childNodes.forEach((child) => processNode(child as ChildNode, extraMeta));\r\n        return;\r\n      }\r\n\r\n      pushWithMeta(\r\n        {\r\n          type: \"element\",\r\n          id: `el_${tokenCounter++}`,\r\n          node: el,\r\n          tagName: tag,\r\n        },\r\n        carryMeta\r\n      );\r\n      return;\r\n    }\r\n\r\n    if (node.nodeType === Node.TEXT_NODE) {\r\n      const text = node.nodeValue ?? \"\";\r\n      const id = `text_${tokenCounter++}`;\r\n      if (text.trim()) {\r\n        pushWithMeta({ type: \"text\", id, node: node as Text, content: text }, carryMeta);\r\n      } else {\r\n        pushWithMeta({ type: \"space\", id, node: node as Text, content: text }, carryMeta);\r\n      }\r\n      return;\r\n    }\r\n\r\n    pushWithMeta({ type: \"other\", id: `node_${tokenCounter++}`, node }, carryMeta);\r\n  };\r\n\r\n  nodes.forEach((n) => processNode(n as ChildNode));\r\n  return tokens;\r\n}\r\n","type PairKey = `${string}|${string}`;\r\n\r\nexport class FontMetrics {\r\n  private ctx: CanvasRenderingContext2D;\r\n  private font: string = \"\";\r\n  private cache = {\r\n    kerning: new Map<PairKey, number>(),\r\n    charWidth: new Map<string, number>(),\r\n  };\r\n\r\n  constructor(element: HTMLElement) {\r\n    const canvas = document.createElement(\"canvas\");\r\n    this.ctx = canvas.getContext(\"2d\")!;\r\n    this.setFontFromElement(element);\r\n  }\r\n\r\n  public setFontFromElement(element: HTMLElement): void {\r\n    const cs = window.getComputedStyle(element);\r\n    const font = `${cs.fontStyle} ${cs.fontVariant} ${cs.fontWeight} ${cs.fontSize}/${cs.lineHeight} ${cs.fontFamily}`;\r\n    if (font !== this.font) {\r\n      this.font = font;\r\n      this.ctx.font = this.font;\r\n      this.cache.kerning.clear();\r\n      this.cache.charWidth.clear();\r\n    }\r\n  }\r\n\r\n  public getCharWidth(char: string): number {\r\n    if (this.cache.charWidth.has(char)) {\r\n      return this.cache.charWidth.get(char)!;\r\n    }\r\n    const width = this.ctx.measureText(char).width;\r\n    this.cache.charWidth.set(char, width);\r\n    return width;\r\n  }\r\n\r\n  public getKerning(charA: string, charB: string): number {\r\n    const pair = `${charA}${charB}`;\r\n    const key: PairKey = `${this.font}|${pair}`;\r\n\r\n    if (this.cache.kerning.has(key)) {\r\n      return this.cache.kerning.get(key)!;\r\n    }\r\n\r\n    const widthWithKerning = this.ctx.measureText(pair).width;\r\n    const widthWithoutKerning = this.getCharWidth(charA) + this.getCharWidth(charB);\r\n\r\n    const kerning = widthWithKerning - widthWithoutKerning;\r\n\r\n    this.cache.kerning.set(key, kerning);\r\n    return kerning;\r\n  }\r\n\r\n  public measureWord(word: string): number {\r\n    let totalWidth = 0;\r\n    for (let i = 0; i < word.length; i++) {\r\n      const char = word[i];\r\n      totalWidth += this.getCharWidth(char);\r\n\r\n      if (i > 0) {\r\n        const prevChar = word[i - 1];\r\n        totalWidth += this.getKerning(prevChar, char);\r\n      }\r\n    }\r\n    return totalWidth;\r\n  }\r\n}\r\n","import { LayoutMeasureAdapter, LayoutMeasureContext, MeasurementSource } from \"./types\";\n\nfunction createCloneMeasurementSource(\n  element: HTMLElement,\n  context: LayoutMeasureContext,\n): MeasurementSource {\n  const measurementWidth = context.contentWidth;\n  const clone = element.cloneNode(true) as HTMLElement;\n  clone.removeAttribute(\"string\");\n  clone.removeAttribute(\"data-string\");\n  clone.removeAttribute(\"string-split\");\n  clone.removeAttribute(\"data-string-split\");\n  clone.removeAttribute(\"string-id\");\n  clone.removeAttribute(\"data-string-id\");\n  clone.removeAttribute(\"string-inited\");\n  clone.classList.remove(\"-splitted\", \"-inview\", \"-restored\");\n\n  clone.innerHTML = element.getAttribute(\"string-split-original-html\") ?? element.innerHTML;\n  clone.style.setProperty(\"position\", \"absolute\", \"important\");\n  clone.style.setProperty(\"visibility\", \"hidden\", \"important\");\n  clone.style.setProperty(\"pointer-events\", \"none\", \"important\");\n  clone.style.setProperty(\"left\", \"0\", \"important\");\n  clone.style.setProperty(\"top\", \"0\", \"important\");\n  clone.style.setProperty(\"display\", \"block\", \"important\");\n  clone.style.setProperty(\"width\", `${measurementWidth}px`, \"important\");\n  clone.style.setProperty(\"min-width\", `${measurementWidth}px`, \"important\");\n  clone.style.setProperty(\"max-width\", `${measurementWidth}px`, \"important\");\n  clone.style.setProperty(\"padding\", \"0\", \"important\");\n  clone.style.setProperty(\"border\", \"0\", \"important\");\n  clone.style.setProperty(\"margin\", \"0\", \"important\");\n  clone.style.setProperty(\"transform\", \"none\", \"important\");\n  clone.style.setProperty(\"scale\", \"1\", \"important\");\n\n  const parent = element.parentElement ?? document.body;\n  parent.appendChild(clone);\n\n  const nodeMap = new Map<Node, Node>();\n  const originalWalker = document.createTreeWalker(element, NodeFilter.SHOW_ALL);\n  const cloneWalker = document.createTreeWalker(clone, NodeFilter.SHOW_ALL);\n\n  let originalNode = originalWalker.currentNode;\n  let cloneNode = cloneWalker.currentNode;\n  nodeMap.set(originalNode, cloneNode);\n\n  while ((originalNode = originalWalker.nextNode()) && (cloneNode = cloneWalker.nextNode())) {\n    nodeMap.set(originalNode, cloneNode);\n  }\n\n  return {\n    resolveNode(node: Node): Node {\n      return nodeMap.get(node) ?? node;\n    },\n    cleanup(): void {\n      clone.remove();\n    },\n  };\n}\n\nexport class FlexMeasureAdapter implements LayoutMeasureAdapter {\n  readonly id = \"flex\";\n\n  supports(_element: HTMLElement, context: LayoutMeasureContext): boolean {\n    return context.display === \"flex\" || context.display === \"inline-flex\";\n  }\n\n  createSource(element: HTMLElement, context: LayoutMeasureContext): MeasurementSource {\n    return createCloneMeasurementSource(element, context);\n  }\n}\n","import { LayoutMeasureAdapter, LayoutMeasureContext, MeasurementSource } from \"./types\";\n\nfunction createLiveMeasurementSource(): MeasurementSource {\n  return {\n    resolveNode(node: Node): Node {\n      return node;\n    },\n    cleanup(): void {},\n  };\n}\n\nexport class InlineFlowMeasureAdapter implements LayoutMeasureAdapter {\n  readonly id = \"inline-flow\";\n\n  supports(_element: HTMLElement, context: LayoutMeasureContext): boolean {\n    return context.display !== \"flex\" && context.display !== \"inline-flex\";\n  }\n\n  createSource(_element: HTMLElement, _context: LayoutMeasureContext): MeasurementSource {\n    return createLiveMeasurementSource();\n  }\n}\n","import { FlexMeasureAdapter } from \"./FlexMeasureAdapter\";\nimport { InlineFlowMeasureAdapter } from \"./InlineFlowMeasureAdapter\";\nimport { LayoutMeasureAdapter, LayoutMeasureContext } from \"./types\";\n\nconst adapters: LayoutMeasureAdapter[] = [new FlexMeasureAdapter(), new InlineFlowMeasureAdapter()];\n\nfunction getOwnContentWidth(container: HTMLElement): number {\n  const cs = window.getComputedStyle(container);\n  const rect = container.getBoundingClientRect();\n  const borderLeft = parseFloat(cs.borderLeftWidth) || 0;\n  const borderRight = parseFloat(cs.borderRightWidth) || 0;\n  const paddingLeft = parseFloat(cs.paddingLeft) || 0;\n  const paddingRight = parseFloat(cs.paddingRight) || 0;\n  return Math.max(0, rect.width - borderLeft - borderRight - paddingLeft - paddingRight);\n}\n\nfunction getBlockContainerContentWidth(container: HTMLElement): number {\n  let el: HTMLElement | null = container.parentElement;\n  while (el) {\n    const cs = window.getComputedStyle(el);\n    const display = cs.display;\n    const isInline = display === \"inline\" || display === \"inline-block\" || display === \"ruby\";\n    if (!isInline) {\n      const rect = el.getBoundingClientRect();\n      const borderLeft = parseFloat(cs.borderLeftWidth) || 0;\n      const borderRight = parseFloat(cs.borderRightWidth) || 0;\n      const paddingLeft = parseFloat(cs.paddingLeft) || 0;\n      const paddingRight = parseFloat(cs.paddingRight) || 0;\n      return Math.max(0, rect.width - borderLeft - borderRight - paddingLeft - paddingRight);\n    }\n    el = el.parentElement;\n  }\n  return 0;\n}\n\nexport function getLayoutMeasureContext(element: HTMLElement): LayoutMeasureContext {\n  const style = window.getComputedStyle(element);\n  const ownContentWidth = getOwnContentWidth(element);\n  const blockContainerContentWidth = getBlockContainerContentWidth(element);\n  const isInlineLike =\n    style.display === \"inline\" || style.display === \"inline-flex\" || style.display === \"inline-grid\";\n\n  let contentWidth = ownContentWidth;\n  if (isInlineLike && blockContainerContentWidth > ownContentWidth + 1 && !element.style.width) {\n    contentWidth = blockContainerContentWidth;\n  } else if (contentWidth <= 0) {\n    contentWidth = blockContainerContentWidth;\n  }\n\n  return {\n    display: style.display,\n    contentWidth,\n    ownContentWidth,\n    blockContainerContentWidth,\n  };\n}\n\nexport function resolveLayoutMeasureAdapter(\n  element: HTMLElement,\n  context: LayoutMeasureContext,\n): LayoutMeasureAdapter {\n  return adapters.find((adapter) => adapter.supports(element, context)) ?? adapters[adapters.length - 1];\n}\n","import { ISplitOptions } from \"../../../models/text/ISplitOptions\";\nimport { Token, WrapperInfo } from \"../BuildTokens\";\nimport { FontMetrics } from \"../CanvasKerningApplier\";\nimport { MeasuredToken, MeasurementSource } from \"./types\";\n\nfunction wrappersEqual(a?: WrapperInfo[], b?: WrapperInfo[]): boolean {\n  if (!a?.length && !b?.length) return true;\n  if (!a || !b) return false;\n  if (a.length !== b.length) return false;\n  return a.every((w, i) => w.id === b[i].id);\n}\n\nexport function measureTokens(\n  tokens: Token[],\n  source: MeasurementSource,\n  fontMetrics: FontMetrics,\n  options: ISplitOptions,\n): MeasuredToken[] {\n  const range = document.createRange();\n  const measured: MeasuredToken[] = [];\n\n  let isAfterElement = false;\n  let lastTokenWasSpace = false;\n  let prevMeasuredWasText = false;\n  let prevTokenWrappers: WrapperInfo[] | undefined = undefined;\n\n  try {\n    for (let tokenIndex = 0; tokenIndex < tokens.length; tokenIndex++) {\n      const token = tokens[tokenIndex];\n      switch (token.type) {\n        case \"br\": {\n          measured.push({ token, rect: new DOMRect(0, 0, 0, 0) });\n          lastTokenWasSpace = true;\n          prevMeasuredWasText = false;\n          prevTokenWrappers = undefined;\n          isAfterElement = false;\n          break;\n        }\n\n        case \"space\":\n          lastTokenWasSpace = !shouldTrimInlineGap(tokens, tokenIndex, options);\n          break;\n\n        case \"other\":\n          prevMeasuredWasText = false;\n          lastTokenWasSpace = false;\n          break;\n\n        case \"text\": {\n          const raw = token.content;\n          const hadLeadingSpace = /^\\s/.test(raw);\n          const hadTrailingSpace = /\\s$/.test(raw);\n          const currentWrappers = (token.meta?.wrappers as WrapperInfo[]) ?? [];\n\n          const wordRe = /\\S+/g;\n          let match: RegExpExecArray | null;\n          let wIdx = 0;\n\n          while ((match = wordRe.exec(raw)) !== null) {\n            const word = match[0];\n            let domRect = new DOMRect(0, 0, 0, 0);\n            const measureNode = source.resolveNode(token.node) as Text;\n\n            try {\n              range.setStart(measureNode, match.index);\n              range.setEnd(measureNode, match.index + word.length);\n              domRect = range.getBoundingClientRect();\n            } catch (_) {\n              // Ignore detached/invalid ranges. The caller will still get a zero rect\n              // and line splitting can continue deterministically.\n            }\n\n            const wouldJoinPrev =\n              wIdx === 0 && !hadLeadingSpace && !lastTokenWasSpace && prevMeasuredWasText;\n            const sameWrappers = wIdx > 0 || wrappersEqual(prevTokenWrappers, currentWrappers);\n\n            const accurateWidth = fontMetrics.measureWord(word);\n            const rect = new DOMRect(domRect.x, domRect.y, accurateWidth, domRect.height);\n\n            const wordMeta: Record<string, any> = {\n              ...(token.meta || {}),\n              joinPrev: wouldJoinPrev && sameWrappers,\n              noSpaceBefore: wouldJoinPrev && !sameWrappers,\n            };\n\n            if (isAfterElement && wIdx === 0) {\n              wordMeta.isAfterElement = true;\n              isAfterElement = false;\n            }\n\n            measured.push({\n              token: { type: \"text\", id: \"\", node: token.node, content: word, meta: wordMeta },\n              rect,\n              browserWidth: domRect.width,\n            });\n\n            wIdx++;\n          }\n\n          if (wIdx > 0) {\n            lastTokenWasSpace = hadTrailingSpace;\n            prevMeasuredWasText = true;\n            prevTokenWrappers = currentWrappers;\n          }\n          break;\n        }\n\n        case \"element\": {\n          const domRect = (source.resolveNode(token.node) as HTMLElement).getBoundingClientRect();\n          measured.push({ token, rect: domRect, browserWidth: domRect.width });\n\n          const prev = measured[measured.length - 2];\n          if (prev?.token.type === \"text\") {\n            prev.token.meta = { ...(prev.token.meta || {}), isBeforeElement: true };\n          }\n\n          isAfterElement = true;\n          prevMeasuredWasText = false;\n          lastTokenWasSpace = false;\n          break;\n        }\n      }\n    }\n  } finally {\n    range.detach?.();\n    source.cleanup();\n  }\n\n  return measured;\n}\n\nfunction shouldTrimInlineGap(tokens: Token[], index: number, options: ISplitOptions): boolean {\n  if (options.trimInlineGaps !== true) return false;\n\n  const token = tokens[index];\n  if (token?.type !== \"space\") return false;\n  if (!/[\\n\\r\\t]/.test(token.content) && token.content.length <= 1) return false;\n\n  const prev = findPrevMeaningfulToken(tokens, index - 1);\n  const next = findNextMeaningfulToken(tokens, index + 1);\n  if (!prev || !next) return false;\n\n  if (!isInlineJoinCandidate(prev) || !isInlineJoinCandidate(next)) return false;\n\n  const prevWrappers = getWrapperIds(prev);\n  const nextWrappers = getWrapperIds(next);\n  if (prevWrappers.length === 0 || nextWrappers.length === 0) return false;\n\n  return prevWrappers.join(\"|\") !== nextWrappers.join(\"|\");\n}\n\nfunction findPrevMeaningfulToken(tokens: Token[], index: number): Token | null {\n  for (let i = index; i >= 0; i--) {\n    const token = tokens[i];\n    if (token.type === \"space\" || token.type === \"other\") continue;\n    return token;\n  }\n  return null;\n}\n\nfunction findNextMeaningfulToken(tokens: Token[], index: number): Token | null {\n  for (let i = index; i < tokens.length; i++) {\n    const token = tokens[i];\n    if (token.type === \"space\" || token.type === \"other\") continue;\n    return token;\n  }\n  return null;\n}\n\nfunction isInlineJoinCandidate(token: Token): boolean {\n  return token.type === \"text\" || token.type === \"element\";\n}\n\nfunction getWrapperIds(token: Token): string[] {\n  const wrappers = (token.meta?.wrappers as WrapperInfo[] | undefined) ?? [];\n  return wrappers.map((wrapper) => wrapper.id);\n}\n","import { ISplitOptions } from \"../../models/text/ISplitOptions\";\nimport { Token } from \"./BuildTokens\";\nimport { FontMetrics } from \"./CanvasKerningApplier\";\nimport { getLayoutMeasureContext, resolveLayoutMeasureAdapter } from \"./layout-measure/LayoutMeasureRouter\";\nimport { measureTokens } from \"./layout-measure/measureTokens\";\nexport type { MeasuredToken } from \"./layout-measure/types\";\n\nexport function LayoutMeasurer(\n  tokens: Token[],\n  container: HTMLElement,\n  fontMetrics: FontMetrics,\n  options: ISplitOptions,\n): import(\"./layout-measure/types\").MeasuredToken[] {\n  const context = getLayoutMeasureContext(container);\n  const adapter = resolveLayoutMeasureAdapter(container, context);\n  const source = adapter.createSource(container, context);\n  return measureTokens(tokens, source, fontMetrics, options);\n}\n","import { MeasuredToken } from \"./LayoutMeasurer\";\r\nimport { Token } from \"./BuildTokens\";\r\nimport { FontMetrics } from \"./CanvasKerningApplier\";\r\n\r\nexport type ProcessedChar = {\r\n  char: string;\r\n  rect: DOMRect;\r\n  token: Token;\r\n  charIndexGlobal: number;\r\n  charIndexInLine: number;\r\n  charIndexInWord: number;\r\n  isBeforeElement?: boolean;\r\n  isAfterElement?: boolean;\r\n};\r\n\r\nexport type ProcessedWord = {\r\n  chars: ProcessedChar[];\r\n  rect: DOMRect;\r\n  wordIndexGlobal: number;\r\n  wordIndexInLine: number;\r\n  isBeforeElement?: boolean;\r\n  isAfterElement?: boolean;\r\n  noSpaceBefore?: boolean;\r\n};\r\n\r\nexport type LayoutLine = {\n  words: ProcessedWord[];\n  rect: DOMRect;\n  lineIndex: number;\n  isBeforeElement?: boolean;\n  isAfterElement?: boolean;\n  fitFontSize?: number;\r\n  /** Browser-accurate line width (right edge from domRect, not Canvas). Used for fit calculations. */\r\n  fitWidth?: number;\r\n  /** Sum of individual browser-accurate word widths (no inter-word spaces). Used for fit formula. */\r\n  browserWordWidthSum?: number;\r\n};\r\n\r\nconst LINE_TOLERANCE = 5;\r\n\r\nexport function SplitMeasuredTokens(\r\n  measured: MeasuredToken[],\r\n  container: HTMLElement,\r\n  fontMetrics: FontMetrics\r\n): LayoutLine[] {\r\n  const lines: LayoutLine[] = [];\r\n  let currentLine: LayoutLine | null = null;\r\n  let y = 0;\r\n\r\n  let charIndexGlobal = 0;\r\n  let wordIndexGlobal = 0;\n  let currentLineBrowserRight = 0;\n\n  measured.forEach((mt) => {\n    const token = mt.token;\n    const isBefore = token.meta?.isBeforeElement ?? false;\n    const isAfter = token.meta?.isAfterElement ?? false;\n\n    if (token.type === \"br\") {\n      currentLine = null;\n      return;\r\n    }\r\n\r\n    if (token.type === \"text\") {\r\n      const wordText = token.content;\r\n      const splitClass: string[] = (token.meta?.splitClass as string[]) ?? [];\r\n      const joinPrev = !!token.meta?.joinPrev;\r\n\r\n      const chars: ProcessedChar[] = [];\r\n      let currentXInWord = 0;\r\n\r\n      for (let i = 0; i < wordText.length; i++) {\r\n        const ch = wordText[i];\r\n        const prev = i > 0 ? wordText[i - 1] : null;\r\n\r\n        const charWidth = fontMetrics.getCharWidth(ch);\r\n        const kerning = prev ? fontMetrics.getKerning(prev, ch) : 0;\r\n\r\n        currentXInWord += kerning;\r\n\r\n        const charRect = new DOMRect(\r\n          mt.rect.left + currentXInWord,\r\n          mt.rect.top,\r\n          charWidth,\r\n          mt.rect.height\r\n        );\r\n\r\n        const pc: ProcessedChar = {\r\n          char: ch,\r\n          rect: charRect,\r\n          token,\r\n          charIndexInWord: i,\r\n          charIndexInLine: 0,\r\n          charIndexGlobal: charIndexGlobal++,\r\n        };\r\n\r\n        if (splitClass.length) (pc as any).splitClass = splitClass;\r\n\r\n        chars.push(pc);\r\n        currentXInWord += charWidth;\r\n      }\r\n\r\n      if (chars.length > 0) {\r\n        const lastChar = chars[chars.length - 1];\r\n        if (isBefore) lastChar.isBeforeElement = true;\r\n        if (isAfter) lastChar.isAfterElement = true;\r\n      }\r\n\n      const currentY = Math.round(mt.rect.top);\n      const baselineY = Math.round(y);\n      const isNewLine = !currentLine || Math.abs(currentY - baselineY) > LINE_TOLERANCE;\n      if (isNewLine) {\n        y = currentY;\n        currentLine = { words: [], rect: mt.rect, lineIndex: lines.length };\n        currentLineBrowserRight = 0;\n        lines.push(currentLine);\n      }\n      if (!currentLine) return;\r\n\r\n      const wordBrowserRight = mt.rect.left + (mt.browserWidth ?? mt.rect.width);\r\n\r\n      if (joinPrev && currentLine.words.length > 0) {\r\n        const target = currentLine.words[currentLine.words.length - 1];\r\n\r\n        const charsBeforeAll = currentLine.words.reduce((acc, w) => acc + w.chars.length, 0);\r\n        const baseInWord = target.chars.length;\r\n\r\n        chars.forEach((c, i) => {\r\n          c.charIndexInLine = charsBeforeAll + i;\r\n          c.charIndexInWord = baseInWord + i;\r\n        });\r\n\r\n        target.chars.push(...chars);\r\n        target.rect = mergeRects([target.rect, mt.rect]);\r\n        currentLine.rect = mergeRects(currentLine.words.map((w) => w.rect));\r\n        currentLineBrowserRight = Math.max(currentLineBrowserRight, wordBrowserRight);\r\n        currentLine.fitWidth = currentLineBrowserRight - currentLine.rect.left;\r\n        currentLine.browserWordWidthSum = (currentLine.browserWordWidthSum ?? 0) + (mt.browserWidth ?? mt.rect.width);\r\n        if (isBefore) target.isBeforeElement = true;\r\n        if (isAfter) target.isAfterElement = true;\r\n        return;\r\n      }\r\n\r\n      const wordIndexInLine = currentLine.words.length;\r\n      const charsBefore = currentLine.words.reduce((acc, w) => acc + w.chars.length, 0);\r\n      chars.forEach((c, i) => (c.charIndexInLine = charsBefore + i));\r\n\r\n      const processedWord: ProcessedWord = {\r\n        chars,\r\n        rect: mt.rect,\r\n        wordIndexGlobal: wordIndexGlobal++,\r\n        wordIndexInLine,\r\n        isBeforeElement: isBefore,\r\n        isAfterElement: isAfter,\r\n        noSpaceBefore: !!token.meta?.noSpaceBefore,\r\n      };\r\n\r\n      currentLine.words.push(processedWord);\r\n      currentLine.rect = mergeRects(currentLine.words.map((w) => w.rect));\r\n      currentLineBrowserRight = Math.max(currentLineBrowserRight, wordBrowserRight);\r\n      currentLine.fitWidth = currentLineBrowserRight - currentLine.rect.left;\r\n      currentLine.browserWordWidthSum = (currentLine.browserWordWidthSum ?? 0) + (mt.browserWidth ?? mt.rect.width);\r\n      if (isBefore) currentLine.isBeforeElement = true;\r\n      if (isAfter) currentLine.isAfterElement = true;\r\n      return;\r\n    }\r\n\r\n    if (token.type === \"element\") {\r\n      const rect = mt.rect;\n      const currentY = Math.round(rect.top);\n      const baselineY = Math.round(y);\n      const isNewLine = !currentLine || Math.abs(currentY - baselineY) > LINE_TOLERANCE;\n\n      if (isNewLine) {\n        y = currentY;\n        currentLine = { words: [], rect, lineIndex: lines.length };\n        currentLineBrowserRight = 0;\n        lines.push(currentLine);\n      }\n      if (!currentLine) return;\r\n\r\n      const wordIndexInLine = currentLine.words.length;\r\n      const charsBefore = currentLine.words.reduce((acc, w) => acc + w.chars.length, 0);\r\n\r\n      const chars: ProcessedChar[] = [\r\n        {\r\n          char: \"[E]\",\r\n          rect,\r\n          token,\r\n          charIndexInWord: 0,\r\n          charIndexInLine: charsBefore,\r\n          charIndexGlobal: charIndexGlobal++,\r\n        },\r\n      ];\r\n\r\n      const processedWord: ProcessedWord = {\r\n        chars,\r\n        rect,\r\n        wordIndexGlobal: wordIndexGlobal++,\r\n        wordIndexInLine,\r\n        isBeforeElement: false,\r\n        isAfterElement: false,\r\n      };\r\n\r\n      currentLine.words.push(processedWord);\r\n      currentLine.rect = mergeRects(currentLine.words.map((w) => w.rect));\r\n      currentLineBrowserRight = Math.max(currentLineBrowserRight, mt.rect.left + (mt.browserWidth ?? mt.rect.width));\r\n      currentLine.fitWidth = currentLineBrowserRight - currentLine.rect.left;\r\n      currentLine.browserWordWidthSum = (currentLine.browserWordWidthSum ?? 0) + (mt.browserWidth ?? mt.rect.width);\r\n    }\r\n  });\r\n\r\n  return lines;\r\n}\r\n\r\nfunction mergeRects(rects: DOMRect[]): DOMRect {\r\n  if (rects.length === 0) return new DOMRect(0, 0, 0, 0);\r\n  const left = Math.min(...rects.map((r) => r.left));\r\n  const top = Math.min(...rects.map((r) => r.top));\r\n  const right = Math.max(...rects.map((r) => r.right));\r\n  const bottom = Math.max(...rects.map((r) => r.bottom));\r\n  return new DOMRect(left, top, right - left, bottom - top);\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { CalculatedValue } from \"../../models/text/CalculatedValue\";\r\nimport { ISplitOptionItem } from \"../../models/text/ISplitOptionItem\";\r\nimport { ISplitOptions } from \"../../models/text/ISplitOptions\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { BuildDOMTree } from \"../../utils/text/BuildDOMTree\";\nimport { BuildTokens, Token } from \"../../utils/text/BuildTokens\";\nimport { FontMetrics } from \"../../utils/text/CanvasKerningApplier\";\nimport { LayoutMeasurer, MeasuredToken } from \"../../utils/text/LayoutMeasurer\";\nimport {\r\n  LayoutLine,\r\n  ProcessedChar,\r\n  ProcessedWord,\r\n  SplitMeasuredTokens,\r\n} from \"../../utils/text/SplitMeasuredTokens\";\r\n\r\ntype FitContext = {\n  currentFontSize: number;\n  contentWidth: number;\n  /** Computed line-height in px at currentFontSize. 0 when unavailable (e.g. \"normal\"). */\n  lineHeightPx: number;\n};\n\ntype SplitDebugRecord = {\n  label: string;\n  timestamp: number;\n  connect?: Record<string, unknown>;\n  measure?: Record<string, unknown>;\n  rendered?: Record<string, unknown>;\n};\n\r\n/**\r\n * StringSplit module: splits text into lines, words, chars,\r\n * computes alignment/random values, and applies CSS vars.\r\n */\r\nexport class StringSplit extends StringModule {\n  /** Last content-width (px) at which each element was split. Keyed by element itself. */\n  private lastSplitWidth = new WeakMap<HTMLElement, number>();\n\n  constructor(context: StringContext) {\n    super(context);\n    this.htmlKey = \"split\";\n    this.permissions.mobile.rebuild.height = false;\r\n    this.permissions.mobile.rebuild.width = false;\r\n    //this.permissions.mobile.rebuild.scrollHeight = false;\r\n  }\r\n\r\n  onInit(): void {\n    const rebuild = () => {\n      this.objectsOnPage.forEach((object) => {\n        const element = object.htmlElement;\n        if (!element) return;\n\n        const options = this.getSplitOptions(element);\n        if (this.needsForcedRebuildOnFontLoad(options)) {\n          this.lastSplitWidth.delete(element);\n        }\n\n        this.onObjectConnected(object);\n      });\n    };\n\n    document.fonts.ready.then(rebuild);\n    document.fonts.addEventListener(\"loadingdone\", rebuild);\n  }\r\n\r\n  override onObjectDisconnected(object: StringObject): void {\r\n    if (object.htmlElement) this.lastSplitWidth.delete(object.htmlElement);\r\n  }\n\n  onResizeWidth(): void {\n    this.objectsOnPage.forEach((object) => {\n      const element = object.htmlElement;\n      if (!element) return;\n\n      const options = this.getSplitOptions(element);\n      if (!this.needsWidthRebuild(options)) {\n        return;\n      }\n\n      this.onObjectConnected(object);\n    });\n  }\n\r\n  onObjectConnected(object: StringObject): void {\n    const element = object.htmlElement;\n    if (!element) return;\n    const debugEnabled = this.isDebugEnabled(element);\n\n    const isAlreadySplit = element.classList.contains(\"-splitted\");\n    let originalHtml = element.getAttribute(\"string-split-original-html\");\r\n    let originalText = element.getAttribute(\"string-split-original\");\r\n\r\n    if (originalHtml === null && originalText !== null && isAlreadySplit) {\n      originalHtml = originalText;\n      originalText = this.extractTextContent(originalHtml);\n      element.setAttribute(\"string-split-original-html\", originalHtml);\n      element.setAttribute(\"string-split-original\", originalText);\n    }\r\n\r\n    if (!isAlreadySplit || originalHtml === null || originalText === null) {\n      originalHtml = this.escapeAttribute(element.innerHTML);\n      originalText = element.textContent ?? \"\";\n      element.setAttribute(\"string-split-original-html\", originalHtml);\n      element.setAttribute(\"string-split-original\", originalText);\n    }\n    if (isAlreadySplit) {\n      element.classList.remove(\"-splitted\");\n    }\n\n    // Skip re-split when called from onResizeWidth and the element's content width\n    // hasn't changed — prevents feedback loops caused by animations or other\n    // unrelated ResizeObserver triggers on the scroll container.\n    const cs = window.getComputedStyle(element);\n    const currentContentWidth = this.getElementContentWidth(element, cs);\n    if (debugEnabled) {\n      this.logConnectionStart(element, {\n        isAlreadySplit,\n        currentContentWidth,\n        lastWidth: this.lastSplitWidth.get(element),\n        originalHtml,\n        originalText,\n      });\n    }\n    const lastWidth = this.lastSplitWidth.get(element);\n    if (\r\n      isAlreadySplit &&\n      lastWidth !== undefined &&\n      Math.abs(currentContentWidth - lastWidth) < 1\n    ) {\n      if (isAlreadySplit) {\n        element.classList.add(\"-splitted\");\n      }\n      return;\n    }\n    this.lastSplitWidth.set(element, currentContentWidth);\n\n    try {\n      object.htmlElement.innerHTML = originalHtml;\n      const attr =\n        element.getAttribute(\"string-split\") ?? element.getAttribute(\"data-string-split\") ?? \"\";\n      const options: ISplitOptions = this.tools.optionsParser.process({\n        attributeValue: attr,\n      });\n      const { fragment, result, extraProps } = this.split(element, options, debugEnabled);\n      object.setProperty(\"nodes\", fragment.childNodes);\n      element.setAttribute(\"aria-label\", originalText);\n      element.innerHTML = \"\";\n      element.appendChild(result);\n      this.applyFlexLineBreaks(element, options);\n      element.classList.add(\"-splitted\");\n\n      extraProps.forEach((value: string, key: string) => {\n        element.style.setProperty(key, value);\n      });\n\n      if (debugEnabled) {\n        this.logRenderedState(element, options, extraProps);\n      }\n\n      const restoreAfter = element.getAttribute(\"string-split-restore-after\");\n      if (restoreAfter && !isNaN(Number(restoreAfter))) {\n        setTimeout(() => {\n          element.innerHTML = originalHtml!;\n          element.classList.add(\"-restored\");\n        }, Number(restoreAfter));\n      }\n    } finally {\n      if (!element.classList.contains(\"-splitted\")) {\n        element.classList.add(\"-splitted\");\n      }\n    }\n  }\n\n  private extractTextContent(html: string): string {\n    const temp = document.createElement(\"div\");\n    temp.innerHTML = html;\n    return temp.textContent ?? \"\";\n  }\n\n  private getSplitOptions(element: HTMLElement): ISplitOptions {\n    const attr =\n      element.getAttribute(\"string-split\") ?? element.getAttribute(\"data-string-split\") ?? \"\";\n    return this.tools.optionsParser.process({\n      attributeValue: attr,\n    });\n  }\n\n  private hasLineDrivenSplit(options: ISplitOptions): boolean {\n    return (\n      (options.line?.length ?? 0) > 0 ||\n      (options.wordLine?.length ?? 0) > 0 ||\n      (options.charLine?.length ?? 0) > 0\n    );\n  }\n\n  private needsWidthRebuild(options: ISplitOptions): boolean {\n    return this.hasLineDrivenSplit(options) || options.fit === true;\n  }\n\n  private needsForcedRebuildOnFontLoad(options: ISplitOptions): boolean {\n    return this.needsWidthRebuild(options);\n  }\n\n  private getDebugStoreKey(element: HTMLElement): string | null {\n    const raw =\n      element.getAttribute(\"string-debug-save\") ??\n      element.getAttribute(\"data-string-debug-save\") ??\n      \"\";\n    if (!raw) return null;\n    return raw === \"true\" || raw === \"1\" ? this.getDebugLabel(element) : raw;\n  }\n\n  private writeDebugRecord(\n    element: HTMLElement,\n    stage: keyof Omit<SplitDebugRecord, \"label\" | \"timestamp\">,\n    payload: Record<string, unknown>,\n  ): void {\n    const key = this.getDebugStoreKey(element);\n    if (!key) return;\n\n    const globalObject = window as Window & {\n      __stringSplitDebug?: Record<string, SplitDebugRecord>;\n    };\n    const store = (globalObject.__stringSplitDebug ??= {});\n    const current = store[key] ?? {\n      label: this.getDebugLabel(element),\n      timestamp: Date.now(),\n    };\n\n    current.timestamp = Date.now();\n    current[stage] = payload;\n    store[key] = current;\n  }\n\n  private isDebugEnabled(element: HTMLElement): boolean {\n    const raw =\n      element.getAttribute(\"string-debug\") ?? element.getAttribute(\"data-string-debug\") ?? \"\";\n    if (!raw) return false;\n    return raw === \"\" || raw === \"true\" || raw === \"1\" || raw.includes(\"split\") || raw === \"all\";\n  }\n\n  private getDebugLabel(element: HTMLElement): string {\n    return (\n      element.getAttribute(\"string-id\") ??\n      element.id ??\n      element.className ??\n      element.tagName.toLowerCase()\n    );\n  }\n\n  private logConnectionStart(\n    element: HTMLElement,\n    payload: {\n      isAlreadySplit: boolean;\n      currentContentWidth: number;\n      lastWidth: number | undefined;\n      originalHtml: string | null;\n      originalText: string | null;\n    },\n  ): void {\n    const style = window.getComputedStyle(element);\n    const baseline = this.captureBaselineSnapshot(element, style);\n    const debugPayload = {\n      text: payload.originalText,\n      html: payload.originalHtml,\n      baseline,\n      flags: {\n        isAlreadySplit: payload.isAlreadySplit,\n        display: style.display,\n        whiteSpace: style.whiteSpace,\n        position: style.position,\n      },\n      widths: {\n        currentContentWidth: payload.currentContentWidth,\n        lastWidth: payload.lastWidth,\n        rectWidth: element.getBoundingClientRect().width,\n        clientWidth: element.clientWidth,\n        parentContentWidth: this.getBlockContainerContentWidth(element),\n      },\n    };\n    this.writeDebugRecord(element, \"connect\", debugPayload);\n\n    console.groupCollapsed(`[StringSplit] connect ${this.getDebugLabel(element)}`);\n    console.log(\"text\", debugPayload.text);\n    console.log(\"html\", debugPayload.html);\n    console.log(\"baseline\", debugPayload.baseline);\n    console.log(\"flags\", debugPayload.flags);\n    console.log(\"widths\", debugPayload.widths);\n    console.groupEnd();\n  }\n\n  private captureBaselineSnapshot(\n    element: HTMLElement,\n    style: CSSStyleDeclaration,\n  ): Record<string, unknown> {\n    const rect = element.getBoundingClientRect();\n    const lineHeight = parseFloat(style.lineHeight);\n    return {\n      rectWidth: Number(rect.width.toFixed(2)),\n      rectHeight: Number(rect.height.toFixed(2)),\n      fontSize: Number(parseFloat(style.fontSize).toFixed(2)),\n      lineHeight: Number.isFinite(lineHeight) ? Number(lineHeight.toFixed(2)) : style.lineHeight,\n      estimatedLineCount:\n        Number.isFinite(lineHeight) && lineHeight > 0\n          ? Number((rect.height / lineHeight).toFixed(2))\n          : null,\n    };\n  }\n\n  private logSplitAnalysis(\n    element: HTMLElement,\n    tokens: Token[],\n    measured: MeasuredToken[],\n    layoutLines: LayoutLine[],\n  ): void {\n    const debugPayload = {\n      tokens: tokens.map((token) => ({\n        type: token.type,\n        text: this.getTokenDebugText(token),\n        wrappers: token.meta?.wrappers?.map((item: { tag: string }) => item.tag) ?? [],\n      })),\n      measured: measured.map((item) => ({\n        type: item.token.type,\n        text: this.getTokenDebugText(item.token),\n        left: Number(item.rect.left.toFixed(2)),\n        top: Number(item.rect.top.toFixed(2)),\n        width: Number(item.rect.width.toFixed(2)),\n        browserWidth: Number((item.browserWidth ?? item.rect.width).toFixed(2)),\n      })),\n      layoutLines: layoutLines.map((line) => ({\n        index: line.lineIndex,\n        text: line.words.map((word) => word.chars.map((char) => char.char).join(\"\")).join(\" \"),\n        wordCount: line.words.length,\n        rect: {\n          left: Number(line.rect.left.toFixed(2)),\n          top: Number(line.rect.top.toFixed(2)),\n          width: Number(line.rect.width.toFixed(2)),\n          height: Number(line.rect.height.toFixed(2)),\n        },\n        fitWidth: Number((line.fitWidth ?? line.rect.width).toFixed(2)),\n      })),\n    };\n    this.writeDebugRecord(element, \"measure\", debugPayload);\n\n    console.groupCollapsed(`[StringSplit] measure ${this.getDebugLabel(element)}`);\n    console.log(\"tokens\", debugPayload.tokens);\n    console.log(\"measured\", debugPayload.measured);\n    console.log(\"layoutLines\", debugPayload.layoutLines);\n    console.groupEnd();\n  }\n\n  private getTokenDebugText(token: Token): string {\n    if (\"content\" in token) {\n      return token.content;\n    }\n    if (\"tagName\" in token) {\n      return token.tagName;\n    }\n    return \"#other\";\n  }\n\n  private logRenderedState(\n    element: HTMLElement,\n    options: ISplitOptions,\n    extraProps: Map<string, string>,\n  ): void {\n    const style = window.getComputedStyle(element);\n    const lines = Array.from(element.querySelectorAll(\".-s-line\")) as HTMLElement[];\n    const debugPayload = {\n      mode: {\n        attr: element.getAttribute(\"string-split\") ?? element.getAttribute(\"data-string-split\"),\n        line: options.line?.length ?? 0,\n        wordLine: options.wordLine?.length ?? 0,\n        charLine: options.charLine?.length ?? 0,\n      },\n      root: {\n        display: style.display,\n        flexWrap: style.flexWrap,\n        rectWidth: Number(element.getBoundingClientRect().width.toFixed(2)),\n        rectHeight: Number(element.getBoundingClientRect().height.toFixed(2)),\n        childCount: element.children.length,\n        extraProps: Object.fromEntries(extraProps.entries()),\n      },\n      children: Array.from(element.children).map((child) => {\n        const childEl = child as HTMLElement;\n        const rect = childEl.getBoundingClientRect();\n        return {\n          tag: childEl.tagName.toLowerCase(),\n          className: childEl.className,\n          text: childEl.textContent?.replace(/\\s+/g, \" \").trim(),\n          width: Number(rect.width.toFixed(2)),\n          height: Number(rect.height.toFixed(2)),\n        };\n      }),\n      lineNodes: lines.map((line, index) => {\n        const rect = line.getBoundingClientRect();\n        const lineStyle = window.getComputedStyle(line);\n        return {\n          index,\n          text: line.getAttribute(\"data-split-content\"),\n          top: Number(rect.top.toFixed(2)),\n          left: Number(rect.left.toFixed(2)),\n          width: Number(rect.width.toFixed(2)),\n          height: Number(rect.height.toFixed(2)),\n          display: lineStyle.display,\n          lineHeight: lineStyle.lineHeight,\n          scale: lineStyle.scale,\n          transform: lineStyle.transform,\n        };\n      }),\n    };\n    this.writeDebugRecord(element, \"rendered\", debugPayload);\n\n    console.groupCollapsed(`[StringSplit] rendered ${this.getDebugLabel(element)}`);\n    console.log(\"mode\", debugPayload.mode);\n    console.log(\"root\", debugPayload.root);\n    console.log(\"children\", debugPayload.children);\n    console.log(\"lineNodes\", debugPayload.lineNodes);\n    console.groupEnd();\n  }\n\n  private applyFlexLineBreaks(element: HTMLElement, options: ISplitOptions): void {\n    const hasLineSplit =\n      (options.line?.length ?? 0) > 0 ||\n      (options.wordLine?.length ?? 0) > 0 ||\n      (options.charLine?.length ?? 0) > 0;\n\n    if (!hasLineSplit) return;\n\n    const display = window.getComputedStyle(element).display;\n    if (display !== \"flex\" && display !== \"inline-flex\") return;\n\n    const lines = Array.from(element.children).filter((child) =>\n      child.classList.contains(\"-s-line\"),\n    ) as HTMLElement[];\n    if (lines.length < 2) return;\n\n    for (let i = 0; i < lines.length - 1; i++) {\n      const marker = document.createElement(\"span\");\n      marker.setAttribute(\"aria-hidden\", \"true\");\n      marker.classList.add(\"-s-line-break\");\n      marker.style.flexBasis = \"100%\";\n      marker.style.width = \"0\";\n      marker.style.height = \"0\";\n      marker.style.overflow = \"hidden\";\n      marker.style.pointerEvents = \"none\";\n      lines[i].after(marker);\n    }\n  }\n\n  private getBlockContainerContentWidth(element: HTMLElement): number {\n    let el: HTMLElement | null = element.parentElement;\n    while (el) {\n      const cs = window.getComputedStyle(el);\n      const d = cs.display;\n      const isInline = d === \"inline\" || d === \"inline-block\" || d === \"ruby\";\n      if (!isInline) {\n        const layoutWidth = el.getBoundingClientRect().width || el.clientWidth;\n        return Math.max(\n          0,\n          layoutWidth - (parseFloat(cs.paddingLeft) || 0) - (parseFloat(cs.paddingRight) || 0),\n        );\n      }\n      el = el.parentElement;\n    }\n    return 0;\r\n  }\r\n\r\n  private getElementContentWidth(\r\n    element: HTMLElement,\r\n    cs = window.getComputedStyle(element),\r\n  ): number {\r\n    const padding = (parseFloat(cs.paddingLeft) || 0) + (parseFloat(cs.paddingRight) || 0);\r\n    const layoutWidth = element.clientWidth || element.getBoundingClientRect().width;\r\n    const parentContentWidth = this.getBlockContainerContentWidth(element);\r\n    const shouldPreferParentWidth =\r\n      parentContentWidth > layoutWidth + 1 &&\r\n      !element.style.width &&\r\n      (cs.display === \"inline\" ||\r\n        cs.display === \"inline-flex\" ||\r\n        cs.display === \"inline-grid\");\r\n\r\n    if (shouldPreferParentWidth) {\r\n      return Math.max(0, parentContentWidth - padding);\r\n    }\r\n\r\n    if (layoutWidth > 0) {\r\n      return Math.max(0, layoutWidth - padding);\r\n    }\r\n\r\n    return Math.max(0, parentContentWidth - padding);\r\n  }\r\n\r\n  public split(element: HTMLElement, options: ISplitOptions, debugEnabled = false) {\n    const fontMetrics = new FontMetrics(element);\n    const frag = document.createDocumentFragment();\n    element.childNodes.forEach((ch) => frag.appendChild(ch.cloneNode(true)));\n    const tokens = BuildTokens(element.childNodes as NodeListOf<ChildNode>);\n    const measured = LayoutMeasurer(tokens, element, fontMetrics, options);\n    const layoutLines: LayoutLine[] = SplitMeasuredTokens(measured, element, fontMetrics);\n\n    if (debugEnabled) {\n      this.logSplitAnalysis(element, tokens, measured, layoutLines);\n    }\n\n    const fitContext = options.fit ? this.getFitContext(layoutLines, element) : null;\n    const fitExtraProps = fitContext\r\n      ? this.applyFit(layoutLines, options, fitContext)\r\n      : new Map<string, string>();\r\n\r\n    this.applyCalculatedValues(layoutLines, options);\r\n\r\n    const dom = BuildDOMTree(layoutLines, options, fontMetrics);\r\n    fitExtraProps.forEach((v, k) => dom.extraProps.set(k, v));\r\n\r\n    if (fitContext) {\r\n      this.refineFitFontSize(\r\n        element,\r\n        dom.fragment,\r\n        dom.extraProps,\r\n        layoutLines,\r\n        options,\r\n        fitContext,\r\n      );\r\n    }\r\n\r\n    return {\r\n      fragment: frag,\r\n      result: dom.fragment,\r\n      extraProps: dom.extraProps,\r\n    };\r\n  }\r\n\r\n  private getFitContext(layoutLines: LayoutLine[], element: HTMLElement): FitContext | null {\r\n    const cs = window.getComputedStyle(element);\r\n    const currentFontSize = parseFloat(cs.fontSize);\r\n    if (!currentFontSize) return null;\r\n\r\n    const elementContentWidth = this.getElementContentWidth(element, cs);\r\n    if (elementContentWidth <= 0) return null;\r\n\r\n    let widestLineWidth = 0;\r\n    for (const line of layoutLines) {\r\n      const w = line.fitWidth ?? line.rect.width;\r\n      if (w > widestLineWidth) widestLineWidth = w;\r\n    }\r\n    if (widestLineWidth <= 0) return null;\r\n\r\n    let contentWidth = elementContentWidth;\r\n    if (Math.abs(elementContentWidth - widestLineWidth) < 2 && element.parentElement) {\r\n      const pcs = window.getComputedStyle(element.parentElement);\r\n      const parentContentWidth =\r\n        element.parentElement.clientWidth -\r\n        (parseFloat(pcs.paddingLeft) || 0) -\r\n        (parseFloat(pcs.paddingRight) || 0);\r\n      if (parentContentWidth > elementContentWidth) {\r\n        contentWidth = parentContentWidth;\r\n      }\r\n    }\r\n\r\n    const lineHeightPx = parseFloat(cs.lineHeight) || 0;\r\n    return { currentFontSize, contentWidth, lineHeightPx };\r\n  }\r\n\r\n  /**\r\n   * Computes target font sizes to fill the container width and stores them on each line.\r\n   *\r\n   * With a line-level split (`line`, `wordLine`, `charLine`): sets `fitFontSize` on each\r\n   * `LayoutLine` so that BuildDOMTree can expose `--fit-font-size` per `-s-line` span.\r\n   * Each line may receive a different value, allowing text to fill 100% of the container\r\n   * width independently per line.\r\n   *\r\n   * Without a line-level split: finds the widest line and returns a single\r\n   * `--fit-font-size` in the extraProps map, to be applied to the container element.\r\n   *\r\n   * Formula: targetFontSize = currentFontSize * (contentWidth / lineWidth)\r\n   */\r\n  private applyFit(\r\n    layoutLines: LayoutLine[],\r\n    options: ISplitOptions,\r\n    fitContext: FitContext,\r\n  ): Map<string, string> {\r\n    const extraProps = new Map<string, string>();\r\n    const { currentFontSize, contentWidth } = fitContext;\r\n\r\n    const hasLineSplit =\r\n      (options.line?.length ?? 0) > 0 ||\r\n      (options.wordLine?.length ?? 0) > 0 ||\r\n      (options.charLine?.length ?? 0) > 0;\r\n\r\n    // Space-aware formula only when individual chars are split (spaces become unscaled text nodes).\r\n    // For line/word-only splits the entire span scales uniformly, so spaces scale too.\r\n    const hasCharSplit =\r\n      (options.char?.length ?? 0) > 0 ||\r\n      (options.charLine?.length ?? 0) > 0 ||\r\n      (options.charWord?.length ?? 0) > 0;\r\n\r\n    if (hasLineSplit) {\r\n      for (const line of layoutLines) {\r\n        const lineWidth = line.fitWidth ?? line.rect.width;\r\n        if (lineWidth > 0) {\r\n          line.fitFontSize = this.computeFitFontSize(\r\n            currentFontSize,\r\n            contentWidth,\r\n            lineWidth,\r\n            hasCharSplit ? line.browserWordWidthSum : undefined,\r\n          );\r\n        }\r\n      }\r\n    } else {\r\n      const widestLine = layoutLines.reduce((best, l) => {\r\n        const w = l.fitWidth ?? l.rect.width;\r\n        return w > (best.fitWidth ?? best.rect.width) ? l : best;\r\n      }, layoutLines[0]);\r\n      const widestLineWidth = widestLine.fitWidth ?? widestLine.rect.width;\r\n      const targetFontSize = this.computeFitFontSize(\r\n        currentFontSize,\r\n        contentWidth,\r\n        widestLineWidth,\r\n        hasCharSplit ? widestLine.browserWordWidthSum : undefined,\r\n      );\r\n      extraProps.set(\"--fit-font-size\", String(Math.floor(targetFontSize)));\r\n    }\r\n\r\n    return extraProps;\r\n  }\r\n\r\n  private refineFitFontSize(\r\n    element: HTMLElement,\r\n    fragment: DocumentFragment,\r\n    extraProps: Map<string, string>,\r\n    layoutLines: LayoutLine[],\r\n    options: ISplitOptions,\r\n    fitContext: FitContext,\r\n  ): void {\r\n    const hasLineSplit =\r\n      (options.line?.length ?? 0) > 0 ||\r\n      (options.wordLine?.length ?? 0) > 0 ||\r\n      (options.charLine?.length ?? 0) > 0;\r\n    const hasCharSplit =\r\n      (options.char?.length ?? 0) > 0 ||\r\n      (options.charLine?.length ?? 0) > 0 ||\r\n      (options.charWord?.length ?? 0) > 0;\r\n\r\n    const originalHtml = element.innerHTML;\r\n\r\n    try {\r\n      element.innerHTML = \"\";\r\n      element.appendChild(fragment.cloneNode(true));\r\n\r\n      if (hasLineSplit) {\r\n        const renderedLines = Array.from(element.querySelectorAll(\".-s-line\")) as HTMLElement[];\r\n        const resultLines = Array.from(fragment.querySelectorAll(\".-s-line\")) as HTMLElement[];\r\n\r\n        renderedLines.forEach((renderedLine, index) => {\r\n          const resultLine = resultLines[index];\r\n          if (!resultLine) return;\r\n\r\n          const provisional = parseFloat(resultLine.style.getPropertyValue(\"--fit-font-size\"));\r\n          if (!provisional) return;\r\n\r\n          const corrected = this.solveRenderedFitFontSize(\r\n            renderedLine,\r\n            fitContext.currentFontSize,\r\n            provisional,\r\n            fitContext.contentWidth,\r\n            hasCharSplit,\r\n          );\r\n          if (!corrected) return;\r\n\r\n          layoutLines[index].fitFontSize = corrected;\r\n          resultLine.style.setProperty(\"--fit-font-size\", String(Math.floor(corrected)));\r\n        });\r\n      } else {\r\n        const provisional = parseFloat(extraProps.get(\"--fit-font-size\") ?? \"\");\r\n        if (!provisional) return;\r\n\r\n        const corrected = this.solveRenderedFitFontSize(\r\n          element,\r\n          fitContext.currentFontSize,\r\n          provisional,\r\n          fitContext.contentWidth,\r\n          hasCharSplit,\r\n        );\r\n        if (!corrected) return;\r\n\r\n        const finalFontSize = Math.floor(corrected);\r\n        extraProps.set(\"--fit-font-size\", String(finalFontSize));\r\n\r\n        const { lineHeightPx, currentFontSize, contentWidth } = fitContext;\r\n        if (lineHeightPx > 0 && currentFontSize > 0) {\r\n          const textHeightAtFit = lineHeightPx * (finalFontSize / currentFontSize);\r\n          if (textHeightAtFit > 0) {\r\n            extraProps.set(\"--fit-scale-y\", String(window.innerHeight / textHeightAtFit));\r\n            extraProps.set(\"--fit-aspect-ratio\", String(contentWidth / textHeightAtFit));\r\n          }\r\n        }\r\n      }\r\n    } finally {\r\n      element.innerHTML = originalHtml;\r\n    }\r\n  }\r\n\r\n  private solveRenderedFitFontSize(\r\n    scope: HTMLElement,\r\n    currentFontSize: number,\r\n    provisionalFontSize: number,\r\n    targetWidth: number,\r\n    applyToChars: boolean,\r\n  ): number | null {\r\n    if (!Number.isFinite(currentFontSize) || !Number.isFinite(provisionalFontSize)) return null;\r\n    if (currentFontSize <= 0 || provisionalFontSize <= 0) return null;\r\n\r\n    const baselineWidth = this.measureScopeAtFontSize(scope, applyToChars, currentFontSize);\r\n    if (baselineWidth <= 0) return null;\r\n    if (Math.abs(targetWidth - baselineWidth) < 0.01) {\r\n      return currentFontSize;\r\n    }\r\n\r\n    const trialWidth =\r\n      Math.abs(provisionalFontSize - currentFontSize) < 0.01\r\n        ? baselineWidth\r\n        : this.measureScopeAtFontSize(scope, applyToChars, provisionalFontSize);\r\n\r\n    if (trialWidth <= 0) {\r\n      return currentFontSize * (targetWidth / baselineWidth);\r\n    }\r\n\r\n    const slope = (trialWidth - baselineWidth) / (provisionalFontSize - currentFontSize);\r\n    if (!Number.isFinite(slope) || Math.abs(slope) < 0.0001) {\r\n      return currentFontSize * (targetWidth / baselineWidth);\r\n    }\r\n\r\n    const corrected = currentFontSize + (targetWidth - baselineWidth) / slope;\r\n    if (!Number.isFinite(corrected) || corrected <= 0) return null;\r\n    return corrected;\r\n  }\r\n\r\n  private measureScopeAtFontSize(\r\n    scope: HTMLElement,\r\n    applyToChars: boolean,\r\n    fontSize: number,\r\n  ): number {\r\n    if (applyToChars) {\r\n      const chars = Array.from(scope.querySelectorAll(\".-s-char\")) as HTMLElement[];\r\n      const restore = chars.map((char) => char.style.fontSize);\r\n      chars.forEach((char) => {\r\n        char.style.fontSize = `${fontSize}px`;\r\n      });\r\n\r\n      scope.offsetWidth;\r\n      const width = this.measureCharScopeWidth(scope);\r\n\r\n      chars.forEach((char, index) => {\r\n        char.style.fontSize = restore[index];\r\n      });\r\n      return width;\r\n    }\r\n\r\n    const previous = scope.style.fontSize;\r\n    scope.style.fontSize = `${fontSize}px`;\r\n    scope.offsetWidth;\r\n    const width = this.measureContentWidth(scope);\r\n    scope.style.fontSize = previous;\r\n    return width;\r\n  }\r\n\r\n  private measureCharScopeWidth(scope: HTMLElement): number {\r\n    let width = 0;\r\n\r\n    const chars = Array.from(scope.querySelectorAll(\".-s-char\")) as HTMLElement[];\r\n    chars.forEach((char) => {\r\n      const rect = char.getBoundingClientRect();\r\n      const style = window.getComputedStyle(char);\r\n      width +=\r\n        rect.width + (parseFloat(style.marginLeft) || 0) + (parseFloat(style.marginRight) || 0);\r\n    });\r\n\r\n    const walker = document.createTreeWalker(scope, NodeFilter.SHOW_TEXT);\r\n    let textNode: Node | null = walker.nextNode();\r\n    while (textNode) {\r\n      const parent = textNode.parentElement;\r\n      const inChar = !!parent?.closest(\".-s-char\");\r\n      const inLeafElement =\r\n        !!parent &&\r\n        !parent.classList.contains(\"-s-char\") &&\r\n        !parent.classList.contains(\"-s-word\") &&\r\n        !parent.classList.contains(\"-s-line\") &&\r\n        !parent.querySelector(\".-s-char, .-s-word, .-s-line\");\r\n\r\n      if (!inChar && !inLeafElement && textNode.textContent?.length) {\r\n        const range = document.createRange();\r\n        range.selectNodeContents(textNode);\r\n        width += range.getBoundingClientRect().width;\r\n      }\r\n\r\n      textNode = walker.nextNode();\r\n    }\r\n\r\n    const leafElements = Array.from(scope.querySelectorAll(\"*\")).filter((node) => {\r\n      const el = node as HTMLElement;\r\n      return (\r\n        !el.classList.contains(\"-s-char\") &&\r\n        !el.classList.contains(\"-s-word\") &&\r\n        !el.classList.contains(\"-s-line\") &&\r\n        !el.querySelector(\".-s-char, .-s-word, .-s-line\")\r\n      );\r\n    }) as HTMLElement[];\r\n\r\n    leafElements.forEach((leaf) => {\r\n      width += leaf.getBoundingClientRect().width;\r\n    });\r\n\r\n    return width;\r\n  }\r\n\r\n  private measureContentWidth(scope: HTMLElement): number {\r\n    if (!scope.childNodes.length) {\r\n      return scope.getBoundingClientRect().width;\r\n    }\r\n\r\n    const range = document.createRange();\r\n    range.selectNodeContents(scope);\r\n    return range.getBoundingClientRect().width;\r\n  }\r\n\r\n  /**\r\n   * Computes the target font size to fill `contentWidth`.\r\n   *\r\n   * Inter-word `\\u00a0` nodes in the DOM are NOT wrapped in `-s-char` spans, so they\r\n   * stay at the original font size and do not scale. The formula accounts for this by\r\n   * subtracting total space width (fitWidth - browserWordWidthSum) from both sides:\r\n   *\r\n   *   targetFontSize = currentFontSize * (contentWidth - spacesWidth) / (lineWidth - spacesWidth)\r\n   *\r\n   * For single-word lines spacesWidth = 0 and the formula reduces to the simple ratio.\r\n   */\r\n  private computeFitFontSize(\r\n    currentFontSize: number,\r\n    contentWidth: number,\r\n    lineWidth: number,\r\n    browserWordWidthSum: number | undefined,\r\n  ): number {\r\n    const spacesWidth = browserWordWidthSum !== undefined ? lineWidth - browserWordWidthSum : 0;\r\n    const scalableWidth = lineWidth - spacesWidth;\r\n    if (scalableWidth <= 0) return currentFontSize * (contentWidth / lineWidth);\r\n    return (currentFontSize * (contentWidth - spacesWidth)) / scalableWidth;\r\n  }\r\n\r\n  /**\r\n   * Computes a numeric value based on the provided split option, index, and total count.\r\n   *\r\n   * @param opt - The split option item containing alignment and optional random range.\r\n   * @param index - The current index in the sequence.\r\n   * @param total - The total number of items in the sequence.\r\n   * @returns A computed numeric value based on the alignment strategy:\r\n   *          - \"random\": A random value within the specified range or default range.\r\n   *          - \"start\": The current index.\r\n   *          - \"end\": The reverse index from the end of the sequence.\r\n   *          - \"center\": The distance from the center index.\r\n   *          - Default: The current index.\r\n   */\r\n  private computeValue(opt: ISplitOptionItem, index: number, total: number): number {\r\n    if (opt.align.startsWith(\"random\")) {\r\n      const min = opt.random?.min ?? 0;\r\n      const max = opt.random?.max ?? total - 1;\r\n      return Math.floor(Math.random() * (max - min + 1)) + min;\r\n    }\r\n    switch (opt.align) {\r\n      case \"start\":\r\n        return index;\r\n      case \"end\":\r\n        return total - index - 1;\r\n      case \"center\": {\r\n        const centerIdx = Math.floor((total - 1) / 2);\r\n        return Math.abs(index - centerIdx);\r\n      }\r\n      default:\r\n        return index;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Applies calculated values to the provided layout lines and their components (words and characters)\r\n   * based on the given options. This method computes and assigns various calculated values\r\n   * (e.g., alignment and value) to lines, words, and characters, depending on the specified options.\r\n   *\r\n   * @param lines - An array of `LayoutLine` objects representing the lines of text to process.\r\n   * @param options - An `ISplitOptions` object specifying the calculation options for lines, words, and characters.\r\n   *\r\n   * The `options` parameter can include the following properties:\r\n   * - `line`: An array of options for calculating values at the line level.\r\n   * - `word`: An array of options for calculating values at the word level.\r\n   * - `wordLine`: An array of options for calculating values at the word level relative to the line.\r\n   * - `char`: An array of options for calculating values at the character level.\r\n   * - `charWord`: An array of options for calculating values at the character level relative to the word.\r\n   * - `charLine`: An array of options for calculating values at the character level relative to the line.\r\n   *\r\n   * Each calculated value is assigned to the corresponding `calculatedValues` property of the line, word, or character.\r\n   * The method ensures that all specified options are processed and the calculated values are appended accordingly.\r\n   */\r\n  private applyCalculatedValues(lines: LayoutLine[], options: ISplitOptions): void {\r\n    const countChars = (ln: LayoutLine) =>\r\n      ln.words.reduce((acc, w: ProcessedWord) => acc + w.chars.length, 0);\r\n\r\n    const totalWords = lines.reduce((acc, l) => acc + l.words.length, 0);\r\n    const totalCharsGlobal = lines.reduce(\r\n      (acc, l) => acc + l.words.reduce((acc2, w) => acc2 + w.chars.length, 0),\r\n      0,\r\n    );\r\n\r\n    lines.forEach((line, li) => {\r\n      if (options.line) {\r\n        (line as any).calculatedValues = options.line.map(\r\n          (opt) =>\r\n            ({\r\n              type: \"line\",\r\n              align: opt.align,\r\n              value: this.computeValue(opt, li, lines.length),\r\n            }) as CalculatedValue,\r\n        );\r\n      }\r\n\r\n      line.words.forEach((word: ProcessedWord) => {\r\n        if (options.word) {\r\n          (word as any).calculatedValues = options.word.map(\r\n            (opt) =>\r\n              ({\r\n                type: \"word\",\r\n                align: opt.align,\r\n                value: this.computeValue(opt, word.wordIndexGlobal, totalWords),\r\n              }) as CalculatedValue,\r\n          );\r\n        }\r\n\r\n        if (options.wordLine) {\r\n          (word as any).calculatedValues ??= [];\r\n          (word as any).calculatedValues.push(\r\n            ...options.wordLine.map(\r\n              (opt) =>\r\n                ({\r\n                  type: \"wordLine\",\r\n                  align: opt.align,\r\n                  value: this.computeValue(opt, word.wordIndexInLine, line.words.length),\r\n                }) as CalculatedValue,\r\n            ),\r\n          );\r\n        }\r\n\r\n        const totalCharsInLine = countChars(line);\r\n\r\n        word.chars.forEach((char: ProcessedChar) => {\r\n          const cvs: CalculatedValue[] = [];\r\n\r\n          if (options.char) {\r\n            cvs.push(\r\n              ...options.char.map(\r\n                (opt) =>\r\n                  ({\r\n                    type: \"char\",\r\n                    align: opt.align,\r\n                    value: this.computeValue(opt, char.charIndexGlobal, totalCharsGlobal),\r\n                  }) as CalculatedValue,\r\n              ),\r\n            );\r\n          }\r\n\r\n          if (options.charWord) {\r\n            cvs.push(\r\n              ...options.charWord.map(\r\n                (opt) =>\r\n                  ({\r\n                    type: \"charWord\",\r\n                    align: opt.align,\r\n                    value: this.computeValue(opt, char.charIndexInWord, word.chars.length),\r\n                  }) as CalculatedValue,\r\n              ),\r\n            );\r\n          }\r\n\r\n          if (options.charLine) {\r\n            cvs.push(\r\n              ...options.charLine.map(\r\n                (opt) =>\r\n                  ({\r\n                    type: \"charLine\",\r\n                    align: opt.align,\r\n                    value: this.computeValue(opt, char.charIndexInLine, totalCharsInLine),\r\n                  }) as CalculatedValue,\r\n              ),\r\n            );\r\n          }\r\n\r\n          (char as any).calculatedValues = cvs;\r\n        });\r\n      });\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Escapes the `src` attribute in a given string by removing the quotes around the URL.\r\n   *\r\n   * This method searches for occurrences of `src=\"URL\"` where `URL` is an HTTP or HTTPS link,\r\n   * and replaces it with `src=URL` (removing the quotes around the URL).\r\n   *\r\n   * @param str - The input string containing the `src` attributes to be escaped.\r\n   * @returns The modified string with escaped `src` attributes.\r\n   */\r\n  private escapeAttribute(str: string): string {\r\n    return str.replace(/src=\"(https?:\\/\\/[^\"\\s]+)\"/g, \"src=$1\");\r\n  }\r\n}\r\n","import { StringContext } from \"../../core/StringContext\"\r\nimport { StringData } from \"../../core/StringData\"\r\nimport { StringModule } from \"../../core/StringModule\"\r\n\r\n/**\r\n * Visual tracker that plots scroll displacement (velocity) in real time.\r\n * Useful for debugging and tuning smoothing behavior.\r\n */\r\nexport class StringDelayLerpTracker extends StringModule {\r\n  private canvas!: HTMLCanvasElement\r\n  private context!: CanvasRenderingContext2D\r\n  private history: number[] = []\r\n\r\n  private maxPoints = 0\r\n  private height = 0\r\n  private value = 0\r\n  private target = 0\r\n\r\n  constructor(context: StringContext) {\r\n    super(context)\r\n    this._type = 2\r\n  }\r\n\r\n  /**\r\n   * Called when the module starts — sets up canvas.\r\n   */\r\n  onInit(): void {\r\n    this.initCanvas()\r\n    this.maxPoints = this.canvas.width\r\n  }\r\n\r\n  /**\r\n   * Called on scroll — stores current displacement and redraws.\r\n   */\r\n  onScroll(data: StringData): void {\r\n    const d = Math.abs(data.scroll.displacement)\r\n    this.value = d\r\n    this.history.push(d)\r\n\r\n    if (this.history.length > this.maxPoints) {\r\n      this.history.shift()\r\n    }\r\n\r\n    this.draw()\r\n  }\r\n\r\n  /**\r\n   * Draws the displacement graph to canvas.\r\n   */\r\n  private draw(): void {\r\n    const ctx = this.context\r\n    const w = this.canvas.width\r\n    const h = this.canvas.height\r\n\r\n    ctx.clearRect(0, 0, w, h)\r\n\r\n    ctx.strokeStyle = \"red\"\r\n    ctx.lineWidth = 2\r\n    ctx.beginPath()\r\n\r\n    this.history.forEach((val, i) => {\r\n      const x = i\r\n      const y = h - val * this.height\r\n      i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y)\r\n    })\r\n\r\n    ctx.stroke()\r\n  }\r\n\r\n  /**\r\n   * Creates and styles the tracking canvas.\r\n   */\r\n  private initCanvas(): void {\r\n    const canvas = document.createElement(\"canvas\")\r\n    const width = window.innerWidth * 0.5\r\n    this.height = window.innerHeight / 15 - 20\r\n\r\n    canvas.width = width\r\n    canvas.height = this.height\r\n\r\n    Object.assign(canvas.style, {\r\n      position: \"fixed\",\r\n      bottom: `${window.innerHeight / 20 + 10}px`,\r\n      left: \"50%\",\r\n      transform: \"translateX(-50%)\",\r\n      backgroundColor: \"#000000\",\r\n      border: \"1px solid rgba(255, 255, 255, 0.2)\",\r\n      zIndex: \"1000\",\r\n      pointerEvents: \"none\",\r\n    })\r\n\r\n    this.canvas = canvas\r\n    this.context = canvas.getContext(\"2d\")!\r\n    document.body.appendChild(canvas)\r\n  }\r\n\r\n  /**\r\n   * Optional method to update external comparison target.\r\n   */\r\n  public setTarget(position: number): void {\r\n    this.target = position\r\n  }\r\n\r\n  /**\r\n   * Removes the canvas from DOM and resets.\r\n   */\r\n  public clear(): void {\r\n    this.canvas.remove()\r\n    this.history = []\r\n  }\r\n}\r\n","import { StringData } from \"../..\";\r\nimport { StringContext } from \"../../core/StringContext\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\n\r\n/** Attribute selector for FPS tracker elements */\r\nconst ATTR_FPS = \"data-fps\";\r\n\r\n/**\r\n * FPS Tracker Module.\r\n * Broadcasts frame rate to elements with `data-fps` attribute.\r\n * Also creates an optional debug display element.\r\n */\r\nexport class StringFPSTracker extends StringModule {\r\n  private displayElement: HTMLDivElement | null = null;\r\n  private intervalId: number = 0;\r\n  private frameCount = 0;\r\n\r\n  /** Cached elements with data-fps attribute */\r\n  private fpsElements: Set<HTMLElement> = new Set();\r\n\r\n  /** MutationObserver for DOM changes */\r\n  private observer: MutationObserver | null = null;\r\n\r\n  /** Last known FPS to avoid redundant updates */\r\n  private lastFps = -1;\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this._type = 2;\r\n  }\r\n\r\n  /**\r\n   * Initializes the visual FPS counter, scans for elements, and starts interval.\r\n   */\r\n  onInit(): void {\r\n    if (this.data.system.fpsTracker) {\r\n      this.createDisplayElement();\r\n    }\r\n\r\n    // Listen for visibility toggle\r\n    this.events.on(\"tracker:fps:visible\", this.onVisibilityChange.bind(this));\r\n\r\n    this.scanElements();\r\n    this.observeDOM();\r\n\r\n    this.intervalId = window.setInterval(() => {\r\n      this.updateFPS(this.frameCount);\r\n      this.frameCount = 0;\r\n    }, 1000);\r\n  }\r\n\r\n  /**\r\n   * Increments the frame counter each frame.\r\n   */\r\n  onFrame(_data: StringData): void {\r\n    this.frameCount++;\r\n  }\r\n\r\n  /**\r\n   * Cleans up DOM, observer, and interval.\r\n   */\r\n  destroy(): void {\r\n    clearInterval(this.intervalId);\r\n    this.observer?.disconnect();\r\n    this.removeDisplayElement();\r\n    this.fpsElements.clear();\r\n  }\r\n\r\n  /**\r\n   * Handles visibility toggle from external API.\r\n   */\r\n  private onVisibilityChange(visible: boolean): void {\r\n    if (visible) {\r\n      this.createDisplayElement();\r\n    } else {\r\n      this.removeDisplayElement();\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Removes the display element and its styles.\r\n   */\r\n  private removeDisplayElement(): void {\r\n    this.displayElement?.remove();\r\n    this.displayElement = null;\r\n  }\r\n\r\n  /**\r\n   * Updates all tracked elements with current FPS.\r\n   */\r\n  private updateFPS(fps: number): void {\r\n    if (fps === this.lastFps) return;\r\n    this.lastFps = fps;\r\n\r\n    const fpsStr = String(fps);\r\n\r\n    // Update cached elements\r\n    for (const el of this.fpsElements) {\r\n      if (el.isConnected) {\r\n        el.setAttribute(ATTR_FPS, fpsStr);\r\n      }\r\n    }\r\n\r\n    // Update debug display\r\n    if (this.displayElement) {\r\n      this.displayElement.setAttribute(ATTR_FPS, fpsStr);\r\n    }\r\n\r\n    this.events.emit(\"fps\", fps);\r\n  }\r\n\r\n  /**\r\n   * Scans document for elements with data-fps attribute.\r\n   */\r\n  private scanElements(): void {\r\n    this.fpsElements.clear();\r\n\r\n    document.querySelectorAll<HTMLElement>(`[${ATTR_FPS}]`).forEach((el) => {\r\n      if (el !== this.displayElement) {\r\n        this.fpsElements.add(el);\r\n      }\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Observes DOM for added/removed elements with data-fps attribute.\r\n   */\r\n  private observeDOM(): void {\r\n    this.observer = new MutationObserver((mutations) => {\r\n      let needsRescan = false;\r\n\r\n      for (const mutation of mutations) {\r\n        // Check added nodes\r\n        for (const node of Array.from(mutation.addedNodes)) {\r\n          if (node.nodeType === Node.ELEMENT_NODE) {\r\n            const el = node as HTMLElement;\r\n            if (el.hasAttribute(ATTR_FPS)) needsRescan = true;\r\n            if (el.querySelector(`[${ATTR_FPS}]`)) needsRescan = true;\r\n          }\r\n        }\r\n\r\n        // Check removed nodes - clean from cache\r\n        for (const node of Array.from(mutation.removedNodes)) {\r\n          if (node.nodeType === Node.ELEMENT_NODE) {\r\n            this.fpsElements.delete(node as HTMLElement);\r\n          }\r\n        }\r\n      }\r\n\r\n      if (needsRescan) {\r\n        this.scanElements();\r\n      }\r\n    });\r\n\r\n    this.observer.observe(document.body, {\r\n      childList: true,\r\n      subtree: true,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Creates and styles the floating FPS display.\r\n   */\r\n  private createDisplayElement(): void {\r\n    if (this.displayElement) return;\r\n\r\n    const el = document.createElement(\"div\");\r\n\r\n    Object.assign(el.style, {\r\n      position: \"fixed\",\r\n      bottom: \"10px\",\r\n      right: \"10px\",\r\n      backgroundColor: \"#000\",\r\n      color: \"#fff\",\r\n      padding: \"4px 8px\",\r\n      fontSize: \"12px\",\r\n      fontFamily: \"monospace\",\r\n      border: \"1px solid rgba(255,255,255,0.2)\",\r\n      zIndex: \"1000\",\r\n      pointerEvents: \"none\",\r\n    });\r\n\r\n    el.setAttribute(ATTR_FPS, \"0\");\r\n    document.body.appendChild(el);\r\n\r\n    // Inject dynamic CSS\r\n    const styleId = \"string-fps-tracker-style\";\r\n    if (!document.getElementById(styleId)) {\r\n      const style = document.createElement(\"style\");\r\n      style.id = styleId;\r\n      style.innerHTML = `\r\n        [${ATTR_FPS}]::before {\r\n          content: 'FPS: ' attr(${ATTR_FPS});\r\n        }\r\n      `;\r\n      document.head.appendChild(style);\r\n    }\r\n\r\n    this.displayElement = el;\r\n  }\r\n}\r\n","import { StringData } from \"../..\"\r\nimport { StringContext } from \"../../core/StringContext\"\r\nimport { StringModule } from \"../../core/StringModule\"\r\n\r\n/**\r\n * Visual tracker that plots lerped scroll velocity (v) in real time.\r\n * Useful for analyzing smooth scroll interpolation behavior.\r\n */\r\nexport class StringLerpTracker extends StringModule {\r\n  private canvas!: HTMLCanvasElement\r\n  private context!: CanvasRenderingContext2D\r\n  private history: number[] = []\r\n\r\n  private maxPoints = 0\r\n  private canvasHeight = 0\r\n  private currentValue = 0\r\n  private targetValue = 0\r\n\r\n  constructor(context: StringContext) {\r\n    super(context)\r\n    this._type = 2\r\n  }\r\n\r\n  /**\r\n   * Called on start — sets up canvas overlay.\r\n   */\r\n  onInit(): void {\r\n    this.initCanvas()\r\n    this.maxPoints = this.canvas.width\r\n  }\r\n\r\n  /**\r\n   * Called on scroll — reads smoothed scroll velocity (v).\r\n   */\r\n  onScroll(data: StringData): void {\r\n    const v = Math.abs(data.scroll.displacement)\r\n    this.currentValue = v\r\n    this.history.push(v)\r\n\r\n    if (this.history.length > this.maxPoints) {\r\n      this.history.shift()\r\n    }\r\n\r\n    this.draw()\r\n  }\r\n\r\n  /**\r\n   * Draws the current graph line based on v-history.\r\n   */\r\n  private draw(): void {\r\n    const ctx = this.context\r\n    const w = this.canvas.width\r\n    const h = this.canvas.height\r\n\r\n    ctx.clearRect(0, 0, w, h)\r\n\r\n    ctx.strokeStyle = \"#007bff\"\r\n    ctx.lineWidth = 2\r\n    ctx.beginPath()\r\n\r\n    this.history.forEach((val, i) => {\r\n      const x = i\r\n      const y = h - val / 2\r\n      i === 0 ? ctx.moveTo(x, y) : ctx.lineTo(x, y)\r\n    })\r\n\r\n    ctx.stroke()\r\n  }\r\n\r\n  /**\r\n   * Creates the canvas overlay and applies style.\r\n   */\r\n  private initCanvas(): void {\r\n    this.canvas = document.createElement(\"canvas\")\r\n    this.canvasHeight = window.innerHeight / 15 - 20\r\n    this.canvas.width = window.innerWidth * 0.5\r\n    this.canvas.height = this.canvasHeight\r\n\r\n    Object.assign(this.canvas.style, {\r\n      position: \"fixed\",\r\n      bottom: \"10px\",\r\n      left: \"50%\",\r\n      transform: \"translateX(-50%)\",\r\n      backgroundColor: \"#000\",\r\n      border: \"1px solid rgba(255,255,255,0.2)\",\r\n      zIndex: \"1000\",\r\n      pointerEvents: \"none\",\r\n    })\r\n\r\n    this.context = this.canvas.getContext(\"2d\")!\r\n    document.body.appendChild(this.canvas)\r\n  }\r\n\r\n  /**\r\n   * Optional external target value for debugging.\r\n   */\r\n  public setTarget(position: number): void {\r\n    this.targetValue = position\r\n  }\r\n\r\n  /**\r\n   * Removes canvas from DOM and clears history.\r\n   */\r\n  public clear(): void {\r\n    this.canvas.remove()\r\n    this.history = []\r\n  }\r\n}\r\n","import { StringData } from \"../..\";\r\nimport { StringContext } from \"../../core/StringContext\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\n\r\n/** Attribute selectors for position tracker elements */\r\nconst ATTR_VAL = \"data-val\";\r\nconst ATTR_VAL_PCT = \"data-val-pct\";\r\nconst ATTR_DIR = \"data-dir\";\r\n\r\n/**\r\n * Tracker module that broadcasts scroll position to elements with data attributes.\r\n * Elements with `data-val`, `data-val-pct`, or `data-dir` will receive updates.\r\n * Also creates an optional debug display element.\r\n */\r\nexport class StringPositionTracker extends StringModule {\r\n  private displayElement: HTMLDivElement | null = null;\r\n\r\n  /** Cached elements by attribute type */\r\n  private valElements: Set<HTMLElement> = new Set();\r\n  private valPctElements: Set<HTMLElement> = new Set();\r\n  private dirElements: Set<HTMLElement> = new Set();\r\n\r\n  /** MutationObserver for DOM changes */\r\n  private observer: MutationObserver | null = null;\r\n\r\n  /** Last known values to avoid redundant updates */\r\n  private lastVal = -1;\r\n  private lastValPct = -1;\r\n  private lastDir = \"\";\r\n\r\n  /** Previous scroll position for direction detection */\r\n  private previousCurrent = 0;\r\n\r\n  /** Timeout for resetting direction to idle state */\r\n  private idleTimeout: ReturnType<typeof setTimeout> | null = null;\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this._type = 2;\r\n  }\r\n\r\n  /**\r\n   * Called on start — creates debug element and scans for tracked elements.\r\n   */\r\n  onInit(): void {\r\n    if (this.data.system.positionTracker) {\r\n      this.createDisplayElement();\r\n    }\r\n\r\n    // Listen for visibility toggle\r\n    this.events.on(\"tracker:position:visible\", this.onVisibilityChange.bind(this));\r\n\r\n    this.scanElements();\r\n    this.observeDOM();\r\n  }\r\n\r\n  /**\r\n   * Called on scroll — updates all tracked elements with position data.\r\n   */\r\n  onScroll(data: StringData): void {\r\n    const current = data.scroll.current;\r\n    const target = data.scroll.target;\r\n    const contentHeight = data.viewport.contentHeight;\r\n    const windowHeight = data.viewport.windowHeight;\r\n\r\n    const val = Math.round(current);\r\n    const maxScroll = Math.max(1, contentHeight - windowHeight);\r\n    const valPct = Math.round((current / maxScroll) * 100);\r\n\r\n    // Determine scroll direction\r\n    let direction: string;\r\n    if (current !== target) {\r\n      // Smooth scroll: compare current vs target (lerping)\r\n      direction = current < target ? \"↓\" : \"↑\";\r\n    } else if (current !== this.previousCurrent) {\r\n      // Default scroll: compare with previous position\r\n      direction = current > this.previousCurrent ? \"↓\" : \"↑\";\r\n    } else {\r\n      // No movement\r\n      direction = this.lastDir || \"•\";\r\n    }\r\n\r\n    this.previousCurrent = current;\r\n\r\n    // Reset idle timeout - will set direction to neutral after scroll stops\r\n    if (this.idleTimeout) {\r\n      clearTimeout(this.idleTimeout);\r\n    }\r\n    if (direction !== \"•\") {\r\n      this.idleTimeout = setTimeout(() => {\r\n        this.setDirection(\"•\");\r\n      }, 150);\r\n    }\r\n\r\n    // Update data-val elements\r\n    if (val !== this.lastVal) {\r\n      this.lastVal = val;\r\n      const valStr = String(val);\r\n      for (const el of this.valElements) {\r\n        if (el.isConnected) {\r\n          el.setAttribute(ATTR_VAL, valStr);\r\n        }\r\n      }\r\n      if (this.displayElement) {\r\n        this.displayElement.setAttribute(ATTR_VAL, valStr);\r\n      }\r\n    }\r\n\r\n    // Update data-val-pct elements\r\n    if (valPct !== this.lastValPct) {\r\n      this.lastValPct = valPct;\r\n      const pctStr = String(valPct);\r\n      for (const el of this.valPctElements) {\r\n        if (el.isConnected) {\r\n          el.setAttribute(ATTR_VAL_PCT, pctStr);\r\n        }\r\n      }\r\n      if (this.displayElement) {\r\n        this.displayElement.setAttribute(ATTR_VAL_PCT, pctStr);\r\n      }\r\n    }\r\n\r\n    // Update data-dir elements\r\n    this.setDirection(direction);\r\n\r\n    this.events.emit(\"scroll-position\", { val, valPct, direction });\r\n  }\r\n\r\n  /**\r\n   * Updates direction on all tracked elements.\r\n   */\r\n  private setDirection(direction: string): void {\r\n    if (direction === this.lastDir) return;\r\n    this.lastDir = direction;\r\n\r\n    for (const el of this.dirElements) {\r\n      if (el.isConnected) {\r\n        el.setAttribute(ATTR_DIR, direction);\r\n      }\r\n    }\r\n    if (this.displayElement) {\r\n      this.displayElement.setAttribute(ATTR_DIR, direction);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Cleans up DOM observer and display element.\r\n   */\r\n  destroy(): void {\r\n    if (this.idleTimeout) {\r\n      clearTimeout(this.idleTimeout);\r\n    }\r\n    this.observer?.disconnect();\r\n    this.removeDisplayElement();\r\n    this.valElements.clear();\r\n    this.valPctElements.clear();\r\n    this.dirElements.clear();\r\n  }\r\n\r\n  /**\r\n   * Handles visibility toggle from external API.\r\n   */\r\n  private onVisibilityChange(visible: boolean): void {\r\n    if (visible) {\r\n      this.createDisplayElement();\r\n    } else {\r\n      this.removeDisplayElement();\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Removes the display element.\r\n   */\r\n  private removeDisplayElement(): void {\r\n    this.displayElement?.remove();\r\n    this.displayElement = null;\r\n  }\r\n\r\n  /**\r\n   * Scans document for elements with tracking attributes.\r\n   */\r\n  private scanElements(): void {\r\n    this.valElements.clear();\r\n    this.valPctElements.clear();\r\n    this.dirElements.clear();\r\n\r\n    document.querySelectorAll<HTMLElement>(`[${ATTR_VAL}]`).forEach((el) => {\r\n      if (el !== this.displayElement) this.valElements.add(el);\r\n    });\r\n\r\n    document.querySelectorAll<HTMLElement>(`[${ATTR_VAL_PCT}]`).forEach((el) => {\r\n      if (el !== this.displayElement) this.valPctElements.add(el);\r\n    });\r\n\r\n    document.querySelectorAll<HTMLElement>(`[${ATTR_DIR}]`).forEach((el) => {\r\n      if (el !== this.displayElement) this.dirElements.add(el);\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Observes DOM for added/removed elements with tracking attributes.\r\n   */\r\n  private observeDOM(): void {\r\n    this.observer = new MutationObserver((mutations) => {\r\n      let needsRescan = false;\r\n\r\n      for (const mutation of mutations) {\r\n        // Check added nodes\r\n        for (const node of Array.from(mutation.addedNodes)) {\r\n          if (node.nodeType === Node.ELEMENT_NODE) {\r\n            const el = node as HTMLElement;\r\n            if (this.hasTrackingAttr(el)) needsRescan = true;\r\n            // Check descendants\r\n            if (el.querySelector(`[${ATTR_VAL}],[${ATTR_VAL_PCT}],[${ATTR_DIR}]`)) {\r\n              needsRescan = true;\r\n            }\r\n          }\r\n        }\r\n\r\n        // Check removed nodes - clean from cache\r\n        for (const node of Array.from(mutation.removedNodes)) {\r\n          if (node.nodeType === Node.ELEMENT_NODE) {\r\n            const el = node as HTMLElement;\r\n            this.valElements.delete(el);\r\n            this.valPctElements.delete(el);\r\n            this.dirElements.delete(el);\r\n          }\r\n        }\r\n      }\r\n\r\n      if (needsRescan) {\r\n        this.scanElements();\r\n      }\r\n    });\r\n\r\n    this.observer.observe(document.body, {\r\n      childList: true,\r\n      subtree: true,\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Checks if element has any tracking attribute.\r\n   */\r\n  private hasTrackingAttr(el: HTMLElement): boolean {\r\n    return el.hasAttribute(ATTR_VAL) || el.hasAttribute(ATTR_VAL_PCT) || el.hasAttribute(ATTR_DIR);\r\n  }\r\n\r\n  /**\r\n   * Creates and styles the floating position indicator.\r\n   */\r\n  private createDisplayElement(): void {\r\n    if (this.displayElement) return;\r\n\r\n    const el = document.createElement(\"div\");\r\n\r\n    Object.assign(el.style, {\r\n      position: \"fixed\",\r\n      bottom: \"10px\",\r\n      left: \"10px\",\r\n      backgroundColor: \"#000\",\r\n      color: \"#fff\",\r\n      border: \"1px solid rgba(255,255,255,0.2)\",\r\n      padding: \"5px 8px\",\r\n      fontSize: \"12px\",\r\n      fontFamily: \"monospace\",\r\n      zIndex: \"1000\",\r\n      pointerEvents: \"none\",\r\n    });\r\n\r\n    el.setAttribute(ATTR_DIR, \"•\");\r\n    el.setAttribute(ATTR_VAL, \"0\");\r\n    el.setAttribute(ATTR_VAL_PCT, \"0\");\r\n    document.body.appendChild(el);\r\n\r\n    // Inject dynamic CSS\r\n    const styleId = \"string-position-tracker-style\";\r\n    if (!document.getElementById(styleId)) {\r\n      const style = document.createElement(\"style\");\r\n      style.id = styleId;\r\n      style.innerHTML = `\r\n        [${ATTR_DIR}][${ATTR_VAL}][${ATTR_VAL_PCT}]::before {\r\n          content: attr(${ATTR_DIR}) ' | ' attr(${ATTR_VAL}) 'px (' attr(${ATTR_VAL_PCT}) '%)';\r\n        }\r\n      `;\r\n      document.head.appendChild(style);\r\n    }\r\n\r\n    this.displayElement = el;\r\n  }\r\n}\r\n","/**\r\n * Creates a debounced version of a function that delays invoking the function\r\n * until after `delay` milliseconds have passed since the last time the\r\n * debounced function was invoked.\r\n *\r\n * @template T The type of the function to debounce.\r\n * @param func The function to debounce.\r\n * @param delay The number of milliseconds to delay.\r\n * @returns The new debounced function.\r\n */\r\nexport function Debounce<T extends (...args: any[]) => any>(func: T, delay: number): (...args: Parameters<T>) => void {\r\n  let timeoutId: ReturnType<typeof setTimeout> | null = null;\r\n\r\n  // Return a new function that will be called instead of the original\r\n  return function(this: ThisParameterType<T>, ...args: Parameters<T>) {\r\n    // Capture the 'this' context and arguments for the original function\r\n    const context = this;\r\n\r\n    // If there is already a scheduled call, cancel it\r\n    if (timeoutId) {\r\n      clearTimeout(timeoutId);\r\n    }\r\n\r\n    // Schedule a new call to the original function after 'delay' ms\r\n    timeoutId = setTimeout(() => {\r\n      func.apply(context, args); // Call the original function with the correct 'this' and arguments\r\n      timeoutId = null; // Clear the timer ID after execution (optional but good practice)\r\n    }, delay);\r\n  };\r\n}","/**\r\n * Utility class that provides a customizable requestAnimationFrame loop.\r\n * Allows running a callback function on every frame or at a specific FPS rate.\r\n * Automatically pauses on `document.hidden` and resumes on visibility change.\r\n */\r\nexport class StringFPS {\r\n  /** Target frames per second (FPS). */\r\n  private fps: number = 0;\r\n\r\n  /** Whether the animation loop is currently active. */\r\n  private isAnimationStarted: boolean = false;\r\n\r\n  /** Time interval between frames in milliseconds, based on FPS. */\r\n  private fpsInterval: number = 0;\r\n\r\n  /** Timestamp of the previous frame (used for timing calculations). */\r\n  private then: number = 0;\r\n\r\n  /** The requestAnimationFrame ID (used to cancel the loop). */\r\n  private requestAnimationId: number = 0;\r\n\r\n  /** Bound function for visibilitychange event handler. */\r\n  private onVisibilityChangeBind: any;\r\n\r\n  /** Callback executed on each frame. */\r\n  private onFrameCallback: (time: number) => void = (time: number) => { };\r\n\r\n  /** Internal animation loop function. */\r\n  private animate: () => void = () => { };\r\n\r\n  constructor() {\r\n    this.onVisibilityChangeBind = this.onVisibilityChange.bind(this);\r\n  }\r\n\r\n  /**\r\n   * Handles visibility change events.\r\n   * Stops the loop when the document is hidden and resumes it when visible.\r\n   */\r\n  private onVisibilityChange() {\r\n    if (document.hidden) {\r\n      this.stop();\r\n      this.isAnimationStarted = false;\r\n    } else {\r\n      this.start(this.fps);\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Starts the animation loop at a given FPS rate.\r\n   * If `fps` is 0, runs the callback as fast as possible (uncapped).\r\n   * \r\n   * @param fps Target frames per second (0 = uncapped).\r\n   */\r\n  public start(fps: number) {\r\n    this.fps = fps;\r\n    if (this.isAnimationStarted) return;\r\n\r\n    this.fpsInterval = 1000 / fps;\r\n    this.then = performance.now();\r\n    this.isAnimationStarted = true;\r\n\r\n    if (fps === 0) {\r\n      this.animate = () => {\r\n        const now = performance.now();\r\n        this.requestAnimationId = requestAnimationFrame(this.animate);\r\n        this.onFrameCallback(now);\r\n      };\r\n    } else {\r\n      this.animate = () => {\r\n        const now = performance.now();\r\n        const elapsed = now - this.then;\r\n        if (elapsed > this.fpsInterval) {\r\n          this.then = now - (elapsed % this.fpsInterval);\r\n          this.onFrameCallback(now);\r\n        }\r\n        this.requestAnimationId = requestAnimationFrame(this.animate);\r\n      };\r\n    }\r\n\r\n    this.animate();\r\n    // document.addEventListener(\"visibilitychange\", this.onVisibilityChangeBind);\r\n  }\r\n\r\n  /**\r\n   * Stops the animation loop and removes the animation frame.\r\n   */\r\n  public stop() {\r\n    if (!this.isAnimationStarted) return;\r\n    cancelAnimationFrame(this.requestAnimationId);\r\n    this.requestAnimationId = 0;\r\n    this.isAnimationStarted = false;\r\n  }\r\n\r\n  /**\r\n   * Assigns a callback function to be called on each frame.\r\n   * \r\n   * @param callback The function to execute per frame.\r\n   */\r\n  public setOnFrame(callback: (time: number) => void) {\r\n    this.onFrameCallback = callback;\r\n  }\r\n\r\n  /**\r\n   * Stops the loop and removes event listeners.\r\n   * Should be called when the loop is no longer needed.\r\n   */\r\n  public destructor() {\r\n    this.stop();\r\n    // document.removeEventListener(\"visibilitychange\", this.onVisibilityChangeBind);\r\n  }\r\n}\r\n","import { StringObject } from \"../../objects/StringObject\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringContext } from \"../../core/StringContext\";\r\n\r\nexport class StringVideoAutoplay extends StringModule {\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"autoplay\";\r\n\r\n    this.attributesToMap = [\r\n      ...this.attributesToMap,\r\n      {\r\n        key: \"src\",\r\n        type: \"string\",\r\n        fallback: \"\",\r\n      },\r\n    ];\r\n  }\r\n\r\n  onObjectConnected(object: StringObject) {\r\n    object.setProperty(\"onEnterEvent\", this.onEnterObject.bind(this));\r\n    object.events.on(\r\n      \"enter\",\r\n      object.getProperty<(object: StringObject) => void>(\"onEnterEvent\")\r\n    );\r\n    object.setProperty(\"onLeaveEvent\", this.onLeaveObject.bind(this));\r\n    object.events.on(\r\n      \"leave\",\r\n      object.getProperty<(object: StringObject) => void>(\"onLeaveEvent\")\r\n    );\r\n\r\n    const videoElement = object.htmlElement as HTMLVideoElement;\r\n    const started =\r\n      this.tools.domAttribute.process({\r\n        element: videoElement,\r\n        key: \"string-started\",\r\n        fallback: null,\r\n      }) !== null;\r\n\r\n    if (videoElement.tagName.toLowerCase() === \"video\" && !started) {\r\n      videoElement.setAttribute(\"string-started\", \"\");\r\n      videoElement.muted = true;\r\n      videoElement.setAttribute(\"muted\", \"muted\");\r\n      videoElement.setAttribute(\"playsinline\", \"\");\r\n      videoElement.setAttribute(\"loop\", \"\");\r\n      videoElement.setAttribute(\"autoplay\", \"\");\r\n      videoElement.src = object.getProperty(\"src\");\r\n      videoElement.load();\r\n      videoElement.addEventListener(\"canplay\", () => {});\r\n    }\r\n  }\r\n\r\n  private onEnterObject(object: StringObject) {\r\n    const videoElement = object.htmlElement as HTMLVideoElement;\r\n    this.tryPlay(videoElement);\r\n  }\r\n  private onLeaveObject(object: StringObject) {\r\n    const videoElement = object.htmlElement as HTMLVideoElement;\r\n    videoElement.pause();\r\n  }\r\n\r\n  private tryPlay(element: HTMLVideoElement) {\r\n    element\r\n      .play()\r\n      .catch((err) =>\r\n        console.warn(\"[StringVideoAutoplay] Autoplay failed:\", err)\r\n      );\r\n  }\r\n}\r\n","/**\r\n * Discrete state classes applied to sequence elements.\r\n */\r\nexport enum SequenceState {\r\n  ACTIVE = \"-active\",\r\n  ENTERING = \"-entering\",\r\n  LEAVING = \"-leaving\",\r\n  DISABLED = \"-disabled\",\r\n}\r\n\r\n/**\r\n * Event data for sequence transitions.\r\n */\r\nexport interface SequenceEventData {\r\n  /** Slider identifier */\r\n  slider: string;\r\n  /** Current step index */\r\n  step: number;\r\n  /** Transition progress from 0 to 1 (optional, for manual scrubbing) */\r\n  transitionProgress?: number;\r\n  /** Direction of transition: 1 = forward, -1 = backward */\r\n  direction?: 1 | -1;\r\n  /** Custom duration for this transition in ms (overrides element's sequence-duration) */\r\n  duration?: number;\r\n  /** Skip animation and switch instantly */\r\n  instant?: boolean;\r\n}\r\n\r\n/**\r\n * CSS custom property names for sequence.\r\n */\r\nexport const SequenceProgressVars = {\r\n  /** Unified progress variable (0 to 1) */\r\n  PROGRESS: \"--sequence-progress\",\r\n  /** Direction of current transition (1 or -1) */\r\n  DIRECTION: \"--sequence-direction\",\r\n} as const;\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringData } from \"../../core/StringData\";\r\nimport {\r\n  SequenceState,\r\n  SequenceEventData,\r\n  SequenceProgressVars,\r\n} from \"../../models/slider/SequenceState\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { EasingFunctionOutput } from \"../../tools/EasingFunctionTool\";\r\nimport { styleTxn } from \"../../utils/style-txn\";\r\n\r\ninterface TransitionState {\r\n  fromStep: number;\r\n  toStep: number;\r\n  direction: 1 | -1;\r\n  startTime: number;\r\n  enteringDuration: number;\r\n  leavingDuration: number;\r\n}\r\n\r\ninterface StepElements {\r\n  objects: StringObject[];\r\n  enteringDuration: number;\r\n  leavingDuration: number;\r\n}\r\n\r\ninterface TriggerData {\r\n  slider: string;\r\n  step: number | \"next\" | \"prev\";\r\n  loop: boolean;\r\n}\r\n\r\ninterface GlobalSliderSettings {\r\n  enteringDuration?: number;\r\n  leavingDuration?: number;\r\n  enteringEasing?: string;\r\n  leavingEasing?: string;\r\n  activeStep?: number;\r\n}\r\n\r\ntype DurationKey = \"enteringDuration\" | \"leavingDuration\";\r\ntype EasingKey = \"enteringEasing\" | \"leavingEasing\";\r\n\r\nexport class StringSequence extends StringModule {\r\n  private activeStep = new Map<string, number>();\r\n  private leavingStep = new Map<string, number>();\r\n  private transitions = new Map<string, TransitionState>();\r\n  private elementIndex = new Map<string, StepElements>();\r\n  private triggerElements = new Map<HTMLElement, TriggerData>();\r\n  private globalSettings = new Map<string, GlobalSliderSettings>();\r\n  private stateRegistered = new Set<string>();\r\n  private lastEnteredStep = new Map<string, number>();\r\n  private defaultDuration: number;\r\n  private initialized = false;\r\n  private static readonly ALL_STATES = Object.values(SequenceState);\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"sequence\";\r\n    this.defaultDuration = this.settings[\"sequence-duration\"] ?? 600;\r\n\r\n    this.attributesToMap = [\r\n      ...this.attributesToMap,\r\n      { key: \"sequence\", type: \"string\", fallback: \"\" },\r\n      { key: \"sequence-trigger\", type: \"string\", fallback: \"\" },\r\n      { key: \"entering-easing\", type: \"string\", fallback: \"\" },\r\n      { key: \"leaving-easing\", type: \"string\", fallback: \"\" },\r\n      { key: \"entering-duration\", type: \"string\", fallback: \"\" },\r\n      { key: \"leaving-duration\", type: \"string\", fallback: \"\" },\r\n      { key: \"sequence-duration\", type: \"string\", fallback: \"\" },\r\n      { key: \"active-step\", type: \"string\", fallback: \"\" },\r\n    ];\r\n  }\r\n\r\n  onInit(): void {\r\n    super.onInit();\r\n    this.events.on<SequenceEventData>(\"sequence\", this.onSequenceEvent.bind(this));\r\n    this.scanStandaloneTriggers();\r\n  }\r\n\r\n  private scanStandaloneTriggers(): void {\r\n    const els = document.querySelectorAll<HTMLElement>(\r\n      \"[string-sequence-trigger]:not([string-inited])\"\r\n    );\r\n    for (const el of Array.from(els)) {\r\n      const trigger = el.getAttribute(\"string-sequence-trigger\");\r\n      const parsed = trigger ? this.parseTriggerKey(trigger) : null;\r\n      if (parsed) {\r\n        this.triggerElements.set(el, parsed);\r\n        el.addEventListener(\"click\", this.onTriggerClick);\r\n      }\r\n    }\r\n  }\r\n\r\n  private parseGlobalSettingsFromObject(object: StringObject): void {\r\n    const get = (k: string) => object.getProperty<string>(k);\r\n    const seq = get(\"sequence-duration\");\r\n\r\n    this.tryParseGlobalSetting(seq, \"enteringDuration\");\r\n    this.tryParseGlobalSetting(seq, \"leavingDuration\");\r\n    this.tryParseGlobalSetting(get(\"entering-duration\"), \"enteringDuration\");\r\n    this.tryParseGlobalSetting(get(\"leaving-duration\"), \"leavingDuration\");\r\n    this.tryParseGlobalSetting(get(\"entering-easing\"), \"enteringEasing\");\r\n    this.tryParseGlobalSetting(get(\"leaving-easing\"), \"leavingEasing\");\r\n    this.tryParseGlobalSetting(get(\"active-step\"), \"activeStep\");\r\n  }\r\n\r\n  private tryParseGlobalSetting(attr: string | null, key: keyof GlobalSliderSettings): void {\r\n    if (!attr) return;\r\n    const match = attr.match(/^(.+)\\[(.+)\\]$/);\r\n    if (!match) return;\r\n\r\n    const [, slider, value] = match;\r\n    const settings = this.globalSettings.get(slider) ?? {};\r\n    this.globalSettings.set(slider, settings);\r\n\r\n    (settings as Record<string, string | number>)[key] =\r\n      key === \"enteringEasing\" || key === \"leavingEasing\" ? value : parseFloat(value);\r\n\r\n    this.applyGlobalSettingsToExistingObjects(slider);\r\n  }\r\n\r\n  private applyGlobalSettingsToExistingObjects(slider: string): void {\r\n    const global = this.globalSettings.get(slider);\r\n    if (!global) return;\r\n\r\n    for (const [key, group] of this.elementIndex) {\r\n      const parsed = this.parseSequenceKey(key);\r\n      if (parsed?.slider !== slider) continue;\r\n\r\n      if (global.enteringDuration !== undefined) group.enteringDuration = global.enteringDuration;\r\n      if (global.leavingDuration !== undefined) group.leavingDuration = global.leavingDuration;\r\n\r\n      for (const obj of group.objects) this.resolveEasings(obj, key);\r\n    }\r\n  }\r\n\r\n  private initializeSliders(): void {\r\n    const sliders = new Set<string>();\r\n    for (const key of this.elementIndex.keys()) {\r\n      const p = this.parseSequenceKey(key);\r\n      if (p) sliders.add(p.slider);\r\n    }\r\n\r\n    for (const slider of sliders) {\r\n      if (this.activeStep.has(slider)) continue;\r\n      const global = this.globalSettings.get(slider);\r\n      let step = global?.activeStep ?? 0;\r\n      if (!this.elementIndex.has(`${slider}[${step}]`)) step = 0;\r\n      this.switchInstant(slider, step, 1);\r\n    }\r\n  }\r\n\r\n  private tryApplyPendingActiveStep(slider: string): void {\r\n    if (this.activeStep.has(slider)) return;\r\n    const step = this.globalSettings.get(slider)?.activeStep;\r\n    if (step !== undefined && this.elementIndex.has(`${slider}[${step}]`)) {\r\n      this.switchInstant(slider, step, 1);\r\n    }\r\n  }\r\n\r\n  override canConnect(object: StringObject): boolean {\r\n    return object.keys.includes(\"sequence\") || object.keys.includes(\"sequence-trigger\");\r\n  }\r\n\r\n  override onObjectConnected(object: StringObject): void {\r\n    super.onObjectConnected(object);\r\n    this.parseGlobalSettingsFromObject(object);\r\n\r\n    let sequence = object.getProperty<string>(\"sequence\");\r\n    const trigger = object.getProperty<string>(\"sequence-trigger\");\r\n\r\n    if (!sequence && trigger) {\r\n      const p = this.parseTriggerKey(trigger);\r\n      if (p && typeof p.step === \"number\") {\r\n        sequence = `${p.slider}[${p.step}]`;\r\n        object.setProperty(\"sequence\", sequence);\r\n      }\r\n    }\r\n\r\n    if (sequence) {\r\n      const parsed = this.parseSequenceKey(sequence);\r\n      if (parsed) {\r\n        this.ensureStateEventRegistered(parsed.slider);\r\n        let group = this.elementIndex.get(sequence);\r\n        if (!group) {\r\n          const { enteringDuration, leavingDuration } = this.resolveDurations(object, sequence);\r\n          group = { objects: [], enteringDuration, leavingDuration };\r\n          this.elementIndex.set(sequence, group);\r\n        }\r\n        group.objects.push(object);\r\n        this.resolveEasings(object, sequence);\r\n\r\n        const active = this.activeStep.get(parsed.slider);\r\n        this.setState(\r\n          object,\r\n          active === parsed.step ? SequenceState.ACTIVE : SequenceState.DISABLED,\r\n          active === parsed.step ? 1 : 0,\r\n          1\r\n        );\r\n        this.tryApplyPendingActiveStep(parsed.slider);\r\n      }\r\n    }\r\n\r\n    if (trigger) {\r\n      const p = this.parseTriggerKey(trigger);\r\n      if (p) {\r\n        this.triggerElements.set(object.htmlElement, p);\r\n        object.htmlElement.addEventListener(\"click\", this.onTriggerClick);\r\n      }\r\n    }\r\n  }\r\n\r\n  private ensureStateEventRegistered(slider: string): void {\r\n    if (this.stateRegistered.has(slider)) return;\r\n    this.stateRegistered.add(slider);\r\n    this.events.registerStateEvent?.(`sequence:active:${slider}`);\r\n  }\r\n\r\n  private parseTriggerKey(key: string): TriggerData | null {\r\n    const m = key.match(/^(.+)\\[(next|prev|\\d+)(\\|loop)?\\]$/);\r\n    if (!m) return null;\r\n    const step = m[2] === \"next\" || m[2] === \"prev\" ? m[2] : parseInt(m[2], 10);\r\n    return { slider: m[1], step, loop: m[3] === \"|loop\" };\r\n  }\r\n\r\n  private getMaxStep(slider: string): number {\r\n    let max = -1;\r\n    for (const key of this.elementIndex.keys()) {\r\n      const p = this.parseSequenceKey(key);\r\n      if (p?.slider === slider && p.step > max) max = p.step;\r\n    }\r\n    return max;\r\n  }\r\n\r\n  private resolveDuration(\r\n    object: StringObject,\r\n    slider: string,\r\n    key: DurationKey,\r\n    attrKey: string\r\n  ): number {\r\n    const attr = object.getProperty<string>(attrKey);\r\n    const seqAttr = object.getProperty<string>(\"sequence-duration\");\r\n    const global = this.globalSettings.get(slider)?.[key];\r\n\r\n    if (attr && !attr.includes(\"[\")) {\r\n      const v = parseFloat(attr);\r\n      if (!isNaN(v)) return v;\r\n    }\r\n    if (seqAttr && !seqAttr.includes(\"[\")) {\r\n      const v = parseFloat(seqAttr);\r\n      if (!isNaN(v)) return v;\r\n    }\r\n    return global ?? this.defaultDuration;\r\n  }\r\n\r\n  private resolveDurations(object: StringObject, sequence: string) {\r\n    const slider = this.parseSequenceKey(sequence)?.slider ?? \"\";\r\n    return {\r\n      enteringDuration: this.resolveDuration(\r\n        object,\r\n        slider,\r\n        \"enteringDuration\",\r\n        \"entering-duration\"\r\n      ),\r\n      leavingDuration: this.resolveDuration(object, slider, \"leavingDuration\", \"leaving-duration\"),\r\n    };\r\n  }\r\n\r\n  private resolveEasing(\r\n    object: StringObject,\r\n    slider: string,\r\n    key: EasingKey,\r\n    attrKey: string\r\n  ): void {\r\n    let easing = object.getProperty<string | EasingFunctionOutput>(attrKey);\r\n    if (!easing || (typeof easing === \"string\" && easing.includes(\"[\"))) {\r\n      easing = this.globalSettings.get(slider)?.[key] ?? this.settings[\"easing\"] ?? \"ease-out\";\r\n    }\r\n    if (typeof easing === \"string\") {\r\n      object.setProperty(attrKey, this.tools.easingFunction.process({ easing }));\r\n    }\r\n  }\r\n\r\n  private resolveEasings(object: StringObject, sequence: string): void {\r\n    const slider = this.parseSequenceKey(sequence)?.slider;\r\n    if (!slider) return;\r\n    this.resolveEasing(object, slider, \"enteringEasing\", \"entering-easing\");\r\n    this.resolveEasing(object, slider, \"leavingEasing\", \"leaving-easing\");\r\n  }\r\n\r\n  override onObjectDisconnected(object: StringObject): void {\r\n    super.onObjectDisconnected(object);\r\n\r\n    const sequence = object.getProperty<string>(\"sequence\");\r\n    if (sequence) {\r\n      const group = this.elementIndex.get(sequence);\r\n      if (group) {\r\n        const idx = group.objects.indexOf(object);\r\n        if (idx !== -1) group.objects.splice(idx, 1);\r\n        if (!group.objects.length) this.elementIndex.delete(sequence);\r\n      }\r\n    }\r\n\r\n    if (this.triggerElements.has(object.htmlElement)) {\r\n      object.htmlElement.removeEventListener(\"click\", this.onTriggerClick);\r\n      this.triggerElements.delete(object.htmlElement);\r\n    }\r\n  }\r\n\r\n  private parseSequenceKey(key: string): { slider: string; step: number } | null {\r\n    const m = key.match(/^(.+)\\[(\\d+)\\]$/);\r\n    return m ? { slider: m[1], step: parseInt(m[2], 10) } : null;\r\n  }\r\n\r\n  private onTriggerClick = (e: Event): void => {\r\n    const data = this.triggerElements.get(e.currentTarget as HTMLElement);\r\n    if (!data) return;\r\n\r\n    const current = this.activeStep.get(data.slider) ?? 0;\r\n    const max = this.getMaxStep(data.slider);\r\n    let target: number, dir: 1 | -1;\r\n\r\n    if (data.step === \"next\") {\r\n      target = current + 1;\r\n      dir = 1;\r\n      if (!this.elementIndex.has(`${data.slider}[${target}]`)) {\r\n        if (data.loop && max >= 0) target = 0;\r\n        else return;\r\n      }\r\n    } else if (data.step === \"prev\") {\r\n      target = current - 1;\r\n      dir = -1;\r\n      if (target < 0) {\r\n        if (data.loop && max >= 0) target = max;\r\n        else return;\r\n      }\r\n      if (!this.elementIndex.has(`${data.slider}[${target}]`)) return;\r\n    } else {\r\n      target = data.step;\r\n      if (current === target) return;\r\n      dir = target > current ? 1 : -1;\r\n    }\r\n\r\n    this.startTransition(data.slider, target, dir);\r\n  };\r\n\r\n  private onSequenceEvent(data: SequenceEventData): void {\r\n    const { slider, step, transitionProgress, direction = 1, duration, instant } = data;\r\n    const current = this.activeStep.get(slider);\r\n\r\n    if (current === step && transitionProgress === undefined) return;\r\n\r\n    if (transitionProgress !== undefined) {\r\n      this.handleScrub(slider, step, transitionProgress, direction);\r\n    } else if (instant) {\r\n      this.switchInstant(slider, step, direction);\r\n    } else {\r\n      this.startTransition(slider, step, direction, duration);\r\n    }\r\n  }\r\n\r\n  private startTransition(\r\n    slider: string,\r\n    toStep: number,\r\n    direction: 1 | -1,\r\n    customDuration?: number\r\n  ): void {\r\n    const fromStep = this.activeStep.get(slider);\r\n    const prevLeaving = this.leavingStep.get(slider);\r\n\r\n    this.ensureStateEventRegistered(slider);\r\n\r\n    if (prevLeaving !== undefined && prevLeaving !== fromStep) {\r\n      this.setStepState(slider, prevLeaving, SequenceState.DISABLED, 0, direction);\r\n    }\r\n\r\n    const enteringGroup = this.elementIndex.get(`${slider}[${toStep}]`);\r\n    const leavingGroup =\r\n      fromStep !== undefined ? this.elementIndex.get(`${slider}[${fromStep}]`) : null;\r\n\r\n    if (fromStep !== undefined) this.leavingStep.set(slider, fromStep);\r\n    this.activeStep.set(slider, toStep);\r\n    this.emitActiveState(slider, toStep);\r\n\r\n    const transition: TransitionState = {\r\n      fromStep: fromStep ?? toStep,\r\n      toStep,\r\n      direction,\r\n      startTime: this.data.time.now,\r\n      enteringDuration: customDuration ?? enteringGroup?.enteringDuration ?? this.defaultDuration,\r\n      leavingDuration: customDuration ?? leavingGroup?.leavingDuration ?? this.defaultDuration,\r\n    };\r\n\r\n    this.transitions.set(slider, transition);\r\n    this.emitTransitionStart(slider, transition);\r\n  }\r\n\r\n  private handleScrub(slider: string, step: number, progress: number, direction: 1 | -1): void {\r\n    this.transitions.delete(slider);\r\n    const current = this.activeStep.get(slider);\r\n\r\n    if (current !== step) {\r\n      const prev = this.leavingStep.get(slider);\r\n      if (prev !== undefined) this.setStepState(slider, prev, SequenceState.DISABLED, 0, direction);\r\n      if (current !== undefined) this.leavingStep.set(slider, current);\r\n      this.activeStep.set(slider, step);\r\n      this.emitActiveState(slider, step);\r\n    }\r\n\r\n    const fromStep = this.leavingStep.get(slider) ?? current ?? step;\r\n    this.applyProgress(slider, fromStep, step, progress, progress, direction);\r\n  }\r\n\r\n  private switchInstant(slider: string, step: number, direction: 1 | -1): void {\r\n    this.transitions.delete(slider);\r\n    const current = this.activeStep.get(slider);\r\n    const leaving = this.leavingStep.get(slider);\r\n\r\n    if (leaving !== undefined)\r\n      this.setStepState(slider, leaving, SequenceState.DISABLED, 0, direction);\r\n    if (current !== undefined && current !== step)\r\n      this.setStepState(slider, current, SequenceState.DISABLED, 0, direction);\r\n\r\n    this.activeStep.set(slider, step);\r\n    this.leavingStep.delete(slider);\r\n    this.setStepState(slider, step, SequenceState.ACTIVE, 1, direction);\r\n\r\n    this.emitActiveState(slider, step);\r\n    if (leaving !== undefined && leaving !== step)\r\n      this.emitStepLeave(slider, leaving, direction, true);\r\n    else if (current !== undefined && current !== step)\r\n      this.emitStepLeave(slider, current, direction, true);\r\n    this.emitStepEnter(slider, step, direction, true);\r\n\r\n    const transition: TransitionState = {\r\n      fromStep: current ?? step,\r\n      toStep: step,\r\n      direction,\r\n      startTime: this.data.time.now,\r\n      enteringDuration: 0,\r\n      leavingDuration: 0,\r\n    };\r\n    this.emitTransitionStart(slider, transition);\r\n    this.emitTransitionEnd(slider, step, current ?? step, direction, true);\r\n  }\r\n\r\n  private applyProgress(\r\n    slider: string,\r\n    fromStep: number,\r\n    toStep: number,\r\n    enteringProg: number,\r\n    leavingProg: number,\r\n    direction: 1 | -1\r\n  ): void {\r\n    const active = this.activeStep.get(slider)!;\r\n    const leaving = this.leavingStep.get(slider);\r\n\r\n    this.setStepState(\r\n      slider,\r\n      active,\r\n      enteringProg >= 1 ? SequenceState.ACTIVE : SequenceState.ENTERING,\r\n      enteringProg,\r\n      direction\r\n    );\r\n\r\n    if (leaving !== undefined && leaving !== active) {\r\n      if (leavingProg >= 1) {\r\n        this.setStepState(slider, leaving, SequenceState.DISABLED, 0, direction);\r\n        this.leavingStep.delete(slider);\r\n        this.emitStepLeave(slider, leaving, direction, false);\r\n      } else {\r\n        this.setStepState(slider, leaving, SequenceState.LEAVING, leavingProg, direction);\r\n      }\r\n    }\r\n\r\n    this.emitTransitionProgress(slider, fromStep, toStep, enteringProg, leavingProg, direction);\r\n\r\n    if (enteringProg >= 1) {\r\n      this.emitStepEnter(slider, active, direction, false);\r\n    }\r\n  }\r\n\r\n  private setStepState(\r\n    slider: string,\r\n    step: number,\r\n    state: SequenceState,\r\n    progress: number,\r\n    direction: 1 | -1\r\n  ): void {\r\n    const group = this.elementIndex.get(`${slider}[${step}]`);\r\n    if (group) for (const obj of group.objects) this.setState(obj, state, progress, direction);\r\n  }\r\n\r\n  private setState(\r\n    object: StringObject,\r\n    state: SequenceState,\r\n    rawProgress: number,\r\n    direction: 1 | -1\r\n  ): void {\r\n    const el = object.htmlElement;\r\n    const currentState = object.getProperty<SequenceState>(\"_state\");\r\n    const currentDir = object.getProperty<number>(\"_direction\");\r\n\r\n    const easing = object.getProperty<EasingFunctionOutput>(\r\n      state === SequenceState.LEAVING ? \"leaving-easing\" : \"entering-easing\"\r\n    );\r\n    const progress = typeof easing === \"function\" ? easing(rawProgress) : rawProgress;\r\n\r\n    if (currentState !== state) {\r\n      el.classList.remove(...StringSequence.ALL_STATES);\r\n      el.classList.add(state);\r\n      object.setProperty(\"_state\", state);\r\n    }\r\n\r\n    if (currentDir !== direction) {\r\n      object.setProperty(\"_direction\", direction);\r\n      styleTxn.run(() =>\r\n        styleTxn.setVars(el, { [SequenceProgressVars.DIRECTION]: direction.toString() })\r\n      );\r\n    }\r\n  }\r\n\r\n  onFrame(data: StringData): void {\r\n    super.onFrame(data);\r\n\r\n    if (!this.initialized) {\r\n      this.initialized = true;\r\n      this.initializeSliders();\r\n    }\r\n\r\n    for (const [slider, t] of this.transitions) {\r\n      const elapsed = data.time.now - t.startTime;\r\n      const enteringProg = Math.min(1, elapsed / t.enteringDuration);\r\n      const leavingProg = Math.min(1, elapsed / t.leavingDuration);\r\n\r\n      this.applyProgress(slider, t.fromStep, t.toStep, enteringProg, leavingProg, t.direction);\r\n\r\n      if (enteringProg >= 1 && leavingProg >= 1) {\r\n        this.emitTransitionEnd(slider, t.toStep, t.fromStep, t.direction, false);\r\n        this.transitions.delete(slider);\r\n      }\r\n    }\r\n  }\r\n\r\n  private emitTransitionStart(slider: string, t: TransitionState): void {\r\n    const payload = {\r\n      slider,\r\n      from: t.fromStep,\r\n      to: t.toStep,\r\n      direction: t.direction,\r\n      enteringDuration: t.enteringDuration,\r\n      leavingDuration: t.leavingDuration,\r\n      startedAt: t.startTime,\r\n    };\r\n    this.events.emit(\"sequence:transition:start\", payload);\r\n    this.events.emit(`sequence:transition:start:${slider}`, payload);\r\n  }\r\n\r\n  private emitTransitionProgress(\r\n    slider: string,\r\n    from: number,\r\n    to: number,\r\n    entering: number,\r\n    leaving: number,\r\n    direction: 1 | -1\r\n  ): void {\r\n    const payload = { slider, from, to, entering, leaving, direction };\r\n    this.events.emit(\"sequence:transition:progress\", payload);\r\n    this.events.emit(`sequence:transition:progress:${slider}`, payload);\r\n  }\r\n\r\n  private emitTransitionEnd(\r\n    slider: string,\r\n    to: number,\r\n    from: number,\r\n    direction: 1 | -1,\r\n    instant: boolean\r\n  ): void {\r\n    const payload = { slider, from, to, direction, instant };\r\n    this.events.emit(\"sequence:transition:end\", payload);\r\n    this.events.emit(`sequence:transition:end:${slider}`, payload);\r\n  }\r\n\r\n  private emitStepEnter(slider: string, step: number, direction: 1 | -1, instant: boolean): void {\r\n    if (!instant && this.lastEnteredStep.get(slider) === step) return;\r\n    this.lastEnteredStep.set(slider, step);\r\n    const payload = { slider, step, direction, instant };\r\n    this.events.emit(\"sequence:step:enter\", payload);\r\n    this.events.emit(`sequence:step:enter:${slider}`, payload);\r\n  }\r\n\r\n  private emitStepLeave(\r\n    slider: string,\r\n    step: number | null,\r\n    direction: 1 | -1,\r\n    instant: boolean\r\n  ): void {\r\n    if (step === null || step === undefined) return;\r\n    const payload = { slider, step, direction, instant };\r\n    this.events.emit(\"sequence:step:leave\", payload);\r\n    this.events.emit(`sequence:step:leave:${slider}`, payload);\r\n  }\r\n\r\n  private emitActiveState(slider: string, step: number): void {\r\n    const payload = { slider, step };\r\n    this.events.emit(\"sequence:active\", payload);\r\n    this.events.emit(`sequence:active:${slider}`, payload);\r\n  }\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { RuleParserResult } from \"../../tools/RuleParserTool\";\r\nimport type { ValidationContext } from \"../../tools/ValidationTool\";\r\n\r\ntype FormField = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;\r\n\r\ninterface RegisteredEvent {\r\n  eventElement: EventTarget;\r\n  eventType: string;\r\n  eventCallback: EventListenerOrEventListenerObject;\r\n}\r\n\r\ninterface FieldEntry {\r\n  field: FormField;\r\n  key: string;\r\n  rules: RuleParserResult[];\r\n  supportsRealtime: boolean;\r\n  needsContext: boolean;\r\n  inputEventType: \"input\" | \"change\";\r\n  inputHandler: EventListener;\r\n  beforeInputHandler?: EventListener;\r\n}\r\n\r\ntype FormState = {\r\n  object: StringObject;\r\n  form: HTMLFormElement;\r\n  entries: FieldEntry[];\r\n  values: Record<string, any>;\r\n  events: RegisteredEvent[];\r\n};\r\n\r\nexport class StringForm extends StringModule {\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"form\";\r\n  }\r\n\r\n  initializeObject(\r\n    globalId: number,\r\n    object: StringObject,\r\n    element: HTMLElement,\r\n    attributes: Record<string, any>\r\n  ): void {\r\n    super.initializeObject(globalId, object, element, attributes);\r\n\r\n    const existingEvents = object.getProperty<Array<RegisteredEvent>>(\"form-events\") ?? [];\r\n    existingEvents.forEach((evt) => {\r\n      evt.eventElement.removeEventListener(evt.eventType, evt.eventCallback);\r\n    });\r\n    existingEvents.length = 0;\r\n    object.setProperty(\"form-events\", existingEvents);\r\n\r\n    super.onObjectConnected(object);\r\n    const form = object.htmlElement as HTMLFormElement;\r\n\r\n    const fieldEntries: FieldEntry[] = [];\r\n    const fieldValues: Record<string, any> = {};\r\n\r\n    this.getInteractiveFields(form).forEach((field, idx) =>\r\n      this.registerField(field, form, fieldEntries, fieldValues, existingEvents, idx)\r\n    );\r\n\r\n    const submitCallback = (event: Event) => {\r\n      event.preventDefault();\r\n      let allValid = true;\r\n      const data: Record<string, any> = {};\r\n      const processedRadioKeys = new Set<string>();\r\n      for (const entry of fieldEntries) {\r\n        const field = entry.field;\r\n        if (!field.isConnected || !this.shouldValidateField(field)) continue;\r\n        if (this.isRadioField(field)) {\r\n          if (processedRadioKeys.has(entry.key)) {\r\n            continue;\r\n          }\r\n          processedRadioKeys.add(entry.key);\r\n        }\r\n        const { key, rules, needsContext } = entry;\r\n        const value = this.getFieldValue(field);\r\n        data[key] = value;\r\n        fieldValues[key] = value;\r\n\r\n        const { valid, errors } = this.tools.validation.process({\r\n          rules,\r\n          value,\r\n          context: this.buildContext(needsContext, key, fieldValues),\r\n        });\r\n\r\n        this.applyValidationState(form, field, key, valid, errors, \"submit\");\r\n\r\n        if (!valid) {\r\n          allValid = false;\r\n        }\r\n      }\r\n\r\n      if (allValid) {\r\n        this.events.emit(`form:submit:${object.id}`, data);\r\n      } else {\r\n        const processedRadioKeys = new Set<string>();\r\n        const firstInvalidEntry = fieldEntries.find((entry) => {\r\n          const field = entry.field;\r\n          if (!field.isConnected || !this.shouldValidateField(field)) return false;\r\n          if (this.isRadioField(field)) {\r\n            if (processedRadioKeys.has(entry.key)) {\r\n              return false;\r\n            }\r\n            processedRadioKeys.add(entry.key);\r\n          }\r\n          const { key, rules, needsContext } = entry;\r\n          const value = this.getFieldValue(field);\r\n          fieldValues[key] = value;\r\n          const { valid } = this.tools.validation.process({\r\n            rules,\r\n            value,\r\n            context: this.buildContext(needsContext, key, fieldValues),\r\n          });\r\n          return !valid;\r\n        });\r\n        if (firstInvalidEntry?.field && typeof firstInvalidEntry.field.focus === \"function\") {\r\n          firstInvalidEntry.field.focus();\r\n        }\r\n        this.events.emit(`form:invalid:${object.id}`);\r\n      }\r\n    };\r\n\r\n    form.addEventListener(\"submit\", submitCallback);\r\n    existingEvents.push({ eventElement: form, eventType: \"submit\", eventCallback: submitCallback });\r\n\r\n    object.setProperty(\"form-field-entries\", fieldEntries);\r\n    object.setProperty(\"form-field-values\", fieldValues);\r\n  }\r\n\r\n  onObjectConnected(object: StringObject) {}\r\n\r\n  onDOMMutate(added: NodeList, removed: NodeList): void {\r\n    if (this.objects.length === 0) {\r\n      return;\r\n    }\r\n\r\n    if (added.length > 0) {\r\n      this.handleMutationAdditions(added);\r\n    }\r\n\r\n    if (removed.length > 0) {\r\n      this.handleMutationRemovals(removed);\r\n    }\r\n  }\r\n\r\n  private applyValidationState(\r\n    form: HTMLFormElement,\r\n    field: FormField,\r\n    key: string,\r\n    valid: boolean,\r\n    errors: string[],\r\n    phase: \"live\" | \"submit\"\r\n  ): void {\r\n    const errorBlock = form.querySelector(`[string-input=\"error[${key}]\"]`);\r\n    const groupBlock = form.querySelector(`[string-input=\"group[${key}]\"]`);\r\n    if (errorBlock) {\r\n      errorBlock.innerHTML = \"\";\r\n      errors.forEach((message) => {\r\n        const span = document.createElement(\"span\");\r\n        span.textContent = message;\r\n        errorBlock.appendChild(span);\r\n      });\r\n    }\r\n    if (phase === \"live\") {\r\n      field.classList.toggle(\"-invalid\", !valid);\r\n      field.classList.remove(\"-error\");\r\n    } else {\r\n      field.classList.remove(\"-invalid\");\r\n      field.classList.toggle(\"-error\", !valid);\r\n    }\r\n    field.classList.toggle(\"-valid\", valid);\r\n    if (groupBlock) {\r\n      if (phase === \"live\") {\r\n        groupBlock.classList.toggle(\"-invalid\", !valid);\r\n        groupBlock.classList.remove(\"-error\");\r\n      } else {\r\n        groupBlock.classList.remove(\"-invalid\");\r\n        groupBlock.classList.toggle(\"-error\", !valid);\r\n      }\r\n      groupBlock.classList.toggle(\"-valid\", valid);\r\n    }\r\n\r\n    const eventSuffix = valid ? \"valid\" : phase === \"live\" ? \"invalid\" : \"error\";\r\n    this.events.emit(`form:field:${eventSuffix}:${key}`, {\r\n      key,\r\n      field,\r\n      errors,\r\n      phase,\r\n      valid,\r\n    });\r\n  }\r\n\r\n  private getInteractiveFields(form: HTMLFormElement): FormField[] {\r\n    return Array.from(form.querySelectorAll(\"[string-input]\"))\r\n      .filter((el) => !this.isServiceFieldAttribute(el.getAttribute(\"string-input\") || \"\"))\r\n      .filter((el): el is FormField => this.isFormFieldElement(el))\r\n      .map((el) => el as FormField);\r\n  }\r\n\r\n  private getFieldRules(field: FormField): RuleParserResult[] {\r\n    const ruleString =\r\n      this.tools.domAttribute.process({\r\n        element: field,\r\n        key: \"input\",\r\n      }) ?? \"\";\r\n    return this.tools.ruleParser.process({ value: ruleString });\r\n  }\r\n\r\n  private registerField(\r\n    field: FormField,\r\n    form: HTMLFormElement,\r\n    fieldEntries: FieldEntry[],\r\n    fieldValues: Record<string, any>,\r\n    events: RegisteredEvent[],\r\n    preferredIndex?: number\r\n  ): void {\r\n    if (!this.isFormFieldElement(field)) return;\r\n    if (field.closest(\"form\") !== form) return;\r\n    if (fieldEntries.some((entry) => entry.field === field)) return;\r\n\r\n    const registeredIndex = this.registerFieldIndex(field, preferredIndex ?? fieldEntries.length);\r\n    const key = this.getInputKey(field, registeredIndex);\r\n    const rules = this.getFieldRules(field);\r\n    const supportsRealtime = this.supportsBeforeInputValidation(rules);\r\n    const needsContext = this.requiresContext(rules);\r\n    const inputEventType = this.getInputEventType(field);\r\n\r\n    const entry: FieldEntry = {\r\n      field,\r\n      key,\r\n      rules,\r\n      supportsRealtime,\r\n      needsContext,\r\n      inputEventType,\r\n      inputHandler: () => undefined,\r\n    };\r\n\r\n    const inputHandler = (event: Event) => {\r\n      const target = (event.currentTarget || event.target) as FormField | null;\r\n      if (!target || !target.isConnected || !this.shouldValidateField(target)) {\r\n        return;\r\n      }\r\n      const value = this.getFieldValue(target);\r\n      fieldValues[entry.key] = value;\r\n      const context = this.buildContext(entry.needsContext, entry.key, fieldValues);\r\n\r\n      const { valid, errors } = this.tools.validation.process({\r\n        rules: entry.rules,\r\n        value,\r\n        context,\r\n      });\r\n\r\n      this.applyValidationState(form, target, entry.key, valid, errors, \"live\");\r\n    };\r\n\r\n    entry.inputHandler = inputHandler;\r\n    field.addEventListener(inputEventType, inputHandler);\r\n    events.push({ eventElement: field, eventType: inputEventType, eventCallback: inputHandler });\r\n\r\n    if (\r\n      supportsRealtime &&\r\n      (field instanceof HTMLInputElement || field instanceof HTMLTextAreaElement)\r\n    ) {\r\n      const beforeInputHandler = (event: Event) => {\r\n        const inputEvent = event as InputEvent;\r\n        if (inputEvent.isComposing || inputEvent.inputType?.startsWith(\"insertComposition\")) {\r\n          return;\r\n        }\r\n        const target = (event.currentTarget || event.target) as FormField | null;\r\n        if (\r\n          !target ||\r\n          !(target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) ||\r\n          !target.isConnected\r\n        ) {\r\n          return;\r\n        }\r\n\r\n        const start = target.selectionStart ?? 0;\r\n        const end = target.selectionEnd ?? 0;\r\n        let nextVal = target.value;\r\n\r\n        switch (inputEvent.inputType) {\r\n          case \"deleteContentBackward\":\r\n            nextVal =\r\n              start === end && start > 0\r\n                ? target.value.slice(0, start - 1) + target.value.slice(end)\r\n                : target.value.slice(0, start) + target.value.slice(end);\r\n            break;\r\n          case \"deleteContentForward\":\r\n            nextVal =\r\n              start === end && start < target.value.length\r\n                ? target.value.slice(0, start) + target.value.slice(start + 1)\r\n                : target.value.slice(0, start) + target.value.slice(end);\r\n            break;\r\n          case \"insertFromPaste\":\r\n          case \"insertFromDrop\":\r\n          case \"insertReplacementText\":\r\n            nextVal =\r\n              target.value.slice(0, start) + (inputEvent.data || \"\") + target.value.slice(end);\r\n            break;\r\n          default:\r\n            if (typeof inputEvent.data === \"string\") {\r\n              nextVal = target.value.slice(0, start) + inputEvent.data + target.value.slice(end);\r\n            }\r\n        }\r\n\r\n        const { errors } = this.tools.validation.process({\r\n          rules: entry.rules,\r\n          value: nextVal,\r\n          type: \"beforeinput\",\r\n          context: this.buildContext(entry.needsContext, entry.key, fieldValues, {\r\n            applied: true,\r\n            value: nextVal,\r\n          }),\r\n        });\r\n\r\n        if (errors.length > 0 && event.cancelable) {\r\n          event.preventDefault();\r\n        }\r\n      };\r\n\r\n      entry.beforeInputHandler = beforeInputHandler;\r\n      field.addEventListener(\"beforeinput\", beforeInputHandler);\r\n      events.push({\r\n        eventElement: field,\r\n        eventType: \"beforeinput\",\r\n        eventCallback: beforeInputHandler,\r\n      });\r\n    }\r\n\r\n    field.classList.add(\"-inited\");\r\n    fieldEntries.push(entry);\r\n    fieldValues[key] = this.getFieldValue(field);\r\n  }\r\n\r\n  private unregisterField(\r\n    field: FormField,\r\n    fieldEntries: FieldEntry[],\r\n    fieldValues: Record<string, any>,\r\n    events: RegisteredEvent[]\r\n  ): void {\r\n    const index = fieldEntries.findIndex((entry) => entry.field === field);\r\n    if (index === -1) return;\r\n    const entry = fieldEntries[index];\r\n    if (entry.inputHandler) {\r\n      field.removeEventListener(entry.inputEventType, entry.inputHandler);\r\n    }\r\n    if (entry.beforeInputHandler) {\r\n      field.removeEventListener(\"beforeinput\", entry.beforeInputHandler);\r\n    }\r\n    delete fieldValues[entry.key];\r\n    fieldEntries.splice(index, 1);\r\n    for (let i = events.length - 1; i >= 0; i--) {\r\n      const registered = events[i];\r\n      if (registered.eventElement !== field) continue;\r\n      if (\r\n        registered.eventCallback === entry.inputHandler ||\r\n        (entry.beforeInputHandler && registered.eventCallback === entry.beforeInputHandler)\r\n      ) {\r\n        events.splice(i, 1);\r\n      }\r\n    }\r\n    field.classList.remove(\"-inited\");\r\n  }\r\n\r\n  private collectInteractiveFieldsFromNode(node: Node): FormField[] {\r\n    const elements: Element[] = [];\r\n    if (node instanceof Element) {\r\n      if (node.hasAttribute(\"string-input\")) {\r\n        elements.push(node);\r\n      }\r\n      elements.push(...Array.from(node.querySelectorAll(\"[string-input]\")));\r\n    } else if (node instanceof DocumentFragment) {\r\n      elements.push(...Array.from(node.querySelectorAll(\"[string-input]\")));\r\n    }\r\n\r\n    return elements\r\n      .filter((el) => !this.isServiceFieldAttribute(el.getAttribute(\"string-input\") || \"\"))\r\n      .filter((el): el is FormField => this.isFormFieldElement(el));\r\n  }\r\n\r\n  private isRadioField(field: FormField): field is HTMLInputElement {\r\n    return field instanceof HTMLInputElement && field.type === \"radio\";\r\n  }\r\n\r\n  private handleMutationAdditions(nodes: NodeList): void {\r\n    nodes.forEach((node) => {\r\n      const fields = this.collectInteractiveFieldsFromNode(node);\r\n      fields.forEach((field) => {\r\n        const state = this.getFormStateByContainment(field);\r\n        if (!state) return;\r\n        this.registerField(field, state.form, state.entries, state.values, state.events);\r\n      });\r\n    });\r\n  }\r\n\r\n  private handleMutationRemovals(nodes: NodeList): void {\r\n    nodes.forEach((node) => {\r\n      const fields = this.collectInteractiveFieldsFromNode(node);\r\n      fields.forEach((field) => {\r\n        const state = this.getFormStateByReference(field);\r\n        if (!state) return;\r\n        this.unregisterField(field, state.entries, state.values, state.events);\r\n      });\r\n    });\r\n  }\r\n\r\n  private getFormStateByContainment(field: FormField): FormState | null {\r\n    const owner = this.objects.find(\r\n      (object) =>\r\n        object.htmlElement instanceof HTMLFormElement && object.htmlElement.contains(field)\r\n    );\r\n    if (!owner) return null;\r\n    return this.buildFormState(owner);\r\n  }\r\n\r\n  private getFormStateByReference(field: FormField): FormState | null {\r\n    for (const object of this.objects) {\r\n      const entries = object.getProperty<FieldEntry[]>(\"form-field-entries\");\r\n      if (!entries) continue;\r\n      if (entries.some((entry) => entry.field === field)) {\r\n        return this.buildFormState(object, entries);\r\n      }\r\n    }\r\n    return null;\r\n  }\r\n\r\n  private buildFormState(object: StringObject, entries?: FieldEntry[]): FormState | null {\r\n    const element = object.htmlElement;\r\n    if (!(element instanceof HTMLFormElement)) {\r\n      return null;\r\n    }\r\n    const stateEntries = entries ?? object.getProperty<FieldEntry[]>(\"form-field-entries\");\r\n    const values = object.getProperty<Record<string, any>>(\"form-field-values\");\r\n    const events = object.getProperty<Array<RegisteredEvent>>(\"form-events\");\r\n    if (!stateEntries || !values || !events) {\r\n      return null;\r\n    }\r\n    return {\r\n      object,\r\n      form: element,\r\n      entries: stateEntries,\r\n      values,\r\n      events,\r\n    };\r\n  }\r\n\r\n  private registerFieldIndex(field: FormField, idx: number): number {\r\n    const existing = field.getAttribute(\"data-string-form-index\");\r\n    if (existing !== null) {\r\n      return Number(existing);\r\n    }\r\n    field.setAttribute(\"data-string-form-index\", String(idx));\r\n    return idx;\r\n  }\r\n\r\n  private getFieldIndex(field: FormField, fallbackIdx: number): number {\r\n    const existing = field.getAttribute(\"data-string-form-index\");\r\n    if (existing !== null) {\r\n      const parsed = Number(existing);\r\n      return Number.isNaN(parsed) ? fallbackIdx : parsed;\r\n    }\r\n    return this.registerFieldIndex(field, fallbackIdx);\r\n  }\r\n\r\n  private shouldValidateField(field: FormField): boolean {\r\n    if (field.disabled) return false;\r\n    if (field instanceof HTMLInputElement && field.type === \"hidden\") return false;\r\n    return true;\r\n  }\r\n\r\n  private supportsBeforeInputValidation(rules: RuleParserResult[]): boolean {\r\n    return rules.some((rule) => StringForm.beforeInputRuleKeys.has(rule.key));\r\n  }\r\n\r\n  private requiresContext(rules: RuleParserResult[]): boolean {\r\n    return rules.some((rule) => StringForm.crossFieldRuleKeys.has(rule.key));\r\n  }\r\n\r\n  private buildContext(\r\n    needsContext: boolean,\r\n    fieldKey: string,\r\n    fieldValues: Record<string, any>,\r\n    override?: { applied: boolean; value: any }\r\n  ): ValidationContext {\r\n    if (!needsContext) {\r\n      return { fieldKey };\r\n    }\r\n\r\n    const needsOverride = Boolean(override?.applied);\r\n    const values = needsOverride ? { ...fieldValues, [fieldKey]: override!.value } : fieldValues;\r\n\r\n    return {\r\n      fieldKey,\r\n      values,\r\n      getValue: (lookupKey: string) => {\r\n        if (needsOverride && lookupKey === fieldKey) {\r\n          return override!.value;\r\n        }\r\n        return values[lookupKey];\r\n      },\r\n    };\r\n  }\r\n\r\n  private static readonly beforeInputRuleKeys = new Set([\r\n    \"number\",\r\n    \"integer\",\r\n    \"email\",\r\n    \"phone\",\r\n    \"letters\",\r\n    \"lettersSpaces\",\r\n    \"lettersNumbers\",\r\n    \"alpha\",\r\n    \"alpha_num\",\r\n    \"alpha_dash\",\r\n    \"digits\",\r\n    \"url\",\r\n    \"pattern\",\r\n  ]);\r\n\r\n  private static readonly crossFieldRuleKeys = new Set([\"same\", \"different\", \"after\", \"before\"]);\r\n\r\n  private static readonly serviceAttributePrefixes = [\"error\", \"group\"];\r\n\r\n  getInputKey(field: FormField, idx: number): string {\r\n    return (\r\n      this.tools.domAttribute.process({\r\n        element: field,\r\n        key: \"id\",\r\n      }) ||\r\n      field.getAttribute(\"name\") ||\r\n      field.getAttribute(\"id\") ||\r\n      `input-${idx}`\r\n    );\r\n  }\r\n\r\n  getFieldValue(field: FormField): any {\r\n    if (field instanceof HTMLInputElement) {\r\n      if (field.type === \"checkbox\") {\r\n        if (field.name) {\r\n          const form = field.form || field.closest(\"form\");\r\n          const checked = form\r\n            ? Array.from(\r\n                form.querySelectorAll<HTMLInputElement>(\r\n                  `input[type=\"checkbox\"][name=\"${field.name}\"]:checked`\r\n                )\r\n              )\r\n            : [field];\r\n          if (checked.length > 1) return checked.map((el) => el.value);\r\n          return checked.length === 1 ? checked[0].value : \"\";\r\n        }\r\n        return field.checked;\r\n      }\r\n      if (field.type === \"radio\") {\r\n        if (field.name) {\r\n          const form = field.form || field.closest(\"form\");\r\n          const checked = form?.querySelector<HTMLInputElement>(\r\n            `input[type=\"radio\"][name=\"${field.name}\"]:checked`\r\n          );\r\n          return checked ? checked.value : \"\";\r\n        }\r\n        return field.checked ? field.value : \"\";\r\n      }\r\n      if (field.type === \"file\") {\r\n        if (field.files && field.files.length > 0) {\r\n          return field.multiple ? Array.from(field.files) : field.files[0];\r\n        }\r\n        return field.value;\r\n      }\r\n      return field.value;\r\n    }\r\n    if (field instanceof HTMLSelectElement) {\r\n      if (field.multiple) {\r\n        return Array.from(field.selectedOptions).map((opt) => opt.value);\r\n      }\r\n      return field.value;\r\n    }\r\n    if (field instanceof HTMLTextAreaElement) {\r\n      return field.value;\r\n    }\r\n    return \"\";\r\n  }\r\n\r\n  private isServiceFieldAttribute(attr: string): boolean {\r\n    return StringForm.serviceAttributePrefixes.some((type) => attr.startsWith(`${type}[`));\r\n  }\r\n\r\n  private isFormFieldElement(element: Element): element is FormField {\r\n    return (\r\n      element instanceof HTMLInputElement ||\r\n      element instanceof HTMLSelectElement ||\r\n      element instanceof HTMLTextAreaElement\r\n    );\r\n  }\r\n\r\n  private getInputEventType(field: FormField): \"input\" | \"change\" {\r\n    if (\r\n      field instanceof HTMLSelectElement ||\r\n      (field instanceof HTMLInputElement && (field.type === \"checkbox\" || field.type === \"radio\"))\r\n    ) {\r\n      return \"change\";\r\n    }\r\n    return \"input\";\r\n  }\r\n}\r\n","import { StringObject } from \"../../objects/StringObject\";\r\n\r\ntype CenterState = {\r\n  cx: number;\r\n  cy: number;\r\n  valid: boolean;\r\n  ro?: ResizeObserver;\r\n  el?: HTMLElement;\r\n};\r\n\r\nexport class CenterCache {\r\n  private map = new WeakMap<StringObject, CenterState>();\r\n  private all: Set<StringObject> = new Set();\r\n\r\n  attach(obj: StringObject) {\r\n    if (this.map.has(obj)) return;\r\n    const el = obj.htmlElement;\r\n    const st: CenterState = { cx: 0, cy: 0, valid: false, el };\r\n    st.ro = new ResizeObserver(() => {\r\n      st.valid = false;\r\n    });\r\n    st.ro.observe(el);\r\n    this.map.set(obj, st);\r\n    this.all.add(obj);\r\n  }\r\n\r\n  detach(obj: StringObject) {\r\n    const st = this.map.get(obj);\r\n    if (!st) return;\r\n    st.ro?.disconnect();\r\n    this.map.delete(obj);\r\n    this.all.delete(obj);\r\n  }\r\n\r\n  invalidate(id: string) {\r\n    this.all.forEach((o) => {\r\n      if (o.id === id) {\r\n        const st = this.map.get(o);\r\n        if (st) st.valid = false;\r\n      }\r\n    });\r\n  }\r\n\r\n  invalidateAll() {\r\n    this.all.forEach((o) => {\r\n      const st = this.map.get(o);\r\n      if (st) st.valid = false;\r\n    });\r\n  }\r\n\r\n  getCenter(obj: StringObject): { cx: number; cy: number } {\r\n    const st = this.map.get(obj);\r\n    if (!st || !st.el) return { cx: 0, cy: 0 };\r\n    if (!st.valid) {\r\n      const r = st.el.getBoundingClientRect();\r\n      st.cx = r.left + r.width / 2;\r\n      st.cy = r.top + r.height / 2;\r\n      st.valid = true;\r\n    }\r\n    return { cx: st.cx, cy: st.cy };\r\n  }\r\n}\r\n","import { StringObject } from \"../../objects/StringObject\";\r\n\r\ntype HoverState = { enter?: () => void; leave?: () => void };\r\n\r\nexport class HoverTracker {\r\n  private active = new Set<StringObject>();\r\n  private subs = new WeakMap<StringObject, HoverState>();\r\n\r\n  track(obj: StringObject) {\r\n    if (this.subs.has(obj)) return;\r\n    const el = obj.htmlElement;\r\n\r\n    const enter = () => this.active.add(obj);\r\n    const leave = () => this.active.delete(obj);\r\n\r\n    el.addEventListener(\"pointerenter\", enter);\r\n    el.addEventListener(\"pointerleave\", leave);\r\n    this.subs.set(obj, { enter, leave });\r\n  }\r\n\r\n  untrack(obj: StringObject) {\r\n    const st = this.subs.get(obj);\r\n    if (!st) return;\r\n    const el = obj.htmlElement;\r\n    if (st.enter) el.removeEventListener(\"pointerenter\", st.enter);\r\n    if (st.leave) el.removeEventListener(\"pointerleave\", st.leave);\r\n    this.active.delete(obj);\r\n    this.subs.delete(obj);\r\n  }\r\n\r\n  isActive(obj: StringObject) {\r\n    return this.active.has(obj);\r\n  }\r\n  activeObjects(): StringObject[] {\r\n    return Array.from(this.active);\r\n  }\r\n}\r\n","export interface DevtoolsIconDef {\r\n  id: string;\r\n  viewBox: string;\r\n  content: string;\r\n}\r\n\r\n// icon-{size}_{name}  |  sizes: 20, 16, 12\r\nexport const DEVTOOLS_ICONS: DevtoolsIconDef[] = [\r\n  // ─── 20px ────────────────────────────────────────────────────────────────\r\n\r\n  {\r\n    id: \"icon-20_logo\",\r\n    viewBox: \"0 0 20 20\",\r\n    content: `<path fill=\"currentColor\" id=\"Combined-Shape\" d=\"M9.443,4.529L13.911,10.273L19.885,15.217L18.865,16.45L12.823,11.45L12.702,11.324L8.181,5.511C7.834,5.066 7.161,5.065 6.814,5.51L1.297,12.564L0.036,11.578L5.553,4.524C6.543,3.259 8.458,3.261 9.443,4.529ZM14.407,2.737L16.907,6.07L16.427,6.43L13.927,3.097L14.407,2.737ZM16.907,1.487L19.407,4.82L18.927,5.18L16.427,1.847L16.907,1.487Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-20_layout\",\r\n    viewBox: \"0 0 20 20\",\r\n    content: `<path fill=\"currentColor\" d=\"M8.4,1.25L11.6,1.25C14.024,1.25 15.231,1.296 16.156,1.768C17.05,2.223 17.777,2.95 18.232,3.844C18.704,4.769 18.75,5.976 18.75,8.4L18.75,11.6C18.75,14.024 18.704,15.231 18.232,16.156C17.777,17.05 17.05,17.777 16.156,18.232C15.231,18.704 14.024,18.75 11.6,18.75L8.4,18.75C5.976,18.75 4.769,18.704 3.844,18.232C2.95,17.777 2.223,17.05 1.768,16.156C1.296,15.231 1.25,14.024 1.25,11.6L1.25,8.4C1.25,5.976 1.296,4.769 1.768,3.844C2.223,2.95 2.95,2.223 3.844,1.768C4.769,1.296 5.976,1.25 8.4,1.25ZM8.4,2.75C6.343,2.75 5.31,2.704 4.525,3.104C3.913,3.416 3.416,3.913 3.104,4.525C2.704,5.31 2.75,6.343 2.75,8.4L2.75,11.6C2.75,13.657 2.704,14.69 3.104,15.475C3.416,16.087 3.913,16.584 4.525,16.896C5.31,17.296 6.343,17.25 8.4,17.25L11.6,17.25C13.657,17.25 14.69,17.296 15.475,16.896C16.087,16.584 16.584,16.087 16.896,15.475C17.296,14.69 17.25,13.657 17.25,11.6L17.25,8.4C17.25,6.343 17.296,5.31 16.896,4.525C16.584,3.913 16.087,3.416 15.475,3.104C14.69,2.704 13.657,2.75 11.6,2.75L8.4,2.75ZM6.5,8.5L5.5,8.5L5.5,7.5L6.5,7.5L6.5,8.5ZM14.5,10.5L13.5,10.5L13.5,9.5L14.5,9.5L14.5,10.5ZM14.5,6.5L13.5,6.5L13.5,5.5L14.5,5.5L14.5,6.5ZM14.5,8.5L13.5,8.5L13.5,7.5L14.5,7.5L14.5,8.5ZM6.5,10.5L5.5,10.5L5.5,9.5L6.5,9.5L6.5,10.5ZM6.5,4.5L5.5,4.5L5.5,3.5L6.5,3.5L6.5,4.5ZM6.5,6.5L5.5,6.5L5.5,5.5L6.5,5.5L6.5,6.5ZM6.5,14.5L5.5,14.5L5.5,13.5L6.5,13.5L6.5,14.5ZM6.5,12.5L5.5,12.5L5.5,11.5L6.5,11.5L6.5,12.5ZM14.5,16.5L13.5,16.5L13.5,15.5L14.5,15.5L14.5,16.5ZM6.5,16.5L5.5,16.5L5.5,15.5L6.5,15.5L6.5,16.5ZM14.5,4.5L13.5,4.5L13.5,3.5L14.5,3.5L14.5,4.5ZM14.5,12.5L13.5,12.5L13.5,11.5L14.5,11.5L14.5,12.5ZM14.5,14.5L13.5,14.5L13.5,13.5L14.5,13.5L14.5,14.5ZM10.5,14.5L9.5,14.5L9.5,13.5L10.5,13.5L10.5,14.5ZM10.5,6.5L9.5,6.5L9.5,5.5L10.5,5.5L10.5,6.5ZM10.5,16.5L9.5,16.5L9.5,15.5L10.5,15.5L10.5,16.5ZM10.5,4.5L9.5,4.5L9.5,3.5L10.5,3.5L10.5,4.5ZM10.5,8.5L9.5,8.5L9.5,7.5L10.5,7.5L10.5,8.5ZM10.5,10.5L9.5,10.5L9.5,9.5L10.5,9.5L10.5,10.5ZM10.5,12.5L9.5,12.5L9.5,11.5L10.5,11.5L10.5,12.5ZM6.5,20L5.5,20L5.5,19.5L6.5,19.5L6.5,20ZM6.5,0.5L5.5,0.5L5.5,0L6.5,0L6.5,0.5ZM14.5,20L13.5,20L13.5,19.5L14.5,19.5L14.5,20ZM14.5,0.5L13.5,0.5L13.5,0L14.5,0L14.5,0.5ZM10.5,20L9.5,20L9.5,19.5L10.5,19.5L10.5,20ZM10.5,0.5L9.5,0.5L9.5,0L10.5,0L10.5,0.5Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-20_intersection\",\r\n    viewBox: \"0 0 20 20\",\r\n    content: `<path fill=\"currentColor\" d=\"M12.702,1.659C13.408,2.018 13.982,2.592 14.341,3.298C14.577,3.76 14.589,4.044 14.75,4.341C14.958,4.726 15.274,5.042 15.659,5.25C15.956,5.41 16.24,5.423 16.702,5.659C17.408,6.018 17.982,6.592 18.341,7.298C18.704,8.009 18.75,8.936 18.75,10.8L18.75,13.2C18.75,15.064 18.704,15.991 18.341,16.702C17.982,17.408 17.408,17.982 16.702,18.341C15.991,18.704 15.064,18.75 13.2,18.75L10.8,18.75C8.936,18.75 8.009,18.704 7.298,18.341C6.592,17.982 6.018,17.408 5.659,16.702C5.423,16.24 5.411,15.956 5.25,15.659C5.042,15.274 4.726,14.958 4.341,14.75C4.044,14.589 3.76,14.577 3.298,14.341C2.592,13.982 2.018,13.408 1.659,12.702C1.296,11.991 1.25,11.064 1.25,9.2L1.25,6.8C1.25,4.936 1.296,4.009 1.659,3.298C2.018,2.592 2.592,2.018 3.298,1.659C4.009,1.296 4.936,1.25 6.8,1.25L9.2,1.25C11.064,1.25 11.991,1.296 12.702,1.659ZM13.715,5.502C13.61,5.36 13.515,5.211 13.431,5.055C13.265,4.748 13.248,4.456 13.005,3.979C12.789,3.555 12.445,3.211 12.021,2.995C11.45,2.704 10.697,2.75 9.2,2.75L6.8,2.75C5.303,2.75 4.55,2.704 3.979,2.995C3.555,3.211 3.211,3.555 2.995,3.979C2.704,4.55 2.75,5.303 2.75,6.8L2.75,9.2C2.75,10.697 2.704,11.45 2.995,12.021C3.211,12.445 3.555,12.789 3.979,13.005C4.456,13.248 4.748,13.265 5.055,13.431C5.275,13.55 5.481,13.69 5.672,13.848C5.562,13.658 5.5,13.438 5.5,13.203L5.5,10.8C5.5,8.997 5.531,8.1 5.881,7.411C6.217,6.752 6.752,6.217 7.411,5.881C8.1,5.531 8.997,5.5 10.8,5.5L13.2,5.5L13.626,5.5C13.658,5.5 13.687,5.501 13.715,5.502ZM6.152,14.328C6.31,14.519 6.45,14.725 6.569,14.945C6.735,15.252 6.752,15.544 6.995,16.021C7.211,16.445 7.555,16.789 7.979,17.005C8.55,17.296 9.303,17.25 10.8,17.25L13.2,17.25C14.697,17.25 15.45,17.296 16.021,17.005C16.445,16.789 16.789,16.445 17.005,16.021C17.296,15.45 17.25,14.697 17.25,13.2L17.25,10.8C17.25,9.303 17.296,8.55 17.005,7.979C16.789,7.555 16.445,7.211 16.021,6.995C15.544,6.752 15.252,6.735 14.945,6.569C14.789,6.485 14.641,6.39 14.5,6.286L14.5,6.8L14.5,9.2C14.5,11.003 14.469,11.9 14.119,12.589C13.783,13.248 13.248,13.783 12.589,14.119C11.9,14.469 11.003,14.5 9.2,14.5L6.797,14.5C6.562,14.5 6.342,14.438 6.152,14.328ZM13.5,6.5L13.2,6.5L10.8,6.5C9.242,6.5 8.46,6.469 7.865,6.772C7.395,7.012 7.012,7.395 6.772,7.865C6.469,8.46 6.5,9.242 6.5,10.8L6.5,13.203C6.5,13.367 6.633,13.5 6.797,13.5L9.2,13.5C10.758,13.5 11.54,13.531 12.135,13.228C12.605,12.988 12.988,12.605 13.228,12.135C13.531,11.54 13.5,10.758 13.5,9.2L13.5,6.8L13.5,6.5ZM10,8C11.104,8 12,8.896 12,10C12,11.104 11.104,12 10,12C8.896,12 8,11.104 8,10C8,8.896 8.896,8 10,8Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-20_progress\",\r\n    viewBox: \"0 0 20 20\",\r\n    content: `<path fill=\"currentColor\" d=\"M11.6,2.5L11.6,1.5L12.402,1.501L12.398,2.501L11.6,2.5ZM11.6,2.5L11.4,2.5L11.4,1.5L11.598,1.5L11.6,2.5ZM2.5,11.378L2.501,12.376L1.501,12.379L1.5,11.378L2.5,11.378ZM6.105,18.243C4.791,18.574 3.416,18.75 2,18.75L2,17.25C2.393,17.25 2.783,17.235 3.169,17.206L3.683,16.624C3.879,16.796 4.094,16.948 4.326,17.074C10.886,16.07 16.07,10.886 17.074,4.326C16.951,4.1 16.804,3.89 16.636,3.698L17.203,3.203C17.234,2.806 17.25,2.405 17.25,2L18.75,2C18.75,3.424 18.572,4.807 18.238,6.128L18.469,6.116C18.484,6.421 18.492,6.758 18.496,7.136L17.946,7.141C16.296,12.264 12.245,16.31 7.119,17.953L7.113,18.496C6.735,18.492 6.398,18.484 6.093,18.468L6.105,18.243ZM9.4,1.5L9.4,2.5L8.363,2.5L8.363,1.5L9.4,1.5ZM2.5,9.378L1.5,9.378L1.5,8.378L2.5,8.378L2.5,9.378ZM14.348,2.568L14.448,1.573C14.864,1.615 15.216,1.681 15.53,1.781L15.227,2.734C14.972,2.653 14.685,2.602 14.348,2.568ZM17.5,9.141L18.5,9.141L18.5,10.141L17.5,10.141L17.5,9.141ZM17.5,12.14L18.5,12.141C18.499,12.509 18.497,12.843 18.492,13.149L17.492,13.132C17.498,12.831 17.499,12.502 17.5,12.14ZM17.326,15.012L18.298,15.246C18.227,15.539 18.133,15.8 18.01,16.043C17.964,16.133 17.915,16.221 17.864,16.307L17.005,15.794C17.045,15.727 17.083,15.659 17.119,15.589C17.208,15.413 17.275,15.224 17.326,15.012ZM15.777,17.015L16.285,17.877C16.206,17.923 16.125,17.968 16.043,18.01C15.794,18.137 15.525,18.233 15.221,18.304L14.993,17.33C15.213,17.279 15.408,17.211 15.589,17.119C15.653,17.086 15.716,17.051 15.777,17.015ZM13.11,17.493L13.127,18.493C12.821,18.498 12.486,18.499 12.119,18.5L12.118,17.5C12.48,17.499 12.809,17.498 13.11,17.493ZM10.119,17.5L10.119,18.5L9.119,18.5L9.119,17.5L10.119,17.5ZM2.728,15.209L1.773,15.506C1.676,15.192 1.611,14.84 1.57,14.425L2.565,14.327C2.599,14.665 2.649,14.953 2.728,15.209ZM2.52,6.396L1.521,6.36C1.535,5.966 1.56,5.622 1.6,5.316L2.591,5.447C2.555,5.725 2.533,6.038 2.52,6.396ZM3.232,3.858L2.441,3.246C2.671,2.949 2.937,2.682 3.233,2.451L3.848,3.24C3.618,3.419 3.411,3.627 3.232,3.858ZM5.433,2.593L5.3,1.602C5.606,1.561 5.95,1.536 6.345,1.521L6.382,2.52C6.024,2.534 5.711,2.556 5.433,2.593Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-20_ruler\",\r\n    viewBox: \"0 0 20 20\",\r\n    content: `<path fill=\"currentColor\" d=\"M6,17.75C4.915,17.75 4.376,17.718 3.948,17.541C3.343,17.29 2.847,16.832 2.55,16.248C2.296,15.75 2.25,15.104 2.25,13.8L2.25,6.2C2.25,4.896 2.296,4.25 2.55,3.752C2.813,3.234 3.234,2.813 3.752,2.55C4.25,2.296 4.896,2.25 6.2,2.25L13.8,2.25C15.104,2.25 15.75,2.296 16.248,2.55C16.832,2.847 17.29,3.343 17.541,3.948C17.718,4.376 17.75,4.915 17.75,6L17.75,6.4C17.75,7.144 17.704,7.51 17.559,7.794C17.391,8.124 17.124,8.391 16.794,8.559C16.51,8.704 16.144,8.75 15.4,8.75L10,8.75L10,7.25L12.5,7.25L12.5,6L13.5,6L13.5,7.25L15.4,7.25C15.61,7.25 15.777,7.25 15.916,7.244C16.002,7.24 16.064,7.248 16.113,7.223C16.161,7.199 16.199,7.161 16.223,7.113C16.248,7.064 16.244,6.916 16.244,6.916C16.244,6.916 16.25,5.61 16.25,5.4C16.25,5.4 16.243,4.735 16.155,4.522C16.041,4.247 15.833,4.021 15.567,3.886C15.21,3.704 14.737,3.75 13.8,3.75L6.2,3.75C5.263,3.75 4.79,3.704 4.433,3.886C4.197,4.006 4.006,4.197 3.886,4.433C3.704,4.79 3.75,5.263 3.75,6.2L3.75,13.8C3.75,14.737 3.704,15.21 3.886,15.567C4.021,15.833 4.247,16.041 4.522,16.155C4.829,16.282 5.221,16.25 6,16.25L6,17.75ZM6,17.75L6.006,16.25L6.399,16.25C6.609,16.25 6.777,16.25 6.916,16.244C7.002,16.24 7.064,16.248 7.113,16.223C7.161,16.199 7.199,16.161 7.223,16.113C7.248,16.064 7.24,16.002 7.244,15.916C7.25,15.777 7.25,15.61 7.25,15.4L7.25,13.5L6,13.5L6,12.5L7.25,12.5L7.25,8.5L6,8.5L6,7.5L7.25,7.5L7.25,6L8.75,6L8.75,15.4C8.75,16.144 8.704,16.51 8.559,16.794C8.391,17.124 8.124,17.391 7.794,17.559C7.51,17.704 7.144,17.75 6.4,17.75L6,17.75Z\"/>`,\r\n  },\r\n\r\n  // ─── 16px ────────────────────────────────────────────────────────────────\r\n\r\n  {\r\n    id: \"icon-16_noplus\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M2.38,0.675L7.499,6.647L7.5,1L8.5,1L8.5,7.5L15,7.5L15,8.5L9.085,8.498L14.38,14.675L13.62,15.325L1.62,1.325L2.38,0.675ZM7.5,10.119L8.5,11.286L8.5,15L7.5,15L7.5,10.119ZM5.254,7.499L6.111,8.499L1,8.5L1,7.5L5.254,7.499Z\" />`,\r\n  },\r\n  {\r\n    id: \"icon-16_nooffset\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M12.067,11.976L14.38,14.675L13.62,15.325L1.62,1.325L2.38,0.675L5.23,4L10.8,4C11.92,4 12.48,4 12.908,4.218C13.284,4.41 13.59,4.716 13.782,5.092C14,5.52 14,6.08 14,7.2L14,8.8C14,9.92 14,10.48 13.782,10.908C13.59,11.284 13.284,11.59 12.908,11.782C12.684,11.896 12.424,11.95 12.067,11.976ZM2.681,4.497L9.111,11.999L5.2,12C4.08,12 3.52,12 3.092,11.782C2.716,11.59 2.41,11.284 2.218,10.908C2,10.48 2,9.92 2,8.8L2,7.2C2,6.08 2,5.52 2.218,5.092C2.334,4.865 2.491,4.663 2.681,4.497ZM12.646,0.646L13.354,1.354L11,3.707L8.646,1.354L9.354,0.646L11,2.293L12.646,0.646ZM7.354,14.646L6.646,15.354L5,13.707L3.354,15.354L2.646,14.646L5,12.293L7.354,14.646Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_settings\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M8.208,1.177C8.363,1.209 8.524,1.303 8.846,1.489L13.216,4.011C13.538,4.197 13.699,4.291 13.805,4.408C13.899,4.512 13.97,4.635 14.013,4.768C14.062,4.919 14.062,5.105 14.062,5.477L14.062,10.523C14.062,10.895 14.062,11.081 14.013,11.232C13.97,11.365 13.899,11.488 13.805,11.592C13.699,11.709 13.538,11.803 13.216,11.989L8.846,14.511C8.524,14.697 8.363,14.791 8.208,14.823C8.071,14.853 7.929,14.853 7.792,14.823C7.637,14.791 7.476,14.697 7.154,14.511L2.784,11.989C2.462,11.803 2.301,11.709 2.195,11.592C2.101,11.488 2.03,11.365 1.987,11.232C1.938,11.081 1.938,10.895 1.938,10.523L1.938,5.477C1.938,5.105 1.938,4.919 1.987,4.768C2.03,4.635 2.101,4.512 2.195,4.408C2.301,4.291 2.462,4.197 2.784,4.011L7.154,1.489C7.476,1.303 7.637,1.209 7.792,1.177C7.929,1.147 8.071,1.147 8.208,1.177ZM8,5C6.343,5 5,6.343 5,8C5,9.657 6.343,11 8,11C9.657,11 11,9.657 11,8C11,6.343 9.657,5 8,5Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_options\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M9,7L9,9L7,9L7,7L9,7ZM9,3L9,5L7,5L7,3L9,3ZM9,11L9,13L7,13L7,11L9,11Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_grab\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M10,4L12,4L12,6L10,6L10,4ZM10,10L12,10L12,12L10,12L10,10ZM7,4L9,4L9,6L7,6L7,4ZM7,10L9,10L9,12L7,12L7,10ZM7,13L9,13L9,15L7,15L7,13ZM4,4L6,4L6,6L4,6L4,4ZM7,1L9,1L9,3L7,3L7,1ZM4,10L6,10L6,12L4,12L4,10Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_eye\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M8,3C10.692,3 13.2,4.46 15.526,7.381C15.815,7.744 15.815,8.256 15.526,8.619C13.2,11.54 10.692,13 8,13C5.308,13 2.8,11.54 0.474,8.619C0.185,8.256 0.185,7.744 0.474,7.381C2.8,4.46 5.308,3 8,3ZM8,5C6.343,5 5,6.343 5,8C5,9.657 6.343,11 8,11C9.657,11 11,9.657 11,8C11,6.343 9.657,5 8,5Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_offset\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M5.2,4L10.8,4C11.92,4 12.48,4 12.908,4.218C13.284,4.41 13.59,4.716 13.782,5.092C14,5.52 14,6.08 14,7.2L14,8.8C14,9.92 14,10.48 13.782,10.908C13.59,11.284 13.284,11.59 12.908,11.782C12.48,12 11.92,12 10.8,12L5.2,12C4.08,12 3.52,12 3.092,11.782C2.716,11.59 2.41,11.284 2.218,10.908C2,10.48 2,9.92 2,8.8L2,7.2C2,6.08 2,5.52 2.218,5.092C2.41,4.716 2.716,4.41 3.092,4.218C3.52,4 4.08,4 5.2,4ZM12.646,0.646L13.354,1.354L11,3.707L8.646,1.354L9.354,0.646L11,2.293L12.646,0.646ZM7.354,14.646L6.646,15.354L5,13.707L3.354,15.354L2.646,14.646L5,12.293L7.354,14.646Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_play-l\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M11.293,3.281C11.769,2.923 12.007,2.745 12.266,2.75C12.491,2.755 12.702,2.86 12.841,3.038C13,3.241 13,3.539 13,4.134L13,11.866C13,12.461 13,12.759 12.841,12.962C12.702,13.14 12.491,13.245 12.266,13.25C12.007,13.255 11.769,13.077 11.293,12.719L6.225,8.919C5.827,8.621 5.629,8.471 5.551,8.272C5.483,8.097 5.483,7.903 5.551,7.728C5.629,7.529 5.827,7.379 6.225,7.081L11.293,3.281ZM2.8,3L4.2,3C4.48,3 4.62,3 4.727,3.054C4.821,3.102 4.898,3.179 4.946,3.273C5,3.38 5,3.52 5,3.8L5,12.2C5,12.48 5,12.62 4.946,12.727C4.898,12.821 4.821,12.898 4.727,12.946C4.62,13 4.48,13 4.2,13L2.8,13C2.52,13 2.38,13 2.273,12.946C2.179,12.898 2.102,12.821 2.054,12.727C2,12.62 2,12.48 2,12.2L2,3.8C2,3.52 2,3.38 2.054,3.273C2.102,3.179 2.179,3.102 2.273,3.054C2.38,3 2.52,3 2.8,3Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_play-r\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M4.707,3.281L9.775,7.081C10.173,7.379 10.371,7.529 10.449,7.728C10.517,7.903 10.517,8.097 10.449,8.272C10.371,8.471 10.173,8.621 9.775,8.919L4.707,12.719C4.231,13.077 3.993,13.255 3.734,13.25C3.509,13.245 3.298,13.14 3.159,12.962C3,12.759 3,12.461 3,11.866L3,4.134C3,3.539 3,3.241 3.159,3.038C3.298,2.86 3.509,2.755 3.734,2.75C3.993,2.745 4.231,2.923 4.707,3.281ZM11.8,3L13.2,3C13.48,3 13.62,3 13.727,3.054C13.821,3.102 13.898,3.179 13.946,3.273C14,3.38 14,3.52 14,3.8L14,12.2C14,12.48 14,12.62 13.946,12.727C13.898,12.821 13.821,12.898 13.727,12.946C13.62,13 13.48,13 13.2,13L11.8,13C11.52,13 11.38,13 11.273,12.946C11.179,12.898 11.102,12.821 11.054,12.727C11,12.62 11,12.48 11,12.2L11,3.8C11,3.52 11,3.38 11.054,3.273C11.102,3.179 11.179,3.102 11.273,3.054C11.38,3 11.52,3 11.8,3Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_plus\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M7.5,8.5L1,8.5L1,7.5L7.5,7.5L7.5,1L8.5,1L8.5,7.5L15,7.5L15,8.5L8.5,8.5L8.5,15L7.5,15L7.5,8.5Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_minus\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<rect x=\"3\" y=\"7.5\" width=\"10\" height=\"1\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_close\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M7.293,8L1.646,2.354L2.354,1.646L8,7.293L13.646,1.646L14.354,2.354L8.707,8L14.354,13.646L13.646,14.354L8,8.707L2.354,14.354L1.646,13.646L7.293,8Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_layout-columns\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M7,3L9,3L9,13L7,13L7,3ZM3,3L5,3L5,13L3,13L3,3ZM11,3L13,3L13,13L11,13L11,3Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_layout-rows\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M13,3L13,5L3,5L3,3L13,3ZM13,7L13,9L3,9L3,7L13,7ZM13,11L13,13L3,13L3,11L13,11Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_layout-center\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M12.673,11.362C12.385,11.926 11.926,12.385 11.362,12.673C10.76,12.98 9.983,12.999 8.501,13L8.5,8.5L13,8.501C12.999,9.983 12.98,10.76 12.673,11.362ZM3,8.501L7.5,8.5L7.5,13C6.017,12.999 5.24,12.98 4.638,12.673C4.074,12.385 3.615,11.926 3.327,11.362C3.02,10.76 3.001,9.983 3,8.501ZM11.362,3.327C11.926,3.615 12.385,4.074 12.673,4.638C12.98,5.24 12.999,6.017 13,7.5L8.5,7.5L8.501,3C9.983,3.001 10.76,3.02 11.362,3.327ZM7.5,3L7.5,7.5L3,7.5C3.001,6.017 3.02,5.24 3.327,4.638C3.615,4.074 4.074,3.615 4.638,3.327C5.24,3.02 6.017,3.001 7.5,3Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_layout-golden\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M8.488,3L8.5,3L8.501,13C8.404,13 8.304,13 8.2,13L7.8,13C6.12,13 5.28,13 4.638,12.673C4.074,12.385 3.615,11.926 3.327,11.362C3,10.72 3,9.88 3,8.2L3,7.8C3,6.12 3,5.28 3.327,4.638C3.615,4.074 4.074,3.615 4.638,3.327C5.28,3 6.12,3 7.8,3L8.2,3L8.488,3ZM12.673,11.362C12.385,11.926 11.926,12.385 11.362,12.673C10.913,12.902 10.366,12.971 9.501,12.991L9.5,9.5L12.991,9.501C12.971,10.366 12.902,10.913 12.673,11.362ZM11.362,3.327C11.926,3.615 12.385,4.074 12.673,4.638C13,5.28 13,6.12 13,7.8L13,8.2C13,8.304 13,8.404 13,8.501L9.5,8.5L9.501,3.009C10.366,3.029 10.913,3.098 11.362,3.327Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_layout-thirds\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M6.5,10.5L9.5,10.5L9.501,12.991C9.131,13 8.703,13 8.2,13L7.8,13C7.297,13 6.869,13 6.5,12.991L6.5,10.5ZM3.077,10.502L5.5,10.5L5.499,12.923C5.159,12.876 4.884,12.798 4.638,12.673C4.074,12.385 3.615,11.926 3.327,11.362C3.202,11.116 3.125,10.841 3.077,10.502ZM12.673,11.362C12.385,11.926 11.926,12.385 11.362,12.673C11.116,12.798 10.841,12.875 10.502,12.923L10.5,10.5L12.923,10.502C12.875,10.841 12.798,11.116 12.673,11.362ZM13,7.8L13,8.2C13,8.703 13,9.131 12.991,9.501L10.5,9.5L10.5,6.5L12.991,6.5C13,6.869 13,7.297 13,7.8ZM3.009,6.5L5.5,6.5L5.5,9.5L3.009,9.501C3,9.131 3,8.703 3,8.2L3,7.8C3,7.297 3,6.869 3.009,6.5ZM6.5,6.5L9.5,6.5L9.5,9.5L6.5,9.5L6.5,6.5ZM11.362,3.327C11.926,3.615 12.385,4.074 12.673,4.638C12.798,4.884 12.876,5.159 12.923,5.499L10.5,5.5L10.502,3.077C10.841,3.125 11.116,3.202 11.362,3.327ZM5.499,3.077L5.5,5.5L3.077,5.499C3.124,5.159 3.202,4.884 3.327,4.638C3.615,4.074 4.074,3.615 4.638,3.327C4.884,3.202 5.159,3.124 5.499,3.077ZM9.501,3.009L9.5,5.5L6.5,5.5L6.5,3.009C6.869,3 7.297,3 7.8,3L8.2,3C8.703,3 9.131,3 9.501,3.009Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_layout-dots\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M11,3L13,3L13,5L11,5L11,3ZM11,7L13,7L13,9L11,9L11,7ZM11,11L13,11L13,13L11,13L11,11ZM7,3L9,3L9,5L7,5L7,3ZM7,7L9,7L9,9L7,9L7,7ZM7,11L9,11L9,13L7,13L7,11ZM3,3L5,3L5,5L3,5L3,3ZM3,7L5,7L5,9L3,9L3,7ZM3,11L5,11L5,13L3,13L3,11Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_export\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M8.5,5C9.983,5.001 10.76,5.02 11.362,5.327C12.12,5.713 12.678,6.402 12.898,7.224C13,7.605 13,8.07 13,9C13,9.93 13,10.395 12.898,10.776C12.678,11.598 12.12,12.287 11.362,12.673C10.72,13 9.88,13 8.2,13L7.8,13C6.12,13 5.28,13 4.638,12.673C3.88,12.287 3.322,11.598 3.102,10.776C3,10.395 3,9.93 3,9C3,8.07 3,7.605 3.102,7.224C3.322,6.402 3.88,5.713 4.638,5.327C5.24,5.02 6.017,5.001 7.5,5L7.5,10L8.5,10L8.5,5ZM7.5,5L7.5,3.207L6.354,4.354L5.646,3.646L8,1.293L10.354,3.646L9.646,4.354L8.5,3.207L8.5,5L7.5,5Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_import\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M8.5,5C9.983,5.001 10.76,5.02 11.362,5.327C12.12,5.713 12.678,6.402 12.898,7.224C13,7.605 13,8.07 13,9C13,9.93 13,10.395 12.898,10.776C12.678,11.598 12.12,12.287 11.362,12.673C10.72,13 9.88,13 8.2,13L7.8,13C6.12,13 5.28,13 4.638,12.673C3.88,12.287 3.322,11.598 3.102,10.776C3,10.395 3,9.93 3,9C3,8.07 3,7.605 3.102,7.224C3.322,6.402 3.88,5.713 4.638,5.327C5.24,5.02 6.017,5.001 7.5,5L7.5,8.793L6.354,7.646L5.646,8.354L8,10.707L10.354,8.354L9.646,7.646L8.5,8.793L8.5,5ZM7.5,5L7.5,2L8.5,2L8.5,5L7.5,5Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_break\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M10.475,11.182L11.182,10.475L14.01,13.303L13.303,14.01L10.475,11.182ZM11.437,9.197L11.634,8.217L15.169,8.924L14.973,9.905L11.437,9.197ZM8.217,11.634L9.197,11.437L9.905,14.973L8.924,15.169L8.217,11.634ZM5.525,4.818L4.818,5.525L1.99,2.697L2.697,1.99L5.525,4.818ZM7.783,4.366L6.803,4.563L6.095,1.027L7.076,0.831L7.783,4.366ZM4.563,6.803L4.366,7.783L0.831,7.076L1.027,6.095L4.563,6.803Z\"/>`,\r\n  },\r\n\r\n  // ─── 12px ────────────────────────────────────────────────────────────────\r\n\r\n  {\r\n    id: \"icon-16_offset-marker-down\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M8.5,3L7.5,3L7.5,10.793L5.354,8.646L4.646,9.354L8,12.707L11.354,9.354L10.646,8.646L8.5,10.793L8.5,3Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-16_offset-marker-up\",\r\n    viewBox: \"0 0 16 16\",\r\n    content: `<path fill=\"currentColor\" d=\"M7.5,13L8.5,13L8.5,5.207L10.646,7.354L11.354,6.646L8,3.293L4.646,6.646L5.354,7.354L7.5,5.207L7.5,13Z\"/>`,\r\n  },\r\n\r\n  // ─── 12px ────────────────────────────────────────────────────────────────\r\n\r\n  {\r\n    id: \"icon-12_chevrone-up\",\r\n    viewBox: \"0 0 12 12\",\r\n    content: `<path fill=\"currentColor\" d=\"M3.277,7.416L2.723,6.584L6,4.399L9.277,6.584L8.723,7.416L6,5.601L3.277,7.416Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-12_chevrone-down\",\r\n    viewBox: \"0 0 12 12\",\r\n    content: `<path fill=\"currentColor\" d=\"M8.723,4.584L9.277,5.416L6,7.601L2.723,5.416L3.277,4.584L6,6.399L8.723,4.584Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-12_arrow-up\",\r\n    viewBox: \"0 0 12 12\",\r\n    content: `<path fill=\"currentColor\" d=\"M5.5,3.934L3.277,5.416L2.723,4.584L6,2.399L9.277,4.584L8.723,5.416L6.5,3.934L6.5,10L5.5,10L5.5,3.934Z\"/>`,\r\n  },\r\n  {\r\n    id: \"icon-12_arrow-down\",\r\n    viewBox: \"0 0 12 12\",\r\n    content: `<path fill=\"currentColor\" d=\"M6.5,8.066L8.723,6.584L9.277,7.416L6,9.601L2.723,7.416L3.277,6.584L5.5,8.066L5.5,2L6.5,2L6.5,8.066Z\"/>`,\r\n  },\r\n];\r\n","import { DEVTOOLS_ICONS, DevtoolsIconDef } from \"./StringDevtoolsIcons\";\r\n\r\nexport type DevtoolsIconSize = 12 | 16 | 20;\r\n\r\nexport class StringDevIconRegistry {\r\n  private static instance: StringDevIconRegistry | null = null;\r\n  private spriteRoot: SVGSVGElement | null = null;\r\n\r\n  private constructor() {\r\n    for (const icon of DEVTOOLS_ICONS) {\r\n      this.register(icon);\r\n    }\r\n  }\r\n\r\n  public static getInstance(): StringDevIconRegistry {\r\n    if (!this.instance) {\r\n      this.instance = new StringDevIconRegistry();\r\n    }\r\n    return this.instance;\r\n  }\r\n\r\n  public register(icon: DevtoolsIconDef): void {\r\n    const sprite = this.ensureSprite();\r\n\r\n    if (sprite.querySelector(`#${icon.id}`)) {\r\n      return;\r\n    }\r\n\r\n    const symbol = document.createElementNS(\"http://www.w3.org/2000/svg\", \"symbol\");\r\n    symbol.id = icon.id;\r\n    symbol.setAttribute(\"viewBox\", icon.viewBox);\r\n    symbol.innerHTML = icon.content;\r\n    sprite.appendChild(symbol);\r\n  }\r\n\r\n  public resolve(size: DevtoolsIconSize, name: string, ...modifiers: string[]): string {\r\n    const id = `icon-${size}_${name}`;\r\n    const extraAttrs = modifiers.map((m) => ` data-stdg-icon-${m}`).join(\"\");\r\n    return `<svg data-stdg-icon-${size}${extraAttrs}><use href=\"#${id}\"></use></svg>`;\r\n  }\r\n\r\n  private ensureSprite(): SVGSVGElement {\r\n    if (this.spriteRoot) {\r\n      return this.spriteRoot;\r\n    }\r\n\r\n    const svg = document.createElementNS(\"http://www.w3.org/2000/svg\", \"svg\");\r\n    svg.setAttribute(\"data-string-devtools-icon-sprite\", \"\");\r\n    svg.setAttribute(\"aria-hidden\", \"true\");\r\n    svg.style.cssText = \"display:none;position:absolute;width:0;height:0;overflow:hidden\";\r\n    (document.body ?? document.documentElement).prepend(svg);\r\n    this.spriteRoot = svg;\r\n    return svg;\r\n  }\r\n}\r\n\r\nexport function resolveDevtoolsIcon(\r\n  size: DevtoolsIconSize,\r\n  name: string,\r\n  ...modifiers: string[]\r\n): string {\r\n  return StringDevIconRegistry.getInstance().resolve(size, name, ...modifiers);\r\n}\r\n","import { resolveDevtoolsIcon } from \"./StringDevIconRegistry\";\n\nexport type IconSize = 12 | 16 | 20;\nexport type ButtonModifier = \"toggle\" | \"left\" | \"right\";\n\nexport interface IconButtonOptions {\n  icon: string;\n  size?: IconSize;\n  label: string;\n  modifiers?: ButtonModifier[];\n  /** Extra data-* attributes, e.g. { \"data-open\": \"false\" } */\n  attrs?: Record<string, string>;\n}\n\nexport interface PanelButtonOptions {\n  icon: string;\n  size?: IconSize;\n  label: string;\n  withLabel?: boolean;\n  /** Extra data-* attributes */\n  attrs?: Record<string, string>;\n}\n\nexport function makeBadge(targetId?: string): HTMLDivElement {\n  const el = document.createElement(\"div\");\n  el.setAttribute(\"data-stdg\", \"\");\n  el.setAttribute(\"data-stdg-badge\", \"\");\n  if (targetId) el.setAttribute(\"data-target-id\", targetId);\n  el.setAttribute(\"data-visible\", \"false\");\n  el.setAttribute(\"data-string-devtools-theme\", \"\");\n  return el;\n}\n\nexport function makePanel(attrs?: Record<string, string>): HTMLDivElement {\n  const el = document.createElement(\"div\");\n  el.setAttribute(\"data-stdg\", \"\");\n  el.setAttribute(\"data-stdg-panel\", \"\");\n  el.setAttribute(\"data-open\", \"false\");\n  if (attrs) {\n    for (const [k, v] of Object.entries(attrs)) el.setAttribute(k, v);\n  }\n  el.addEventListener(\"pointerdown\", (e) => e.stopPropagation());\n  return el;\n}\n\n/**\n * Creates a panel header div.\n *   <div data-stdg-panel-header>\n */\nexport function makePanelHeader(): HTMLDivElement {\n  const el = document.createElement(\"div\");\n  el.setAttribute(\"data-stdg-panel-header\", \"\");\n  return el;\n}\n\n/**\n * Creates a panel content div.\n *   <div data-stdg-panel-content>\n */\nexport function makePanelContent(attrs?: Record<string, string>): HTMLDivElement {\n  const el = document.createElement(\"div\");\n  el.setAttribute(\"data-stdg-panel-content\", \"\");\n  if (attrs) {\n    for (const [k, v] of Object.entries(attrs)) el.setAttribute(k, v);\n  }\n  return el;\n}\n\n/**\n * Creates a small icon button (header/toolbar use).\n *\n * Modifiers map to data-stdg-button-{modifier} attributes.\n * Default size is 16.\n *\n * @example\n * makeIconButton({ icon: \"close\", label: \"Close panel\", modifiers: [\"right\"] })\n */\nexport function makeIconButton(options: IconButtonOptions): HTMLButtonElement {\n  const { icon, size = 16, label, modifiers = [], attrs } = options;\n  const el = document.createElement(\"button\");\n  el.type = \"button\";\n  el.setAttribute(\"data-stdg-button\", \"\");\n  el.setAttribute(`data-stdg-button-icon-${size}`, \"\");\n  for (const mod of modifiers) {\n    el.setAttribute(`data-stdg-button-${mod}`, \"\");\n  }\n  el.setAttribute(\"aria-label\", label);\n  el.setAttribute(\"title\", label);\n  el.innerHTML = resolveDevtoolsIcon(size, icon);\n  if (attrs) {\n    for (const [k, v] of Object.entries(attrs)) el.setAttribute(k, v);\n  }\n  return el;\n}\n\nexport function makeDeleteButton(label: string, attrs?: Record<string, string>): HTMLButtonElement {\n  const el = document.createElement(\"button\");\n  el.type = \"button\";\n  el.setAttribute(\"data-stdg-button\", \"\");\n  el.setAttribute(\"data-string-grid-list-delete\", \"\");\n  el.setAttribute(\"aria-label\", label);\n  el.setAttribute(\"title\", label);\n  el.innerHTML = resolveDevtoolsIcon(16, \"minus\");\n  if (attrs) {\n    for (const [k, v] of Object.entries(attrs)) el.setAttribute(k, v);\n  }\n  return el;\n}\n\n/**\n * Creates a panel-style button (wider, can include a text label next to the icon).\n *\n * @example\n * makePanelButton({ icon: \"plus\", label: \"Add Layout Guide\", withLabel: true })\n */\nexport function makePanelButton(options: PanelButtonOptions): HTMLButtonElement {\n  const { icon, size = 16, label, withLabel = false, attrs } = options;\n  const el = document.createElement(\"button\");\n  el.type = \"button\";\n  el.setAttribute(\"data-stdg-button\", \"\");\n  el.setAttribute(\"data-stdg-button-toggle\", \"\");\n  el.setAttribute(\"data-stdg-panel-button\", \"\");\n  el.setAttribute(`data-stdg-panel-button-icon-${size}`, \"\");\n  el.setAttribute(\"aria-label\", label);\n  el.setAttribute(\"title\", label);\n  el.innerHTML = withLabel\n    ? `${resolveDevtoolsIcon(size, icon)}<span>${label}</span>`\n    : resolveDevtoolsIcon(size, icon);\n  if (attrs) {\n    for (const [k, v] of Object.entries(attrs)) el.setAttribute(k, v);\n  }\n  return el;\n}\n","export const CORE_STYLES = `\r\n\r\n[data-string-devtools-overlay-badge][data-module-enabled=\"false\"] {\r\n  display: none;\r\n}\r\n\r\n[data-string-devtools-overlay-badge][data-visible=\"false\"] {\r\n  display: none;\r\n}\r\n\r\n[data-stdg] {\r\n  --string-dg-font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans',\r\n    'Helvetica Neue', sans-serif;\r\n  --string-dg-font-size: 12px;\r\n  --string-dg-font-size-s: 10px;\r\n  --string-dg-font-size-xs: 8px;\r\n  --string-dg-font-normal: 400;\r\n  --string-dg-font-medium: 500;\r\n  --string-dg-font-bold: 600;\r\n\r\n  --string-dg-color-blue: #3687ff;\r\n  --string-dg-color-amber: #b45100;\r\n  --string-dg-color-green: #00823c;\r\n  --string-dg-color-teal: #00788c;\r\n  --string-dg-color-red: #f45524;\r\n  --string-dg-color-black: #111111;\r\n  --string-dg-color-white: #ffffff;\r\n  --string-dg-color-cloud-white: rgba(249, 249, 249, 0.8);\r\n  --string-dg-color-middle-white: rgba(249, 249, 249, 0.4);\r\n  --string-dg-color-hairline: rgba(220, 220, 220, 0.5);\r\n  --string-dg-color-offset: rgba(127, 127, 127, 0.8);\r\n  --string-dg-color-grey-1: #eeeeee;\r\n  --string-dg-color-grey-2: #dddddd;\r\n  --string-dg-color-grey-3: #cccccc;\r\n  --string-dg-color-grey-4: #bbbbbb;\r\n  --string-dg-color-grey-5: #aaaaaa;\r\n  --string-dg-color-grey-6: #888888;\r\n\r\n  /* dock */\r\n  --string-dg-dock-radius: 16px;\r\n  --string-dg-dock-padding: 3px 4px;\r\n  --string-dg-dock-shadow: 0 16px 32px rgba(0, 0, 0, 0.08);\r\n\r\n  /* badge */\r\n  --string-dg-badge-radius: 12px;\r\n  --string-dg-badge-padding: 1px;\r\n  --string-dg-badge-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);\r\n\r\n  /* panel */\r\n  --string-dg-panel-radius: 18px;\r\n  --string-dg-panel-padding: 0px;\r\n  --string-dg-panel-shadow: 0 0 1px rgba(0, 0, 0, 0.4), 0 16px 32px rgba(0, 0, 0, 0.08);\r\n  --string-dg-panel-header-padding: 5px;\r\n  --string-dg-panel-responsive-margin: 0 5px 8px 5px;\r\n  --string-dg-panel-conent-margin: 0 5px 8px 5px;\r\n  --string-dg-panel-hr-margin: 16px 0;\r\n\r\n  /* buttons | inputs | etc */\r\n  --string-dg-min-height: 34px;\r\n\r\n  /* input */\r\n  --string-dg-input: 4px 0;\r\n  --string-dg-input-container-negative-margin: -8px;\r\n  --string-dg-input-range-padding: 6px 8px;\r\n  --string-dg-panel-range-width: 2px;\r\n  --string-dg-input-range-webkit-margin: 4px;\r\n\r\n  /* toggle */\r\n  --string-dg-toggle-gap: 8px;\r\n  --string-dg-toggle-knob: 12px;\r\n  --string-dg-toggle-padding: 1px;\r\n  --string-dg-toggle-radius: 12px;\r\n  --string-dg-toggle-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);\r\n\r\n  /* button */\r\n  /* button | icon-20 */\r\n  --string-dg-button-icon-20-background: rgba(255, 255, 255, 0.25);\r\n  --string-dg-button-icon-20-radius: 12px;\r\n  --string-dg-button-icon-20-padding: 6px;\r\n  /* button | icon-16 */\r\n  --string-dg-button-icon-16-background: rgba(255, 255, 255, 0.25);\r\n  --string-dg-button-icon-16-radius: 10px;\r\n  --string-dg-button-icon-16-padding: 5px;\r\n  /* button | icon-12 */\r\n  --string-dg-button-icon-12-background: rgba(255, 255, 255, 0.25);\r\n  --string-dg-button-icon-12-radius: 5px;\r\n  --string-dg-button-icon-12-margin: 1px;\r\n\r\n  /* panel button */\r\n  --string-dg-panel-button-radius: 8px;\r\n  --string-dg-panel-button-padding-1: 8px;\r\n  --string-dg-panel-button-padding-2: 8px 12px 8px 5px;\r\n  --string-dg-panel-button-gap: 8px;\r\n\r\n  /* panel field */\r\n  --string-dg-panel-field-slider-gap: 4px;\r\n\r\n  --string-dg-panel-field-padding: 0 0 0 8px;\r\n  --string-dg-panel-field-input-padding: 8px 0;\r\n  --string-dg-panel-field-icon-left: 5px;\r\n  --string-dg-panel-field-label-left: 8px;\r\n\r\n  /* panel breakpoints */\r\n  --string-dg-panel-breakpoints-margin: 16px 0 24px;\r\n  --string-dg-panel-breakpoint-marker-width: 2px;\r\n  --string-dg-panel-breakpoint-marker-padding: 4px 8px 0px;\r\n  --string-dg-panel-breakpoint-marker-margin: -4px -16px 0px;\r\n  --string-dg-panel-breakpoints-span-pos-cor: 4px;\r\n\r\n  /* panel-item */\r\n  --string-dg-panel-list-item-radius: 8px;\r\n  --string-dg-panel-list-item-padding: 8px 5px 8px 5px;\r\n  --string-dg-panel-list-item-grabbing: -8px -5px -8px -5px;\r\n  --string-dg-panel-list-item-delete-margin: -4px 0;\r\n\r\n  /* offsets */\r\n  --string-dg-offsets-dasharray: 2px 8px;\r\n\r\n  font-family: var(--string-dg-font-family);\r\n  font-size: var(--string-dg-font-size);\r\n  line-height: 1;\r\n  color: var(--string-dg-color-black);\r\n  box-sizing: content-box;\r\n  box-shadow: none;\r\n  background: none;\r\n  border: none;\r\n  border-radius: 0;\r\n}\r\n\r\n/* input */\r\n\r\n\r\n[data-stdg-input], [data-stdg-input]:focus, [data-stdg-input]:hover {\r\n  box-shadow: none !important;\r\n  background-color: none;\r\n  background-image: none;\r\n  outline: none;\r\n  border: none;\r\n  color: none;\r\n  -webkit-box-shadow: none !important;\r\n}\r\n\r\ninput[type=number] {\r\n  -moz-appearance:textfield; /* Firefox */\r\n}\r\n  \r\n\r\n[data-stdg-input][type='color'] {\r\n  display: flex;\r\n  justify-content: center;\r\n  \r\n}\r\n\r\ninput[type=\"color\" i]::-webkit-color-swatch-wrapper {\r\n  padding: 0;\r\n  height: 50%;\r\n  width: 50%;\r\n  aspect-ratio: 1/1;\r\n  border-radius: 50%;\r\n  overflow: hidden;\r\n  border: 1px solid var(--string-dg-color-white);\r\n}\r\n\r\ninput[type=\"color\" i]::-webkit-color-swatch{\r\nborder: none;\r\n}\r\n\r\n[data-stdg-input][type='color']::-moz-color-swatch {\r\n  padding: 0;\r\n  height: 50%;\r\n  width: 50%;\r\n  aspect-ratio: 1/1;\r\n  border-radius: 50%;\r\n  overflow: hidden;\r\n  border: 1px solid var(--string-dg-color-white);\r\n}\r\n[data-stdg-input][type='number'] {\r\n  font-variant-numeric: tabular-nums;\r\n}\r\n[data-stdg-select],\r\n[data-stdg-select]::-webkit-outer-spin-button,\r\n[data-stdg-select]::-webkit-inner-spin-button,\r\n[data-stdg-input][type='number']::-webkit-outer-spin-button,\r\n[data-stdg-input][type='number']::-webkit-inner-spin-button {\r\n  -moz-appearance: textfield;\r\n  -webkit-appearance: none;\r\n  margin: 0;\r\n}\r\n[data-stdg-input][type=\"range\"] {\r\n  -webkit-appearance: none;\r\n  appearance: none;\r\n  align-items: stretch;\r\n  width: 100%;\r\n  display: inline-block;\r\n  background: transparent;\r\n  background-image: linear-gradient(\r\n    to right,\r\n    var(--string-dg-color-grey-2) var(--string-progress-slider-fill),\r\n    transparent var(--string-progress-slider-fill)\r\n  );\r\n  border-radius: var(--string-dg-panel-button-radius);\r\n}\r\n[data-stdg-input][type=\"range\"]::-moz-range-track {\r\n  display: none;\r\n}\r\n[data-stdg-input][type=\"range\"]::-moz-range-thumb {\r\n  appearance: none;\r\n  width: 0;\r\n  height: 100%;\r\n  border: none;\r\n  padding: var(--string-dg-input-range-padding);\r\n  background: none;\r\n  background-image:\r\n    linear-gradient(0deg, var(--string-dg-color-black))\r\n  ;\r\n  background-repeat: no-repeat;\r\n  background-size: var(--string-dg-panel-breakpoint-marker-width) 100%;\r\n  background-position: center center;\r\n  cursor: col-resize;\r\n}\r\n[data-stdg-input][type=\"range\"]::-webkit-slider-container {\r\n  margin-top: calc(-1.5 * var(--string-dg-input-range-webkit-margin));\r\n  height: calc(100% + var(--string-dg-input-range-webkit-margin) * 3);\r\n\r\n  margin-left: var(--string-dg-input-container-negative-margin);\r\n  margin-right: var(--string-dg-input-container-negative-margin);\r\n}\r\n[data-stdg-input][type=\"range\"]::-webkit-slider-runnable-track {\r\n  height: 100%;\r\n}\r\n[data-stdg-input][type=\"range\"]::-webkit-slider-thumb {\r\n  -webkit-appearance: none;\r\n  width: 0;\r\n  height: 100%;\r\n  padding: var(--string-dg-input-range-padding);\r\n  background-image:\r\n    linear-gradient(0deg, var(--string-dg-color-black))\r\n  ;\r\n  background-repeat: no-repeat;\r\n  background-size: var(--string-dg-panel-range-width) 100%;\r\n  background-position: center center;\r\n  cursor: col-resize;\r\n\r\n  opacity: 0;\r\n  transition: opacity 0.15s ease-out;\r\n}\r\n[data-stdg-input][type=\"range\"]:hover::-webkit-slider-thumb,\r\n[data-stdg-input][type=\"range\"]:active::-webkit-slider-thumb {\r\n  opacity: 1;\r\n  transition: opacity 0.3s ease-in-out;\r\n}\r\n\r\n[data-stdg-select],\r\n[data-stdg-input],\r\n[data-stdg-textarea] {\r\n  display: block;\r\n  width: 100%;\r\n  box-sizing: content-box;\r\n  background-color: transparent;\r\n  padding: var(--string-dg-input);\r\n  margin: 0;\r\n  border-radius: 0;\r\n  border: none;\r\n  box-shadow: none;\r\n  text-align: center;\r\n  text-align-last: center;\r\n  cursor: default;\r\n\r\n  font-family: var(--string-dg-font-family);\r\n  font-size: var(--string-dg-font-size-s);\r\n  font-weight: var(--string-dg-font-bold);\r\n}\r\n[data-stdg-select]:focus,\r\n[data-stdg-input]:focus,\r\n[data-stdg-textarea]:focus {\r\n  outline: none;\r\n  box-shadow: none;\r\n}\r\n\r\n/* toggle */\r\n[data-stdg-toggle] {\r\n  border-radius: var(--string-dg-toggle-radius);\r\n  background: var(--string-dg-color-grey-3);\r\n  padding: var(--string-dg-toggle-padding) calc(var(--string-dg-toggle-gap) + var(--string-dg-toggle-padding))\r\n    var(--string-dg-toggle-padding) var(--string-dg-toggle-padding);\r\n  display: inline-flex;\r\n  position: relative;\r\n}\r\n[data-stdg-toggle-input] {\r\n  display: none;\r\n}\r\n[data-stdg-toggle-knob] {\r\n  width: var(--string-dg-toggle-knob);\r\n  height: var(--string-dg-toggle-knob);\r\n  border-radius: var(--string-dg-toggle-radius);\r\n  background: var(--string-dg-color-white);\r\n  box-shadow: var(--string-dg-toggle-shadow);\r\n  margin-left: auto;\r\n}\r\n[data-stdg-toggle][data-checked='true'] {\r\n  background-color: var(--string-dg-color-blue);\r\n}\r\n[data-checked='false'] [data-stdg-toggle-knob] {\r\n  translate: var(--string-dg-toggle-gap) 0;\r\n}\r\n\r\n/* button */\r\n\r\n[data-stdg-panel-content] > [data-stdg-panel-breakpoints],\r\n[data-stdg-panel-field-slider] > [data-stdg-panel-field],\r\n[data-stdg-panel-content] > [data-stdg-panel-field],\r\n[data-stdg-panel-content] > [data-stdg-button] {\r\n  min-height: var(--string-dg-min-height);\r\n}\r\n\r\n[data-stdg-panel-breakpoints],\r\n[data-stdg-panel-field],\r\n[data-stdg-button] {\r\n  display: flex;\r\n  box-shadow: none;\r\n  background: none;\r\n  border-radius: 0;\r\n  margin: 0;\r\n  padding: 0;\r\n  cursor: default;\r\n  box-sizing: border-box;\r\n  border: 1px solid transparent;\r\n  font-family: var(--string-dg-font-family);\r\n  font-size: var(--string-dg-font-size);\r\n  font-weight: var(--string-dg-font-medium);\r\n  color: var(--string-dg-color-black);\r\n}\r\n[data-stdg-panel-field][data-disabled=\"true\"]{\r\n  display: none;\r\n}\r\n[data-stdg-dock-list] > [data-stdg-button] {\r\n  display: block;\r\n}\r\n[data-stdg-panel-breakpoints] > *,\r\n[data-stdg-panel-field] > *,\r\n[data-stdg-button] > * {\r\n  grid-area: 1/1;\r\n  flex-shrink: 0;\r\n}\r\n[data-stdg-panel-breakpoints] span,\r\n[data-stdg-panel-field] span,\r\n[data-stdg-button] span {\r\n  pointer-events: none;\r\n  -webkit-user-select: none;\r\n  user-select: none;\r\n}\r\n/* button | icon-20 */\r\n[data-stdg-holder-icon-20] {\r\n  padding: var(--string-dg-button-icon-20-padding);\r\n}\r\n[data-stdg-button-icon-20] {\r\n  background-color: var(--string-dg-button-icon-20-background);\r\n  padding: var(--string-dg-button-icon-20-padding);\r\n  border-radius: var(--string-dg-button-icon-20-radius);\r\n}\r\n[data-stdg-icon-20] {\r\n  width: 20px;\r\n  aspect-ratio: 1/1;\r\n  color: var(--string-dg-color-black);\r\n}\r\n/* button | icon-16 */\r\n[data-stdg-holder-icon-16] {\r\n  padding: var(--string-dg-button-icon-16-padding);\r\n}\r\n[data-stdg-button-icon-16] {\r\n  background-color: var(--string-dg-button-icon-16-background);\r\n  padding: var(--string-dg-button-icon-16-padding);\r\n  border-radius: var(--string-dg-button-icon-16-radius);\r\n}\r\n[data-stdg-icon-16] {\r\n  width: 16px;\r\n  aspect-ratio: 1/1;\r\n  color: var(--string-dg-color-black);\r\n}\r\n/* button | icon-12 */\r\n[data-stdg-holder-icon-12] {\r\n}\r\n[data-stdg-button-icon-12] {\r\n  background-color: var(--string-dg-button-icon-12-background);\r\n  border-radius: var(--string-dg-button-icon-12-radius);\r\n  margin: var(--string-dg-button-icon-12-margin);\r\n}\r\n[data-stdg-icon-12] {\r\n  width: 12px;\r\n  aspect-ratio: 1/1;\r\n  color: var(--string-dg-color-black);\r\n}\r\n/* button | icon-second */\r\n[data-stdg-icon-second] {\r\n  color: var(--string-dg-color-grey-4);\r\n}\r\n/* button | hover */\r\n[data-stdg-button-hover] {\r\n  display: grid;\r\n  place-items: center;\r\n}\r\n[data-stdg-button-hover] svg:last-child {\r\n  visibility: hidden;\r\n}\r\n[data-stdg-button-hover]:hover svg:first-child {\r\n  visibility: hidden;\r\n}\r\n[data-stdg-button-hover]:hover svg:last-child {\r\n  visibility: visible;\r\n}\r\n[data-stdg-dock] [data-stdg-button-hover] svg:last-child {\r\n  transform: rotate(-90deg);\r\n}\r\n[data-stdg-dock] [data-stdg-button-hover][data-collapsed='true'] svg:last-child {\r\n  transform: rotate(90deg);\r\n}\r\n\r\n/* button | data-active */\r\n[data-active='false'] [data-stdg-icon-12],\r\n[data-active='false'] [data-stdg-icon-16],\r\n[data-active='false'] [data-stdg-icon-20] {\r\n  color: var(--string-dg-color-grey-5);\r\n}\r\n/* button | toggle */\r\n[data-stdg-button-toggle][data-active='false'] [data-stdg-icon-12]:not([data-stdg-icon-second]),\r\n[data-stdg-button-toggle][data-active='false'] [data-stdg-icon-16]:not([data-stdg-icon-second]),\r\n[data-stdg-button-toggle][data-active='false'] [data-stdg-icon-20]:not([data-stdg-icon-second]) {\r\n  color: var(--string-dg-color-black);\r\n}\r\n[data-stdg-button-toggle][data-active='true'] {\r\n  background-color: var(--string-dg-color-grey-2);\r\n}\r\n  \r\n[data-stdg-button-toggle][data-active='true'] [data-stdg-icon-12]:not([data-stdg-icon-second]),\r\n[data-stdg-button-toggle][data-active='true'] [data-stdg-icon-16]:not([data-stdg-icon-second]),\r\n[data-stdg-button-toggle][data-active='true'] [data-stdg-icon-20]:not([data-stdg-icon-second]) {\r\n  \r\n}\r\n\r\n[data-stdg-panel-breakpoints]:hover:not([data-stdg-panel-breakpoint-marker]):not([data-string-grid-list-delete]),\r\n[data-stdg-panel-field]:hover:not([data-stdg-panel-breakpoint-marker]):not([data-string-grid-list-delete]),\r\n[data-stdg-button]:hover:not([data-stdg-panel-breakpoint-marker]):not([data-string-grid-list-delete]) {\r\n  border: 1px solid var(--string-dg-color-cloud-white);\r\n  background-color: var(--string-dg-color-grey-1);\r\n}\r\n[data-stdg-button]:active:not(:has([data-stdg-toggle]:active)):not([data-stdg-panel-breakpoint-marker]) {\r\n  border: 1px solid var(--string-dg-color-cloud-white);\r\n  background-color: var(--string-dg-color-grey-3);\r\n}\r\n\r\n/* panel button */\r\n[data-stdg-panel-button] {\r\n  box-sizing: border-box;\r\n  border: 1px solid var(--string-dg-color-white);\r\n  background-color: var(--string-dg-color-grey-1);\r\n\r\n  border-radius: var(--string-dg-panel-button-radius);\r\n  display: flex;\r\n  justify-content: flex-start;\r\n  align-items: center;\r\n  gap: var(--string-dg-panel-button-gap);\r\n}\r\n[data-stdg-panel-button]:has(svg):has(span) {\r\n  width: 100%;\r\n  padding: var(--string-dg-panel-button-padding-2);\r\n}\r\n[data-stdg-panel-button]:not(:has(svg):has(span)) {\r\n  background-color: var(--string-dg-color-white);\r\n  padding: var(--string-dg-panel-button-padding-1);\r\n}\r\n\r\n[data-stdg-panel-button]:not(:has(svg):has(span)) span {\r\n  font-size: var(--string-dg-font-size-s);\r\n  font-weight: var(--string-dg-font-bold);\r\n  width: 16px;\r\n  aspect-ratio: 1/1;\r\n  display: grid;\r\n  place-items: center;\r\n}\r\n[data-stdg-panel-button][data-active='true']:not(:has(svg):has(span)) span {\r\n}\r\n\r\n[data-string-grid-list-delete] {\r\n  background-color: var(--string-dg-color-white);\r\n  border-radius: 50%;\r\n}\r\n\r\n\r\n/* panel list-item */\r\n[data-stdg-panel-list-item] {\r\n  border: 1px solid var(--string-dg-color-white);\r\n  background-color: var(--string-dg-color-grey-1);\r\n\r\n  border-radius: var(--string-dg-panel-list-item-radius);\r\n  display: flex;\r\n  justify-content: flex-start;\r\n  align-items: center;\r\n  gap: var(--string-dg-panel-button-gap);\r\n\r\n  padding: var(--string-dg-panel-list-item-padding);\r\n}\r\n[data-stdg-panel-list-item] [data-stdg-icon-second] {\r\n  padding: var(--string-dg-panel-list-item-padding);\r\n  margin: var(--string-dg-panel-list-item-grabbing);\r\n}\r\n[data-stdg-panel-list-item] [data-stdg-icon-second]:active {\r\n  cursor: grabbing;\r\n}\r\n[data-stdg-panel-list-item] > span {\r\n  margin-right: auto;\r\n}\r\n[data-stdg-panel-list-item] [data-stdg-toggle] {\r\n}\r\n[data-stdg-panel-list-item] [data-string-grid-list-delete] {\r\n  margin: var(--string-dg-panel-list-item-delete-margin);\r\n}\r\n[data-stdg-panel-list-item][data-dragging=\"true\"] {\r\n  opacity: 0.4;\r\n  cursor: grabbing;\r\n}\r\n[data-stdg-panel-list-item][data-drag-over=\"before\"] {\r\n  box-shadow: 0 -2px 0 var(--string-dg-color-black);\r\n}\r\n[data-stdg-panel-list-item][data-drag-over=\"after\"] {\r\n  box-shadow: 0 2px 0 var(--string-dg-color-black);\r\n}\r\n\r\n[data-stdg-panel-list-item]:has([data-checked='false']) > [data-stdg-icon-16] {\r\n  color: var(--string-dg-color-grey-4) !important;\r\n}\r\n[data-stdg-panel-list-item]:has([data-checked='false']) > span {\r\n  color: var(--string-dg-color-grey-6);\r\n}\r\n\r\n/* panel field */\r\n[data-stdg-panel-field] {\r\n  box-sizing: border-box;\r\n  border: 1px solid var(--string-dg-color-white);\r\n  background-color: var(--string-dg-color-grey-1);\r\n\r\n  border-radius: var(--string-dg-panel-button-radius);\r\n  padding: var(--string-dg-panel-field-padding);\r\n  position: relative;\r\n  display: flex;\r\n  justify-content: space-between;\r\n  align-items: center;\r\n  gap: var(--string-dg-panel-button-gap);\r\n}\r\n[data-stdg-panel-field]:has(> [data-stdg-field-input-disable]) {\r\n  padding: 0;\r\n  gap: 0;\r\n}\r\n\r\n[data-stdg-panel-field]:has(> [data-stdg-toggle]:last-child) {\r\n  padding-right: 8px;\r\n}\r\n\r\n[data-stdg-panel-field] span {\r\n}\r\n\r\n[data-stdg-field-input] {\r\n  width: 50%;\r\n  display: flex;\r\n  align-items: center;\r\n}\r\n[data-stdg-field-input] > * {\r\n  flex: 1;\r\n}\r\n[data-stdg-field-value] {\r\n  display: flex;\r\n  align-items: center;\r\n  min-width: 0;\r\n}\r\n[data-stdg-field-value] [data-stdg-input] {\r\n  flex: 1;\r\n  min-width: 0;\r\n}\r\n[data-stdg-field-suffix] {\r\n  flex: 0 0 auto;\r\n  padding: var(--string-dg-panel-field-input-padding);\r\n  color: var(--string-dg-color-grey-6);\r\n  font-size: var(--string-dg-font-size-s);\r\n  font-weight: var(--string-dg-font-bold);\r\n  background-image: linear-gradient(0deg, var(--string-dg-color-grey-3));\r\n  background-repeat: no-repeat;\r\n  background-size: 1px 80%;\r\n  background-position: left center;\r\n}\r\n[data-stdg-field-input] [data-stdg-select],\r\n[data-stdg-field-input] [data-stdg-input] {\r\n  padding: var(--string-dg-panel-field-input-padding);\r\n  background-image: linear-gradient(0deg, var(--string-dg-color-grey-3));\r\n  background-repeat: no-repeat;\r\n  background-size: 1px 80%;\r\n  background-position: left center;\r\n}\r\n[data-stdg-field-input] [data-stdg-input][type='color'] {\r\n  flex: 0 0 33.3333%;\r\n  height: 100%;\r\n}\r\n[data-stdg-field-input] [data-stdg-stepper] {\r\n  flex: 0 0 33.3333%;\r\n  display: flex;\r\n  flex-wrap: wrap;\r\n  justify-content: stretch;\r\n  align-items: stretch;\r\n  background-image: linear-gradient(0deg, var(--string-dg-color-grey-3)), linear-gradient(0deg, var(--string-dg-color-grey-3));\r\n  background-repeat: no-repeat, no-repeat;\r\n  background-size:\r\n    1px 80%,\r\n    90% 1px;\r\n  background-position:\r\n    left center,\r\n    left center;\r\n}\r\n[data-stdg-field-input] [data-stdg-stepper] button {\r\n  width: 100%;\r\n  display: grid;\r\n  place-items: center;\r\n}\r\n\r\n/* svg + input + px */\r\n[data-stdg-panel-field] > span > [data-stdg-icon-16] {\r\n  position: absolute;\r\n  top: 8px;\r\n  left: var(--string-dg-panel-field-icon-left);\r\n  pointer-events: none;\r\n}\r\n[data-stdg-panel-field] > [data-stdg-icon-16] {\r\n  position: absolute;\r\n  left: var(--string-dg-panel-field-icon-left);\r\n  pointer-events: none;\r\n}\r\n[data-stdg-panel-field] > input {\r\n  align-self: stretch;\r\n  flex: 1;\r\n}\r\n[data-stdg-panel-field]:has(> [data-stdg-icon-16]) > input {\r\n  padding-left: var(--string-dg-panel-field-icon-left);\r\n}\r\n[data-stdg-field-input-disable] {\r\n  flex: 0 0 16%;\r\n  min-width: calc(var(--string-dg-font-size) * 3);\r\n  text-align: center;\r\n  color: var(--string-dg-color-grey-6);\r\n  padding: var(--string-dg-panel-field-input-padding);\r\n  background-image: linear-gradient(0deg, var(--string-dg-color-grey-3));\r\n  background-repeat: no-repeat;\r\n  background-size: 1px 80%;\r\n  background-position: left center;\r\n}\r\n\r\n/* slider wrapper */\r\n[data-stdg-panel-field-slider-row] {\r\n  display: flex;\r\n  gap: var(--string-dg-panel-field-slider-gap);\r\n}\r\n[data-stdg-panel-field-slider-row] [data-stdg-panel-field] {\r\n  flex: 0 0 20%;\r\n}\r\n[data-stdg-panel-field-slider-row] [data-stdg-panel-field-slider] {\r\n  flex: 1;\r\n  padding: 0;\r\n  position: relative;\r\n  display: flex;\r\n  justify-content: center;\r\n  align-items: center;\r\n}\r\n[data-stdg-panel-field-slider] label {\r\n  position: absolute;\r\n  left: var(--string-dg-panel-field-label-left);\r\n  color: var(--string-dg-color-grey-6);\r\n  pointer-events: none;\r\n}\r\n[data-stdg-panel-field-slider] input {\r\n  grid-area: 1/1;\r\n  justify-self: stretch;\r\n  min-width: 0;\r\n  width: 100%;\r\n}\r\n\r\n/* panel responsive */\r\n[data-stdg-panel-breakpoints] {\r\n  box-sizing: border-box;\r\n  border: 1px solid var(--string-dg-color-white);\r\n  background-color: var(--string-dg-color-grey-1);\r\n\r\n  border-radius: var(--string-dg-panel-button-radius);\r\n\r\n  margin: var(--string-dg-panel-breakpoints-margin);\r\n\r\n  position: relative;\r\n  display: flex;\r\n  justify-content: space-between;\r\n  align-items: stretch;\r\n  gap: var(--string-dg-panel-button-gap);\r\n\r\n  font-size: var(--string-dg-font-size-s);\r\n  font-weight: var(--string-dg-font-bold);\r\n}\r\n[data-stdg-panel-breakpoints]:before {\r\n  content: '0';\r\n  font-size: var(--string-dg-font-size-xs);\r\n  color: var(--string-dg-color-grey-3);\r\n  position: absolute;\r\n  bottom: calc(100% + var(--string-dg-font-size-xs) / 2 + var(--string-dg-panel-breakpoints-span-pos-cor));\r\n}\r\n[data-stdg-panel-breakpoint-value] {\r\n  flex: 1;\r\n  display: grid;\r\n  place-items: center;\r\n  text-align: center;\r\n}\r\n[data-stdg-panel-breakpoint-value] > * {\r\n  grid-area: 1/1;\r\n}\r\n[data-stdg-panel-breakpoint-value] [data-string-grid-list-delete] {\r\n  visibility: hidden;\r\n}\r\n[data-stdg-panel-breakpoint-value]:hover [data-string-grid-list-delete] {\r\n  visibility: visible;\r\n}\r\n\r\n[data-stdg-panel-breakpoint-marker] {\r\n  align-self: stretch;\r\n  position: relative;\r\n  display: flex;\r\n  justify-content: center;\r\n  padding: var(--string-dg-panel-breakpoint-marker-padding);\r\n  margin: var(--string-dg-panel-breakpoint-marker-margin);\r\n  background-image: linear-gradient(0deg, var(--string-dg-color-black));\r\n  background-repeat: no-repeat;\r\n  background-size: var(--string-dg-panel-breakpoint-marker-width) 100%;\r\n  background-position: center center;\r\n}\r\n[data-stdg-panel-breakpoint-marker]::before,\r\n[data-stdg-panel-breakpoint-marker]::after {\r\n  content: '';\r\n  position: absolute;\r\n  top: 100%;\r\n  width: 100%;\r\n  padding-bottom: 100%;\r\n}\r\n[data-stdg-panel-breakpoint-marker]::after {\r\n  border-radius: 50%;\r\n  background-color: var(--string-dg-color-black);\r\n  transform-origin: 50% 0%;\r\n  scale: 0.5;\r\n}\r\n[data-stdg-panel-breakpoint-marker] span {\r\n  font-size: var(--string-dg-font-size-xs);\r\n  color: var(--string-dg-color-grey-6);\r\n  position: absolute;\r\n  bottom: calc(100% + var(--string-dg-font-size-xs) / 2);\r\n}\r\n[data-stdg-panel-breakpoint-marker]:hover span {\r\n  color: var(--string-dg-color-black);\r\n}\r\n[data-stdg-panel-breakpoint-marker][data-active='true']::after {\r\n  scale: 1;\r\n}\r\n[data-stdg-panel-breakpoints] [data-stdg-panel-breakpoint-value]:first-child {\r\n  border-radius: var(--string-dg-panel-button-radius);\r\n  border-top-right-radius: 0;\r\n  border-bottom-right-radius: 0;\r\n}\r\n[data-stdg-panel-breakpoints] [data-stdg-panel-breakpoint-value]:last-child {\r\n  border-radius: var(--string-dg-panel-button-radius);\r\n  border-top-left-radius: 0;\r\n  border-bottom-left-radius: 0;\r\n}\r\n[data-stdg-panel-breakpoint-value]:has(+ [data-active='true']),\r\n[data-stdg-panel-breakpoint-marker][data-active='true'] + div {\r\n  background-color: var(--string-dg-color-grey-3);\r\n}\r\n\r\n/* dock */\r\n[data-stdg-dock] {\r\n  position: fixed;\r\n  z-index: 10035;\r\n  bottom: 24px;\r\n  left: 124px;\r\n\r\n  display: flex;\r\n  flex-direction: row;\r\n  align-items: center;\r\n\r\n  background-color: var(--string-dg-color-cloud-white);\r\n  padding: var(--string-dg-dock-padding);\r\n  border: 1px solid var(--string-dg-color-middle-white);\r\n  border-radius: var(--string-dg-dock-radius);\r\n  box-shadow: var(--string-dg-dock-shadow);\r\n\r\n  backdrop-filter: blur(4px);\r\n}\r\n[data-stdg-dock-list] {\r\n  display: flex;\r\n  flex-direction: row;\r\n  align-items: center;\r\n  gap: 0;\r\n  overflow: visible;\r\n}\r\n[data-stdg-dock-tools] {\r\n  position: relative;\r\n  display: flex;\r\n  flex-direction: row;\r\n  align-items: center;\r\n  overflow: visible;\r\n  opacity: 1;\r\n  transition:\r\n    max-width 0.22s ease,\r\n    opacity 0.16s ease;\r\n}\r\n[data-stdg-dock][data-collapsed=\"true\"] [data-stdg-dock-tools] {\r\n  overflow: hidden;\r\n}\r\n[data-stdg-dock-fps-separator] {\r\n  display: block;\r\n}\r\n[data-stdg-dock] > [data-stdg-button] {\r\n  align-self: center;\r\n}\r\n[data-string-defguides-doc-fps] {\r\n  display: grid;\r\n  place-items: center;\r\n  aspect-ratio: 1/1;\r\n  padding: var(--string-dg-button-icon-20-padding);\r\n}\r\n[data-string-defguides-doc-fps] span {\r\n  grid-area: 1/1;\r\n  width: 20px;\r\n  text-align: center;\r\n  vertical-align: middle;\r\n  cursor: default;\r\n}\r\n[data-stdg-horizontal-line] {\r\n  align-self: stretch;\r\n  display: block;\r\n  width: 0px;\r\n  margin: 0 4px;\r\n  border-right: 1px solid var(--string-dg-color-hairline);\r\n}\r\n\r\n/* dock sub-badges */\r\n[data-stdg-dock-slot] {\r\n  position: relative;\r\n  display: flex;\r\n  align-items: center;\r\n  overflow: visible;\r\n}\r\n[data-stdg-dock-slot][data-has-sub-badges]::after {\r\n  content: \"\";\r\n  position: absolute;\r\n  left: -4px;\r\n  right: -4px;\r\n  bottom: 100%;\r\n  height: 8px;\r\n  pointer-events: auto;\r\n}\r\n[data-stdg-dock-sub-badges] {\r\n  position: fixed;\r\n  display: flex;\r\n  flex-direction: row;\r\n  gap: 4px;\r\n  white-space: nowrap;\r\n  padding: var(--string-dg-badge-padding);\r\n  background-color: var(--string-dg-color-cloud-white);\r\n  border: 1px solid var(--string-dg-color-middle-white);\r\n  border-radius: var(--string-dg-badge-radius);\r\n  box-shadow: var(--string-dg-badge-shadow);\r\n  backdrop-filter: blur(4px);\r\n  opacity: 0;\r\n  pointer-events: none;\r\n  z-index: 10034;\r\n  -webkit-touch-callout: none;\r\n  -webkit-user-select: none;\r\n  user-select: none;\r\n  touch-action: manipulation;\r\n  transform: translate(-50%, calc(100% + 16px));\r\n  transition: transform .3s, opacity .3s;\r\n}\r\n[data-stdg-dock-sub-badge] {\r\n  position: relative;\r\n}\r\n[data-stdg-dock-sub-badge][data-parent-active=\"false\"] [data-stdg-icon-12],\r\n[data-stdg-dock-sub-badge][data-parent-active=\"false\"] [data-stdg-icon-16],\r\n[data-stdg-dock-sub-badge][data-parent-active=\"false\"] [data-stdg-icon-20] {\r\n  color: var(--string-dg-color-grey-5);\r\n}\r\n[data-stdg-dock-sub-badge]::before {\r\n  content: \"\";\r\n  position: absolute;\r\n  inset: -6px;\r\n}\r\n[data-stdg-dock-sub-badges][data-open=\"true\"] {\r\n  opacity: 1;\r\n  transform: translate(-50%, 0);\r\n  pointer-events: auto;\r\n}\r\n\r\n@media (max-width: 1024px), (pointer: coarse) {\r\n  [data-stdg-dock] [data-stdg-button-hover] svg:last-child {\r\n    transform: rotate(0deg);\r\n  }\r\n\r\n  [data-stdg-dock] [data-stdg-button-hover][data-collapsed='true'] svg:last-child {\r\n    transform: rotate(180deg);\r\n  }\r\n\r\n  [data-stdg-dock] {\r\n    top: 50%;\r\n    bottom: auto;\r\n    left: max(12px, env(safe-area-inset-left, 0px) + 12px);\r\n    transform: translateY(-50%);\r\n    max-height: calc(100vh - 24px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));\r\n    flex-direction: column;\r\n    -webkit-touch-callout: none;\r\n    -webkit-user-select: none;\r\n    user-select: none;\r\n    touch-action: manipulation;\r\n  }\r\n\r\n  [data-stdg-dock-list] {\r\n    flex-direction: column;\r\n  }\r\n\r\n  [data-stdg-dock-tools] {\r\n    flex-direction: column;\r\n    transition:\r\n      max-height 0.22s ease,\r\n      opacity 0.16s ease;\r\n  }\r\n\r\n  [data-stdg-dock][data-collapsed=\"true\"] [data-stdg-dock-tools] {\r\n    overflow: hidden;\r\n  }\r\n\r\n  [data-stdg-horizontal-line] {\r\n    width: auto;\r\n    height: 0px;\r\n    margin: 4px 0;\r\n    border-right: none;\r\n    border-top: 1px solid var(--string-dg-color-hairline);\r\n  }\r\n\r\n  [data-stdg-dock-slot][data-has-sub-badges]::after {\r\n    left: 100%;\r\n    right: auto;\r\n    top: -4px;\r\n    bottom: -4px;\r\n    width: 8px;\r\n    height: auto;\r\n  }\r\n\r\n  [data-stdg-dock-sub-badges] {\r\n    flex-direction: column;\r\n    transform: translate(8px, -50%);\r\n  }\r\n\r\n  [data-stdg-dock-sub-badges][data-open=\"true\"] {\r\n    transform: translate(0, -50%);\r\n  }\r\n\r\n  /* compact: panel width shrinks to fit narrow viewports */\r\n  [data-stdg-panel] {\r\n    width: min(280px, calc(100vw - 32px));\r\n    max-width: calc(100vw - 32px);\r\n  }\r\n\r\n  [data-stdg-badge][data-mobile-sheet=\"true\"] > [data-stdg-panel] {\r\n    right: auto;\r\n    height: auto;\r\n    overflow: hidden auto;\r\n    overscroll-behavior: contain;\r\n  }\r\n\r\n  [data-stdg-badge][data-mobile-sheet=\"true\"] > [data-stdg-panel] > [data-stdg-panel] {\r\n    position: static;\r\n    display: none;\r\n    inset: auto;\r\n    width: 100%;\r\n    max-width: 100%;\r\n    height: auto;\r\n    overflow: hidden auto;\r\n    overscroll-behavior: contain;\r\n    box-shadow: none;\r\n    transform: none;\r\n  }\r\n\r\n  [data-stdg-badge][data-mobile-sheet=\"true\"] > [data-stdg-panel]:has(> [data-stdg-panel][data-open=\"true\"]) > :not([data-stdg-panel]) {\r\n    display: none;\r\n  }\r\n\r\n  [data-stdg-badge][data-mobile-sheet=\"true\"] > [data-stdg-panel] > [data-stdg-panel][data-open=\"true\"] {\r\n    display: block;\r\n  }\r\n\r\n  /* panel detached to body as fixed element in mobile mode */\r\n  [data-stdg-panel][data-mobile-sheet=\"true\"] {\r\n    z-index: 10045;\r\n    overflow: hidden auto;\r\n    overscroll-behavior: contain;\r\n  }\r\n\r\n  [data-stdg-panel][data-mobile-sheet=\"true\"] > [data-stdg-panel] {\r\n    position: static;\r\n    display: none;\r\n    inset: auto;\r\n    width: 100%;\r\n    max-width: 100%;\r\n    height: auto;\r\n    overflow: hidden auto;\r\n    overscroll-behavior: contain;\r\n    box-shadow: none;\r\n    transform: none;\r\n  }\r\n\r\n  [data-stdg-panel][data-mobile-sheet=\"true\"]:has(> [data-stdg-panel][data-open=\"true\"]) > :not([data-stdg-panel]) {\r\n    display: none;\r\n  }\r\n\r\n  [data-stdg-panel][data-mobile-sheet=\"true\"] > [data-stdg-panel][data-open=\"true\"] {\r\n    display: block;\r\n  }\r\n\r\n  /* compact: progress floating panel */\r\n  [data-stdg-progress] {\r\n    bottom: max(16px, env(safe-area-inset-bottom, 0px) + 16px);\r\n    max-height: calc(100vh - 32px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));\r\n  }\r\n}\r\n\r\n/* badge */\r\n[data-stdg-badge] {\r\n  position: absolute;\r\n  z-index: 10030;\r\n  top: 0;\r\n  left: 0;\r\n  width: auto;\r\n  padding-bottom: auto;\r\n\r\n  display: flex;\r\n  pointer-events: auto;\r\n\r\n  background-color: var(--string-dg-color-cloud-white);\r\n  padding: var(--string-dg-badge-padding);\r\n  border: 1px solid var(--string-dg-color-middle-white);\r\n  border-radius: var(--string-dg-badge-radius);\r\n  box-shadow: var(--string-dg-badge-shadow);\r\n}\r\n\r\n[data-dragging-active] [data-stdg-badge]:not([data-dragging]) {\r\n  opacity: 0;\r\n  pointer-events: none;\r\n}\r\n\r\n[data-stdg-badge][data-test-progress] {\r\n  left: 62px;\r\n}\r\n[data-stdg-badge][data-test-layout] {\r\n  position: fixed;\r\n  top: 200px;\r\n  left: auto;\r\n  right: 100px;\r\n}\r\n[data-stdg-badge][data-visible=\"false\"] {\r\n  display: none;\r\n}\r\n\r\n[data-stdg-button]:has([data-stdg-badge-label]) {\r\n  flex-direction: column;\r\n  align-items: center;\r\n}\r\n[data-stdg-button]:has([data-stdg-badge-label]) svg {\r\n  transform: translateY(-25%);\r\n}\r\n[data-stdg-button]:has([data-stdg-badge-label]) > :not([data-stdg-badge-label]) {\r\n  grid-area: unset;\r\n}\r\n[data-stdg-badge-label] {\r\n  grid-area: unset;\r\n  font-size: var(--string-dg-font-size-xs);\r\n  line-height: 0;\r\n  text-align: center;\r\n  color: var(--string-dg-color-black);\r\n  pointer-events: none;\r\n  user-select: none;\r\n  // margin-bottom: -0.4em;\r\n  white-space: nowrap;\r\n  font-weight: var(--string-dg-font-bold);\r\n  width: 0;\r\n  display: flex;\r\n  justify-content: center;\r\n}\r\n\r\n/* panel */\r\n[data-stdg-panel] {\r\n  position: absolute;\r\n\r\n  width: 220px;\r\n  background-color: var(--string-dg-color-white);\r\n  padding: var(--string-dg-panel-padding);\r\n  border-radius: var(--string-dg-panel-radius);\r\n  box-shadow: var(--string-dg-panel-shadow);\r\n}\r\n[data-stdg-panel][data-open=\"false\"] {\r\n  opacity: 0;\r\n  pointer-events: none;\r\n  transform: translateY(4px);\r\n  transition: opacity 0.15s ease, transform 0.15s ease;\r\n}\r\n[data-stdg-panel][data-open=\"true\"] {\r\n  z-index: 10045;\r\n  opacity: 1;\r\n  pointer-events: auto;\r\n  transform: translateY(0);\r\n  transition: opacity 0.15s ease, transform 0.15s ease;\r\n}\r\n[data-stdg-panel][data-test-panel-1] {\r\n  top: 0px;\r\n  right: calc(100% + 20px);\r\n}\r\n[data-stdg-panel][data-test-panel-2] {\r\n  top: 0;\r\n  right: calc(100% + 20px + 220px + 80px);\r\n}\r\n[data-stdg-panel][data-test-panel-3] {\r\n  top: 0;\r\n  right: calc(100% + 20px);\r\n}\r\n\r\n[data-stdg-panel][data-test-panel-4] {\r\n  top: 0;\r\n  right: calc(100% + 20px + 220px + 80px + 220px + 20px + 220px + 80px);\r\n}\r\n[data-stdg-panel][data-test-panel-5] {\r\n  top: 0;\r\n  right: calc(100% + 20px);\r\n}\r\n[data-stdg-panel][data-test-panel-6] {\r\n  top: calc(400px);\r\n  right: calc(100% + 20px);\r\n}\r\n[data-stdg-panel][data-test-panel-7] {\r\n  top: calc(36px);\r\n  right: calc(100% + 20px);\r\n}\r\n\r\n/* progress */\r\n[data-stdg-progress] {\r\n  position: fixed;\r\n  z-index: 999;\r\n  bottom: 62px;\r\n  left: calc((100vw + env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px)) / 2);\r\n  translate: -50% 0;\r\n\r\n  width: min(\r\n    440px,\r\n    calc(100vw - 24px - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px))\r\n  );\r\n  max-height: calc(100vh - 86px - env(safe-area-inset-top, 0px) - env(safe-area-inset-bottom, 0px));\r\n  overflow: hidden auto;\r\n  overscroll-behavior: contain;\r\n}\r\n\r\n[data-stdg-panel-hr] {\r\n  display: block;\r\n  margin: var(--string-dg-panel-hr-margin);\r\n  border-bottom: 1px solid var(--string-dg-color-grey-1);\r\n}\r\n/* header */\r\n[data-stdg-panel-header] {\r\n  display: grid;\r\n  place-items: center;\r\n  padding: var(--string-dg-panel-header-padding);\r\n}\r\n[data-stdg-panel-header] > * {\r\n  grid-area: 1/1;\r\n}\r\n[data-stdg-button-left] {\r\n  justify-self: start;\r\n}\r\n[data-stdg-button-right] {\r\n  justify-self: end;\r\n}\r\n[data-stdg-panel-header] span {\r\n  font-size: var(--string-dg-font-size-s);\r\n  font-weight: var(--string-dg-font-bold);\r\n}\r\n[data-stdg-panel-header] nav {\r\n  display: flex;\r\n}\r\n\r\n/* responsive */\r\n[data-stdg-panel-responsive] {\r\n  display: grid;\r\n  place-items: center;\r\n  padding: var(--string-dg-panel-responsive-margin);\r\n}\r\n[data-stdg-panel-responsive] > * {\r\n  grid-area: 1/1;\r\n}\r\n[data-stdg-panel-list] {\r\n  display: flex;\r\n  flex-direction: row;\r\n}\r\n\r\n/* content */\r\n[data-stdg-panel-content] {\r\n  margin: var(--string-dg-panel-conent-margin);\r\n}\r\n[data-stdg-panel-content-50] {\r\n  display: flex;\r\n  flex-wrap: wrap;\r\n}\r\n[data-stdg-panel-content-50] > * {\r\n  width: 50% !important;\r\n}\r\n\r\n/* list-item */\r\n\r\n/* offsets */\r\n[data-stdg-offsets-item] {\r\n  position: absolute;\r\n  z-index: 999;\r\n  top: 600px;\r\n  left: 260px;\r\n\r\n  width: 400px;\r\n  height: 400px;\r\n  fill: none;\r\n  overflow: visible;\r\n}\r\n[data-stdg-offsets-item] [data-stdg-offsets-item-border] {\r\n  stroke-width: 1px;\r\n  stroke: var(--string-dg-color-offset);\r\n  stroke-dasharray: var(--string-dg-offsets-dasharray);\r\n}\r\n[data-stdg-offsets-item-offset] {\r\n}\r\n[data-stdg-offsets-item-offset-arrow-bg] {\r\n  color: var(--string-dg-color-white);\r\n}\r\n[data-stdg-offsets-item-offset-arrow] {\r\n  color: var(--string-dg-color-black);\r\n}\r\n\r\n`;\r\n","import { CORE_STYLES } from \"./StringDevCoreStyles.css\";\r\nexport type StringDevStyleTokens = Record<string, string>;\r\n\r\nconst STRING_DEV_DEFAULT_TOKENS: StringDevStyleTokens = {\r\n  \"--string-dev-panel-bg\": \"#ffffff\",\r\n  \"--string-dev-panel-border\": \"1px solid #e0e0e0\",\r\n  \"--string-dev-panel-radius\": \"16px\",\r\n  \"--string-dev-panel-shadow\": \"0 16px 24px rgba(0, 0, 0, 0.1)\",\r\n  \"--string-dev-panel-backdrop\": \"blur(12px)\",\r\n  \"--string-dev-panel-padding\": \"4px\",\r\n  \"--string-dev-panel-font-family\":\r\n    '-apple-system, system-ui, BlinkMacSystemFont, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, sans-serif',\r\n  \"--string-dev-panel-font-size\": \"12px\",\r\n  \"--string-dev-panel-text\": \"#111111\",\r\n  \"--string-dev-panel-muted\": \"rgba(17, 17, 17, 0.6)\",\r\n  \"--string-dev-panel-subtle\": \"rgba(17, 17, 17, 0.72)\",\r\n  \"--string-dev-panel-divider\": \"rgba(17, 17, 17, 0.08)\",\r\n  \"--string-dev-header-font-size\": \"10px\",\r\n  \"--string-dev-header-font-weight\": \"500\",\r\n  \"--string-dev-header-letter-spacing\": \"0\",\r\n  \"--string-dev-header-padding\": \"8px 8px 8px\",\r\n  \"--string-dev-header-margin-bottom\": \"4px\",\r\n  \"--string-dev-accent\": \"#FF4F36\",\r\n  \"--string-dev-accent-soft\": \"rgba(255, 79, 54, 0.12)\",\r\n  \"--string-dev-accent-soft-hover\": \"rgba(255, 79, 54, 0.18)\",\r\n  \"--string-dev-focus-color\": \"rgba(255, 79, 54, 0.68)\",\r\n  \"--string-dev-focus-shadow\": \"0 0 0 2px rgba(255, 79, 54, 0.18)\",\r\n  \"--string-dev-field-bg\": \"rgba(221, 221, 221, 0.4)\",\r\n  \"--string-dev-field-border\": \"rgba(255, 255, 255, 0.96)\",\r\n  \"--string-dev-field-radius\": \"8px\",\r\n  \"--string-dev-input-height\": \"32px\",\r\n  \"--string-dev-button-height\": \"32px\",\r\n  \"--string-dev-chip-size\": \"24px\",\r\n  \"--string-dev-icon-button-size\": \"20px\",\r\n  \"--string-dev-icon-button-radius\": \"8px\",\r\n  \"--string-dev-chip-active-bg\": \"rgba(221, 221, 221, 0.54)\",\r\n  \"--string-dev-chip-muted\": \"rgba(17, 17, 17, 0.22)\",\r\n  \"--string-dev-chip-resolved\": \"rgba(17, 17, 17, 0.78)\",\r\n  \"--string-dev-icon-button-hover-bg\": \"rgba(17, 17, 17, 0.08)\",\r\n};\r\n\r\nfunction indentCss(cssText: string, indent: string): string {\r\n  return cssText\r\n    .trim()\r\n    .split(\"\\n\")\r\n    .map((line) => `${indent}${line}`)\r\n    .join(\"\\n\");\r\n}\r\n\r\nexport function buildDevtoolsThemeBlock(\r\n  selectors: string | string[],\r\n  overrides: StringDevStyleTokens = {},\r\n): string {\r\n  const selectorText = Array.isArray(selectors) ? selectors.join(\",\\n\") : selectors;\r\n  const tokens = { ...STRING_DEV_DEFAULT_TOKENS, ...overrides };\r\n  const declarations = Object.entries(tokens)\r\n    .map(([name, value]) => `${name}: ${value};`)\r\n    .join(\"\\n\");\r\n\r\n  return `${selectorText} {\\n${indentCss(declarations, \"  \")}\\n}`;\r\n}\r\n\r\nexport function ensureStringDevtoolsSharedStyles(): HTMLStyleElement | null {\r\n  if (typeof document === \"undefined\") {\r\n    return null;\r\n  }\r\n\r\n  const styleId = \"string-devtools-shared-styles\";\r\n  const existing = document.getElementById(styleId);\r\n  if (existing instanceof HTMLStyleElement) {\r\n    return existing;\r\n  }\r\n\r\n  const style = document.createElement(\"style\");\r\n  style.id = styleId;\r\n  style.textContent = CORE_STYLES;\r\n  document.head.appendChild(style);\r\n  return style;\r\n}\r\n","export interface StringDevViewportPolicy {\n  coarsePointer: boolean;\n  compact: boolean;\n}\n\nconst COMPACT_VIEWPORT_WIDTH = 1024;\n\nfunction canUseMatchMedia(): boolean {\n  return typeof window !== \"undefined\" && typeof window.matchMedia === \"function\";\n}\n\nexport function isCoarsePointerDevice(): boolean {\n  if (!canUseMatchMedia()) {\n    return false;\n  }\n\n  return (\n    window.matchMedia(\"(pointer: coarse)\").matches ||\n    window.matchMedia(\"(any-pointer: coarse)\").matches\n  );\n}\n\nexport function getStringDevViewportPolicy(\n  viewportWidth: number = typeof window !== \"undefined\" ? window.innerWidth : COMPACT_VIEWPORT_WIDTH,\n): StringDevViewportPolicy {\n  const coarsePointer = isCoarsePointerDevice();\n  const compact = viewportWidth <= COMPACT_VIEWPORT_WIDTH || coarsePointer;\n\n  return {\n    coarsePointer,\n    compact,\n  };\n}\n","let storageScopeToken = \"\";\n\nfunction normalizeStorageScopeToken(value: string | null | undefined): string {\n  const normalized = (value ?? \"\").trim();\n  if (!normalized) return \"\";\n  return encodeURIComponent(normalized);\n}\n\nexport function setStringDevStorageScopeToken(value: string | null | undefined): void {\n  storageScopeToken = normalizeStorageScopeToken(value);\n}\n\nexport function scopeStringDevStorageKey(baseKey: string): string {\n  if (!storageScopeToken) {\n    return baseKey;\n  }\n  return `${baseKey}::${storageScopeToken}`;\n}\n","﻿import {\r\n  StringDevtoolDefinition,\r\n  StringDevtoolState,\r\n  StringDevtoolSubBadge,\r\n} from \"../../../models/devtools/StringDevtool\";\r\nimport { makeIconButton } from \"./StringDevElements\";\r\nimport { resolveDevtoolsIcon } from \"./StringDevIconRegistry\";\r\nimport { ensureStringDevtoolsSharedStyles } from \"./StringDevStyleSystem\";\r\nimport { getStringDevViewportPolicy } from \"./StringDevViewportPolicy\";\r\nimport { scopeStringDevStorageKey } from \"./StringDevStorageScope\";\r\n\r\ninterface DockEntry {\n  definition: StringDevtoolDefinition;\n  button: HTMLButtonElement;\n  slot: HTMLDivElement;\n  subBadges: HTMLDivElement | null;\n  unsubscribe: (() => void) | null;\n  cleanup: Array<() => void>;\n}\n\r\ninterface DockPreferences {\r\n  collapsed: boolean;\r\n  active: Record<string, boolean>;\r\n}\r\n\r\nconst DEVTOOLS_DOCK_STORAGE_KEY = \"string-devtools:dock\";\nconst SUB_BADGE_LONG_PRESS_DELAY_MS = 600;\nconst SUB_BADGE_LONG_PRESS_MOVE_TOLERANCE = 12;\nconst DOCK_ROOT_SELECTOR = \"[data-stdg-dock]\";\nconst SUB_BADGE_GROUP_SELECTOR = \"[data-stdg-dock-sub-badges]\";\n\r\nfunction formatHotkey(hotkey: StringDevtoolDefinition[\"hotkey\"]): string {\r\n  if (!hotkey) return \"\";\r\n\r\n  const parts: string[] = [];\r\n  if (hotkey.ctrlKey) parts.push(\"Ctrl\");\r\n  if (hotkey.altKey) parts.push(\"Alt\");\r\n  if (hotkey.shiftKey) parts.push(\"Shift\");\r\n  if (hotkey.metaKey) parts.push(\"Meta\");\r\n  parts.push(hotkey.key.length === 1 ? hotkey.key.toUpperCase() : hotkey.key);\r\n  return parts.join(\"+\");\r\n}\r\n\r\nexport class StringDevtoolsDock {\r\n  private root: HTMLDivElement;\r\n  private mainButton: HTMLButtonElement;\r\n  private itemsWrap: HTMLDivElement;\r\n  private toolsWrap: HTMLDivElement;\r\n  private fpsSeparator: HTMLSpanElement;\r\n  private fpsElement: HTMLDivElement;\r\n  private entries: Map<string, DockEntry> = new Map();\r\n  private collapsed: boolean = false;\r\n  private suppressPersist: boolean = false;\r\n  private readonly preferences: DockPreferences;\r\n  private readonly onKeydownBind: (event: KeyboardEvent) => void;\r\n  private readonly onResizeBind: () => void;\r\n\r\n  constructor() {\n    ensureStringDevtoolsSharedStyles();\n    this.cleanupExistingDockArtifacts();\n    this.preferences = this.loadPreferences();\n    this.onResizeBind = () => {\r\n      window.requestAnimationFrame(() => this.handleViewportChange());\r\n    };\r\n    this.onKeydownBind = (event: KeyboardEvent) => {\r\n      const target = event.target as HTMLElement | null;\r\n      if (\r\n        target &&\r\n        (target instanceof HTMLInputElement ||\r\n          target instanceof HTMLTextAreaElement ||\r\n          target instanceof HTMLSelectElement ||\r\n          target.isContentEditable)\r\n      ) {\r\n        return;\r\n      }\r\n      if (\r\n        event.shiftKey &&\r\n        !event.ctrlKey &&\r\n        !event.altKey &&\r\n        !event.metaKey &&\r\n        event.code === \"KeyS\"\r\n      ) {\r\n        event.preventDefault();\r\n        this.setCollapsed(!this.collapsed);\r\n      }\r\n    };\r\n    window.addEventListener(\"keydown\", this.onKeydownBind);\r\n    window.addEventListener(\"resize\", this.onResizeBind);\r\n    this.root = document.createElement(\"div\");\r\n    this.root.setAttribute(\"data-stdg\", \"\");\r\n    this.root.setAttribute(\"data-stdg-dock\", \"\");\r\n    this.root.setAttribute(\"data-collapsed\", this.preferences.collapsed ? \"true\" : \"false\");\r\n    this.mainButton = this.createMainButton();\r\n    this.itemsWrap = document.createElement(\"div\");\r\n    this.itemsWrap.setAttribute(\"data-stdg-dock-list\", \"\");\r\n    this.toolsWrap = document.createElement(\"div\");\r\n    this.toolsWrap.setAttribute(\"data-stdg-dock-tools\", \"\");\r\n    this.fpsSeparator = this.createSeparator();\r\n    this.fpsSeparator.setAttribute(\"data-stdg-dock-fps-separator\", \"\");\r\n    this.fpsElement = document.createElement(\"div\");\r\n    this.fpsElement.setAttribute(\"data-string-defguides-doc-fps\", \"\");\r\n    this.fpsElement.title = \"Current FPS\";\r\n    const fpsSpan = document.createElement(\"span\");\r\n    fpsSpan.textContent = \"0\";\r\n    this.fpsElement.appendChild(fpsSpan);\r\n    this.root.appendChild(this.mainButton);\r\n    this.itemsWrap.appendChild(this.toolsWrap);\r\n    this.itemsWrap.appendChild(this.fpsSeparator);\r\n    this.itemsWrap.appendChild(this.fpsElement);\r\n    this.root.appendChild(this.itemsWrap);\r\n    (document.body ?? document.documentElement).appendChild(this.root);\r\n    this.setCollapsed(this.preferences.collapsed, false);\r\n  }\r\n\r\n  add(definition: StringDevtoolDefinition): void {\r\n    if (this.entries.has(definition.id)) {\r\n      return;\r\n    }\r\n\r\n    this.applyStoredActiveState(definition);\r\n\r\n    const button = document.createElement(\"button\");\r\n    button.type = \"button\";\r\n    button.setAttribute(\"data-stdg\", \"\");\r\n    button.setAttribute(\"data-stdg-button\", \"\");\r\n    button.setAttribute(\"data-stdg-button-icon-20\", \"\");\r\n    button.setAttribute(\"data-devguides-id\", definition.id);\r\n    const hotkeyLabel = formatHotkey(definition.hotkey);\r\n    const buttonLabel = hotkeyLabel ? `${definition.label} (${hotkeyLabel})` : definition.label;\r\n    button.setAttribute(\"aria-label\", buttonLabel);\r\n    button.innerHTML = resolveDevtoolsIcon(20, definition.icon);\r\n    button.title = buttonLabel;\r\n    button.addEventListener(\"click\", () => {\r\n      const nextActive = !definition.getState().active;\r\n      definition.setActive(nextActive);\r\n      if (!definition.subscribe) {\r\n        const nextState = definition.getState();\r\n        this.renderButton(button, definition.label, definition.hotkey, nextState);\r\n        this.persistActiveState(definition.id, nextState.active);\r\n      }\r\n    });\r\n\r\n    const slot = document.createElement(\"div\");\r\n    slot.setAttribute(\"data-stdg\", \"\");\r\n    slot.setAttribute(\"data-stdg-dock-slot\", \"\");\r\n    slot.setAttribute(\"data-devguides-slot\", definition.id);\r\n    slot.appendChild(button);\r\n\r\n    let subBadges: HTMLDivElement | null = null;\r\n    if (definition.subBadges && definition.subBadges.length > 0) {\r\n      slot.setAttribute(\"data-has-sub-badges\", \"\");\r\n      subBadges = this.createSubBadgeGroup(definition);\n    }\n\n    const cleanup: Array<() => void> = [];\n    if (subBadges) {\n      cleanup.push(...this.attachSubBadges(slot, subBadges));\n    }\n\n    const unsubscribe = definition.subscribe\n      ? definition.subscribe((state) => {\n          this.renderButton(button, definition.label, definition.hotkey, state);\n          this.syncSubBadgeState(slot, subBadges, state.active);\n          this.persistActiveState(definition.id, state.active);\n        })\n      : null;\n\n    this.entries.set(definition.id, { definition, button, slot, subBadges, unsubscribe, cleanup });\n    this.toolsWrap.appendChild(slot);\r\n    this.sortButtons();\r\n    const currentState = definition.getState();\r\n    this.renderButton(button, definition.label, definition.hotkey, currentState);\r\n    this.syncSubBadgeState(slot, subBadges, currentState.active);\r\n    this.persistActiveState(definition.id, currentState.active);\r\n  }\r\n\r\n  private attachSubBadges(slot: HTMLDivElement, group: HTMLDivElement): Array<() => void> {\n    const cleanup: Array<() => void> = [];\n    (document.body ?? document.documentElement).appendChild(group);\n\n    let open = false;\n    let longPressTimer: number | null = null;\r\n    let longPressPointerId: number | null = null;\r\n    let longPressStartX = 0;\r\n    let longPressStartY = 0;\r\n    let suppressNextClick = false;\r\n    const setOpen = (next: boolean) => {\r\n      if (open === next) return;\r\n      open = next;\r\n      group.setAttribute(\"data-open\", next ? \"true\" : \"false\");\r\n      if (next) this.positionSubBadges(slot, group);\r\n    };\r\n\r\n    const isCompact = () => getStringDevViewportPolicy(window.innerWidth).compact;\r\n    const clearLongPress = () => {\r\n      if (longPressTimer !== null) {\r\n        window.clearTimeout(longPressTimer);\r\n        longPressTimer = null;\r\n      }\r\n      longPressPointerId = null;\r\n    };\r\n    const releaseLongPress = () => {\r\n      clearLongPress();\r\n      if (!suppressNextClick) return;\r\n      window.setTimeout(() => {\r\n        suppressNextClick = false;\r\n      }, 0);\r\n    };\r\n\r\n    const scheduleClose = () => {\r\n      window.setTimeout(() => {\r\n        if (slot.matches(\":hover\") || group.matches(\":hover\")) return;\r\n        setOpen(false);\r\n      }, 60);\r\n    };\r\n\r\n    const onSlotPointerEnter = () => {\n      if (!isCompact()) setOpen(true);\n    };\n    slot.addEventListener(\"pointerenter\", onSlotPointerEnter);\n    cleanup.push(() => slot.removeEventListener(\"pointerenter\", onSlotPointerEnter));\n    const onSlotPointerLeave = () => {\n      if (!isCompact()) scheduleClose();\n    };\n    slot.addEventListener(\"pointerleave\", onSlotPointerLeave);\n    cleanup.push(() => slot.removeEventListener(\"pointerleave\", onSlotPointerLeave));\n    const onGroupPointerEnter = () => {\n      if (!isCompact()) setOpen(true);\n    };\n    group.addEventListener(\"pointerenter\", onGroupPointerEnter);\n    cleanup.push(() => group.removeEventListener(\"pointerenter\", onGroupPointerEnter));\n    const onGroupPointerLeave = () => {\n      if (!isCompact()) scheduleClose();\n    };\n    group.addEventListener(\"pointerleave\", onGroupPointerLeave);\n    cleanup.push(() => group.removeEventListener(\"pointerleave\", onGroupPointerLeave));\n    const onSubBadgeAction = () => setOpen(false);\n    group.addEventListener(\"string-devtools-sub-badge-action\", onSubBadgeAction);\n    cleanup.push(() => group.removeEventListener(\"string-devtools-sub-badge-action\", onSubBadgeAction));\n    const onSlotPointerDown = (event: PointerEvent) => {\n      if (!isCompact()) return;\n      if (\n        event.target instanceof HTMLElement &&\n        event.target.closest(\"[data-stdg-dock-sub-badge]\")\r\n      ) {\r\n        return;\r\n      }\r\n      clearLongPress();\r\n      longPressPointerId = event.pointerId;\r\n      longPressStartX = event.clientX;\r\n      longPressStartY = event.clientY;\r\n      longPressTimer = window.setTimeout(() => {\n        longPressTimer = null;\n        suppressNextClick = true;\n        setOpen(true);\n      }, SUB_BADGE_LONG_PRESS_DELAY_MS);\n    };\n    slot.addEventListener(\"pointerdown\", onSlotPointerDown);\n    cleanup.push(() => slot.removeEventListener(\"pointerdown\", onSlotPointerDown));\n    const onSlotPointerMove = (event: PointerEvent) => {\n      if (!isCompact() || longPressTimer === null || event.pointerId !== longPressPointerId) {\n        return;\n      }\n      const distanceX = Math.abs(event.clientX - longPressStartX);\r\n      const distanceY = Math.abs(event.clientY - longPressStartY);\r\n      if (\r\n        distanceX > SUB_BADGE_LONG_PRESS_MOVE_TOLERANCE ||\r\n        distanceY > SUB_BADGE_LONG_PRESS_MOVE_TOLERANCE\r\n      ) {\n        clearLongPress();\n      }\n    };\n    slot.addEventListener(\"pointermove\", onSlotPointerMove);\n    cleanup.push(() => slot.removeEventListener(\"pointermove\", onSlotPointerMove));\n    slot.addEventListener(\"pointerup\", releaseLongPress);\n    cleanup.push(() => slot.removeEventListener(\"pointerup\", releaseLongPress));\n    slot.addEventListener(\"pointercancel\", releaseLongPress);\n    cleanup.push(() => slot.removeEventListener(\"pointercancel\", releaseLongPress));\n    const onSlotPointerLeaveCompact = () => {\n      if (isCompact()) clearLongPress();\n    };\n    slot.addEventListener(\"pointerleave\", onSlotPointerLeaveCompact);\n    cleanup.push(() => slot.removeEventListener(\"pointerleave\", onSlotPointerLeaveCompact));\n    const onSlotContextMenu = (event: Event) => {\n      if (!isCompact() || !suppressNextClick) return;\n      event.preventDefault();\n    };\n    slot.addEventListener(\"contextmenu\", onSlotContextMenu);\n    cleanup.push(() => slot.removeEventListener(\"contextmenu\", onSlotContextMenu));\n    const onSlotSelectStart = (event: Event) => {\n      if (!isCompact()) return;\n      event.preventDefault();\n    };\n    slot.addEventListener(\"selectstart\", onSlotSelectStart);\n    cleanup.push(() => slot.removeEventListener(\"selectstart\", onSlotSelectStart));\n    const onSlotClickCapture = (event: Event) => {\n      if (!isCompact() || !suppressNextClick) return;\n      suppressNextClick = false;\n      event.preventDefault();\n      event.stopImmediatePropagation();\n    };\n    slot.addEventListener(\"click\", onSlotClickCapture, true);\n    cleanup.push(() => slot.removeEventListener(\"click\", onSlotClickCapture, true));\n    group.addEventListener(\"pointerdown\", releaseLongPress);\n    cleanup.push(() => group.removeEventListener(\"pointerdown\", releaseLongPress));\n    group.addEventListener(\"pointercancel\", releaseLongPress);\n    cleanup.push(() => group.removeEventListener(\"pointercancel\", releaseLongPress));\n    const onGroupContextMenu = (event: Event) => {\n      if (!isCompact()) return;\n      event.preventDefault();\n    };\n    group.addEventListener(\"contextmenu\", onGroupContextMenu);\n    cleanup.push(() => group.removeEventListener(\"contextmenu\", onGroupContextMenu));\n    const onGroupSelectStart = (event: Event) => {\n      if (!isCompact()) return;\n      event.preventDefault();\n    };\n    group.addEventListener(\"selectstart\", onGroupSelectStart);\n    cleanup.push(() => group.removeEventListener(\"selectstart\", onGroupSelectStart));\n    const onGroupClick = () => {\n      suppressNextClick = false;\n    };\n    group.addEventListener(\"click\", onGroupClick);\n    cleanup.push(() => group.removeEventListener(\"click\", onGroupClick));\n    const onDocumentPointerDown = (event: PointerEvent) => {\n      if (!open) return;\n      const target = event.target;\n      if (!(target instanceof Node)) return;\n      if (slot.contains(target) || group.contains(target)) return;\n      setOpen(false);\n    };\n    document.addEventListener(\"pointerdown\", onDocumentPointerDown);\n    cleanup.push(() => document.removeEventListener(\"pointerdown\", onDocumentPointerDown));\n\n    const activeObserver = new MutationObserver(() => {\n      if (!group.querySelector('[data-active=\"true\"]')) scheduleClose();\n    });\r\n    activeObserver.observe(group, {\r\n      subtree: true,\n      attributes: true,\n      attributeFilter: [\"data-active\"],\n    });\n    cleanup.push(() => activeObserver.disconnect());\n\n    const reposition = () => {\n      if (open) this.positionSubBadges(slot, group);\n    };\n    window.addEventListener(\"resize\", reposition);\n    window.addEventListener(\"scroll\", reposition, true);\n    cleanup.push(() => window.removeEventListener(\"resize\", reposition));\n    cleanup.push(() => window.removeEventListener(\"scroll\", reposition, true));\n\n    group.setAttribute(\"data-open\", \"false\");\n    cleanup.push(() => group.remove());\n    return cleanup;\n  }\n\r\n  private positionSubBadges(slot: HTMLDivElement, group: HTMLDivElement): void {\r\n    const rect = slot.getBoundingClientRect();\r\n    if (getStringDevViewportPolicy(window.innerWidth).compact) {\r\n      group.style.left = `${Math.round(rect.right + 8)}px`;\r\n      group.style.top = `${Math.round(rect.top + rect.height / 2)}px`;\r\n      group.style.bottom = \"\";\r\n    } else {\r\n      group.style.left = `${Math.round(rect.left + rect.width / 2)}px`;\r\n      group.style.top = \"\";\r\n      group.style.bottom = `${Math.round(window.innerHeight - rect.top + 8)}px`;\r\n    }\r\n  }\r\n\r\n  private createSubBadgeGroup(definition: StringDevtoolDefinition): HTMLDivElement {\r\n    const group = document.createElement(\"div\");\r\n    group.setAttribute(\"data-stdg\", \"\");\r\n    group.setAttribute(\"data-stdg-dock-sub-badges\", \"\");\r\n    group.setAttribute(\"data-parent-active\", \"false\");\r\n    for (const descriptor of definition.subBadges ?? []) {\r\n      const attrs: Record<string, string> = {\r\n        \"data-stdg\": \"\",\r\n        \"data-stdg-dock-sub-badge\": \"\",\r\n        \"data-sub-badge-id\": descriptor.id,\r\n        \"data-active\": \"false\",\r\n        \"data-parent-active\": \"false\",\r\n      };\r\n      if (descriptor.selectorAttribute) {\r\n        attrs[descriptor.selectorAttribute] = \"\";\r\n      }\r\n      if (descriptor.attributes) {\r\n        for (const [key, value] of Object.entries(descriptor.attributes)) {\r\n          if (value === null || value === undefined || value === false) continue;\r\n          attrs[key] = value === true ? \"\" : String(value);\r\n        }\r\n      }\r\n      const badge = makeIconButton({\r\n        icon: descriptor.icon,\r\n        size: 16,\r\n        label: descriptor.label,\r\n        modifiers: [\"toggle\"],\r\n        attrs,\r\n      });\r\n      badge.addEventListener(\"pointerdown\", (event) => {\r\n        event.stopPropagation();\r\n      });\r\n      badge.addEventListener(\"click\", (event) => {\r\n        event.stopPropagation();\r\n        if (!definition.getState().active) {\r\n          definition.setActive(true);\r\n        }\r\n        descriptor.onClick(badge);\r\n        badge.setAttribute(\"data-active\", \"false\");\r\n        badge.dispatchEvent(new CustomEvent(\"string-devtools-sub-badge-action\", { bubbles: true }));\r\n      });\r\n      group.appendChild(badge);\r\n    }\r\n    return group;\r\n  }\r\n\r\n  remove(id: string): void {\n    const entry = this.entries.get(id);\n    if (!entry) return;\n\n    entry.unsubscribe?.();\n    for (const cleanup of entry.cleanup) cleanup();\n    entry.slot.remove();\n    this.entries.delete(id);\n  }\n\n  destroy(): void {\n    window.removeEventListener(\"keydown\", this.onKeydownBind);\r\n    window.removeEventListener(\"resize\", this.onResizeBind);\n    for (const entry of this.entries.values()) {\n      entry.unsubscribe?.();\n      for (const cleanup of entry.cleanup) cleanup();\n      entry.slot.remove();\n    }\n    this.entries.clear();\n    this.root.remove();\n  }\n\n  private cleanupExistingDockArtifacts(): void {\n    document.querySelectorAll(DOCK_ROOT_SELECTOR).forEach((node) => node.remove());\n    document.querySelectorAll(SUB_BADGE_GROUP_SELECTOR).forEach((node) => node.remove());\n  }\n\r\n  setFPS(fps: number): void {\r\n    const span = this.fpsElement.querySelector(\"span\");\r\n    if (span) span.textContent = String(Math.max(0, Math.round(fps)));\r\n  }\r\n\r\n  private sortButtons(): void {\r\n    const ordered = Array.from(this.entries.values()).sort((left, right) => {\r\n      const leftOrder = left.definition.order ?? 0;\r\n      const rightOrder = right.definition.order ?? 0;\r\n      if (leftOrder !== rightOrder) {\r\n        return leftOrder - rightOrder;\r\n      }\r\n      return left.definition.label.localeCompare(right.definition.label);\r\n    });\r\n\r\n    this.toolsWrap.innerHTML = \"\";\r\n    this.toolsWrap.appendChild(this.createSeparator());\r\n\r\n    let lastGroup: number | undefined = undefined;\r\n    for (const entry of ordered) {\r\n      const currentGroup = entry.definition.group;\r\n      if (lastGroup !== undefined && currentGroup !== lastGroup) {\r\n        this.toolsWrap.appendChild(this.createSeparator());\r\n      }\r\n      lastGroup = currentGroup;\r\n      this.toolsWrap.appendChild(entry.slot);\r\n    }\r\n\r\n    this.fpsSeparator.style.display = ordered.length > 0 ? \"block\" : \"none\";\r\n    this.syncCollapsedLayout();\r\n  }\r\n\r\n  private createSeparator(): HTMLSpanElement {\r\n    const sep = document.createElement(\"span\");\r\n    sep.setAttribute(\"data-stdg-horizontal-line\", \"\");\r\n    return sep;\r\n  }\r\n\r\n  private createMainButton(): HTMLButtonElement {\r\n    const button = document.createElement(\"button\");\r\n    button.type = \"button\";\r\n    button.setAttribute(\"data-stdg\", \"\");\r\n    button.setAttribute(\"data-stdg-button\", \"\");\r\n    button.setAttribute(\"data-stdg-button-hover\", \"\");\r\n    button.setAttribute(\"data-stdg-button-icon-20\", \"\");\r\n    button.setAttribute(\"data-collapsed\", this.preferences.collapsed ? \"true\" : \"false\");\r\n    button.setAttribute(\"aria-label\", \"Toggle Dev Guides\");\r\n    button.innerHTML = `\r\n      ${resolveDevtoolsIcon(20, \"logo\")}\r\n      ${resolveDevtoolsIcon(12, \"chevrone-up\")}\r\n    `;\r\n    button.addEventListener(\"click\", () => {\r\n      this.setCollapsed(!this.collapsed);\r\n    });\r\n    return button;\r\n  }\r\n\r\n  private setCollapsed(collapsed: boolean, persist: boolean = true): void {\r\n    this.collapsed = collapsed;\r\n    this.root.setAttribute(\"data-collapsed\", collapsed ? \"true\" : \"false\");\r\n    this.mainButton.setAttribute(\"data-collapsed\", collapsed ? \"true\" : \"false\");\r\n    this.mainButton.setAttribute(\r\n      \"aria-label\",\r\n      collapsed ? \"Expand developer tools\" : \"Collapse developer tools\",\r\n    );\r\n    if (collapsed) {\r\n      this.suppressPersist = true;\r\n      for (const entry of this.entries.values()) {\r\n        if (entry.definition.getState().active) {\r\n          entry.definition.setActive(false);\r\n        }\r\n      }\r\n      this.suppressPersist = false;\r\n    } else {\r\n      this.suppressPersist = true;\r\n      for (const entry of this.entries.values()) {\r\n        const saved = this.preferences.active[entry.definition.id];\r\n        if (saved === true) {\r\n          entry.definition.setActive(true);\r\n        }\r\n      }\r\n      this.suppressPersist = false;\r\n    }\r\n    if (persist) {\r\n      this.preferences.collapsed = collapsed;\r\n      this.savePreferences();\r\n    }\r\n    this.syncCollapsedLayout();\r\n  }\r\n\r\n  private syncCollapsedLayout(): void {\r\n    const compact = getStringDevViewportPolicy(window.innerWidth).compact;\r\n    const contentSize = compact ? this.toolsWrap.scrollHeight : this.toolsWrap.scrollWidth;\r\n    this.toolsWrap.style.maxHeight = compact ? (this.collapsed ? \"0px\" : `${contentSize}px`) : \"\";\r\n    this.toolsWrap.style.maxWidth = compact ? \"\" : this.collapsed ? \"0px\" : `${contentSize}px`;\r\n    this.toolsWrap.style.opacity = this.collapsed ? \"0\" : \"1\";\r\n    this.toolsWrap.style.pointerEvents = this.collapsed ? \"none\" : \"auto\";\r\n  }\r\n\r\n  private handleViewportChange(): void {\r\n    this.syncCollapsedLayout();\r\n    for (const entry of this.entries.values()) {\r\n      if (!entry.subBadges) continue;\r\n      if (entry.subBadges.getAttribute(\"data-open\") !== \"true\") continue;\r\n      this.positionSubBadges(entry.slot, entry.subBadges);\r\n    }\r\n  }\r\n\r\n  private renderButton(\r\n    button: HTMLButtonElement,\r\n    label: string,\r\n    hotkey: StringDevtoolDefinition[\"hotkey\"],\r\n    state: StringDevtoolState,\r\n  ): void {\r\n    const hotkeyLabel = formatHotkey(hotkey);\r\n    const labelWithHotkey = hotkeyLabel ? `${label} (${hotkeyLabel})` : label;\r\n    button.setAttribute(\"data-active\", state.active ? \"true\" : \"false\");\r\n    button.setAttribute(\"aria-label\", `${labelWithHotkey}: ${state.active ? \"On\" : \"Off\"}`);\r\n    button.title = `${labelWithHotkey}: ${state.active ? \"On\" : \"Off\"}`;\r\n  }\r\n\r\n  private syncSubBadgeState(\r\n    slot: HTMLDivElement,\r\n    group: HTMLDivElement | null,\r\n    active: boolean,\r\n  ): void {\r\n    const value = active ? \"true\" : \"false\";\r\n    slot.setAttribute(\"data-active\", value);\r\n    if (!group) return;\r\n\r\n    group.setAttribute(\"data-parent-active\", value);\r\n    for (const badge of group.querySelectorAll<HTMLElement>(\"[data-stdg-dock-sub-badge]\")) {\r\n      badge.setAttribute(\"data-parent-active\", value);\r\n      badge.setAttribute(\"aria-disabled\", active ? \"false\" : \"true\");\r\n    }\r\n  }\r\n\r\n  private applyStoredActiveState(definition: StringDevtoolDefinition): void {\r\n    const saved = this.preferences.active[definition.id];\r\n    if (typeof saved !== \"boolean\") {\r\n      return;\r\n    }\r\n\r\n    // When dock is collapsed, never activate modules — they'll be restored on expand.\r\n    const targetActive = this.collapsed ? false : saved;\r\n    if (targetActive === definition.getState().active) {\r\n      return;\r\n    }\r\n\r\n    definition.setActive(targetActive);\r\n  }\r\n\r\n  private persistActiveState(id: string, active: boolean): void {\r\n    if (this.suppressPersist) return;\r\n    // When collapsed, the modules are force-deactivated — don't overwrite the\r\n    // stored \"true\" entries that need to be restored when expanding.\r\n    if (this.collapsed) return;\r\n    this.preferences.active[id] = active;\r\n    this.savePreferences();\r\n  }\r\n\r\n  private loadPreferences(): DockPreferences {\r\n    try {\r\n      const raw = localStorage.getItem(this.dockStorageKey);\r\n      if (!raw) {\r\n        return { collapsed: false, active: {} };\r\n      }\r\n\r\n      const parsed = JSON.parse(raw) as Partial<DockPreferences>;\r\n      return {\r\n        collapsed: parsed.collapsed === true,\r\n        active: parsed.active && typeof parsed.active === \"object\" ? parsed.active : {},\r\n      };\r\n    } catch {\r\n      return { collapsed: false, active: {} };\r\n    }\r\n  }\r\n\r\n  private savePreferences(): void {\r\n    try {\r\n      localStorage.setItem(this.dockStorageKey, JSON.stringify(this.preferences));\r\n    } catch {\r\n      // localStorage may be unavailable\r\n    }\r\n  }\r\n\r\n  private get dockStorageKey(): string {\r\n    return scopeStringDevStorageKey(DEVTOOLS_DOCK_STORAGE_KEY);\r\n  }\r\n}\r\n","import { StringDevtoolsDock } from \"../../modules/dev-tools/core/StringDevtoolsDock\";\nimport { StringDevtoolDefinition } from \"../../models/devtools/StringDevtool\";\n\nexport class DevtoolsManager {\n  private definitions: Map<string, StringDevtoolDefinition> = new Map();\n  private dock: StringDevtoolsDock | null = null;\n\n  register(definition: StringDevtoolDefinition | null): void {\n    if (!definition || this.definitions.has(definition.id)) {\n      return;\n    }\n\n    this.definitions.set(definition.id, definition);\n    if (!this.dock) {\n      this.dock = new StringDevtoolsDock();\n    }\n    this.dock.add(definition);\n  }\n\n  setFPS(fps: number): void {\n    this.dock?.setFPS(fps);\n  }\n\n  destroy(): void {\n    this.definitions.clear();\n    this.dock?.destroy();\n    this.dock = null;\n  }\n}\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringData } from \"../../core/StringData\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\n\r\nexport class StringScroller extends StringModule {\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"scroller\";\r\n  }\r\n\r\n  onObjectConnected(object: StringObject): void {\r\n    let isScrollInited = object.getProperty(\"scroller-inited\");\r\n    if (isScrollInited == null || isScrollInited == \"\") {\r\n      object.setProperty(\"scroller-inited\", \"inited\");\r\n      let wheelEvent = (event: Event) => {\r\n        this.events.emit(`wheel`, event);\r\n      };\r\n      object.setProperty(\"scroller-wheel-event\", wheelEvent);\r\n      object.htmlElement.addEventListener(\"wheel\", wheelEvent);\r\n    }\r\n  }\r\n  onObjectDisconnected(object: StringObject): void {\r\n    object.setProperty(\"scroller-inited\", \"\");\r\n    object.htmlElement.removeEventListener(\"wheel\", object.getProperty(\"scroller-wheel-event\"));\r\n  }\r\n}\r\n","\r\nimport { StringContext } from \"../../core/StringContext\";\r\nimport { StringData } from \"../../core/StringData\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\n\r\n/**\r\n * Interface representing the internal state of a scroll container.\r\n * Tracks current position, target position, and animation parameters.\r\n */\r\ninterface ScrollContainerState {\r\n  current: number;\r\n  target: number;\r\n  maxScroll: number;\r\n  velocity: number;\r\n  lerp: number;\r\n  isDragging: boolean;\r\n  isActive: boolean;\r\n}\r\n\r\n/**\r\n * Module that provides smooth scrolling behavior for isolated containers.\r\n * Allows nested elements to have independent smooth scroll physics similar to the main window.\r\n * \r\n * Usage:\r\n * Add `string=\"scroll-container\"` to any block element.\r\n * Optional: `string-lerp=\"0.1\"` to controls the smoothing factor.\r\n */\r\nexport class StringScrollContainer extends StringModule {\r\n  /**\r\n   * WeakMap storing the state for each managed HTMLElement.\r\n   */\r\n  private states = new WeakMap<HTMLElement, ScrollContainerState>();\r\n\r\n  /**\r\n   * Initializes the StringScrollContainer module.\r\n   * Registers the `lerp` attribute configuration.\r\n   * \r\n   * @param context The shared StringTune context.\r\n   */\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"scroll-container\";\r\n    this.attributesToMap.push({ key: \"lerp\", type: \"number\", fallback: 0.1 });\r\n  }\r\n\r\n  /**\r\n   * Called when a new object with `string=\"scroll-container\"` is initialized.\r\n   * Sets up initial state, event listeners, and default styles.\r\n   * \r\n   * @param object The StringObject instance being connected.\r\n   */\r\n  override onObjectConnected(object: StringObject): void {\r\n    super.onObjectConnected(object);\r\n    const el = object.htmlElement;\r\n\r\n    if (getComputedStyle(el).overflowY === 'visible') {\r\n      el.style.overflowY = 'auto';\r\n    }\r\n\r\n    const state: ScrollContainerState = {\r\n      current: el.scrollTop,\r\n      target: el.scrollTop,\r\n      maxScroll: el.scrollHeight - el.clientHeight,\r\n      velocity: 0,\r\n      lerp: object.getProperty<number>(\"lerp\") || 0.1,\r\n      isDragging: false,\r\n      isActive: false\r\n    };\r\n\r\n    this.states.set(el, state);\r\n\r\n    el.addEventListener(\"wheel\", (e) => this.handleWheel(e, el, state), { passive: false });\r\n    el.addEventListener(\"scroll\", (e) => this.onNativeScroll(e, el, state), { passive: true });\r\n\r\n    this.measure(el, state);\r\n  }\r\n\r\n  /**\r\n   * Called when an object is removed from the DOM or disconnected.\r\n   * Cleans up the state associated with the element.\r\n   * \r\n   * @param object The StringObject instance being disconnected.\r\n   */\r\n  override onObjectDisconnected(object: StringObject): void {\r\n    this.states.delete(object.htmlElement);\r\n  }\r\n\r\n  /**\r\n   * Main animation loop for the module.\r\n   * Updates the scroll position of active containers based on their target state.\r\n   * \r\n   * @param data Global frame data including time deltas.\r\n   */\r\n  override onFrame(data: StringData): void {\r\n    for (const object of this.objectsOnPage) {\r\n      const el = object.htmlElement;\r\n      const state = this.states.get(el);\r\n      if (!state) continue;\r\n\r\n      if (state.isActive && !state.isDragging) {\r\n        this.updateScroll(el, state);\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Called when the window or layout is resized.\r\n   * Recalculates scroll boundaries for all managed containers.\r\n   */\r\n  override onResize(): void {\r\n    for (const object of this.objectsOnPage) {\r\n      const el = object.htmlElement;\r\n      const state = this.states.get(el);\r\n      if (state) {\r\n        this.measure(el, state);\r\n      }\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Recalculates the maximum scrollable distance for a container.\r\n   * \r\n   * @param el The scroll container element.\r\n   * @param state The state object associated with the element.\r\n   */\r\n  private measure(el: HTMLElement, state: ScrollContainerState) {\r\n    state.maxScroll = el.scrollHeight - el.clientHeight;\r\n  }\r\n\r\n  /**\r\n   * Handles the mouse wheel event to apply custom scroll physics.\r\n   * Intercepts the event to prevent native scrolling and updates the target position.\r\n   * Allows event propagation if scrolling past the boundaries (scroll chaining).\r\n   * \r\n   * @param e The WheelEvent triggered by the user.\r\n   * @param el The target scroll container element.\r\n   * @param state The state object associated with the element.\r\n   */\r\n  private handleWheel(e: WheelEvent, el: HTMLElement, state: ScrollContainerState) {\r\n    const delta = e.deltaY;\r\n\r\n    const isScrollingUp = delta < 0;\r\n    const isScrollingDown = delta > 0;\r\n\r\n    const atTop = state.target <= 0.1;\r\n    const atBottom = state.target >= state.maxScroll - 0.1;\r\n\r\n    if ((isScrollingUp && atTop) || (isScrollingDown && atBottom)) {\r\n      return;\r\n    }\r\n\r\n    e.preventDefault();\r\n    e.stopPropagation();\r\n\r\n    state.target += delta;\r\n\r\n    state.target = Math.max(0, Math.min(state.target, state.maxScroll));\r\n\r\n    state.isActive = true;\r\n    state.isDragging = false;\r\n  }\r\n\r\n  /**\r\n   * Placeholder for global wheel handler if needed by generic StringModule interface.\r\n   * Specific handling is done via local event listeners in `handleWheel`.\r\n   * \r\n   * @param e Global WheelEvent.\r\n   */\r\n  override onWheel(e: WheelEvent): void {\r\n  }\r\n\r\n  /**\r\n   * Handles native scroll events (dragbars, keyboard, touch).\r\n   * Syncs the internal state with the native scroll position if the custom animation is not active.\r\n   * \r\n   * @param e The Scroll event.\r\n   * @param el The target scroll container element.\r\n   * @param state The state object associated with the element.\r\n   */\r\n  private onNativeScroll(e: Event, el: HTMLElement, state: ScrollContainerState) {\r\n    if (!state.isActive) {\r\n      state.current = el.scrollTop;\r\n      state.target = el.scrollTop;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Updates the element's scrollTop property by interpolating towards the target.\r\n   * Stops the animation if the difference is negligible.\r\n   * \r\n   * @param el The scroll container element.\r\n   * @param state The state object associated with the element.\r\n   */\r\n  private updateScroll(el: HTMLElement, state: ScrollContainerState) {\r\n    const diff = state.target - state.current;\r\n\r\n    if (Math.abs(diff) < 0.1) {\r\n      state.current = state.target;\r\n      state.isActive = false;\r\n    } else {\r\n      state.current += diff * state.lerp;\r\n    }\r\n\r\n    el.scrollTop = state.current;\r\n  }\r\n}\r\n","export function parsePartOf(value: string): { id: string; start: number; end: number } | null {\r\n  const match = value.match(/([^[]+)\\[([\\d.]+)-([\\d.]+)\\]/);\r\n  if (!match) return null;\r\n  return {\r\n    id: match[1],\r\n    start: parseFloat(match[2]),\r\n    end: parseFloat(match[3]),\r\n  };\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\r\nimport { StringModule } from \"../../core/StringModule\";\r\nimport { StringObject } from \"../../objects/StringObject\";\r\nimport { parsePartOf } from \"../../utils/ParsePartOf\";\r\n\r\nfunction remap(value: number, from1: number, to1: number, from2: number, to2: number): number {\r\n  return from2 + ((to2 - from2) * (value - from1)) / (to1 - from1);\r\n}\r\n\r\nexport class StringProgressPart extends StringModule {\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.htmlKey = \"progress-part\";\r\n    this.attributesToMap = [\r\n      ...this.attributesToMap,\r\n      { key: \"part-of\", type: \"string\", fallback: \"\" },\r\n    ];\r\n  }\r\n\r\n  onObjectConnected(object: StringObject): void {\r\n    let partOfId = object.getProperty(\"part-of\");\r\n    let partOfData = parsePartOf(partOfId as string);\r\n    if (partOfData) {\r\n      object.setProperty(\"part-of-id\", partOfData.id);\r\n      object.setProperty(\"start\", partOfData.start);\r\n      object.setProperty(\"end\", partOfData.end);\r\n      let progressEvent = (progress: number) => {\r\n        if (partOfData) {\r\n          const sliceProgress = remap(progress, partOfData?.start, partOfData?.end, 0, 1);\n          const clampedProgress = Math.max(0, Math.min(1, sliceProgress));\n          object.htmlElement.style.setProperty(\"--progress-slice\", clampedProgress.toString());\n          this.events.emit(this.getObjectEventName(object, \"object:progress-slice\"), clampedProgress);\n        }\n      };\n      object.setProperty(\"progress-event\", progressEvent);\r\n      this.events.on(`object:progress:${partOfData.id}`, progressEvent);\r\n    }\r\n  }\r\n\r\n  onObjectDisconnected(object: StringObject): void {\r\n    let partOfId = object.getProperty(\"part-of-id\");\r\n    if (partOfId) {\r\n      this.events.off(`object:progress:${partOfId}`, object.getProperty<any>(\"progress-event\"));\r\n    }\r\n  }\r\n}\r\n","import { StringContext } from \"../../core/StringContext\";\nimport { StringModule } from \"../../core/StringModule\";\nimport { StringObject } from \"../../objects/StringObject\";\nimport { styleTxn } from \"../../utils/style-txn\";\n\nconst getRandomInRange = (min: number, max: number): number => {\n  const lo = Math.min(min, max);\n  const hi = Math.max(min, max);\n  return lo + Math.random() * (hi - lo);\n};\n\nconst getRandomIntInRange = (min: number, max: number): number => {\n  const lo = Math.ceil(Math.min(min, max));\n  const hi = Math.floor(Math.max(min, max));\n  if (hi < lo) return lo;\n  return Math.floor(Math.random() * (hi - lo + 1)) + lo;\n};\n\nconst normalizeRange = (value: unknown): [number, number] => {\n  if (Array.isArray(value) && value.length >= 2) {\n    const a = Number(value[0]);\n    const b = Number(value[1]);\n    if (Number.isFinite(a) && Number.isFinite(b)) return [a, b];\n  }\n  if (typeof value === \"number\" && Number.isFinite(value)) {\n    return [0, value];\n  }\n  return [0, 1];\n};\n\nexport class StringRandom extends StringModule {\n  constructor(context: StringContext) {\n    super(context);\n    this.htmlKey = \"random\";\n    this.attributesToMap.push({\n      key: \"random-number\",\n      type: \"json\",\n      fallback: \"[0,1]\",\n    });\n    this.attributesToMap.push({\n      key: \"random-type\",\n      type: \"string\",\n      fallback: \"int\",\n    });\n  }\n\n  override onObjectConnected(object: StringObject): void {\n    const el = object.htmlElement as HTMLElement;\n    const range = normalizeRange(object.getProperty(\"random-number\"));\n    const type = String(object.getProperty(\"random-type\") ?? \"float\").toLowerCase();\n    const value =\n      type === \"int\"\n        ? getRandomIntInRange(range[0], range[1])\n        : getRandomInRange(range[0], range[1]);\n\n    styleTxn.run(() => {\n      styleTxn.setVars(el, { \"--random\": value });\n    });\n  }\n}\n","export class StringDevViewportLayer {\r\n  private screenRoot: HTMLDivElement | null = null;\r\n  private world: HTMLDivElement | null = null;\r\n  private screen: HTMLDivElement | null = null;\r\n  private worldHost: HTMLElement | null = null;\r\n  private hostPositionWasPatched = false;\r\n  private hostPositionInlineValue: string | null = null;\r\n\r\n  constructor(\r\n    private readonly id: string,\r\n    private readonly zIndex: number,\r\n  ) {}\r\n\r\n  public ensure(host?: HTMLElement | null): HTMLDivElement {\r\n    if (this.screenRoot?.isConnected) {\r\n      if (host) {\r\n        this.attachWorldToHost(host);\r\n      }\r\n      return this.screenRoot;\r\n    }\r\n\r\n    const existing = document.querySelector<HTMLDivElement>(\r\n      `[data-string-dev-viewport-layer=\"${this.id}\"]`,\r\n    );\r\n\r\n    if (existing) {\r\n      this.screenRoot = existing;\r\n      this.screen = existing.querySelector<HTMLDivElement>(\r\n        `[data-string-dev-viewport-screen=\"${this.id}\"]`,\r\n      );\r\n      if (host) {\r\n        this.attachWorldToHost(host);\r\n      }\r\n      return existing;\r\n    }\r\n\r\n    const root = document.createElement(\"div\");\r\n    root.setAttribute(\"data-string-dev-viewport-layer\", this.id);\r\n    root.setAttribute(\"data-string-devtools-theme\", \"\");\r\n    root.style.position = \"fixed\";\r\n    root.style.inset = \"0\";\r\n    root.style.zIndex = String(this.zIndex);\r\n    root.style.pointerEvents = \"none\";\r\n    root.style.overflow = \"hidden\";\r\n\r\n    const screen = document.createElement(\"div\");\r\n    screen.setAttribute(\"data-string-dev-viewport-screen\", this.id);\r\n    screen.style.position = \"absolute\";\r\n    screen.style.inset = \"0\";\r\n    screen.style.pointerEvents = \"none\";\r\n    screen.style.overflow = \"hidden\";\r\n\r\n    root.appendChild(screen);\r\n\r\n    (document.body ?? document.documentElement).appendChild(root);\r\n    this.screenRoot = root;\r\n    this.screen = screen;\r\n    this.attachWorldToHost(host ?? document.body ?? document.documentElement);\r\n    return root;\r\n  }\r\n\r\n  public getElement(): HTMLDivElement | null {\r\n    return this.screenRoot?.isConnected ? this.screenRoot : null;\r\n  }\r\n\r\n  public getWorldElement(host?: HTMLElement | null): HTMLDivElement {\r\n    this.ensure(host);\r\n    return this.world!;\r\n  }\r\n\r\n  public getScreenElement(): HTMLDivElement {\r\n    this.ensure();\r\n    return this.screen!;\r\n  }\r\n\r\n  public destroy(): void {\r\n    this.restoreHostPosition();\r\n    this.screenRoot?.remove();\r\n    this.screenRoot = null;\r\n    this.world?.remove();\r\n    this.world = null;\r\n    this.screen = null;\r\n    this.worldHost = null;\r\n  }\r\n\r\n  private attachWorldToHost(host: HTMLElement): void {\r\n    if (this.worldHost === host && this.world?.isConnected) {\r\n      return;\r\n    }\r\n\r\n    this.restoreHostPosition();\r\n    this.worldHost = host;\r\n\r\n    if (!this.world) {\r\n      const world = document.createElement(\"div\");\r\n      world.setAttribute(\"data-string-dev-viewport-world\", this.id);\r\n      world.setAttribute(\"data-string-devtools-theme\", \"\");\r\n      world.style.position = \"absolute\";\r\n      world.style.top = \"0\";\r\n      world.style.left = \"0\";\r\n      world.style.width = \"1px\";\r\n      world.style.height = \"1px\";\r\n      world.style.pointerEvents = \"none\";\r\n      world.style.overflow = \"visible\";\r\n      world.style.zIndex = String(this.zIndex);\r\n      this.world = world;\r\n    }\r\n\r\n    const shouldPatchHostPosition =\r\n      host !== document.body &&\r\n      host !== document.documentElement &&\r\n      window.getComputedStyle(host).position === \"static\";\r\n\r\n    if (shouldPatchHostPosition) {\r\n      this.hostPositionWasPatched = true;\r\n      this.hostPositionInlineValue = host.style.position || null;\r\n      host.style.position = \"relative\";\r\n    }\r\n\r\n    host.appendChild(this.world);\r\n  }\r\n\r\n  private restoreHostPosition(): void {\r\n    if (this.world) {\r\n      this.world.remove();\r\n    }\r\n\r\n    if (this.worldHost && this.hostPositionWasPatched) {\r\n      if (this.hostPositionInlineValue == null || this.hostPositionInlineValue === \"\") {\r\n        this.worldHost.style.removeProperty(\"position\");\r\n      } else {\r\n        this.worldHost.style.position = this.hostPositionInlineValue;\r\n      }\r\n    }\r\n\r\n    this.hostPositionWasPatched = false;\r\n    this.hostPositionInlineValue = null;\r\n  }\r\n}\r\n","import { StringDevViewportLayer } from \"./StringDevViewportLayer\";\n\ninterface SharedViewportLayerEntry {\n  layer: StringDevViewportLayer;\n  refs: number;\n  zIndex: number;\n}\n\nexport class StringDevOverlayRegistry {\n  private static instance: StringDevOverlayRegistry | null = null;\n  private readonly layers = new Map<string, SharedViewportLayerEntry>();\n\n  public static getInstance(): StringDevOverlayRegistry {\n    if (!this.instance) {\n      this.instance = new StringDevOverlayRegistry();\n    }\n    return this.instance;\n  }\n\n  public acquire(id: string, zIndex: number): StringDevViewportLayer {\n    const existing = this.layers.get(id);\n    if (existing) {\n      if (existing.zIndex !== zIndex) {\n        throw new Error(\n          `Shared devtools layer \"${id}\" already exists with z-index ${existing.zIndex}, requested ${zIndex}.`,\n        );\n      }\n      existing.refs += 1;\n      return existing.layer;\n    }\n\n    const layer = new StringDevViewportLayer(id, zIndex);\n    this.layers.set(id, { layer, refs: 1, zIndex });\n    return layer;\n  }\n\n  public release(id: string): void {\n    const existing = this.layers.get(id);\n    if (!existing) {\n      return;\n    }\n\n    existing.refs -= 1;\n    if (existing.refs > 0) {\n      return;\n    }\n\n    existing.layer.destroy();\n    this.layers.delete(id);\n  }\n}\n","import { StringContext } from \"../../../core/StringContext\";\r\nimport { StringModule } from \"../../../core/StringModule\";\r\nimport { StringObject } from \"../../../objects/StringObject\";\r\nimport {\r\n  StringDevtoolDefinition,\r\n  StringDevtoolHotkey,\r\n  StringDevtoolProvider,\r\n  StringDevtoolState,\r\n} from \"../../../models/devtools/StringDevtool\";\r\nimport { resolveDevtoolsIcon } from \"./StringDevIconRegistry\";\r\nimport { StringDevOverlayRegistry } from \"./StringDevOverlayRegistry\";\r\nimport { ensureStringDevtoolsSharedStyles } from \"./StringDevStyleSystem\";\r\nimport { StringDevViewportLayer } from \"./StringDevViewportLayer\";\r\n\r\nexport interface StringDevModuleDefinitionConfig {\r\n  id: string;\r\n  label: string;\r\n  icon: string;\r\n  order?: number;\r\n  group?: number;\r\n  hotkey?: StringDevtoolHotkey;\r\n}\r\n\r\nexport interface StringDevConnectsConfig {\r\n  /** If true, connects to every StringObject (overlay default). If false, only explicit matches below + dev-inspect fallback. */\r\n  global?: boolean;\r\n  /** Connect to objects whose string=\"…\" token list includes any of these keys. */\r\n  keys?: string[];\r\n  /** Connect to objects whose DOM element has any of these attributes present. */\r\n  attributes?: string[];\r\n}\r\n\r\nexport interface StringDevOverlayConfig {\r\n  /** Unique layer name, e.g. \"devtools-progress\" */\r\n  layerName: string;\r\n  /** Z-index for the viewport layer */\r\n  zIndex: number;\r\n  /** Data-attribute added to the layer root, e.g. \"data-string-progress-layer\" */\r\n  layerAttribute?: string;\r\n  /** Overlay ID used for the anchor/collision system. Omit if not needed. */\r\n  overlayId?: string;\r\n  /** Whether the overlay starts enabled before dock preferences apply. Default: false */\r\n  defaultEnabled?: boolean;\r\n  /** For badge overlay modules: data-attribute placed on each badge element */\r\n  badgeAttribute?: string;\r\n}\r\n\r\nexport interface StringDevModuleConfig extends StringDevModuleDefinitionConfig {\r\n  /** Declare CSS styles to inject once. Can be a string or a lazy getter. */\r\n  styles?: string | (() => string);\r\n  /** Overlay layer configuration. Declare for any module that uses a viewport layer. */\r\n  overlay?: StringDevOverlayConfig;\r\n  /** Declare which StringObjects this module connects to. Replaces htmlKey assignment in constructor. */\r\n  connects?: StringDevConnectsConfig;\r\n}\r\n\r\nexport class StringDevModule extends StringModule implements StringDevtoolProvider {\n  /** Declare module metadata statically. Subclasses override this. */\r\n  static devtool: StringDevModuleConfig | null = null;\r\n\r\n  protected readonly overlayRegistry = StringDevOverlayRegistry.getInstance();\r\n\r\n  private readonly acquiredViewportLayers = new Map<string, StringDevViewportLayer>();\r\n  private readonly devtoolListeners = new Set<(state: StringDevtoolState) => void>();\r\n  private hotkeyHandler: ((event: KeyboardEvent) => void) | null = null;\r\n  protected devtoolConfig: StringDevModuleDefinitionConfig | null = null;\r\n\r\n  constructor(context: StringContext) {\n    super(context);\r\n    this._type = 2;\r\n    ensureStringDevtoolsSharedStyles();\r\n\r\n    const staticConfig = (this.constructor as typeof StringDevModule).devtool;\r\n    if (staticConfig) {\r\n      this.configureDevtool(staticConfig);\r\n      this.bindDevtoolHotkey(staticConfig.hotkey);\r\n    }\r\n\r\n    const rawStaticStyles = staticConfig?.styles;\r\n    const styles =\r\n      (typeof rawStaticStyles === \"function\" ? rawStaticStyles() : rawStaticStyles) ??\r\n      this.getStyles();\r\n    if (styles) {\r\n      this.ensureStyle(`${this.getStyleScopeId(styles)}-styles`, styles);\r\n    }\r\n  }\n\n  protected override get respectSelfDisable(): boolean {\n    return false;\n  }\n\r\n  protected get connectsConfig(): StringDevConnectsConfig | undefined {\r\n    return (this.constructor as typeof StringDevModule).devtool?.connects;\r\n  }\r\n\r\n  canConnect(object: StringObject): boolean {\r\n    const connects = this.connectsConfig;\r\n    if (!connects) {\r\n      // No connects declared — fall back to base htmlKey matching.\r\n      return super.canConnect(object);\r\n    }\r\n\r\n    if (connects.global === true) {\r\n      return true;\r\n    }\r\n\r\n    // global: false (or omitted) — match explicit keys/attributes, plus dev-inspect fallback.\r\n    if (object.keys.includes(\"dev-inspect\")) {\r\n      return true;\r\n    }\r\n    if (connects.keys?.some((k) => object.keys.includes(k))) {\r\n      return true;\r\n    }\r\n    if (connects.attributes?.some((attr) => object.htmlElement.hasAttribute(attr))) {\r\n      return true;\r\n    }\r\n\r\n    return false;\r\n  }\r\n\r\n  protected getStyleScopeId(stylesText: string): string {\r\n    const firstKey =\r\n      this.htmlKey || (this.constructor as typeof StringDevModule).devtool?.connects?.keys?.[0];\r\n    if (firstKey) {\r\n      return firstKey;\r\n    }\r\n\r\n    let hash = 0;\r\n    for (let i = 0; i < stylesText.length; i += 1) {\r\n      hash = (hash * 31 + stylesText.charCodeAt(i)) >>> 0;\r\n    }\r\n\r\n    return `string-dev-${hash.toString(16)}`;\r\n  }\r\n\r\n  protected getStyles(): string | null {\r\n    return null;\r\n  }\r\n\r\n  public getDevtoolDefinition(): StringDevtoolDefinition | null {\r\n    if (!this.devtoolConfig) {\r\n      return null;\r\n    }\r\n\r\n    const config = this.devtoolConfig;\r\n    const subBadges = this.getDevtoolSubBadges();\r\n    return {\r\n      id: config.id,\r\n      label: config.label,\r\n      icon: config.icon,\r\n      order: config.order,\r\n      group: config.group,\r\n      hotkey: config.hotkey,\r\n      subBadges: subBadges.length > 0 ? subBadges : undefined,\r\n      getState: () => ({ active: this.getDevtoolActiveState() }),\r\n      setActive: (active) => {\r\n        this.setDevtoolActiveState(active);\r\n      },\r\n      subscribe: (listener) => {\r\n        this.devtoolListeners.add(listener);\r\n        listener({ active: this.getDevtoolActiveState() });\r\n        return () => {\r\n          this.devtoolListeners.delete(listener);\r\n        };\r\n      },\r\n    };\r\n  }\r\n\r\n  protected getDevtoolSubBadges(): import(\"../../../models/devtools/StringDevtool\").StringDevtoolSubBadge[] {\r\n    return [];\r\n  }\r\n\r\n  protected configureDevtool(config: StringDevModuleDefinitionConfig): void {\r\n    this.devtoolConfig = config;\r\n  }\r\n\r\n  protected bindDevtoolHotkey(hotkey?: StringDevtoolHotkey): void {\r\n    if (typeof window === \"undefined\" || !hotkey) {\r\n      return;\r\n    }\r\n\r\n    this.hotkeyHandler = (event: KeyboardEvent) => {\r\n      const target = event.target as HTMLElement | null;\r\n      if (\r\n        target &&\r\n        (target instanceof HTMLInputElement ||\r\n          target instanceof HTMLTextAreaElement ||\r\n          target instanceof HTMLSelectElement ||\r\n          target.isContentEditable)\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      if (\r\n        event.key.toLowerCase() !== hotkey.key.toLowerCase() ||\r\n        event.shiftKey !== (hotkey.shiftKey ?? false) ||\r\n        event.ctrlKey !== (hotkey.ctrlKey ?? false) ||\r\n        event.altKey !== (hotkey.altKey ?? false) ||\r\n        event.metaKey !== (hotkey.metaKey ?? false)\r\n      ) {\r\n        return;\r\n      }\r\n\r\n      event.preventDefault();\r\n      this.setDevtoolActiveState(!this.getDevtoolActiveState());\r\n    };\r\n\r\n    window.addEventListener(\"keydown\", this.hotkeyHandler);\r\n  }\r\n\r\n  protected emitDevtoolState(active: boolean = this.getDevtoolActiveState()): void {\r\n    const state = { active };\r\n    for (const listener of this.devtoolListeners) {\r\n      listener(state);\r\n    }\r\n  }\r\n\r\n  protected acquireViewportLayer(id: string, zIndex: number): StringDevViewportLayer {\r\n    const existing = this.acquiredViewportLayers.get(id);\r\n    if (existing) {\r\n      return existing;\r\n    }\r\n\r\n    const layer = this.overlayRegistry.acquire(id, zIndex);\r\n    this.acquiredViewportLayers.set(id, layer);\r\n    return layer;\r\n  }\r\n\r\n  protected releaseViewportLayer(id: string): void {\r\n    if (!this.acquiredViewportLayers.has(id)) {\r\n      return;\r\n    }\r\n\r\n    this.overlayRegistry.release(id);\r\n    this.acquiredViewportLayers.delete(id);\r\n  }\r\n\r\n  protected ensureStyle(styleId: string, cssText: string): HTMLStyleElement {\r\n    const existing = document.getElementById(styleId);\r\n    if (existing instanceof HTMLStyleElement) {\r\n      return existing;\r\n    }\r\n\r\n    const style = document.createElement(\"style\");\r\n    style.id = styleId;\r\n    style.textContent = cssText;\r\n    document.head.appendChild(style);\r\n    return style;\r\n  }\r\n\r\n  protected getWorldHost(): HTMLElement {\r\n    return this.data.scroll.container ?? document.body ?? document.documentElement;\r\n  }\r\n\r\n  protected getDevtoolActiveState(): boolean {\r\n    return false;\r\n  }\r\n\r\n  protected setDevtoolActiveState(_active: boolean): void {}\r\n\r\n  destroy(): void {\r\n    if (this.hotkeyHandler) {\r\n      window.removeEventListener(\"keydown\", this.hotkeyHandler);\r\n      this.hotkeyHandler = null;\r\n    }\r\n    this.devtoolListeners.clear();\r\n    for (const id of this.acquiredViewportLayers.keys()) {\r\n      this.overlayRegistry.release(id);\r\n    }\r\n    this.acquiredViewportLayers.clear();\r\n    super.destroy();\r\n  }\r\n}\r\n","/**\n * Represents a single active grid overlay on an element.\n * Multiple instances can coexist on the same element.\n */\nexport interface GridInstance {\n  /** Unique identifier for this grid instance */\n  readonly id: string;\n\n  /** Adapter type key (e.g. \"columns\", \"phi\", \"rule-of-thirds\") */\n  readonly type: string;\n\n  /** Whether this grid is currently rendered */\n  visible: boolean;\n\n  /** Custom display name; falls back to adapter.label when absent */\n  name?: string;\n\n  /** Adapter-specific settings, keyed by UIFieldDescriptor.key */\n  settings: Record<string, any>;\n}\n\n/**\n * Breakpoint label — S is always smallest, XL is always largest.\n * The number of active breakpoints determines which labels are used:\n *   2 layouts → S, M\n *   3 layouts → S, M, L\n *   4 layouts → S, M, L, XL\n */\nexport type GridLayoutLabel = \"S\" | \"M\" | \"L\" | \"XL\";\n\nexport const GRID_LAYOUT_LABELS: GridLayoutLabel[] = [\"S\", \"M\", \"L\", \"XL\"];\n\nexport const MIN_LAYOUTS = 2;\nexport const MAX_LAYOUTS = 4;\n\n/** Default minWidth values for each breakpoint slot (index 0 = largest) */\nconst DEFAULT_MIN_WIDTHS = [1280, 1024, 768, 0];\n\n/**\n * Returns the label for a layout given its index in a sorted (desc) array.\n * index 0 = largest → last label; index n-1 = smallest → \"S\"\n */\nexport function getLayoutLabel(index: number, total: number): GridLayoutLabel {\n  const labelIndex = total - 1 - index;\n  return GRID_LAYOUT_LABELS[labelIndex] ?? \"S\";\n}\n\n/**\n * A named responsive layout containing a set of grid instances.\n * Each element can have multiple layouts which resolve automatically by width.\n */\nexport interface GridLayout {\n  /** Unique identifier for this layout */\n  readonly id: string;\n\n  /** Breakpoint label (S / M / L / XL) */\n  label: GridLayoutLabel;\n\n  /** Minimum viewport width required for this layout to become active */\n  minWidth: number;\n\n  /** Grid instances active in this layout */\n  instances: GridInstance[];\n}\n\n/**\n * Serializable snapshot of all layouts on one element.\n * Used for localStorage persistence.\n */\nexport interface GridElementState {\n  readonly elementId: string;\n  layouts: GridLayout[];\n  selectedLayoutId: string;\n  panelTitle?: string;\n}\n\nlet nextId = 0;\n\nexport function createGridInstanceId(): string {\n  return `grid-${Date.now()}-${nextId++}`;\n}\n\nexport function createGridLayoutId(): string {\n  return `layout-${Date.now()}-${nextId++}`;\n}\n\n/**\n * Creates a fresh set of layouts with the given count (2–4).\n * Layouts are sorted descending by minWidth (largest first).\n */\nexport function createDefaultLayouts(count: number = MIN_LAYOUTS): GridLayout[] {\n  const safeCount = Math.max(MIN_LAYOUTS, Math.min(MAX_LAYOUTS, count));\n  const layouts: GridLayout[] = [];\n\n  for (let i = 0; i < safeCount; i++) {\n    const label = getLayoutLabel(i, safeCount);\n    const minWidth = i === safeCount - 1 ? 0 : (DEFAULT_MIN_WIDTHS[i] ?? 0);\n    layouts.push({\n      id: createGridLayoutId(),\n      label,\n      minWidth,\n      instances: [],\n    });\n  }\n\n  return layouts;\n}\n\nexport function normalizeGridLayoutMinWidth(value: number): number {\n  if (!Number.isFinite(value)) return 0;\n  return Math.max(0, Math.round(value));\n}\n\n/**\n * Re-assigns labels after the layout count changes.\n * Layouts must already be sorted descending by minWidth.\n */\nexport function reassignLabels(layouts: GridLayout[]): void {\n  const total = layouts.length;\n  for (let i = 0; i < total; i++) {\n    layouts[i].label = getLayoutLabel(i, total);\n  }\n}\n","import { GridAdapter } from \"./adapters/GridAdapter\";\nimport {\n  GridInstance,\n  GridLayout,\n  GridElementState,\n  createGridInstanceId,\n  createGridLayoutId,\n  createDefaultLayouts,\n  normalizeGridLayoutMinWidth,\n  reassignLabels,\n  MIN_LAYOUTS,\n  MAX_LAYOUTS,\n} from \"./models/GridInstance\";\nimport { scopeStringDevStorageKey } from \"../core/StringDevStorageScope\";\n\nconst STORAGE_PREFIX = \"string-grid:\";\n\nfunction getStorageSlot(elementId: string): string {\n  return scopeStringDevStorageKey(STORAGE_PREFIX + elementId);\n}\n\nfunction countSerializedGrids(data: unknown): number {\n  if (!data || typeof data !== \"object\") {\n    return 0;\n  }\n\n  if (Array.isArray(data)) {\n    return data.length;\n  }\n\n  const object = data as Record<string, unknown>;\n  const layouts = Array.isArray(object[\"layouts\"]) ? object[\"layouts\"] : [];\n  let total = 0;\n\n  for (const layout of layouts) {\n    if (!layout || typeof layout !== \"object\") {\n      continue;\n    }\n\n    const layoutObject = layout as Record<string, unknown>;\n    const instances = Array.isArray(layoutObject[\"instances\"])\n      ? layoutObject[\"instances\"]\n      : Array.isArray(layoutObject[\"grids\"])\n        ? layoutObject[\"grids\"]\n        : [];\n    total += instances.length;\n  }\n\n  return total;\n}\n\n/**\n * Centralized state manager for all grid instances across all elements.\n *\n * Responsibilities:\n * - Adapter registry (register / lookup)\n * - Per-element responsive layout CRUD (2–4 layouts)\n * - Per-layout grid instance CRUD\n * - Persistence to/from localStorage\n */\nexport class GridManager {\n  private adapterRegistry: Map<string, GridAdapter> = new Map();\n  private elementStates: Map<string, GridElementState> = new Map();\n\n  registerAdapter(adapter: GridAdapter): void {\n    this.adapterRegistry.set(adapter.type, adapter);\n  }\n\n  getAdapter(type: string): GridAdapter | undefined {\n    return this.adapterRegistry.get(type);\n  }\n\n  getAdapterRegistry(): Map<string, GridAdapter> {\n    return this.adapterRegistry;\n  }\n\n  getLayouts(elementId: string): GridLayout[] {\n    return this.getOrInitState(elementId).layouts;\n  }\n\n  getLayoutCount(elementId: string): number {\n    return this.getOrInitState(elementId).layouts.length;\n  }\n\n  getSelectedLayoutId(elementId: string): string {\n    return this.getOrInitState(elementId).selectedLayoutId;\n  }\n\n  getPanelTitle(elementId: string): string {\n    return this.getOrInitState(elementId).panelTitle?.trim() || \"Layout\";\n  }\n\n  getSelectedLayoutLabel(elementId: string): string {\n    const state = this.getOrInitState(elementId);\n    return this.findSelectedLayout(state)?.label ?? \"S\";\n  }\n\n  getResolvedLayoutId(elementId: string, viewportWidth: number): string {\n    const state = this.getOrInitState(elementId);\n    return this.findResolvedLayout(state, viewportWidth)?.id ?? state.layouts[state.layouts.length - 1].id;\n  }\n\n  getSelectedInstances(elementId: string): GridInstance[] {\n    const state = this.getOrInitState(elementId);\n    return this.findSelectedLayout(state)?.instances ?? [];\n  }\n\n  getResolvedInstances(elementId: string, viewportWidth: number): GridInstance[] {\n    const state = this.getOrInitState(elementId);\n    return this.findResolvedLayout(state, viewportWidth)?.instances ?? [];\n  }\n\n  /**\n   * Adds a new layout breakpoint. Max 4. New layout is inserted before the\n   * current smallest (S) and becomes the new XL / L / M depending on count.\n   * Returns the new layout, or null if already at max.\n   */\n  addLayout(elementId: string): GridLayout | null {\n    const state = this.getOrInitState(elementId);\n    if (state.layouts.length >= MAX_LAYOUTS) return null;\n\n    // Insert a new largest breakpoint at the front\n    const currentLargest = state.layouts[0];\n    const newMinWidth = currentLargest\n      ? Math.min(1920, currentLargest.minWidth + 256)\n      : 1280;\n\n    const newLayout: GridLayout = {\n      id: createGridLayoutId(),\n      label: \"XL\", // will be reassigned below\n      minWidth: newMinWidth,\n      instances: [],\n    };\n\n    state.layouts.unshift(newLayout);\n    this.sortLayouts(state);\n    reassignLabels(state.layouts);\n    this.ensureMinWidthConstraints(state);\n\n    if (!state.layouts.some((l) => l.id === state.selectedLayoutId)) {\n      state.selectedLayoutId = state.layouts[0].id;\n    }\n\n    this.save(elementId);\n    return newLayout;\n  }\n\n  /**\n   * Removes a layout by id. Min 2 layouts must remain.\n   * Returns false if removal is not allowed.\n   */\n  removeLayout(elementId: string, layoutId: string): boolean {\n    const state = this.getOrInitState(elementId);\n    if (state.layouts.length <= MIN_LAYOUTS) return false;\n\n    const index = state.layouts.findIndex((l) => l.id === layoutId);\n    if (index === -1) return false;\n\n    state.layouts.splice(index, 1);\n    reassignLabels(state.layouts);\n    this.ensureMinWidthConstraints(state);\n\n    if (!state.layouts.some((l) => l.id === state.selectedLayoutId)) {\n      state.selectedLayoutId = state.layouts[state.layouts.length - 1].id;\n    }\n\n    this.save(elementId);\n    return true;\n  }\n\n  selectLayout(elementId: string, layoutId: string, persist: boolean = true): void {\n    const state = this.getOrInitState(elementId);\n    if (!state.layouts.some((layout) => layout.id === layoutId)) return;\n    state.selectedLayoutId = layoutId;\n    if (persist) this.save(elementId);\n  }\n\n  updateLayoutMinWidth(\n    elementId: string,\n    layoutId: string,\n    minWidth: number,\n    persist: boolean = true,\n  ): void {\n    const state = this.getOrInitState(elementId);\n    const layout = state.layouts.find((l) => l.id === layoutId);\n    if (!layout) return;\n\n    layout.minWidth = normalizeGridLayoutMinWidth(minWidth);\n    this.sortLayouts(state);\n    reassignLabels(state.layouts);\n    this.ensureMinWidthConstraints(state);\n    if (persist) this.save(elementId);\n  }\n\n  replaceLayouts(\n    elementId: string,\n    layouts: GridLayout[],\n    selectedLayoutId: string,\n  ): void {\n    const normalized = this.normalizeLayouts(layouts);\n    const state: GridElementState = {\n      elementId,\n      layouts: normalized,\n      selectedLayoutId,\n    };\n    this.ensureValidSelection(state);\n    this.elementStates.set(elementId, state);\n    this.save(elementId);\n  }\n\n  getInstances(elementId: string): GridInstance[] {\n    return this.getSelectedInstances(elementId);\n  }\n\n  addInstance(elementId: string, type: string): GridInstance | null {\n    const adapter = this.adapterRegistry.get(type);\n    if (!adapter) return null;\n\n    const layout = this.findSelectedLayout(this.getOrInitState(elementId));\n    if (!layout) return null;\n\n    const instance: GridInstance = {\n      id: createGridInstanceId(),\n      type,\n      visible: true,\n      settings: { ...adapter.getDefaults() },\n    };\n\n    layout.instances.push(instance);\n    this.save(elementId);\n    return instance;\n  }\n\n  removeInstance(elementId: string, instanceId: string): void {\n    const layout = this.findSelectedLayout(this.getOrInitState(elementId));\n    if (!layout) return;\n    layout.instances = layout.instances.filter((i) => i.id !== instanceId);\n    this.save(elementId);\n  }\n\n  reorderInstance(\n    elementId: string,\n    draggedId: string,\n    targetId: string,\n    placement: \"before\" | \"after\",\n  ): void {\n    const layout = this.findSelectedLayout(this.getOrInitState(elementId));\n    if (!layout || draggedId === targetId) return;\n\n    const fromIndex = layout.instances.findIndex((i) => i.id === draggedId);\n    const targetIndex = layout.instances.findIndex((i) => i.id === targetId);\n    if (fromIndex === -1 || targetIndex === -1) return;\n\n    const [dragged] = layout.instances.splice(fromIndex, 1);\n    const normalizedTarget = layout.instances.findIndex((i) => i.id === targetId);\n    const insertIndex = placement === \"before\" ? normalizedTarget : normalizedTarget + 1;\n    layout.instances.splice(insertIndex, 0, dragged);\n    this.save(elementId);\n  }\n\n  moveInstanceToEnd(elementId: string, instanceId: string): void {\n    const layout = this.findSelectedLayout(this.getOrInitState(elementId));\n    if (!layout) return;\n\n    const fromIndex = layout.instances.findIndex((i) => i.id === instanceId);\n    if (fromIndex === -1 || fromIndex === layout.instances.length - 1) return;\n\n    const [instance] = layout.instances.splice(fromIndex, 1);\n    layout.instances.push(instance);\n    this.save(elementId);\n  }\n\n  toggleVisibility(elementId: string, instanceId: string): void {\n    const instance = this.findInstance(elementId, instanceId);\n    if (!instance) return;\n    instance.visible = !instance.visible;\n    this.save(elementId);\n  }\n\n  renameInstance(elementId: string, instanceId: string, name: string): void {\n    const instance = this.findInstance(elementId, instanceId);\n    if (!instance) return;\n    instance.name = name.trim() || undefined;\n    this.save(elementId);\n  }\n\n  renamePanelTitle(elementId: string, title: string): void {\n    const state = this.getOrInitState(elementId);\n    state.panelTitle = title.trim() || \"Layout\";\n    this.save(elementId);\n  }\n\n  updateSetting(elementId: string, instanceId: string, key: string, value: any): void {\n    const instance = this.findInstance(elementId, instanceId);\n    if (!instance) return;\n    instance.settings[key] = value;\n    this.save(elementId);\n  }\n\n  findInstance(elementId: string, instanceId: string): GridInstance | undefined {\n    return this.getSelectedInstances(elementId).find((i) => i.id === instanceId);\n  }\n\n  save(elementId: string): void {\n    const state = this.elementStates.get(elementId);\n    if (!state) return;\n    try {\n      const payload = {\n        layouts: state.layouts,\n        selectedLayoutId: state.selectedLayoutId,\n        panelTitle: state.panelTitle ?? \"Layout\",\n      };\n      const storageSlot = getStorageSlot(elementId);\n      localStorage.setItem(storageSlot, JSON.stringify(payload));\n    } catch (error) {\n      console.warn(\"[StringDevLayout:storage] save failed\", {\n        elementId,\n        storageSlot: getStorageSlot(elementId),\n        error,\n      });\n    }\n  }\n\n  load(elementId: string, fallbackIds: string[] = []): void {\n    try {\n      const candidateIds = [elementId, ...fallbackIds];\n      const candidates: Array<{\n        elementId: string;\n        storageSlot: string;\n        raw: string;\n        parsed: unknown;\n        gridCount: number;\n      }> = [];\n\n      for (const candidateId of candidateIds) {\n        const storageSlot = getStorageSlot(candidateId);\n        const raw = localStorage.getItem(storageSlot);\n        if (!raw) {\n          continue;\n        }\n\n        try {\n          const parsed = JSON.parse(raw);\n          candidates.push({\n            elementId: candidateId,\n            storageSlot,\n            raw,\n            parsed,\n            gridCount: countSerializedGrids(parsed),\n          });\n        } catch (error) {\n          console.warn(\"[StringDevLayout:storage] candidate parse failed\", {\n            elementId,\n            candidateId,\n            storageSlot,\n            error,\n          });\n        }\n      }\n\n      let selectedCandidate = candidates[0] ?? null;\n      for (const candidate of candidates) {\n        if (!selectedCandidate || candidate.gridCount > selectedCandidate.gridCount) {\n          selectedCandidate = candidate;\n        }\n      }\n\n      if (!selectedCandidate) return;\n\n      const parsed = selectedCandidate.parsed;\n      const resolvedStorageId = selectedCandidate.elementId;\n\n      // Legacy: array of instances (pre-layouts era)\n      if (Array.isArray(parsed)) {\n        const valid = parsed.filter((i: any) => this.adapterRegistry.has(i.type));\n        for (const i of valid) {\n          const adapter = this.adapterRegistry.get(i.type);\n          if (adapter) i.settings = { ...adapter.getDefaults(), ...i.settings };\n        }\n        const layouts = createDefaultLayouts(MIN_LAYOUTS);\n        layouts[layouts.length - 1].instances = valid;\n        this.elementStates.set(elementId, {\n          elementId,\n          layouts,\n          selectedLayoutId: layouts[0].id,\n          panelTitle: \"Layout\",\n        });\n        if (resolvedStorageId !== elementId) {\n          this.save(elementId);\n        }\n        return;\n      }\n\n      const rawLayouts = Array.isArray(parsed?.layouts) ? parsed.layouts : null;\n      if (!rawLayouts) return;\n\n      const layouts = this.normalizeLayouts(rawLayouts);\n      if (layouts.length === 0) return;\n\n      const selectedLayoutId =\n        typeof parsed?.selectedLayoutId === \"string\"\n          ? parsed.selectedLayoutId\n          : layouts[0].id;\n\n      const state: GridElementState = {\n        elementId,\n        layouts,\n        selectedLayoutId,\n        panelTitle:\n          typeof parsed?.panelTitle === \"string\" && parsed.panelTitle.trim().length > 0\n            ? parsed.panelTitle.trim()\n            : \"Layout\",\n      };\n      this.ensureValidSelection(state);\n      this.elementStates.set(elementId, state);\n      if (resolvedStorageId !== elementId) {\n        this.save(elementId);\n      }\n    } catch {\n      // ignore malformed storage data\n    }\n  }\n\n  clear(): void {\n    this.elementStates.clear();\n  }\n\n  // ── Private ───────────────────────────────────────────\n\n  private getOrInitState(elementId: string): GridElementState {\n    let state = this.elementStates.get(elementId);\n    if (!state) {\n      const layouts = createDefaultLayouts(MIN_LAYOUTS);\n      state = { elementId, layouts, selectedLayoutId: layouts[0].id, panelTitle: \"Layout\" };\n      this.elementStates.set(elementId, state);\n    }\n    this.sortLayouts(state);\n    this.ensureValidSelection(state);\n    return state;\n  }\n\n  private normalizeLayouts(layouts: any[]): GridLayout[] {\n    const filtered = layouts.filter(\n      (l: any) => l && typeof l === \"object\" && typeof l.id === \"string\",\n    );\n\n    const normalized: GridLayout[] = filtered.map((l: any) => {\n      const instances = Array.isArray(l.instances)\n        ? l.instances\n        : Array.isArray(l.grids)\n          ? l.grids\n          : [];\n\n      return {\n        id: l.id,\n        label: l.label ?? \"S\",\n        minWidth: normalizeGridLayoutMinWidth(\n          typeof l.minWidth === \"number\" ? l.minWidth : 0,\n        ),\n        instances: instances\n          .filter((i: any) => this.adapterRegistry.has(i.type))\n          .map((i: any) => {\n            const adapter = this.adapterRegistry.get(i.type);\n            return adapter\n              ? { ...i, visible: i.visible !== false, settings: { ...adapter.getDefaults(), ...i.settings } }\n              : i;\n          }),\n      } satisfies GridLayout;\n    });\n\n    // Clamp to allowed range\n    const clamped = normalized.slice(0, MAX_LAYOUTS);\n    while (clamped.length < MIN_LAYOUTS) {\n      clamped.push({\n        id: createGridLayoutId(),\n        label: \"S\",\n        minWidth: 0,\n        instances: [],\n      });\n    }\n\n    this.sortLayoutsArr(clamped);\n    reassignLabels(clamped);\n    this.ensureMinWidthConstraintsArr(clamped);\n    return clamped;\n  }\n\n  private sortLayouts(state: GridElementState): void {\n    this.sortLayoutsArr(state.layouts);\n  }\n\n  private sortLayoutsArr(layouts: GridLayout[]): void {\n    layouts.sort((a, b) => b.minWidth - a.minWidth);\n  }\n\n  private ensureValidSelection(state: GridElementState): void {\n    if (state.layouts.length < MIN_LAYOUTS) {\n      state.layouts = createDefaultLayouts(MIN_LAYOUTS);\n    }\n    if (state.layouts.length > MAX_LAYOUTS) {\n      state.layouts = state.layouts.slice(0, MAX_LAYOUTS);\n      reassignLabels(state.layouts);\n    }\n    if (!state.layouts.some((l) => l.id === state.selectedLayoutId)) {\n      state.selectedLayoutId = state.layouts[state.layouts.length - 1].id;\n    }\n  }\n\n  private ensureMinWidthConstraints(state: GridElementState): void {\n    this.ensureMinWidthConstraintsArr(state.layouts);\n  }\n\n  private ensureMinWidthConstraintsArr(layouts: GridLayout[]): void {\n    // Smallest layout always has minWidth = 0\n    if (layouts.length === 0) return;\n    layouts[layouts.length - 1].minWidth = 0;\n\n    // Each layout must have strictly smaller minWidth than the one above it\n    for (let i = layouts.length - 2; i >= 0; i--) {\n      const below = layouts[i + 1].minWidth;\n      if (layouts[i].minWidth <= below) {\n        layouts[i].minWidth = below + 1;\n      }\n    }\n  }\n\n  private findSelectedLayout(state: GridElementState): GridLayout | undefined {\n    return state.layouts.find((l) => l.id === state.selectedLayoutId);\n  }\n\n  private findResolvedLayout(state: GridElementState, viewportWidth: number): GridLayout | undefined {\n    for (const layout of state.layouts) {\n      if (viewportWidth >= layout.minWidth) return layout;\n    }\n    return state.layouts[state.layouts.length - 1];\n  }\n}\n","import { GridAdapter } from \"./adapters/GridAdapter\";\r\nimport { GridInstance } from \"./models/GridInstance\";\r\n\r\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\r\n\r\n/**\r\n * Manages the SVG overlay that sits on top of a target element.\r\n *\r\n * Responsibilities:\r\n * - Creates and positions the SVG element\r\n * - Delegates rendering to the appropriate GridAdapter per instance\r\n * - Handles resize/reposition via `refresh()`\r\n */\r\nexport class GridOverlay {\r\n  private svg: SVGSVGElement;\r\n  private target: HTMLElement;\r\n  private resizeObserver: ResizeObserver;\r\n  private enabled: boolean = true;\r\n  private onResize?: () => void;\r\n\r\n  constructor(target: HTMLElement, world: HTMLElement, onResize?: () => void) {\r\n    this.target = target;\r\n    this.onResize = onResize;\r\n    this.svg = document.createElementNS(SVG_NS, \"svg\") as SVGSVGElement;\r\n    this.svg.setAttribute(\"data-string-grid-overlay\", \"\");\r\n    this.svg.style.position = \"absolute\";\r\n    this.svg.style.pointerEvents = \"none\";\r\n    this.svg.style.transformOrigin = \"top left\";\r\n\r\n    world.appendChild(this.svg);\r\n    this.syncViewBox();\r\n\r\n    this.resizeObserver = new ResizeObserver(() => {\r\n      this.syncViewBox();\r\n      this.onResize?.();\r\n    });\r\n    this.resizeObserver.observe(this.target);\r\n  }\r\n\r\n  public getElement(): SVGSVGElement { return this.svg; }\r\n\r\n  public setPosition(docX: number, docY: number, width: number, height: number): void {\r\n    this.svg.style.width = `${width}px`;\r\n    this.svg.style.height = `${height}px`;\r\n    this.svg.style.transform = `translate3d(${Math.round(docX)}px, ${Math.round(docY)}px, 0)`;\r\n  }\r\n\r\n  /**\r\n   * Re-renders all visible grid instances.\r\n   * Clears the entire SVG first so stale groups from a previous layout are removed.\r\n   */\r\n  render(instances: GridInstance[], adapterRegistry: Map<string, GridAdapter>): void {\r\n    this.clearAll();\r\n    if (!this.enabled) {\r\n      return;\r\n    }\r\n    const { width, height } = this.getDimensions();\r\n\r\n    for (const instance of [...instances].reverse()) {\r\n      const adapter = adapterRegistry.get(instance.type);\r\n      if (!adapter) continue;\r\n\r\n      if (instance.visible) {\r\n        adapter.render(this.svg, width, height, {\r\n          ...instance.settings,\r\n          __instanceId: instance.id,\r\n        });\r\n        const group = this.svg.querySelector(\r\n          `[data-grid-id=\"${instance.id}\"]`,\r\n        ) as SVGGElement | null;\r\n        if (group) {\r\n          group.setAttribute(\"data-grid-type\", instance.type);\r\n          group.setAttribute(\"data-grid-visible\", \"true\");\r\n        }\r\n      }\r\n    }\r\n  }\r\n\r\n  setEnabled(enabled: boolean): void {\r\n    this.enabled = enabled;\r\n    this.svg.style.display = enabled ? \"\" : \"none\";\r\n    if (!enabled) {\r\n      this.clearAll();\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Removes all rendered grid groups from the SVG.\r\n   */\r\n  clearAll(): void {\r\n    const groups = this.svg.querySelectorAll(\"[data-grid-id]\");\r\n    for (let i = groups.length - 1; i >= 0; i--) {\r\n      groups[i].remove();\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Clears a specific grid instance from the overlay.\r\n   */\r\n  clearInstance(instanceId: string, adapter: GridAdapter): void {\r\n    adapter.clear(this.svg, instanceId);\r\n  }\r\n\r\n  /**\r\n   * Syncs the SVG viewBox to match element dimensions.\r\n   */\r\n  syncViewBox(): void {\r\n    const { width, height } = this.getDimensions();\r\n    this.svg.setAttribute(\"viewBox\", `0 0 ${width} ${height}`);\r\n  }\r\n\r\n  /**\r\n   * Returns the current dimensions of the target element.\r\n   */\r\n  getDimensions(): { width: number; height: number } {\r\n    return {\r\n      width: this.target.offsetWidth,\r\n      height: this.target.offsetHeight,\r\n    };\r\n  }\r\n\r\n  /**\r\n   * Cleans up the overlay and observer.\r\n   */\r\n  destroy(): void {\r\n    this.resizeObserver.disconnect();\r\n    this.svg.remove();\r\n  }\r\n\r\n  /**\r\n   * Ensures the target element has positioning context for the overlay.\r\n   */\r\n  private ensurePositioned(): void {\r\n    const computed = getComputedStyle(this.target);\r\n    if (computed.position === \"static\") {\r\n      this.target.style.position = \"relative\";\r\n    }\r\n  }\r\n}\r\n","/**\r\n * Abstract base class for all devtools UI field components.\r\n *\r\n * Each field type creates its own DOM, handles user interaction,\r\n * and emits value changes through a callback. The field is fully\r\n * self-contained — no external framework required.\r\n */\r\nexport abstract class StringDevUIField<T = any> {\n  protected readonly key: string;\r\n  protected readonly label: string;\r\n  protected value: T;\r\n  protected onChange: (key: string, value: T) => void;\r\n  protected root: HTMLElement | null = null;\r\n\r\n  constructor(\r\n    key: string,\r\n    label: string,\r\n    defaultValue: T,\r\n    onChange: (key: string, value: T) => void,\r\n  ) {\r\n    this.key = key;\r\n    this.label = label;\r\n    this.value = defaultValue;\r\n    this.onChange = onChange;\r\n  }\r\n\r\n  /** Builds and returns the DOM element for this field */\r\n  abstract build(): HTMLElement;\r\n\r\n  /** Updates the field's visual state from an external value */\n  abstract setValue(value: T): void;\n\n  /** Updates the field disabled state from external conditions */\n  setDisabled(disabled: boolean): void {\n    if (!this.root) return;\n    this.root.setAttribute(\"data-disabled\", disabled ? \"true\" : \"false\");\n  }\n\r\n  /** Returns the current value */\r\n  getValue(): T {\r\n    return this.value;\r\n  }\r\n\r\n  /** Removes DOM and cleans up event listeners */\r\n  destroy(): void {\r\n    this.root?.remove();\r\n    this.root = null;\r\n  }\r\n\r\n  /** Emits the current value through the callback */\r\n  protected emit(value: T): void {\r\n    this.value = value;\r\n    this.onChange(this.key, value);\r\n  }\r\n\r\n  /** Creates a label element with consistent styling */\r\n  protected createLabel(): HTMLLabelElement {\r\n    const label = document.createElement(\"label\");\r\n    label.textContent = this.label;\r\n    label.setAttribute(\"data-stdg-label\", \"\");\r\n    return label;\r\n  }\r\n\r\n  /** Creates a row wrapper for label + input */\r\n  protected createRow(): HTMLDivElement {\r\n    const row = document.createElement(\"div\");\r\n    row.setAttribute(\"data-stdg-panel-field\", \"\");\r\n    return row;\r\n  }\r\n}\r\n","import { StringDevUIField } from \"./StringDevUIField\";\r\nimport { resolveDevtoolsIcon } from \"../../StringDevIconRegistry\";\r\n\r\nconst HOLD_DELAY_MS = 320;\r\nconst HOLD_INTERVAL_MS = 60;\r\nconst DRAG_PIXELS_PER_STEP = 6;\r\n\r\nexport class StringDevFieldNumber extends StringDevUIField<number> {\n  private min: number;\r\n  private max: number;\r\n  private step: number;\r\n  private input: HTMLInputElement | null = null;\n  private stepperButtons: HTMLButtonElement[] = [];\n\r\n  constructor(\r\n    key: string,\r\n    label: string,\r\n    defaultValue: number,\r\n    onChange: (key: string, value: number) => void,\r\n    min: number = 0,\r\n    max: number = 100,\r\n    step: number = 1,\r\n  ) {\r\n    super(key, label, defaultValue, onChange);\r\n    this.min = min;\r\n    this.max = max;\r\n    this.step = step;\r\n  }\r\n\r\n  build(): HTMLElement {\r\n    const row = this.createRow();\r\n    row.appendChild(this.createLabel());\r\n    row.appendChild(this.createControls());\r\n    this.root = row;\r\n    return row;\r\n  }\r\n\r\n  setValue(value: number): void {\n    this.value = value;\n    if (this.input) this.input.value = this.formatValue(value);\n  }\n\n  override setDisabled(disabled: boolean): void {\n    super.setDisabled(disabled);\n    if (this.input) this.input.disabled = disabled;\n    for (const button of this.stepperButtons) {\n      button.disabled = disabled;\n    }\n  }\n\r\n  private createControls(): HTMLDivElement {\r\n    const control = document.createElement(\"div\");\r\n    control.setAttribute(\"data-stdg-field-input\", \"\");\r\n\r\n    const stepper = document.createElement(\"div\");\r\n    stepper.setAttribute(\"data-stdg-stepper\", \"\");\r\n    stepper.appendChild(this.createStepperButton(\"up\", 1));\r\n    stepper.appendChild(this.createStepperButton(\"down\", -1));\r\n\r\n    control.appendChild(this.createInput());\r\n    control.appendChild(stepper);\r\n    return control;\r\n  }\r\n\r\n  private createInput(): HTMLInputElement {\n    const input = document.createElement(\"input\");\n    input.type = \"text\";\n    input.inputMode = \"text\";\n    input.setAttribute(\"enterkeyhint\", \"done\");\n    input.autocomplete = \"off\";\n    input.spellcheck = false;\n    input.value = this.formatValue(this.value);\n    input.setAttribute(\"data-stdg-input\", \"\");\n\r\n    input.addEventListener(\"focus\", () => {\r\n      input.select();\r\n    });\r\n    input.addEventListener(\"blur\", () => {\r\n      this.commitValue(input.value);\r\n    });\r\n    input.addEventListener(\"keydown\", (event) => {\r\n      if (event.key === \"Enter\") {\r\n        input.blur();\r\n        return;\r\n      }\r\n      if (event.key === \"Escape\") {\r\n        input.value = this.formatValue(this.value);\r\n        input.blur();\r\n        return;\r\n      }\r\n      if (event.key !== \"ArrowUp\" && event.key !== \"ArrowDown\") return;\r\n      event.preventDefault();\r\n      this.applyDelta(event.key === \"ArrowUp\" ? 1 : -1, event);\r\n    });\r\n    input.addEventListener(\"wheel\", (event) => {\r\n      if (document.activeElement !== input) return;\r\n      event.preventDefault();\r\n      this.applyDelta(event.deltaY < 0 ? 1 : -1, event);\r\n    });\r\n    input.addEventListener(\"mousedown\", (event) => {\r\n      if (event.button !== 1) return;\r\n      this.startMiddleDrag(event, input);\r\n    });\r\n    input.addEventListener(\"auxclick\", (event) => {\r\n      if (event.button === 1) event.preventDefault();\r\n    });\r\n\r\n    this.input = input;\r\n    return input;\r\n  }\r\n\r\n  private createStepperButton(directionName: \"up\" | \"down\", direction: 1 | -1): HTMLButtonElement {\r\n    const button = document.createElement(\"button\");\r\n    button.type = \"button\";\r\n    button.setAttribute(\"data-stdg-button\", \"\");\r\n    button.setAttribute(\"data-stdg-button-icon-12\", \"\");\r\n    button.setAttribute(\"data-direction\", directionName);\r\n    button.innerHTML = resolveDevtoolsIcon(\r\n      12,\r\n      directionName === \"up\" ? \"chevrone-up\" : \"chevrone-down\",\r\n    );\r\n\r\n    let holdTimeout = 0;\r\n    let holdInterval = 0;\r\n    let suppressClick = false;\r\n\r\n    const stopHold = () => {\r\n      window.clearTimeout(holdTimeout);\r\n      window.clearInterval(holdInterval);\r\n      document.removeEventListener(\"pointerup\", stopHold);\r\n      document.removeEventListener(\"pointercancel\", stopHold);\r\n    };\r\n\r\n    button.addEventListener(\"pointerdown\", (event) => {\r\n      if (event.button !== 0) return;\r\n\r\n      holdTimeout = window.setTimeout(() => {\r\n        suppressClick = true;\r\n        this.applyDelta(direction);\r\n        holdInterval = window.setInterval(() => {\r\n          this.applyDelta(direction);\r\n        }, HOLD_INTERVAL_MS);\r\n      }, HOLD_DELAY_MS);\r\n\r\n      document.addEventListener(\"pointerup\", stopHold);\r\n      document.addEventListener(\"pointercancel\", stopHold);\r\n    });\r\n\r\n    button.addEventListener(\"click\", (event) => {\n      if (suppressClick) {\r\n        suppressClick = false;\r\n        event.preventDefault();\r\n        return;\r\n      }\r\n\r\n      this.applyDelta(direction);\r\n      this.input?.focus();\r\n      this.input?.select();\r\n    });\n\n    this.stepperButtons.push(button);\n    return button;\n  }\n\r\n  private startMiddleDrag(event: MouseEvent, input: HTMLInputElement): void {\r\n    event.preventDefault();\r\n\r\n    let previousX = event.clientX;\r\n    let accumulated = 0;\r\n    const previousCursor = document.body.style.cursor;\r\n    const previousUserSelect = document.body.style.userSelect;\r\n\r\n    document.body.style.cursor = \"ew-resize\";\r\n    document.body.style.userSelect = \"none\";\r\n\r\n    const stopDrag = () => {\r\n      document.removeEventListener(\"mousemove\", onMouseMove);\r\n      document.removeEventListener(\"mouseup\", stopDrag);\r\n      document.body.style.cursor = previousCursor;\r\n      document.body.style.userSelect = previousUserSelect;\r\n    };\r\n\r\n    const onMouseMove = (moveEvent: MouseEvent) => {\r\n      const deltaX = moveEvent.clientX - previousX;\r\n      previousX = moveEvent.clientX;\r\n      accumulated += deltaX;\r\n\r\n      while (Math.abs(accumulated) >= DRAG_PIXELS_PER_STEP) {\r\n        const direction = accumulated > 0 ? 1 : -1;\r\n        this.applyDelta(direction, moveEvent);\r\n        accumulated -= DRAG_PIXELS_PER_STEP * direction;\r\n      }\r\n    };\r\n\r\n    input.focus();\r\n    input.select();\r\n    document.addEventListener(\"mousemove\", onMouseMove);\r\n    document.addEventListener(\"mouseup\", stopDrag);\r\n  }\r\n\r\n  private commitValue(rawValue: string): void {\r\n    const parsed = parseFloat(rawValue.replace(\",\", \".\"));\r\n    if (isNaN(parsed)) {\r\n      if (this.input) this.input.value = this.formatValue(this.value);\r\n      return;\r\n    }\r\n\r\n    const nextValue = this.normalizeValue(parsed);\r\n    if (this.input) this.input.value = this.formatValue(nextValue);\r\n    this.emit(nextValue);\r\n  }\r\n\r\n  private applyDelta(direction: 1 | -1, event?: KeyboardEvent | WheelEvent | MouseEvent): void {\r\n    const multiplier = event?.shiftKey ? 10 : event?.altKey ? 0.1 : 1;\r\n    const nextValue = this.normalizeValue(this.value + direction * this.step * multiplier);\r\n    if (this.input) this.input.value = this.formatValue(nextValue);\r\n    this.emit(nextValue);\r\n  }\r\n\r\n  private normalizeValue(value: number): number {\r\n    const snapped = Math.round(value / this.step) * this.step;\r\n    const precision = this.getPrecision(this.step);\r\n    return Number(snapped.toFixed(precision));\r\n  }\r\n\r\n  private getPrecision(value: number): number {\r\n    const parts = String(value).split(\".\");\r\n    return parts[1]?.length ?? 0;\r\n  }\r\n\r\n  private formatValue(value: number): string {\r\n    const precision = this.getPrecision(this.step);\r\n    return precision > 0 ? value.toFixed(precision) : String(value);\r\n  }\r\n}\r\n","import { StringDevUIField } from \"./StringDevUIField\";\r\nimport { resolveDevtoolsIcon } from \"../../StringDevIconRegistry\";\r\n\r\nconst HOLD_DELAY_MS = 320;\r\nconst HOLD_INTERVAL_MS = 60;\r\nconst DRAG_PIXELS_PER_STEP = 6;\r\n\r\nexport class StringDevFieldRange extends StringDevUIField<number> {\n  private min: number;\r\n  private max: number;\r\n  private step: number;\r\n  private displayMultiplier: number;\r\n  private displayStep?: number;\r\n  private suffix?: string;\r\n  private units: ReadonlyArray<{ value: string; label: string }> | undefined;\r\n  private currentUnit: string | undefined;\r\n  private valueInput: HTMLInputElement | null = null;\n  private unitSelect: HTMLSelectElement | null = null;\n  private stepperButtons: HTMLButtonElement[] = [];\n\r\n  private static readonly DECIMAL_UNITS = new Set([\"rem\", \"em\"]);\r\n\r\n  constructor(\r\n    key: string,\r\n    label: string,\r\n    defaultValue: number,\r\n    onChange: (key: string, value: any) => void,\r\n    min: number = 0,\r\n    max: number = 100,\r\n    step: number = 1,\r\n    displayMultiplier: number = 1,\r\n    displayStep?: number,\r\n    suffix?: string,\r\n    units?: ReadonlyArray<{ value: string; label: string }>,\r\n    currentUnit?: string,\r\n  ) {\r\n    super(key, label, defaultValue, onChange);\r\n    this.min = min;\r\n    this.max = max;\r\n    this.step = step;\r\n    this.displayMultiplier = displayMultiplier;\r\n    this.displayStep = displayStep;\r\n    this.suffix = suffix;\r\n    this.units = units;\r\n    this.currentUnit = currentUnit;\r\n  }\r\n\r\n  build(): HTMLElement {\r\n    const row = this.createRow();\r\n    row.appendChild(this.createLabel());\r\n    row.appendChild(this.createControls());\r\n    this.root = row;\r\n    return row;\r\n  }\r\n\r\n  setValue(value: number): void {\n    this.value = value;\n    if (this.valueInput) this.valueInput.value = this.formatValue(value);\n  }\n\n  override setDisabled(disabled: boolean): void {\n    super.setDisabled(disabled);\n    if (this.valueInput) this.valueInput.disabled = disabled;\n    if (this.unitSelect) this.unitSelect.disabled = disabled;\n    for (const button of this.stepperButtons) {\n      button.disabled = disabled;\n    }\n  }\n\r\n  private createControls(): HTMLDivElement {\r\n    const control = document.createElement(\"div\");\r\n    control.setAttribute(\"data-stdg-field-input\", \"\");\r\n    const inputShell = document.createElement(\"div\");\r\n    inputShell.setAttribute(\"data-stdg-field-value\", \"\");\r\n    inputShell.appendChild(this.createInput());\r\n\r\n    if (this.suffix) {\r\n      const suffix = document.createElement(\"span\");\r\n      suffix.setAttribute(\"data-stdg-field-suffix\", \"\");\r\n      suffix.textContent = this.suffix;\r\n      inputShell.appendChild(suffix);\r\n    }\r\n\r\n    control.appendChild(inputShell);\r\n\r\n    if (this.units && this.units.length > 0) {\r\n      const unitSelect = document.createElement(\"select\");\r\n      unitSelect.setAttribute(\"data-stdg-select\", \"\");\r\n\r\n      for (const u of this.units) {\r\n        const opt = document.createElement(\"option\");\r\n        opt.value = u.value;\r\n        opt.textContent = u.label;\r\n        unitSelect.appendChild(opt);\r\n      }\r\n\r\n      unitSelect.value = this.currentUnit || this.units[0].value;\r\n      unitSelect.addEventListener(\"change\", () => {\r\n        this.currentUnit = unitSelect.value;\r\n        if (this.valueInput) this.valueInput.value = this.formatValue(this.value);\r\n        this.onChange(this.key + \"Unit\", unitSelect.value);\r\n      });\r\n\r\n      this.unitSelect = unitSelect;\r\n      control.appendChild(unitSelect);\r\n    }\r\n\r\n    const stepper = document.createElement(\"div\");\r\n    stepper.setAttribute(\"data-stdg-stepper\", \"\");\r\n    stepper.appendChild(this.createStepperButton(\"up\", 1));\r\n    stepper.appendChild(this.createStepperButton(\"down\", -1));\r\n    control.appendChild(stepper);\r\n\r\n    return control;\r\n  }\r\n\r\n  private createInput(): HTMLInputElement {\n    const valueInput = document.createElement(\"input\");\n    valueInput.type = \"text\";\n    valueInput.inputMode = \"text\";\n    valueInput.setAttribute(\"enterkeyhint\", \"done\");\n    valueInput.autocomplete = \"off\";\n    valueInput.spellcheck = false;\n    valueInput.value = this.formatValue(this.value);\n    valueInput.setAttribute(\"data-stdg-input\", \"\");\n\r\n    valueInput.addEventListener(\"focus\", () => {\r\n      valueInput.select();\r\n    });\r\n    valueInput.addEventListener(\"blur\", () => {\r\n      this.commitInputValue(valueInput);\r\n    });\r\n    valueInput.addEventListener(\"keydown\", (e) => {\r\n      if (e.key === \"Enter\") {\r\n        valueInput.blur();\r\n      } else if (e.key === \"Escape\") {\r\n        valueInput.value = this.formatValue(this.value);\r\n        valueInput.blur();\r\n      } else if (e.key === \"ArrowUp\" || e.key === \"ArrowDown\") {\r\n        e.preventDefault();\r\n        this.applyDelta(e.key === \"ArrowUp\" ? 1 : -1, e, valueInput);\r\n      }\r\n    });\r\n    valueInput.addEventListener(\"wheel\", (event) => {\r\n      if (document.activeElement !== valueInput) return;\r\n      event.preventDefault();\r\n      this.applyDelta(event.deltaY < 0 ? 1 : -1, event, valueInput);\r\n    });\r\n    valueInput.addEventListener(\"mousedown\", (event) => {\r\n      if (event.button !== 1) return;\r\n      this.startMiddleDrag(event, valueInput);\r\n    });\r\n    valueInput.addEventListener(\"auxclick\", (event) => {\r\n      if (event.button === 1) event.preventDefault();\r\n    });\r\n\r\n    this.valueInput = valueInput;\r\n    return valueInput;\r\n  }\r\n\r\n  private createStepperButton(directionName: \"up\" | \"down\", direction: 1 | -1): HTMLButtonElement {\r\n    const button = document.createElement(\"button\");\r\n    button.type = \"button\";\r\n    button.setAttribute(\"data-stdg-button\", \"\");\r\n    button.setAttribute(\"data-stdg-button-icon-12\", \"\");\r\n    button.setAttribute(\"data-direction\", directionName);\r\n    button.innerHTML = resolveDevtoolsIcon(\r\n      12,\r\n      directionName === \"up\" ? \"chevrone-up\" : \"chevrone-down\",\r\n    );\r\n\r\n    let holdTimeout = 0;\r\n    let holdInterval = 0;\r\n    let suppressClick = false;\r\n\r\n    const stopHold = () => {\r\n      window.clearTimeout(holdTimeout);\r\n      window.clearInterval(holdInterval);\r\n      document.removeEventListener(\"pointerup\", stopHold);\r\n      document.removeEventListener(\"pointercancel\", stopHold);\r\n    };\r\n\r\n    button.addEventListener(\"pointerdown\", (event) => {\r\n      if (event.button !== 0) return;\r\n\r\n      holdTimeout = window.setTimeout(() => {\r\n        suppressClick = true;\r\n        if (!this.valueInput) return;\r\n        this.applyDelta(direction, undefined, this.valueInput);\r\n        holdInterval = window.setInterval(() => {\r\n          if (!this.valueInput) return;\r\n          this.applyDelta(direction, undefined, this.valueInput);\r\n        }, HOLD_INTERVAL_MS);\r\n      }, HOLD_DELAY_MS);\r\n\r\n      document.addEventListener(\"pointerup\", stopHold);\r\n      document.addEventListener(\"pointercancel\", stopHold);\r\n    });\r\n\r\n    button.addEventListener(\"click\", (event) => {\n      if (suppressClick) {\r\n        suppressClick = false;\r\n        event.preventDefault();\r\n        return;\r\n      }\r\n\r\n      if (!this.valueInput) return;\r\n      this.applyDelta(direction, undefined, this.valueInput);\r\n      this.valueInput.focus();\r\n      this.valueInput.select();\r\n    });\n\n    this.stepperButtons.push(button);\n    return button;\n  }\n\r\n  private startMiddleDrag(event: MouseEvent, input: HTMLInputElement): void {\r\n    event.preventDefault();\r\n\r\n    let previousX = event.clientX;\r\n    let accumulated = 0;\r\n    const previousCursor = document.body.style.cursor;\r\n    const previousUserSelect = document.body.style.userSelect;\r\n\r\n    document.body.style.cursor = \"ew-resize\";\r\n    document.body.style.userSelect = \"none\";\r\n\r\n    const stopDrag = () => {\r\n      document.removeEventListener(\"mousemove\", onMouseMove);\r\n      document.removeEventListener(\"mouseup\", stopDrag);\r\n      document.body.style.cursor = previousCursor;\r\n      document.body.style.userSelect = previousUserSelect;\r\n    };\r\n\r\n    const onMouseMove = (moveEvent: MouseEvent) => {\r\n      const deltaX = moveEvent.clientX - previousX;\r\n      previousX = moveEvent.clientX;\r\n      accumulated += deltaX;\r\n\r\n      while (Math.abs(accumulated) >= DRAG_PIXELS_PER_STEP) {\r\n        const direction = accumulated > 0 ? 1 : -1;\r\n        this.applyDelta(direction, moveEvent, input);\r\n        accumulated -= DRAG_PIXELS_PER_STEP * direction;\r\n      }\r\n    };\r\n\r\n    input.focus();\r\n    input.select();\r\n    document.addEventListener(\"mousemove\", onMouseMove);\r\n    document.addEventListener(\"mouseup\", stopDrag);\r\n  }\r\n\r\n  private commitInputValue(input: HTMLInputElement): void {\r\n    const parsed = parseFloat(input.value.replace(\",\", \".\"));\r\n    if (isNaN(parsed)) {\r\n      input.value = this.formatValue(this.value);\r\n      return;\r\n    }\r\n    const snapped = this.normalizeDisplayValue(parsed);\r\n    input.value = this.formatValue(snapped);\r\n    this.emit(snapped);\r\n  }\r\n\r\n  private applyDelta(\r\n    direction: 1 | -1,\r\n    event: KeyboardEvent | WheelEvent | MouseEvent | undefined,\r\n    input: HTMLInputElement,\r\n  ): void {\r\n    const multiplier = event?.shiftKey ? 10 : event?.altKey ? 0.1 : 1;\r\n    const displayNextValue =\r\n      this.modelToDisplay(this.value) + direction * this.getDisplayStep() * multiplier;\r\n    const nextValue = this.normalizeDisplayValue(displayNextValue);\r\n    input.value = this.formatValue(nextValue);\r\n    this.emit(nextValue);\r\n  }\r\n\r\n  private normalizeValue(value: number): number {\r\n    const clamped = Math.min(this.max, Math.max(this.min, value));\r\n    if (StringDevFieldRange.DECIMAL_UNITS.has(this.currentUnit ?? \"\")) {\r\n      return Number(clamped.toFixed(2));\r\n    }\r\n    const snapped = Math.round(clamped / this.step) * this.step;\r\n    const precision = this.getPrecision(this.step);\r\n    return Number(snapped.toFixed(precision));\r\n  }\r\n\r\n  private normalizeDisplayValue(value: number): number {\r\n    const displayMin = this.modelToDisplay(this.min);\r\n    const displayMax = this.modelToDisplay(this.max);\r\n    const clamped = Math.min(displayMax, Math.max(displayMin, value));\r\n    const precision = this.getDisplayPrecision();\r\n    if (StringDevFieldRange.DECIMAL_UNITS.has(this.currentUnit ?? \"\")) {\r\n      const normalizedDisplay = Number(clamped.toFixed(precision));\r\n      return this.normalizeValue(this.displayToModel(normalizedDisplay));\r\n    }\r\n    const displayStep = this.getDisplayStep();\r\n    const snapped = Math.round(clamped / displayStep) * displayStep;\r\n    const normalizedDisplay = Number(snapped.toFixed(precision));\r\n    return this.normalizeValue(this.displayToModel(normalizedDisplay));\r\n  }\r\n\r\n  private getPrecision(value: number): number {\r\n    const parts = String(value).split(\".\");\r\n    return parts[1]?.length ?? 0;\r\n  }\r\n\r\n  private formatValue(v: number): string {\r\n    const displayValue = this.modelToDisplay(v);\r\n    const precision = this.getDisplayPrecision();\r\n    return precision > 0 ? displayValue.toFixed(precision) : String(displayValue);\r\n  }\r\n\r\n  private modelToDisplay(value: number): number {\r\n    const precision = this.getDisplayPrecision();\r\n    return Number((value * this.displayMultiplier).toFixed(precision));\r\n  }\r\n\r\n  private displayToModel(value: number): number {\r\n    return value / this.displayMultiplier;\r\n  }\r\n\r\n  private getDisplayStep(): number {\r\n    return this.displayStep ?? this.step * this.displayMultiplier;\r\n  }\r\n\r\n  private getDisplayPrecision(): number {\r\n    if (StringDevFieldRange.DECIMAL_UNITS.has(this.currentUnit ?? \"\")) {\r\n      return 2;\r\n    }\r\n    const displayStep = this.getDisplayStep();\r\n    return displayStep < 1 ? Math.max(2, this.getPrecision(displayStep)) : 0;\r\n  }\r\n}\r\n","import { StringDevUIField } from \"./StringDevUIField\";\r\n\r\nexport class StringDevFieldColor extends StringDevUIField<string> {\r\n  private colorInput: HTMLInputElement | null = null;\r\n  private hexLabel: HTMLInputElement | null = null;\r\n\r\n  build(): HTMLElement {\r\n    const row = this.createRow();\r\n    row.appendChild(this.createLabel());\r\n    row.appendChild(this.createControl());\r\n    this.root = row;\r\n    return row;\r\n  }\r\n\r\n  setValue(value: string): void {\n    this.value = value;\n    if (this.colorInput) this.colorInput.value = value;\n    if (this.hexLabel) this.hexLabel.value = value;\n  }\n\n  override setDisabled(disabled: boolean): void {\n    super.setDisabled(disabled);\n    if (this.colorInput) this.colorInput.disabled = disabled;\n    if (this.hexLabel) this.hexLabel.disabled = disabled;\n  }\n\r\n  private createControl(): HTMLDivElement {\r\n    const shell = document.createElement(\"div\");\r\n    shell.setAttribute(\"data-stdg-field-input\", \"\");\r\n\r\n    const colorInput = document.createElement(\"input\");\r\n    colorInput.type = \"color\";\r\n    colorInput.value = this.value;\r\n    colorInput.setAttribute(\"data-stdg-input\", \"\");\r\n    colorInput.setAttribute(\"data-stdg-input-color\", \"\");\r\n\r\n    const hexLabel = document.createElement(\"input\");\r\n    hexLabel.type = \"text\";\r\n    hexLabel.inputMode = \"text\";\r\n    hexLabel.value = this.value;\r\n    hexLabel.setAttribute(\"data-stdg-input\", \"\");\r\n\r\n    colorInput.addEventListener(\"input\", () => {\r\n      hexLabel.value = colorInput.value;\r\n      this.emit(colorInput.value);\r\n    });\r\n\r\n    hexLabel.addEventListener(\"change\", () => {\r\n      const val = hexLabel.value.trim();\r\n      colorInput.value = val;\r\n      this.emit(val);\r\n    });\r\n\r\n    this.colorInput = colorInput;\r\n    this.hexLabel = hexLabel;\r\n\r\n    shell.appendChild(colorInput);\r\n    shell.appendChild(hexLabel);\r\n    return shell;\r\n  }\r\n}\r\n","import { StringDevUIField } from \"./StringDevUIField\";\r\nimport { resolveDevtoolsIcon } from \"../../StringDevIconRegistry\";\r\n\r\nexport class StringDevFieldSelect extends StringDevUIField<string> {\n  private options: ReadonlyArray<{ value: string; label: string }>;\n  private select: HTMLSelectElement | null = null;\n  private stepperButtons: HTMLButtonElement[] = [];\n\r\n  constructor(\r\n    key: string,\r\n    label: string,\r\n    defaultValue: string,\r\n    onChange: (key: string, value: string) => void,\r\n    options: ReadonlyArray<{ value: string; label: string }>,\r\n  ) {\r\n    super(key, label, defaultValue, onChange);\r\n    this.options = options;\r\n  }\r\n\r\n  build(): HTMLElement {\r\n    const row = this.createRow();\r\n    row.appendChild(this.createLabel());\r\n    row.appendChild(this.createControl());\r\n    this.root = row;\r\n    return row;\r\n  }\r\n\r\n  setValue(value: string): void {\n    this.value = value;\n    if (this.select) this.select.value = value;\n  }\n\n  override setDisabled(disabled: boolean): void {\n    super.setDisabled(disabled);\n    if (this.select) this.select.disabled = disabled;\n    for (const button of this.stepperButtons) {\n      button.disabled = disabled;\n    }\n  }\n\r\n  private createControl(): HTMLDivElement {\r\n    const shell = document.createElement(\"div\");\r\n    shell.setAttribute(\"data-stdg-field-input\", \"\");\r\n\r\n    const select = document.createElement(\"select\");\r\n    select.setAttribute(\"data-stdg-select\", \"\");\r\n\r\n    for (const opt of this.options) {\r\n      const option = document.createElement(\"option\");\r\n      option.value = opt.value;\r\n      option.textContent = opt.label;\r\n      if (opt.value === this.value) option.selected = true;\r\n      select.appendChild(option);\r\n    }\r\n\r\n    select.addEventListener(\"change\", () => {\r\n      this.emit(select.value);\r\n    });\r\n\r\n    this.select = select;\r\n\r\n    const stepper = document.createElement(\"div\");\r\n    stepper.setAttribute(\"data-stdg-stepper\", \"\");\r\n    stepper.appendChild(this.createStepperButton(\"up\", -1));\r\n    stepper.appendChild(this.createStepperButton(\"down\", 1));\r\n\r\n    shell.appendChild(select);\r\n    shell.appendChild(stepper);\r\n    return shell;\r\n  }\r\n\r\n  private createStepperButton(directionName: \"up\" | \"down\", direction: 1 | -1): HTMLButtonElement {\r\n    const button = document.createElement(\"button\");\r\n    button.type = \"button\";\r\n    button.setAttribute(\"data-stdg-button\", \"\");\r\n    button.setAttribute(\"data-stdg-button-icon-12\", \"\");\r\n    button.setAttribute(\"data-direction\", directionName);\r\n    button.innerHTML = resolveDevtoolsIcon(\r\n      12,\r\n      directionName === \"up\" ? \"chevrone-up\" : \"chevrone-down\",\r\n    );\r\n    button.addEventListener(\"click\", () => {\n      if (!this.select) return;\r\n      const count = this.select.options.length;\r\n      if (count === 0) return;\r\n      const currentIndex = this.select.selectedIndex;\r\n      const nextIndex = (((currentIndex + direction) % count) + count) % count;\r\n      this.select.selectedIndex = nextIndex;\r\n      this.emit(this.select.value);\r\n    });\n    this.stepperButtons.push(button);\n    return button;\n  }\n}\r\n","import { StringDevUIField } from \"./StringDevUIField\";\r\n\r\nexport class StringDevFieldToggle extends StringDevUIField<boolean> {\r\n  private checkbox: HTMLInputElement | null = null;\r\n  private toggle: HTMLElement | null = null;\r\n\r\n  build(): HTMLElement {\r\n    const row = this.createRow();\r\n    row.appendChild(this.createLabel());\r\n\r\n    const toggle = document.createElement(\"label\");\r\n    toggle.setAttribute(\"data-stdg-toggle\", \"\");\r\n    toggle.setAttribute(\"data-checked\", String(this.value));\r\n\r\n    const hidden = document.createElement(\"input\");\r\n    hidden.type = \"checkbox\";\r\n    hidden.checked = this.value;\r\n    hidden.setAttribute(\"data-stdg-toggle-input\", \"\");\r\n    this.checkbox = hidden;\r\n    this.toggle = toggle;\r\n\r\n    const knob = document.createElement(\"span\");\r\n    knob.setAttribute(\"data-stdg-toggle-knob\", \"\");\r\n\r\n    hidden.addEventListener(\"change\", () => {\r\n      const next = hidden.checked;\r\n      this.value = next;\r\n      toggle.setAttribute(\"data-checked\", String(next));\r\n      this.emit(next);\r\n    });\r\n\r\n    toggle.appendChild(hidden);\r\n    toggle.appendChild(knob);\r\n    row.appendChild(toggle);\r\n    this.root = row;\r\n    return row;\r\n  }\r\n\r\n  setValue(value: boolean): void {\n    this.value = value;\n    if (this.checkbox) this.checkbox.checked = value;\n    this.toggle?.setAttribute(\"data-checked\", String(value));\n  }\n\n  override setDisabled(disabled: boolean): void {\n    super.setDisabled(disabled);\n    if (this.checkbox) this.checkbox.disabled = disabled;\n    this.toggle?.setAttribute(\"aria-disabled\", disabled ? \"true\" : \"false\");\n  }\n}\r\n","import { StringDevUIFieldDescriptor } from \"./StringDevUISchema\";\nimport { StringDevUIField } from \"./fields/StringDevUIField\";\nimport { StringDevFieldNumber } from \"./fields/StringDevFieldNumber\";\nimport { StringDevFieldRange } from \"./fields/StringDevFieldRange\";\nimport { StringDevFieldColor } from \"./fields/StringDevFieldColor\";\nimport { StringDevFieldSelect } from \"./fields/StringDevFieldSelect\";\nimport { StringDevFieldToggle } from \"./fields/StringDevFieldToggle\";\n\ninterface BuiltFieldEntry {\n  descriptor: Exclude<StringDevUIFieldDescriptor, { type: \"divider\" }>;\n  field: StringDevUIField;\n}\n\r\n/**\r\n * Constructs a settings panel from a StringDevUIFieldDescriptor schema.\r\n *\r\n * The builder is module-agnostic — it reads the schema,\r\n * instantiates the correct field components, and wires up\r\n * change callbacks. The module never touches the UI directly.\r\n */\r\nexport class StringDevUIBuilder {\n  private fields: StringDevUIField[] = [];\n  private fieldEntries: BuiltFieldEntry[] = [];\n  private values: Record<string, any> = {};\n\r\n  /**\r\n   * Builds a DocumentFragment containing grouped [data-stdg-panel-content] sections.\r\n   * Each \"divider\" descriptor in the schema starts a new group.\r\n   *\r\n   * @param schema    Array of field descriptors from a devtool module\r\n   * @param values    Current values (merged with defaults)\r\n   * @param onChange  Callback fired when any field value changes\r\n   * @returns         A DocumentFragment with one or more panel-content groups\r\n   */\r\n  build(\n    schema: StringDevUIFieldDescriptor[],\n    values: Record<string, any>,\n    onChange: (key: string, value: any) => void,\n  ): DocumentFragment {\n    this.destroy();\n    this.values = { ...values };\n    const handleChange = (key: string, value: any) => {\n      this.values[key] = value;\n      this.syncDisabledStates();\n      onChange(key, value);\n    };\n\r\n    const fragment = document.createDocumentFragment();\r\n    let currentGroup = document.createElement(\"div\");\r\n    currentGroup.setAttribute(\"data-stdg-panel-content\", \"\");\r\n    fragment.appendChild(currentGroup);\r\n\r\n    for (const descriptor of schema) {\r\n      if (descriptor.type === \"divider\") {\r\n        currentGroup = document.createElement(\"div\");\r\n        currentGroup.setAttribute(\"data-stdg-panel-content\", \"\");\r\n        fragment.appendChild(currentGroup);\r\n        continue;\r\n      }\n      const field = this.createField(descriptor, values, handleChange);\n      if (field) {\n        this.fields.push(field);\n        this.fieldEntries.push({ descriptor, field });\n        currentGroup.appendChild(field.build());\n      }\n    }\n\n    this.syncDisabledStates();\n\n    return fragment;\n  }\n\r\n  /**\r\n   * Updates all field values from an external state object.\r\n   */\r\n  updateValues(values: Record<string, any>): void {\n    this.values = { ...this.values, ...values };\n    for (const field of this.fields) {\n      const key = (field as any).key;\n      if (key && key in values) {\n        field.setValue(values[key]);\n      }\n    }\n    this.syncDisabledStates();\n  }\n\r\n  /**\r\n   * Tears down all fields and removes the container.\r\n   */\r\n  destroy(): void {\n    for (const field of this.fields) {\n      field.destroy();\n    }\n    this.fields = [];\n    this.fieldEntries = [];\n    this.values = {};\n  }\n\r\n  private createField(\n    descriptor: StringDevUIFieldDescriptor,\n    values: Record<string, any>,\n    onChange: (key: string, value: any) => void,\n  ): StringDevUIField | null {\n    switch (descriptor.type) {\r\n      case \"number\":\r\n        return new StringDevFieldNumber(\r\n          descriptor.key,\r\n          descriptor.label,\r\n          values[descriptor.key] ?? descriptor.default,\r\n          onChange,\r\n          descriptor.min,\r\n          descriptor.max,\r\n          descriptor.step,\r\n        );\r\n\r\n      case \"range\":\n        return new StringDevFieldRange(\n          descriptor.key,\n          descriptor.label,\n          values[descriptor.key] ?? descriptor.default,\n          onChange,\n          descriptor.min,\n          descriptor.max,\n          descriptor.step,\n          descriptor.displayMultiplier,\n          descriptor.displayStep,\n          descriptor.suffix,\n          descriptor.units,\n          values[descriptor.key + \"Unit\"] ?? descriptor.defaultUnit,\n        );\n\r\n      case \"color\":\r\n        return new StringDevFieldColor(\r\n          descriptor.key,\r\n          descriptor.label,\r\n          values[descriptor.key] ?? descriptor.default,\r\n          onChange,\r\n        );\r\n\r\n      case \"select\":\r\n        return new StringDevFieldSelect(\r\n          descriptor.key,\r\n          descriptor.label,\r\n          values[descriptor.key] ?? descriptor.default,\r\n          onChange,\r\n          descriptor.options,\r\n        );\r\n\r\n      case \"toggle\":\r\n        return new StringDevFieldToggle(\r\n          descriptor.key,\r\n          descriptor.label,\r\n          values[descriptor.key] ?? descriptor.default,\r\n          onChange,\r\n        );\r\n\r\n      default:\n        return null;\n    }\n  }\n\n  private syncDisabledStates(): void {\n    for (const entry of this.fieldEntries) {\n      const disabledWhen = entry.descriptor.disabledWhen;\n      const disabled =\n        !!disabledWhen && this.values[disabledWhen.key] === disabledWhen.equals;\n      entry.field.setDisabled(disabled);\n    }\n  }\n}\n","import { GridAdapter } from \"./adapters/GridAdapter\";\r\nimport { GridInstance, GridLayout, MAX_LAYOUTS, MIN_LAYOUTS } from \"./models/GridInstance\";\r\nimport { StringDevUIBuilder as GridUIBuilder } from \"../core/ui/StringDevUIBuilder\";\r\nimport { resolveDevtoolsIcon } from \"../core/StringDevIconRegistry\";\r\nimport {\r\n  makeBadge,\r\n  makeDeleteButton,\r\n  makePanel,\r\n  makePanelHeader,\r\n  makePanelContent,\r\n  makeIconButton,\r\n  makePanelButton,\r\n} from \"../core/StringDevElements\";\r\n\r\ntype DropPlacement = \"before\" | \"after\";\r\n\r\nconst MOBILE_PANEL_MARGIN = 12;\r\nconst MOBILE_PANEL_MAX_WIDTH = 360;\r\nconst MOBILE_PANEL_MAX_HEIGHT = 560;\r\n\r\nexport class GridHUD {\r\n  private target: HTMLElement;\r\n  private adapterRegistry: Map<string, GridAdapter>;\r\n  private hudRoot: HTMLDivElement;\r\n  private trigger: HTMLButtonElement;\r\n  private panel: HTMLDivElement;\r\n  private layoutTitle!: HTMLInputElement;\r\n\r\n  private layoutChipTabs!: HTMLDivElement;\r\n  private layoutSettingsToggle!: HTMLButtonElement;\r\n  private layoutSettingsList!: HTMLDivElement;\r\n  private layoutAddButton!: HTMLButtonElement;\r\n  private layoutIOActions!: HTMLDivElement;\r\n  private listContainer!: HTMLDivElement;\r\n  private addGuideButton!: HTMLButtonElement;\r\n  private headerAddButton!: HTMLButtonElement;\r\n  private addPanel!: HTMLDivElement;\r\n  private addGridList!: HTMLDivElement;\r\n  private layoutPanel!: HTMLDivElement;\r\n  private detailPanel!: HTMLDivElement;\r\n  private detailContent!: HTMLDivElement;\r\n  private detailTitle: HTMLSpanElement | null = null;\r\n  private detailIcon: HTMLSpanElement | null = null;\r\n  private detailBuilder: GridUIBuilder | null = null;\r\n  private instances: GridInstance[] = [];\r\n  private layouts: GridLayout[] = [];\r\n  private panelTitleValue = \"Layout\";\r\n  private selectedLayoutId = \"\";\r\n  private resolvedLayoutId = \"\";\r\n  private selectedInstanceId: string | null = null;\r\n  private selectedBreakpointLayoutId: string | null = null;\r\n  private isOpen = false;\r\n  private panelInBody = false;\r\n  private isAddPanelOpen = false;\r\n  private isLayoutSettingsOpen = false;\r\n  private enabled = true;\r\n\r\n  private onDocumentPointerDownBind!: (event: PointerEvent) => void;\r\n  private onViewportChangeBind!: () => void;\r\n\r\n  private onAdd!: (type: string) => void;\r\n  private onRemove!: (id: string) => void;\r\n  private onToggle!: (id: string) => void;\r\n  private onSettingChange!: (id: string, key: string, value: any) => void;\r\n  private onReorder!: (draggedId: string, targetId: string, placement: DropPlacement) => void;\r\n  private onMoveToEnd!: (id: string) => void;\r\n  private onSelectLayout!: (layoutId: string) => void;\r\n  private onUpdateLayoutMinWidth!: (layoutId: string, minWidth: number) => void;\r\n  private onAddLayout!: () => void;\r\n  private onRemoveLayout!: (layoutId: string) => void;\r\n  private onExport!: () => void;\r\n  private onImport!: () => void;\r\n  private onRenameInstance!: (instanceId: string, name: string) => void;\r\n  private onRenamePanelTitle!: (title: string) => void;\r\n  private onHUDOpen!: () => void;\r\n  private onHUDClose!: () => void;\r\n  private onLayoutPanelOpen!: () => void;\r\n  private onLayoutPanelClose!: () => void;\r\n\r\n  constructor(\r\n    target: HTMLElement,\r\n    adapterRegistry: Map<string, GridAdapter>,\r\n    callbacks: {\r\n      onAdd: (type: string) => void;\r\n      onRemove: (id: string) => void;\r\n      onToggle: (id: string) => void;\r\n      onSettingChange: (id: string, key: string, value: any) => void;\r\n      onReorder: (draggedId: string, targetId: string, placement: DropPlacement) => void;\r\n      onMoveToEnd: (id: string) => void;\r\n      onSelectLayout: (layoutId: string) => void;\r\n      onUpdateLayoutMinWidth: (layoutId: string, minWidth: number) => void;\r\n      onAddLayout: () => void;\r\n      onRemoveLayout: (layoutId: string) => void;\r\n      onExport: () => void;\r\n      onImport: () => void;\r\n      onRenameInstance: (instanceId: string, name: string) => void;\r\n      onRenamePanelTitle: (title: string) => void;\r\n      onHUDOpen: () => void;\r\n      onHUDClose: () => void;\r\n      onLayoutPanelOpen: () => void;\r\n      onLayoutPanelClose: () => void;\r\n    },\r\n    options?: { attachTrigger?: boolean },\r\n  ) {\r\n    this.target = target;\r\n    this.adapterRegistry = adapterRegistry;\r\n    this.onAdd = callbacks.onAdd;\r\n    this.onRemove = callbacks.onRemove;\r\n    this.onToggle = callbacks.onToggle;\r\n    this.onSettingChange = callbacks.onSettingChange;\r\n    this.onReorder = callbacks.onReorder;\r\n    this.onMoveToEnd = callbacks.onMoveToEnd;\r\n    this.onSelectLayout = callbacks.onSelectLayout;\r\n    this.onUpdateLayoutMinWidth = callbacks.onUpdateLayoutMinWidth;\r\n    this.onAddLayout = callbacks.onAddLayout;\r\n    this.onRemoveLayout = callbacks.onRemoveLayout;\r\n    this.onExport = callbacks.onExport;\r\n    this.onImport = callbacks.onImport;\r\n    this.onRenameInstance = callbacks.onRenameInstance;\r\n    this.onRenamePanelTitle = callbacks.onRenamePanelTitle;\r\n    this.onHUDOpen = callbacks.onHUDOpen;\r\n    this.onHUDClose = callbacks.onHUDClose;\r\n    this.onLayoutPanelOpen = callbacks.onLayoutPanelOpen;\r\n    this.onLayoutPanelClose = callbacks.onLayoutPanelClose;\r\n    this.onDocumentPointerDownBind = this.onDocumentPointerDown.bind(this);\r\n    this.onViewportChangeBind = () => this.syncPanelPlacement();\r\n\r\n    this.hudRoot = this.createHudRoot();\r\n    this.trigger = this.createTrigger();\r\n    this.panel = this.createMainPanel();\r\n    this.addPanel = this.createAddPanel();\r\n    this.layoutPanel = this.createLayoutPanel();\r\n    this.detailPanel = this.createDetailPanel();\r\n\r\n    if (options?.attachTrigger !== false) {\r\n      this.hudRoot.appendChild(this.trigger);\r\n    }\r\n    this.panel.appendChild(this.addPanel);\r\n    this.panel.appendChild(this.layoutPanel);\r\n    this.panel.appendChild(this.detailPanel);\r\n    this.hudRoot.appendChild(this.panel);\r\n    document.addEventListener(\"pointerdown\", this.onDocumentPointerDownBind);\r\n    window.addEventListener(\"resize\", this.onViewportChangeBind);\r\n    window.visualViewport?.addEventListener(\"resize\", this.onViewportChangeBind);\r\n    window.visualViewport?.addEventListener(\"scroll\", this.onViewportChangeBind);\r\n  }\r\n\r\n  refresh(\r\n    instances: GridInstance[],\r\n    layouts: GridLayout[],\r\n    panelTitle: string,\r\n    selectedLayoutId: string,\r\n    resolvedLayoutId: string,\r\n  ): void {\r\n    this.instances = [...instances];\r\n    this.layouts = [...layouts];\r\n    this.panelTitleValue = panelTitle.trim() || \"Layout\";\r\n    this.selectedLayoutId = selectedLayoutId;\r\n    this.resolvedLayoutId = resolvedLayoutId;\r\n    if (\r\n      this.selectedInstanceId &&\r\n      !instances.some((instance) => instance.id === this.selectedInstanceId)\r\n    ) {\r\n      this.clearSelection();\r\n    }\r\n    if (\r\n      this.selectedBreakpointLayoutId &&\r\n      !this.layouts.some((layout) => layout.id === this.selectedBreakpointLayoutId)\r\n    ) {\r\n      this.selectedBreakpointLayoutId = null;\r\n    }\r\n    this.layoutTitle.value = this.panelTitleValue;\r\n    this.renderLayoutChips();\r\n    this.renderLayoutSettings();\r\n    this.renderList();\r\n    this.renderDetailPanel();\r\n  }\r\n\r\n  destroy(): void {\r\n    this.detailBuilder?.destroy();\r\n    document.removeEventListener(\"pointerdown\", this.onDocumentPointerDownBind);\r\n    window.removeEventListener(\"resize\", this.onViewportChangeBind);\r\n    window.visualViewport?.removeEventListener(\"resize\", this.onViewportChangeBind);\r\n    window.visualViewport?.removeEventListener(\"scroll\", this.onViewportChangeBind);\r\n    if (this.panelInBody) {\r\n      this.panel.remove();\r\n    }\r\n    this.hudRoot.remove();\r\n  }\r\n\r\n  getTriggerElement(): HTMLButtonElement {\r\n    return this.trigger;\r\n  }\r\n\r\n  getHudElement(): HTMLDivElement {\r\n    return this.hudRoot;\r\n  }\r\n\r\n  setTargetId(targetId: string): void {\r\n    this.hudRoot.setAttribute(\"data-target-id\", targetId);\r\n    this.trigger.setAttribute(\"data-target-id\", targetId);\r\n    this.panel.setAttribute(\"data-target-id\", targetId);\r\n    this.addPanel.setAttribute(\"data-target-id\", targetId);\r\n    this.layoutPanel.setAttribute(\"data-target-id\", targetId);\r\n    this.detailPanel.setAttribute(\"data-target-id\", targetId);\r\n  }\r\n\r\n  setAnchorPosition(docX: number, docY: number, align: \"top-left\" | \"top-right\" = \"top-left\"): void {\r\n    this.hudRoot.setAttribute(\"data-visible\", \"true\");\r\n    const anchorTransform = align === \"top-right\" ? \" translate(-100%, 0%)\" : \"\";\r\n    this.hudRoot.style.transform = `translate3d(${Math.round(docX)}px, ${Math.round(docY)}px, 0)${anchorTransform}`;\r\n    this.syncPanelPlacement();\r\n  }\r\n\r\n  setAnchorVisible(visible: boolean): void {\r\n    this.hudRoot.setAttribute(\"data-visible\", visible ? \"true\" : \"false\");\r\n  }\r\n\r\n  isHUDOpen(): boolean {\r\n    return this.isOpen;\r\n  }\r\n\r\n  isLayoutSettingsPanelOpen(): boolean {\r\n    return this.isLayoutSettingsOpen;\r\n  }\r\n\r\n  setEnabled(enabled: boolean): void {\r\n    this.enabled = enabled;\r\n    if (!enabled) this.hide();\r\n    this.hudRoot.style.display = enabled ? \"\" : \"none\";\r\n  }\r\n\r\n  isEnabled(): boolean {\r\n    return this.enabled;\r\n  }\r\n\r\n  private createHudRoot(): HTMLDivElement {\r\n    return makeBadge();\r\n  }\r\n\r\n  private createTrigger(): HTMLButtonElement {\r\n    const trigger = makeIconButton({\r\n      icon: \"settings\",\r\n      label: \"Open layout guides\",\r\n      modifiers: [\"toggle\"],\r\n      attrs: {\r\n        \"data-devguides-id\": \"layout\",\r\n        \"data-open\": \"false\",\r\n        \"data-state\": \"visible\",\r\n        \"data-active\": \"false\",\r\n        \"aria-expanded\": \"false\",\r\n      },\r\n    });\r\n    trigger.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      this.toggle();\r\n    });\r\n    return trigger;\r\n  }\r\n\r\n  private createMainPanel(): HTMLDivElement {\r\n    const panel = makePanel();\r\n\r\n    const header = makePanelHeader();\r\n\r\n    this.layoutTitle = document.createElement(\"input\");\r\n    this.layoutTitle.setAttribute(\"data-stdg-input\", \"\");\r\n    this.layoutTitle.setAttribute(\"data-stdg-panel-title\", \"\");\r\n    this.layoutTitle.type = \"text\";\r\n    this.layoutTitle.value = this.panelTitleValue;\r\n    this.layoutTitle.addEventListener(\"blur\", () => {\r\n      const nextTitle = this.layoutTitle.value.trim() || \"Layout\";\r\n      if (nextTitle !== this.panelTitleValue) {\r\n        this.panelTitleValue = nextTitle;\r\n        this.onRenamePanelTitle(nextTitle);\r\n      }\r\n      this.layoutTitle.value = nextTitle;\r\n    });\r\n    this.layoutTitle.addEventListener(\"keydown\", (event) => {\r\n      event.stopPropagation();\r\n      if (event.key === \"Enter\") this.layoutTitle.blur();\r\n      if (event.key === \"Escape\") {\r\n        this.layoutTitle.value = this.panelTitleValue.trim() || \"Layout\";\r\n        this.layoutTitle.blur();\r\n      }\r\n    });\r\n    this.layoutTitle.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      this.startLayoutTitleRename();\r\n    });\r\n\r\n    this.layoutSettingsToggle = makeIconButton({\r\n      icon: \"options\",\r\n      label: \"Layout Settings\",\r\n      modifiers: [\"toggle\", \"left\"],\r\n      attrs: { \"data-active\": \"false\" },\r\n    });\r\n    this.layoutSettingsToggle.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      if (this.isLayoutSettingsOpen) this.closeLayoutPanel();\r\n      else this.openLayoutPanel();\r\n    });\r\n\r\n    const closeButton = makeIconButton({\r\n      icon: \"close\",\r\n      label: \"Close layout guides\",\r\n      modifiers: [\"right\"],\r\n    });\r\n    closeButton.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      this.hide();\r\n    });\r\n\r\n    this.headerAddButton = makeIconButton({\r\n      icon: \"plus\",\r\n      label: \"Add Layout Guide\",\r\n      modifiers: [\"toggle\", \"left\"],\r\n      attrs: { \"data-active\": \"false\" },\r\n    });\r\n    this.headerAddButton.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      this.openAddPanel();\r\n    });\r\n\r\n    header.appendChild(this.layoutTitle);\r\n    header.appendChild(this.headerAddButton);\r\n    header.appendChild(closeButton);\r\n\r\n    const responsive = document.createElement(\"div\");\r\n    responsive.setAttribute(\"data-stdg-panel-responsive\", \"\");\r\n\r\n    this.layoutChipTabs = document.createElement(\"div\");\r\n    this.layoutChipTabs.setAttribute(\"data-stdg-panel-list\", \"\");\r\n\r\n    responsive.appendChild(this.layoutSettingsToggle);\r\n    responsive.appendChild(this.layoutChipTabs);\r\n\r\n    this.listContainer = makePanelContent({ \"data-string-grid-list\": \"\" });\r\n\r\n    this.addGuideButton = makePanelButton({\r\n      icon: \"plus\",\r\n      label: \"Add Layout Guide\",\r\n      withLabel: true,\r\n      attrs: { \"data-active\": \"false\" },\r\n    });\r\n    this.addGuideButton.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      this.openAddPanel();\r\n    });\r\n\r\n    this.listContainer.appendChild(this.addGuideButton);\r\n\r\n    panel.appendChild(header);\r\n    panel.appendChild(responsive);\r\n    panel.appendChild(this.listContainer);\r\n    return panel;\r\n  }\r\n\r\n  private createAddPanel(): HTMLDivElement {\r\n    const panel = makePanel({ \"data-panel\": \"add\" });\r\n    const header = makePanelHeader();\r\n\r\n    const closeButton = makeIconButton({\r\n      icon: \"close\",\r\n      label: \"Close panel\",\r\n      modifiers: [\"right\"],\r\n    });\r\n    closeButton.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      this.closeAddPanel();\r\n    });\r\n    header.appendChild(closeButton);\r\n\r\n    this.addGridList = makePanelContent({\r\n      \"data-string-grid-add-grid-list\": \"\",\r\n      \"data-stdg-panel-content-50\": \"\",\r\n    });\r\n    this.renderAddPanelList();\r\n\r\n    panel.appendChild(header);\r\n    panel.appendChild(this.addGridList);\r\n    return panel;\r\n  }\r\n\r\n  private renderAddPanelList(): void {\r\n    this.addGridList.innerHTML = \"\";\r\n\r\n    if (this.adapterRegistry.size === 0) {\r\n      const empty = document.createElement(\"div\");\r\n      empty.setAttribute(\"data-string-grid-add-grid-empty\", \"\");\r\n      empty.textContent = \"No layout guides available\";\r\n      this.addGridList.appendChild(empty);\r\n      return;\r\n    }\r\n\r\n    for (const [, adapter] of this.adapterRegistry) {\r\n      const item = makePanelButton({ icon: \"\", label: adapter.label, withLabel: true });\r\n      item.innerHTML = `${adapter.icon.replace(\"<svg\", \"<svg data-stdg-icon-16\")}<span>${adapter.label}</span>`;\r\n      item.addEventListener(\"click\", (event) => {\r\n        event.stopPropagation();\r\n        this.onAdd(adapter.type);\r\n        this.closeAddPanel();\r\n      });\r\n      this.addGridList.appendChild(item);\r\n    }\r\n  }\r\n\r\n  private createLayoutPanel(): HTMLDivElement {\r\n    const panel = makePanel({ \"data-panel\": \"layout\" });\r\n    const header = makePanelHeader();\r\n\r\n    this.layoutAddButton = makeIconButton({\r\n      icon: \"plus\",\r\n      label: \"Add Layout Guide\",\r\n      modifiers: [\"toggle\", \"left\"],\r\n      attrs: { \"data-active\": \"false\" },\r\n    });\r\n    this.layoutAddButton.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      this.onAddLayout();\r\n    });\r\n\r\n    const closeButton = makeIconButton({\r\n      icon: \"close\",\r\n      label: \"Close panel\",\r\n      modifiers: [\"right\"],\r\n    });\r\n    closeButton.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      this.closeLayoutPanel();\r\n    });\r\n\r\n    header.appendChild(this.layoutAddButton);\r\n    header.appendChild(closeButton);\r\n\r\n    this.layoutSettingsList = makePanelContent();\r\n\r\n    this.layoutIOActions = makePanelContent({ \"data-stdg-panel-content-50\": \"\" });\r\n\r\n    const exportButton = makePanelButton({\r\n      icon: \"export\",\r\n      label: \"Export\",\r\n      withLabel: true,\r\n      attrs: { \"data-io\": \"export\" },\r\n    });\r\n    exportButton.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      this.onExport();\r\n    });\r\n\r\n    const importButton = makePanelButton({\r\n      icon: \"import\",\r\n      label: \"Import\",\r\n      withLabel: true,\r\n      attrs: { \"data-io\": \"import\" },\r\n    });\r\n    importButton.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      this.onImport();\r\n    });\r\n\r\n    this.layoutIOActions.appendChild(exportButton);\r\n    this.layoutIOActions.appendChild(importButton);\r\n\r\n    const hr = document.createElement(\"span\");\r\n    hr.setAttribute(\"data-stdg-panel-hr\", \"\");\r\n\r\n    panel.appendChild(header);\r\n    panel.appendChild(this.layoutSettingsList);\r\n    panel.appendChild(hr);\r\n    panel.appendChild(this.layoutIOActions);\r\n    return panel;\r\n  }\r\n\r\n  private createDetailPanel(): HTMLDivElement {\r\n    const panel = makePanel({ \"data-panel\": \"detail\" });\r\n    const header = makePanelHeader();\r\n\r\n    this.detailIcon = document.createElement(\"span\");\r\n    this.detailIcon.setAttribute(\"data-stdg-holder-icon-16\", \"\");\r\n    this.detailIcon.setAttribute(\"data-stdg-button-left\", \"\");\r\n\r\n    this.detailTitle = document.createElement(\"span\");\r\n    this.detailTitle.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      this.startDetailRename();\r\n    });\r\n\r\n    const closeButton = makeIconButton({\r\n      icon: \"close\",\r\n      label: \"Close detail panel\",\r\n      modifiers: [\"right\"],\r\n    });\r\n    closeButton.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      this.closeDetailPanel();\r\n    });\r\n\r\n    header.appendChild(this.detailIcon);\r\n    header.appendChild(this.detailTitle);\r\n    header.appendChild(closeButton);\r\n\r\n    this.detailContent = document.createElement(\"div\");\r\n    this.detailContent.setAttribute(\"data-string-dev-detail-body\", \"\");\r\n\r\n    panel.appendChild(header);\r\n    panel.appendChild(this.detailContent);\r\n    return panel;\r\n  }\r\n  private renderLayoutChips(): void {\r\n    this.layoutChipTabs.innerHTML = \"\";\r\n    const activateChipLayout = (layoutId: string) => {\r\n      this.selectedLayoutId = layoutId;\r\n      this.renderLayoutChips();\r\n      this.renderLayoutSettings();\r\n    };\r\n\r\n    // Render S → XL order (smallest first, so reverse the descending array)\r\n    [...this.layouts].reverse().forEach((layout) => {\r\n      const chip = makePanelButton({ icon: \"\", label: `Select ${layout.label} layout` });\r\n      chip.innerHTML = `<span>${layout.label}</span>`;\r\n      chip.setAttribute(\"data-active\", String(layout.id === this.selectedLayoutId));\r\n      chip.setAttribute(\"data-resolved\", String(layout.id === this.resolvedLayoutId));\r\n      chip.setAttribute(\"data-mode\", layout.label);\r\n      chip.addEventListener(\"click\", (event) => {\r\n        event.stopPropagation();\r\n        activateChipLayout(layout.id);\r\n        this.onSelectLayout(layout.id);\r\n      });\r\n      this.layoutChipTabs.appendChild(chip);\r\n    });\r\n    this.layoutSettingsToggle.setAttribute(\"data-active\", String(this.isLayoutSettingsOpen));\r\n  }\r\n\r\n  private renderLayoutSettings(): void {\r\n    this.layoutSettingsList.innerHTML = \"\";\r\n    this.layoutAddButton.style.display = this.layouts.length >= MAX_LAYOUTS ? \"none\" : \"\";\r\n    const { breakpointsRow, inputField } = this.createBreakpointWidget();\r\n    this.layoutSettingsList.appendChild(breakpointsRow);\r\n    this.layoutSettingsList.appendChild(inputField);\r\n  }\r\n\r\n  private createBreakpointWidget(): { breakpointsRow: HTMLDivElement; inputField: HTMLDivElement } {\r\n    const orderedLayouts = [...this.layouts].reverse(); // S first\r\n    const canDelete = orderedLayouts.length > MIN_LAYOUTS;\r\n\r\n    const breakpointsRow = document.createElement(\"div\");\r\n    breakpointsRow.setAttribute(\"data-stdg-panel-breakpoints\", \"\");\r\n\r\n    const inputField = document.createElement(\"div\");\r\n    inputField.setAttribute(\"data-stdg-panel-field\", \"\");\r\n\r\n    const inputId = `st-dg-break-${Date.now()}`;\r\n\r\n    const fieldIconWrap = document.createElement(\"span\");\r\n    fieldIconWrap.innerHTML = resolveDevtoolsIcon(16, \"break\", \"second\");\r\n\r\n    const editorInput = document.createElement(\"input\");\r\n    editorInput.id = inputId;\r\n    editorInput.type = \"number\";\r\n    editorInput.inputMode = \"numeric\";\r\n    editorInput.step = \"1\";\r\n    editorInput.min = \"1\";\r\n    editorInput.setAttribute(\"data-stdg-input\", \"\");\r\n\r\n    const pxLabel = document.createElement(\"label\");\r\n    pxLabel.htmlFor = inputId;\r\n    pxLabel.setAttribute(\"data-stdg-field-input-disable\", \"\");\r\n    pxLabel.textContent = \"px\";\r\n\r\n    inputField.appendChild(fieldIconWrap);\r\n    inputField.appendChild(editorInput);\r\n    inputField.appendChild(pxLabel);\r\n\r\n    let activeLayoutId: string | null = null;\r\n    let activeMarkerEl: HTMLButtonElement | null = null;\r\n    let activeValue = 0;\r\n\r\n    const setActive = (\r\n      layoutId: string,\r\n      currentValue: number,\r\n      markerEl: HTMLButtonElement,\r\n      focusInput = false,\r\n    ) => {\r\n      activeMarkerEl?.setAttribute(\"data-active\", \"false\");\r\n      activeLayoutId = layoutId;\r\n      activeMarkerEl = markerEl;\r\n      activeValue = currentValue;\r\n      this.selectedBreakpointLayoutId = layoutId;\r\n      markerEl.setAttribute(\"data-active\", \"true\");\r\n      editorInput.value = String(currentValue);\r\n      if (focusInput) {\r\n        editorInput.focus();\r\n        editorInput.select();\r\n      }\r\n    };\r\n\r\n    const commitEditor = () => {\r\n      if (!activeLayoutId) return;\r\n      if (!editorInput.isConnected) return;\r\n      const parsed = Number.parseInt(editorInput.value, 10);\r\n      if (Number.isFinite(parsed) && parsed >= 0) {\r\n        if (parsed === activeValue) return;\r\n        activeValue = parsed;\r\n        this.onUpdateLayoutMinWidth(activeLayoutId, parsed);\r\n      } else {\r\n        editorInput.value = String(activeValue);\r\n      }\r\n    };\r\n\r\n    editorInput.addEventListener(\"keydown\", (event) => {\r\n      event.stopPropagation();\r\n      if (event.key === \"Enter\") {\r\n        commitEditor();\r\n        return;\r\n      }\r\n      if (event.key === \"Escape\") {\r\n        editorInput.value = String(activeValue);\r\n        editorInput.blur();\r\n      }\r\n    });\r\n    editorInput.addEventListener(\"blur\", () => requestAnimationFrame(commitEditor));\r\n    editorInput.addEventListener(\"click\", (event) => event.stopPropagation());\r\n\r\n    let initialMarker: { layoutId: string; value: number; el: HTMLButtonElement } | null = null;\r\n\r\n    orderedLayouts.forEach((layout, index) => {\r\n      const segmentDiv = document.createElement(\"div\");\r\n      segmentDiv.setAttribute(\"data-stdg-panel-breakpoint-value\", \"\");\r\n\r\n      const labelSpan = document.createElement(\"span\");\r\n      labelSpan.textContent = layout.label;\r\n      segmentDiv.appendChild(labelSpan);\r\n\r\n      if (canDelete && index >= MIN_LAYOUTS) {\r\n        const deleteBtn = makeDeleteButton(`Remove ${layout.label} layout`);\r\n        deleteBtn.addEventListener(\"pointerdown\", (event) => event.stopPropagation());\r\n        deleteBtn.addEventListener(\"click\", (event) => {\r\n          event.preventDefault();\r\n          event.stopPropagation();\r\n          if (this.layouts.length > MIN_LAYOUTS) this.onRemoveLayout(layout.id);\r\n        });\r\n        segmentDiv.appendChild(deleteBtn);\r\n      }\r\n\r\n      breakpointsRow.appendChild(segmentDiv);\r\n\r\n      if (index < orderedLayouts.length - 1) {\r\n        const largerLayout = orderedLayouts[index + 1];\r\n        const marker = document.createElement(\"button\");\r\n        marker.type = \"button\";\r\n        marker.setAttribute(\"data-stdg-button\", \"\");\r\n        marker.setAttribute(\"data-stdg-panel-breakpoint-marker\", \"\");\r\n        marker.setAttribute(\"data-active\", \"false\");\r\n        marker.setAttribute(\"aria-label\", `Edit ${largerLayout.label} breakpoint`);\r\n\r\n        const markerSpan = document.createElement(\"span\");\r\n        markerSpan.textContent = String(largerLayout.minWidth);\r\n        marker.appendChild(markerSpan);\r\n\r\n        marker.addEventListener(\"click\", (event) => {\r\n          event.stopPropagation();\r\n          setActive(largerLayout.id, largerLayout.minWidth, marker, true);\r\n        });\r\n\r\n        breakpointsRow.appendChild(marker);\r\n\r\n        if (\r\n          this.selectedBreakpointLayoutId === largerLayout.id ||\r\n          (initialMarker === null && this.selectedBreakpointLayoutId === null)\r\n        ) {\r\n          initialMarker = { layoutId: largerLayout.id, value: largerLayout.minWidth, el: marker };\r\n        }\r\n      }\r\n    });\r\n\r\n    if (initialMarker !== null) {\r\n      const m = initialMarker as { layoutId: string; value: number; el: HTMLButtonElement };\r\n      setActive(m.layoutId, m.value, m.el);\r\n    }\r\n\r\n    return { breakpointsRow, inputField };\r\n  }\r\n\r\n  private syncChipRowStates(): void {\r\n    const chips = this.layoutChipTabs.querySelectorAll(\"[data-stdg-panel-button][data-mode]\");\r\n    chips.forEach((chip) => {\r\n      const mode = chip.getAttribute(\"data-mode\");\r\n      const layout = this.layouts.find((l) => l.label === mode);\r\n      if (!layout) return;\r\n      chip.setAttribute(\"data-active\", String(layout.id === this.selectedLayoutId));\r\n      chip.setAttribute(\"data-resolved\", String(layout.id === this.resolvedLayoutId));\r\n    });\r\n  }\r\n\r\n  private renderList(): void {\r\n    while (this.addGuideButton.nextSibling) {\r\n      this.listContainer.removeChild(this.addGuideButton.nextSibling);\r\n    }\r\n    for (const instance of this.instances) {\r\n      const adapter = this.adapterRegistry.get(instance.type);\r\n      if (!adapter) continue;\r\n      const item = document.createElement(\"div\");\r\n      item.setAttribute(\"data-stdg-panel-list-item\", \"\");\r\n      item.setAttribute(\"data-stdg-button\", \"\");\r\n      item.setAttribute(\"data-stdg-button-toggle\", \"\");\r\n      item.setAttribute(\"data-active\", String(instance.id === this.selectedInstanceId));\r\n      item.innerHTML = `${resolveDevtoolsIcon(16, \"grab\", \"second\")}${adapter.icon.replace(\"<svg\", \"<svg data-stdg-icon-16\")}<span>${instance.name?.trim() || adapter.label}</span>`;\r\n      const toggle = this.createToggle(instance.visible, () => this.onToggle(instance.id));\r\n      const deleteButton = makeDeleteButton(`Remove ${instance.name?.trim() || \"instance\"}`);\r\n      deleteButton.addEventListener(\"click\", (event) => {\r\n        event.stopPropagation();\r\n        if (this.selectedInstanceId === instance.id) this.closeDetailPanel();\r\n        this.onRemove(instance.id);\r\n      });\r\n      item.appendChild(toggle);\r\n      item.appendChild(deleteButton);\r\n      item.addEventListener(\"click\", () => {\r\n        if (this.selectedInstanceId === instance.id) this.closeDetailPanel();\r\n        else this.selectInstance(instance.id);\r\n      });\r\n\r\n      // Drag-and-drop reorder\r\n      item.setAttribute(\"draggable\", \"true\");\r\n      item.addEventListener(\"dragstart\", (event) => {\r\n        event.stopPropagation();\r\n        event.dataTransfer?.setData(\"text/plain\", instance.id);\r\n        item.setAttribute(\"data-dragging\", \"true\");\r\n      });\r\n      item.addEventListener(\"dragend\", () => {\r\n        item.removeAttribute(\"data-dragging\");\r\n        this.listContainer\r\n          .querySelectorAll<HTMLElement>(\"[data-drag-over]\")\r\n          .forEach((el) => el.removeAttribute(\"data-drag-over\"));\r\n      });\r\n      item.addEventListener(\"dragover\", (event) => {\r\n        event.preventDefault();\r\n        event.stopPropagation();\r\n        const rect = item.getBoundingClientRect();\r\n        const placement = event.clientY < rect.top + rect.height / 2 ? \"before\" : \"after\";\r\n        this.listContainer\r\n          .querySelectorAll<HTMLElement>(\"[data-drag-over]\")\r\n          .forEach((el) => el.removeAttribute(\"data-drag-over\"));\r\n        item.setAttribute(\"data-drag-over\", placement);\r\n      });\r\n      item.addEventListener(\"dragleave\", (event) => {\r\n        if (!item.contains(event.relatedTarget as Node)) {\r\n          item.removeAttribute(\"data-drag-over\");\r\n        }\r\n      });\r\n      item.addEventListener(\"drop\", (event) => {\r\n        event.preventDefault();\r\n        event.stopPropagation();\r\n        const draggedId = event.dataTransfer?.getData(\"text/plain\");\r\n        item.removeAttribute(\"data-drag-over\");\r\n        if (!draggedId || draggedId === instance.id) return;\r\n        const rect = item.getBoundingClientRect();\r\n        const placement: DropPlacement =\r\n          event.clientY < rect.top + rect.height / 2 ? \"before\" : \"after\";\r\n        this.onReorder(draggedId, instance.id, placement);\r\n      });\r\n\r\n      this.listContainer.appendChild(item);\r\n    }\r\n    this.addGuideButton.setAttribute(\"data-empty\", String(this.instances.length === 0));\r\n    const hasInstances = this.instances.length > 0;\r\n    this.addGuideButton.style.display = hasInstances ? \"none\" : \"\";\r\n    this.headerAddButton.style.display = hasInstances ? \"\" : \"none\";\r\n  }\r\n\r\n  private renderDetailPanel(): void {\r\n    if (!this.selectedInstanceId) {\r\n      this.hideDetailPanelUI();\r\n      return;\r\n    }\r\n    const instance = this.instances.find((entry) => entry.id === this.selectedInstanceId);\r\n    if (!instance) {\r\n      this.clearSelection();\r\n      return;\r\n    }\r\n    const adapter = this.adapterRegistry.get(instance.type);\r\n    if (!adapter) {\r\n      this.clearSelection();\r\n      return;\r\n    }\r\n    if (this.detailIcon) {\r\n      this.detailIcon.innerHTML = adapter.icon.replace(\r\n        \"<svg\",\r\n        \"<svg data-stdg-icon-16 data-stdg-icon-second\",\r\n      );\r\n    }\r\n    if (this.detailTitle) this.detailTitle.textContent = instance.name?.trim() || adapter.label;\r\n    this.detailBuilder?.destroy();\r\n    this.detailBuilder = new GridUIBuilder();\r\n    const settingsEl = this.detailBuilder.build(\r\n      adapter.getUISchema(),\r\n      instance.settings,\r\n      (key, value) => this.onSettingChange(instance.id, key, value),\r\n    );\r\n    while (this.detailContent.firstChild) {\r\n      this.detailContent.removeChild(this.detailContent.firstChild);\r\n    }\r\n    this.detailContent.appendChild(settingsEl);\r\n    this.detailPanel.setAttribute(\"data-open\", \"true\");\r\n    this.alignDetailPanel();\r\n    this.syncPanelPlacement();\r\n  }\r\n\r\n  private createToggle(checked: boolean, onChange: () => void): HTMLLabelElement {\r\n    const label = document.createElement(\"label\");\r\n    label.setAttribute(\"data-stdg-toggle\", \"\");\r\n    label.setAttribute(\"data-checked\", String(checked));\r\n    const input = document.createElement(\"input\");\r\n    input.type = \"checkbox\";\r\n    input.checked = checked;\r\n    input.setAttribute(\"data-stdg-toggle-input\", \"\");\r\n    input.addEventListener(\"change\", (event) => {\r\n      event.stopPropagation();\r\n      onChange();\r\n    });\r\n    const knob = document.createElement(\"span\");\r\n    knob.setAttribute(\"data-stdg-toggle-knob\", \"\");\r\n    label.addEventListener(\"click\", (event) => event.stopPropagation());\r\n    label.appendChild(input);\r\n    label.appendChild(knob);\r\n    return label;\r\n  }\r\n\r\n  private startDetailRename(): void {\r\n    if (!this.selectedInstanceId || !this.detailTitle) return;\r\n    const instance = this.instances.find((entry) => entry.id === this.selectedInstanceId);\r\n    if (!instance) return;\r\n    const adapter = this.adapterRegistry.get(instance.type);\r\n    if (!adapter) return;\r\n    const currentName = instance.name?.trim() || adapter.label;\r\n    const parent = this.detailTitle.parentElement;\r\n    if (!parent) return;\r\n    const input = document.createElement(\"input\");\r\n    input.setAttribute(\"data-stdg-input\", \"\");\r\n    input.type = \"text\";\r\n    input.value = currentName;\r\n    const commit = () => {\r\n      const nextName = input.value.trim();\r\n      if (nextName !== currentName) this.onRenameInstance(instance.id, nextName);\r\n      if (parent.contains(input)) parent.replaceChild(this.detailTitle!, input);\r\n    };\r\n    input.addEventListener(\"blur\", commit);\r\n    input.addEventListener(\"keydown\", (event) => {\r\n      if (event.key === \"Enter\") input.blur();\r\n      if (event.key === \"Escape\") {\r\n        input.value = currentName;\r\n        input.blur();\r\n      }\r\n    });\r\n    input.addEventListener(\"click\", (event) => event.stopPropagation());\r\n    input.addEventListener(\"pointerdown\", (event) => event.stopPropagation());\r\n    parent.replaceChild(input, this.detailTitle);\r\n    input.focus();\r\n    input.select();\r\n  }\r\n\r\n  private startLayoutTitleRename(): void {\r\n    this.layoutTitle.select();\r\n  }\r\n\r\n  private openAddPanel(): void {\r\n    this.isAddPanelOpen = true;\r\n    this.closeLayoutPanel();\r\n    this.clearSelection();\r\n    this.renderAddPanelList();\r\n    this.addPanel.setAttribute(\"data-open\", \"true\");\r\n    this.syncPanelPlacement();\r\n  }\r\n\r\n  private closeAddPanel(): void {\r\n    this.isAddPanelOpen = false;\r\n    this.addPanel.setAttribute(\"data-open\", \"false\");\r\n    this.syncPanelPlacement();\r\n  }\r\n\r\n  private openLayoutPanel(): void {\r\n    this.isLayoutSettingsOpen = true;\r\n    this.closeAddPanel();\r\n    this.clearSelection();\r\n    this.layoutPanel.setAttribute(\"data-open\", \"true\");\r\n    this.renderLayoutChips();\r\n    this.alignLayoutPanel();\r\n    this.syncPanelPlacement();\r\n    this.onLayoutPanelOpen();\r\n  }\r\n\r\n  private closeLayoutPanel(): void {\r\n    this.isLayoutSettingsOpen = false;\r\n    this.layoutPanel.setAttribute(\"data-open\", \"false\");\r\n    this.renderLayoutChips();\r\n    this.syncPanelPlacement();\r\n    this.onLayoutPanelClose();\r\n  }\r\n\r\n  private alignLayoutPanel(): void {\r\n    if (this.isMobilePanelMode()) {\r\n      this.layoutPanel.style.removeProperty(\"top\");\r\n      return;\r\n    }\r\n\r\n    if (this.hudRoot.getAttribute(\"data-target-id\") === \"__global__\") {\r\n      this.layoutPanel.style.removeProperty(\"top\");\r\n      return;\r\n    }\r\n\r\n    const btnRect = this.layoutSettingsToggle.getBoundingClientRect();\r\n    const containerRect = this.panel.getBoundingClientRect();\r\n    this.layoutPanel.style.top = `${btnRect.top - containerRect.top}px`;\r\n  }\r\n\r\n  private selectInstance(instanceId: string): void {\r\n    this.selectedInstanceId = instanceId;\r\n    this.closeLayoutPanel();\r\n    this.closeAddPanel();\r\n    this.renderList();\r\n    this.renderDetailPanel();\r\n  }\r\n\r\n  private closeDetailPanel(): void {\r\n    this.clearSelection();\r\n    this.renderList();\r\n  }\r\n\r\n  private clearSelection(): void {\r\n    this.selectedInstanceId = null;\r\n    this.hideDetailPanelUI();\r\n  }\r\n\r\n  private hideDetailPanelUI(): void {\r\n    const builder = this.detailBuilder;\r\n    this.detailBuilder = null;\r\n    this.detailPanel.setAttribute(\"data-open\", \"false\");\r\n    this.syncPanelPlacement();\r\n    window.setTimeout(() => {\r\n      if (this.detailPanel.getAttribute(\"data-open\") === \"false\") {\r\n        builder?.destroy();\r\n        this.detailContent.innerHTML = \"\";\r\n        this.detailPanel.style.removeProperty(\"top\");\r\n      }\r\n    }, 220);\r\n  }\r\n\r\n  private alignDetailPanel(): void {\r\n    if (this.isMobilePanelMode()) {\r\n      this.detailPanel.style.removeProperty(\"top\");\r\n      return;\r\n    }\r\n\r\n    if (this.hudRoot.getAttribute(\"data-target-id\") === \"__global__\") {\r\n      this.detailPanel.style.removeProperty(\"top\");\r\n      return;\r\n    }\r\n\r\n    const selectedItem = this.listContainer.querySelector(\r\n      '[data-stdg-panel-list-item][data-active=\"true\"]',\r\n    ) as HTMLElement | null;\r\n    if (!selectedItem) return;\r\n    const itemRect = selectedItem.getBoundingClientRect();\r\n    const containerRect = this.panel.getBoundingClientRect();\r\n    this.detailPanel.style.top = `${itemRect.top - containerRect.top}px`;\r\n  }\r\n\r\n  public show(): void {\r\n    this.isOpen = true;\r\n    this.panel.setAttribute(\"data-open\", \"true\");\r\n    this.trigger.setAttribute(\"data-active\", \"true\");\r\n    this.trigger.setAttribute(\"aria-expanded\", \"true\");\r\n    this.syncPanelPlacement();\r\n    this.onHUDOpen();\r\n  }\r\n\r\n  public hide(): void {\r\n    this.isOpen = false;\r\n    this.panel.setAttribute(\"data-open\", \"false\");\r\n    this.closeAddPanel();\r\n    this.closeDetailPanel();\r\n    this.closeLayoutPanel();\r\n    this.trigger.setAttribute(\"data-active\", \"false\");\r\n    this.trigger.setAttribute(\"aria-expanded\", \"false\");\r\n    this.syncPanelPlacement();\r\n    this.onHUDClose();\r\n  }\r\n\r\n  public toggle(): void {\r\n    if (!this.enabled) return;\r\n    if (this.isOpen) this.hide();\r\n    else this.show();\r\n  }\r\n\r\n  private isMobilePanelMode(): boolean {\r\n    if (typeof window === \"undefined\") return false;\r\n    return window.matchMedia(\"(max-width: 1024px), (pointer: coarse)\").matches;\r\n  }\r\n\r\n  private syncPanelPlacement(): void {\r\n    const mobileMode = this.isMobilePanelMode();\r\n    if (!mobileMode) {\r\n      if (this.panelInBody) {\r\n        this.panel.removeAttribute(\"data-mobile-sheet\");\r\n        this.panel.style.removeProperty(\"position\");\r\n        this.panel.style.removeProperty(\"bottom\");\r\n        this.hudRoot.appendChild(this.panel);\r\n        this.panelInBody = false;\r\n      }\r\n      this.hudRoot.setAttribute(\"data-mobile-sheet\", \"false\");\r\n      this.panel.style.removeProperty(\"left\");\r\n      this.panel.style.removeProperty(\"top\");\r\n      this.panel.style.removeProperty(\"width\");\r\n      this.panel.style.removeProperty(\"height\");\r\n      this.panel.style.removeProperty(\"max-height\");\r\n      return;\r\n    }\r\n\r\n    if (!this.isOpen) {\r\n      return;\r\n    }\r\n\r\n    if (!this.panelInBody) {\r\n      (document.body ?? document.documentElement).appendChild(this.panel);\r\n      this.panelInBody = true;\r\n    }\r\n\r\n    const viewport = window.visualViewport;\r\n    const viewportWidth = viewport?.width ?? window.innerWidth;\r\n    const viewportHeight = viewport?.height ?? window.innerHeight;\r\n    const availableWidth = Math.max(220, viewportWidth - MOBILE_PANEL_MARGIN * 2);\r\n    const availableHeight = Math.max(120, viewportHeight - MOBILE_PANEL_MARGIN * 2);\r\n    const width = Math.min(MOBILE_PANEL_MAX_WIDTH, availableWidth);\r\n    const maxHeight = Math.min(MOBILE_PANEL_MAX_HEIGHT, availableHeight);\r\n    const left = Math.round((viewport?.offsetLeft ?? 0) + (viewportWidth - width) / 2);\r\n\r\n    this.hudRoot.setAttribute(\"data-mobile-sheet\", \"true\");\r\n    this.panel.setAttribute(\"data-mobile-sheet\", \"true\");\r\n    this.panel.style.position = \"fixed\";\r\n    this.panel.style.left = `${left}px`;\r\n    this.panel.style.bottom = `${MOBILE_PANEL_MARGIN}px`;\r\n    this.panel.style.removeProperty(\"top\");\r\n    this.panel.style.width = `${Math.round(width)}px`;\r\n    this.panel.style.maxHeight = `${Math.round(maxHeight)}px`;\r\n    this.panel.style.removeProperty(\"height\");\r\n    this.addPanel.style.removeProperty(\"top\");\r\n    this.layoutPanel.style.removeProperty(\"top\");\r\n    this.detailPanel.style.removeProperty(\"top\");\r\n  }\r\n\r\n  private onDocumentPointerDown(event: PointerEvent): void {\r\n    if (!this.isOpen) return;\r\n    const target = event.target;\r\n    if (!(target instanceof Node)) return;\r\n    if (\r\n      this.panel.contains(target) ||\r\n      this.trigger.contains(target) ||\r\n      this.addPanel.contains(target) ||\r\n      this.layoutPanel.contains(target) ||\r\n      this.detailPanel.contains(target)\r\n    ) {\r\n      return;\r\n    }\r\n    this.hide();\r\n  }\r\n}\r\n","import type { GridAdapter } from \"./adapters/GridAdapter\";\nimport type { GridLayout, GridLayoutLabel } from \"./models/GridInstance\";\nimport {\n  GRID_LAYOUT_LABELS,\n  createGridInstanceId,\n  normalizeGridLayoutMinWidth,\n} from \"./models/GridInstance\";\n\nexport interface GridExportInstance {\n  id: string;\n  type: string;\n  visible: boolean;\n  name?: string;\n  settings: Record<string, any>;\n}\n\nexport interface GridExportLayout {\n  id: string;\n  label: GridLayoutLabel;\n  minWidth: number;\n  grids: GridExportInstance[];\n}\n\nexport interface GridExportData {\n  v: 2;\n  source: \"StringDevLayout\";\n  selectedLayout: string;\n  layouts: GridExportLayout[];\n}\n\nexport class GridSerializer {\n  static readonly VERSION = 2 as const;\n\n  static serialize(layouts: GridLayout[], selectedLayoutId: string): GridExportData {\n    return {\n      v: this.VERSION,\n      source: \"StringDevLayout\",\n      selectedLayout: selectedLayoutId,\n      layouts: layouts.map((layout) => ({\n        id: layout.id,\n        label: layout.label,\n        minWidth: layout.minWidth,\n        grids: layout.instances.map((instance) => ({\n          id: instance.id,\n          type: instance.type,\n          visible: instance.visible,\n          ...(instance.name !== undefined ? { name: instance.name } : {}),\n          settings: { ...instance.settings },\n        })),\n      })),\n    };\n  }\n\n  static deserialize(\n    data: unknown,\n    adapterRegistry: Map<string, GridAdapter>,\n  ): { layouts: GridLayout[]; selectedLayoutId: string } | null {\n    if (!data || typeof data !== \"object\") {\n      return null;\n    }\n\n    const object = data as Record<string, unknown>;\n    const version = object[\"v\"];\n    const source = object[\"source\"];\n    if ((source !== \"StringDevLayout\" && source !== \"StringGrid\") || (version !== 1 && version !== 2)) {\n      return null;\n    }\n    if (!Array.isArray(object[\"layouts\"])) {\n      return null;\n    }\n\n    const layouts: GridLayout[] = (object[\"layouts\"] as unknown[])\n      .filter(\n        (layout): layout is Record<string, unknown> =>\n          !!layout &&\n          typeof layout === \"object\" &&\n          typeof layout[\"id\"] === \"string\",\n      )\n      .map((layout, index) => ({\n        id: layout[\"id\"] as string,\n        label: (GRID_LAYOUT_LABELS.includes(layout[\"label\"] as GridLayoutLabel)\n          ? layout[\"label\"]\n          : \"S\") as GridLayoutLabel,\n        minWidth: this.resolveImportedMinWidth(layout[\"minWidth\"], index),\n        instances: (Array.isArray(layout[\"grids\"]) ? layout[\"grids\"] : [])\n          .filter(\n            (grid): grid is Record<string, unknown> =>\n              !!grid &&\n              typeof grid === \"object\" &&\n              typeof grid[\"type\"] === \"string\" &&\n              adapterRegistry.has(grid[\"type\"] as string),\n          )\n          .map((grid) => {\n            const type = grid[\"type\"] as string;\n            const adapter = adapterRegistry.get(type)!;\n            return {\n              id: typeof grid[\"id\"] === \"string\" ? grid[\"id\"] : createGridInstanceId(),\n              type,\n              visible: grid[\"visible\"] !== false,\n              ...(typeof grid[\"name\"] === \"string\" && grid[\"name\"]\n                ? { name: grid[\"name\"] }\n                : {}),\n              settings: {\n                ...adapter.getDefaults(),\n                ...(grid[\"settings\"] &&\n                typeof grid[\"settings\"] === \"object\" &&\n                !Array.isArray(grid[\"settings\"])\n                  ? (grid[\"settings\"] as Record<string, unknown>)\n                  : {}),\n              },\n            };\n          }),\n      }));\n\n    if (layouts.length === 0) {\n      return null;\n    }\n\n    layouts.sort((left, right) => right.minWidth - left.minWidth);\n\n    const rawSelected =\n      typeof object[\"selectedLayout\"] === \"string\"\n        ? object[\"selectedLayout\"]\n        : typeof object[\"activeLayout\"] === \"string\"\n          ? object[\"activeLayout\"]\n          : layouts[0].id;\n\n    const selectedLayoutId = layouts.some((layout) => layout.id === rawSelected)\n      ? rawSelected\n      : layouts[0].id;\n\n    return { layouts, selectedLayoutId };\n  }\n\n  static toFile(filename: string, data: GridExportData): void {\n    const json = JSON.stringify(data, null, 2);\n    const blob = new Blob([json], { type: \"application/json\" });\n    const url = URL.createObjectURL(blob);\n    const link = document.createElement(\"a\");\n    link.href = url;\n    link.download = filename;\n    link.click();\n    URL.revokeObjectURL(url);\n  }\n\n  static fromFile(): Promise<unknown> {\n    return new Promise<unknown>((resolve, reject) => {\n      const input = document.createElement(\"input\");\n      input.type = \"file\";\n      input.accept = \".json,application/json\";\n\n      const cleanup = () => input.remove();\n\n      input.addEventListener(\"change\", () => {\n        const file = input.files?.[0];\n        if (!file) {\n          cleanup();\n          reject(new Error(\"No file selected\"));\n          return;\n        }\n\n        const reader = new FileReader();\n        reader.onload = () => {\n          cleanup();\n          try {\n            resolve(JSON.parse(reader.result as string));\n          } catch {\n            reject(new Error(\"Invalid JSON\"));\n          }\n        };\n        reader.onerror = () => {\n          cleanup();\n          reject(new Error(\"File read error\"));\n        };\n        reader.readAsText(file);\n      });\n\n      input.addEventListener(\"cancel\", () => {\n        cleanup();\n        reject(new Error(\"Cancelled\"));\n      });\n\n      document.body.appendChild(input);\n      input.click();\n    });\n  }\n\n  private static resolveImportedMinWidth(value: unknown, index: number): number {\n    if (typeof value === \"number\" && Number.isFinite(value)) {\n      return normalizeGridLayoutMinWidth(value);\n    }\n    // Fallback defaults: index 0=largest, descending\n    const defaults = [1280, 1024, 768, 0];\n    return defaults[index] ?? Math.max(0, 1280 - index * 256);\n  }\n}\n","import { StringDevUIFieldDescriptor } from \"../../core/ui/StringDevUISchema\";\r\n\r\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\r\n\r\n/**\r\n * Abstract base class for all grid adapters.\r\n *\r\n * Each adapter is a self-contained unit that:\r\n * - Declares its own default settings\r\n * - Describes its UI schema for the settings panel\r\n * - Renders itself into an SVG overlay\r\n *\r\n * To create a new grid type, extend this class and implement\r\n * all abstract members. The system handles everything else.\r\n */\r\nexport abstract class GridAdapter {\r\n  /** Unique type key used for serialization and registry lookup */\r\n  abstract readonly type: string;\r\n\r\n  /** Human-readable label shown in the HUD menu */\r\n  abstract readonly label: string;\r\n\r\n  /** SVG icon string (inline SVG markup) */\r\n  abstract readonly icon: string;\r\n\r\n  /**\r\n   * Returns the default settings for this adapter.\r\n   * These are used when a new grid instance is created.\r\n   */\r\n  abstract getDefaults(): Record<string, any>;\r\n\r\n  /**\r\n   * Returns the UI field descriptors that GridUIBuilder\r\n   * uses to construct the settings panel.\r\n   */\r\n  abstract getUISchema(): StringDevUIFieldDescriptor[];\r\n\r\n  /**\r\n   * Renders the grid into the given SVG element.\r\n   *\r\n   * @param svg    The SVG overlay element (same size as target)\r\n   * @param width  Element width in px\r\n   * @param height Element height in px\r\n   * @param settings  Current settings for this instance\r\n   */\r\n  abstract render(\r\n    svg: SVGSVGElement,\r\n    width: number,\r\n    height: number,\r\n    settings: Record<string, any>,\r\n  ): void;\r\n\r\n  /**\r\n   * Removes all elements previously rendered by this adapter.\r\n   * Default implementation clears the adapter's group element.\r\n   */\r\n  clear(svg: SVGSVGElement, instanceId: string): void {\r\n    const group = svg.querySelector(`[data-grid-id=\"${instanceId}\"]`);\r\n    if (group) group.remove();\r\n  }\r\n\r\n  /**\r\n   * Creates or retrieves a <g> group element scoped to a grid instance.\r\n   * All rendering should happen inside this group for clean cleanup.\r\n   */\r\n  protected getGroup(svg: SVGSVGElement, instanceId: string): SVGGElement {\r\n    let group = svg.querySelector(\r\n      `[data-grid-id=\"${instanceId}\"]`,\r\n    ) as SVGGElement | null;\r\n    if (!group) {\r\n      group = document.createElementNS(SVG_NS, \"g\") as SVGGElement;\r\n      group.setAttribute(\"data-grid-id\", instanceId);\r\n      svg.appendChild(group);\r\n    }\r\n    return group;\r\n  }\r\n\r\n  /**\r\n   * Helper: creates an SVG line element.\r\n   */\r\n  protected createLine(\r\n    x1: number,\r\n    y1: number,\r\n    x2: number,\r\n    y2: number,\r\n    color: string,\r\n    opacity: number,\r\n    strokeWidth: number = 1,\r\n  ): SVGLineElement {\r\n    const line = document.createElementNS(SVG_NS, \"line\") as SVGLineElement;\r\n    line.setAttribute(\"data-string-grid-shape\", \"line\");\r\n    line.setAttribute(\"x1\", String(x1));\r\n    line.setAttribute(\"y1\", String(y1));\r\n    line.setAttribute(\"x2\", String(x2));\r\n    line.setAttribute(\"y2\", String(y2));\r\n    line.setAttribute(\"stroke\", color);\r\n    line.setAttribute(\"stroke-opacity\", String(opacity));\r\n    line.setAttribute(\"stroke-width\", String(strokeWidth));\r\n    return line;\r\n  }\r\n\r\n  /**\r\n   * Helper: creates an SVG rect element.\r\n   */\r\n  protected createRect(\r\n    x: number,\r\n    y: number,\r\n    width: number,\r\n    height: number,\r\n    fill: string,\r\n    opacity: number,\r\n  ): SVGRectElement {\r\n    const rect = document.createElementNS(SVG_NS, \"rect\") as SVGRectElement;\r\n    rect.setAttribute(\"data-string-grid-shape\", \"rect\");\r\n    rect.setAttribute(\"x\", String(x));\r\n    rect.setAttribute(\"y\", String(y));\r\n    rect.setAttribute(\"width\", String(width));\r\n    rect.setAttribute(\"height\", String(height));\r\n    rect.setAttribute(\"fill\", fill);\r\n    rect.setAttribute(\"fill-opacity\", String(opacity));\r\n    return rect;\r\n  }\r\n\r\n  /**\r\n   * Converts a value from the given unit to pixels.\r\n   *\r\n   * @param value     Raw numeric value\r\n   * @param unit      \"px\" | \"%\" | \"vw\" | \"vh\" | \"em\" | \"rem\"\r\n   * @param dimension Reference dimension (element width or height) for \"%\" mode\r\n   */\r\n  protected resolveUnit(\r\n    value: number,\r\n    unit: string,\r\n    dimension: number,\r\n    referenceElement?: Element | null,\r\n  ): number {\r\n    const rootFontSize =\r\n      parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;\r\n    const elementFontSize =\r\n      referenceElement instanceof Element\r\n        ? parseFloat(getComputedStyle(referenceElement).fontSize) || rootFontSize\r\n        : rootFontSize;\r\n\r\n    switch (unit) {\r\n      case \"%\":  return (value / 100) * dimension;\r\n      case \"vw\": return (value / 100) * window.innerWidth;\r\n      case \"vh\": return (value / 100) * window.innerHeight;\r\n      case \"em\": return value * elementFontSize;\r\n      case \"rem\": return value * rootFontSize;\r\n      default:   return value;\r\n    }\r\n  }\r\n\r\n  /**\r\n   * Helper: creates an SVG path element.\r\n   */\r\n  protected createPath(\r\n    d: string,\r\n    stroke: string,\r\n    opacity: number,\r\n    strokeWidth: number = 1,\r\n    fill: string = \"none\",\r\n  ): SVGPathElement {\r\n    const path = document.createElementNS(SVG_NS, \"path\") as SVGPathElement;\r\n    path.setAttribute(\"data-string-grid-shape\", \"path\");\r\n    path.setAttribute(\"d\", d);\r\n    path.setAttribute(\"stroke\", stroke);\r\n    path.setAttribute(\"stroke-opacity\", String(opacity));\r\n    path.setAttribute(\"stroke-width\", String(strokeWidth));\r\n    path.setAttribute(\"fill\", fill);\r\n    return path;\r\n  }\r\n}\r\n","import { StringDevUIFieldDescriptor as UIFieldDescriptor } from \"../../core/ui/StringDevUISchema\";\r\nimport { GridAdapter } from \"./GridAdapter\";\r\n\r\n/**\r\n * Column grid adapter.\r\n * Renders N evenly-spaced vertical columns with configurable gap and margin.\r\n * Classic tool for layout alignment (12-column, 16-column, etc.).\r\n */\r\nexport class ColumnsAdapter extends GridAdapter {\r\n  readonly type = \"columns\";\r\n  readonly label = \"Columns\";\r\n  readonly icon = `<svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"7\" y=\"3\" width=\"2\" height=\"10\" fill=\"currentColor\"/><rect x=\"3\" y=\"3\" width=\"2\" height=\"10\" fill=\"currentColor\"/><rect x=\"11\" y=\"3\" width=\"2\" height=\"10\" fill=\"currentColor\"/></svg>`;\r\n\r\n  private static readonly UNIT_OPTIONS = [\r\n    { value: \"px\", label: \"px\" },\r\n    { value: \"%\", label: \"%\" },\r\n    { value: \"vw\", label: \"vw\" },\r\n    { value: \"vh\", label: \"vh\" },\r\n    { value: \"em\", label: \"em\" },\r\n    { value: \"rem\", label: \"rem\" },\r\n  ] as const;\r\n\r\n  getDefaults(): Record<string, any> {\r\n    return {\r\n      count: 12,\r\n      gap: 20,\r\n      gapUnit: \"px\",\r\n      margin: 0,\r\n      marginUnit: \"px\",\r\n      color: \"#4a90e2\",\r\n      opacity: 0.15,\r\n      showLines: false,\r\n    };\r\n  }\r\n\r\n  getUISchema(): UIFieldDescriptor[] {\r\n    return [\r\n      { type: \"number\", key: \"count\", label: \"Columns\", default: 12, min: 1, max: 48, step: 1 },\r\n      {\r\n        type: \"range\",\r\n        key: \"gap\",\r\n        label: \"Gap\",\r\n        default: 20,\r\n        min: 0,\r\n        max: 100,\r\n        step: 1,\r\n        units: ColumnsAdapter.UNIT_OPTIONS,\r\n        defaultUnit: \"px\",\r\n      },\r\n      {\r\n        type: \"range\",\r\n        key: \"margin\",\r\n        label: \"Margin\",\r\n        default: 0,\r\n        min: 0,\r\n        max: 100,\r\n        step: 1,\r\n        units: ColumnsAdapter.UNIT_OPTIONS,\r\n        defaultUnit: \"px\",\r\n      },\r\n      { type: \"divider\" },\r\n      { type: \"color\", key: \"color\", label: \"Color\", default: \"#4a90e2\" },\r\n      {\r\n        type: \"range\",\r\n        key: \"opacity\",\r\n        label: \"Opacity\",\r\n        default: 0.15,\r\n        min: 0,\r\n        max: 1,\r\n        step: 0.01,\r\n        displayMultiplier: 100,\r\n        displayStep: 10,\r\n      },\r\n      { type: \"toggle\", key: \"showLines\", label: \"Lines only\", default: false },\r\n    ];\r\n  }\r\n\r\n  render(svg: SVGSVGElement, width: number, height: number, settings: Record<string, any>): void {\r\n    const group = this.getGroup(svg, settings.__instanceId);\r\n    const {\r\n      count,\r\n      gap: rawGap,\r\n      gapUnit,\r\n      margin: rawMargin,\r\n      marginUnit,\r\n      color,\r\n      opacity,\r\n      showLines,\r\n    } = settings;\r\n\r\n    const referenceElement = svg.parentElement;\r\n    const gap = this.resolveUnit(rawGap, gapUnit || \"px\", width, referenceElement);\r\n    const margin = this.resolveUnit(rawMargin, marginUnit || \"px\", width, referenceElement);\r\n\r\n    const availableWidth = width - margin * 2;\r\n    const totalGaps = (count - 1) * gap;\r\n    const columnWidth = (availableWidth - totalGaps) / count;\r\n\r\n    if (columnWidth <= 0) return;\r\n\r\n    for (let i = 0; i < count; i++) {\r\n      const x = margin + i * (columnWidth + gap);\r\n\r\n      if (showLines) {\r\n        group.appendChild(this.createLine(x, 0, x, height, color, opacity));\r\n        group.appendChild(\r\n          this.createLine(x + columnWidth, 0, x + columnWidth, height, color, opacity),\r\n        );\r\n      } else {\r\n        group.appendChild(this.createRect(x, 0, columnWidth, height, color, opacity));\r\n      }\r\n    }\r\n  }\r\n}\r\n","import { StringDevUIFieldDescriptor as UIFieldDescriptor } from \"../../core/ui/StringDevUISchema\";\r\nimport { GridAdapter } from \"./GridAdapter\";\r\n\r\n/**\r\n * Row grid adapter.\r\n * Renders horizontal rows by count or by size.\r\n * Useful for baseline grids and vertical rhythm verification.\r\n */\r\nexport class RowsAdapter extends GridAdapter {\r\n  readonly type = \"rows\";\r\n  readonly label = \"Rows\";\r\n  readonly icon = `<svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"3\" y=\"3\" width=\"10\" height=\"2\" fill=\"currentColor\"/><rect x=\"3\" y=\"7\" width=\"10\" height=\"2\" fill=\"currentColor\"/><rect x=\"3\" y=\"11\" width=\"10\" height=\"2\" fill=\"currentColor\"/></svg>`;\r\n\r\n  private static readonly UNIT_OPTIONS = [\r\n    { value: \"px\", label: \"px\" },\r\n    { value: \"%\", label: \"%\" },\r\n    { value: \"vh\", label: \"vh\" },\r\n    { value: \"vw\", label: \"vw\" },\r\n    { value: \"em\", label: \"em\" },\r\n    { value: \"rem\", label: \"rem\" },\r\n  ] as const;\r\n\r\n  getDefaults(): Record<string, any> {\r\n    return {\r\n      mode: \"count\",\r\n      count: 8,\r\n      size: 24,\r\n      sizeUnit: \"px\",\r\n      gap: 0,\r\n      gapUnit: \"px\",\r\n      margin: 0,\r\n      marginUnit: \"px\",\r\n      color: \"#e2784a\",\r\n      opacity: 0.2,\r\n      style: \"line\",\r\n    };\r\n  }\r\n\r\n  getUISchema(): UIFieldDescriptor[] {\r\n    return [\r\n      {\r\n        type: \"select\",\r\n        key: \"mode\",\r\n        label: \"Mode\",\r\n        default: \"count\",\r\n        options: [\r\n          { value: \"count\", label: \"By count\" },\r\n          { value: \"size\", label: \"By size\" },\r\n        ],\r\n      },\r\n      {\n        type: \"number\",\n        key: \"count\",\n        label: \"Rows\",\n        default: 8,\n        min: 1,\n        max: 48,\n        step: 1,\n        disabledWhen: { key: \"mode\", equals: \"size\" },\n      },\n      {\n        type: \"range\",\n        key: \"size\",\n        label: \"Size\",\n        default: 24,\n        min: 0,\r\n        max: 1200,\r\n        step: 1,\n        units: RowsAdapter.UNIT_OPTIONS,\n        defaultUnit: \"px\",\n        disabledWhen: { key: \"mode\", equals: \"count\" },\n      },\n      {\r\n        type: \"range\",\r\n        key: \"gap\",\r\n        label: \"Gap\",\r\n        default: 0,\r\n        min: 0,\r\n        max: 100,\r\n        step: 1,\r\n        units: RowsAdapter.UNIT_OPTIONS,\r\n        defaultUnit: \"px\",\r\n      },\r\n      {\r\n        type: \"range\",\r\n        key: \"margin\",\r\n        label: \"Margin\",\r\n        default: 0,\r\n        min: 0,\r\n        max: 100,\r\n        step: 1,\r\n        units: RowsAdapter.UNIT_OPTIONS,\r\n        defaultUnit: \"px\",\r\n      },\r\n      { type: \"divider\" },\r\n      { type: \"color\", key: \"color\", label: \"Color\", default: \"#e2784a\" },\r\n      {\r\n        type: \"range\",\r\n        key: \"opacity\",\r\n        label: \"Opacity\",\r\n        default: 0.2,\r\n        min: 0,\r\n        max: 1,\r\n        step: 0.01,\r\n        displayMultiplier: 100,\r\n        displayStep: 10,\r\n      },\r\n      {\r\n        type: \"select\",\r\n        key: \"style\",\r\n        label: \"Style\",\r\n        default: \"line\",\r\n        options: [\r\n          { value: \"line\", label: \"Lines\" },\r\n          { value: \"fill\", label: \"Fill\" },\r\n        ],\r\n      },\r\n    ];\r\n  }\r\n\r\n  render(svg: SVGSVGElement, width: number, height: number, settings: Record<string, any>): void {\r\n    const group = this.getGroup(svg, settings.__instanceId);\r\n    const {\r\n      mode,\r\n      count,\r\n      size: rawSize,\r\n      sizeUnit,\r\n      gap: rawGap,\r\n      gapUnit,\r\n      margin: rawMargin,\r\n      marginUnit,\r\n      color,\r\n      opacity,\r\n      style,\r\n    } = settings;\r\n\r\n    const referenceElement = svg.parentElement;\r\n    const gap = this.resolveUnit(rawGap, gapUnit || \"px\", height, referenceElement);\r\n    const margin = this.resolveUnit(rawMargin, marginUnit || \"px\", height, referenceElement);\r\n    const availableHeight = height - margin * 2;\r\n\r\n    if (availableHeight <= 0) return;\r\n\r\n    if (mode === \"count\") {\r\n      this.renderByCount(group, width, availableHeight, margin, count, gap, color, opacity, style);\r\n    } else {\r\n      const size = this.resolveUnit(rawSize, sizeUnit || \"px\", height, referenceElement);\r\n      if (size <= 0) return;\r\n      this.renderBySize(group, width, availableHeight, margin, size, gap, color, opacity, style);\r\n    }\r\n  }\r\n\r\n  private renderByCount(\r\n    group: SVGGElement,\r\n    width: number,\r\n    available: number,\r\n    margin: number,\r\n    count: number,\r\n    gap: number,\r\n    color: string,\r\n    opacity: number,\r\n    style: string,\r\n  ): void {\r\n    if (style === \"fill\") {\r\n      const bandHeight = (available - (count - 1) * gap) / count;\r\n      if (bandHeight <= 0) return;\r\n      for (let i = 0; i < count; i++) {\r\n        const y = margin + i * (bandHeight + gap);\r\n        group.appendChild(this.createRect(0, y, width, bandHeight, color, opacity));\r\n      }\r\n    } else {\r\n      if (count === 1) {\r\n        const y = margin + available / 2;\r\n        group.appendChild(this.createLine(0, y, width, y, color, opacity));\r\n        return;\r\n      }\r\n      const step = available / (count - 1);\r\n      for (let i = 0; i < count; i++) {\r\n        const y = margin + i * step;\r\n        group.appendChild(this.createLine(0, y, width, y, color, opacity));\r\n      }\r\n    }\r\n  }\r\n\r\n  private renderBySize(\r\n    group: SVGGElement,\r\n    width: number,\r\n    available: number,\r\n    margin: number,\r\n    size: number,\r\n    gap: number,\r\n    color: string,\r\n    opacity: number,\r\n    style: string,\r\n  ): void {\r\n    if (style === \"fill\") {\r\n      const step = size + gap;\r\n      for (let y = 0; y < available; y += step) {\r\n        const h = Math.min(size, available - y);\r\n        group.appendChild(this.createRect(0, margin + y, width, h, color, opacity));\r\n      }\r\n    } else {\r\n      for (let y = 0; y <= available; y += size) {\r\n        group.appendChild(this.createLine(0, margin + y, width, margin + y, color, opacity));\r\n      }\r\n    }\r\n  }\r\n}\r\n","import { StringDevUIFieldDescriptor as UIFieldDescriptor } from \"../../core/ui/StringDevUISchema\";\r\nimport { GridAdapter } from \"./GridAdapter\";\r\n\r\n/**\r\n * Center lines adapter.\r\n * Renders vertical and/or horizontal center axes.\r\n * Simple but essential for alignment verification.\r\n */\r\nexport class CenterAdapter extends GridAdapter {\r\n  readonly type = \"center\";\r\n  readonly label = \"Center\";\r\n  readonly icon = `<svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"3\" y=\"3\" width=\"10\" height=\"10\" rx=\"3\" fill=\"currentColor\"/><path d=\"M8 2V14\" stroke=\"white\"/><path d=\"M2 8H14\" stroke=\"white\"/></svg>`;\r\n\r\n  getDefaults(): Record<string, any> {\r\n    return {\r\n      showVertical: true,\r\n      showHorizontal: true,\r\n      color: \"#50e24a\",\r\n      opacity: 0.5,\r\n      dashed: true,\r\n    };\r\n  }\r\n\r\n  getUISchema(): UIFieldDescriptor[] {\r\n    return [\r\n      { type: \"toggle\", key: \"showVertical\", label: \"Vertical\", default: true },\r\n      { type: \"toggle\", key: \"showHorizontal\", label: \"Horizontal\", default: true },\r\n      { type: \"divider\" },\r\n      { type: \"color\", key: \"color\", label: \"Color\", default: \"#50e24a\" },\r\n      {\r\n        type: \"range\",\r\n        key: \"opacity\",\r\n        label: \"Opacity\",\r\n        default: 0.5,\r\n        min: 0,\r\n        max: 1,\r\n        step: 0.01,\r\n        displayMultiplier: 100,\r\n        displayStep: 10,\r\n      },\r\n      { type: \"toggle\", key: \"dashed\", label: \"Dashed\", default: true },\r\n    ];\r\n  }\r\n\r\n  render(svg: SVGSVGElement, width: number, height: number, settings: Record<string, any>): void {\r\n    const group = this.getGroup(svg, settings.__instanceId);\r\n    const { showVertical, showHorizontal, color, opacity, dashed } = settings;\r\n    const dashAttr = dashed ? \"6 3\" : \"none\";\r\n\r\n    if (showVertical) {\r\n      const line = this.createLine(width / 2, 0, width / 2, height, color, opacity);\r\n      if (dashed) line.setAttribute(\"stroke-dasharray\", dashAttr);\r\n      group.appendChild(line);\r\n    }\r\n\r\n    if (showHorizontal) {\r\n      const line = this.createLine(0, height / 2, width, height / 2, color, opacity);\r\n      if (dashed) line.setAttribute(\"stroke-dasharray\", dashAttr);\r\n      group.appendChild(line);\r\n    }\r\n  }\r\n}\r\n","import { StringDevUIFieldDescriptor as UIFieldDescriptor } from \"../../core/ui/StringDevUISchema\";\r\nimport { GridAdapter } from \"./GridAdapter\";\r\n\r\n/**\r\n * Rule of Thirds adapter.\r\n * Divides the element into a 3×3 grid (2 vertical + 2 horizontal lines).\r\n * Classic composition technique from photography and design.\r\n */\r\nexport class RuleOfThirdsAdapter extends GridAdapter {\r\n  readonly type = \"rule-of-thirds\";\r\n  readonly label = \"3×3\";\r\n  readonly icon = `<svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"6\" y=\"6\" width=\"4\" height=\"4\" fill=\"currentColor\"/><path d=\"M6 3.6C6 3.03995 6 2.75992 6.10899 2.54601C6.20487 2.35785 6.35785 2.20487 6.54601 2.10899C6.75992 2 7.03995 2 7.6 2H8.4C8.96005 2 9.24008 2 9.45399 2.10899C9.64215 2.20487 9.79513 2.35785 9.89101 2.54601C10 2.75992 10 3.03995 10 3.6V5H6V3.6Z\" fill=\"currentColor\"/><path d=\"M6 11H10V12.4C10 12.9601 10 13.2401 9.89101 13.454C9.79513 13.6422 9.64215 13.7951 9.45399 13.891C9.24008 14 8.96005 14 8.4 14H7.6C7.03995 14 6.75992 14 6.54601 13.891C6.35785 13.7951 6.20487 13.6422 6.10899 13.454C6 13.2401 6 12.9601 6 12.4V11Z\" fill=\"currentColor\"/><path d=\"M2 7.6C2 7.03995 2 6.75992 2.10899 6.54601C2.20487 6.35785 2.35785 6.20487 2.54601 6.10899C2.75992 6 3.03995 6 3.6 6H5V10H3.6C3.03995 10 2.75992 10 2.54601 9.89101C2.35785 9.79513 2.20487 9.64215 2.10899 9.45399C2 9.24008 2 8.96005 2 8.4V7.6Z\" fill=\"currentColor\"/><path d=\"M11 6H12.4C12.9601 6 13.2401 6 13.454 6.10899C13.6422 6.20487 13.7951 6.35785 13.891 6.54601C14 6.75992 14 7.03995 14 7.6V8.4C14 8.96005 14 9.24008 13.891 9.45399C13.7951 9.64215 13.6422 9.79513 13.454 9.89101C13.2401 10 12.9601 10 12.4 10H11V6Z\" fill=\"currentColor\"/></svg>`;\r\n\r\n  getDefaults(): Record<string, any> {\r\n    return {\r\n      color: \"#e2e24a\",\r\n      opacity: 0.4,\r\n      showIntersections: true,\r\n    };\r\n  }\r\n\r\n  getUISchema(): UIFieldDescriptor[] {\r\n    return [\r\n      { type: \"color\", key: \"color\", label: \"Color\", default: \"#e2e24a\" },\r\n      {\r\n        type: \"range\",\r\n        key: \"opacity\",\r\n        label: \"Opacity\",\r\n        default: 0.4,\r\n        min: 0,\r\n        max: 1,\r\n        step: 0.01,\r\n        displayMultiplier: 100,\r\n        displayStep: 10,\r\n      },\r\n      { type: \"toggle\", key: \"showIntersections\", label: \"Show points\", default: true },\r\n    ];\r\n  }\r\n\r\n  render(svg: SVGSVGElement, width: number, height: number, settings: Record<string, any>): void {\r\n    const group = this.getGroup(svg, settings.__instanceId);\r\n    const { color, opacity, showIntersections } = settings;\r\n\r\n    const third_w = width / 3;\r\n    const third_h = height / 3;\r\n\r\n    // Vertical lines\r\n    group.appendChild(this.createLine(third_w, 0, third_w, height, color, opacity));\r\n    group.appendChild(this.createLine(third_w * 2, 0, third_w * 2, height, color, opacity));\r\n\r\n    // Horizontal lines\r\n    group.appendChild(this.createLine(0, third_h, width, third_h, color, opacity));\r\n    group.appendChild(this.createLine(0, third_h * 2, width, third_h * 2, color, opacity));\r\n\r\n    // Intersection points\r\n    if (showIntersections) {\r\n      const points = [\r\n        [third_w, third_h],\r\n        [third_w * 2, third_h],\r\n        [third_w, third_h * 2],\r\n        [third_w * 2, third_h * 2],\r\n      ];\r\n\r\n      for (const [cx, cy] of points) {\r\n        const circle = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\r\n        circle.setAttribute(\"cx\", String(cx));\r\n        circle.setAttribute(\"cy\", String(cy));\r\n        circle.setAttribute(\"r\", \"3\");\r\n        circle.setAttribute(\"fill\", color);\r\n        circle.setAttribute(\"fill-opacity\", String(opacity * 1.5));\r\n        group.appendChild(circle);\r\n      }\r\n    }\r\n  }\r\n}\r\n","import { StringDevUIFieldDescriptor as UIFieldDescriptor } from \"../../core/ui/StringDevUISchema\";\r\nimport { GridAdapter } from \"./GridAdapter\";\r\n\r\nconst PHI = 1.6180339887;\r\n\r\n/**\r\n * Golden Rectangle adapter.\r\n *\r\n * Inscribes a true golden rectangle (φ:1) inside the element,\r\n * then recursively subdivides it into squares. Because each\r\n * remaining rectangle is also a golden rectangle, the quarter-circle\r\n * arcs in every square connect seamlessly into the golden spiral.\r\n */\r\nexport class GoldenRectangleAdapter extends GridAdapter {\r\n  readonly type = \"golden-rectangle\";\r\n  readonly label = \"Golden\";\r\n  readonly icon = `<svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"3\" y=\"3\" width=\"10\" height=\"10\" rx=\"3\" fill=\"currentColor\"/><path d=\"M9 13V3\" stroke=\"white\"/><path d=\"M13 9H9\" stroke=\"white\"/></svg>`;\r\n\r\n  getDefaults(): Record<string, any> {\r\n    return {\r\n      depth: 8,\r\n      showSpiral: true,\r\n      color: \"#e2a44a\",\r\n      opacity: 0.4,\r\n    };\r\n  }\r\n\r\n  getUISchema(): UIFieldDescriptor[] {\r\n    return [\r\n      { type: \"number\", key: \"depth\", label: \"Depth\", default: 8, min: 2, max: 14, step: 1 },\r\n      { type: \"toggle\", key: \"showSpiral\", label: \"Show spiral\", default: true },\r\n      { type: \"divider\" },\r\n      { type: \"color\", key: \"color\", label: \"Color\", default: \"#e2a44a\" },\r\n      {\r\n        type: \"range\",\r\n        key: \"opacity\",\r\n        label: \"Opacity\",\r\n        default: 0.4,\r\n        min: 0,\r\n        max: 1,\r\n        step: 0.01,\r\n        displayMultiplier: 100,\r\n        displayStep: 10,\r\n      },\r\n    ];\r\n  }\r\n\r\n  render(svg: SVGSVGElement, width: number, height: number, settings: Record<string, any>): void {\r\n    const group = this.getGroup(svg, settings.__instanceId);\r\n    const { depth, showSpiral, color, opacity } = settings;\r\n\r\n    // ── Inscribe a golden rectangle (φ : 1) centered in the element ──\r\n    let gw: number, gh: number;\r\n    if (width / height >= PHI) {\r\n      gh = height;\r\n      gw = gh * PHI;\r\n    } else {\r\n      gw = width;\r\n      gh = gw / PHI;\r\n    }\r\n    const gx = (width - gw) / 2;\r\n    const gy = (height - gh) / 2;\r\n\r\n    // Draw the golden rectangle border if it doesn't fill the element\r\n    if (gw < width - 1 || gh < height - 1) {\r\n      const border = this.createPath(\r\n        `M ${gx} ${gy} L ${gx + gw} ${gy} L ${gx + gw} ${gy + gh} L ${gx} ${gy + gh} Z`,\r\n        color,\r\n        opacity * 0.3,\r\n        1,\r\n      );\r\n      border.setAttribute(\"stroke-dasharray\", \"6 4\");\r\n      group.appendChild(border);\r\n    }\r\n\r\n    // ── Subdivide into squares, rotating CW: right → bottom → left → top ──\r\n    let x = gx,\r\n      y = gy,\r\n      w = gw,\r\n      h = gh;\r\n    let spiralD = \"\";\r\n    let isFirst = true;\r\n\r\n    for (let i = 0; i < depth; i++) {\r\n      if (w < 1 || h < 1) break;\r\n      const dir = i % 4;\r\n      const s = Math.min(w, h);\r\n      let sqX: number, sqY: number;\r\n\r\n      switch (dir) {\r\n        case 0: {\r\n          // Square on RIGHT\r\n          sqX = x + w - s;\r\n          sqY = y;\r\n          if (w - s > 0.5) group.appendChild(this.createLine(sqX, y, sqX, y + h, color, opacity));\r\n\r\n          if (showSpiral) {\r\n            // Center: top-left of square. Arc: TR → BL (CW)\r\n            if (isFirst) {\r\n              spiralD = `M ${sqX + s} ${sqY}`;\r\n              isFirst = false;\r\n            }\r\n            spiralD += ` A ${s} ${s} 0 0 1 ${sqX} ${sqY + s}`;\r\n          }\r\n\r\n          w -= s;\r\n          break;\r\n        }\r\n        case 1: {\r\n          // Square on BOTTOM\r\n          sqX = x;\r\n          sqY = y + h - s;\r\n          if (h - s > 0.5) group.appendChild(this.createLine(x, sqY, x + w, sqY, color, opacity));\r\n\r\n          if (showSpiral) {\r\n            // Center: top-right of square. Arc: BR → TL (CW)\r\n            if (isFirst) {\r\n              spiralD = `M ${sqX + s} ${sqY + s}`;\r\n              isFirst = false;\r\n            }\r\n            spiralD += ` A ${s} ${s} 0 0 1 ${sqX} ${sqY}`;\r\n          }\r\n\r\n          h -= s;\r\n          break;\r\n        }\r\n        case 2: {\r\n          // Square on LEFT\r\n          sqX = x;\r\n          sqY = y;\r\n          if (w - s > 0.5)\r\n            group.appendChild(this.createLine(x + s, y, x + s, y + h, color, opacity));\r\n\r\n          if (showSpiral) {\r\n            // Center: bottom-right of square. Arc: BL → TR (CW)\r\n            if (isFirst) {\r\n              spiralD = `M ${sqX} ${sqY + s}`;\r\n              isFirst = false;\r\n            }\r\n            spiralD += ` A ${s} ${s} 0 0 1 ${sqX + s} ${sqY}`;\r\n          }\r\n\r\n          x += s;\r\n          w -= s;\r\n          break;\r\n        }\r\n        case 3: {\r\n          // Square on TOP\r\n          sqX = x;\r\n          sqY = y;\r\n          if (h - s > 0.5)\r\n            group.appendChild(this.createLine(x, y + s, x + w, y + s, color, opacity));\r\n\r\n          if (showSpiral) {\r\n            // Center: bottom-left of square. Arc: TL → BR (CW)\r\n            if (isFirst) {\r\n              spiralD = `M ${sqX} ${sqY}`;\r\n              isFirst = false;\r\n            }\r\n            spiralD += ` A ${s} ${s} 0 0 1 ${sqX + s} ${sqY + s}`;\r\n          }\r\n\r\n          y += s;\r\n          h -= s;\r\n          break;\r\n        }\r\n      }\r\n    }\r\n\r\n    if (showSpiral && spiralD) {\r\n      group.appendChild(this.createPath(spiralD, color, opacity * 0.8, 1.5));\r\n    }\r\n  }\r\n}\r\n","import { StringDevUIFieldDescriptor as UIFieldDescriptor } from \"../../core/ui/StringDevUISchema\";\nimport { GridAdapter } from \"./GridAdapter\";\n\nconst SVG_NS = \"http://www.w3.org/2000/svg\";\n\n/**\n * Dot Grid adapter.\n *\n * Places small dots or crosses at every intersection of an invisible grid.\n * Much less visual noise than full lines — ideal for containers with\n * dense content (text, images) where you still want alignment guides.\n */\nexport class DotGridAdapter extends GridAdapter {\n  private static readonly MAX_DOT_CELLS = 120_000;\n  private static readonly MAX_CROSS_CELLS = 80_000;\n\n  readonly type = \"dot-grid\";\n  readonly label = \"Dots\";\n  readonly icon = `<svg viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><rect x=\"11\" y=\"3\" width=\"2\" height=\"2\" fill=\"currentColor\"/><rect x=\"11\" y=\"7\" width=\"2\" height=\"2\" fill=\"currentColor\"/><rect x=\"11\" y=\"11\" width=\"2\" height=\"2\" fill=\"currentColor\"/><rect x=\"7\" y=\"3\" width=\"2\" height=\"2\" fill=\"currentColor\"/><rect x=\"7\" y=\"7\" width=\"2\" height=\"2\" fill=\"currentColor\"/><rect x=\"7\" y=\"11\" width=\"2\" height=\"2\" fill=\"currentColor\"/><rect x=\"3\" y=\"3\" width=\"2\" height=\"2\" fill=\"currentColor\"/><rect x=\"3\" y=\"7\" width=\"2\" height=\"2\" fill=\"currentColor\"/><rect x=\"3\" y=\"11\" width=\"2\" height=\"2\" fill=\"currentColor\"/></svg>`;\n\n  private static readonly UNIT_OPTIONS = [\n    { value: \"px\", label: \"px\" },\n    { value: \"%\", label: \"%\" },\n    { value: \"vw\", label: \"vw\" },\n    { value: \"vh\", label: \"vh\" },\n    { value: \"em\", label: \"em\" },\n    { value: \"rem\", label: \"rem\" },\n  ] as const;\n\n  getDefaults(): Record<string, any> {\n    return {\n      step: 16,\n      stepUnit: \"px\",\n      dotSize: 1.5,\n      shape: \"dot\",\n      color: \"#a0a0a0\",\n      opacity: 0.4,\n    };\n  }\n\n  getUISchema(): UIFieldDescriptor[] {\n    return [\n      {\n        type: \"range\",\n        key: \"step\",\n        label: \"Step\",\n        default: 16,\n        min: 0,\n        max: 100,\n        step: 1,\n        units: DotGridAdapter.UNIT_OPTIONS,\n        defaultUnit: \"px\",\n      },\n      { type: \"range\", key: \"dotSize\", label: \"Size\", default: 1.5, min: 0.5, max: 6, step: 0.5 },\n      {\n        type: \"select\",\n        key: \"shape\",\n        label: \"Shape\",\n        default: \"dot\",\n        options: [\n          { value: \"dot\", label: \"Dot ●\" },\n          { value: \"cross\", label: \"Cross +\" },\n        ],\n      },\n      { type: \"divider\" },\n      { type: \"color\", key: \"color\", label: \"Color\", default: \"#a0a0a0\" },\n      {\n        type: \"range\",\n        key: \"opacity\",\n        label: \"Opacity\",\n        default: 0.4,\n        min: 0,\n        max: 1,\n        step: 0.01,\n        displayMultiplier: 100,\n        displayStep: 10,\n      },\n    ];\n  }\n\n  render(svg: SVGSVGElement, width: number, height: number, settings: Record<string, any>): void {\n    const group = this.getGroup(svg, settings.__instanceId);\n    const { step: rawStep, stepUnit, dotSize, shape, color, opacity } = settings;\n\n    const desiredStep = this.resolveUnit(\n      rawStep,\n      stepUnit || \"px\",\n      Math.min(width, height),\n      svg.parentElement,\n    );\n    const step = this.getSafeStep(width, height, desiredStep, shape);\n    if (step < 2) return;\n\n    const patternId = this.getPatternId(settings.__instanceId);\n    const defs = this.getDefs(svg);\n    const pattern = document.createElementNS(SVG_NS, \"pattern\");\n    pattern.setAttribute(\"id\", patternId);\n    pattern.setAttribute(\"data-string-grid-pattern-for\", settings.__instanceId);\n    pattern.setAttribute(\"patternUnits\", \"userSpaceOnUse\");\n    pattern.setAttribute(\"width\", String(step));\n    pattern.setAttribute(\"height\", String(step));\n    pattern.setAttribute(\"x\", String(step / 2));\n    pattern.setAttribute(\"y\", String(step / 2));\n\n    const center = step / 2;\n\n    if (shape === \"cross\") {\n      pattern.appendChild(\n        this.createLine(\n          center - dotSize * 2,\n          center,\n          center + dotSize * 2,\n          center,\n          color,\n          opacity,\n          0.8,\n        ),\n      );\n      pattern.appendChild(\n        this.createLine(\n          center,\n          center - dotSize * 2,\n          center,\n          center + dotSize * 2,\n          color,\n          opacity,\n          0.8,\n        ),\n      );\n    } else {\n      const circle = document.createElementNS(SVG_NS, \"circle\") as SVGCircleElement;\n      circle.setAttribute(\"cx\", String(center));\n      circle.setAttribute(\"cy\", String(center));\n      circle.setAttribute(\"r\", String(dotSize));\n      circle.setAttribute(\"fill\", color);\n      circle.setAttribute(\"fill-opacity\", String(opacity));\n      pattern.appendChild(circle);\n    }\n\n    defs.appendChild(pattern);\n\n    const rect = this.createRect(0, 0, width, height, `url(#${patternId})`, 1);\n    rect.setAttribute(\"fill-opacity\", \"1\");\n    group.appendChild(rect);\n  }\n\n  override clear(svg: SVGSVGElement, instanceId: string): void {\n    super.clear(svg, instanceId);\n\n    const pattern = svg.querySelector(`[data-string-grid-pattern-for=\"${instanceId}\"]`);\n    pattern?.remove();\n  }\n\n  private getDefs(svg: SVGSVGElement): SVGDefsElement {\n    let defs = svg.querySelector(\"defs\") as SVGDefsElement | null;\n    if (!defs) {\n      defs = document.createElementNS(SVG_NS, \"defs\") as SVGDefsElement;\n      svg.insertBefore(defs, svg.firstChild);\n    }\n    return defs;\n  }\n\n  private getPatternId(instanceId: string): string {\n    return `string-grid-dot-pattern-${instanceId.replace(/[^a-zA-Z0-9_-]/g, \"-\")}`;\n  }\n\n  private getSafeStep(width: number, height: number, step: number, shape: string): number {\n    const minStep = 2;\n    const normalizedStep = Math.max(step, minStep);\n    const maxCells =\n      shape === \"cross\" ? DotGridAdapter.MAX_CROSS_CELLS : DotGridAdapter.MAX_DOT_CELLS;\n    const estimatedCells = Math.floor(width / normalizedStep) * Math.floor(height / normalizedStep);\n\n    if (estimatedCells <= maxCells) {\n      return normalizedStep;\n    }\n\n    return Math.max(normalizedStep, Math.sqrt((width * height) / maxCells));\n  }\n}\n","export type StringDevtoolsOverlayId = string;\n\nexport const STRING_DEVTOOLS_OVERLAY_LAYOUT_CHANGE_EVENT = \"string-devtools-overlay-layout:change\";\n\nconst SLOT_STEP = 31;\nconst COLLISION_STEP = 33;\nconst COLLISION_SIZE_X = 50;\nconst COLLISION_SIZE_Y = 31;\nconst BASE_OFFSET_X = 0;\nconst BASE_OFFSET_Y = 0;\n\ninterface OverlayEntry {\n  order: number;\n  badgeCount: number;\n}\n\nexport interface AnchorPoint {\n  docX: number;\n  docY: number;\n}\n\nexport class OverlaySlotRegistry {\n  private readonly entries = new Map<string, OverlayEntry>();\n\n  register(id: string, order: number, badgeCount = 1): void {\n    this.entries.set(id, { order, badgeCount });\n  }\n\n  unregister(id: string): void {\n    this.entries.delete(id);\n  }\n\n  resolveAnchor(\n    overlayId: StringDevtoolsOverlayId,\n    contentX: number,\n    contentY: number,\n  ): AnchorPoint {\n    const sorted = this.getSorted();\n    const index = sorted.findIndex((o) => o.id === overlayId);\n\n    let slotOffset = 0;\n    for (let i = 0; i < index; i += 1) {\n      slotOffset += sorted[i].badgeCount;\n    }\n\n    return {\n      docX: contentX + BASE_OFFSET_X + slotOffset * SLOT_STEP,\n      docY: contentY + BASE_OFFSET_Y,\n    };\n  }\n\n  resolveCollisionOffset(\n    element: HTMLElement,\n    baseDocX: number,\n    baseDocY: number,\n    resolveAncestorAnchor: (ancestorId: string) => AnchorPoint | null,\n  ): number {\n    const ancestorAnchors: AnchorPoint[] = [];\n    let current = element.parentElement;\n\n    while (current) {\n      const ancestorId =\n        current.getAttribute(\"string-id\") ?? current.getAttribute(\"data-string-id\");\n      if (ancestorId) {\n        const anchor = resolveAncestorAnchor(ancestorId);\n        if (anchor) {\n          ancestorAnchors.push(anchor);\n        }\n      }\n      current = current.parentElement;\n    }\n\n    let offset = 0;\n    let hasCollision = true;\n\n    while (hasCollision) {\n      hasCollision = false;\n\n      for (const anchor of ancestorAnchors) {\n        if (\n          Math.abs(anchor.docX - baseDocX) < COLLISION_SIZE_X &&\n          Math.abs(anchor.docY - (baseDocY + offset)) < COLLISION_SIZE_Y\n        ) {\n          offset += COLLISION_STEP;\n          hasCollision = true;\n          break;\n        }\n      }\n    }\n\n    return offset;\n  }\n\n  emitLayoutChange(): void {\n    window.dispatchEvent(new CustomEvent(STRING_DEVTOOLS_OVERLAY_LAYOUT_CHANGE_EVENT));\n  }\n\n  private getSorted(): Array<{ id: string } & OverlayEntry> {\n    const list: Array<{ id: string } & OverlayEntry> = [];\n    for (const [id, entry] of this.entries) {\n      list.push({ id, ...entry });\n    }\n    list.sort((a, b) => {\n      if (a.order !== b.order) return a.order - b.order;\n      return a.id.localeCompare(b.id);\n    });\n    return list;\n  }\n}\n\nexport const overlaySlotRegistry = new OverlaySlotRegistry();\n","import { buildDevtoolsThemeBlock } from \"../core/StringDevStyleSystem\";\r\n\r\nexport function buildGridCSS(): string {\r\n  return `\r\n    ${buildDevtoolsThemeBlock([\"[data-string-grid-root]\", \"[data-stdg-badge]\"])}\r\n\r\n    [data-string-grid-root],\r\n    [data-stdg-badge] {\r\n      --string-grid-stack-offset: 0px;\r\n      --string-grid-panel-offset-top: 0px;\r\n      --string-grid-trigger-gap: 8px;\r\n      --string-grid-side-panel-gap: 8px;\r\n    }\r\n\r\n    [data-string-grid-overlay] {\r\n      position: absolute;\r\n      inset: 0;\r\n      width: 100%;\r\n      height: 100%;\r\n      pointer-events: none;\r\n      overflow: hidden;\r\n    }\r\n\r\n    [data-string-grid-list] {\r\n      display: flex;\r\n      flex-direction: column;\r\n      gap: 0;\r\n    }\r\n\r\n    [data-stdg-badge] > [data-stdg-panel] {\r\n      top: var(--string-grid-panel-offset-top);\r\n      right: calc(100% + var(--string-grid-trigger-gap));\r\n    }\r\n\r\n    [data-string-grid-global-hud][data-stdg-badge] {\r\n      background: none;\r\n      border: none;\r\n      box-shadow: none;\r\n      padding: 0;\r\n      width: 0;\r\n      min-width: 0;\r\n      overflow: visible;\r\n    }\r\n\r\n    [data-string-grid-global-hud][data-stdg-badge] > [data-stdg-panel] {\r\n      top: auto;\r\n      bottom: 0;\r\n      left: var(--string-grid-trigger-gap);\r\n      right: auto;\r\n    }\r\n\r\n    [data-string-grid-global-hud][data-stdg-badge] [data-stdg-panel] > [data-stdg-panel] {\r\n      top: auto;\r\n      bottom: 0;\r\n      left: calc(100% + var(--string-grid-side-panel-gap));\r\n      right: auto;\r\n    }\r\n\r\n    \r\n\r\n    [data-stdg-panel] > [data-stdg-panel] {\r\n      top: 0;\r\n      right: calc(100% + var(--string-grid-side-panel-gap));\r\n    }\r\n\r\n    @media (max-width: 1024px), (pointer: coarse) {\r\n      [data-stdg-badge] > [data-stdg-panel],\r\n      [data-string-grid-global-hud][data-stdg-badge] > [data-stdg-panel] {\r\n        top: 0;\r\n        right: auto;\r\n        bottom: auto;\r\n        left: 100%;\r\n        margin-left: var(--string-grid-trigger-gap);\r\n      }\r\n\r\n      [data-stdg-panel] > [data-stdg-panel],\r\n      [data-string-grid-global-hud][data-stdg-badge] [data-stdg-panel] > [data-stdg-panel] {\r\n        top: calc(100% + var(--string-grid-side-panel-gap));\r\n        right: auto;\r\n        bottom: auto;\r\n        left: 0;\r\n      }\r\n    }\r\n  `;\r\n}\r\n","import { StringContext } from \"../../../core/StringContext\";\r\nimport { StringDevModule } from \"../core/StringDevModule\";\r\nimport { StringObject } from \"../../../objects/StringObject\";\r\nimport { StringDevtoolSubBadge } from \"../../../models/devtools/StringDevtool\";\r\nimport { GridAdapter } from \"./adapters/GridAdapter\";\r\nimport { GridManager } from \"./GridManager\";\r\nimport { GridOverlay } from \"./GridOverlay\";\r\nimport { GridHUD } from \"./GridHUD\";\r\nimport { GridSerializer } from \"./GridSerializer\";\r\n\r\nimport { ColumnsAdapter } from \"./adapters/ColumnsAdapter\";\r\nimport { RowsAdapter } from \"./adapters/RowsAdapter\";\r\nimport { CenterAdapter } from \"./adapters/CenterAdapter\";\r\nimport { RuleOfThirdsAdapter } from \"./adapters/RuleOfThirdsAdapter\";\r\nimport { GoldenRectangleAdapter } from \"./adapters/GoldenRectangleAdapter\";\r\nimport { DotGridAdapter } from \"./adapters/DotGridAdapter\";\r\nimport { overlaySlotRegistry } from \"../core/StringDevtoolsOverlayLayout\";\r\nimport { StringDevViewportLayer } from \"../core/StringDevViewportLayer\";\r\nimport { buildGridCSS } from \"./StringGrid.css\";\r\n\r\nconst GRID_STORAGE_KEY_ATTR = \"data-string-grid-storage-key\";\r\nconst AUTO_STRING_OBJECT_ID_RE = /^string-\\d+$/;\r\nconst GLOBAL_GRID_ELEMENT_ID = \"__global__\";\r\n\r\n/**\r\n * Resolves a stable storage key for an element. Runtime-generated StringObject\r\n * ids are intentionally avoided because they do not reliably survive reloads.\r\n */\r\nfunction resolveElementId(element: HTMLElement, object: StringObject): string {\r\n  const existing = element.getAttribute(GRID_STORAGE_KEY_ATTR)?.trim();\r\n  if (existing) {\r\n    return existing;\r\n  }\r\n\r\n  const declaredStringId =\r\n    element.getAttribute(\"data-string-id\")?.trim() ||\r\n    element.getAttribute(\"string-id\")?.trim() ||\r\n    \"\";\r\n\r\n  if (declaredStringId && !AUTO_STRING_OBJECT_ID_RE.test(declaredStringId)) {\r\n    const key = `string:${window.location.pathname}#${declaredStringId}`;\r\n    element.setAttribute(GRID_STORAGE_KEY_ATTR, key);\r\n    return key;\r\n  }\r\n\r\n  const domId = element.id.trim();\r\n  if (domId) {\r\n    const key = `dom:${window.location.pathname}#${domId}`;\r\n    element.setAttribute(GRID_STORAGE_KEY_ATTR, key);\r\n    return key;\r\n  }\r\n\r\n  const key = `path:${window.location.pathname}:${buildElementPathKey(element)}`;\r\n  element.setAttribute(GRID_STORAGE_KEY_ATTR, key);\r\n  return key;\r\n}\r\n\r\nfunction resolveLegacyElementIds(\r\n  element: HTMLElement,\r\n  object: StringObject,\r\n  primaryId: string,\r\n): string[] {\r\n  const pathname = window.location.pathname;\r\n  const domId = element.id.trim();\r\n  const declaredStringId =\r\n    element.getAttribute(\"data-string-id\")?.trim() ||\r\n    element.getAttribute(\"string-id\")?.trim() ||\r\n    \"\";\r\n\r\n  const candidates = [\r\n    domId ? `dom:${pathname}#${domId}` : \"\",\r\n    declaredStringId && !AUTO_STRING_OBJECT_ID_RE.test(declaredStringId)\r\n      ? `string:${pathname}#${declaredStringId}`\r\n      : \"\",\r\n    domId,\r\n    declaredStringId,\r\n    object.id.trim(),\r\n  ].filter(Boolean);\r\n\r\n  return candidates.filter(\r\n    (candidate, index) => candidate !== primaryId && candidates.indexOf(candidate) === index,\r\n  );\r\n}\r\n\r\nfunction buildElementPathKey(element: HTMLElement): string {\r\n  const segments: string[] = [];\r\n  let current: HTMLElement | null = element;\r\n\r\n  while (current && current !== document.body && current !== document.documentElement) {\r\n    const parent: HTMLElement | null = current.parentElement;\r\n    const tag = current.tagName.toLowerCase();\r\n    let index = 1;\r\n\r\n    if (parent) {\r\n      let sibling = current.previousElementSibling;\r\n      while (sibling) {\r\n        if (sibling.tagName === current.tagName) {\r\n          index += 1;\r\n        }\r\n        sibling = sibling.previousElementSibling;\r\n      }\r\n    }\r\n\r\n    segments.unshift(`${tag}:nth-of-type(${index})`);\r\n\r\n    if (parent?.id) {\r\n      segments.unshift(`#${parent.id}`);\r\n      break;\r\n    }\r\n\r\n    current = parent;\r\n  }\r\n\r\n  return segments.join(\">\");\r\n}\r\n\r\nfunction resolveGridDepth(element: HTMLElement): number {\r\n  let depth = 0;\r\n  let current = element.parentElement;\r\n\r\n  while (current) {\r\n    if (current.hasAttribute(\"data-string-grid-root\")) {\r\n      depth += 1;\r\n    }\r\n    current = current.parentElement;\r\n  }\r\n\r\n  return depth;\r\n}\r\n\r\ninterface GridTriggerEntry {\r\n  object: StringObject;\r\n  hud: GridHUD;\r\n  depth: number;\r\n}\r\n\r\ninterface GridTriggerMeasurement {\r\n  visible: boolean;\r\n  docX: number;\r\n  docY: number;\r\n  stackOffsetY: number;\r\n  elementDocX?: number;\r\n  elementDocY?: number;\r\n  width?: number;\r\n  height?: number;\r\n}\r\n\r\n/**\r\n * StringDevLayout — developer utility module for layout overlays.\r\n *\r\n * Usage:\r\n *   <div string=\"layout\">...</div>\r\n *\r\n * No configuration attributes needed. All configuration happens\r\n * through the interactive HUD panel (hover top-right corner).\r\n *\r\n * Supports multiple grid types via the adapter pattern:\r\n * - Columns, Rows, Center\r\n * - Rule of Thirds, Phi Grid, Golden Rectangle, Harmonic Armature\r\n * - Extensible via `st.use(StringDevLayout, { adapters: [MyAdapter] })`\r\n */\r\nexport class StringDevLayout extends StringDevModule {\r\n  private gridManager: GridManager = new GridManager();\r\n  private viewportLayer: StringDevViewportLayer;\r\n  private overlayLayer: StringDevViewportLayer;\r\n  private overlays: Map<string, GridOverlay> = new Map();\r\n  private huds: Map<string, GridHUD> = new Map();\r\n  private elementMap: Map<string, HTMLElement> = new Map();\r\n  private triggerEntries: Map<string, GridTriggerEntry> = new Map();\r\n  private triggerMeasurements: Map<string, GridTriggerMeasurement> = new Map();\r\n  private enabled: boolean = true;\r\n  private needsMeasure = false;\r\n  private hasPendingMutate = false;\r\n\r\n  private globalHost: HTMLDivElement | null = null;\r\n  private globalOverlay: GridOverlay | null = null;\r\n  private globalHUD: GridHUD | null = null;\r\n  private globalSubBadge: HTMLElement | null = null;\r\n  static override devtool = {\r\n    id: \"layout\",\r\n    label: \"Layout\",\r\n    icon: \"layout\",\r\n    order: 20,\r\n    group: 1,\r\n    hotkey: { key: \"L\", shiftKey: true },\r\n    styles: buildGridCSS,\r\n    connects: { global: false, keys: [\"layout\"] },\r\n  };\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.attributesToMap = [];\r\n    this.overlayLayer = this.acquireViewportLayer(\"devtools-grid-overlay\", 10010);\r\n    this.viewportLayer = this.acquireViewportLayer(\"devtools-hud\", 10040);\r\n    this.registerBuiltInAdapters();\r\n    this.registerExternalAdapters();\r\n  }\r\n\r\n  // ── Lifecycle ─────────────────────────────────────────\r\n\r\n  onInit(): void {\r\n    this.ensureTriggerLayer();\r\n    this.ensureGlobalGrid();\r\n  }\r\n\r\n  protected override getDevtoolSubBadges(): StringDevtoolSubBadge[] {\r\n    return [\r\n      {\r\n        id: \"global-settings\",\r\n        icon: \"settings\",\r\n        label: \"Open global grid settings\",\r\n        selectorAttribute: \"data-string-grid-global-toggle\",\r\n        onClick: (anchorElement) => this.toggleGlobalPanel(anchorElement),\r\n      },\r\n    ];\r\n  }\r\n\r\n  onObjectConnected(object: StringObject): void {\r\n    const element = object.htmlElement;\r\n    const elementId = resolveElementId(element, object);\r\n    const fallbackIds = resolveLegacyElementIds(element, object, elementId);\r\n    element.setAttribute(\"data-string-grid-root\", \"\");\r\n    const gridDepth = resolveGridDepth(element);\r\n    element.setAttribute(\"data-string-grid-depth\", String(gridDepth));\r\n    element.style.setProperty(\"--string-grid-stack-offset\", \"0px\");\r\n    this.elementMap.set(elementId, element);\r\n\r\n    this.gridManager.load(elementId, fallbackIds);\r\n\r\n    const overlayWorld = this.overlayLayer.getWorldElement(this.getWorldHost());\r\n    const overlay = new GridOverlay(element, overlayWorld, () => {\r\n      if (!this.enabled) return;\r\n      this.renderElement(elementId);\r\n      this.scheduleTriggerSync();\r\n    });\r\n    this.overlays.set(elementId, overlay);\r\n\r\n    const hud = new GridHUD(element, this.gridManager.getAdapterRegistry(), {\r\n      onAdd: (type) => this.handleAdd(elementId, type),\r\n      onRemove: (id) => this.handleRemove(elementId, id),\r\n      onToggle: (id) => this.handleToggle(elementId, id),\r\n      onSettingChange: (id, key, value) => this.handleSettingChange(elementId, id, key, value),\r\n      onReorder: (draggedId, targetId, placement) =>\r\n        this.handleReorder(elementId, draggedId, targetId, placement),\r\n      onMoveToEnd: (id) => this.handleMoveToEnd(elementId, id),\r\n      onSelectLayout: (layoutId) => this.handleSelectLayout(elementId, layoutId),\r\n      onUpdateLayoutMinWidth: (layoutId, minWidth) =>\r\n        this.handleUpdateLayoutMinWidth(elementId, layoutId, minWidth),\r\n      onAddLayout: () => this.handleAddLayout(elementId),\r\n      onRemoveLayout: (layoutId) => this.handleRemoveLayout(elementId, layoutId),\r\n      onExport: () => this.handleExport(elementId),\r\n      onImport: () => this.handleImport(elementId),\r\n      onRenameInstance: (instanceId, name) =>\r\n        this.handleRenameInstance(elementId, instanceId, name),\r\n      onRenamePanelTitle: (title) => this.handleRenamePanelTitle(elementId, title),\r\n      onHUDOpen: () => this.handleHUDOpen(elementId),\r\n      onHUDClose: () => this.handleHUDClose(elementId),\r\n      onLayoutPanelOpen: () => this.handleLayoutPanelOpen(elementId),\r\n      onLayoutPanelClose: () => this.handleLayoutPanelClose(elementId),\r\n    });\r\n    this.huds.set(elementId, hud);\r\n    hud.setTargetId(elementId);\r\n    this.ensureTriggerLayer();\r\n    this.viewportLayer.getWorldElement(this.getWorldHost()).appendChild(hud.getHudElement());\r\n    this.triggerEntries.set(elementId, { object, hud, depth: gridDepth });\r\n\r\n    this.renderElement(elementId);\r\n    this.refreshHUD(elementId);\r\n    overlay.setEnabled(this.enabled);\r\n    hud.setEnabled(this.enabled);\r\n    requestAnimationFrame(() => this.scheduleTriggerSync());\r\n  }\r\n\r\n  onObjectDisconnected(object: StringObject): void {\r\n    const element = object.htmlElement;\r\n    const elementId = resolveElementId(element, object);\r\n    this.destroyElement(elementId);\r\n  }\r\n\r\n  onResize(): void {\r\n    for (const [elementId, overlay] of this.overlays) {\r\n      overlay.syncViewBox();\r\n      this.renderElement(elementId);\r\n      this.refreshHUD(elementId);\r\n    }\r\n    this.syncGlobalHostSize();\r\n    this.globalOverlay?.syncViewBox();\r\n    this.renderGlobal();\r\n    this.refreshGlobalHUD();\r\n    this.scheduleTriggerSync();\r\n  }\r\n\r\n  onScroll(): void {\r\n    if (!this.enabled) return;\r\n    this.needsMeasure = true;\r\n  }\r\n\r\n  onScrollMeasure(): void {\r\n    if (!this.enabled || !this.needsMeasure) return;\r\n    this.collectTriggerMeasurements();\r\n    this.needsMeasure = false;\r\n    for (const [elementId, entry] of this.triggerEntries) {\r\n      this.applyTriggerMeasurement(entry, this.triggerMeasurements.get(elementId));\r\n    }\r\n    this.hasPendingMutate = false;\r\n  }\r\n\r\n  onMutate(): void {\r\n    if (!this.enabled || !this.hasPendingMutate) return;\r\n    for (const [elementId, entry] of this.triggerEntries) {\r\n      this.applyTriggerMeasurement(entry, this.triggerMeasurements.get(elementId));\r\n    }\r\n    this.hasPendingMutate = false;\r\n  }\r\n\r\n  onDOMRebuild(): void {\r\n    if (!this.enabled) return;\r\n    this.scheduleTriggerSync();\r\n  }\r\n\r\n  destroy(): void {\r\n    for (const [id] of this.overlays) {\r\n      this.destroyElement(id);\r\n    }\r\n    this.destroyGlobalGrid();\r\n    this.gridManager.clear();\r\n    super.destroy();\r\n  }\r\n\r\n  public setEnabled(enabled: boolean): void {\r\n    if (this.enabled === enabled) {\r\n      return;\r\n    }\r\n\r\n    this.enabled = enabled;\r\n    for (const overlay of this.overlays.values()) {\r\n      overlay.setEnabled(enabled);\r\n    }\r\n    for (const hud of this.huds.values()) {\r\n      hud.setEnabled(enabled);\r\n    }\r\n    this.globalOverlay?.setEnabled(enabled);\r\n    this.globalHUD?.setEnabled(enabled);\r\n    if (!enabled) {\r\n      this.globalHUD?.hide();\r\n    }\r\n    this.applyTriggerLayerState();\r\n    if (enabled) {\r\n      for (const elementId of this.overlays.keys()) {\r\n        this.renderElement(elementId);\r\n      }\r\n      this.renderGlobal();\r\n      this.scheduleTriggerSync();\r\n    } else {\r\n      this.hasPendingMutate = false;\r\n    }\r\n    this.emitDevtoolState();\r\n  }\r\n\r\n  public isEnabled(): boolean {\r\n    return this.enabled;\r\n  }\r\n\r\n  protected getDevtoolActiveState(): boolean {\r\n    return this.enabled;\r\n  }\r\n\r\n  protected setDevtoolActiveState(active: boolean): void {\r\n    this.setEnabled(active);\r\n  }\r\n\r\n  // ── HUD Callbacks ─────────────────────────────────────\r\n\r\n  private handleAdd(elementId: string, type: string): void {\r\n    this.gridManager.addInstance(elementId, type);\r\n    this.renderElement(elementId);\r\n    this.refreshHUD(elementId);\r\n  }\r\n\r\n  private handleRemove(elementId: string, instanceId: string): void {\r\n    const instance = this.gridManager.findInstance(elementId, instanceId);\r\n    if (instance) {\r\n      const adapter = this.gridManager.getAdapter(instance.type);\r\n      const overlay = this.overlays.get(elementId);\r\n      if (adapter && overlay) {\r\n        overlay.clearInstance(instanceId, adapter);\r\n      }\r\n    }\r\n    this.gridManager.removeInstance(elementId, instanceId);\r\n    this.refreshHUD(elementId);\r\n  }\r\n\r\n  private handleToggle(elementId: string, instanceId: string): void {\r\n    this.gridManager.toggleVisibility(elementId, instanceId);\r\n    this.renderElement(elementId);\r\n    this.refreshHUD(elementId);\r\n  }\r\n\r\n  private handleSettingChange(\r\n    elementId: string,\r\n    instanceId: string,\r\n    key: string,\r\n    value: any,\r\n  ): void {\r\n    this.gridManager.updateSetting(elementId, instanceId, key, value);\r\n    this.renderElement(elementId);\r\n  }\r\n\r\n  private handleReorder(\r\n    elementId: string,\r\n    draggedId: string,\r\n    targetId: string,\r\n    placement: \"before\" | \"after\",\r\n  ): void {\r\n    this.gridManager.reorderInstance(elementId, draggedId, targetId, placement);\r\n    this.renderElement(elementId);\r\n    this.refreshHUD(elementId);\r\n  }\r\n\r\n  private handleMoveToEnd(elementId: string, instanceId: string): void {\r\n    this.gridManager.moveInstanceToEnd(elementId, instanceId);\r\n    this.renderElement(elementId);\r\n    this.refreshHUD(elementId);\r\n  }\r\n\r\n  private handleSelectLayout(elementId: string, layoutId: string): void {\r\n    this.gridManager.selectLayout(elementId, layoutId);\r\n    this.renderElement(elementId);\r\n    this.refreshHUD(elementId);\r\n  }\r\n\r\n  private handleUpdateLayoutMinWidth(elementId: string, layoutId: string, minWidth: number): void {\n    this.gridManager.updateLayoutMinWidth(elementId, layoutId, minWidth);\n    this.syncSelectedLayoutToViewport(elementId);\n    this.renderElement(elementId);\n    this.refreshHUD(elementId);\n  }\n\n  private handleAddLayout(elementId: string): void {\n    this.gridManager.addLayout(elementId);\n    this.syncSelectedLayoutToViewport(elementId);\n    this.renderElement(elementId);\n    this.refreshHUD(elementId);\n  }\n\n  private handleRemoveLayout(elementId: string, layoutId: string): void {\n    this.gridManager.removeLayout(elementId, layoutId);\n    this.syncSelectedLayoutToViewport(elementId);\n    this.renderElement(elementId);\n    this.refreshHUD(elementId);\n  }\n\r\n  private handleRenameInstance(elementId: string, instanceId: string, name: string): void {\r\n    this.gridManager.renameInstance(elementId, instanceId, name);\r\n    this.refreshHUD(elementId);\r\n  }\r\n\r\n  private handleRenamePanelTitle(elementId: string, title: string): void {\r\n    this.gridManager.renamePanelTitle(elementId, title);\r\n    this.refreshHUD(elementId);\r\n  }\r\n\r\n  private handleHUDOpen(elementId: string): void {\r\n    this.syncToResolved(elementId);\r\n    this.renderElement(elementId);\r\n    this.refreshHUD(elementId);\r\n  }\r\n\r\n  private handleHUDClose(elementId: string): void {\r\n    this.syncToResolved(elementId);\r\n    this.renderElement(elementId);\r\n    this.refreshHUD(elementId);\r\n  }\r\n\r\n  private handleLayoutPanelOpen(elementId: string): void {\r\n    this.renderElement(elementId);\r\n    this.refreshHUD(elementId);\r\n  }\r\n\r\n  private handleLayoutPanelClose(elementId: string): void {\r\n    this.renderElement(elementId);\r\n    this.refreshHUD(elementId);\r\n  }\r\n\r\n  private handleExport(elementId: string): void {\r\n    const layouts = this.gridManager.getLayouts(elementId);\r\n    const selectedLayoutId = this.gridManager.getSelectedLayoutId(elementId);\r\n    const data = GridSerializer.serialize(layouts, selectedLayoutId);\r\n    const slug = elementId.replace(/[^a-z0-9]/gi, \"-\").toLowerCase() || \"element\";\r\n    GridSerializer.toFile(`string-grid-${slug}.json`, data);\r\n  }\r\n\r\n  private handleImport(elementId: string): void {\r\n    GridSerializer.fromFile()\r\n      .then((raw) => {\n        const result = GridSerializer.deserialize(raw, this.gridManager.getAdapterRegistry());\n        if (!result) return;\n        this.gridManager.replaceLayouts(elementId, result.layouts, result.selectedLayoutId);\n        this.syncSelectedLayoutToViewport(elementId);\n        this.renderElement(elementId);\n        this.refreshHUD(elementId);\n      })\n      .catch(() => {\r\n        // user cancelled or invalid file — nothing to do\r\n      });\r\n  }\r\n\r\n  // ── Internal ──────────────────────────────────────────\r\n\r\n  private renderElement(elementId: string): void {\r\n    if (elementId === GLOBAL_GRID_ELEMENT_ID) {\r\n      this.renderGlobal();\r\n      return;\r\n    }\r\n\r\n    const overlay = this.overlays.get(elementId);\r\n    if (!overlay) return;\r\n\r\n    const hud = this.huds.get(elementId);\r\n    const viewportWidth = this.data.viewport.windowWidth || window.innerWidth;\r\n    const instances = hud?.isHUDOpen()\r\n      ? this.gridManager.getSelectedInstances(elementId)\r\n      : this.gridManager.getResolvedInstances(elementId, viewportWidth);\r\n    overlay.render(instances, this.gridManager.getAdapterRegistry());\r\n  }\r\n\r\n  private syncToResolved(elementId: string): void {\n    this.syncSelectedLayoutToViewport(elementId);\n  }\n\n  private syncSelectedLayoutToViewport(elementId: string): void {\n    const viewportWidth = this.data.viewport.windowWidth || window.innerWidth;\n    const resolvedLayoutId = this.gridManager.getResolvedLayoutId(elementId, viewportWidth);\n    const selectedLayoutId = this.gridManager.getSelectedLayoutId(elementId);\n    if (selectedLayoutId !== resolvedLayoutId) {\n      this.gridManager.selectLayout(elementId, resolvedLayoutId, false);\n    }\r\n  }\r\n\r\n  private refreshHUD(elementId: string): void {\r\n    if (elementId === GLOBAL_GRID_ELEMENT_ID) {\r\n      this.refreshGlobalHUD();\r\n      return;\r\n    }\r\n\r\n    const hud = this.huds.get(elementId);\r\n    if (!hud) return;\r\n\r\n    const viewportWidth = this.data.viewport.windowWidth || window.innerWidth;\r\n    const resolvedLayoutId = this.gridManager.getResolvedLayoutId(elementId, viewportWidth);\r\n    if (!hud.isHUDOpen()) {\r\n      const selectedLayoutId = this.gridManager.getSelectedLayoutId(elementId);\r\n      if (selectedLayoutId !== resolvedLayoutId) {\r\n        this.gridManager.selectLayout(elementId, resolvedLayoutId, false);\r\n      }\r\n    }\r\n    const selectedLayoutId = this.gridManager.getSelectedLayoutId(elementId);\r\n    const instances = this.gridManager.getSelectedInstances(elementId);\r\n    const layouts = this.gridManager.getLayouts(elementId);\r\n    const panelTitle = this.gridManager.getPanelTitle(elementId);\r\n    hud.refresh(instances, layouts, panelTitle, selectedLayoutId, resolvedLayoutId);\r\n  }\r\n\r\n  // ── Global grid ───────────────────────────────────────\r\n\r\n  private ensureGlobalGrid(): void {\r\n    if (this.globalOverlay && this.globalHUD) return;\r\n\r\n    const screen = this.overlayLayer.getScreenElement();\r\n\r\n    const host = document.createElement(\"div\");\r\n    host.setAttribute(\"data-string-grid-global-root\", \"\");\r\n    host.style.position = \"absolute\";\r\n    host.style.inset = \"0\";\r\n    host.style.pointerEvents = \"none\";\r\n    screen.appendChild(host);\r\n    this.globalHost = host;\r\n    this.syncGlobalHostSize();\r\n\r\n    this.gridManager.load(GLOBAL_GRID_ELEMENT_ID);\r\n\r\n    const overlay = new GridOverlay(host, screen, () => {\r\n      if (!this.enabled) return;\r\n      this.renderGlobal();\r\n    });\r\n    this.globalOverlay = overlay;\r\n    overlay.setEnabled(this.enabled);\r\n    overlay.setPosition(0, 0, host.clientWidth, host.clientHeight);\r\n\r\n    const hud = new GridHUD(\r\n      host,\r\n      this.gridManager.getAdapterRegistry(),\r\n      {\r\n        onAdd: (type) => this.handleAdd(GLOBAL_GRID_ELEMENT_ID, type),\r\n        onRemove: (id) => this.handleRemove(GLOBAL_GRID_ELEMENT_ID, id),\r\n        onToggle: (id) => this.handleToggle(GLOBAL_GRID_ELEMENT_ID, id),\r\n        onSettingChange: (id, key, value) =>\r\n          this.handleSettingChange(GLOBAL_GRID_ELEMENT_ID, id, key, value),\r\n        onReorder: (draggedId, targetId, placement) =>\r\n          this.handleReorder(GLOBAL_GRID_ELEMENT_ID, draggedId, targetId, placement),\r\n        onMoveToEnd: (id) => this.handleMoveToEnd(GLOBAL_GRID_ELEMENT_ID, id),\r\n        onSelectLayout: (layoutId) => this.handleSelectLayout(GLOBAL_GRID_ELEMENT_ID, layoutId),\r\n        onUpdateLayoutMinWidth: (layoutId, minWidth) =>\r\n          this.handleUpdateLayoutMinWidth(GLOBAL_GRID_ELEMENT_ID, layoutId, minWidth),\r\n        onAddLayout: () => this.handleAddLayout(GLOBAL_GRID_ELEMENT_ID),\r\n        onRemoveLayout: (layoutId) => this.handleRemoveLayout(GLOBAL_GRID_ELEMENT_ID, layoutId),\r\n        onExport: () => this.handleExport(GLOBAL_GRID_ELEMENT_ID),\r\n        onImport: () => this.handleImport(GLOBAL_GRID_ELEMENT_ID),\r\n        onRenameInstance: (instanceId, name) =>\r\n          this.handleRenameInstance(GLOBAL_GRID_ELEMENT_ID, instanceId, name),\r\n        onRenamePanelTitle: (title) => this.handleRenamePanelTitle(GLOBAL_GRID_ELEMENT_ID, title),\r\n        onHUDOpen: () => {\r\n          this.syncToResolved(GLOBAL_GRID_ELEMENT_ID);\r\n          this.renderGlobal();\r\n          this.refreshGlobalHUD();\r\n          this.syncGlobalSubBadgeState();\r\n        },\r\n        onHUDClose: () => {\r\n          this.syncToResolved(GLOBAL_GRID_ELEMENT_ID);\r\n          this.renderGlobal();\r\n          this.refreshGlobalHUD();\r\n          this.syncGlobalSubBadgeState();\r\n        },\r\n        onLayoutPanelOpen: () => this.refreshGlobalHUD(),\r\n        onLayoutPanelClose: () => this.refreshGlobalHUD(),\r\n      },\r\n      { attachTrigger: false },\r\n    );\r\n    this.globalHUD = hud;\r\n    hud.setTargetId(GLOBAL_GRID_ELEMENT_ID);\r\n    hud.setEnabled(this.enabled);\r\n\r\n    const hudScreen = this.viewportLayer.getScreenElement();\r\n    const hudRoot = hud.getHudElement();\r\n    hudRoot.setAttribute(\"data-string-grid-global-hud\", \"\");\r\n    hudRoot.style.position = \"absolute\";\r\n    hudRoot.style.left = \"24px\";\r\n    hudRoot.style.bottom = \"96px\";\r\n    hudRoot.style.pointerEvents = \"auto\";\r\n    hudScreen.appendChild(hudRoot);\r\n    hud.setAnchorVisible(true);\r\n\r\n    this.renderGlobal();\r\n    this.refreshGlobalHUD();\r\n  }\r\n\r\n  private syncGlobalHostSize(): void {\r\n    const host = this.globalHost;\r\n    if (!host) return;\r\n    const width = this.data.viewport.windowWidth || window.innerWidth;\r\n    const height = this.data.viewport.windowHeight || window.innerHeight;\r\n    host.style.width = `${width}px`;\r\n    host.style.height = `${height}px`;\r\n    this.globalOverlay?.setPosition(0, 0, width, height);\r\n  }\r\n\r\n  private renderGlobal(): void {\r\n    const overlay = this.globalOverlay;\r\n    if (!overlay) return;\r\n    const hud = this.globalHUD;\r\n    const viewportWidth = this.data.viewport.windowWidth || window.innerWidth;\r\n    const instances = hud?.isHUDOpen()\r\n      ? this.gridManager.getSelectedInstances(GLOBAL_GRID_ELEMENT_ID)\r\n      : this.gridManager.getResolvedInstances(GLOBAL_GRID_ELEMENT_ID, viewportWidth);\r\n    overlay.render(instances, this.gridManager.getAdapterRegistry());\r\n  }\r\n\r\n  private refreshGlobalHUD(): void {\r\n    const hud = this.globalHUD;\r\n    if (!hud) return;\r\n    const viewportWidth = this.data.viewport.windowWidth || window.innerWidth;\r\n    const resolvedLayoutId = this.gridManager.getResolvedLayoutId(\r\n      GLOBAL_GRID_ELEMENT_ID,\r\n      viewportWidth,\r\n    );\r\n    if (!hud.isHUDOpen()) {\r\n      const selectedLayoutId = this.gridManager.getSelectedLayoutId(GLOBAL_GRID_ELEMENT_ID);\r\n      if (selectedLayoutId !== resolvedLayoutId) {\r\n        this.gridManager.selectLayout(GLOBAL_GRID_ELEMENT_ID, resolvedLayoutId, false);\r\n      }\r\n    }\r\n    const selectedLayoutId = this.gridManager.getSelectedLayoutId(GLOBAL_GRID_ELEMENT_ID);\r\n    const instances = this.gridManager.getSelectedInstances(GLOBAL_GRID_ELEMENT_ID);\r\n    const layouts = this.gridManager.getLayouts(GLOBAL_GRID_ELEMENT_ID);\r\n    const panelTitle = this.gridManager.getPanelTitle(GLOBAL_GRID_ELEMENT_ID);\r\n    hud.refresh(instances, layouts, panelTitle, selectedLayoutId, resolvedLayoutId);\r\n  }\r\n\r\n  private toggleGlobalPanel(anchorElement?: HTMLElement): void {\r\n    this.ensureGlobalGrid();\r\n    if (anchorElement) {\r\n      this.globalSubBadge = anchorElement;\r\n    }\r\n    this.positionGlobalHudAtAnchor(anchorElement);\r\n    this.globalHUD?.toggle();\r\n    this.syncGlobalSubBadgeState();\r\n  }\r\n\r\n  private syncGlobalSubBadgeState(): void {\r\n    if (!this.globalSubBadge) return;\r\n    const open = this.globalHUD?.isHUDOpen() ?? false;\r\n    this.globalSubBadge.setAttribute(\"data-active\", open ? \"true\" : \"false\");\r\n    this.globalSubBadge.setAttribute(\"aria-expanded\", open ? \"true\" : \"false\");\r\n  }\r\n\r\n  private positionGlobalHudAtAnchor(anchorElement?: HTMLElement): void {\r\n    if (!anchorElement || !this.globalHUD) {\r\n      return;\r\n    }\r\n\r\n    const hudRoot = this.globalHUD.getHudElement();\r\n    const screen = this.viewportLayer.getScreenElement();\r\n    const anchorRect = anchorElement.getBoundingClientRect();\r\n    const screenRect = screen.getBoundingClientRect();\r\n    hudRoot.style.left = `${Math.round(anchorRect.right - screenRect.left)}px`;\r\n    hudRoot.style.top = `${Math.round(anchorRect.top - screenRect.top + 28)}px`;\r\n    hudRoot.style.bottom = \"auto\";\r\n    hudRoot.style.transform = \"\";\r\n  }\r\n\r\n  private destroyGlobalGrid(): void {\r\n    this.globalOverlay?.destroy();\r\n    this.globalOverlay = null;\r\n    this.globalHUD?.destroy();\r\n    this.globalHUD = null;\r\n    this.globalHost?.remove();\r\n    this.globalHost = null;\r\n  }\r\n\r\n  private destroyElement(elementId: string): void {\r\n    this.overlays.get(elementId)?.destroy();\r\n    this.overlays.delete(elementId);\r\n    this.huds.get(elementId)?.destroy();\r\n    this.huds.delete(elementId);\r\n    this.triggerEntries.delete(elementId);\r\n    this.triggerMeasurements.delete(elementId);\r\n    this.elementMap.get(elementId)?.removeAttribute(\"data-string-grid-root\");\r\n    this.elementMap.get(elementId)?.removeAttribute(\"data-string-grid-depth\");\r\n    this.elementMap.get(elementId)?.removeAttribute(GRID_STORAGE_KEY_ATTR);\r\n    this.elementMap.get(elementId)?.style.removeProperty(\"--string-grid-stack-offset\");\r\n    this.elementMap.delete(elementId);\r\n  }\r\n\r\n  private ensureTriggerLayer(): void {\r\n    const layer = this.viewportLayer.ensure(this.getWorldHost());\r\n    layer.setAttribute(\"data-string-grid-trigger-layer\", \"\");\r\n  }\r\n\r\n  private applyTriggerLayerState(): void {\r\n    return;\r\n  }\r\n\r\n  private scheduleTriggerSync(): void {\r\n    this.ensureTriggerLayer();\r\n    this.needsMeasure = true;\r\n    this.collectTriggerMeasurements();\r\n    this.needsMeasure = false;\r\n    for (const [elementId, entry] of this.triggerEntries) {\r\n      this.applyTriggerMeasurement(entry, this.triggerMeasurements.get(elementId));\r\n    }\r\n    this.hasPendingMutate = false;\r\n  }\r\n\r\n  private collectTriggerMeasurements(): void {\r\n    for (const [elementId, entry] of this.triggerEntries) {\r\n      this.triggerMeasurements.set(elementId, this.measureTrigger(entry));\r\n    }\r\n  }\r\n\r\n  private measureTrigger(entry: GridTriggerEntry): GridTriggerMeasurement {\r\n    const object = entry.object;\r\n    const element = object.htmlElement;\r\n    if (!this.enabled || !element || !element.isConnected) {\r\n      return { visible: false, docX: 0, docY: 0, stackOffsetY: 0 };\r\n    }\r\n\r\n    const scrollLeft = this.getViewportScrollLeft();\r\n    const scrollTop = this.getViewportScrollTop();\r\n    const rect = element.getBoundingClientRect();\r\n    const width = rect.width || element.offsetWidth || element.clientWidth || 0;\r\n    const height = rect.height || element.offsetHeight || element.clientHeight || 0;\r\n    const contentX = rect.left + scrollLeft;\r\n    const contentY = rect.top + scrollTop;\r\n\r\n    if (width <= 0 || height <= 0) {\r\n      return { visible: false, docX: 0, docY: 0, stackOffsetY: 0 };\r\n    }\r\n\r\n    const viewportHeight = this.data.viewport.windowHeight || window.innerHeight;\r\n    const viewportWidth = this.data.viewport.windowWidth || window.innerWidth;\r\n    const viewportLeft = rect.left;\r\n    const viewportTop = rect.top;\r\n    const isOffscreen =\r\n      viewportTop + height < 0 ||\r\n      viewportTop > viewportHeight ||\r\n      viewportLeft + width < 0 ||\r\n      viewportLeft > viewportWidth;\r\n\r\n    if (isOffscreen) {\r\n      return { visible: false, docX: 0, docY: 0, stackOffsetY: 0 };\r\n    }\r\n\r\n    const triggerDocX = contentX + width;\r\n    const baseTriggerDocY = contentY;\r\n    const stackOffsetY = this.resolveTriggerStackOffset(entry, triggerDocX, baseTriggerDocY);\r\n\r\n    return {\r\n      visible: true,\r\n      docX: triggerDocX,\r\n      docY: baseTriggerDocY + stackOffsetY,\r\n      stackOffsetY,\r\n      elementDocX: contentX,\r\n      elementDocY: contentY,\r\n      width,\r\n      height,\r\n    };\r\n  }\r\n\r\n  private applyTriggerMeasurement(\r\n    entry: GridTriggerEntry,\r\n    measurement: GridTriggerMeasurement | undefined,\r\n  ): void {\r\n    if (!measurement || !measurement.visible) {\r\n      entry.hud.setAnchorVisible(false);\r\n      entry.object.htmlElement.style.setProperty(\"--string-grid-stack-offset\", \"0px\");\r\n      return;\r\n    }\r\n\r\n    entry.hud.setAnchorVisible(true);\r\n    entry.object.htmlElement.style.setProperty(\r\n      \"--string-grid-stack-offset\",\r\n      `${measurement.stackOffsetY}px`,\r\n    );\r\n    entry.hud.setAnchorPosition(measurement.docX, measurement.docY, \"top-right\");\r\n\r\n    const overlay = this.overlays.get(resolveElementId(entry.object.htmlElement, entry.object));\r\n    if (\r\n      overlay &&\r\n      measurement.elementDocX != null &&\r\n      measurement.elementDocY != null &&\r\n      measurement.width != null &&\r\n      measurement.height != null\r\n    ) {\r\n      overlay.setPosition(\r\n        measurement.elementDocX,\r\n        measurement.elementDocY,\r\n        measurement.width,\r\n        measurement.height,\r\n      );\r\n    }\r\n  }\r\n\r\n  protected getWorldHost(): HTMLElement {\r\n    return this.data.scroll.container ?? document.body ?? document.documentElement;\r\n  }\r\n\r\n  private getObjectDocY(object: StringObject): number {\r\n    const start = object.getProperty<number>(\"start\");\r\n    const size = object.getProperty<number>(\"size\");\r\n    if (start != null && size != null && size > 0) {\r\n      return start;\r\n    }\r\n    return object.getProperty<number>(\"layout-doc-top\") ?? 0;\r\n  }\r\n\r\n  private getViewportScrollLeft(): number {\r\n    const scroller = this.data.scroll.elementContainer;\r\n    return scroller?.scrollLeft ?? 0;\r\n  }\r\n\r\n  private getViewportScrollTop(): number {\r\n    const scroller = this.data.scroll.elementContainer;\r\n    return scroller?.scrollTop ?? 0;\r\n  }\r\n\r\n  private resolveTriggerStackOffset(\r\n    entry: GridTriggerEntry,\r\n    triggerDocX: number,\r\n    triggerDocY: number,\r\n  ): number {\r\n    return overlaySlotRegistry.resolveCollisionOffset(\r\n      entry.object.htmlElement,\r\n      triggerDocX,\r\n      triggerDocY,\r\n      (ancestorId) => {\r\n        const ancestorObject = this.objectManager.all.get(ancestorId);\r\n        if (!ancestorObject) {\r\n          return null;\r\n        }\r\n\r\n        const ancestorWidth =\r\n          ancestorObject.getProperty<number>(\"layout-width\") ??\r\n          ancestorObject.htmlElement.offsetWidth ??\r\n          ancestorObject.htmlElement.clientWidth ??\r\n          0;\r\n\r\n        return {\r\n          docX:\r\n            (ancestorObject.getProperty<number>(\"layout-doc-left\") ?? 0) + ancestorWidth,\r\n          docY: this.getObjectDocY(ancestorObject),\r\n        };\r\n      },\r\n    );\r\n  }\r\n\r\n  private registerBuiltInAdapters(): void {\r\n    const builtIn: GridAdapter[] = [\r\n      new ColumnsAdapter(),\r\n      new RowsAdapter(),\r\n      new CenterAdapter(),\r\n      new GoldenRectangleAdapter(),\r\n      new RuleOfThirdsAdapter(),\r\n      new DotGridAdapter(),\r\n    ];\r\n\r\n    for (const adapter of builtIn) {\r\n      this.gridManager.registerAdapter(adapter);\r\n    }\r\n  }\r\n\r\n  private registerExternalAdapters(): void {\r\n    const external = this.settings[\"adapters\"] as GridAdapter[] | undefined;\r\n    if (!external) return;\r\n\r\n    for (const adapter of external) {\r\n      this.gridManager.registerAdapter(adapter);\r\n    }\r\n  }\r\n}\r\n\r\nexport { StringDevLayout as StringGrid };\r\n","export const RULERS_CSS = `\n  /* ── Ruler bars ── */\n  [data-string-rulers-top],\n  [data-string-rulers-left] {\n    position: absolute;\n    z-index: 3;\n    display: block;\n    cursor: crosshair;\n    image-rendering: pixelated;\n    transition: opacity 0.15s ease;\n  }\n\n  [data-string-rulers-top] {\n    top: 0; left: 0;\n    width: 100%; height: 20px;\n    pointer-events: auto;\n  }\n\n  [data-string-rulers-left] {\n    top: 0; left: 0;\n    width: 20px; height: 100%;\n    pointer-events: auto;\n  }\n\n  /* ── Corner mode toggle ── */\n  [data-string-rulers-corner] {\n    position: absolute;\n    top: 0; left: 0;\n    width: 20px; height: 20px;\n    z-index: 4;\n    background: var(--string-dg-color-cloud-white);\n    border: 1px solid var(--string-dg-color-middle-white);\n    border-radius: var(--string-dg-panel-button-radius);\n    box-sizing: border-box;\n    display: flex;\n    align-items: center;\n    justify-content: center;\n    pointer-events: auto;\n    cursor: pointer;\n    transition: opacity 0.15s ease, background 0.15s ease;\n  }\n\n  [data-string-rulers-corner]:hover {\n    background: var(--string-dg-color-grey-1);\n  }\n\n  [data-string-rulers-corner][data-mode=\"center\"] {\n    background: var(--string-dg-color-grey-2);\n  }\n  [data-string-rulers-corner][data-mode=\"center\"]:hover {\n    background: var(--string-dg-color-grey-3);\n  }\n\n  [data-string-rulers-corner] > span {\n    font: 10px \"JetBrains Mono\", monospace;\n    color: var(--string-dg-color-grey-6, #888888);\n    white-space: nowrap;\n    line-height: 1;\n    pointer-events: none;\n    user-select: none;\n  }\n\n  [data-string-rulers-corner][data-mode=\"center\"] > span {\n    color: var(--string-dg-color-blue, #3B82F6);\n  }\n\n  @media (max-width: 1024px) {\n    [data-string-rulers-top] {\n      height: 12px;\n    }\n\n    [data-string-rulers-left] {\n      width: 12px;\n    }\n\n    [data-string-rulers-corner] {\n      width: 12px;\n      height: 12px;\n      border-radius: 6px;\n    }\n\n    [data-string-rulers-corner] > span {\n      font-size: 8px;\n    }\n  }\n\n  /* ── Layout grid canvas ── */\n  [data-string-rulers-grid] {\n    position: absolute;\n    top: 0; left: 0;\n    z-index: 1;\n    pointer-events: none;\n    image-rendering: pixelated;\n    transition: opacity 0.15s ease;\n  }\n\n  /* ── Lines layer ── */\n  [data-string-rulers-lines] {\n    position: absolute;\n    top: 0;\n    left: 0;\n    pointer-events: none;\n    z-index: 2;\n    overflow: hidden;\n  }\n\n  /* ── Guide lines ── */\n  [data-string-rulers-line] {\n    position: absolute;\n    pointer-events: auto;\n    opacity: var(--string-rulers-line-opacity, 1);\n  }\n\n  [data-string-rulers-line][data-axis=\"horizontal\"] {\n    border-top: 1px solid var(--string-rulers-line-color, rgba(0, 120, 255, 0.4));\n    height: 0;\n    cursor: row-resize;\n  }\n\n  [data-string-rulers-line][data-axis=\"vertical\"] {\n    border-left: 1px solid var(--string-rulers-line-color, rgba(0, 120, 255, 0.4));\n    width: 0;\n    cursor: col-resize;\n  }\n\n  /* ── Expanded hit area via ::before ──\n     Adds 5px grab zone above/below horizontal lines,\n     and 5px left/right of vertical lines — no change to visuals. */\n  [data-string-rulers-line][data-axis=\"horizontal\"]::before {\n    content: '';\n    display: block;\n    position: absolute;\n    left: 0; right: 0;\n    top: -5px;\n    height: 11px;\n  }\n\n  [data-string-rulers-line][data-axis=\"vertical\"]::before {\n    content: '';\n    display: block;\n    position: absolute;\n    top: 0; bottom: 0;\n    left: -5px;\n    width: 11px;\n  }\n\n  [data-string-rulers-line]:hover {\n    border-color: rgba(255, 60, 60, 0.5);\n  }\n\n  /* ── Coordinate label ── */\n  [data-string-rulers-label] {\n    position: absolute;\n    top: 2px; left: 24px;\n    padding: 2px 2px;\n    background-color: var(--string-dg-color-blue);\n    color: var(--string-dg-color-white);\n    font-size: var(--string-dg-font-size-xs);\n    font-weight: var(--string-dg-font-medium);\n    line-height: 1;\n    letter-spacing: 0.04em;\n    text-transform: uppercase;\n    box-sizing: border-box;\n    pointer-events: none;\n    white-space: nowrap;\n  }\n\n  [data-string-rulers-line][data-axis=\"vertical\"] [data-string-rulers-label] {\n    top: 24px; left: 2px;\n    writing-mode: vertical-lr;\n  }\n\n  /* ── Snap: ELEMENT (amber) ── */\n  [data-string-rulers-line][data-snapping=\"element\"][data-axis=\"horizontal\"] {\n    border-top-color: rgba(220, 120, 0, 0.5);\n  }\n  [data-string-rulers-line][data-snapping=\"element\"][data-axis=\"vertical\"] {\n    border-left-color: rgba(220, 120, 0, 0.5);\n  }\n  [data-string-rulers-line][data-snapping=\"element\"] [data-string-rulers-label] {\n    background-color: var(--string-dg-color-amber, rgba(180, 80, 0, 0.95));\n    color: var(--string-dg-color-white);\n  }\n\n  /* ── Snap: GRID (green) ── */\n  [data-string-rulers-line][data-snapping=\"grid\"][data-axis=\"horizontal\"] {\n    border-top-color: rgba(0, 170, 80, 0.5);\n  }\n  [data-string-rulers-line][data-snapping=\"grid\"][data-axis=\"vertical\"] {\n    border-left-color: rgba(0, 170, 80, 0.5);\n  }\n  [data-string-rulers-line][data-snapping=\"grid\"] [data-string-rulers-label] {\n    background-color: var(--string-dg-color-green, rgba(0, 130, 60, 0.95));\n    color: var(--string-dg-color-white);\n  }\n\n  /* ── Snap: GUIDE GAP (cyan) ── */\n  [data-string-rulers-line][data-snapping=\"guide\"][data-axis=\"horizontal\"] {\n    border-top-color: rgba(0, 150, 170, 0.5);\n  }\n  [data-string-rulers-line][data-snapping=\"guide\"][data-axis=\"vertical\"] {\n    border-left-color: rgba(0, 150, 170, 0.5);\n  }\n  [data-string-rulers-line][data-snapping=\"guide\"] [data-string-rulers-label] {\n    background-color: var(--string-dg-color-teal, rgba(0, 120, 140, 0.95));\n    color: var(--string-dg-color-white);\n  }\n\n  /* ── Snap: COLUMN (magenta) ── */\n  [data-string-rulers-line][data-snapping=\"column\"][data-axis=\"horizontal\"] {\n    border-top-color: rgba(200, 0, 100, 0.5);\n  }\n  [data-string-rulers-line][data-snapping=\"column\"][data-axis=\"vertical\"] {\n    border-left-color: rgba(200, 0, 100, 0.5);\n  }\n  [data-string-rulers-line][data-snapping=\"column\"] [data-string-rulers-label] {\n    background-color: var(--string-dg-color-crimson, rgba(160, 0, 80, 0.95));\n    color: var(--string-dg-color-white);\n  }\n\n  /* ── Guide-gap references ── */\n  [data-string-rulers-line][data-string-rulers-guide-ref][data-axis=\"horizontal\"] {\n    border-top-color: rgba(0, 150, 170, 0.35);\n  }\n  [data-string-rulers-line][data-string-rulers-guide-ref][data-axis=\"vertical\"] {\n    border-left-color: rgba(0, 150, 170, 0.35);\n  }\n\n  [data-string-rulers-gap-indicator] {\n    \n    position: absolute;\n    pointer-events: none;\n    z-index: 4;\n  }\n\n  [data-string-rulers-gap-indicator][data-axis=\"vertical\"] {\n    border-top: 1px dashed rgba(0, 150, 170, 0.5);\n  }\n\n  [data-string-rulers-gap-indicator][data-axis=\"horizontal\"] {\n    border-left: 1px dashed rgba(0, 150, 170, 0.5);\n  }\n\n  [data-string-rulers-gap-indicator-label] {\n    position: absolute;\n    font-size: var(--string-dg-font-size-s);\n    font-weight: var(--string-dg-font-medium);\n    color: var(--string-dg-color-white);\n    background: var(--string-dg-color-teal, rgba(0, 120, 140, 0.95));\n    padding: 2px 4px;\n    white-space: nowrap;\n    line-height: 1;\n    letter-spacing: 0.04em;\n    text-transform: uppercase;\n    box-sizing: border-box;\n  }\n\n  [data-string-rulers-gap-indicator][data-axis=\"vertical\"] [data-string-rulers-gap-indicator-label] {\n    left: 50%;\n    top: 50%;\n    transform: translate(-50%, -50%);\n  }\n\n  [data-string-rulers-gap-indicator][data-axis=\"horizontal\"] [data-string-rulers-gap-indicator-label] {\n    left: 50%;\n    top: 50%;\n    transform: translate(-50%, -50%);\n  }\n\n  /* ── Snap target element highlight ── */\n  [data-string-rulers-snap-target] {\n    outline: 1px dashed rgba(220, 120, 0, 0.3) !important;\n    outline-offset: 0px;\n  }\n\n  /* ── Ghost (preview during drag from ruler) ── */\n  [data-string-rulers-ghost] {\n    color: var(--string-dg-color-white);\n    font-size: var(--string-dg-font-size-xs);\n    font-weight: var(--string-dg-font-medium);\n    position: absolute;\n    pointer-events: none;\n    opacity: calc(var(--string-rulers-line-opacity, 1) * 0.45);\n  }\n\n  [data-string-rulers-ghost][data-axis=\"horizontal\"] {\n    border-top: 1px dashed var(--string-rulers-line-color, rgba(0, 120, 255, 0.4));\n    height: 0;\n  }\n\n  [data-string-rulers-ghost][data-axis=\"vertical\"] {\n    border-left: 1px dashed var(--string-rulers-line-color, rgba(0, 120, 255, 0.4));\n    width: 0;\n  }\n\n  /* Ghost snap: ELEMENT (amber) */\n  [data-string-rulers-ghost][data-snapping=\"element\"][data-axis=\"horizontal\"] {\n    border-top-style: solid;\n    border-top-color: rgba(220, 120, 0, 0.5);\n    opacity: 0.55;\n  }\n  [data-string-rulers-ghost][data-snapping=\"element\"][data-axis=\"vertical\"] {\n    border-left-style: solid;\n    border-left-color: rgba(220, 120, 0, 0.5);\n    opacity: 0.55;\n  }\n\n  /* Ghost snap: GRID (green) */\n  [data-string-rulers-ghost][data-snapping=\"grid\"][data-axis=\"horizontal\"] {\n    border-top-style: solid;\n    border-top-color: rgba(0, 170, 80, 0.5);\n    opacity: 0.55;\n  }\n  [data-string-rulers-ghost][data-snapping=\"grid\"][data-axis=\"vertical\"] {\n    border-left-style: solid;\n    border-left-color: rgba(0, 170, 80, 0.5);\n    opacity: 0.55;\n  }\n\n  /* Ghost snap: COLUMN (magenta) */\n  [data-string-rulers-ghost][data-snapping=\"column\"][data-axis=\"horizontal\"] {\n    border-top-style: solid;\n    border-top-color: rgba(200, 0, 100, 0.5);\n    opacity: 0.55;\n  }\n  [data-string-rulers-ghost][data-snapping=\"column\"][data-axis=\"vertical\"] {\n    border-left-style: solid;\n    border-left-color: rgba(200, 0, 100, 0.5);\n    opacity: 0.55;\n  }\n\n  /* Ghost snap: GUIDE GAP (cyan) */\n  [data-string-rulers-ghost][data-snapping=\"guide\"][data-axis=\"horizontal\"] {\n    border-top-style: solid;\n    border-top-color: rgba(0, 150, 170, 0.5);\n    opacity: 0.55;\n  }\n  [data-string-rulers-ghost][data-snapping=\"guide\"][data-axis=\"vertical\"] {\n    border-left-style: solid;\n    border-left-color: rgba(0, 150, 170, 0.5);\n    opacity: 0.55;\n  }\n\n  /* ── Ghost coordinate label ── */\n  [data-string-rulers-ghost-label] {\n    position: absolute;\n    font-size: var(--string-dg-font-size-xs);\n    font-weight: var(--string-dg-font-medium);\n    color: var(--string-dg-color-white);\n    background: var(--string-dg-color-blue);\n    padding: 2px 4px;\n    pointer-events: none;\n    white-space: nowrap;\n    line-height: 1;\n    letter-spacing: 0.04em;\n    text-transform: uppercase;\n    box-sizing: border-box;\n  }\n\n  [data-string-rulers-ghost][data-snapping=\"element\"] [data-string-rulers-ghost-label] {\n    background-color: var(--string-dg-color-amber, rgba(180, 80, 0, 0.95));\n    color: var(--string-dg-color-white);\n  }\n  [data-string-rulers-ghost][data-snapping=\"grid\"] [data-string-rulers-ghost-label] {\n    background-color: var(--string-dg-color-green, rgba(0, 130, 60, 0.95));\n    color: var(--string-dg-color-white);\n  }\n  [data-string-rulers-ghost][data-snapping=\"guide\"] [data-string-rulers-ghost-label] {\n    background-color: var(--string-dg-color-teal, rgba(0, 120, 140, 0.95));\n    color: var(--string-dg-color-white);\n  }\n  [data-string-rulers-ghost][data-snapping=\"column\"] [data-string-rulers-ghost-label] {\n    background-color: var(--string-dg-color-crimson, rgba(160, 0, 80, 0.95));\n    color: var(--string-dg-color-white);\n  }\n\n  [data-axis=\"horizontal\"] [data-string-rulers-ghost-label] {\n    top: 3px; left: 24px;\n  }\n  [data-axis=\"vertical\"] [data-string-rulers-ghost-label] {\n    left: 3px; top: 24px;\n  }\n\n  /* ── Fixed guide lines (center cross, etc.) ── */\n  [data-string-rulers-fixed-line] {\n    position: absolute;\n    pointer-events: none;\n  }\n\n  [data-string-rulers-fixed-line][data-axis=\"horizontal\"] {\n    border-top: 1px dashed rgba(100, 100, 100, 0.18);\n    height: 0;\n  }\n\n  [data-string-rulers-fixed-line][data-axis=\"vertical\"] {\n    border-left: 1px dashed rgba(100, 100, 100, 0.18);\n    width: 0;\n  }\n\n  /* ── Hidden state ── */\n  [data-string-rulers-hidden] [data-string-rulers-grid],\n  [data-string-rulers-hidden] [data-string-rulers-top],\n  [data-string-rulers-hidden] [data-string-rulers-left],\n  [data-string-rulers-hidden] [data-string-rulers-corner],\n  [data-string-rulers-hidden] [data-string-rulers-lines],\n  [data-string-rulers-hidden] [data-string-rulers-line],\n  [data-string-rulers-hidden] [data-string-rulers-fixed-line],\n  [data-string-rulers-hidden] [data-string-rulers-gap-indicator],\n  [data-string-rulers-hidden] [data-string-rulers-ghost] {\n    opacity: 0;\n    visibility: hidden;\n    pointer-events: none;\n  }\n`;\n","/**\n * A single guide line dragged out from a ruler.\n */\nexport interface RulerLine {\n  /** Unique identifier */\n  readonly id: string;\n\n  /** Orientation of the line */\n  readonly axis: \"horizontal\" | \"vertical\";\n\n  /**\n   * Position in pixels relative to the target element's content edge.\n   * - horizontal  → distance from the top\n   * - vertical    → distance from the left\n   */\n  position: number;\n\n  /** Optional snap target label rendered next to the coordinate. */\n  targetLabel?: string;\n\n  /** CSS selector to re-find the element this line is bound to. */\n  targetSelector?: string;\n\n  /** Which edge/center of the target this line tracks. */\n  targetEdge?:\n    | \"top\" | \"bottom\" | \"center-y\" | \"left\" | \"right\" | \"center-x\"\n    | \"col-left\" | \"col-right\" | \"col-center\";\n}\n\n/**\n * Serialisable snapshot for one element.\n */\nexport interface RulerElementState {\n  readonly elementId: string;\n  lines: RulerLine[];\n}\n\nlet _nextId = 0;\nexport function createRulerLineId(): string {\n  return `ruler-${Date.now()}-${_nextId++}`;\n}\n","import { RulerLine, RulerElementState, createRulerLineId } from \"./models/RulerLine\";\nimport type { RulerModeId } from \"./models/RulerMode\";\nimport { scopeStringDevStorageKey } from \"../core/StringDevStorageScope\";\n\nconst STORAGE_PREFIX = \"string-rulers:\";\n\n/**\n * Centralized state manager for ruler lines across all elements.\n *\n * Responsibilities:\n * - Per-element, per-mode RulerLine CRUD\n * - Persistence to / from localStorage\n */\nexport class RulersManager {\n  private elementStates: Map<string, RulerElementState> = new Map();\n\n  private stateKey(elementId: string, modeId: RulerModeId = \"default\"): string {\n    return `${elementId}:${modeId}`;\n  }\n\n  private storageKey(elementId: string, modeId: RulerModeId = \"default\"): string {\n    return scopeStringDevStorageKey(STORAGE_PREFIX + elementId + \":\" + modeId);\n  }\n\n  private legacyStorageKey(elementId: string): string {\n    return scopeStringDevStorageKey(STORAGE_PREFIX + elementId);\n  }\n\n  // ── Line Management ───────────────────────────────────\n\n  getLines(elementId: string, modeId: RulerModeId = \"default\"): RulerLine[] {\n    return this.elementStates.get(this.stateKey(elementId, modeId))?.lines ?? [];\n  }\n\n  addLine(\n    elementId: string,\n    axis: \"horizontal\" | \"vertical\",\n    position: number,\n    targetLabel?: string,\n    modeId: RulerModeId = \"default\",\n    targetSelector?: string,\n    targetEdge?: RulerLine[\"targetEdge\"],\n  ): RulerLine {\n    const line: RulerLine = { id: createRulerLineId(), axis, position, targetLabel, targetSelector, targetEdge };\n    const key = this.stateKey(elementId, modeId);\n\n    let state = this.elementStates.get(key);\n    if (!state) {\n      state = { elementId, lines: [] };\n      this.elementStates.set(key, state);\n    }\n\n    state.lines.push(line);\n    this.save(elementId, modeId);\n    return line;\n  }\n\n  /**\n   * Updates the position of an existing line (called while dragging).\n   * Does NOT persist on every move — call `save()` explicitly when drag ends.\n   */\n  moveLine(\n    elementId: string,\n    lineId: string,\n    position: number,\n    targetLabel?: string,\n    modeId: RulerModeId = \"default\",\n  ): void {\n    const line = this.findLine(elementId, lineId, modeId);\n    if (!line) return;\n    line.position = position;\n    line.targetLabel = targetLabel;\n  }\n\n  removeLine(elementId: string, lineId: string, modeId: RulerModeId = \"default\"): void {\n    const state = this.elementStates.get(this.stateKey(elementId, modeId));\n    if (!state) return;\n    state.lines = state.lines.filter((l) => l.id !== lineId);\n    this.save(elementId, modeId);\n  }\n\n  removeAllLines(elementId: string, modeId: RulerModeId = \"default\"): void {\n    this.elementStates.delete(this.stateKey(elementId, modeId));\n    try {\n      localStorage.removeItem(this.storageKey(elementId, modeId));\n      if (modeId === \"default\") {\n        localStorage.removeItem(this.legacyStorageKey(elementId));\n      }\n    } catch {\n      // localStorage may be unavailable\n    }\n  }\n\n  findLine(elementId: string, lineId: string, modeId: RulerModeId = \"default\"): RulerLine | undefined {\n    return this.elementStates.get(this.stateKey(elementId, modeId))?.lines.find((l) => l.id === lineId);\n  }\n\n  // ── Persistence ───────────────────────────────────────\n\n  save(elementId: string, modeId: RulerModeId = \"default\"): void {\n    const state = this.elementStates.get(this.stateKey(elementId, modeId));\n    if (!state) return;\n    try {\n      const serialized = JSON.stringify(state.lines);\n      localStorage.setItem(this.storageKey(elementId, modeId), serialized);\n      if (modeId === \"default\") {\n        localStorage.setItem(this.legacyStorageKey(elementId), serialized);\n      }\n    } catch {\n      // localStorage may be unavailable\n    }\n  }\n\n  load(elementId: string, modeId: RulerModeId = \"default\"): void {\n    const key = this.stateKey(elementId, modeId);\n    try {\n      let raw = localStorage.getItem(this.storageKey(elementId, modeId));\n\n      // Migration: if mode-qualified key is absent and this is \"default\",\n      // try the old unqualified key (pre-modes format).\n      if (!raw && modeId === \"default\") {\n        raw = localStorage.getItem(this.legacyStorageKey(elementId));\n      }\n\n      if (!raw) return;\n      const lines: RulerLine[] = JSON.parse(raw);\n      if (!Array.isArray(lines)) return;\n      this.elementStates.set(key, { elementId, lines });\n    } catch {\n      // ignore corrupt data\n    }\n  }\n\n  clearElement(elementId: string): void {\n    for (const [key] of this.elementStates) {\n      if (key.startsWith(elementId + \":\")) {\n        this.elementStates.delete(key);\n      }\n    }\n  }\n\n  clearAll(): void {\n    this.elementStates.clear();\n  }\n}\n","import type { RulerLine } from \"./models/RulerLine\";\nimport type { RulersLayoutGrid } from \"./models/RulersLayoutGrid\";\n\n/**\n * Snap candidate types.\n * Discriminated by the edge/center role for tooltip/highlight labelling.\n */\nexport type SnapCandidateType =\n  | \"element-top\"\n  | \"element-bottom\"\n  | \"element-center-y\"\n  | \"element-left\"\n  | \"element-right\"\n  | \"element-center-x\"\n  | \"viewport-edge\"\n  | \"document-origin\"\n  | \"grid-column-edge\"\n  | \"grid-column-center\"\n  | \"grid-row-edge\"\n  | \"guide-gap\";\n\nexport interface SnapCandidate {\n  /** Document-coordinate position (px from document origin). */\n  position: number;\n  type: SnapCandidateType;\n  /** Source DOM element, if this candidate came from an element edge/center. */\n  el?: Element;\n  /** Mirrored spacing between nearby guides. */\n  gap?: number;\n  /** Reference guides that define the mirrored spacing. */\n  referenceLineIds?: [string, string];\n  /** Custom display label for snap feedback. */\n  label?: string;\n}\n\nexport interface SnapResult {\n  position: number;\n  type: SnapCandidateType | \"grid-step\";\n  el?: Element;\n  gap?: number;\n  referenceLineIds?: [string, string];\n  label?: string;\n}\n\nexport interface SnapEngineOptions {\n  /**\n   * Pixel distance within which a snap candidate is considered active.\n   * Screen pixels — the same threshold applies regardless of scroll position.\n   */\n  threshold: number;\n\n  /**\n   * Grid step in document pixels. 0 / 1 = disabled.\n   * Element/viewport/layout-grid candidates take priority when equidistant.\n   */\n  snapStep: number;\n\n  /** Whether to collect element edge/center candidates. */\n  snapToElements: boolean;\n\n  /**\n   * CSS selector used to collect element candidates.\n   * All matching elements are measured via getBoundingClientRect().\n   */\n  snapSelector: string;\n\n  /**\n   * Layout grids (columns / rows) whose edges are also added as snap candidates.\n   * Column edges are viewport-relative; row edges are document-relative.\n   */\n  layoutGrids?: RulersLayoutGrid[];\n}\n\n/**\n * Pure snap-calculation engine — no DOM mutations, no side-effects.\n *\n * Usage:\n *   1. Call `buildCandidates(axis, scrollX, scrollY)` once at drag start.\n *   2. Call `findSnap(rawDocPos)` on every pointermove.\n *   3. Use `snapToStep(pos)` as a lightweight grid-only fallback.\n */\nexport class SnapEngine {\n  private opts: SnapEngineOptions;\n  private candidates: SnapCandidate[] = [];\n\n  constructor(opts: SnapEngineOptions) {\n    this.opts = opts;\n  }\n\n  // ── Candidate collection ──────────────────────────────\n\n  /**\n   * Collects all snap candidates for the given drag axis.\n   * Must be called at drag-start with the current scroll offsets.\n   *\n   * @param axis       \"horizontal\" → Y candidates; \"vertical\" → X candidates\n   * @param scrollX    Current horizontal scroll (document px from origin)\n   * @param scrollY    Current vertical scroll (document px from origin)\n   */\n  buildCandidates(\n    axis: \"horizontal\" | \"vertical\",\n    scrollX: number,\n    scrollY: number,\n    viewportWidth: number = window.innerWidth,\n    viewportHeight: number = window.innerHeight,\n    lines: RulerLine[] = [],\n    excludeLineId?: string,\n    extraCandidates?: SnapCandidate[],\n  ): void {\n    this.candidates = [];\n\n    // ── Document origin ──\n    this.candidates.push({ position: 0, type: \"document-origin\" });\n\n    // ── Viewport edges (in document coords) ──\n    if (axis === \"horizontal\") {\n      this.candidates.push({ position: scrollY, type: \"viewport-edge\" });\n      this.candidates.push({ position: scrollY + viewportHeight, type: \"viewport-edge\" });\n    } else {\n      this.candidates.push({ position: scrollX, type: \"viewport-edge\" });\n      this.candidates.push({ position: scrollX + viewportWidth, type: \"viewport-edge\" });\n    }\n\n    // ── Element edges / centers ──\n    if (this.opts.snapToElements && this.opts.snapSelector) {\n      document.querySelectorAll(this.opts.snapSelector).forEach((el) => {\n        const rect = el.getBoundingClientRect();\n        if (rect.width === 0 && rect.height === 0) return;\n\n        if (axis === \"horizontal\") {\n          this.candidates.push({ position: rect.top + scrollY,    type: \"element-top\",      el });\n          this.candidates.push({ position: rect.bottom + scrollY, type: \"element-bottom\",   el });\n          this.candidates.push({\n            position: (rect.top + rect.bottom) / 2 + scrollY,\n            type: \"element-center-y\",\n            el,\n          });\n        } else {\n          this.candidates.push({ position: rect.left + scrollX,  type: \"element-left\",     el });\n          this.candidates.push({ position: rect.right + scrollX, type: \"element-right\",    el });\n          this.candidates.push({\n            position: (rect.left + rect.right) / 2 + scrollX,\n            type: \"element-center-x\",\n            el,\n          });\n        }\n      });\n    }\n\n    // ── Layout grid candidates ──\n    this._addLayoutGridCandidates(axis, scrollX, scrollY, viewportWidth, viewportHeight);\n    this._addGuideGapCandidates(axis, lines, excludeLineId);\n\n    // ── External candidates (e.g. column layout) ──\n    if (extraCandidates) {\n      this.candidates.push(...extraCandidates);\n    }\n  }\n\n  // ── Snap resolution ───────────────────────────────────\n\n  /**\n   * Returns the best snap result for a raw document position,\n   * or `null` if nothing is within threshold.\n   *\n   * Element / viewport / layout-grid candidates beat grid-step when equidistant.\n   */\n  findSnap(rawDocPos: number): SnapResult | null {\n    let bestDist = this.opts.threshold;\n    let best: SnapCandidate | null = null;\n\n    for (const c of this.candidates) {\n      const dist = Math.abs(c.position - rawDocPos);\n      if (dist < bestDist) {\n        bestDist = dist;\n        best = c;\n      }\n    }\n\n    // Grid-step snap — only wins if strictly closer than any candidate\n    if (this.opts.snapStep > 1) {\n      const stepped = Math.round(rawDocPos / this.opts.snapStep) * this.opts.snapStep;\n      const dist = Math.abs(stepped - rawDocPos);\n      if (dist < bestDist) {\n        return { position: stepped, type: \"grid-step\" };\n      }\n    }\n\n    return best\n      ? {\n        position: best.position,\n        type: best.type,\n        el: best.el,\n        gap: best.gap,\n        referenceLineIds: best.referenceLineIds,\n        label: best.label,\n      }\n      : null;\n  }\n\n  /**\n   * Grid-step snap only — no threshold, no element candidates.\n   * Used as a plain rounding fallback when no dynamic snap result is needed.\n   */\n  snapToStep(pos: number): number {\n    if (this.opts.snapStep <= 1) return pos;\n    return Math.round(pos / this.opts.snapStep) * this.opts.snapStep;\n  }\n\n  // ── Layout grid candidates ────────────────────────────\n\n  private _addLayoutGridCandidates(\n    axis: \"horizontal\" | \"vertical\",\n    scrollX: number,\n    scrollY: number,\n    viewportWidth: number,\n    viewportHeight: number,\n  ): void {\n    if (!this.opts.layoutGrids?.length) return;\n\n    const vw = viewportWidth;\n    const vh = viewportHeight;\n\n    for (const grid of this.opts.layoutGrids) {\n      if (grid.type === \"columns\" && axis === \"vertical\") {\n        // Column grid → X candidates (converted to document coords via +scrollX)\n        const { count, marginLeft = 0, marginRight = 0, gap = 0 } = grid;\n        const usableWidth = vw - marginLeft - marginRight;\n        if (usableWidth <= 0 || count <= 0) continue;\n        const colWidth = (usableWidth - (count - 1) * gap) / count;\n\n        // Outer margin edges\n        this.candidates.push({ position: marginLeft + scrollX,         type: \"grid-column-edge\" });\n        this.candidates.push({ position: vw - marginRight + scrollX,   type: \"grid-column-edge\" });\n\n        for (let i = 0; i < count; i++) {\n          const left   = marginLeft + i * (colWidth + gap);\n          const right  = left + colWidth;\n          const center = (left + right) / 2;\n          // Inner column edges (exclude outer margins, already added above)\n          if (i > 0)          this.candidates.push({ position: left   + scrollX, type: \"grid-column-edge\"   });\n          if (i < count - 1)  this.candidates.push({ position: right  + scrollX, type: \"grid-column-edge\"   });\n          this.candidates.push(                    { position: center + scrollX, type: \"grid-column-center\" });\n        }\n      }\n\n      if (grid.type === \"rows\" && axis === \"horizontal\") {\n        // Row grid → Y candidates in document coords (rows scroll with content)\n        const { height, gap = 0 } = grid;\n        const period = height + gap;\n        if (period <= 0 || height <= 0) continue;\n\n        // Cover the visible range + buffer so drags within the viewport always snap\n        const rangeStart = Math.max(0, scrollY - 200);\n        const rangeEnd   = scrollY + vh + 200;\n        const firstRow   = Math.floor(rangeStart / period) * period;\n\n        for (let pos = firstRow; pos < rangeEnd; pos += period) {\n          this.candidates.push({ position: pos,          type: \"grid-row-edge\" });\n          if (gap > 0) {\n            // When there's a gap, the row bottom is also a distinct edge\n            this.candidates.push({ position: pos + height, type: \"grid-row-edge\" });\n          }\n        }\n      }\n    }\n  }\n\n  private _addGuideGapCandidates(\n    axis: \"horizontal\" | \"vertical\",\n    lines: RulerLine[],\n    excludeLineId?: string,\n  ): void {\n    const axisLines = lines\n      .filter((line) => line.axis === axis && line.id !== excludeLineId)\n      .slice()\n      .sort((a, b) => a.position - b.position);\n\n    if (axisLines.length < 2) return;\n\n    for (let i = 0; i < axisLines.length; i++) {\n      const base = axisLines[i];\n      const prev = i > 0 ? axisLines[i - 1] : null;\n      const next = i < axisLines.length - 1 ? axisLines[i + 1] : null;\n\n      if (prev) {\n        const gap = base.position - prev.position;\n        if (gap > 0) {\n          this.candidates.push({\n            position: base.position + gap,\n            type: \"guide-gap\",\n            gap,\n            referenceLineIds: [prev.id, base.id],\n          });\n        }\n      }\n\n      if (next) {\n        const gap = next.position - base.position;\n        if (gap > 0) {\n          this.candidates.push({\n            position: base.position - gap,\n            type: \"guide-gap\",\n            gap,\n            referenceLineIds: [base.id, next.id],\n          });\n        }\n      }\n    }\n  }\n}\n","/**\n * Mode identifiers for the ruler overlay.\n * Add new entries here and register a corresponding RulerMode\n * implementation in RULER_MODES below.\n */\nexport type RulerModeId = \"default\" | \"center\";\n\n/**\n * A non-interactive guide line rendered by the mode itself\n * (e.g. the center-cross in \"center\" mode).\n */\nexport interface FixedGuideLine {\n  axis: \"horizontal\" | \"vertical\";\n  /** Absolute document-coordinate position (px). */\n  position: number;\n}\n\n/**\n * Strategy interface for ruler modes.\n *\n * Each mode controls:\n *  - how tick-mark numbers are displayed\n *  - what the corner element shows\n *  - whether any permanent helper lines exist\n */\nexport interface RulerMode {\n  readonly id: RulerModeId;\n\n  /** Label shown inside the corner square. */\n  readonly cornerLabel: string;\n\n  /**\n   * Transforms an absolute document-coordinate into a display value\n   * for ruler ticks and guide-line labels.\n   *\n   * Default mode: identity (returns docPos).\n   * Center mode:  returns offset from viewport center.\n   */\n  formatPosition(\n    docPos: number,\n    axis: \"horizontal\" | \"vertical\",\n    viewportSize: number,\n    scroll: number,\n  ): number;\n\n  /**\n   * Returns permanent (non-removable, non-draggable) guide lines\n   * for this mode. Called every scroll/resize frame.\n   */\n  getFixedLines(\n    viewportWidth: number,\n    viewportHeight: number,\n    scrollX: number,\n    scrollY: number,\n  ): FixedGuideLine[];\n}\n\n// ── Concrete modes ──────────────────────────────────────\n\nclass DefaultMode implements RulerMode {\n  readonly id = \"default\" as const;\n  readonly cornerLabel = \"↗\";\n\n  formatPosition(docPos: number): number {\n    return docPos;\n  }\n\n  getFixedLines(): FixedGuideLine[] {\n    return [];\n  }\n}\n\nclass CenterMode implements RulerMode {\n  readonly id = \"center\" as const;\n  readonly cornerLabel = \"+\";\n\n  formatPosition(\n    docPos: number,\n    axis: \"horizontal\" | \"vertical\",\n    viewportSize: number,\n    scroll: number,\n  ): number {\n    const center = scroll + viewportSize / 2;\n    return docPos - center;\n  }\n\n  getFixedLines(\n    viewportWidth: number,\n    viewportHeight: number,\n    scrollX: number,\n    scrollY: number,\n  ): FixedGuideLine[] {\n    return [\n      { axis: \"horizontal\", position: scrollY + viewportHeight / 2 },\n      { axis: \"vertical\",   position: scrollX + viewportWidth  / 2 },\n    ];\n  }\n}\n\n// ── Registry ────────────────────────────────────────────\n\nexport const RULER_MODES: Record<RulerModeId, RulerMode> = {\n  default: new DefaultMode(),\n  center:  new CenterMode(),\n};\n\n/** Cycling order for corner-click. */\nexport const MODE_ORDER: RulerModeId[] = [\"default\", \"center\"];\n","export interface PointerDragDelta {\n  dx: number;\n  dy: number;\n}\n\nexport interface PointerDragHandlers {\n  threshold?: number;\n  onMove(event: PointerEvent, delta: PointerDragDelta): void;\n  onEnd?(event: PointerEvent): void;\n  onCancel?(): void;\n}\n\nexport function startPointerDrag(\n  startEvent: PointerEvent,\n  handlers: PointerDragHandlers,\n): () => void {\n  const originEl = startEvent.currentTarget as Element | null;\n  const startX = startEvent.clientX;\n  const startY = startEvent.clientY;\n  const pointerId = startEvent.pointerId;\n  const threshold = handlers.threshold ?? 0;\n\n  let started = threshold === 0;\n  let disposed = false;\n\n  try {\n    if (originEl && \"setPointerCapture\" in originEl) {\n      (originEl as Element & { setPointerCapture(id: number): void }).setPointerCapture(pointerId);\n    }\n  } catch {\n    /* capture may fail on synthetic events */\n  }\n\n  const dispose = () => {\n    if (disposed) return;\n    disposed = true;\n    document.removeEventListener(\"pointermove\", onMove);\n    document.removeEventListener(\"pointerup\", onEnd);\n    document.removeEventListener(\"pointercancel\", onCancel);\n    document.removeEventListener(\"keydown\", onKey);\n    try {\n      if (originEl && \"releasePointerCapture\" in originEl) {\n        (\n          originEl as Element & { releasePointerCapture(id: number): void }\n        ).releasePointerCapture(pointerId);\n      }\n    } catch {\n      /* ignore */\n    }\n  };\n\n  const onMove = (e: PointerEvent) => {\n    if (e.pointerId !== pointerId) return;\n    const dx = e.clientX - startX;\n    const dy = e.clientY - startY;\n    if (!started) {\n      if (Math.abs(dx) < threshold && Math.abs(dy) < threshold) return;\n      started = true;\n    }\n    handlers.onMove(e, { dx, dy });\n  };\n\n  const onEnd = (e: PointerEvent) => {\n    if (e.pointerId !== pointerId) return;\n    dispose();\n    if (started) {\n      handlers.onEnd?.(e);\n    }\n  };\n\n  const onCancel = (e: PointerEvent) => {\n    if (e.pointerId !== pointerId) return;\n    dispose();\n    handlers.onCancel?.();\n  };\n\n  const onKey = (e: KeyboardEvent) => {\n    if (e.key !== \"Escape\") return;\n    dispose();\n    handlers.onCancel?.();\n  };\n\n  document.addEventListener(\"pointermove\", onMove);\n  document.addEventListener(\"pointerup\", onEnd);\n  document.addEventListener(\"pointercancel\", onCancel);\n  document.addEventListener(\"keydown\", onKey);\n\n  return dispose;\n}\n","export interface InteractionLockOptions {\n  scroll?: boolean;\n  scrollTarget?: HTMLElement | Document | Window | null;\n  selection?: boolean;\n}\n\ninterface StyleSnapshot {\n  htmlOverflow: string;\n  htmlOverscrollBehavior: string;\n  htmlTouchAction: string;\n  htmlUserSelect: string;\n  htmlWebkitUserSelect: string;\n  bodyOverflow: string;\n  bodyOverscrollBehavior: string;\n  bodyTouchAction: string;\n  bodyUserSelect: string;\n  bodyWebkitUserSelect: string;\n}\n\ninterface TargetSnapshot {\n  target: HTMLElement;\n  overflow: string;\n  overscrollBehavior: string;\n  touchAction: string;\n  count: number;\n}\n\nlet scrollLocks = 0;\nlet pageScrollLocks = 0;\nlet selectionLocks = 0;\nlet snapshot: StyleSnapshot | null = null;\nconst targetSnapshots = new Map<HTMLElement, TargetSnapshot>();\n\nfunction captureSnapshot(): StyleSnapshot {\n  const html = document.documentElement;\n  const body = document.body;\n\n  return {\n    htmlOverflow: html.style.overflow,\n    htmlOverscrollBehavior: html.style.overscrollBehavior,\n    htmlTouchAction: html.style.touchAction,\n    htmlUserSelect: html.style.userSelect,\n    htmlWebkitUserSelect: html.style.webkitUserSelect,\n    bodyOverflow: body.style.overflow,\n    bodyOverscrollBehavior: body.style.overscrollBehavior,\n    bodyTouchAction: body.style.touchAction,\n    bodyUserSelect: body.style.userSelect,\n    bodyWebkitUserSelect: body.style.webkitUserSelect,\n  };\n}\n\nfunction ensureSnapshot(): void {\n  if (!snapshot) {\n    snapshot = captureSnapshot();\n  }\n}\n\nfunction resolveScrollTarget(target: InteractionLockOptions[\"scrollTarget\"]): HTMLElement | null {\n  if (!target || target === window || target === document) {\n    return null;\n  }\n  return target;\n}\n\nfunction preventTouchScroll(event: TouchEvent): void {\n  if (event.cancelable) {\n    event.preventDefault();\n  }\n}\n\nfunction lockScrollTarget(target: HTMLElement): void {\n  const existing = targetSnapshots.get(target);\n  if (existing) {\n    existing.count += 1;\n  } else {\n    targetSnapshots.set(target, {\n      target,\n      overflow: target.style.overflow,\n      overscrollBehavior: target.style.overscrollBehavior,\n      touchAction: target.style.touchAction,\n      count: 1,\n    });\n  }\n\n  target.style.overflow = \"hidden\";\n  target.style.overscrollBehavior = \"none\";\n  target.style.touchAction = \"none\";\n}\n\nfunction unlockScrollTarget(target: HTMLElement): void {\n  const existing = targetSnapshots.get(target);\n  if (!existing) return;\n\n  existing.count -= 1;\n  if (existing.count > 0) return;\n\n  target.style.overflow = existing.overflow;\n  target.style.overscrollBehavior = existing.overscrollBehavior;\n  target.style.touchAction = existing.touchAction;\n  targetSnapshots.delete(target);\n}\n\nfunction applyLocks(scrollTarget: HTMLElement | null): void {\n  const html = document.documentElement;\n  const body = document.body;\n\n  if (selectionLocks > 0) {\n    html.style.userSelect = \"none\";\n    html.style.webkitUserSelect = \"none\";\n    body.style.userSelect = \"none\";\n    body.style.webkitUserSelect = \"none\";\n  }\n\n  if (scrollLocks > 0) {\n    html.style.overscrollBehavior = \"none\";\n    html.style.touchAction = \"none\";\n    body.style.overscrollBehavior = \"none\";\n    body.style.touchAction = \"none\";\n    if (scrollTarget) {\n      lockScrollTarget(scrollTarget);\n    } else {\n      pageScrollLocks += 1;\n      html.style.overflow = \"hidden\";\n      body.style.overflow = \"hidden\";\n    }\n    window.addEventListener(\"touchmove\", preventTouchScroll, { passive: false });\n  }\n}\n\nfunction syncLocks(releasedScrollTarget: HTMLElement | null): void {\n  if (!snapshot) {\n    return;\n  }\n\n  const html = document.documentElement;\n  const body = document.body;\n\n  if (releasedScrollTarget) {\n    unlockScrollTarget(releasedScrollTarget);\n  } else if (pageScrollLocks > 0) {\n    pageScrollLocks -= 1;\n  }\n\n  if (pageScrollLocks === 0) {\n    html.style.overflow = snapshot.htmlOverflow;\n    body.style.overflow = snapshot.bodyOverflow;\n  }\n\n  if (scrollLocks === 0) {\n    html.style.overscrollBehavior = snapshot.htmlOverscrollBehavior;\n    html.style.touchAction = snapshot.htmlTouchAction;\n    body.style.overscrollBehavior = snapshot.bodyOverscrollBehavior;\n    body.style.touchAction = snapshot.bodyTouchAction;\n    window.removeEventListener(\"touchmove\", preventTouchScroll);\n  }\n\n  if (selectionLocks === 0) {\n    html.style.userSelect = snapshot.htmlUserSelect;\n    html.style.webkitUserSelect = snapshot.htmlWebkitUserSelect;\n    body.style.userSelect = snapshot.bodyUserSelect;\n    body.style.webkitUserSelect = snapshot.bodyWebkitUserSelect;\n  }\n\n  if (scrollLocks === 0 && selectionLocks === 0) {\n    snapshot = null;\n  }\n}\n\nexport function lockPageInteraction(options: InteractionLockOptions = {}): () => void {\n  const lockScroll = options.scroll === true;\n  const lockSelection = options.selection === true;\n  const scrollTarget = lockScroll ? resolveScrollTarget(options.scrollTarget) : null;\n\n  if (!lockScroll && !lockSelection) {\n    return () => {};\n  }\n\n  ensureSnapshot();\n\n  if (lockScroll) {\n    scrollLocks += 1;\n  }\n  if (lockSelection) {\n    selectionLocks += 1;\n  }\n\n  applyLocks(scrollTarget);\n\n  let released = false;\n  return () => {\n    if (released) return;\n    released = true;\n\n    if (lockScroll) {\n      scrollLocks = Math.max(0, scrollLocks - 1);\n    }\n    if (lockSelection) {\n      selectionLocks = Math.max(0, selectionLocks - 1);\n    }\n\n    syncLocks(scrollTarget);\n  };\n}\n","import { RulerLine } from \"./models/RulerLine\";\nimport type { RulersLayoutGrid } from \"./models/RulersLayoutGrid\";\nimport { SnapCandidate, SnapEngine, SnapResult } from \"./SnapEngine\";\nimport { RULER_MODES, type RulerMode, type FixedGuideLine } from \"./models/RulerMode\";\nimport { StringDevViewportLayer } from \"../core/StringDevViewportLayer\";\nimport { startPointerDrag } from \"../core/startPointerDrag\";\nimport { getStringDevViewportPolicy } from \"../core/StringDevViewportPolicy\";\nimport { lockPageInteraction } from \"../../../utils/interaction-lock\";\n\nconst RULER_THICKNESS = 20; // px — width of horizontal / vertical ruler bar\nconst RULER_THICKNESS_MOBILE = 12;\nconst RULER_PLATE_BACKGROUND_COLOR = \"#E3E3E3\";\nconst RULER_PLATE_BACKGROUND_OPACITY = 0.85;\nconst RULER_PLATE_BORDER_COLOR = \"#000000\";\nconst RULER_PLATE_BORDER_OPACITY = 0.25;\nconst RULER_TICK_COLOR = \"#313131\";\nconst RULER_TICK_FONT_SIZE = 10;\nconst RULER_TICK_FONT = `${RULER_TICK_FONT_SIZE}px \"JetBrains Mono\", monospace`;\nconst RULER_TICK_LABEL_OFFSET_TOP = 4;\nconst RULER_TICK_LABEL_OFFSET_LEFT = -2;\nconst RULER_TICK_LONG_SIZE = 8;\nconst RULER_TICK_SHORT_SIZE = 4;\nconst RULER_TICK_LONG_SIZE_MOBILE = 5;\nconst RULER_TICK_SHORT_SIZE_MOBILE = 2;\n\nconst COL_EDGE_COLOR = \"rgba(255, 56, 96, 0.50)\";\nconst COL_CENTER_COLOR = \"rgba(255, 56, 96, 0.22)\";\nconst COL_BG_COLOR = \"rgba(255, 56, 96, 0.05)\";\nconst COL_LABEL_COLOR = \"rgba(255, 56, 96, 0.45)\";\nconst COL_LABEL_FONT_SIZE = 8;\nconst COL_LABEL_FONT = `${COL_LABEL_FONT_SIZE}px \"JetBrains Mono\", monospace`;\n\nconst ROW_EDGE_COLOR = \"rgba(0, 120, 255, 0.50)\";\nconst ROW_CENTER_COLOR = \"rgba(0, 120, 255, 0.22)\";\nconst ROW_BG_COLOR = \"rgba(0, 120, 255, 0.05)\";\n\nfunction fillRectWithAlpha(\n  ctx: CanvasRenderingContext2D,\n  color: string,\n  alpha: number,\n  x: number,\n  y: number,\n  width: number,\n  height: number,\n): void {\n  ctx.save();\n  ctx.globalAlpha = alpha;\n  ctx.fillStyle = color;\n  ctx.fillRect(x, y, width, height);\n  ctx.restore();\n}\n\nexport interface RulersColumnLayout {\n  columns: number;\n  margin: string;\n  gap: string;\n}\n\nexport interface RulersRowLayout {\n  /** Height of each row band (CSS unit value: px, rem, %, vw, vh). */\n  size: string;\n  /** Gap between row bands (CSS unit value). */\n  gap: string;\n}\n\nfunction resolveCSSUnit(\n  value: string,\n  axis: \"x\" | \"y\" = \"x\",\n  viewportWidth: number = window.innerWidth,\n  viewportHeight: number = window.innerHeight,\n): number {\n  const match = value.trim().match(/^(-?[\\d.]+)\\s*(px|rem|%|vw|vh)?$/);\n  if (!match) return 0;\n  const num = parseFloat(match[1]);\n  const unit = match[2] || \"px\";\n  switch (unit) {\n    case \"px\":\n      return num;\n    case \"rem\":\n      return num * parseFloat(getComputedStyle(document.documentElement).fontSize);\n    case \"%\":\n      return axis === \"y\" ? (num / 100) * viewportHeight : (num / 100) * viewportWidth;\n    case \"vw\":\n      return (num / 100) * viewportWidth;\n    case \"vh\":\n      return (num / 100) * viewportHeight;\n    default:\n      return num;\n  }\n}\n\ntype DragCommitCallback = (\n  lineId: string,\n  position: number,\n  targetLabel?: string,\n  targetSelector?: string,\n  targetEdge?: RulerLine[\"targetEdge\"],\n) => void;\ntype LineCreatedCallback = (\n  axis: \"horizontal\" | \"vertical\",\n  position: number,\n  targetLabel?: string,\n  targetSelector?: string,\n  targetEdge?: RulerLine[\"targetEdge\"],\n) => void;\ntype LineMovedCallback = (lineId: string, position: number, targetLabel?: string) => void;\ntype LineRemovedCallback = (lineId: string) => void;\n\nexport interface RulersOverlayCallbacks {\n  onLineCreated: LineCreatedCallback;\n  onLineMoved: LineMovedCallback;\n  onLineRemoved: LineRemovedCallback;\n  onDragCommit: DragCommitCallback;\n  onModeToggle: () => void;\n}\n\nexport interface RulersOverlayOptions {\n  /** Grid step in document pixels. 0 / 1 = disabled. */\n  snapStep: number;\n  /** Whether to snap to element edges and centers during drag. Default: true. */\n  snapToElements: boolean;\n  /** Pixel threshold for snapping. Default: 8. */\n  snapThreshold: number;\n  /** CSS selector for snap targets. Default: \"[string],[data-string]\". */\n  snapSelector: string;\n  /** Layout grid definitions (columns / rows) rendered as overlay bands. */\n  layoutGrids?: RulersLayoutGrid[];\n  /** Column layout with CSS-unit margins, column count, and gap. */\n  columnLayout?: RulersColumnLayout;\n  /** Row layout with CSS-unit row size and gap. */\n  rowLayout?: RulersRowLayout;\n  /** Scroll element to lock while dragging rulers on mobile. */\n  scrollTarget?: HTMLElement | null;\n}\n\nconst DEFAULT_OPTIONS: RulersOverlayOptions = {\n  snapStep: 0,\n  snapToElements: true,\n  snapThreshold: 8,\n  snapSelector: \"[string],[data-string]\",\n};\n\nconst COLUMNS_COLOR_DEFAULT = \"rgba(255, 0, 80, 0.08)\";\nconst ROWS_COLOR_DEFAULT = \"rgba(0, 120, 255, 0.06)\";\n\n/**\n * Global fixed-position overlay that renders ruler bars, layout grid, and guide lines.\n *\n * Layer order (bottom → top):\n *   [data-string-rulers-grid]   z 9998  layout-grid canvas (columns / rows)\n *   [data-string-rulers-top]    z 10001 horizontal ruler bar\n *   [data-string-rulers-left]   z 10001 vertical ruler bar\n *   [data-string-rulers-lines]  z 10000 guide line DOM nodes\n *\n * Snap feedback:\n *   amber  →  snapping to a DOM element edge / center\n *   green  →  snapping to a layout grid line\n */\nexport class RulersOverlay {\n  private viewportLayer: StringDevViewportLayer;\n  private host: HTMLElement | null;\n  private gridCanvas: HTMLCanvasElement;\n  private topCanvas: HTMLCanvasElement;\n  private leftCanvas: HTMLCanvasElement;\n  private cornerEl: HTMLDivElement;\n  private cornerLabelEl: HTMLSpanElement;\n  private linesLayer: HTMLDivElement;\n  private gapIndicatorEl: HTMLDivElement;\n  private gapIndicatorLabelEl: HTMLSpanElement;\n\n  // DOM nodes for active guide lines: lineId → { el, labelEl }\n  private lineEls: Map<string, { el: HTMLDivElement; labelEl: HTMLSpanElement }> = new Map();\n\n  // DOM nodes for mode-provided fixed guide lines (e.g. center cross)\n  private fixedLineEls: Map<string, HTMLDivElement> = new Map();\n\n  private callbacks: RulersOverlayCallbacks;\n  private options: RulersOverlayOptions;\n  private snapEngine: SnapEngine;\n  private resizeObserver: ResizeObserver;\n  private currentMode: RulerMode = RULER_MODES.default;\n\n  private visible: boolean = false;\n  private viewportWidth: number = window.innerWidth;\n  private viewportHeight: number = window.innerHeight;\n  private contentWidth: number = document.documentElement.scrollWidth;\n  private contentHeight: number = document.documentElement.scrollHeight;\n  private viewportOffsetX: number = 0;\n  private viewportOffsetY: number = 0;\n\n  // Current scroll offset (updated every frame from StringDevRulers)\n  private scrollX: number = 0;\n  private scrollY: number = 0;\n\n  // Last pixel-rounded values used for canvas redraw (avoid redundant redraws)\n  private renderedScrollX: number = -1;\n  private renderedScrollY: number = -1;\n\n  // Last rendered lines\n  private currentLines: RulerLine[] = [];\n\n  // Currently highlighted snap-target element\n  private _snapHighlightEl: Element | null = null;\n  private _guideReferenceLineIds: [string, string] | null = null;\n  private _guideReferenceAxis: \"horizontal\" | \"vertical\" | null = null;\n  private _guideReferenceGap: number | null = null;\n  private dragInteractionReleases = new Set<() => void>();\n\n  constructor(\n    callbacks: RulersOverlayCallbacks,\n    options: Partial<RulersOverlayOptions> = {},\n    host: HTMLElement | undefined,\n    viewportLayer: StringDevViewportLayer,\n  ) {\n    this.callbacks = callbacks;\n    this.options = { ...DEFAULT_OPTIONS, ...options };\n    this.host = host ?? null;\n    this.viewportLayer = viewportLayer;\n\n    this.snapEngine = new SnapEngine({\n      threshold: this.options.snapThreshold,\n      snapStep: this.options.snapStep,\n      snapToElements: this.options.snapToElements,\n      snapSelector: this.options.snapSelector,\n      layoutGrids: this.options.layoutGrids,\n    });\n\n    this.gridCanvas = this.createCanvas(\"grid\");\n    this.topCanvas = this.createCanvas(\"top\");\n    this.leftCanvas = this.createCanvas(\"left\");\n    this.linesLayer = this.createLinesLayer();\n    this.gapIndicatorEl = this.createGapIndicator();\n    this.gapIndicatorLabelEl = document.createElement(\"span\");\n    this.gapIndicatorLabelEl.setAttribute(\"data-string-rulers-gap-indicator-label\", \"\");\n    this.gapIndicatorLabelEl.setAttribute(\"data-stdg\", \"\");\n\n    this.gapIndicatorEl.appendChild(this.gapIndicatorLabelEl);\n\n    this.cornerEl = document.createElement(\"div\");\n    this.cornerEl.setAttribute(\"data-string-rulers-corner\", \"\");\n    this.cornerEl.setAttribute(\"data-mode\", this.currentMode.id);\n    this.cornerLabelEl = document.createElement(\"span\");\n    this.cornerLabelEl.textContent = this.currentMode.cornerLabel;\n    this.cornerEl.appendChild(this.cornerLabelEl);\n    this.cornerEl.addEventListener(\"click\", () => this.callbacks.onModeToggle());\n\n    const screenRoot = this.viewportLayer.getScreenElement();\n    const worldRoot = this.viewportLayer.getWorldElement(host);\n\n    worldRoot.appendChild(this.gridCanvas);\n    worldRoot.appendChild(this.linesLayer);\n    this.linesLayer.appendChild(this.gapIndicatorEl);\n    screenRoot.appendChild(this.topCanvas);\n    screenRoot.appendChild(this.leftCanvas);\n    screenRoot.appendChild(this.cornerEl);\n\n    document.body.setAttribute(\"data-string-rulers-hidden\", \"\");\n\n    this.resizeObserver = new ResizeObserver(() => {\n      if (this.visible) this.redraw();\n    });\n    this.resizeObserver.observe(document.documentElement);\n\n    this.bindRulerDrag(this.topCanvas, \"horizontal\");\n    this.bindRulerDrag(this.leftCanvas, \"vertical\");\n  }\n\n  // ── Public API ────────────────────────────────────────\n\n  refresh(lines: RulerLine[]): void {\n    this.currentLines = lines;\n    this.redraw();\n  }\n\n  updateScroll(\n    scrollX: number,\n    scrollY: number,\n    viewportWidth: number,\n    viewportHeight: number,\n    contentWidth: number,\n    contentHeight: number,\n  ): void {\n    const metricsChanged =\n      this.viewportWidth !== viewportWidth ||\n      this.viewportHeight !== viewportHeight ||\n      this.contentWidth !== contentWidth ||\n      this.contentHeight !== contentHeight;\n\n    this.scrollX = scrollX;\n    this.scrollY = scrollY;\n    this.viewportWidth = viewportWidth;\n    this.viewportHeight = viewportHeight;\n    this.contentWidth = contentWidth;\n    this.contentHeight = contentHeight;\n    this.syncScreenChromePosition();\n    if (!this.visible) return;\n\n    const rx = Math.round(scrollX);\n    const ry = Math.round(scrollY);\n    const canvasNeedsRedraw =\n      metricsChanged || rx !== this.renderedScrollX || ry !== this.renderedScrollY;\n\n    if (canvasNeedsRedraw) {\n      this.renderedScrollX = rx;\n      this.renderedScrollY = ry;\n      if (metricsChanged) {\n        this.syncWorldDimensions();\n      }\n      this.drawTopRuler(this.viewportWidth);\n      this.drawLeftRuler(this.viewportHeight);\n      if (metricsChanged) {\n        this.drawGrid(this.contentWidth, this.contentHeight);\n      }\n    }\n\n    this.updateLineLabels();\n    this._positionGuideReferenceIndicator();\n\n    // Fixed lines only exist in non-default modes — skip entirely when empty\n    if (this.fixedLineEls.size > 0 || this.currentMode.id !== \"default\") {\n      this.syncFixedLines();\n    }\n  }\n\n  setVisible(visible: boolean): void {\n    this.visible = visible;\n    if (visible) {\n      document.body.removeAttribute(\"data-string-rulers-hidden\");\n      this.redraw();\n    } else {\n      document.body.setAttribute(\"data-string-rulers-hidden\", \"\");\n    }\n  }\n\n  setMode(mode: RulerMode): void {\n    this.currentMode = mode;\n    this.cornerEl.setAttribute(\"data-mode\", mode.id);\n    this.cornerLabelEl.textContent = mode.cornerLabel;\n    this.redraw();\n  }\n\n  destroy(): void {\n    this.releaseAllDragInteractionLocks();\n    this._setSnapHighlight(null);\n    this._setGuideReference(null, null, null);\n    this.resizeObserver.disconnect();\n    this.gridCanvas.remove();\n    this.topCanvas.remove();\n    this.leftCanvas.remove();\n    this.cornerEl.remove();\n    this.linesLayer.remove();\n    document.body.removeAttribute(\"data-string-rulers-hidden\");\n    this.lineEls.clear();\n    for (const [, el] of this.fixedLineEls) el.remove();\n    this.fixedLineEls.clear();\n  }\n\n  // ── Internal redraw ───────────────────────────────────\n\n  private redraw(): void {\n    this.renderedScrollX = Math.round(this.scrollX);\n    this.renderedScrollY = Math.round(this.scrollY);\n    this.syncScreenChromePosition();\n    this.syncWorldDimensions();\n    this.drawTopRuler(this.viewportWidth);\n    this.drawLeftRuler(this.viewportHeight);\n    this.drawGrid(this.contentWidth, this.contentHeight);\n    this.syncLineEls(this.currentLines);\n    this.syncFixedLines();\n    this._positionGuideReferenceIndicator();\n  }\n\n  private updateLineLabels(): void {\n    for (const line of this.currentLines) {\n      const entry = this.lineEls.get(line.id);\n      if (!entry) continue;\n      this.updateLineLabel(line, entry.labelEl);\n    }\n  }\n\n  // ── Canvas creation ───────────────────────────────────\n\n  private createCanvas(side: \"grid\" | \"top\" | \"left\"): HTMLCanvasElement {\n    const canvas = document.createElement(\"canvas\");\n    canvas.setAttribute(`data-string-rulers-${side}`, \"\");\n    return canvas;\n  }\n\n  private createLinesLayer(): HTMLDivElement {\n    const div = document.createElement(\"div\");\n    div.setAttribute(\"data-string-rulers-lines\", \"\");\n    return div;\n  }\n\n  private createGapIndicator(): HTMLDivElement {\n    const el = document.createElement(\"div\");\n    el.setAttribute(\"data-string-rulers-gap-indicator\", \"\");\n    el.setAttribute(\"hidden\", \"\");\n    return el;\n  }\n\n  private syncWorldDimensions(): void {\n    this.linesLayer.style.width = `${this.contentWidth}px`;\n    this.linesLayer.style.height = `${this.contentHeight}px`;\n    this.gridCanvas.style.width = `${this.contentWidth}px`;\n    this.gridCanvas.style.height = `${this.contentHeight}px`;\n  }\n\n  // ── Layout grid drawing ───────────────────────────────\n\n  private drawGrid(worldWidth: number, worldHeight: number): void {\n    const grids = this.options.layoutGrids;\n    const c = this.gridCanvas;\n    if (c.width !== worldWidth || c.height !== worldHeight) {\n      c.width = worldWidth;\n      c.height = worldHeight;\n      c.style.width = `${worldWidth}px`;\n      c.style.height = `${worldHeight}px`;\n    }\n\n    if (!grids?.length) return;\n\n    const ctx = c.getContext(\"2d\")!;\n    ctx.clearRect(0, 0, worldWidth, worldHeight);\n\n    for (const grid of grids) {\n      if (grid.type === \"columns\")\n        this._drawColumnsGrid(ctx, this.viewportWidth, worldHeight, grid);\n      if (grid.type === \"rows\") this._drawRowsGrid(ctx, this.viewportWidth, worldHeight, grid);\n    }\n  }\n\n  private _drawColumnsGrid(\n    ctx: CanvasRenderingContext2D,\n    vw: number,\n    vh: number,\n    grid: import(\"./models/RulersLayoutGrid\").ColumnsLayoutGrid,\n  ): void {\n    const { count, marginLeft = 0, marginRight = 0, gap = 0 } = grid;\n    const usableWidth = vw - marginLeft - marginRight;\n    if (usableWidth <= 0 || count <= 0) return;\n\n    const colWidth = (usableWidth - (count - 1) * gap) / count;\n    ctx.fillStyle = grid.color ?? COLUMNS_COLOR_DEFAULT;\n\n    for (let i = 0; i < count; i++) {\n      const x = marginLeft + i * (colWidth + gap);\n      ctx.fillRect(x, 0, colWidth, vh);\n    }\n  }\n\n  private _drawRowsGrid(\n    ctx: CanvasRenderingContext2D,\n    vw: number,\n    vh: number,\n    grid: import(\"./models/RulersLayoutGrid\").RowsLayoutGrid,\n  ): void {\n    const { height, gap = 0 } = grid;\n    const period = height + gap;\n    if (period <= 0 || height <= 0) return;\n\n    ctx.fillStyle = grid.color ?? ROWS_COLOR_DEFAULT;\n    for (let y = 0; y < vh; y += period) {\n      ctx.fillRect(0, y, vw, height);\n    }\n  }\n\n  // ── Ruler drawing ─────────────────────────────────────\n\n  private drawTopRuler(vw: number): void {\n    const t = this.getRulerThickness();\n    const c = this.topCanvas;\n    // Only resize canvas when dimensions change (avoids buffer reallocation)\n    if (c.width !== vw || c.height !== t) {\n      c.width = vw;\n      c.height = t;\n    }\n    const ctx = c.getContext(\"2d\")!;\n\n    ctx.clearRect(0, 0, vw, t);\n    fillRectWithAlpha(\n      ctx,\n      RULER_PLATE_BACKGROUND_COLOR,\n      RULER_PLATE_BACKGROUND_OPACITY,\n      0,\n      0,\n      vw,\n      t,\n    );\n    fillRectWithAlpha(ctx, RULER_PLATE_BORDER_COLOR, RULER_PLATE_BORDER_OPACITY, 0, t - 1, vw, 1);\n\n    this._drawColumnMarkers(ctx, vw, t);\n    this.drawTicks(ctx, vw, t, \"top\", this.scrollX);\n  }\n\n  private drawLeftRuler(vh: number): void {\n    const t = this.getRulerThickness();\n    const c = this.leftCanvas;\n    if (c.width !== t || c.height !== vh) {\n      c.width = t;\n      c.height = vh;\n    }\n    const ctx = c.getContext(\"2d\")!;\n\n    ctx.clearRect(0, 0, t, vh);\n    fillRectWithAlpha(\n      ctx,\n      RULER_PLATE_BACKGROUND_COLOR,\n      RULER_PLATE_BACKGROUND_OPACITY,\n      0,\n      0,\n      t,\n      vh,\n    );\n    fillRectWithAlpha(ctx, RULER_PLATE_BORDER_COLOR, RULER_PLATE_BORDER_OPACITY, t - 1, 0, 1, vh);\n\n    this._drawRowMarkers(ctx, t, vh);\n    this.drawTicks(ctx, vh, t, \"left\", this.scrollY);\n  }\n\n  private drawTicks(\n    ctx: CanvasRenderingContext2D,\n    length: number,\n    thickness: number,\n    side: \"top\" | \"left\",\n    offset: number,\n  ): void {\n    const { tick: tickStep, label: labelInterval } = this.pickStep(length);\n    const axis: \"horizontal\" | \"vertical\" = side === \"top\" ? \"vertical\" : \"horizontal\";\n    const isTop = side === \"top\";\n    const compact = this.isCompactMobileRuler();\n    const showTickLabels = !compact;\n    const halfThickness = Math.round(thickness / 2);\n    const longTick = Math.min(\n      thickness,\n      compact ? RULER_TICK_LONG_SIZE_MOBILE : RULER_TICK_LONG_SIZE,\n    );\n    const shortTick = Math.min(\n      thickness,\n      compact ? RULER_TICK_SHORT_SIZE_MOBILE : RULER_TICK_SHORT_SIZE,\n    );\n\n    ctx.fillStyle = RULER_TICK_COLOR;\n    ctx.font = RULER_TICK_FONT;\n\n    const startDoc = Math.ceil(offset / tickStep) * tickStep;\n    const startScreen = startDoc - offset;\n\n    if (isTop) {\n      ctx.textAlign = \"center\";\n      ctx.textBaseline = \"top\";\n      for (let i = 0; startScreen + i * tickStep <= length; i++) {\n        const screenPos = Math.round(startScreen + i * tickStep);\n        const docPos = startDoc + i * tickStep;\n        const displayValue = this.currentMode.formatPosition(docPos, axis, length, offset);\n        const showLabel = Math.round(displayValue) % labelInterval === 0;\n        const tickLen = showLabel ? longTick : shortTick;\n\n        const tickStart = compact ? 0 : thickness - tickLen;\n        ctx.fillRect(screenPos, tickStart, 1, tickLen);\n        if (showTickLabels && showLabel && screenPos > 4) {\n          ctx.fillText(String(Math.round(displayValue)), screenPos, RULER_TICK_LABEL_OFFSET_TOP);\n        }\n      }\n    } else {\n      // Left ruler — labels are rotated, need save/restore per label\n      ctx.textAlign = \"center\";\n      ctx.textBaseline = \"middle\";\n      for (let i = 0; startScreen + i * tickStep <= length; i++) {\n        const screenPos = Math.round(startScreen + i * tickStep);\n        const docPos = startDoc + i * tickStep;\n        const displayValue = this.currentMode.formatPosition(docPos, axis, length, offset);\n        const showLabel = Math.round(displayValue) % labelInterval === 0;\n        const tickLen = showLabel ? longTick : shortTick;\n\n        const tickStart = compact ? 0 : thickness - tickLen;\n        ctx.fillRect(tickStart, screenPos, tickLen, 1);\n        if (showTickLabels && showLabel && screenPos > 4) {\n          ctx.save();\n          ctx.translate(halfThickness, screenPos);\n          ctx.rotate(-Math.PI / 2);\n          ctx.fillText(String(Math.round(displayValue)), 0, RULER_TICK_LABEL_OFFSET_LEFT);\n          ctx.restore();\n        }\n      }\n    }\n  }\n\n  /**\n   * Returns the tick step and the label interval for a given ruler length.\n   * Label interval is always a clean multiple so labels land on round numbers\n   * (e.g. step=25 → labels at 0, 100, 200 — not 0, 125, 250).\n   */\n  private pickStep(length: number): { tick: number; label: number } {\n    if (length < 300) return { tick: 5, label: 25 };\n    if (length < 800) return { tick: 10, label: 50 };\n    if (length < 1800) return { tick: 25, label: 100 };\n    return { tick: 50, label: 500 };\n  }\n\n  // ── Column layout ────────────────────────────────────\n\n  private _resolveColumnLayout(): {\n    columns: number;\n    marginPx: number;\n    gapPx: number;\n    colWidth: number;\n  } | null {\n    const cl = this.options.columnLayout;\n    if (!cl || cl.columns <= 0) return null;\n    const marginPx = resolveCSSUnit(cl.margin, \"x\", this.viewportWidth, this.viewportHeight);\n    const gapPx = resolveCSSUnit(cl.gap, \"x\", this.viewportWidth, this.viewportHeight);\n    const vw = this.viewportWidth;\n    const usableWidth = vw - 2 * marginPx;\n    if (usableWidth <= 0) return null;\n    const colWidth = (usableWidth - (cl.columns - 1) * gapPx) / cl.columns;\n    if (colWidth <= 0) return null;\n    return { columns: cl.columns, marginPx, gapPx, colWidth };\n  }\n\n  private _drawColumnMarkers(ctx: CanvasRenderingContext2D, vw: number, thickness: number): void {\n    const layout = this._resolveColumnLayout();\n    if (!layout) return;\n    const { columns, marginPx, gapPx, colWidth } = layout;\n\n    // Subtle column backgrounds on the ruler\n    ctx.fillStyle = COL_BG_COLOR;\n    for (let i = 0; i < columns; i++) {\n      const x = marginPx + i * (colWidth + gapPx);\n      ctx.fillRect(x, 0, colWidth, thickness);\n    }\n\n    // Column edge lines (full ruler height)\n    ctx.fillStyle = COL_EDGE_COLOR;\n    for (let i = 0; i < columns; i++) {\n      const left = marginPx + i * (colWidth + gapPx);\n      const right = left + colWidth;\n      ctx.fillRect(Math.round(left), 0, 1, thickness);\n      ctx.fillRect(Math.round(right), 0, 1, thickness);\n    }\n\n    // Column center marks (shorter)\n    ctx.fillStyle = COL_CENTER_COLOR;\n    for (let i = 0; i < columns; i++) {\n      const left = marginPx + i * (colWidth + gapPx);\n      const center = left + colWidth / 2;\n      ctx.fillRect(Math.round(center), Math.round(thickness * 0.6), 1, Math.round(thickness * 0.4));\n    }\n\n    // Column number labels (only if columns are wide enough)\n    if (!this.isCompactMobileRuler() && colWidth > 16) {\n      ctx.fillStyle = COL_LABEL_COLOR;\n      ctx.font = COL_LABEL_FONT;\n      ctx.textAlign = \"center\";\n      ctx.textBaseline = \"middle\";\n      for (let i = 0; i < columns; i++) {\n        const left = marginPx + i * (colWidth + gapPx);\n        const center = left + colWidth / 2;\n        ctx.fillText(String(i + 1), Math.round(center), Math.round(thickness / 2));\n      }\n    }\n  }\n\n  private _buildColumnCandidates(axis: \"horizontal\" | \"vertical\"): SnapCandidate[] {\n    if (axis !== \"vertical\") return [];\n    const layout = this._resolveColumnLayout();\n    if (!layout) return [];\n    const { columns, marginPx, gapPx, colWidth } = layout;\n    const candidates: SnapCandidate[] = [];\n\n    for (let i = 0; i < columns; i++) {\n      const left = marginPx + i * (colWidth + gapPx);\n      const right = left + colWidth;\n      const center = (left + right) / 2;\n      const n = i + 1;\n\n      candidates.push({\n        position: left + this.scrollX,\n        type: \"grid-column-edge\",\n        label: `c${n}`,\n      });\n      candidates.push({\n        position: right + this.scrollX,\n        type: \"grid-column-edge\",\n        label: `c${n}◂`,\n      });\n      candidates.push({\n        position: center + this.scrollX,\n        type: \"grid-column-center\",\n        label: `c${n}⊙`,\n      });\n    }\n\n    return candidates;\n  }\n\n  // ── Row layout ───────────────────────────────────────\n\n  private _resolveRowLayout(): { sizePx: number; gapPx: number; period: number } | null {\n    const rl = this.options.rowLayout;\n    if (!rl) return null;\n    const sizePx = resolveCSSUnit(rl.size, \"y\", this.viewportWidth, this.viewportHeight);\n    const gapPx = resolveCSSUnit(rl.gap, \"y\", this.viewportWidth, this.viewportHeight);\n    if (sizePx <= 0) return null;\n    return { sizePx, gapPx, period: sizePx + gapPx };\n  }\n\n  private _drawRowMarkers(ctx: CanvasRenderingContext2D, thickness: number, vh: number): void {\n    const layout = this._resolveRowLayout();\n    if (!layout) return;\n    const { sizePx, gapPx, period } = layout;\n\n    const startDoc = Math.floor(this.scrollY / period) * period;\n    const endDoc = this.scrollY + vh + period;\n\n    for (let docY = startDoc; docY < endDoc; docY += period) {\n      const topScreen = Math.round(docY - this.scrollY);\n      const bottomScreen = Math.round(docY + sizePx - this.scrollY);\n\n      // Row background band\n      const bgTop = Math.max(0, topScreen);\n      const bgBottom = Math.min(vh, bottomScreen);\n      if (bgBottom > bgTop) {\n        ctx.fillStyle = ROW_BG_COLOR;\n        ctx.fillRect(0, bgTop, thickness, bgBottom - bgTop);\n      }\n\n      // Top edge line\n      if (topScreen >= 0 && topScreen <= vh) {\n        ctx.fillStyle = ROW_EDGE_COLOR;\n        ctx.fillRect(0, topScreen, thickness, 1);\n      }\n\n      // Bottom edge line (only when there's a gap, marking end of band)\n      if (gapPx > 0 && bottomScreen >= 0 && bottomScreen <= vh) {\n        ctx.fillStyle = ROW_EDGE_COLOR;\n        ctx.fillRect(0, bottomScreen, thickness, 1);\n      }\n\n      // Center mark (shorter, from left edge)\n      if (sizePx > 4) {\n        const centerScreen = Math.round(docY + sizePx / 2 - this.scrollY);\n        if (centerScreen >= 0 && centerScreen <= vh) {\n          ctx.fillStyle = ROW_CENTER_COLOR;\n          ctx.fillRect(0, centerScreen, Math.round(thickness * 0.45), 1);\n        }\n      }\n    }\n  }\n\n  private _buildRowCandidates(axis: \"horizontal\" | \"vertical\"): SnapCandidate[] {\n    if (axis !== \"horizontal\") return [];\n    const layout = this._resolveRowLayout();\n    if (!layout) return [];\n    const { sizePx, gapPx, period } = layout;\n\n    const vh = this.viewportHeight;\n    const rangeStart = Math.max(0, this.scrollY - 200);\n    const rangeEnd = this.scrollY + vh + 200;\n    const firstRow = Math.floor(rangeStart / period) * period;\n    const candidates: SnapCandidate[] = [];\n\n    for (let docY = firstRow; docY < rangeEnd; docY += period) {\n      const n = Math.round(docY / period) + 1;\n\n      candidates.push({ position: docY, type: \"grid-row-edge\", label: `r${n}` });\n      candidates.push({ position: docY + sizePx / 2, type: \"grid-row-edge\", label: `r${n}⊙` });\n      if (gapPx > 0) {\n        candidates.push({ position: docY + sizePx, type: \"grid-row-edge\", label: `r${n}◂` });\n      }\n    }\n\n    return candidates;\n  }\n\n  // ── Fixed (mode-provided) guide lines ────────────────\n\n  private syncFixedLines(): void {\n    const fixedLines = this.currentMode.getFixedLines(\n      this.viewportWidth,\n      this.viewportHeight,\n      this.scrollX,\n      this.scrollY,\n    );\n\n    // Build a set of keys we expect this frame\n    const expectedKeys = new Set<string>();\n    for (const fl of fixedLines) {\n      const key = `fixed-${fl.axis}`;\n      expectedKeys.add(key);\n\n      let el = this.fixedLineEls.get(key);\n      if (!el) {\n        el = document.createElement(\"div\");\n        el.setAttribute(\"data-string-rulers-fixed-line\", \"\");\n        el.setAttribute(\"data-axis\", fl.axis);\n        this.linesLayer.appendChild(el);\n        this.fixedLineEls.set(key, el);\n      }\n\n      if (fl.axis === \"horizontal\") {\n        el.style.top = `${fl.position}px`;\n        el.style.left = \"0\";\n        el.style.width = `${this.contentWidth}px`;\n      } else {\n        el.style.left = `${fl.position}px`;\n        el.style.top = \"0\";\n        el.style.height = `${this.contentHeight}px`;\n      }\n    }\n\n    // Remove stale fixed lines (e.g. mode switched away from center)\n    for (const [key, el] of this.fixedLineEls) {\n      if (!expectedKeys.has(key)) {\n        el.remove();\n        this.fixedLineEls.delete(key);\n      }\n    }\n  }\n\n  // ── Guide line DOM sync ───────────────────────────────\n\n  private syncLineEls(lines: RulerLine[]): void {\n    for (const [id] of this.lineEls) {\n      if (!lines.some((l) => l.id === id)) {\n        this.lineEls.get(id)!.el.remove();\n        this.lineEls.delete(id);\n      }\n    }\n    for (const line of lines) {\n      if (!this.lineEls.has(line.id)) this.createLineEl(line);\n      this.positionLineEl(line);\n    }\n  }\n\n  private createLineEl(line: RulerLine): void {\n    const el = document.createElement(\"div\");\n    el.setAttribute(\"data-string-rulers-line\", line.id);\n    el.setAttribute(\"data-axis\", line.axis);\n    el.setAttribute(\"data-stdg\", \"\");\n\n    const labelEl = document.createElement(\"span\");\n    labelEl.setAttribute(\"data-string-rulers-label\", \"\");\n    el.appendChild(labelEl);\n\n    this.linesLayer.appendChild(el);\n    this.lineEls.set(line.id, { el, labelEl });\n\n    el.addEventListener(\"pointerdown\", (e) => {\n      e.stopPropagation();\n      if (e.button === 1) {\n        e.preventDefault();\n        this.callbacks.onLineRemoved(line.id);\n        return;\n      }\n      this.startLineDrag(e, line);\n    });\n  }\n\n  private positionLineEl(line: RulerLine): void {\n    const entry = this.lineEls.get(line.id);\n    if (!entry) return;\n    const { el, labelEl } = entry;\n\n    if (line.axis === \"horizontal\") {\n      el.style.top = `${line.position}px`;\n      el.style.left = \"0\";\n      el.style.width = `${this.contentWidth}px`;\n    } else {\n      el.style.left = `${line.position}px`;\n      el.style.top = \"0\";\n      el.style.height = `${this.contentHeight}px`;\n    }\n\n    this.updateLineLabel(line, labelEl);\n  }\n\n  private updateLineLabel(line: RulerLine, labelEl: HTMLSpanElement): void {\n    const vSize = line.axis === \"horizontal\" ? this.viewportHeight : this.viewportWidth;\n    const scroll = line.axis === \"horizontal\" ? this.scrollY : this.scrollX;\n    const displayPos = this.currentMode.formatPosition(line.position, line.axis, vSize, scroll);\n    const positionLabel = String(Math.round(displayPos));\n    const nextLabel = line.targetLabel ? `${positionLabel} ${line.targetLabel}` : positionLabel;\n    if (labelEl.textContent !== nextLabel) {\n      labelEl.textContent = nextLabel;\n    }\n  }\n\n  private _setGuideReference(\n    axis: \"horizontal\" | \"vertical\" | null,\n    referenceLineIds: [string, string] | null,\n    gap: number | null,\n  ): void {\n    if (this._guideReferenceLineIds) {\n      for (const lineId of this._guideReferenceLineIds) {\n        this.lineEls.get(lineId)?.el.removeAttribute(\"data-string-rulers-guide-ref\");\n      }\n    }\n\n    this._guideReferenceAxis = axis;\n    this._guideReferenceLineIds = referenceLineIds;\n    this._guideReferenceGap = gap;\n\n    if (referenceLineIds) {\n      for (const lineId of referenceLineIds) {\n        this.lineEls.get(lineId)?.el.setAttribute(\"data-string-rulers-guide-ref\", \"\");\n      }\n    }\n\n    this._positionGuideReferenceIndicator();\n  }\n\n  private _positionGuideReferenceIndicator(): void {\n    const refIds = this._guideReferenceLineIds;\n    const axis = this._guideReferenceAxis;\n    const gap = this._guideReferenceGap;\n\n    if (!refIds || !axis || gap == null) {\n      this.gapIndicatorEl.setAttribute(\"hidden\", \"\");\n      this.gapIndicatorEl.removeAttribute(\"data-axis\");\n      return;\n    }\n\n    const lines = refIds\n      .map((lineId) => this.currentLines.find((line) => line.id === lineId))\n      .filter((line): line is RulerLine => Boolean(line));\n\n    if (lines.length !== 2) {\n      this.gapIndicatorEl.setAttribute(\"hidden\", \"\");\n      this.gapIndicatorEl.removeAttribute(\"data-axis\");\n      return;\n    }\n\n    const start = Math.min(lines[0].position, lines[1].position);\n    const end = Math.max(lines[0].position, lines[1].position);\n\n    this.gapIndicatorEl.removeAttribute(\"hidden\");\n    this.gapIndicatorEl.setAttribute(\"data-axis\", axis);\n    this.gapIndicatorLabelEl.textContent = `${Math.round(gap)}px`;\n\n    if (axis === \"vertical\") {\n      const centerY = Math.round(\n        this.scrollY + Math.max(this.getRulerThickness() + 32, this.viewportHeight / 2),\n      );\n      this.gapIndicatorEl.style.left = `${start}px`;\n      this.gapIndicatorEl.style.top = `${centerY}px`;\n      this.gapIndicatorEl.style.width = `${Math.max(0, end - start)}px`;\n      this.gapIndicatorEl.style.height = \"0\";\n    } else {\n      const centerX = Math.round(\n        this.scrollX + Math.max(this.getRulerThickness() + 32, this.viewportWidth / 2),\n      );\n      this.gapIndicatorEl.style.left = `${centerX}px`;\n      this.gapIndicatorEl.style.top = `${start}px`;\n      this.gapIndicatorEl.style.width = \"0\";\n      this.gapIndicatorEl.style.height = `${Math.max(0, end - start)}px`;\n    }\n  }\n\n  // ── Snap helpers ──────────────────────────────────────\n\n  private _setSnapHighlight(el: Element | null): void {\n    if (this._snapHighlightEl === el) return;\n    this._snapHighlightEl?.removeAttribute(\"data-string-rulers-snap-target\");\n    this._snapHighlightEl = el;\n    el?.setAttribute(\"data-string-rulers-snap-target\", \"\");\n  }\n\n  /**\n   * Returns \"element\" or \"grid\" for use as the `data-snapping` value.\n   * CSS uses this to apply different colours for each category.\n   */\n  private _snapCategory(type: SnapResult[\"type\"]): \"element\" | \"grid\" | \"guide\" | \"column\" {\n    if (type === \"guide-gap\") return \"guide\";\n    if (type === \"grid-column-edge\" || type === \"grid-column-center\") return \"column\";\n    if (type === \"grid-step\" || type.startsWith(\"grid-\")) return \"grid\";\n    return \"element\";\n  }\n\n  private _snapLabel(result: SnapResult, docPos: number, axis: \"horizontal\" | \"vertical\"): string {\n    const rawPos = result.position ?? docPos;\n    const vSize = this.getViewportSizeForAxis(axis);\n    const scroll = axis === \"horizontal\" ? this.scrollY : this.scrollX;\n    const pos = String(Math.round(this.currentMode.formatPosition(rawPos, axis, vSize, scroll)));\n    if (result.type === \"guide-gap\" && typeof result.gap === \"number\") {\n      return `${pos} ${Math.round(result.gap)}px`;\n    }\n    if (result.label) return `${pos} ${result.label}`;\n    if (result.el) return `${pos} ${this._elementLabel(result.el)}`;\n    return pos;\n  }\n\n  private _elementLabel(el: Element): string {\n    if (el.id) return `#${el.id}`;\n    const cls = el.classList[0];\n    if (cls) return `.${cls}`;\n    const key = el.getAttribute(\"string\") ?? el.getAttribute(\"data-string\");\n    if (key) return `[${key}]`;\n    return el.tagName.toLowerCase();\n  }\n\n  /** Produces a CSS selector that can re-find `el` via querySelector. */\n  private _elementSelector(el: Element): string | null {\n    if (el.id) return `#${CSS.escape(el.id)}`;\n    const sKey = el.getAttribute(\"string\");\n    if (sKey) return `[string=\"${CSS.escape(sKey)}\"]`;\n    const dsKey = el.getAttribute(\"data-string\");\n    if (dsKey) return `[data-string=\"${CSS.escape(dsKey)}\"]`;\n    if (el.classList[0]) return `.${CSS.escape(el.classList[0])}`;\n    return null;\n  }\n\n  /**\n   * Extracts binding info (label, selector, edge) from a snap result.\n   * Handles both DOM-element snaps and column-layout snaps.\n   */\n  private _resolveBinding(snapResult: SnapResult | null): {\n    targetLabel?: string;\n    targetSelector?: string;\n    targetEdge?: RulerLine[\"targetEdge\"];\n  } {\n    if (!snapResult) return {};\n\n    // DOM element binding\n    if (snapResult.el) {\n      let edge: RulerLine[\"targetEdge\"];\n      switch (snapResult.type) {\n        case \"element-top\":\n          edge = \"top\";\n          break;\n        case \"element-bottom\":\n          edge = \"bottom\";\n          break;\n        case \"element-center-y\":\n          edge = \"center-y\";\n          break;\n        case \"element-left\":\n          edge = \"left\";\n          break;\n        case \"element-right\":\n          edge = \"right\";\n          break;\n        case \"element-center-x\":\n          edge = \"center-x\";\n          break;\n      }\n      return {\n        targetLabel: this._elementLabel(snapResult.el),\n        targetSelector: this._elementSelector(snapResult.el) ?? undefined,\n        targetEdge: edge,\n      };\n    }\n\n    // Column layout binding (labels: c1, c1◂, c1⊙)\n    if (\n      (snapResult.type === \"grid-column-edge\" || snapResult.type === \"grid-column-center\") &&\n      snapResult.label\n    ) {\n      const m = snapResult.label.match(/^c(\\d+)(◂|⊙)?$/);\n      if (m) {\n        const colIndex = parseInt(m[1], 10) - 1;\n        const edge: RulerLine[\"targetEdge\"] =\n          m[2] === \"◂\" ? \"col-right\" : m[2] === \"⊙\" ? \"col-center\" : \"col-left\";\n        return {\n          targetLabel: snapResult.label,\n          targetSelector: `__col:${colIndex}`,\n          targetEdge: edge,\n        };\n      }\n    }\n\n    // Non-bindable snap (grid step, row, guide gap, etc.) — just keep label\n    if (snapResult.label) return { targetLabel: snapResult.label };\n    return {};\n  }\n\n  /**\n   * Recalculates positions of bound lines from current DOM / layout state.\n   * Call before `refresh()` on resize so lines track their targets.\n   */\n  recalculateBindings(lines: RulerLine[]): void {\n    for (const line of lines) {\n      if (!line.targetSelector || !line.targetEdge) continue;\n\n      // Column layout binding\n      if (line.targetSelector.startsWith(\"__col:\")) {\n        const colIndex = parseInt(line.targetSelector.slice(6), 10);\n        const layout = this._resolveColumnLayout();\n        if (!layout || colIndex < 0 || colIndex >= layout.columns) continue;\n        const left = layout.marginPx + colIndex * (layout.colWidth + layout.gapPx);\n        const right = left + layout.colWidth;\n        switch (line.targetEdge) {\n          case \"col-left\":\n            line.position = left + this.scrollX;\n            break;\n          case \"col-right\":\n            line.position = right + this.scrollX;\n            break;\n          case \"col-center\":\n            line.position = (left + right) / 2 + this.scrollX;\n            break;\n        }\n        continue;\n      }\n\n      // DOM element binding\n      const el = document.querySelector(line.targetSelector);\n      if (!el) continue;\n      const rect = el.getBoundingClientRect();\n      switch (line.targetEdge) {\n        case \"top\":\n          line.position = rect.top + this.scrollY;\n          break;\n        case \"bottom\":\n          line.position = rect.bottom + this.scrollY;\n          break;\n        case \"center-y\":\n          line.position = (rect.top + rect.bottom) / 2 + this.scrollY;\n          break;\n        case \"left\":\n          line.position = rect.left + this.scrollX;\n          break;\n        case \"right\":\n          line.position = rect.right + this.scrollX;\n          break;\n        case \"center-x\":\n          line.position = (rect.left + rect.right) / 2 + this.scrollX;\n          break;\n      }\n    }\n  }\n\n  // ── Drag from ruler ───────────────────────────────────\n\n  private bindRulerDrag(canvas: HTMLCanvasElement, axis: \"horizontal\" | \"vertical\"): void {\n    canvas.addEventListener(\"pointerdown\", (e) => {\n      e.preventDefault();\n      this.startRulerDrag(e, axis);\n    });\n  }\n\n  private startRulerDrag(e: PointerEvent, axis: \"horizontal\" | \"vertical\"): void {\n    const releaseInteractionLock = this.acquireDragInteractionLock();\n    const ghost = document.createElement(\"div\");\n    ghost.setAttribute(\"data-string-rulers-ghost\", \"\");\n    ghost.setAttribute(\"data-axis\", axis);\n\n    const ghostLabel = document.createElement(\"span\");\n    ghostLabel.setAttribute(\"data-string-rulers-ghost-label\", \"\");\n    ghostLabel.setAttribute(\"data-stdg\", \"\");\n    ghost.appendChild(ghostLabel);\n\n    this.linesLayer.appendChild(ghost);\n    this.snapEngine.buildCandidates(\n      axis,\n      this.scrollX,\n      this.scrollY,\n      this.viewportWidth,\n      this.viewportHeight,\n      this.currentLines,\n      undefined,\n      [...this._buildColumnCandidates(axis), ...this._buildRowCandidates(axis)],\n    );\n\n    const onMove = (ev: PointerEvent) => {\n      const rawDocPos = this.resolveDocPositionFromPointer(axis, ev);\n\n      const snapResult = ev.shiftKey ? null : this.snapEngine.findSnap(rawDocPos);\n      const docPos = snapResult\n        ? snapResult.position\n        : ev.shiftKey\n          ? rawDocPos\n          : this.snapEngine.snapToStep(rawDocPos);\n      if (axis === \"horizontal\") {\n        ghost.style.top = `${docPos}px`;\n        ghost.style.left = \"0\";\n        ghost.style.width = `${this.contentWidth}px`;\n      } else {\n        ghost.style.left = `${docPos}px`;\n        ghost.style.top = \"0\";\n        ghost.style.height = `${this.contentHeight}px`;\n      }\n\n      if (snapResult) {\n        ghost.setAttribute(\"data-snapping\", this._snapCategory(snapResult.type));\n        this._setSnapHighlight(snapResult.el ?? null);\n        this._setGuideReference(\n          snapResult.type === \"guide-gap\" ? axis : null,\n          snapResult.type === \"guide-gap\" ? (snapResult.referenceLineIds ?? null) : null,\n          snapResult.type === \"guide-gap\" ? (snapResult.gap ?? null) : null,\n        );\n        ghostLabel.textContent = this._snapLabel(snapResult, docPos, axis);\n      } else {\n        ghost.removeAttribute(\"data-snapping\");\n        this._setSnapHighlight(null);\n        this._setGuideReference(null, null, null);\n        const vSize = this.getViewportSizeForAxis(axis);\n        const scroll = axis === \"horizontal\" ? this.scrollY : this.scrollX;\n        ghostLabel.textContent = String(\n          Math.round(this.currentMode.formatPosition(docPos, axis, vSize, scroll)),\n        );\n      }\n    };\n\n    const cleanup = () => {\n      releaseInteractionLock();\n      ghost.remove();\n      this._setSnapHighlight(null);\n      this._setGuideReference(null, null, null);\n    };\n\n    const onEnd = (ev: PointerEvent) => {\n      cleanup();\n\n      const screenPos = this.resolveViewportPointerPos(axis, ev);\n      if (screenPos > this.getRulerThickness()) {\n        const rawDocPos =\n          axis === \"horizontal\" ? screenPos + this.scrollY : screenPos + this.scrollX;\n        const snapResult = ev.shiftKey ? null : this.snapEngine.findSnap(rawDocPos);\n        const finalPos = snapResult\n          ? snapResult.position\n          : ev.shiftKey\n            ? rawDocPos\n            : this.snapEngine.snapToStep(rawDocPos);\n        const binding = this._resolveBinding(snapResult);\n        this.callbacks.onLineCreated(\n          axis,\n          finalPos,\n          binding.targetLabel,\n          binding.targetSelector,\n          binding.targetEdge,\n        );\n      }\n    };\n\n    startPointerDrag(e, { onMove, onEnd, onCancel: cleanup });\n  }\n\n  // ── Drag line reposition ──────────────────────────────\n\n  private startLineDrag(e: PointerEvent, line: RulerLine): void {\n    const releaseInteractionLock = this.acquireDragInteractionLock();\n    const { el } = this.lineEls.get(line.id)!;\n\n    const startPointer = line.axis === \"horizontal\" ? e.clientY : e.clientX;\n    const startDocPosition = line.position;\n\n    this.snapEngine.buildCandidates(\n      line.axis,\n      this.scrollX,\n      this.scrollY,\n      this.viewportWidth,\n      this.viewportHeight,\n      this.currentLines,\n      line.id,\n      [...this._buildColumnCandidates(line.axis), ...this._buildRowCandidates(line.axis)],\n    );\n\n    const onMove = (ev: PointerEvent) => {\n      const delta =\n        line.axis === \"horizontal\" ? ev.clientY - startPointer : ev.clientX - startPointer;\n      const rawDocPos = Math.max(0, startDocPosition + delta);\n\n      const snapResult = ev.shiftKey ? null : this.snapEngine.findSnap(rawDocPos);\n      const docPos = snapResult\n        ? snapResult.position\n        : ev.shiftKey\n          ? rawDocPos\n          : this.snapEngine.snapToStep(rawDocPos);\n\n      if (snapResult) {\n        el.setAttribute(\"data-snapping\", this._snapCategory(snapResult.type));\n        this._setSnapHighlight(snapResult.el ?? null);\n        this._setGuideReference(\n          snapResult.type === \"guide-gap\" ? line.axis : null,\n          snapResult.type === \"guide-gap\" ? (snapResult.referenceLineIds ?? null) : null,\n          snapResult.type === \"guide-gap\" ? (snapResult.gap ?? null) : null,\n        );\n      } else {\n        el.removeAttribute(\"data-snapping\");\n        this._setSnapHighlight(null);\n        this._setGuideReference(null, null, null);\n      }\n\n      this.callbacks.onLineMoved(\n        line.id,\n        docPos,\n        snapResult?.el ? this._elementLabel(snapResult.el) : snapResult?.label,\n      );\n\n      // positionLineEl resets the label — override it when snapping to a named element\n      const entry = this.lineEls.get(line.id);\n      if (entry) {\n        if (snapResult) {\n          entry.labelEl.textContent = this._snapLabel(snapResult, docPos, line.axis);\n        } else {\n          const vSize = this.getViewportSizeForAxis(line.axis);\n          const scroll = line.axis === \"horizontal\" ? this.scrollY : this.scrollX;\n          entry.labelEl.textContent = String(\n            Math.round(this.currentMode.formatPosition(docPos, line.axis, vSize, scroll)),\n          );\n        }\n      }\n    };\n\n    const cleanup = () => {\n      releaseInteractionLock();\n      el.removeAttribute(\"data-snapping\");\n      this._setSnapHighlight(null);\n      this._setGuideReference(null, null, null);\n    };\n\n    const onEnd = (ev: PointerEvent) => {\n      cleanup();\n\n      const delta =\n        line.axis === \"horizontal\" ? ev.clientY - startPointer : ev.clientX - startPointer;\n      const rawDocPos = Math.max(0, startDocPosition + delta);\n      const snapResult = ev.shiftKey ? null : this.snapEngine.findSnap(rawDocPos);\n      const docPos = snapResult\n        ? snapResult.position\n        : ev.shiftKey\n          ? rawDocPos\n          : this.snapEngine.snapToStep(rawDocPos);\n\n      const screenPos = line.axis === \"horizontal\" ? docPos - this.scrollY : docPos - this.scrollX;\n\n      if (screenPos <= this.getRulerThickness()) {\n        this.callbacks.onLineRemoved(line.id);\n      } else {\n        const binding = this._resolveBinding(snapResult);\n        this.callbacks.onDragCommit(\n          line.id,\n          docPos,\n          binding.targetLabel,\n          binding.targetSelector,\n          binding.targetEdge,\n        );\n      }\n    };\n\n    startPointerDrag(e, { onMove, onEnd, onCancel: cleanup });\n  }\n\n  private syncScreenChromePosition(): void {\n    const host = this.host;\n    const rulerThickness = this.getRulerThickness();\n    let chromeWidth = this.viewportWidth;\n    let chromeHeight = this.viewportHeight;\n\n    if (!host || host === document.body || host === document.documentElement) {\n      this.viewportOffsetX = 0;\n      this.viewportOffsetY = 0;\n    } else {\n      const rect = host.getBoundingClientRect();\n      this.viewportOffsetX = Math.round(rect.left);\n      this.viewportOffsetY = Math.round(rect.top);\n      chromeWidth = Math.max(0, Math.round(rect.width));\n      chromeHeight = Math.max(0, Math.round(rect.height));\n    }\n\n    this.topCanvas.style.left = `${this.viewportOffsetX}px`;\n    this.topCanvas.style.top = `${this.viewportOffsetY}px`;\n    this.topCanvas.style.width = `${chromeWidth}px`;\n    this.topCanvas.style.height = `${rulerThickness}px`;\n\n    this.leftCanvas.style.left = `${this.viewportOffsetX}px`;\n    this.leftCanvas.style.top = `${this.viewportOffsetY}px`;\n    this.leftCanvas.style.width = `${rulerThickness}px`;\n    this.leftCanvas.style.height = `${chromeHeight}px`;\n\n    this.cornerEl.style.left = `${this.viewportOffsetX}px`;\n    this.cornerEl.style.top = `${this.viewportOffsetY}px`;\n    this.cornerEl.style.width = `${rulerThickness}px`;\n    this.cornerEl.style.height = `${rulerThickness}px`;\n  }\n\n  private isCompactMobileRuler(): boolean {\n    return getStringDevViewportPolicy(this.viewportWidth).compact;\n  }\n\n  private getRulerThickness(): number {\n    return this.isCompactMobileRuler() ? RULER_THICKNESS_MOBILE : RULER_THICKNESS;\n  }\n\n  private getViewportSizeForAxis(axis: \"horizontal\" | \"vertical\"): number {\n    return axis === \"horizontal\" ? this.viewportHeight : this.viewportWidth;\n  }\n\n  private resolveViewportPointerPos(axis: \"horizontal\" | \"vertical\", ev: PointerEvent): number {\n    const clientPos = axis === \"horizontal\" ? ev.clientY : ev.clientX;\n    const offset = axis === \"horizontal\" ? this.viewportOffsetY : this.viewportOffsetX;\n    return clientPos - offset;\n  }\n\n  private resolveDocPositionFromPointer(axis: \"horizontal\" | \"vertical\", ev: PointerEvent): number {\n    const viewportPos = this.resolveViewportPointerPos(axis, ev);\n    return axis === \"horizontal\" ? viewportPos + this.scrollY : viewportPos + this.scrollX;\n  }\n\n  private acquireDragInteractionLock(): () => void {\n    const release = lockPageInteraction({\n      selection: true,\n      scroll: this.isCompactMobileRuler(),\n      scrollTarget: this.options.scrollTarget,\n    });\n    const trackedRelease = () => {\n      release();\n      this.dragInteractionReleases.delete(trackedRelease);\n    };\n    this.dragInteractionReleases.add(trackedRelease);\n    return trackedRelease;\n  }\n\n  private releaseAllDragInteractionLocks(): void {\n    for (const release of Array.from(this.dragInteractionReleases)) {\n      release();\n    }\n  }\n}\n","import { scopeStringDevStorageKey } from \"./StringDevStorageScope\";\nconst KEY_PREFIX = \"stdg\";\n\nexport interface StringDevPersistedStateOptions<T> {\n  moduleId: string;\n  name: string;\n  default: T;\n  validate?: (raw: unknown) => T | null;\n  legacyKeys?: string[];\n}\n\nexport class StringDevPersistedState<T> {\n  private readonly baseStorageKey: string;\n  private readonly defaultValue: T;\n  private readonly validate?: (raw: unknown) => T | null;\n  private readonly legacyKeys: string[];\n\n  constructor(options: StringDevPersistedStateOptions<T>) {\n    this.baseStorageKey = `${KEY_PREFIX}:${options.moduleId}:${options.name}`;\n    this.defaultValue = options.default;\n    this.validate = options.validate;\n    this.legacyKeys = options.legacyKeys ?? [];\n  }\n\n  public read(): T {\n    const current = this.readRaw(this.storageKey);\n    if (current !== undefined) {\n      return current;\n    }\n\n    for (const legacyKey of this.legacyKeys) {\n      const scopedLegacyKey = scopeStringDevStorageKey(legacyKey);\n      const migrated = this.readRaw(scopedLegacyKey);\n      if (migrated !== undefined) {\n        this.write(migrated);\n        this.clearRaw(scopedLegacyKey);\n        return migrated;\n      }\n    }\n\n    return this.defaultValue;\n  }\n\n  public write(value: T): void {\n    try {\n      localStorage.setItem(this.storageKey, JSON.stringify(value));\n    } catch {\n      /* quota, access denied, etc. */\n    }\n  }\n\n  public clear(): void {\n    this.clearRaw(this.storageKey);\n  }\n\n  private get storageKey(): string {\n    return scopeStringDevStorageKey(this.baseStorageKey);\n  }\n\n  private readRaw(key: string): T | undefined {\n    let raw: string | null;\n    try {\n      raw = localStorage.getItem(key);\n    } catch {\n      return undefined;\n    }\n    if (raw == null) return undefined;\n\n    let parsed: unknown;\n    try {\n      parsed = JSON.parse(raw);\n    } catch {\n      return undefined;\n    }\n\n    if (this.validate) {\n      const validated = this.validate(parsed);\n      return validated == null ? undefined : validated;\n    }\n\n    return parsed as T;\n  }\n\n  private clearRaw(key: string): void {\n    try {\n      localStorage.removeItem(key);\n    } catch {\n      /* ignore */\n    }\n  }\n}\n","import { StringContext } from \"../../../core/StringContext\";\r\nimport { StringDevModule } from \"../core/StringDevModule\";\r\nimport { RULERS_CSS } from \"./StringRulers.css\";\r\nimport { StringData } from \"../../../core/StringData\";\r\nimport { RulersManager } from \"./RulersManager\";\r\nimport { RulersOverlay, RulersRowLayout } from \"./RulersOverlay\";\r\nimport type { RulersLayoutGrid } from \"./models/RulersLayoutGrid\";\r\nimport { StringRulersTrigger, RulersTriggerAction } from \"./models/StringRulersTrigger\";\r\nimport { RULER_MODES, MODE_ORDER, type RulerModeId } from \"./models/RulerMode\";\r\nimport { overlaySlotRegistry } from \"../core/StringDevtoolsOverlayLayout\";\r\nimport { StringDevViewportLayer } from \"../core/StringDevViewportLayer\";\r\nimport { StringDevPersistedState } from \"../core/StringDevPersistedState\";\r\nimport { StringDevtoolSubBadge } from \"../../../models/devtools/StringDevtool\";\r\n\r\nconst GLOBAL_ELEMENT_ID = \"__string-rulers-global__\";\r\n\r\nconst DEFAULT_TRIGGERS: StringRulersTrigger[] = [];\r\n\r\n/**\r\n * StringDevRulers — developer utility module for guide-line rulers.\r\n *\r\n * Usage:\r\n *   st.use(StringDevRulers)\r\n *   st.use(StringDevRulers, { triggers: [...], grid: { type: \"columns\", count: 12, ... } })\r\n *\r\n * Default trigger: Shift + R\r\n *\r\n * Settings:\r\n *   triggers               — array of trigger descriptors (keyboard / element / event)\r\n *   rulers-snap            — grid step in px (0 = off)\r\n *   rulers-snap-elements   — snap to [string] element edges (default: true)\r\n *   rulers-snap-threshold  — snap pull radius in px (default: 8)\r\n *   rulers-snap-selector   — CSS selector for snap targets\r\n *   grid                   — RulersLayoutGrid | RulersLayoutGrid[]\r\n *\r\n * Snap visual feedback:\r\n *   amber → snapping to a DOM element edge / center\r\n *   green → snapping to a layout-grid line\r\n */\r\nexport class StringDevRulers extends StringDevModule {\r\n  private manager: RulersManager = new RulersManager();\r\n  private overlay: RulersOverlay | null = null;\r\n  private visible: boolean = false;\r\n  private dockDisabled: boolean = false;\r\n  private currentModeId: RulerModeId = \"default\";\r\n\r\n  private readonly modeStore = new StringDevPersistedState<RulerModeId>({\r\n    moduleId: \"rulers\",\r\n    name: \"mode\",\r\n    default: \"default\" as RulerModeId,\r\n    validate: (raw) =>\r\n      typeof raw === \"string\" && raw in RULER_MODES ? (raw as RulerModeId) : null,\r\n    legacyKeys: [\"string-rulers:mode\"],\r\n  });\r\n  private readonly viewportLayer: StringDevViewportLayer;\r\n\r\n  // ── Trigger infrastructure ────────────────────────────\r\n\r\n  private _kbHandlers: Array<(e: KeyboardEvent) => void> = [];\r\n  private _elHandlers: Array<{ el: Element; event: string; fn: EventListener }> = [];\r\n  private _evHandlers: Array<{ name: string; fn: (...args: unknown[]) => void }> = [];\r\n\r\n  static override devtool = {\r\n    id: \"rulers\",\r\n    label: \"Rulers\",\r\n    icon: \"ruler\",\r\n    order: 10,\r\n    group: 1,\r\n    hotkey: { key: \"R\", shiftKey: true },\r\n    styles: RULERS_CSS,\r\n    connects: { global: false, keys: [\"rulers\"] },\r\n  };\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.attributesToMap = [];\r\n    this.viewportLayer = this.acquireViewportLayer(\"devtools-rulers\", 10020);\r\n  }\r\n\r\n  // ── Lifecycle ─────────────────────────────────────────\r\n\r\n  onInit(): void {\r\n    this.applyStyleSettings();\r\n    this.mountOverlay();\r\n  }\r\n\r\n  onSettingsChange(): void {\r\n    this.applyStyleSettings();\r\n  }\r\n\r\n  onSubscribe(): void {\r\n    const raw = (this.settings as Record<string, unknown>)[\"triggers\"];\r\n    const triggers: StringRulersTrigger[] = Array.isArray(raw)\r\n      ? (raw as StringRulersTrigger[])\r\n      : DEFAULT_TRIGGERS;\r\n    this._bindTriggers(triggers);\r\n  }\r\n\r\n  onUnsubscribe(): void {\r\n    this._unbindTriggers();\r\n  }\r\n\r\n  onFrame(data: StringData): void {\r\n    if (!this.visible || !this.overlay) return;\r\n    this.pushScrollToOverlay(data);\r\n  }\r\n\r\n  onResize(): void {\r\n    if (!this.overlay) return;\r\n    this.syncOverlayMetrics();\r\n    const lines = this.manager.getLines(GLOBAL_ELEMENT_ID, this.currentModeId);\r\n    this.overlay.recalculateBindings(lines);\r\n    this.manager.save(GLOBAL_ELEMENT_ID, this.currentModeId);\r\n    this.overlay.refresh(lines);\r\n  }\r\n\r\n  destroy(): void {\r\n    this._unbindTriggers();\r\n    this.overlay?.destroy();\r\n    this.overlay = null;\r\n    this.manager.clearAll();\r\n    this.clearStyleSettings();\r\n    super.destroy();\r\n  }\r\n\r\n  // ── Public API ────────────────────────────────────────\r\n\r\n  toggle(): void {\r\n    this.setVisible(!this.visible);\r\n  }\r\n  show(): void {\r\n    this.setVisible(true);\r\n  }\r\n  hide(): void {\r\n    this.setVisible(false);\r\n  }\r\n  clear(): void {\r\n    this.manager.removeAllLines(GLOBAL_ELEMENT_ID, this.currentModeId);\r\n    this.overlay?.refresh([]);\r\n  }\r\n\r\n  public isVisible(): boolean {\r\n    return this.visible;\r\n  }\r\n\r\n  protected getDevtoolActiveState(): boolean {\r\n    return this.visible;\r\n  }\r\n\r\n  protected setDevtoolActiveState(active: boolean): void {\r\n    this.setDockActive(active);\r\n  }\r\n\r\n  protected override getDevtoolSubBadges(): StringDevtoolSubBadge[] {\r\n    return [\r\n      {\r\n        id: \"clear-rulers\",\r\n        icon: \"noplus\",\r\n        label: \"Clear guides\",\r\n        selectorAttribute: \"data-string-rulers-clear-all\",\r\n        onClick: () => this.clear(),\r\n      },\r\n    ];\r\n  }\r\n\r\n  // ── Trigger binding ───────────────────────────────────\r\n\r\n  private _bindTriggers(triggers: StringRulersTrigger[]): void {\r\n    for (const t of triggers) {\r\n      if (t.type === \"keyboard\") {\r\n        const handler = (e: KeyboardEvent) => {\r\n          if (\r\n            e.key === t.key &&\r\n            e.shiftKey === (t.shiftKey ?? false) &&\r\n            e.ctrlKey === (t.ctrlKey ?? false) &&\r\n            e.altKey === (t.altKey ?? false) &&\r\n            e.metaKey === (t.metaKey ?? false)\r\n          ) {\r\n            e.preventDefault();\r\n            this._applyAction(t.action);\r\n          }\r\n        };\r\n        window.addEventListener(\"keydown\", handler);\r\n        this._kbHandlers.push(handler);\r\n      } else if (t.type === \"element\") {\r\n        const eventName = t.event ?? \"click\";\r\n        for (const el of Array.from(document.querySelectorAll(t.selector))) {\r\n          const fn: EventListener = () => this._applyAction(t.action);\r\n          el.addEventListener(eventName, fn);\r\n          this._elHandlers.push({ el, event: eventName, fn });\r\n        }\r\n      } else if (t.type === \"event\") {\r\n        const fn = () => this._applyAction(t.action);\r\n        this.events.on(t.name, fn);\r\n        this._evHandlers.push({ name: t.name, fn });\r\n      }\r\n    }\r\n  }\r\n\r\n  private _unbindTriggers(): void {\r\n    for (const h of this._kbHandlers) window.removeEventListener(\"keydown\", h);\r\n    this._kbHandlers = [];\r\n    for (const { el, event, fn } of this._elHandlers) el.removeEventListener(event, fn);\r\n    this._elHandlers = [];\r\n    for (const { name, fn } of this._evHandlers) this.events.off(name, fn);\r\n    this._evHandlers = [];\r\n  }\r\n\r\n  private _applyAction(action: RulersTriggerAction = \"toggle\"): void {\r\n    if (this.dockDisabled) {\r\n      return;\r\n    }\r\n    if (action === \"show\") this.show();\r\n    else if (action === \"hide\") this.hide();\r\n    else this.toggle();\r\n  }\r\n\r\n  // ── Visibility ────────────────────────────────────────\r\n\r\n  private setVisible(value: boolean): void {\r\n    if (value && this.dockDisabled) {\r\n      return;\r\n    }\r\n    if (this.visible === value) {\r\n      return;\r\n    }\r\n    this.visible = value;\r\n    this.overlay?.setVisible(value);\r\n    overlaySlotRegistry.emitLayoutChange();\r\n    this.emitDevtoolState();\r\n  }\r\n\r\n  private setDockActive(active: boolean): void {\r\n    this.dockDisabled = !active;\r\n    this.setVisible(active);\r\n  }\r\n\r\n  // ── Overlay management ────────────────────────────────\r\n\r\n  private mountOverlay(): void {\r\n    if (this.overlay) return;\r\n\r\n    const elementId = GLOBAL_ELEMENT_ID;\r\n\r\n    this.currentModeId = this.modeStore.read();\r\n\r\n    this.manager.load(elementId, this.currentModeId);\r\n\r\n    const s = this.settings as Record<string, unknown>;\r\n    const snapStep = typeof s[\"rulers-snap\"] === \"number\" ? (s[\"rulers-snap\"] as number) : 0;\r\n    const snapToElements =\r\n      typeof s[\"rulers-snap-elements\"] === \"boolean\"\r\n        ? (s[\"rulers-snap-elements\"] as boolean)\r\n        : true;\r\n    const snapThreshold =\r\n      typeof s[\"rulers-snap-threshold\"] === \"number\" ? (s[\"rulers-snap-threshold\"] as number) : 8;\r\n    const snapSelector =\r\n      typeof s[\"rulers-snap-selector\"] === \"string\"\r\n        ? (s[\"rulers-snap-selector\"] as string)\r\n        : \"[string],[data-string]\";\r\n    const layoutGrids = this._resolveGrids(s[\"grid\"]);\r\n\r\n    const rulersColumns =\r\n      typeof s[\"rulers-columns\"] === \"number\" ? (s[\"rulers-columns\"] as number) : 0;\r\n    const rulersMargin =\r\n      typeof s[\"rulers-margin\"] === \"string\" ? (s[\"rulers-margin\"] as string) : \"0px\";\r\n    const rulersGap = typeof s[\"rulers-gap\"] === \"string\" ? (s[\"rulers-gap\"] as string) : \"0px\";\r\n    const columnLayout =\r\n      rulersColumns > 0\r\n        ? { columns: rulersColumns, margin: rulersMargin, gap: rulersGap }\r\n        : undefined;\r\n\r\n    const rulersRowSize = typeof s[\"rulers-rows\"] === \"string\" ? (s[\"rulers-rows\"] as string) : \"\";\r\n    const rulersRowGap =\r\n      typeof s[\"rulers-rows-gap\"] === \"string\" ? (s[\"rulers-rows-gap\"] as string) : \"0px\";\r\n    const rowLayout: RulersRowLayout | undefined = rulersRowSize\r\n      ? { size: rulersRowSize, gap: rulersRowGap }\r\n      : undefined;\r\n\r\n    this.overlay = new RulersOverlay(\r\n      {\r\n        onLineCreated: (axis, position, targetLabel, targetSelector, targetEdge) => {\r\n          this.manager.addLine(\r\n            elementId,\r\n            axis,\r\n            position,\r\n            targetLabel,\r\n            this.currentModeId,\r\n            targetSelector,\r\n            targetEdge,\r\n          );\r\n          this.overlay!.refresh(this.manager.getLines(elementId, this.currentModeId));\r\n        },\r\n        onLineMoved: (lineId, position, targetLabel) => {\r\n          this.manager.moveLine(elementId, lineId, position, targetLabel, this.currentModeId);\r\n          this.overlay!.refresh(this.manager.getLines(elementId, this.currentModeId));\r\n        },\r\n        onLineRemoved: (lineId) => {\r\n          this.manager.removeLine(elementId, lineId, this.currentModeId);\r\n          this.overlay!.refresh(this.manager.getLines(elementId, this.currentModeId));\r\n        },\r\n        onDragCommit: (lineId, position, targetLabel, targetSelector, targetEdge) => {\r\n          this.manager.moveLine(elementId, lineId, position, targetLabel, this.currentModeId);\r\n          const line = this.manager.findLine(elementId, lineId, this.currentModeId);\r\n          if (line) {\r\n            line.targetSelector = targetSelector;\r\n            line.targetEdge = targetEdge;\r\n          }\r\n          this.manager.save(elementId, this.currentModeId);\r\n          this.overlay!.refresh(this.manager.getLines(elementId, this.currentModeId));\r\n        },\r\n        onModeToggle: () => this.cycleMode(),\r\n      },\r\n      {\r\n        snapStep,\r\n        snapToElements,\r\n        snapThreshold,\r\n        snapSelector,\r\n        layoutGrids,\r\n        columnLayout,\r\n        rowLayout,\r\n        scrollTarget: this.data.scroll.elementContainer,\r\n      },\r\n      this.data.scroll.container,\r\n      this.viewportLayer,\r\n    );\r\n\r\n    this.syncOverlayMetrics();\r\n    this.overlay.setMode(RULER_MODES[this.currentModeId]);\r\n    this.overlay.setVisible(this.visible);\r\n    this.overlay.refresh(this.manager.getLines(elementId, this.currentModeId));\r\n  }\r\n\r\n  // ── Mode switching ──────────────────────────────────────\r\n\r\n  private cycleMode(): void {\r\n    const idx = MODE_ORDER.indexOf(this.currentModeId);\r\n    const nextIdx = (idx + 1) % MODE_ORDER.length;\r\n    this.switchMode(MODE_ORDER[nextIdx]);\r\n  }\r\n\r\n  private switchMode(modeId: RulerModeId): void {\r\n    const elementId = GLOBAL_ELEMENT_ID;\r\n\r\n    // Persist current mode's lines\r\n    this.manager.save(elementId, this.currentModeId);\r\n\r\n    // Switch\r\n    this.currentModeId = modeId;\r\n    this.manager.load(elementId, modeId);\r\n\r\n    // Update overlay\r\n    this.overlay?.setMode(RULER_MODES[modeId]);\r\n    this.overlay?.refresh(this.manager.getLines(elementId, modeId));\r\n\r\n    this.modeStore.write(modeId);\r\n  }\r\n\r\n  private applyStyleSettings(): void {\r\n    const s = this.settings as Record<string, unknown>;\r\n    const lineColor =\r\n      typeof s[\"rulers-color\"] === \"string\"\r\n        ? (s[\"rulers-color\"] as string)\r\n        : \"rgba(0, 120, 255, 0.75)\";\r\n    const lineOpacityRaw =\r\n      typeof s[\"rulers-opacity\"] === \"number\" ? (s[\"rulers-opacity\"] as number) : 1;\r\n    const lineOpacity = Math.max(0, Math.min(1, lineOpacityRaw));\r\n\r\n    document.documentElement.style.setProperty(\"--string-rulers-line-color\", lineColor);\r\n    document.documentElement.style.setProperty(\"--string-rulers-line-opacity\", String(lineOpacity));\r\n  }\r\n\r\n  private clearStyleSettings(): void {\r\n    document.documentElement.style.removeProperty(\"--string-rulers-line-color\");\r\n    document.documentElement.style.removeProperty(\"--string-rulers-line-opacity\");\r\n  }\r\n\r\n  /** Normalises the `grid` setting to RulersLayoutGrid[] (or undefined). */\r\n  private _resolveGrids(raw: unknown): RulersLayoutGrid[] | undefined {\r\n    if (!raw) return undefined;\r\n    if (Array.isArray(raw)) return raw as RulersLayoutGrid[];\r\n    if (typeof raw === \"object\") return [raw as RulersLayoutGrid];\r\n    return undefined;\r\n  }\r\n\r\n  private syncOverlayMetrics(): void {\r\n    if (!this.overlay) return;\r\n    this.pushScrollToOverlay(this.data);\r\n  }\r\n\r\n  private pushScrollToOverlay(data: StringData): void {\r\n    if (!this.overlay) return;\r\n    const container = data.scroll.elementContainer;\r\n    const horizontal = data.scroll.direction === \"horizontal\";\r\n    const scrollX = horizontal ? container.scrollLeft : 0;\r\n    const scrollY = horizontal ? 0 : container.scrollTop;\r\n    this.overlay.updateScroll(\r\n      scrollX,\r\n      scrollY,\r\n      data.viewport.windowWidth,\r\n      data.viewport.windowHeight,\r\n      data.viewport.contentWidth,\r\n      data.viewport.contentHeight,\r\n    );\r\n  }\r\n}\r\n\r\nexport { StringDevRulers as StringRulers };\r\n","import { StringContext } from \"../../../core/StringContext\";\r\nimport { StringDevModule, StringDevOverlayConfig } from \"./StringDevModule\";\r\nimport { StringObject } from \"../../../objects/StringObject\";\r\nimport { styleTxn } from \"../../../utils/style-txn\";\r\nimport {\r\n  AnchorPoint,\r\n  overlaySlotRegistry,\r\n  STRING_DEVTOOLS_OVERLAY_LAYOUT_CHANGE_EVENT,\r\n  StringDevtoolsOverlayId,\r\n} from \"./StringDevtoolsOverlayLayout\";\r\nimport { StringDevViewportLayer } from \"./StringDevViewportLayer\";\r\n\r\nconst RULERS_LEFT_PANEL_WIDTH = 20;\r\nconst RULERS_TOP_PANEL_HEIGHT = 20;\r\nconst BADGE_RULER_OFFSET_X = 24;\r\nconst BADGE_RULER_OFFSET_Y = 24;\r\nconst RULERS_HIDDEN_ATTRIBUTE = \"data-string-rulers-hidden\";\r\nconst RULERS_LEFT_SELECTOR = \"[data-string-rulers-left]\";\r\nconst RULERS_TOP_SELECTOR = \"[data-string-rulers-top]\";\r\n\r\nexport type OverlayAxis = \"y\" | \"x\";\r\nexport type OverlayAnchor = \"start\" | \"end\";\r\n\r\nexport interface OverlayBaseMetrics {\r\n  visible: boolean;\r\n  contentX: number;\r\n  contentY: number;\r\n  width: number;\r\n  height: number;\r\n  isOffscreen: boolean;\r\n  baseAnchorX: number;\r\n  baseAnchorY: number;\r\n  collisionOffset: number;\r\n  axis: OverlayAxis;\r\n  primarySize: number;\r\n  crossSize: number;\r\n  primaryContentOffset: number;\r\n  viewportPrimarySize: number;\r\n}\r\n\r\ninterface OverlayObjectGeometry {\r\n  contentX: number;\r\n  contentY: number;\r\n  width: number;\r\n  height: number;\r\n}\r\n\r\nconst VIEWPORT_ANCHOR_MAP: Record<string, OverlayAnchor> = {\r\n  top: \"start\",\r\n  left: \"start\",\r\n  start: \"start\",\r\n  bottom: \"end\",\r\n  right: \"end\",\r\n  end: \"end\",\r\n};\r\n\r\nexport function resolveOverlayAnchor(raw: string | null | undefined): OverlayAnchor {\r\n  if (!raw) return \"start\";\r\n  return VIEWPORT_ANCHOR_MAP[raw.toLowerCase()] ?? \"start\";\r\n}\r\n\r\nexport interface StringDevOverlayBadgeInit {\r\n  targetId: string;\r\n  selectorAttribute?: string;\r\n  depth?: number;\r\n  attributes?: Record<string, string | boolean | number | null | undefined>;\r\n}\r\n\r\nexport interface StringDevOverlayBadgeState {\r\n  visible?: boolean;\r\n  active?: boolean;\r\n  disabled?: boolean;\r\n  title?: string;\r\n  html?: string;\r\n  label?: string;\r\n  attributes?: Record<string, string | boolean | number | null | undefined>;\r\n}\r\n\r\nexport abstract class StringDevOverlayModule<\r\n  TEntry = unknown,\r\n  TMeasurement = unknown,\r\n> extends StringDevModule {\r\n  private _viewportLayer?: StringDevViewportLayer;\r\n  private _badgeLayer?: StringDevViewportLayer;\r\n  private _hudLayer?: StringDevViewportLayer;\r\n\r\n  protected get viewportLayer(): StringDevViewportLayer {\r\n    if (!this._viewportLayer) {\r\n      this._viewportLayer = this.acquireViewportLayer(this.layerName, this.layerZIndex);\r\n    }\r\n    return this._viewportLayer;\r\n  }\r\n\r\n  protected get badgeLayer(): StringDevViewportLayer {\r\n    if (!this._badgeLayer) {\r\n      this._badgeLayer = this.acquireViewportLayer(\"devtools-badges\", 10030);\r\n    }\r\n    return this._badgeLayer;\r\n  }\r\n\r\n  protected get hudLayer(): StringDevViewportLayer {\r\n    if (!this._hudLayer) {\r\n      this._hudLayer = this.acquireViewportLayer(\"devtools-hud\", 10040);\r\n    }\r\n    return this._hudLayer;\r\n  }\r\n  protected readonly entries = new Map<string, TEntry>();\r\n  protected readonly measurements = new Map<string, TMeasurement>();\r\n\r\n  protected enabled = false;\r\n  protected needsMeasure = false;\r\n  protected hasPendingMutate = false;\r\n\r\n  private _rafId: number | null = null;\r\n  private _pendingSingleIds = new Set<string>();\r\n\r\n  private readonly onOverlayLayoutChangeBind = () => {\r\n    if (!this.enabled) return;\r\n    this.scheduleSync();\r\n  };\r\n\r\n  private get _overlayConfig(): StringDevOverlayConfig | undefined {\r\n    return (this.constructor as typeof StringDevModule).devtool?.overlay;\r\n  }\r\n\r\n  /** Override to provide the overlay ID for the anchor/collision system. */\r\n  protected get overlayId(): StringDevtoolsOverlayId | null {\r\n    return this._overlayConfig?.overlayId ?? null;\r\n  }\r\n\r\n  /** Override to declare how many badge slots this overlay occupies. */\r\n  protected get overlayBadgeCount(): number {\r\n    return 1;\r\n  }\r\n\r\n  /** Override to define your viewport layer name. Falls back to devtool.overlay.layerName. */\r\n  protected get layerName(): string {\r\n    return this._overlayConfig?.layerName ?? \"\";\r\n  }\r\n\r\n  /** Override to define your viewport layer z-index. Falls back to devtool.overlay.zIndex. */\r\n  protected get layerZIndex(): number {\r\n    return this._overlayConfig?.zIndex ?? 10011;\r\n  }\r\n\r\n  /** Override to define the data-attribute added to the layer root. Falls back to devtool.overlay.layerAttribute. */\r\n  protected get layerAttribute(): string {\r\n    return this._overlayConfig?.layerAttribute ?? \"\";\r\n  }\r\n\r\n  /** Override when an overlay module should start enabled before dock preferences apply. Falls back to devtool.overlay.defaultEnabled. */\r\n  protected get defaultEnabled(): boolean {\r\n    return this._overlayConfig?.defaultEnabled ?? false;\r\n  }\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.enabled = this.defaultEnabled;\r\n  }\r\n\r\n  onInit(): void {\r\n    this.ensureLayer();\r\n    this.applyEnabledState();\r\n    window.addEventListener(\r\n      STRING_DEVTOOLS_OVERLAY_LAYOUT_CHANGE_EVENT,\r\n      this.onOverlayLayoutChangeBind,\r\n    );\r\n  }\r\n\r\n  onObjectConnected(object: StringObject): void {\r\n    this.ensureLayer();\r\n    const entry = this.createOverlayEntry(object);\r\n    if (!entry) return;\r\n\r\n    this.entries.set(object.id, entry);\r\n    this.syncSlotRegistration();\r\n    this.scheduleSync();\r\n  }\r\n\r\n  onObjectDisconnected(object: StringObject): void {\r\n    const entry = this.entries.get(object.id);\r\n    if (!entry) return;\r\n\r\n    this.destroyOverlayEntry(entry);\r\n    this.entries.delete(object.id);\r\n    this.measurements.delete(object.id);\r\n    this.syncSlotRegistration();\r\n  }\r\n\r\n  public setEnabled(enabled: boolean): void {\r\n    if (this.enabled === enabled) return;\r\n    this.enabled = enabled;\r\n    if (enabled) {\r\n      this.measurements.clear();\r\n    }\r\n\r\n    this.applyEnabledState();\r\n    this.onEnabledChange(enabled);\r\n    this.scheduleFullSync();\r\n    this.emitDevtoolState();\r\n  }\r\n\r\n  public isEnabled(): boolean {\r\n    return this.enabled;\r\n  }\r\n\r\n  protected getDevtoolActiveState(): boolean {\r\n    return this.enabled;\r\n  }\r\n\r\n  protected setDevtoolActiveState(active: boolean): void {\r\n    this.setEnabled(active);\r\n  }\r\n\r\n  // --- Abstract Methods ---\r\n\r\n  /** Create DOM and return state for the given element */\r\n  protected abstract createOverlayEntry(object: StringObject): TEntry | null;\r\n\r\n  /** Clean up DOM and listeners for the given element */\r\n  protected abstract destroyOverlayEntry(entry: TEntry): void;\r\n\r\n  /** Produce a custom measurement state utilizing the provided base metrics */\r\n  protected abstract measureEntry(entry: TEntry, baseMetrics: OverlayBaseMetrics): TMeasurement;\r\n\r\n  /** Render DOM efficiently utilizing `styleTxn` */\r\n  protected abstract applyMeasurement(entry: TEntry, measurement: TMeasurement | undefined): void;\r\n\r\n  /** Called when `setEnabled` state flips, allowing subclasses to show/hide specific entries */\r\n  protected onEnabledChange(_enabled: boolean): void {}\r\n\r\n  // --- Render Loop (Measurement and Syncing) ---\r\n\r\n  onScroll(): void {\r\n    if (!this.enabled) return;\r\n    this.needsMeasure = true;\r\n  }\r\n\r\n  onScrollMeasure(): void {\r\n    if (!this.enabled || !this.needsMeasure) return;\r\n    this.collectMeasurements();\r\n    this.needsMeasure = false;\r\n    this.flushMeasurements();\r\n    this.hasPendingMutate = false;\r\n  }\r\n\r\n  onMutate(): void {\r\n    if (!this.enabled || !this.hasPendingMutate) return;\r\n    this.flushMeasurements();\r\n    this.hasPendingMutate = false;\r\n  }\r\n\r\n  onResize(): void {\r\n    if (!this.enabled) return;\r\n    this.scheduleSync();\r\n  }\r\n\r\n  onDOMRebuild(): void {\r\n    if (!this.enabled) return;\r\n    this.scheduleSync();\r\n  }\r\n\r\n  // --- Internal implementations ---\r\n\r\n  /**\r\n   * Immediate synchronous full sync — use only when instant visual response\r\n   * is required (e.g. setEnabled). For everything else prefer scheduleSync().\r\n   */\r\n  protected scheduleFullSync(): void {\r\n    this.ensureLayer();\r\n    this._pendingSingleIds.clear();\r\n    if (this._rafId !== null) {\r\n      cancelAnimationFrame(this._rafId);\r\n      this._rafId = null;\r\n    }\r\n    this.needsMeasure = true;\r\n    this.collectMeasurements();\r\n    this.needsMeasure = false;\r\n    this.flushMeasurements();\r\n    this.hasPendingMutate = false;\r\n  }\r\n\r\n  /**\r\n   * Deferred full sync — batches multiple calls within the same animation\r\n   * frame into a single measure+flush pass. Use for resize, layout changes,\r\n   * object connected, and any other non-immediate triggers.\r\n   */\r\n  protected scheduleSync(): void {\r\n    if (!this.enabled) return;\r\n    this._pendingSingleIds.clear();\r\n    if (this._rafId !== null) return;\r\n    this._rafId = requestAnimationFrame(() => {\r\n      this._rafId = null;\r\n      if (!this.enabled) return;\r\n      this.ensureLayer();\r\n      this.collectMeasurements();\r\n      this.flushMeasurements();\r\n    });\r\n  }\r\n\r\n  /**\r\n   * Deferred single-entry sync — measures and flushes only the given entry.\r\n   * Multiple calls for different entries within the same frame are batched\r\n   * together into one styleTxn flush. Use for per-object events like\r\n   * object:inview or slider input where only one entry changes.\r\n   */\r\n  protected scheduleSingleSync(entry: TEntry): void {\r\n    if (!this.enabled) return;\r\n    const id = (entry as any).object?.id ?? (entry as any).targetId;\r\n    if (!id) {\r\n      this.scheduleSync();\r\n      return;\r\n    }\r\n    this._pendingSingleIds.add(id);\r\n    if (this._rafId !== null) return;\r\n    this._rafId = requestAnimationFrame(() => {\r\n      this._rafId = null;\r\n      if (!this.enabled) return;\r\n      this.ensureLayer();\r\n      const ids = this._pendingSingleIds;\r\n      this._pendingSingleIds = new Set();\r\n      const measured: TEntry[] = [];\r\n      for (const entryId of ids) {\r\n        const e = this.entries.get(entryId);\r\n        if (!e) continue;\r\n        const bMetrics = this.computeBaseMetrics(e);\r\n        const measurement = this.measureEntry(e, bMetrics);\r\n        this.measurements.set(entryId, measurement);\r\n        measured.push(e);\r\n      }\r\n      styleTxn.run(() => {\r\n        for (const e of measured) {\r\n          const entryId = (e as any).object?.id ?? (e as any).targetId;\r\n          if (!entryId) continue;\r\n          this.applyMeasurement(e, this.measurements.get(entryId));\r\n        }\r\n      });\r\n    });\r\n  }\r\n\r\n  protected collectMeasurements(): void {\r\n    this.ensureLayer();\r\n    for (const [id, entry] of this.entries) {\r\n      const bMetrics = this.computeBaseMetrics(entry);\r\n      this.measurements.set(id, this.measureEntry(entry, bMetrics));\r\n    }\r\n  }\r\n\r\n  protected flushMeasurements(): void {\r\n    styleTxn.run(() => {\r\n      for (const [id, entry] of this.entries) {\r\n        this.applyMeasurement(entry, this.measurements.get(id));\r\n      }\r\n    });\r\n  }\r\n\r\n  protected ensureLayer(): HTMLDivElement {\r\n    const root = this.viewportLayer.ensure(this.getWorldHost());\r\n    if (this.layerAttribute) {\r\n      root.setAttribute(this.layerAttribute, \"\");\r\n    }\r\n    return root;\r\n  }\r\n\r\n  protected applyEnabledState(): void {\r\n    const layer = this.viewportLayer.getElement();\r\n    if (!layer) return;\r\n\r\n    layer.setAttribute(\"data-enabled\", this.enabled ? \"true\" : \"false\");\r\n\r\n    if (this.layerAttribute) {\r\n      if (this.enabled) {\r\n        layer.setAttribute(this.layerAttribute, \"\");\r\n      } else {\r\n        layer.removeAttribute(this.layerAttribute);\r\n      }\r\n    }\r\n\r\n    this.syncSlotRegistration();\r\n  }\r\n\r\n  private syncSlotRegistration(): void {\r\n    if (!this.overlayId) return;\r\n\r\n    const shouldOccupySlot = this.enabled && this.entries.size > 0;\r\n    if (shouldOccupySlot) {\r\n      overlaySlotRegistry.register(\r\n        this.overlayId,\r\n        this.devtoolConfig?.order ?? 0,\r\n        this.overlayBadgeCount,\r\n      );\r\n    } else {\r\n      overlaySlotRegistry.unregister(this.overlayId);\r\n    }\r\n\r\n    overlaySlotRegistry.emitLayoutChange();\r\n  }\r\n\r\n  protected resolveOverlayTargetId(object: StringObject): string {\r\n    return object.htmlElement.id || object.id;\r\n  }\r\n\r\n  protected resolveOverlayObjectDepth(element: HTMLElement): number {\r\n    let depth = 0;\r\n    let current = element.parentElement;\r\n\r\n    while (current) {\r\n      if (current.hasAttribute(\"string-id\") || current.hasAttribute(\"data-string-id\")) {\r\n        depth += 1;\r\n      }\r\n      current = current.parentElement;\r\n    }\r\n\r\n    return depth;\r\n  }\r\n\r\n  protected createOverlayBadge(init: StringDevOverlayBadgeInit): HTMLButtonElement {\r\n    const badge = document.createElement(\"button\");\r\n    badge.type = \"button\";\r\n\r\n    badge.setAttribute(\"data-stdg-button\", \"\");\r\n    badge.setAttribute(\"data-stdg-button-icon-16\", \"\");\r\n    badge.setAttribute(\"data-string-devtools-overlay-badge\", \"\");\r\n    badge.setAttribute(\"data-target-id\", init.targetId);\r\n\r\n    if (init.selectorAttribute) {\r\n      badge.setAttribute(init.selectorAttribute, \"\");\r\n    }\r\n\r\n    if (init.depth != null) {\r\n      badge.setAttribute(\"data-depth\", String(init.depth));\r\n    }\r\n\r\n    this.applyOverlayBadgeState(badge, { attributes: init.attributes });\r\n    return badge;\r\n  }\r\n\r\n  protected applyOverlayBadgeState(badge: HTMLElement, state: StringDevOverlayBadgeState): void {\r\n    if (state.visible != null) {\r\n      badge.setAttribute(\"data-visible\", state.visible ? \"true\" : \"false\");\r\n    }\r\n\r\n    if (state.active != null) {\r\n      badge.setAttribute(\"data-active\", state.active ? \"true\" : \"false\");\r\n    }\r\n\r\n    if (state.disabled != null && badge instanceof HTMLButtonElement) {\r\n      badge.disabled = state.disabled;\r\n    }\r\n\r\n    if (state.title != null) {\r\n      badge.title = state.title;\r\n    }\r\n\r\n    if (state.html != null) {\r\n      const existingLabel = badge.querySelector<HTMLElement>(\"[data-stdg-badge-label]\");\r\n      badge.innerHTML = state.html;\r\n      if (existingLabel) badge.appendChild(existingLabel);\r\n    }\r\n\r\n    if (state.label !== undefined) {\r\n      let labelEl = badge.querySelector<HTMLElement>(\"[data-stdg-badge-label]\");\r\n      if (state.label === null || state.label === \"\") {\r\n        labelEl?.remove();\r\n      } else {\r\n        if (!labelEl) {\r\n          labelEl = document.createElement(\"span\");\r\n          labelEl.setAttribute(\"data-stdg-badge-label\", \"\");\r\n          badge.appendChild(labelEl);\r\n        }\r\n        if (labelEl.textContent !== state.label) {\r\n          labelEl.textContent = state.label;\r\n        }\r\n      }\r\n    }\r\n\r\n    if (!state.attributes) return;\r\n\r\n    for (const [key, value] of Object.entries(state.attributes)) {\r\n      if (value == null) {\r\n        badge.removeAttribute(key);\r\n        continue;\r\n      }\r\n\r\n      if (typeof value === \"boolean\") {\r\n        badge.setAttribute(key, value ? \"true\" : \"false\");\r\n        continue;\r\n      }\r\n\r\n      badge.setAttribute(key, String(value));\r\n    }\r\n  }\r\n\r\n  protected applyOverlayBadgePosition(\r\n    badge: HTMLElement,\r\n    measurement: { visible: boolean; docX: number; docY: number; translate?: string } | undefined,\r\n  ): void {\r\n    if (!measurement) {\r\n      badge.setAttribute(\"data-visible\", \"false\");\r\n      return;\r\n    }\r\n\r\n    badge.setAttribute(\"data-visible\", measurement.visible ? \"true\" : \"false\");\r\n    if (!measurement.visible) {\r\n      return;\r\n    }\r\n\r\n    styleTxn.setProps(badge, {\r\n      transform: `translate3d(${Math.round(measurement.docX)}px, ${Math.round(measurement.docY)}px, 0)${measurement.translate ? ` ${measurement.translate}` : \"\"}`,\r\n    });\r\n  }\r\n\r\n  protected getOverlayTargetLabel(object: StringObject): string {\r\n    const element = object.htmlElement;\r\n    const elementId = element.getAttribute(\"id\")?.trim();\r\n    if (elementId) return `#${elementId}`;\r\n\r\n    const className = element.getAttribute(\"class\")?.trim();\r\n    if (className) {\r\n      const classSelector = className\r\n        .split(/\\s+/)\r\n        .filter(Boolean)\r\n        .map((name) => `.${name}`)\r\n        .join(\"\");\r\n      if (classSelector) return classSelector;\r\n    }\r\n\r\n    const stringId =\r\n      element.getAttribute(\"string-id\")?.trim() || element.getAttribute(\"data-string-id\")?.trim();\r\n    if (stringId) return stringId;\r\n\r\n    return object.id || \"<unnamed>\";\r\n  }\r\n\r\n  protected getViewportAnchorOffset(anchor: OverlayAnchor, metrics: OverlayBaseMetrics): number {\r\n    return anchor === \"end\" ? metrics.viewportPrimarySize : 0;\r\n  }\r\n\r\n  protected getOverlayAnchorAdjustment(\r\n    _object: StringObject,\r\n    _anchor: AnchorPoint,\r\n    _metrics?: { contentX: number; contentY: number; width: number; height: number },\r\n  ): AnchorPoint {\r\n    return { docX: 0, docY: 0 };\r\n  }\r\n\r\n  protected resolveRulerPanelOffset(contentX: number, contentY: number): { x: number; y: number } {\r\n    if (typeof document === \"undefined\") return { x: 0, y: 0 };\r\n    if (document.body.hasAttribute(RULERS_HIDDEN_ATTRIBUTE)) return { x: 0, y: 0 };\r\n    const scrollLeft = this.getViewportScrollLeft();\r\n    const scrollTop = this.getViewportScrollTop();\r\n    const x =\r\n      !!document.querySelector(RULERS_LEFT_SELECTOR) &&\r\n      contentX - scrollLeft < RULERS_LEFT_PANEL_WIDTH\r\n        ? BADGE_RULER_OFFSET_X\r\n        : 0;\r\n    const y =\r\n      !!document.querySelector(RULERS_TOP_SELECTOR) &&\r\n      contentY - scrollTop < RULERS_TOP_PANEL_HEIGHT\r\n        ? BADGE_RULER_OFFSET_Y\r\n        : 0;\r\n    return { x, y };\r\n  }\r\n\r\n  protected computeBaseMetrics(entry: any): OverlayBaseMetrics {\r\n    const object = entry.object as StringObject;\r\n    const element = object.htmlElement;\r\n    if (!this.enabled || !element || !element.isConnected) {\r\n      return this.getHiddenMetrics();\r\n    }\r\n\r\n    const geometry = this.resolveOverlayObjectGeometry(object, element);\r\n    const { contentX, contentY, width, height } = geometry;\r\n\r\n    if (width <= 0 || height <= 0) {\r\n      return this.getHiddenMetrics();\r\n    }\r\n\r\n    const viewportHeight = this.data.viewport.windowHeight || window.innerHeight;\r\n    const viewportWidth = this.data.viewport.windowWidth || window.innerWidth;\r\n    const scrollLeft = this.getViewportScrollLeft();\r\n    const scrollTop = this.getViewportScrollTop();\r\n\r\n    const viewportLeft = contentX - scrollLeft;\r\n    const viewportTop = contentY - scrollTop;\r\n\r\n    const isOffscreen =\r\n      viewportTop + height < 0 ||\r\n      viewportTop > viewportHeight ||\r\n      viewportLeft + width < 0 ||\r\n      viewportLeft > viewportWidth;\r\n\r\n    if (isOffscreen) {\r\n      return this.getHiddenMetrics();\r\n    }\r\n\r\n    let baseAnchorX = contentX;\r\n    let baseAnchorY = contentY;\r\n    let collisionOffset = 0;\r\n\r\n    if (this.overlayId) {\r\n      const effectiveAnchorCache = new Map<string, { base: AnchorPoint; effective: AnchorPoint } | null>();\r\n\r\n      const resolveEffectiveAnchor = (\r\n        targetObject: StringObject,\r\n      ): { base: AnchorPoint; effective: AnchorPoint } | null => {\r\n        if (!this.overlayId) return null;\r\n        const targetEntry = this.entries.get(targetObject.id);\r\n        if (!targetEntry) {\r\n          effectiveAnchorCache.set(targetObject.id, null);\r\n          return null;\r\n        }\r\n\r\n        const existingMeasurement = this.measurements.get(targetObject.id) as\r\n          | { visible?: boolean }\r\n          | undefined;\r\n        if (existingMeasurement?.visible === false) {\r\n          effectiveAnchorCache.set(targetObject.id, null);\r\n          return null;\r\n        }\r\n\r\n        const cached = effectiveAnchorCache.get(targetObject.id);\r\n        if (cached !== undefined) {\r\n          return cached;\r\n        }\r\n\r\n        const targetElement = targetObject.htmlElement;\r\n        if (!targetElement) {\r\n          effectiveAnchorCache.set(targetObject.id, null);\r\n          return null;\r\n        }\r\n\r\n        const targetGeometry = this.resolveOverlayObjectGeometry(targetObject, targetElement);\r\n        const targetContentX = targetGeometry.contentX;\r\n        const targetContentY = targetGeometry.contentY;\r\n        const targetWidth = targetGeometry.width;\r\n        const targetHeight = targetGeometry.height;\r\n\r\n        const targetAnchor = overlaySlotRegistry.resolveAnchor(\r\n          this.overlayId,\r\n          targetContentX,\r\n          targetContentY,\r\n        );\r\n        const targetAdjustment = this.getOverlayAnchorAdjustment(targetObject, targetAnchor, {\r\n          contentX: targetContentX,\r\n          contentY: targetContentY,\r\n          width: targetWidth,\r\n          height: targetHeight,\r\n        });\r\n        const targetRulerOffset = this.resolveRulerPanelOffset(targetContentX, targetContentY);\r\n        const targetBaseX = targetAnchor.docX + targetAdjustment.docX + targetRulerOffset.x;\r\n        const targetBaseY = targetAnchor.docY + targetAdjustment.docY + targetRulerOffset.y;\r\n        const targetCollisionOffset = overlaySlotRegistry.resolveCollisionOffset(\r\n          targetElement,\r\n          targetBaseX,\r\n          targetBaseY,\r\n          (ancestorId) => {\r\n            const ancestorObject = this.objectManager.all.get(ancestorId);\r\n            if (!ancestorObject) return null;\r\n            const effective = resolveEffectiveAnchor(ancestorObject)?.effective;\r\n            if (effective) return effective;\r\n            // Ancestor exists but has no badge for this overlay — fall back to its element Y\r\n            // so all overlays on the same child get consistent collision offsets.\r\n            // Use targetBaseX so the X check is a no-op and only Y proximity matters.\r\n            return {\r\n              docX: targetBaseX,\r\n              docY: this.resolveOverlayObjectGeometry(ancestorObject).contentY,\r\n            };\r\n          },\r\n        );\r\n        const resolvedAnchor = {\r\n          base: {\r\n            docX: targetBaseX,\r\n            docY: targetBaseY,\r\n          },\r\n          effective: {\r\n            docX: targetBaseX,\r\n            docY: targetBaseY + targetCollisionOffset,\r\n          },\r\n        };\r\n        effectiveAnchorCache.set(targetObject.id, resolvedAnchor);\r\n        return resolvedAnchor;\r\n      };\r\n\r\n      const resolvedAnchor = resolveEffectiveAnchor(object);\r\n      if (resolvedAnchor) {\r\n        baseAnchorX = resolvedAnchor.base.docX;\r\n        baseAnchorY = resolvedAnchor.base.docY;\r\n        collisionOffset = resolvedAnchor.effective.docY - resolvedAnchor.base.docY;\r\n      }\r\n    }\r\n\r\n    const axis: OverlayAxis = this.data.scroll.direction === \"horizontal\" ? \"x\" : \"y\";\r\n    const primarySize = axis === \"y\" ? height : width;\r\n    const crossSize = axis === \"y\" ? width : height;\r\n    const primaryContentOffset = axis === \"y\" ? contentY : contentX;\r\n    const viewportPrimarySize = axis === \"y\" ? viewportHeight : viewportWidth;\r\n\r\n    return {\r\n      visible: true,\r\n      contentX,\r\n      contentY,\r\n      width,\r\n      height,\r\n      isOffscreen,\r\n      baseAnchorX,\r\n      baseAnchorY,\r\n      collisionOffset,\r\n      axis,\r\n      primarySize,\r\n      crossSize,\r\n      primaryContentOffset,\r\n      viewportPrimarySize,\r\n    };\r\n  }\r\n\r\n  protected getHiddenMetrics(): OverlayBaseMetrics {\r\n    const axis: OverlayAxis = this.data.scroll.direction === \"horizontal\" ? \"x\" : \"y\";\r\n    return {\r\n      visible: false,\r\n      contentX: 0,\r\n      contentY: 0,\r\n      width: 0,\r\n      height: 0,\r\n      isOffscreen: true,\r\n      baseAnchorX: 0,\r\n      baseAnchorY: 0,\r\n      collisionOffset: 0,\r\n      axis,\r\n      primarySize: 0,\r\n      crossSize: 0,\r\n      primaryContentOffset: 0,\r\n      viewportPrimarySize: 0,\r\n    };\r\n  }\r\n\r\n  protected getObjectDocY(object: StringObject): number {\r\n    const start = object.getProperty<number>(\"start\");\r\n    const size = object.getProperty<number>(\"size\");\r\n    if (start != null && size != null && size > 0) {\r\n      return start;\r\n    }\r\n    return object.getProperty<number>(\"layout-doc-top\") ?? 0;\r\n  }\r\n\r\n  protected resolveOverlayObjectGeometry(\r\n    object: StringObject,\r\n    element: HTMLElement = object.htmlElement,\r\n  ): OverlayObjectGeometry {\r\n    const liveRect = element.getBoundingClientRect();\r\n    const liveMetrics = this.resolveLiveElementMetrics(element, liveRect);\r\n    const width =\r\n      liveMetrics.width ||\r\n      (object.getProperty<number>(\"layout-width\") ??\r\n        (object.getProperty<number>(\"half-width\") ?? 0) * 2) ||\r\n      element.offsetWidth ||\r\n      element.clientWidth ||\r\n      0;\r\n\r\n    const measuredSize = object.getProperty<number>(\"size\");\r\n    const layoutHeight =\r\n      liveMetrics.height ||\r\n      (object.getProperty<number>(\"layout-height\") ??\r\n        (object.getProperty<number>(\"half-height\") ?? 0) * 2) ||\r\n      element.offsetHeight ||\r\n      element.clientHeight ||\r\n      0;\r\n\r\n    return {\r\n      contentX: liveMetrics.docLeft ?? object.getProperty<number>(\"layout-doc-left\") ?? 0,\r\n      contentY: liveMetrics.docTop ?? this.getObjectDocY(object),\r\n      width,\r\n      height: measuredSize != null && measuredSize > 0 ? measuredSize : layoutHeight,\r\n    };\r\n  }\r\n\r\n  protected getViewportScrollLeft(): number {\r\n    return this.data.scroll.elementContainer?.scrollLeft ?? 0;\r\n  }\r\n\r\n  protected getViewportScrollTop(): number {\r\n    return this.data.scroll.elementContainer?.scrollTop ?? 0;\r\n  }\r\n\r\n  protected resolveLiveElementMetrics(\r\n    element: HTMLElement,\r\n    rect: DOMRect,\r\n  ): { docLeft?: number; docTop?: number; width: number; height: number } {\r\n    const width = rect.width || element.offsetWidth || element.clientWidth || 0;\r\n    const height = rect.height || element.offsetHeight || element.clientHeight || 0;\r\n    const host = this.getWorldHost();\r\n    const scroller = this.data.scroll.elementContainer;\r\n\r\n    if (!(width > 0) || !(height > 0)) {\r\n      return { width, height };\r\n    }\r\n\r\n    if (host === document.body || host === document.documentElement) {\r\n      return {\r\n        docLeft: rect.left + (scroller?.scrollLeft ?? window.scrollX ?? 0),\r\n        docTop: rect.top + (scroller?.scrollTop ?? window.scrollY ?? 0),\r\n        width,\r\n        height,\r\n      };\r\n    }\r\n\r\n    const hostRect = host.getBoundingClientRect();\r\n    return {\r\n      docLeft: rect.left - hostRect.left + host.scrollLeft,\r\n      docTop: rect.top - hostRect.top + host.scrollTop,\r\n      width,\r\n      height,\r\n    };\r\n  }\r\n\r\n  destroy(): void {\r\n    if (this.overlayId) {\r\n      overlaySlotRegistry.unregister(this.overlayId);\r\n    }\r\n    window.removeEventListener(\r\n      STRING_DEVTOOLS_OVERLAY_LAYOUT_CHANGE_EVENT,\r\n      this.onOverlayLayoutChangeBind,\r\n    );\r\n    for (const entry of this.entries.values()) {\r\n      this.destroyOverlayEntry(entry);\r\n    }\r\n    this.entries.clear();\r\n    this.measurements.clear();\r\n    super.destroy();\r\n  }\r\n}\r\n","import { StringObject } from \"../../../objects/StringObject\";\r\nimport { makeBadge } from \"./StringDevElements\";\r\nimport {\r\n  OverlayBaseMetrics,\r\n  StringDevOverlayBadgeState,\r\n  StringDevOverlayModule,\r\n} from \"./StringDevOverlayModule\";\r\nimport { StringDevModule } from \"./StringDevModule\";\r\n\r\nconst BADGE_SLOT_STEP = 31;\r\n\r\nexport type StringDevBadgeSlot = \"top-left\" | \"top-right\" | \"bottom-right\" | \"bottom-left\";\r\n\r\nexport interface StringDevBadgeSlotConfig {\r\n  gap?: number;\r\n  offsetX?: number;\r\n  offsetY?: number;\r\n}\r\n\r\nexport interface StringDevBadgeDescriptor {\r\n  id: string;\r\n  slot?: StringDevBadgeSlot;\r\n  group?: string;\r\n  selectorAttribute?: string;\r\n  depth?: number;\r\n  attributes?: Record<string, string | boolean | number | null | undefined>;\r\n  gap?: number;\r\n  offsetX?: number;\r\n  offsetY?: number;\r\n}\r\n\r\nexport interface StringDevManagedBadge {\r\n  id: string;\r\n  descriptor: StringDevBadgeDescriptor;\r\n  element: HTMLButtonElement;\r\n}\r\n\r\nexport interface StringDevBadgePositionMeasurement {\r\n  visible: boolean;\r\n  docX: number;\r\n  docY: number;\r\n  translate?: string;\r\n}\r\n\r\nexport interface StringDevBadgeMeasurement {\r\n  visible: boolean;\r\n  badges: Record<string, StringDevBadgePositionMeasurement>;\r\n}\r\n\r\nexport interface StringDevBadgeEntry<TExtra = undefined> {\r\n  object: StringObject;\r\n  targetId: string;\r\n  badge: HTMLButtonElement;\r\n  depth: number;\r\n  extra: TExtra;\r\n  cleanup: Array<() => void>;\r\n  badges: Map<string, StringDevManagedBadge>;\r\n  groups: Map<string, HTMLDivElement>;\r\n}\r\n\r\nexport abstract class StringDevBadgeOverlayModule<\r\n  TExtra = undefined,\r\n  TMeasurement extends StringDevBadgeMeasurement = StringDevBadgeMeasurement,\r\n> extends StringDevOverlayModule<StringDevBadgeEntry<TExtra>, TMeasurement> {\r\n  protected get badgeAttribute(): string {\r\n    return (this.constructor as typeof StringDevModule).devtool?.overlay?.badgeAttribute ?? \"\";\r\n  }\r\n\r\n  protected createOverlayEntry(object: StringObject): StringDevBadgeEntry<TExtra> {\r\n    const targetId = this.resolveOverlayTargetId(object);\r\n    const depth = this.resolveBadgeDepth(object);\r\n    const cleanup: Array<() => void> = [];\r\n    const entry: StringDevBadgeEntry<TExtra> = {\r\n      object,\r\n      targetId,\r\n      badge: document.createElement(\"button\"),\r\n      depth,\r\n      extra: undefined as TExtra,\r\n      cleanup,\r\n      badges: new Map(),\r\n      groups: new Map(),\r\n    };\r\n\r\n    const descriptors = this.getBadgeDescriptors(object, targetId, depth);\r\n    const world = this.badgeLayer.getWorldElement(this.getWorldHost());\r\n\r\n    for (const descriptor of descriptors) {\r\n      const badge = this.createOverlayBadge({\r\n        targetId,\r\n        selectorAttribute: descriptor.selectorAttribute,\r\n        depth: descriptor.depth ?? depth,\r\n        attributes: {\r\n          \"data-badge-id\": descriptor.id,\r\n          ...descriptor.attributes,\r\n        },\r\n      });\r\n      const managedBadge: StringDevManagedBadge = {\r\n        id: descriptor.id,\r\n        descriptor,\r\n        element: badge,\r\n      };\r\n      badge.setAttribute(\"data-visible\", \"false\");\r\n\r\n      const onClick = (event: MouseEvent) => {\r\n        event.stopPropagation();\r\n        event.preventDefault();\r\n        this.onBadgeClick(entry, event, managedBadge);\r\n      };\r\n\r\n      badge.addEventListener(\"click\", onClick);\r\n      cleanup.push(() => badge.removeEventListener(\"click\", onClick));\r\n      entry.badges.set(descriptor.id, managedBadge);\r\n\r\n      if (descriptor.group) {\r\n        let groupEl = entry.groups.get(descriptor.group);\r\n        if (!groupEl) {\r\n          groupEl = makeBadge(targetId);\r\n          entry.groups.set(descriptor.group, groupEl);\r\n          world.appendChild(groupEl);\r\n        }\r\n        groupEl.appendChild(badge);\r\n      } else {\r\n        world.appendChild(badge);\r\n      }\r\n    }\r\n\r\n    const primaryBadge = entry.badges.values().next().value as StringDevManagedBadge | undefined;\r\n    if (!primaryBadge) {\r\n      throw new Error(`${this.constructor.name} must define at least one badge descriptor.`);\r\n    }\r\n\r\n    entry.badge = primaryBadge.element;\r\n    entry.extra = this.createBadgeExtra(object, entry.badge, targetId, depth);\r\n\r\n    const subscriptions = this.bindBadge(entry);\r\n    if (subscriptions) {\r\n      cleanup.push(...subscriptions);\r\n    }\r\n\r\n    this.applyBadgeEnabledState(entry);\r\n    this.renderBadge(entry);\r\n\r\n    return entry;\r\n  }\r\n\r\n  protected destroyOverlayEntry(entry: StringDevBadgeEntry<TExtra>): void {\r\n    for (const cleanup of entry.cleanup) {\r\n      cleanup();\r\n    }\r\n    this.destroyBadgeExtra(entry);\r\n    for (const group of entry.groups.values()) {\r\n      group.remove();\r\n    }\r\n    for (const badge of entry.badges.values()) {\r\n      if (!badge.descriptor.group) {\r\n        badge.element.remove();\r\n      }\r\n    }\r\n  }\r\n\r\n  protected measureEntry(\r\n    entry: StringDevBadgeEntry<TExtra>,\r\n    metrics: OverlayBaseMetrics,\r\n  ): TMeasurement {\r\n    const measurements: Record<string, StringDevBadgePositionMeasurement> = {};\r\n\r\n    if (!metrics.visible) {\r\n      for (const badge of entry.badges.values()) {\r\n        measurements[badge.id] = { visible: false, docX: 0, docY: 0 };\r\n      }\r\n      return { visible: false, badges: measurements } as TMeasurement;\r\n    }\r\n\r\n    // Build ordered slot items: ungrouped badges and groups each get one slot index.\r\n    // Key: either badge.id (ungrouped) or \"group:<groupId>\" (grouped).\r\n    type SlotItem =\r\n      | { kind: \"badge\"; badge: StringDevManagedBadge }\r\n      | { kind: \"group\"; groupId: string; badges: StringDevManagedBadge[] };\r\n\r\n    const slotItems = new Map<StringDevBadgeSlot, SlotItem[]>();\r\n\r\n    const seenGroups = new Set<string>();\r\n    for (const badge of entry.badges.values()) {\r\n      const slot = badge.descriptor.slot ?? \"top-left\";\r\n      if (!slotItems.has(slot)) slotItems.set(slot, []);\r\n      const items = slotItems.get(slot)!;\r\n\r\n      if (badge.descriptor.group) {\r\n        const groupId = badge.descriptor.group;\r\n        if (!seenGroups.has(groupId)) {\r\n          seenGroups.add(groupId);\r\n          items.push({ kind: \"group\", groupId, badges: [] });\r\n        }\r\n        const groupItem = items.find(\r\n          (i): i is Extract<SlotItem, { kind: \"group\" }> =>\r\n            i.kind === \"group\" && i.groupId === groupId,\r\n        );\r\n        groupItem?.badges.push(badge);\r\n      } else {\r\n        items.push({ kind: \"badge\", badge });\r\n      }\r\n    }\r\n\r\n    for (const [slot, items] of slotItems) {\r\n      for (let index = 0; index < items.length; index += 1) {\r\n        const item = items[index];\r\n        const representativeBadge = item.kind === \"badge\" ? item.badge : item.badges[0];\r\n        const slotConfig = this.resolveBadgeSlotConfig(representativeBadge.descriptor);\r\n        const step = BADGE_SLOT_STEP + (slotConfig.gap ?? 0);\r\n        const offsetX = slotConfig.offsetX ?? 0;\r\n        const offsetY = slotConfig.offsetY ?? 0;\r\n        const position = this.resolveBadgePosition(metrics, slot, index, step, offsetX, offsetY);\r\n\r\n        if (item.kind === \"badge\") {\r\n          measurements[item.badge.id] = position;\r\n        } else {\r\n          // All badges in the group share the same slot position —\r\n          // the wrapper gets the transform, individual buttons don't need coordinates.\r\n          for (const badge of item.badges) {\r\n            measurements[badge.id] = position;\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    return { visible: true, badges: measurements } as TMeasurement;\r\n  }\r\n\r\n  protected applyMeasurement(\r\n    entry: StringDevBadgeEntry<TExtra>,\r\n    measurement: TMeasurement | undefined,\r\n  ): void {\r\n    // Apply position to group wrappers (use first badge in group for measurement).\r\n    const positionedGroups = new Set<string>();\r\n    for (const badge of entry.badges.values()) {\r\n      const groupId = badge.descriptor.group;\r\n      if (!groupId) continue;\r\n      if (positionedGroups.has(groupId)) continue;\r\n      positionedGroups.add(groupId);\r\n\r\n      const groupEl = entry.groups.get(groupId);\r\n      if (groupEl) {\r\n        this.applyOverlayBadgePosition(groupEl, measurement?.badges[badge.id]);\r\n      }\r\n    }\r\n\r\n    // Apply visibility to individual badges; ungrouped badges also get their position.\r\n    for (const badge of entry.badges.values()) {\r\n      if (badge.descriptor.group) {\r\n        const pos = measurement?.badges[badge.id];\r\n        badge.element.setAttribute(\"data-visible\", pos?.visible ? \"true\" : \"false\");\r\n      } else {\r\n        this.applyOverlayBadgePosition(badge.element, measurement?.badges[badge.id]);\r\n      }\r\n    }\r\n\r\n    this.afterBadgeMeasurement(entry, measurement);\r\n  }\r\n\r\n  protected onEnabledChange(_enabled: boolean): void {\r\n    for (const entry of this.entries.values()) {\r\n      this.applyBadgeEnabledState(entry);\r\n      this.renderBadge(entry);\r\n    }\r\n  }\r\n\r\n  protected createBadgeExtra(\r\n    _object: StringObject,\r\n    _badge: HTMLButtonElement,\r\n    _targetId: string,\r\n    _depth: number,\r\n  ): TExtra {\r\n    return undefined as TExtra;\r\n  }\r\n\r\n  protected destroyBadgeExtra(_entry: StringDevBadgeEntry<TExtra>): void {}\r\n\r\n  protected bindBadge(_entry: StringDevBadgeEntry<TExtra>): Array<() => void> | void {}\r\n\r\n  protected resolveBadgeDepth(object: StringObject): number {\r\n    return this.resolveOverlayObjectDepth(object.htmlElement);\r\n  }\r\n\r\n  protected getBadgeSlotConfig(): Partial<Record<StringDevBadgeSlot, StringDevBadgeSlotConfig>> {\r\n    return {};\r\n  }\r\n\r\n  protected getBadgeDescriptors(\r\n    object: StringObject,\r\n    targetId: string,\r\n    depth: number,\r\n  ): Array<StringDevBadgeDescriptor> {\r\n    return [\r\n      {\r\n        id: \"primary\",\r\n        slot: \"top-left\",\r\n        selectorAttribute: this.badgeAttribute,\r\n        attributes: this.getInitialBadgeAttributes(object, targetId, depth),\r\n      },\r\n    ];\r\n  }\r\n\r\n  protected getInitialBadgeAttributes(\r\n    _object: StringObject,\r\n    _targetId: string,\r\n    _depth: number,\r\n  ): Record<string, string | boolean | number | null | undefined> | undefined {\r\n    return undefined;\r\n  }\r\n\r\n  protected applyBadgeEnabledState(entry: StringDevBadgeEntry<TExtra>): void {\r\n    for (const badge of entry.badges.values()) {\r\n      this.applyOverlayBadgeState(badge.element, {\r\n        disabled: !this.enabled,\r\n        attributes: { \"data-module-enabled\": this.enabled },\r\n      });\r\n    }\r\n    for (const group of entry.groups.values()) {\r\n      group.setAttribute(\"data-module-enabled\", this.enabled ? \"true\" : \"false\");\r\n    }\r\n  }\r\n\r\n  protected renderBadge(entry: StringDevBadgeEntry<TExtra>): void {\r\n    for (const badge of entry.badges.values()) {\r\n      this.applyOverlayBadgeState(badge.element, this.getBadgeState(entry, badge));\r\n    }\r\n  }\r\n\r\n  protected afterBadgeMeasurement(\r\n    _entry: StringDevBadgeEntry<TExtra>,\r\n    _measurement: TMeasurement | undefined,\r\n  ): void {}\r\n\r\n  protected abstract onBadgeClick(\r\n    entry: StringDevBadgeEntry<TExtra>,\r\n    event: MouseEvent,\r\n    badge: StringDevManagedBadge,\r\n  ): void;\r\n\r\n  protected abstract getBadgeState(\r\n    entry: StringDevBadgeEntry<TExtra>,\r\n    badge?: StringDevManagedBadge,\r\n  ): StringDevOverlayBadgeState;\r\n\r\n  private resolveBadgeSlotConfig(descriptor: StringDevBadgeDescriptor): StringDevBadgeSlotConfig {\r\n    const slot = descriptor.slot ?? \"top-left\";\r\n    const shared = this.getBadgeSlotConfig()[slot] ?? {};\r\n    return {\r\n      gap: descriptor.gap ?? shared.gap ?? 0,\r\n      offsetX: descriptor.offsetX ?? shared.offsetX ?? 0,\r\n      offsetY: descriptor.offsetY ?? shared.offsetY ?? 0,\r\n    };\r\n  }\r\n\r\n  private resolveBadgePosition(\r\n    metrics: OverlayBaseMetrics,\r\n    slot: StringDevBadgeSlot,\r\n    index: number,\r\n    step: number,\r\n    offsetX: number,\r\n    offsetY: number,\r\n  ): StringDevBadgePositionMeasurement {\r\n    const anchorOffsetX = metrics.baseAnchorX - metrics.contentX;\r\n    const anchorOffsetY = metrics.baseAnchorY - metrics.contentY + metrics.collisionOffset;\r\n    const left = metrics.contentX + anchorOffsetX;\r\n    const right = metrics.contentX + metrics.width + anchorOffsetX;\r\n    const top = metrics.contentY + anchorOffsetY;\r\n    const bottom = metrics.contentY + metrics.height + anchorOffsetY;\r\n    switch (slot) {\r\n      case \"top-right\":\r\n        return {\r\n          visible: true,\r\n          docX: right - index * step + offsetX,\r\n          docY: top + offsetY,\r\n          translate: \"translate(-100%, 0%)\",\r\n        };\r\n      case \"bottom-right\":\r\n        return {\r\n          visible: true,\r\n          docX: right - index * step + offsetX,\r\n          docY: bottom + offsetY,\r\n          translate: \"translate(-100%, -100%)\",\r\n        };\r\n      case \"bottom-left\":\r\n        return {\r\n          visible: true,\r\n          docX: left + index * step + offsetX,\r\n          docY: bottom + offsetY,\r\n          translate: \"translate(0%, -100%)\",\r\n        };\r\n      case \"top-left\":\r\n      default:\r\n        return {\r\n          visible: true,\r\n          docX: left + index * step + offsetX,\r\n          docY: top + offsetY,\r\n          translate: \"translate(0%, 0%)\",\r\n        };\r\n    }\r\n  }\r\n}\r\n","export const INVIEW_CSS = `\r\n  [data-string-inview-layer] {\r\n  \r\n  }\r\n\r\n  [data-string-offset-outline] {\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    pointer-events: none;\r\n    box-sizing: border-box;\r\n    // --string-inview-enter-line: rgb(125, 125, 125);\r\n    // border: 1px dashed var(--string-inview-enter-line);\r\n    background-image: url(\"data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' stroke='%23333' stroke-width='1' stroke-dasharray='2%2c 8' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e\");\r\n    will-change: transform, width, height;\r\n  }\r\n\r\n  [data-string-offset-outline][data-visible=\"false\"] {\r\n    display: none;\r\n  }\r\n\r\n  [data-string-offset-outline][data-inview=\"true\"] {\r\n    border-color: var(--string-inview-enter-line);\r\n  }\r\n\r\n  [data-string-offset-connector] {\n    position: absolute;\n    top: 0;\n    left: 0;\n    pointer-events: auto;\r\n    will-change: transform, width, height;\r\n    cursor: col-resize;\r\n    user-select: none;\r\n    touch-action: none;\n  }\n\n  [data-string-offset-connector][data-pointer=\"coarse\"] {\n    width: 22px !important;\n    margin-left: -4px;\n  }\n\r\n  [data-string-offset-connector]::before {\r\n    content: \"\";\r\n    position: absolute;\r\n    top: 0;\r\n    bottom: 0;\r\n    left: 50%;\r\n    width: 1px;\r\n    pointer-events: none;\r\n    background-repeat: repeat-y;\r\n    background-position: center top;\r\n    background-size: 1px 10px;\r\n  }\r\n\r\n  [data-string-offset-connector][data-visible=\"false\"] {\r\n    display: none;\r\n  }\r\n\r\n  [data-string-offset-connector=\"enter\"] {\r\n    color: var(--string-dg-color-blue);\r\n  }\r\n\r\n  [data-string-offset-connector=\"enter\"]::before {\r\n    background-image: url(\"data:image/svg+xml,%3csvg width='1' height='10' viewBox='0 0 1 10' xmlns='http://www.w3.org/2000/svg'%3e%3cline x1='0.5' y1='0' x2='0.5' y2='10' stroke='%231f7dff' stroke-width='1' stroke-dasharray='2%2c4' stroke-linecap='square'/%3e%3c/svg%3e\");\r\n  }\r\n\r\n  [data-string-offset-connector=\"exit\"] {\r\n    color: var(--string-dg-color-red);\r\n  }\r\n\r\n  [data-string-offset-connector=\"exit\"]::before {\r\n    background-image: url(\"data:image/svg+xml,%3csvg width='1' height='10' viewBox='0 0 1 10' xmlns='http://www.w3.org/2000/svg'%3e%3cline x1='0.5' y1='0' x2='0.5' y2='10' stroke='%23e63f3f' stroke-width='1' stroke-dasharray='2%2c4' stroke-linecap='square'/%3e%3c/svg%3e\");\r\n  }\r\n\r\n  [data-string-offset-edge-marker] {\n    position: absolute;\n    top: 0;\n    left: 0;\n    display: inline-flex;\r\n    align-items: center;\r\n    gap: 4px;\r\n    pointer-events: auto;\r\n    z-index: 1;\r\n    padding: 2px 4px;\r\n    border-radius: 0;\r\n    font-size: 8px;\r\n    line-height: 1;\r\n    font-weight: 500;\r\n    letter-spacing: 0.04em;\r\n    text-transform: uppercase;\r\n    white-space: nowrap;\r\n    will-change: transform;\r\n    box-shadow: none;\r\n    cursor: col-resize;\r\n    user-select: none;\r\n    touch-action: none;\n\n  }\n\n  [data-string-offset-edge-marker][data-pointer=\"coarse\"]::before {\n    content: \"\";\n    position: absolute;\n    inset: -10px;\n  }\n\r\n  [data-string-offset-edge-marker-label] {\r\n    display: inline-flex;\r\n    align-items: center;\r\n    justify-content: center;\r\n    min-height: 8px;\r\n  }\r\n\r\n  [data-string-offset-edge-marker]::after {\r\n    content: \"\";\r\n    display: inline-block;\r\n    width: 9px;\r\n    height: 5px;\r\n    border: 1px solid white;\r\n    border-radius: 2px;\r\n  }\r\n\r\n  [data-string-offset-edge-marker][data-viewport-anchor=\"top\"]::after {\r\n    border-top-width: 3px;\r\n  }\r\n  [data-string-offset-edge-marker][data-viewport-anchor=\"bottom\"]::after {\r\n    border-bottom-width: 3px;\r\n  }\r\n\r\n  [data-string-offset-edge-marker][data-visible=\"false\"] {\r\n    display: none;\r\n  }\r\n\r\n  [data-string-offset-edge-marker=\"enter\"] {\r\n    color: var(--string-dg-color-white);\r\n    background: var(--string-dg-color-blue);\r\n    padding-right: 10px;\r\n    clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 100%, 0 100%);\r\n  }\r\n\r\n  [data-string-offset-edge-marker=\"enter\"][data-flip-y=\"true\"] {\r\n    clip-path: polygon(0 0, 100% 0, calc(100% - 10px) 100%, 0 100%);\r\n  }\r\n\r\n  [data-string-offset-edge-marker=\"exit\"] {\r\n    color: var(--string-dg-color-white);\r\n    background: var(--string-dg-color-red);\r\n    padding-left: 10px;\r\n    clip-path: polygon(0 0, 100% 0, 100% 100%, 10px 100%);\r\n  }\r\n\r\n  [data-string-offset-edge-marker=\"exit\"][data-flip-y=\"true\"] {\n    clip-path: polygon(10px 0, 100% 0, 100% 100%, 0 100%);\n  }\n\n  [data-string-offset-edge-marker][data-compact=\"true\"] {\n    gap: 3px;\n    padding-top: 1px;\n    padding-bottom: 1px;\n    font-size: 7px;\n  }\n\n  [data-string-offset-edge-marker][data-compact=\"true\"]::after {\n    width: 7px;\n    height: 4px;\n  }\n\n  [data-string-offset-edge-marker=\"enter\"][data-compact=\"true\"] {\n    padding-right: 7px;\n    clip-path: polygon(0 0, calc(100% - 7px) 0, 100% 100%, 0 100%);\n  }\n\n  [data-string-offset-edge-marker=\"enter\"][data-compact=\"true\"][data-flip-y=\"true\"] {\n    clip-path: polygon(0 0, 100% 0, calc(100% - 7px) 100%, 0 100%);\n  }\n\n  [data-string-offset-edge-marker=\"exit\"][data-compact=\"true\"] {\n    padding-left: 7px;\n    clip-path: polygon(0 0, 100% 0, 100% 100%, 7px 100%);\n  }\n\n  [data-string-offset-edge-marker=\"exit\"][data-compact=\"true\"][data-flip-y=\"true\"] {\n    clip-path: polygon(7px 0, 100% 0, 100% 100%, 0 100%);\n  }\n`;\n","import { StringObject } from \"../../../objects/StringObject\";\r\nimport { styleTxn } from \"../../../utils/style-txn\";\r\nimport {\r\n  StringDevBadgeDescriptor,\r\n  StringDevBadgeEntry,\r\n  StringDevBadgeMeasurement,\r\n  StringDevBadgeOverlayModule,\r\n  StringDevManagedBadge,\r\n} from \"../core/StringDevBadgeOverlayModule\";\r\nimport {\r\n  OverlayBaseMetrics,\r\n  StringDevOverlayBadgeState,\r\n  resolveOverlayAnchor,\r\n} from \"../core/StringDevOverlayModule\";\r\nimport { resolveDevtoolsIcon } from \"../core/StringDevIconRegistry\";\r\nimport { StringDevPersistedState } from \"../core/StringDevPersistedState\";\r\nimport { startPointerDrag } from \"../core/startPointerDrag\";\r\nimport { getStringDevViewportPolicy } from \"../core/StringDevViewportPolicy\";\r\nimport { StringDevtoolSubBadge } from \"../../../models/devtools/StringDevtool\";\r\nimport { INVIEW_CSS } from \"./StringDevInview.css\";\r\n\r\nconst ENTER_MARKER_SHIFT_X = 1;\r\nconst MARKER_VIEWPORT_EDGE_GAP = 4;\r\nconst MARKER_VIEWPORT_OVERFLOW_GUARD = 4;\r\nconst MARKER_FALLBACK_WIDTH = 64;\r\nconst MARKER_FALLBACK_HEIGHT = 16;\r\nconst MARKER_CONNECTOR_WIDTH = 14;\r\n\r\ntype MarkerKind = \"enter\" | \"exit\";\r\n\r\ninterface MarkerOffset {\r\n  xPercent: number;\r\n}\r\n\r\ninterface InviewExtra {\r\n  outline: HTMLDivElement;\r\n  enterConnector: HTMLDivElement;\r\n  exitConnector: HTMLDivElement;\r\n  enterMarker: HTMLDivElement;\r\n  exitMarker: HTMLDivElement;\r\n  enterMarkerLabel: HTMLSpanElement;\r\n  exitMarkerLabel: HTMLSpanElement;\r\n}\r\n\r\ninterface InviewMeasurement extends StringDevBadgeMeasurement {\r\n  overlayVisible: boolean;\r\n  badgeVisible: boolean;\r\n  markersVisible: boolean;\r\n  inview: boolean;\r\n  outlineDocX: number;\r\n  outlineDocY: number;\r\n  outlineWidth: number;\r\n  outlineHeight: number;\r\n  enterConnectorDocX: number;\r\n  enterConnectorDocY: number;\r\n  enterConnectorWidth: number;\r\n  enterConnectorHeight: number;\r\n  exitConnectorDocX: number;\r\n  exitConnectorDocY: number;\r\n  exitConnectorWidth: number;\r\n  exitConnectorHeight: number;\r\n  enterMarkerDocX: number;\r\n  enterMarkerDocY: number;\r\n  enterMarkerFlippedY: boolean;\r\n  exitMarkerDocX: number;\r\n  exitMarkerDocY: number;\r\n  exitMarkerFlippedY: boolean;\r\n}\r\n\r\ninterface LiveStickyGeometry {\r\n  contentX: number;\r\n  contentY: number;\r\n  width: number;\r\n  height: number;\r\n}\r\n\r\nfunction fixedTranslate(x: number, y: number): string {\r\n  return `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`;\r\n}\r\n\r\nfunction clampPercent(value: number): number {\r\n  return Math.min(100, Math.max(0, value));\r\n}\r\n\r\nfunction clamp(value: number, min: number, max: number): number {\r\n  return Math.min(max, Math.max(min, value));\r\n}\r\n\r\nconst EMPTY_GEOMETRY = {\r\n  outlineDocX: 0,\r\n  outlineDocY: 0,\r\n  outlineWidth: 0,\r\n  outlineHeight: 0,\r\n  enterConnectorDocX: 0,\r\n  enterConnectorDocY: 0,\r\n  enterConnectorWidth: 0,\r\n  enterConnectorHeight: 0,\r\n  exitConnectorDocX: 0,\r\n  exitConnectorDocY: 0,\r\n  exitConnectorWidth: 0,\r\n  exitConnectorHeight: 0,\r\n  enterMarkerDocX: 0,\r\n  enterMarkerDocY: 0,\r\n  enterMarkerFlippedY: false,\r\n  exitMarkerDocX: 0,\r\n  exitMarkerDocY: 0,\r\n  exitMarkerFlippedY: false,\r\n} as const;\r\n\r\nexport class StringDevInview extends StringDevBadgeOverlayModule<InviewExtra, InviewMeasurement> {\r\n  static override devtool = {\r\n    id: \"inview\",\r\n    label: \"Inview\",\r\n    icon: \"intersection\",\r\n    order: 25,\r\n    group: 2,\r\n    hotkey: { key: \"I\", shiftKey: true },\r\n    styles: INVIEW_CSS,\r\n    overlay: {\r\n      layerName: \"devtools-inview\",\r\n      zIndex: 10011,\r\n      layerAttribute: \"data-string-inview-layer\",\r\n      overlayId: \"inview\",\r\n      defaultEnabled: true,\r\n    },\r\n    connects: { global: true },\r\n  };\r\n\r\n  protected override get overlayBadgeCount(): number {\r\n    return 2;\r\n  }\r\n\r\n  protected override getDevtoolSubBadges(): StringDevtoolSubBadge[] {\r\n    return [\r\n      {\r\n        id: \"hide-all-offsets\",\r\n        icon: \"nooffset\",\r\n        label: \"Hide all inview offsets\",\r\n        selectorAttribute: \"data-string-inview-hide-all-offsets\",\r\n        onClick: () => this.disableAllOffsets(),\r\n      },\r\n    ];\r\n  }\r\n\r\n  private entryEnabled: Map<string, boolean> = new Map();\r\n  private markerSizeCache = new WeakMap<HTMLElement, { width: number; height: number }>();\r\n\r\n  private readonly disabledStore = new StringDevPersistedState<string[]>({\r\n    moduleId: \"inview\",\r\n    name: \"disabled-targets\",\r\n    default: [],\r\n    validate: (raw) =>\r\n      Array.isArray(raw) ? raw.filter((v): v is string => typeof v === \"string\") : null,\r\n    legacyKeys: [\"string-devtools:inview\"],\r\n  });\r\n\r\n  private readonly markerStore = new StringDevPersistedState<\r\n    Record<string, Partial<Record<MarkerKind, MarkerOffset>>>\r\n  >({\r\n    moduleId: \"inview\",\r\n    name: \"marker-offsets\",\r\n    default: {},\r\n    validate: (raw) => {\r\n      if (!raw || typeof raw !== \"object\") return null;\r\n      const out: Record<string, Partial<Record<MarkerKind, MarkerOffset>>> = {};\r\n      for (const [targetId, value] of Object.entries(raw as Record<string, unknown>)) {\r\n        if (!value || typeof value !== \"object\") continue;\r\n        const next: Partial<Record<MarkerKind, MarkerOffset>> = {};\r\n        const v = value as { enter?: unknown; exit?: unknown };\r\n        if (v.enter && typeof (v.enter as MarkerOffset).xPercent === \"number\") {\r\n          next.enter = { xPercent: (v.enter as MarkerOffset).xPercent };\r\n        }\r\n        if (v.exit && typeof (v.exit as MarkerOffset).xPercent === \"number\") {\r\n          next.exit = { xPercent: (v.exit as MarkerOffset).xPercent };\r\n        }\r\n        if (next.enter || next.exit) out[targetId] = next;\r\n      }\r\n      return out;\r\n    },\r\n    legacyKeys: [\"string-devtools:inview-marker-offsets\"],\r\n  });\r\n\r\n  private disabledTargetIds: Set<string> = new Set(this.disabledStore.read());\r\n  private markerOffsets: Map<string, Partial<Record<MarkerKind, MarkerOffset>>> = new Map(\r\n    Object.entries(this.markerStore.read()),\r\n  );\r\n  private stableCoarseViewportWidth = 0;\r\n  private stableCoarseViewportHeight = 0;\r\n\r\n  protected getBadgeDescriptors(\r\n    _object: StringObject,\r\n    _targetId: string,\r\n    _depth: number,\r\n  ): Array<StringDevBadgeDescriptor> {\r\n    return [\r\n      {\r\n        id: \"inview-toggle\",\r\n        slot: \"top-left\",\r\n        group: \"main\",\r\n        selectorAttribute: \"data-string-inview-toggle\",\r\n      },\r\n      {\r\n        id: \"offsets\",\r\n        slot: \"top-left\",\r\n        group: \"main\",\r\n        selectorAttribute: \"data-string-offsets-badge\",\r\n        attributes: {\r\n          \"data-string-inview-tool\": \"offsets\",\r\n        },\r\n      },\r\n    ];\r\n  }\r\n\r\n  protected createBadgeExtra(\r\n    object: StringObject,\r\n    _badge: HTMLButtonElement,\r\n    targetId: string,\r\n    _depth: number,\r\n  ): InviewExtra {\r\n    const savedEnabled = !this.disabledTargetIds.has(targetId);\r\n    this.entryEnabled.set(object.id, savedEnabled);\r\n\r\n    const outline = document.createElement(\"div\");\r\n    outline.setAttribute(\"data-string-offset-outline\", \"\");\r\n    outline.setAttribute(\"data-target-id\", targetId);\r\n    outline.setAttribute(\"data-visible\", \"false\");\r\n\r\n    const enterConnector = document.createElement(\"div\");\r\n    enterConnector.setAttribute(\"data-string-offset-connector\", \"enter\");\r\n    enterConnector.setAttribute(\"data-stdg\", \"\");\r\n    enterConnector.setAttribute(\"data-target-id\", targetId);\r\n    enterConnector.setAttribute(\"data-visible\", \"false\");\r\n\r\n    const exitConnector = document.createElement(\"div\");\r\n    exitConnector.setAttribute(\"data-string-offset-connector\", \"exit\");\r\n    exitConnector.setAttribute(\"data-stdg\", \"\");\r\n    exitConnector.setAttribute(\"data-target-id\", targetId);\r\n    exitConnector.setAttribute(\"data-visible\", \"false\");\r\n\r\n    const enterMarker = document.createElement(\"div\");\r\n    enterMarker.setAttribute(\"data-string-offset-edge-marker\", \"enter\");\r\n    enterMarker.setAttribute(\"data-stdg\", \"\");\r\n    enterMarker.setAttribute(\"data-target-id\", targetId);\r\n    enterMarker.setAttribute(\"data-visible\", \"false\");\r\n    const enterMarkerLabel = document.createElement(\"span\");\r\n    enterMarkerLabel.setAttribute(\"data-string-offset-edge-marker-label\", \"\");\r\n    enterMarker.append(enterMarkerLabel);\r\n\r\n    const exitMarker = document.createElement(\"div\");\r\n    exitMarker.setAttribute(\"data-string-offset-edge-marker\", \"exit\");\r\n    exitMarker.setAttribute(\"data-stdg\", \"\");\r\n    exitMarker.setAttribute(\"data-target-id\", targetId);\r\n    exitMarker.setAttribute(\"data-visible\", \"false\");\r\n    const exitMarkerLabel = document.createElement(\"span\");\r\n    exitMarkerLabel.setAttribute(\"data-string-offset-edge-marker-label\", \"\");\r\n    exitMarker.append(exitMarkerLabel);\r\n\r\n    const world = this.viewportLayer.getWorldElement(this.getWorldHost());\r\n    world.appendChild(outline);\r\n    world.appendChild(enterConnector);\r\n    world.appendChild(exitConnector);\r\n    world.appendChild(enterMarker);\r\n    world.appendChild(exitMarker);\r\n    const extra = {\r\n      outline,\r\n      enterConnector,\r\n      exitConnector,\r\n      enterMarker,\r\n      exitMarker,\r\n      enterMarkerLabel,\r\n      exitMarkerLabel,\r\n    };\r\n    this.syncCompactModeForExtra(extra);\r\n    return extra;\r\n  }\r\n\r\n  protected destroyBadgeExtra(entry: StringDevBadgeEntry<InviewExtra>): void {\r\n    entry.extra.outline.remove();\r\n    entry.extra.enterConnector.remove();\r\n    entry.extra.exitConnector.remove();\r\n    entry.extra.enterMarker.remove();\r\n    entry.extra.exitMarker.remove();\r\n    this.entryEnabled.delete(entry.object.id);\r\n  }\r\n\r\n  protected bindBadge(entry: StringDevBadgeEntry<InviewExtra>): Array<() => void> {\r\n    const onInviewChange = () => {\r\n      this.renderBadge(entry);\r\n      this.scheduleSingleSync(entry);\r\n    };\r\n\r\n    const enterCleanup = this.bindMarkerDrag(entry, \"enter\", [\r\n      entry.extra.enterMarker,\r\n      entry.extra.enterConnector,\r\n    ]);\r\n    const exitCleanup = this.bindMarkerDrag(entry, \"exit\", [\r\n      entry.extra.exitMarker,\r\n      entry.extra.exitConnector,\r\n    ]);\r\n\r\n    this.events.on(entry.object.getScopedEventName(\"object:inview\"), onInviewChange);\r\n    return [\r\n      enterCleanup,\r\n      exitCleanup,\r\n      () => this.events.off(entry.object.getScopedEventName(\"object:inview\"), onInviewChange),\r\n    ];\r\n  }\r\n\r\n  protected measureEntry(\r\n    entry: StringDevBadgeEntry<InviewExtra>,\r\n    metrics: OverlayBaseMetrics,\r\n  ): InviewMeasurement {\r\n    const badges = super.measureEntry(entry, metrics).badges;\r\n    const object = entry.object;\r\n    const entryEnabled = this.isEntryEnabled(object.id);\r\n    const stickyGeometry = metrics.visible\r\n      ? null\r\n      : this.resolveLiveStickyGeometry(object.htmlElement);\r\n    const geometryVisible = metrics.visible || stickyGeometry != null;\r\n\r\n    // Resolve element geometry: from live metrics if in viewport, else from stored properties.\r\n    const contentX = stickyGeometry\r\n      ? stickyGeometry.contentX\r\n      : metrics.visible\r\n        ? metrics.contentX\r\n        : (object.getProperty<number>(\"layout-doc-left\") ?? 0);\r\n    const contentY = stickyGeometry\r\n      ? stickyGeometry.contentY\r\n      : metrics.visible\r\n        ? metrics.contentY\r\n        : this.getObjectDocY(object);\r\n    const width = stickyGeometry\r\n      ? stickyGeometry.width\r\n      : metrics.visible\r\n        ? metrics.width\r\n        : (object.getProperty<number>(\"layout-width\") ??\r\n          (object.getProperty<number>(\"half-width\") ?? 0) * 2);\r\n    const height = stickyGeometry\r\n      ? stickyGeometry.height\r\n      : metrics.visible\r\n        ? metrics.height\r\n        : (object.getProperty<number>(\"layout-height\") ??\r\n          (object.getProperty<number>(\"half-height\") ?? 0) * 2);\r\n\r\n    if (width <= 0 || height <= 0) {\r\n      return this.hiddenMeasurement(object, badges);\r\n    }\r\n\r\n    const scrollTop = this.getViewportScrollTop();\r\n    const viewportHeight = this.getStableViewportHeight();\r\n\r\n    const startViewport = object.getProperty<string>(\"enter-vp\") ?? \"bottom\";\r\n    const endViewport = object.getProperty<string>(\"exit-vp\") ?? \"top\";\r\n    const startElement = object.getProperty<string>(\"enter-el\") ?? \"top\";\r\n    const endElement = object.getProperty<string>(\"exit-el\") ?? \"bottom\";\r\n    const inviewStartPosition = object.getProperty<number>(\"inview-start-position\");\r\n    const inviewEndPosition = object.getProperty<number>(\"inview-end-position\");\r\n\r\n    const topAnchor = startElement === \"bottom\" ? contentY + height : contentY;\r\n    const bottomAnchor = endElement === \"top\" ? contentY : contentY + height;\r\n    const startVpOffset = resolveOverlayAnchor(startViewport) === \"end\" ? viewportHeight : 0;\r\n    const endVpOffset = resolveOverlayAnchor(endViewport) === \"end\" ? viewportHeight : 0;\r\n    const enterTrigger =\r\n      inviewStartPosition != null ? inviewStartPosition + startVpOffset : topAnchor;\r\n    const exitTrigger = inviewEndPosition != null ? inviewEndPosition + endVpOffset : bottomAnchor;\r\n\r\n    const enterMarkerSize = this.measureMarkerSize(entry.extra.enterMarker);\r\n    const exitMarkerSize = this.measureMarkerSize(entry.extra.exitMarker);\r\n    const enterMarkerWidth = enterMarkerSize.width;\r\n    const enterMarkerHeight = enterMarkerSize.height;\r\n    const exitMarkerWidth = exitMarkerSize.width;\r\n    const exitMarkerHeight = exitMarkerSize.height;\r\n    const enterMarkerOverride = this.getMarkerOffset(entry.targetId, \"enter\");\r\n    const exitMarkerOverride = this.getMarkerOffset(entry.targetId, \"exit\");\r\n    const enterAnchorXPercent = this.clampMarkerPercentInViewport(\r\n      contentX,\r\n      width,\r\n      enterMarkerOverride?.xPercent ?? 100,\r\n      \"enter\",\r\n      enterMarkerWidth,\r\n    );\r\n    const exitAnchorXPercent = this.clampMarkerPercentInViewport(\r\n      contentX,\r\n      width,\r\n      exitMarkerOverride?.xPercent ?? 0,\r\n      \"exit\",\r\n      exitMarkerWidth,\r\n    );\r\n    const enterAnchorDocX = contentX + width * (enterAnchorXPercent / 100);\r\n    const exitAnchorDocX = contentX + width * (exitAnchorXPercent / 100);\r\n    const enterConnectorDocX = enterAnchorDocX + ENTER_MARKER_SHIFT_X;\r\n    const enterConnectorDocY = Math.min(topAnchor, enterTrigger);\r\n    const enterConnectorWidth = MARKER_CONNECTOR_WIDTH;\r\n    const enterConnectorHeight = Math.abs(enterTrigger - topAnchor);\r\n    const exitConnectorDocX = exitAnchorDocX;\r\n    const exitConnectorDocY = Math.min(bottomAnchor, exitTrigger);\r\n    const exitConnectorWidth = MARKER_CONNECTOR_WIDTH;\r\n    const exitConnectorHeight = Math.abs(exitTrigger - bottomAnchor);\r\n    const enterMarkerDocX = enterAnchorDocX + ENTER_MARKER_SHIFT_X;\r\n    const exitMarkerDocX = exitAnchorDocX;\r\n    const documentBottom =\r\n      this.data.viewport.contentHeight || this.data.viewport.windowHeight || window.innerHeight;\r\n    const enterMarkerPastTop = enterTrigger - enterMarkerHeight < 0;\r\n    const exitMarkerPastTop = exitTrigger < 0;\r\n    const enterMarkerPastBottom = enterTrigger > documentBottom;\r\n    const exitMarkerPastBottom = exitTrigger + exitMarkerHeight > documentBottom;\r\n    const enterMarkerFlippedY = enterMarkerPastTop || enterMarkerPastBottom;\r\n    const exitMarkerFlippedY = exitMarkerPastTop || exitMarkerPastBottom;\r\n    const enterMarkerDocY = enterMarkerPastBottom\r\n      ? documentBottom\r\n      : enterTrigger + (enterMarkerPastTop ? enterMarkerHeight : 0);\r\n    const exitMarkerDocY = exitMarkerPastBottom\r\n      ? documentBottom - exitMarkerHeight\r\n      : exitTrigger + (exitMarkerPastTop ? exitMarkerHeight : 0);\r\n\r\n    // Each trigger line is visible if it falls within (or just above) the viewport.\r\n    const enterInView =\r\n      enterTrigger - scrollTop >= -enterMarkerHeight && enterTrigger - scrollTop <= viewportHeight;\r\n    const exitInView =\r\n      exitTrigger - scrollTop >= -exitMarkerHeight && exitTrigger - scrollTop <= viewportHeight;\r\n    const markersVisible = this.enabled && entryEnabled && (enterInView || exitInView);\r\n\r\n    // Nothing to show at all.\r\n    if (!geometryVisible && !markersVisible) {\r\n      return this.hiddenMeasurement(object, badges);\r\n    }\r\n\r\n    return {\r\n      visible: geometryVisible,\r\n      badges,\r\n      overlayVisible: this.enabled && entryEnabled,\r\n      badgeVisible: this.enabled,\r\n      markersVisible,\r\n      inview: object.getProperty<boolean>(\"is-inview\") === true,\r\n      outlineDocX: contentX,\r\n      outlineDocY: contentY,\r\n      outlineWidth: width,\r\n      outlineHeight: height,\r\n      enterConnectorDocX,\r\n      enterConnectorDocY,\r\n      enterConnectorWidth,\r\n      enterConnectorHeight,\r\n      exitConnectorDocX,\r\n      exitConnectorDocY,\r\n      exitConnectorWidth,\r\n      exitConnectorHeight,\r\n      enterMarkerDocX,\r\n      enterMarkerDocY,\r\n      enterMarkerFlippedY,\r\n      exitMarkerDocX,\r\n      exitMarkerDocY,\r\n      exitMarkerFlippedY,\r\n    };\r\n  }\r\n\r\n  protected afterBadgeMeasurement(\r\n    entry: StringDevBadgeEntry<InviewExtra>,\r\n    measurement: InviewMeasurement | undefined,\r\n  ): void {\r\n    this.syncCompactMode(entry);\r\n    const object = entry.object;\r\n    const startViewport = object.getProperty<string>(\"enter-vp\") ?? \"bottom\";\r\n    const endViewport = object.getProperty<string>(\"exit-vp\") ?? \"top\";\r\n    this.syncMarkerContent(entry, \"enter\", this.getViewportMarkerLabel(startViewport));\r\n    this.syncMarkerContent(entry, \"exit\", this.getViewportMarkerLabel(endViewport));\r\n    const { outline, enterConnector, exitConnector, enterMarker, exitMarker } = entry.extra;\r\n\r\n    const outlineVisible = !!measurement?.visible && !!measurement.overlayVisible;\r\n    const markersVisible = !!measurement?.markersVisible && !!measurement.overlayVisible;\r\n\r\n    outline.setAttribute(\"data-visible\", outlineVisible ? \"true\" : \"false\");\r\n    const m = measurement;\r\n    if (m && outlineVisible) {\r\n      outline.setAttribute(\"data-inview\", m.inview ? \"true\" : \"false\");\r\n      styleTxn.setProps(outline, {\r\n        transform: fixedTranslate(m.outlineDocX, m.outlineDocY),\r\n        width: `${Math.max(0, m.outlineWidth)}px`,\r\n        height: `${Math.max(0, m.outlineHeight)}px`,\r\n      });\r\n    }\r\n\r\n    if (!markersVisible) {\r\n      for (const part of [enterConnector, exitConnector, enterMarker, exitMarker]) {\r\n        part.setAttribute(\"data-visible\", \"false\");\r\n      }\r\n      return;\r\n    }\r\n    if (!m) return;\r\n\r\n    const inviewAttr = m.inview ? \"true\" : \"false\";\r\n    for (const part of [enterConnector, exitConnector, enterMarker, exitMarker]) {\r\n      part.setAttribute(\"data-visible\", \"true\");\r\n      part.setAttribute(\"data-inview\", inviewAttr);\r\n    }\r\n    enterMarker.setAttribute(\"data-flip-y\", m.enterMarkerFlippedY ? \"true\" : \"false\");\r\n    exitMarker.setAttribute(\"data-flip-y\", m.exitMarkerFlippedY ? \"true\" : \"false\");\r\n    styleTxn.setProps(enterConnector, {\r\n      transform: fixedTranslate(\r\n        m.enterConnectorDocX - m.enterConnectorWidth / 2,\r\n        m.enterConnectorDocY,\r\n      ),\r\n      width: `${Math.max(0, m.enterConnectorWidth)}px`,\r\n      height: `${Math.max(0, m.enterConnectorHeight)}px`,\r\n    });\r\n    styleTxn.setProps(exitConnector, {\r\n      transform: fixedTranslate(\r\n        m.exitConnectorDocX - m.exitConnectorWidth / 2,\r\n        m.exitConnectorDocY,\r\n      ),\r\n      width: `${Math.max(0, m.exitConnectorWidth)}px`,\r\n      height: `${Math.max(0, m.exitConnectorHeight)}px`,\r\n    });\r\n    styleTxn.setProps(enterMarker, {\r\n      transform: `${fixedTranslate(m.enterMarkerDocX, m.enterMarkerDocY)} translate(-100%, -100%)`,\r\n    });\r\n    styleTxn.setProps(exitMarker, {\r\n      transform: fixedTranslate(m.exitMarkerDocX, m.exitMarkerDocY),\r\n    });\r\n  }\r\n\r\n  protected onBadgeClick(\r\n    entry: StringDevBadgeEntry<InviewExtra>,\r\n    _event: MouseEvent,\r\n    badge: StringDevManagedBadge,\r\n  ): void {\r\n    if (badge.id === \"inview-toggle\") {\r\n      this.toggleInview(entry.object);\r\n      this.renderBadge(entry);\r\n      this.scheduleSingleSync(entry);\r\n      return;\r\n    }\r\n\r\n    if (badge.id === \"offsets\") {\r\n      this.setEntryEnabled(entry.object.id, !this.isEntryEnabled(entry.object.id));\r\n      this.renderBadge(entry);\r\n      this.scheduleFullSync();\r\n    }\r\n  }\r\n\r\n  protected getBadgeState(\r\n    entry: StringDevBadgeEntry<InviewExtra>,\r\n    badge?: StringDevManagedBadge,\r\n  ): StringDevOverlayBadgeState {\r\n    if (badge?.id === \"offsets\") {\r\n      const isActive = this.isEntryEnabled(entry.object.id);\r\n      return {\r\n        active: isActive,\r\n        title: isActive ? \"Hide offsets for this element\" : \"Show offsets for this element\",\r\n        html: resolveDevtoolsIcon(16, \"offset\"),\r\n      };\r\n    }\r\n\r\n    const state = this.getInviewBadgeState(entry.object);\r\n    return {\r\n      active: state.active,\r\n      title: state.title,\r\n      html: state.html,\r\n      attributes: {\r\n        \"data-inview\": state.inview,\r\n        \"data-blocked\": state.blocked,\r\n      },\r\n    };\r\n  }\r\n\r\n  private hiddenMeasurement(\r\n    object: StringObject,\r\n    badges: StringDevBadgeMeasurement[\"badges\"],\r\n  ): InviewMeasurement {\r\n    const hiddenBadges: StringDevBadgeMeasurement[\"badges\"] = {};\r\n    for (const [id, measurement] of Object.entries(badges)) {\r\n      hiddenBadges[id] = { ...measurement, visible: false };\r\n    }\r\n\r\n    return {\r\n      visible: false,\r\n      badges: hiddenBadges,\r\n      overlayVisible: this.enabled && this.isEntryEnabled(object.id),\r\n      badgeVisible: this.enabled,\r\n      markersVisible: false,\r\n      inview: object.getProperty<boolean>(\"is-inview\") === true,\r\n      ...EMPTY_GEOMETRY,\r\n    };\r\n  }\r\n\r\n  private getInviewBadgeState(object: StringObject): {\r\n    active: boolean;\r\n    blocked: boolean;\r\n    inview: boolean;\r\n    title: string;\r\n    html: string;\r\n  } {\r\n    const isInView = object.getProperty<boolean>(\"is-inview\") === true;\r\n    const isBlocked = object.isInviewAutoBlocked();\r\n\r\n    return {\r\n      active: this.isInviewBadgeActive(object),\r\n      blocked: isBlocked,\r\n      inview: isInView,\r\n      title: isBlocked ? \"Enable automatic -inview\" : \"Disable automatic -inview\",\r\n      html: resolveDevtoolsIcon(16, \"eye\"),\r\n    };\r\n  }\r\n\r\n  private toggleInview(object: StringObject): void {\r\n    if (this.isInviewBadgeActive(object)) {\r\n      object.setInviewManualActive(false);\r\n      object.setInviewAutoBlocked(true);\r\n      object.htmlElement.classList.remove(\"-inview\");\r\n      return;\r\n    }\r\n\r\n    object.setInviewAutoBlocked(false);\r\n    object.setInviewManualActive(true);\r\n    object.syncInviewClass();\r\n  }\r\n\r\n  private isInviewBadgeActive(object: StringObject): boolean {\r\n    if (object.isInviewAutoBlocked()) return false;\r\n    if (object.isInviewManualActive()) return true;\r\n    if (object.getProperty<boolean>(\"is-inview\") === true) return true;\r\n    if (object.getProperty<boolean>(\"repeat\") === true) return false;\r\n    return object.htmlElement.classList.contains(\"-inview\");\r\n  }\r\n\r\n  private isEntryEnabled(objectId: string): boolean {\r\n    return this.entryEnabled.get(objectId) !== false;\r\n  }\r\n\r\n  private setEntryEnabled(objectId: string, enabled: boolean): void {\r\n    this.entryEnabled.set(objectId, enabled);\r\n    const entry = this.entries.get(objectId);\r\n    if (entry) {\r\n      const targetId = entry.targetId;\r\n      if (enabled) {\r\n        this.disabledTargetIds.delete(targetId);\r\n      } else {\r\n        this.disabledTargetIds.add(targetId);\r\n      }\r\n      this.disabledStore.write([...this.disabledTargetIds]);\r\n    }\r\n    if (!this.enabled) return;\r\n    if (entry) this.scheduleSingleSync(entry);\r\n    else this.scheduleSync();\r\n  }\r\n\r\n  private disableAllOffsets(): void {\r\n    let changed = false;\r\n    for (const entry of this.entries.values()) {\r\n      if (this.entryEnabled.get(entry.object.id) === false) continue;\r\n      this.entryEnabled.set(entry.object.id, false);\r\n      this.disabledTargetIds.add(entry.targetId);\r\n      this.renderBadge(entry);\r\n      changed = true;\r\n    }\r\n\r\n    if (!changed) return;\r\n    this.disabledStore.write([...this.disabledTargetIds]);\r\n    if (this.enabled) this.scheduleSync();\r\n  }\r\n\r\n  private bindMarkerDrag(\r\n    entry: StringDevBadgeEntry<InviewExtra>,\r\n    kind: MarkerKind,\r\n    dragHandles: HTMLDivElement[],\r\n  ): () => void {\r\n    const onPointerDown = (event: PointerEvent) => {\r\n      event.preventDefault();\r\n      event.stopPropagation();\r\n\r\n      const element = entry.object.htmlElement;\r\n      if (!element?.isConnected) return;\r\n\r\n      const elementRect = element.getBoundingClientRect();\r\n      if (elementRect.width <= 0) return;\r\n\r\n      const markerWidth =\r\n        kind === \"enter\"\r\n          ? entry.extra.enterMarker.getBoundingClientRect().width\r\n          : entry.extra.exitMarker.getBoundingClientRect().width;\r\n      const currentOffset = this.getMarkerOffset(entry.targetId, kind);\r\n      const currentXPercent = this.clampMarkerPercentInViewport(\r\n        elementRect.left + this.getViewportScrollLeft(),\r\n        elementRect.width,\r\n        currentOffset?.xPercent ?? (kind === \"enter\" ? 100 : 0),\r\n        kind,\r\n        markerWidth,\r\n      );\r\n      const anchorClientX = elementRect.left + elementRect.width * (currentXPercent / 100);\r\n      const pointerOffsetX = event.clientX - anchorClientX;\r\n\r\n      const badgeWorld = this.badgeLayer.getWorldElement(this.getWorldHost());\r\n      const activeBadges = Array.from(\r\n        badgeWorld.querySelectorAll<HTMLElement>(\r\n          `[data-stdg-badge][data-target-id=\"${entry.targetId}\"]`,\r\n        ),\r\n      );\r\n      for (const el of activeBadges) {\r\n        el.setAttribute(\"data-dragging\", \"\");\r\n      }\r\n      badgeWorld.setAttribute(\"data-dragging-active\", \"\");\r\n\r\n      startPointerDrag(event, {\r\n        onMove: (moveEvent) => {\r\n          const liveElementRect = element.getBoundingClientRect();\r\n          if (liveElementRect.width <= 0) return;\r\n          const nextAnchorClientX = moveEvent.clientX - pointerOffsetX;\r\n          const nextXPercent = this.clampMarkerPercentInClientViewport(\r\n            liveElementRect,\r\n            nextAnchorClientX,\r\n            kind,\r\n            markerWidth,\r\n          );\r\n          this.setMarkerOffset(entry.targetId, kind, { xPercent: nextXPercent });\r\n          this.scheduleSingleSync(entry);\r\n        },\r\n        onEnd: () => {\r\n          for (const el of activeBadges) {\r\n            el.removeAttribute(\"data-dragging\");\r\n          }\r\n          badgeWorld.removeAttribute(\"data-dragging-active\");\r\n        },\r\n      });\r\n    };\r\n\r\n    for (const handle of dragHandles) {\r\n      handle.addEventListener(\"pointerdown\", onPointerDown);\r\n    }\r\n\r\n    return () => {\r\n      for (const handle of dragHandles) {\r\n        handle.removeEventListener(\"pointerdown\", onPointerDown);\r\n      }\r\n    };\r\n  }\r\n\r\n  private getMarkerOffset(targetId: string, kind: MarkerKind): MarkerOffset | null {\r\n    return this.markerOffsets.get(targetId)?.[kind] ?? null;\r\n  }\r\n\r\n  private setMarkerOffset(targetId: string, kind: MarkerKind, offset: MarkerOffset): void {\r\n    const existing = this.markerOffsets.get(targetId) ?? {};\r\n    existing[kind] = offset;\r\n    this.markerOffsets.set(targetId, existing);\r\n    this.markerStore.write(Object.fromEntries(this.markerOffsets.entries()));\r\n  }\r\n\r\n  private syncMarkerContent(\r\n    entry: StringDevBadgeEntry<InviewExtra>,\r\n    kind: MarkerKind,\r\n    viewportLabel: \"top\" | \"bottom\",\r\n  ): void {\r\n    const marker = kind === \"enter\" ? entry.extra.enterMarker : entry.extra.exitMarker;\r\n    const labelNode = kind === \"enter\" ? entry.extra.enterMarkerLabel : entry.extra.exitMarkerLabel;\r\n    const label = this.getOverlayTargetLabel(entry.object);\r\n\r\n    if (labelNode.textContent !== label) {\r\n      labelNode.textContent = label;\r\n    }\r\n    this.setAttributeIfChanged(marker, \"data-viewport-anchor\", viewportLabel);\r\n    const title = `${label} -> viewport ${viewportLabel}`;\r\n    if (marker.title !== title) {\r\n      marker.title = title;\r\n    }\r\n  }\r\n\r\n  private getViewportMarkerLabel(raw: string | null | undefined): \"top\" | \"bottom\" {\r\n    return resolveOverlayAnchor(raw) === \"end\" ? \"bottom\" : \"top\";\r\n  }\r\n\r\n  private measureMarkerSize(marker: HTMLElement): { width: number; height: number } {\r\n    const rect = marker.getBoundingClientRect();\r\n    if (rect.width > 0 && rect.height > 0) {\r\n      const size = { width: rect.width, height: rect.height };\r\n      this.markerSizeCache.set(marker, size);\r\n      return size;\r\n    }\r\n\r\n    return (\r\n      this.markerSizeCache.get(marker) ?? {\r\n        width: MARKER_FALLBACK_WIDTH,\r\n        height: MARKER_FALLBACK_HEIGHT,\r\n      }\r\n    );\r\n  }\r\n\r\n  private resolveLiveStickyGeometry(element: HTMLElement): LiveStickyGeometry | null {\r\n    if (!element?.isConnected) return null;\r\n    if (window.getComputedStyle(element).position !== \"sticky\") return null;\r\n\r\n    const rect = element.getBoundingClientRect();\r\n    const liveMetrics = this.resolveLiveElementMetrics(element, rect);\r\n    const width = liveMetrics.width;\r\n    const height = liveMetrics.height;\r\n\r\n    if (width <= 0 || height <= 0) return null;\r\n\r\n    const viewportWidth = this.data.viewport.windowWidth || window.innerWidth;\r\n    const viewportHeight = this.data.viewport.windowHeight || window.innerHeight;\r\n    const isVisible =\r\n      rect.bottom >= 0 &&\r\n      rect.top <= viewportHeight &&\r\n      rect.right >= 0 &&\r\n      rect.left <= viewportWidth;\r\n\r\n    if (!isVisible || liveMetrics.docLeft == null || liveMetrics.docTop == null) return null;\r\n\r\n    return {\r\n      contentX: liveMetrics.docLeft,\r\n      contentY: liveMetrics.docTop,\r\n      width,\r\n      height,\r\n    };\r\n  }\r\n\r\n  private clampMarkerPercentInViewport(\r\n    elementDocLeft: number,\r\n    elementWidth: number,\r\n    percent: number,\r\n    kind: MarkerKind,\r\n    markerWidth: number,\r\n  ): number {\r\n    if (elementWidth <= 0) {\r\n      return kind === \"enter\" ? 100 : 0;\r\n    }\r\n\r\n    const desiredAnchorDocX = elementDocLeft + elementWidth * (clampPercent(percent) / 100);\r\n    const scrollLeft = this.getViewportScrollLeft();\r\n    const viewportWidth = this.data.viewport.windowWidth || window.innerWidth;\r\n    const edgeInset = MARKER_VIEWPORT_EDGE_GAP + MARKER_VIEWPORT_OVERFLOW_GUARD;\r\n    const viewportMinX = scrollLeft + edgeInset;\r\n    const viewportMaxX = scrollLeft + viewportWidth - edgeInset;\r\n    const connectorHalfWidth = MARKER_CONNECTOR_WIDTH / 2;\r\n    const minAnchorDocX =\r\n      kind === \"enter\"\r\n        ? Math.max(\r\n            viewportMinX + markerWidth - ENTER_MARKER_SHIFT_X,\r\n            viewportMinX + connectorHalfWidth - ENTER_MARKER_SHIFT_X,\r\n          )\r\n        : viewportMinX + connectorHalfWidth;\r\n    const maxAnchorDocX =\r\n      kind === \"enter\"\r\n        ? viewportMaxX - connectorHalfWidth - ENTER_MARKER_SHIFT_X\r\n        : Math.min(viewportMaxX - markerWidth, viewportMaxX - connectorHalfWidth);\r\n    const allowedMin = Math.max(elementDocLeft, minAnchorDocX);\r\n    const allowedMax = Math.min(elementDocLeft + elementWidth, maxAnchorDocX);\r\n    const anchorDocX = clamp(desiredAnchorDocX, allowedMin, Math.max(allowedMin, allowedMax));\r\n    return clampPercent(((anchorDocX - elementDocLeft) / elementWidth) * 100);\r\n  }\r\n\r\n  private clampMarkerPercentInClientViewport(\r\n    elementRect: DOMRect,\r\n    anchorClientX: number,\r\n    kind: MarkerKind,\r\n    markerWidth: number,\r\n  ): number {\r\n    if (elementRect.width <= 0) {\r\n      return kind === \"enter\" ? 100 : 0;\r\n    }\r\n\r\n    const viewportWidth = this.data.viewport.windowWidth || window.innerWidth;\r\n    const edgeInset = MARKER_VIEWPORT_EDGE_GAP + MARKER_VIEWPORT_OVERFLOW_GUARD;\r\n    const connectorHalfWidth = MARKER_CONNECTOR_WIDTH / 2;\r\n    const minAnchorClientX =\r\n      kind === \"enter\"\r\n        ? Math.max(\r\n            edgeInset + markerWidth - ENTER_MARKER_SHIFT_X,\r\n            edgeInset + connectorHalfWidth - ENTER_MARKER_SHIFT_X,\r\n          )\r\n        : edgeInset + connectorHalfWidth;\r\n    const maxAnchorClientX =\r\n      kind === \"enter\"\r\n        ? viewportWidth - edgeInset - connectorHalfWidth - ENTER_MARKER_SHIFT_X\r\n        : Math.min(\r\n            viewportWidth - edgeInset - markerWidth,\r\n            viewportWidth - edgeInset - connectorHalfWidth,\r\n          );\r\n    const allowedMin = Math.max(elementRect.left, minAnchorClientX);\r\n    const allowedMax = Math.min(elementRect.right, maxAnchorClientX);\r\n    const clampedAnchorClientX = clamp(anchorClientX, allowedMin, Math.max(allowedMin, allowedMax));\r\n\r\n    return clampPercent(((clampedAnchorClientX - elementRect.left) / elementRect.width) * 100);\r\n  }\r\n\r\n  private syncCompactMode(entry: StringDevBadgeEntry<InviewExtra>): void {\r\n    this.syncCompactModeForExtra(entry.extra);\r\n  }\r\n\r\n  private syncCompactModeForExtra(extra: InviewExtra): void {\r\n    const viewportWidth = this.data.viewport.windowWidth || window.innerWidth;\r\n    const policy = getStringDevViewportPolicy(viewportWidth);\r\n    const compactValue = policy.compact ? \"true\" : \"false\";\r\n    const pointerValue = policy.coarsePointer ? \"coarse\" : \"fine\";\r\n\r\n    for (const element of [\r\n      extra.outline,\r\n      extra.enterConnector,\r\n      extra.exitConnector,\r\n      extra.enterMarker,\r\n      extra.exitMarker,\r\n    ]) {\r\n      this.setAttributeIfChanged(element, \"data-compact\", compactValue);\r\n      this.setAttributeIfChanged(element, \"data-pointer\", pointerValue);\r\n    }\r\n  }\r\n\r\n  private setAttributeIfChanged(element: HTMLElement, name: string, value: string): void {\r\n    if (element.getAttribute(name) !== value) {\r\n      element.setAttribute(name, value);\r\n    }\r\n  }\r\n\r\n  private getStableViewportHeight(): number {\r\n    const viewportWidth = this.data.viewport.windowWidth || window.innerWidth;\r\n    const viewportHeight = this.data.viewport.windowHeight || window.innerHeight;\r\n    const policy = getStringDevViewportPolicy(viewportWidth);\r\n\r\n    if (!policy.coarsePointer) {\r\n      this.stableCoarseViewportWidth = viewportWidth;\r\n      this.stableCoarseViewportHeight = viewportHeight;\r\n      return viewportHeight;\r\n    }\r\n\r\n    if (Math.abs(this.stableCoarseViewportWidth - viewportWidth) > 1) {\r\n      this.stableCoarseViewportWidth = viewportWidth;\r\n      this.stableCoarseViewportHeight = viewportHeight;\r\n      return viewportHeight;\r\n    }\r\n\r\n    this.stableCoarseViewportWidth = viewportWidth;\r\n    this.stableCoarseViewportHeight = Math.max(this.stableCoarseViewportHeight, viewportHeight);\r\n    return this.stableCoarseViewportHeight;\r\n  }\r\n}\r\n\r\nexport { StringDevInview as StringInview };\r\n","export interface BindOutsideClickOptions {\n  ignore?: Array<HTMLElement | null | undefined>;\n}\n\nexport function bindOutsideClick(\n  panel: HTMLElement,\n  onOutside: (event: PointerEvent) => void,\n  options: BindOutsideClickOptions = {},\n): () => void {\n  const handler = (event: PointerEvent) => {\n    const target = event.target;\n    if (!(target instanceof Node)) return;\n    if (panel.contains(target)) return;\n    for (const ignored of options.ignore ?? []) {\n      if (ignored && ignored.contains(target)) return;\n    }\n    onOutside(event);\n  };\n\n  document.addEventListener(\"pointerdown\", handler);\n  return () => document.removeEventListener(\"pointerdown\", handler);\n}\n","// export const PROGRESS_CSS = `\r\n//   [data-string-progress-dock],\r\n//   [data-stdg-progress] {\r\n//     position: fixed;\r\n//     left: 50%;\r\n//     bottom: 20px;\r\n//     z-index: 10032;\r\n//     width: min(25vw, calc(100vw - 32px));\r\n//     min-width: 360px;\r\n//     max-width: 520px;\r\n//     transform: translate3d(-50%, 16px, 0);\r\n//     opacity: 0;\r\n//     pointer-events: none;\r\n//     transition:\r\n//       opacity 0.22s ease,\r\n//       transform 0.22s ease;\r\n//     box-sizing: border-box;\r\n//     border-radius: 16px;\r\n//     background: rgba(255, 255, 255, 0.98);\r\n//     box-shadow:\r\n//       0 0 0 1px rgba(255, 255, 255, 0.95),\r\n//       0 18px 36px rgba(0, 0, 0, 0.12);\r\n//     padding: 10px 12px 12px;\r\n//     backdrop-filter: blur(18px);\r\n//   }\r\n\r\n//   [data-stdg-progress][data-open=\"true\"] {\r\n//     opacity: 1;\r\n//     transform: translate3d(-50%, 0, 0);\r\n//     pointer-events: auto;\r\n//   }\r\n\r\n//   [data-stdg-panel-header] {\r\n//     display: grid;\r\n//     grid-template-columns: minmax(0, 1fr) auto 28px;\r\n//     align-items: center;\r\n//     column-gap: 8px;\r\n//     margin-bottom: 8px;\r\n//   }\r\n\r\n//   [data-stdg-panel-header] > span:first-child,\r\n//   [data-string-progress-dock-title] {\r\n//     min-width: 0;\r\n//     color: #111111;\r\n//     font-family: var(--string-dev-panel-font-family);\r\n//     font-size: 13px;\r\n//     font-weight: 700;\r\n//     line-height: 1.2;\r\n//     text-align: left;\r\n//     white-space: nowrap;\r\n//     overflow: hidden;\r\n//     text-overflow: ellipsis;\r\n//   }\r\n\r\n//   [data-stdg-button-left],\r\n//   [data-string-progress-dock-play-group] {\r\n//     display: flex;\r\n//     align-items: center;\r\n//     gap: 2px;\r\n//     justify-self: center;\r\n//     order: -1;\r\n//   }\r\n\r\n//   [data-stdg-button][data-string-progress-dock-play-forward],\r\n//   [data-stdg-button][data-string-progress-dock-play-backward],\r\n//   [data-stdg-button][data-string-progress-dock-close],\r\n//   [data-string-progress-dock-play-forward],\r\n//   [data-string-progress-dock-play-backward],\r\n//   [data-string-progress-dock-close] {\r\n//     width: 28px;\r\n//     height: 28px;\r\n//     padding: 0;\r\n//     border: 0;\r\n//     background: transparent;\r\n//     color: #111111;\r\n//     display: inline-flex;\r\n//     align-items: center;\r\n//     justify-content: center;\r\n//     cursor: pointer;\r\n//     border-radius: 6px;\r\n//     transition: color 0.15s ease, background 0.15s ease;\r\n//   }\r\n\r\n//   [data-stdg-button][data-string-progress-dock-play-forward]:hover,\r\n//   [data-stdg-button][data-string-progress-dock-play-backward]:hover,\r\n//   [data-stdg-button][data-string-progress-dock-close]:hover,\r\n//   [data-string-progress-dock-play-forward]:hover,\r\n//   [data-string-progress-dock-play-backward]:hover,\r\n//   [data-string-progress-dock-close]:hover,\r\n//   [data-stdg-button][data-string-progress-dock-play-forward]:focus-visible,\r\n//   [data-stdg-button][data-string-progress-dock-play-backward]:focus-visible,\r\n//   [data-stdg-button][data-string-progress-dock-close]:focus-visible,\r\n//   [data-string-progress-dock-play-forward]:focus-visible,\r\n//   [data-string-progress-dock-play-backward]:focus-visible,\r\n//   [data-string-progress-dock-close]:focus-visible {\r\n//     background: rgba(17, 17, 17, 0.06);\r\n//     outline: none;\r\n//   }\r\n\r\n//   [data-stdg-button][data-string-progress-dock-play-forward] svg,\r\n//   [data-stdg-button][data-string-progress-dock-play-backward] svg,\r\n//   [data-stdg-button][data-string-progress-dock-close] svg,\r\n//   [data-string-progress-dock-play-forward] svg,\r\n//   [data-string-progress-dock-play-backward] svg,\r\n//   [data-string-progress-dock-close] svg {\r\n//     width: 16px;\r\n//     height: 16px;\r\n//   }\r\n\r\n//   [data-stdg-button][data-string-progress-dock-play-forward][data-active=\"true\"],\r\n//   [data-stdg-button][data-string-progress-dock-play-backward][data-active=\"true\"],\r\n//   [data-string-progress-dock-play-forward][data-active=\"true\"],\r\n//   [data-string-progress-dock-play-backward][data-active=\"true\"] {\r\n//     color: rgba(17, 17, 17, 0.35);\r\n//   }\r\n\r\n//   [data-stdg-button-right],\r\n//   [data-string-progress-dock-close] {\r\n//     justify-self: end;\r\n//   }\r\n\r\n//   [data-stdg-panel-content] {\r\n//     display: block;\r\n//   }\r\n\r\n//   [data-stdg-panel-field-slider-row] {\r\n//     display: grid;\r\n//     grid-template-columns: minmax(0, 1fr) 80px;\r\n//     gap: 8px;\r\n//     align-items: stretch;\r\n//   }\r\n\r\n//   [data-stdg-panel-field][data-string-progress-field],\r\n//   [data-string-progress-field] {\r\n//     position: relative;\r\n//     min-width: 0;\r\n//     min-height: 40px;\r\n//     display: flex;\r\n//     align-items: center;\r\n//     padding: 0;\r\n//     border-radius: 14px;\r\n//     background: #efefef;\r\n//     box-sizing: border-box;\r\n//     overflow: hidden;\r\n//   }\r\n\r\n//   [data-stdg-panel-field-slider] > label {\r\n//     flex: 0 0 auto;\r\n//     padding-left: 14px;\r\n//     padding-right: 12px;\r\n//     color: rgba(17, 17, 17, 0.45);\r\n//     font-family: var(--string-dev-panel-font-family);\r\n//     font-size: 12px;\r\n//     font-weight: 500;\r\n//     line-height: 1;\r\n//     user-select: none;\r\n//   }\r\n\r\n//   [data-stdg-input][data-string-progress-slider],\r\n//   [data-string-progress-slider] {\r\n//     flex: 1 1 auto;\r\n//     width: 100%;\r\n//     height: 40px;\r\n//     display: block;\r\n//     margin: 0;\r\n//     appearance: none;\r\n//     -webkit-appearance: none;\r\n//     background: transparent;\r\n//     cursor: pointer;\r\n//   }\r\n\r\n//   [data-stdg-input][data-string-progress-slider]:focus-visible,\r\n//   [data-string-progress-slider]:focus-visible {\r\n//     outline: none;\r\n//   }\r\n\r\n//   [data-stdg-input][data-string-progress-slider]::-webkit-slider-runnable-track,\r\n//   [data-string-progress-slider]::-webkit-slider-runnable-track {\r\n//     height: 40px;\r\n//     border-radius: 0;\r\n//     background:\r\n//       linear-gradient(\r\n//         90deg,\r\n//         rgba(17, 17, 17, 0.12) 0%,\r\n//         rgba(17, 17, 17, 0.12) var(--string-progress-slider-fill),\r\n//         transparent var(--string-progress-slider-fill),\r\n//         transparent 100%\r\n//       );\r\n//   }\r\n\r\n//   [data-stdg-input][data-string-progress-slider]::-webkit-slider-thumb,\r\n//   [data-string-progress-slider]::-webkit-slider-thumb {\r\n//     -webkit-appearance: none;\r\n//     width: 2px;\r\n//     height: 46px;\r\n//     border: 0;\r\n//     border-radius: 999px;\r\n//     background: #111111;\r\n//     margin-top: -4px;\r\n//     box-shadow: none;\r\n//   }\r\n\r\n//   [data-stdg-input][data-string-progress-slider]::-moz-range-track,\r\n//   [data-string-progress-slider]::-moz-range-track {\r\n//     height: 40px;\r\n//     border: 0;\r\n//     border-radius: 0;\r\n//     background: transparent;\r\n//   }\r\n\r\n//   [data-stdg-input][data-string-progress-slider]::-moz-range-progress,\r\n//   [data-string-progress-slider]::-moz-range-progress {\r\n//     height: 40px;\r\n//     background: rgba(17, 17, 17, 0.12);\r\n//   }\r\n\r\n//   [data-stdg-input][data-string-progress-slider]::-moz-range-thumb,\r\n//   [data-string-progress-slider]::-moz-range-thumb {\r\n//     width: 4px;\r\n//     height: 52px;\r\n//     border: 0;\r\n//     border-radius: 999px;\r\n//     background: #111111;\r\n//     box-shadow: none;\r\n//   }\r\n\r\n//   [data-stdg-panel-field][data-string-progress-value-card],\r\n//   [data-string-progress-value-card] {\r\n//     min-height: 40px;\r\n//     display: grid;\r\n//     grid-template-columns: minmax(0, 1fr) auto;\r\n//     align-items: center;\r\n//     padding: 0 14px;\r\n//     border-radius: 14px;\r\n//     background: #efefef;\r\n//     box-sizing: border-box;\r\n//   }\r\n\r\n//   [data-stdg-input][data-string-progress-value-number],\r\n//   [data-string-progress-value-number] {\r\n//     width: 100%;\r\n//     min-width: 0;\r\n//     border: 0;\r\n//     background: transparent;\r\n//     color: #111111;\r\n//     font-family: var(--string-dev-panel-font-family);\r\n//     font-size: 13px;\r\n//     font-weight: 600;\r\n//     line-height: 1;\r\n//     text-align: center;\r\n//     outline: none;\r\n//     padding: 0;\r\n//     -moz-appearance: textfield;\r\n//   }\r\n\r\n//   [data-stdg-input][data-string-progress-value-number]::-webkit-inner-spin-button,\r\n//   [data-stdg-input][data-string-progress-value-number]::-webkit-outer-spin-button,\r\n//   [data-string-progress-value-number]::-webkit-inner-spin-button,\r\n//   [data-string-progress-value-number]::-webkit-outer-spin-button {\r\n//     -webkit-appearance: none;\r\n//   }\r\n\r\n//   [data-stdg-field-input-disable][data-string-progress-value-unit],\r\n//   [data-string-progress-value-unit] {\r\n//     display: inline-flex;\r\n//     align-items: center;\r\n//     padding-left: 12px;\r\n//     margin-left: 12px;\r\n//     border-left: 1px solid rgba(17, 17, 17, 0.14);\r\n//     color: rgba(17, 17, 17, 0.45);\r\n//     font-family: var(--string-dev-panel-font-family);\r\n//     font-size: 13px;\r\n//     font-weight: 500;\r\n//     line-height: 1;\r\n//   }\r\n\r\n//   @media (max-width: 720px) {\r\n//     [data-string-progress-dock],\r\n//     [data-stdg-progress] {\r\n//       width: calc(100vw - 20px);\r\n//       min-width: 0;\r\n//       max-width: none;\r\n//       bottom: 10px;\r\n//       padding: 12px 10px 10px;\r\n//     }\r\n\r\n//     [data-stdg-panel-header] {\r\n//       grid-template-columns: minmax(0, 1fr) auto 28px;\r\n//       margin-bottom: 10px;\r\n//     }\r\n\r\n//     [data-stdg-panel-field-slider-row] {\r\n//       grid-template-columns: 1fr;\r\n//     }\r\n\r\n//     [data-stdg-panel-field][data-string-progress-field],\r\n//     [data-string-progress-field] {\r\n//       min-height: 48px;\r\n//     }\r\n\r\n//     [data-stdg-panel-field-slider] > label {\r\n//       font-size: 15px;\r\n//     }\r\n\r\n//     [data-stdg-input][data-string-progress-slider]::-webkit-slider-runnable-track,\r\n//     [data-stdg-input][data-string-progress-slider]::-webkit-slider-thumb,\r\n//     [data-stdg-input][data-string-progress-slider]::-moz-range-track,\r\n//     [data-stdg-input][data-string-progress-slider]::-moz-range-progress,\r\n//     [data-stdg-input][data-string-progress-slider]::-moz-range-thumb,\r\n//     [data-string-progress-slider]::-webkit-slider-runnable-track,\r\n//     [data-string-progress-slider]::-webkit-slider-thumb,\r\n//     [data-string-progress-slider]::-moz-range-track,\r\n//     [data-string-progress-slider]::-moz-range-progress,\r\n//     [data-string-progress-slider]::-moz-range-thumb {\r\n//       height: 48px;\r\n//     }\r\n\r\n//     [data-stdg-panel-field][data-string-progress-value-card],\r\n//     [data-string-progress-value-card] {\r\n//       min-height: 48px;\r\n//       padding: 0 14px;\r\n//     }\r\n//   }\r\n// `;\r\nexport const PROGRESS_CSS = \"\";\r\n","import { StringDevOverlayModule, OverlayBaseMetrics } from \"../core/StringDevOverlayModule\";\r\nimport { resolveDevtoolsIcon } from \"../core/StringDevIconRegistry\";\r\nimport { makeBadge } from \"../core/StringDevElements\";\r\nimport { bindOutsideClick } from \"../core/bindOutsideClick\";\r\nimport { StringObject } from \"../../../objects/StringObject\";\r\nimport { StringContext } from \"../../../core/StringContext\";\r\nimport { EasingFunctionOutput } from \"../../../tools/EasingFunctionTool\";\r\nimport { styleTxn } from \"../../../utils/style-txn\";\r\nimport { STRING_DEV_PROGRESS_OVERRIDE_KEY } from \"../../scroll/StringProgress\";\r\nimport { PROGRESS_CSS } from \"./StringDevProgress.css\";\r\n\r\ninterface ProgressEntry {\r\n  object: StringObject;\r\n  hud: HTMLDivElement;\r\n  badge: HTMLButtonElement;\r\n  onBadgeClick: (event: MouseEvent) => void;\r\n}\r\n\r\ninterface ProgressMeasurement {\r\n  visible: boolean;\r\n  docX: number;\r\n  docY: number;\r\n  targetId: string;\r\n  progress: number;\r\n  rawProgress: number;\r\n  startPosition: number;\r\n  endPosition: number;\r\n  currentScroll: number;\r\n  key: string;\r\n}\r\n\r\nfunction clampProgress(raw: number): number {\r\n  if (!Number.isFinite(raw)) return 0;\r\n  if (raw <= 0) return 0;\r\n  if (raw >= 1) return 1;\r\n  const epsilon = 1e-4;\r\n  if (raw > 1 - epsilon) return 1;\r\n  if (raw < epsilon) return 0;\r\n  return raw;\r\n}\r\n\r\nfunction formatPercent(value: number): string {\r\n  const percent = clampProgress(value) * 100;\r\n  return `${Math.round(percent * 10) / 10}%`;\r\n}\r\n\r\nexport class StringDevProgress extends StringDevOverlayModule<ProgressEntry, ProgressMeasurement> {\r\n  static override devtool = {\r\n    id: \"progress\",\r\n    label: \"Progress\",\r\n    icon: \"progress\",\r\n    order: 35,\r\n    group: 2,\r\n    hotkey: { key: \"P\", shiftKey: true },\r\n    styles: PROGRESS_CSS,\r\n    overlay: {\r\n      layerName: \"devtools-progress\",\r\n      zIndex: 10012,\r\n      layerAttribute: \"data-string-progress-layer\",\r\n      overlayId: \"progress\",\r\n    },\r\n    connects: { keys: [\"progress\"] },\r\n  };\r\n\r\n  private openTargetLabel: string | null = null;\r\n  private panelRoot: HTMLDivElement | null = null;\r\n  private panelTitle: HTMLSpanElement | null = null;\r\n  private panelSlider: HTMLInputElement | null = null;\r\n  private panelValue: HTMLInputElement | null = null;\r\n  private panelEasedValue: HTMLSpanElement | null = null;\r\n  private panelPlayForwardButton: HTMLButtonElement | null = null;\r\n  private panelPlayBackwardButton: HTMLButtonElement | null = null;\r\n  private autoplayRaf: number | null = null;\r\n  private autoplayDirection: 1 | -1 = 1;\r\n  private autoplayProgress = 0;\r\n  private readonly onPanelSliderInputBind = () => {\r\n    this.onPanelSliderInput();\r\n  };\r\n  private unbindOutsideClick: (() => void) | null = null;\r\n\r\n  constructor(context: StringContext) {\r\n    super(context);\r\n    this.attributesToMap = [\r\n      ...this.attributesToMap,\r\n      { key: \"easing\", type: \"easing\", fallback: this.settings[\"easing\"] },\r\n    ];\r\n  }\r\n\r\n  onInit(): void {\r\n    super.onInit();\r\n    this.ensurePanel();\r\n  }\r\n\r\n  destroy(): void {\r\n    this.unbindOutsideClick?.();\r\n    this.unbindOutsideClick = null;\r\n    this.panelSlider?.removeEventListener(\"input\", this.onPanelSliderInputBind);\r\n    this.stopAutoplay();\r\n    this.panelRoot?.remove();\r\n    this.panelRoot = null;\r\n    this.panelTitle = null;\r\n    this.panelSlider = null;\r\n    this.panelValue = null;\r\n    this.panelEasedValue = null;\r\n    this.panelPlayForwardButton = null;\r\n    this.panelPlayBackwardButton = null;\r\n    this.clearAllProgressOverrides();\r\n    this.openTargetLabel = null;\r\n    super.destroy();\r\n  }\r\n\r\n  protected createOverlayEntry(object: StringObject): ProgressEntry {\r\n    const targetLabel = this.resolveOverlayTargetId(object);\r\n    const hud = makeBadge(targetLabel);\r\n    hud.setAttribute(\"data-string-devtools-overlay-hud\", \"\");\r\n\r\n    const badge = this.createOverlayBadge({\r\n      targetId: targetLabel,\r\n      selectorAttribute: \"data-string-progress-badge\",\r\n      attributes: {\r\n        \"data-stdg-button-toggle\": \"\",\r\n        \"data-active\": \"false\",\r\n        \"aria-label\": `Open progress controller for ${targetLabel}`,\r\n      },\r\n    });\r\n    this.applyOverlayBadgeState(badge, {\r\n      html: resolveDevtoolsIcon(16, \"play-r\"),\r\n    });\r\n\r\n    const onBadgeClick = (event: MouseEvent) => {\r\n      event.stopPropagation();\r\n      event.preventDefault();\r\n      if (this.openTargetLabel === targetLabel) {\r\n        this.closePanel(targetLabel);\r\n        return;\r\n      }\r\n      this.openPanel(targetLabel);\r\n    };\r\n\r\n    badge.addEventListener(\"click\", onBadgeClick);\r\n    hud.appendChild(badge);\r\n    this.badgeLayer.getWorldElement(this.getWorldHost()).appendChild(hud);\r\n    this.applyEntryEnabledState(hud);\r\n\r\n    return {\r\n      object,\r\n      hud,\r\n      badge,\r\n      onBadgeClick,\r\n    };\r\n  }\r\n\r\n  protected destroyOverlayEntry(entry: ProgressEntry): void {\r\n    const targetLabel = this.resolveOverlayTargetId(entry.object);\r\n    if (this.openTargetLabel === targetLabel) {\r\n      this.clearEntryProgressOverride(entry.object);\r\n      this.closePanel(targetLabel);\r\n    }\r\n\r\n    entry.badge.removeEventListener(\"click\", entry.onBadgeClick);\r\n    entry.hud.remove();\r\n  }\r\n\r\n  protected measureEntry(entry: ProgressEntry, metrics: OverlayBaseMetrics): ProgressMeasurement {\r\n    const object = entry.object;\r\n    const targetId = this.resolveOverlayTargetId(object);\r\n    const currentScroll = this.data.scroll.transformedCurrent;\r\n    const key = object.getProperty<string>(\"key\") || \"--progress\";\r\n\r\n    const { startPosition, differencePosition } = this.getEntryRange(object);\r\n    const endPosition =\r\n      object.getProperty<number>(\"end-position\") ?? startPosition + differencePosition;\r\n\r\n    const rawProgress = this.resolveEntryRawProgress(object, currentScroll);\r\n    const progress = this.resolveEasedProgress(object, rawProgress);\r\n\r\n    return {\r\n      visible: metrics.visible,\r\n      docX: metrics.visible ? metrics.baseAnchorX : 0,\r\n      docY: metrics.visible ? metrics.baseAnchorY + metrics.collisionOffset : 0,\r\n      targetId,\r\n      progress,\r\n      rawProgress,\r\n      startPosition,\r\n      endPosition,\r\n      currentScroll,\r\n      key,\r\n    };\r\n  }\r\n\r\n  protected applyMeasurement(\r\n    entry: ProgressEntry,\r\n    measurement: ProgressMeasurement | undefined,\r\n  ): void {\r\n    const targetId = this.resolveOverlayTargetId(entry.object);\r\n\r\n    if (!measurement || !measurement.visible) {\r\n      entry.hud.setAttribute(\"data-visible\", \"false\");\r\n      if (this.openTargetLabel === targetId) {\r\n        this.renderPanel();\r\n      }\r\n      return;\r\n    }\r\n\r\n    entry.hud.setAttribute(\"data-visible\", \"true\");\r\n    styleTxn.setProps(entry.hud, {\r\n      transform: `translate3d(${Math.round(measurement.docX)}px, ${Math.round(measurement.docY)}px, 0)`,\r\n    });\r\n\r\n    entry.badge.title = `${this.getOverlayTargetLabel(entry.object)}: ${formatPercent(measurement.progress)}`;\r\n    this.applyOverlayBadgeState(entry.badge, {\r\n      label: measurement.progress.toFixed(2),\r\n    });\r\n\r\n    if (this.openTargetLabel === measurement.targetId) {\r\n      this.renderPanel();\r\n    }\r\n  }\r\n\r\n  protected onEnabledChange(enabled: boolean): void {\r\n    for (const entry of this.entries.values()) {\r\n      this.applyEntryEnabledState(entry.hud);\r\n    }\r\n\r\n    if (!enabled) {\r\n      this.closeAllPanels();\r\n      this.clearAllProgressOverrides();\r\n    }\r\n\r\n    if (this.panelRoot) {\r\n      this.panelRoot.style.display = enabled ? \"\" : \"none\";\r\n    }\r\n  }\r\n\r\n  private applyEntryEnabledState(hud: HTMLDivElement): void {\r\n    hud.style.display = this.enabled ? \"\" : \"none\";\r\n  }\r\n\r\n  private openPanel(targetLabel: string): void {\r\n    this.ensurePanel();\r\n    this.closeAllPanels();\r\n    this.openTargetLabel = targetLabel;\r\n    const entry = this.findEntryByTargetLabel(targetLabel);\r\n    if (entry) entry.badge.setAttribute(\"data-active\", \"true\");\r\n    if (this.panelRoot) {\r\n      this.unbindOutsideClick = bindOutsideClick(this.panelRoot, () => this.closeAllPanels(), {\r\n        ignore: this.collectEntryHuds(),\r\n      });\r\n    }\r\n    this.renderPanel();\r\n  }\r\n\r\n  private closePanel(targetLabel: string): void {\r\n    this.stopAutoplay();\r\n    const entry = this.findEntryByTargetLabel(targetLabel);\r\n    if (entry) {\r\n      entry.badge.setAttribute(\"data-active\", \"false\");\r\n      this.clearEntryProgressOverride(entry.object);\r\n    }\r\n\r\n    if (this.openTargetLabel === targetLabel) {\r\n      this.openTargetLabel = null;\r\n    }\r\n\r\n    this.renderPanel();\r\n  }\r\n\r\n  private closeAllPanels(): void {\r\n    this.stopAutoplay();\r\n    for (const entry of this.entries.values()) {\r\n      entry.badge.setAttribute(\"data-active\", \"false\");\r\n      this.clearEntryProgressOverride(entry.object);\r\n    }\r\n    this.openTargetLabel = null;\r\n    this.unbindOutsideClick?.();\r\n    this.unbindOutsideClick = null;\r\n    this.renderPanel();\r\n  }\r\n\r\n  private collectEntryHuds(): HTMLElement[] {\r\n    const huds: HTMLElement[] = [];\r\n    for (const entry of this.entries.values()) {\r\n      huds.push(entry.hud);\r\n    }\r\n    return huds;\r\n  }\r\n\r\n  private startAutoplay(direction: 1 | -1): void {\r\n    this.stopAutoplay();\r\n    this.autoplayDirection = direction;\r\n    this.autoplayProgress = direction === 1 ? 0 : 1;\r\n\r\n    const duration = 1200;\r\n    let lastTime: number | null = null;\r\n\r\n    const tick = (time: number) => {\r\n      if (lastTime === null) {\r\n        lastTime = time;\r\n        this.autoplayRaf = requestAnimationFrame(tick);\r\n        return;\r\n      }\r\n\r\n      const delta = (time - lastTime) / duration;\r\n      lastTime = time;\r\n      this.autoplayProgress += delta * this.autoplayDirection;\r\n\r\n      const entry = this.openTargetLabel ? this.findEntryByTargetLabel(this.openTargetLabel) : null;\r\n\r\n      if (this.autoplayProgress >= 1) {\r\n        this.autoplayProgress = 1;\r\n        if (entry) this.setEntryProgressOverride(entry.object, 1);\r\n        this.stopAutoplay();\r\n        return;\r\n      }\r\n\r\n      if (this.autoplayProgress <= 0) {\r\n        this.autoplayProgress = 0;\r\n        if (entry) this.setEntryProgressOverride(entry.object, 0);\r\n        this.stopAutoplay();\r\n        return;\r\n      }\r\n\r\n      if (entry) {\r\n        this.setEntryProgressOverride(entry.object, this.autoplayProgress);\r\n      }\r\n\r\n      this.autoplayRaf = requestAnimationFrame(tick);\r\n    };\r\n\r\n    this.autoplayRaf = requestAnimationFrame(tick);\r\n    this.syncPlayButtonState();\r\n  }\r\n\r\n  private stopAutoplay(): void {\r\n    if (this.autoplayRaf !== null) {\r\n      cancelAnimationFrame(this.autoplayRaf);\r\n      this.autoplayRaf = null;\r\n    }\r\n    this.syncPlayButtonState();\r\n  }\r\n\r\n  private syncPlayButtonState(): void {\r\n    const isPlaying = this.autoplayRaf !== null;\r\n    const isForward = isPlaying && this.autoplayDirection === 1;\r\n    const isBackward = isPlaying && this.autoplayDirection === -1;\r\n    this.panelPlayForwardButton?.setAttribute(\"data-active\", String(isForward));\r\n    this.panelPlayBackwardButton?.setAttribute(\"data-active\", String(isBackward));\r\n  }\r\n\r\n  private getEntryRange(object: StringObject): {\r\n    startPosition: number;\r\n    differencePosition: number;\r\n  } {\r\n    const startPosition =\r\n      object.getProperty<number>(\"start-position\") ??\r\n      object.getProperty<number>(\"progress-start-position\") ??\r\n      0;\r\n    const differencePosition =\r\n      object.getProperty<number>(\"difference-position\") ??\r\n      object.getProperty<number>(\"progress-difference-position\") ??\r\n      0;\r\n    return { startPosition, differencePosition };\r\n  }\r\n\r\n  private resolveEntryRawProgress(object: StringObject, currentScroll: number): number {\r\n    const overrideRawProgress = object.getProperty<number | null>(STRING_DEV_PROGRESS_OVERRIDE_KEY);\r\n    if (overrideRawProgress != null) {\r\n      return clampProgress(overrideRawProgress);\r\n    }\r\n\r\n    const { startPosition, differencePosition } = this.getEntryRange(object);\r\n\r\n    return clampProgress(\r\n      differencePosition === 0 ? 0 : (currentScroll - startPosition) / differencePosition,\r\n    );\r\n  }\r\n\r\n  private resolveEasedProgress(object: StringObject, rawProgress: number): number {\r\n    const easing = object.getProperty<EasingFunctionOutput>(\"easing\");\r\n    return typeof easing === \"function\" ? clampProgress(easing(rawProgress)) : rawProgress;\r\n  }\r\n\r\n  private setEntryProgressOverride(object: StringObject, rawProgress: number): void {\r\n    object.setProperty(STRING_DEV_PROGRESS_OVERRIDE_KEY, clampProgress(rawProgress));\r\n    this.applyObjectProgress(object, rawProgress);\r\n    const entry = this.entries.get(object.id);\r\n    if (entry) this.scheduleSingleSync(entry);\r\n    else this.scheduleSync();\r\n  }\r\n\r\n  private clearEntryProgressOverride(object: StringObject): void {\r\n    if (object.getProperty<number | null>(STRING_DEV_PROGRESS_OVERRIDE_KEY) == null) {\r\n      return;\r\n    }\r\n\r\n    object.setProperty<number | null>(STRING_DEV_PROGRESS_OVERRIDE_KEY, null);\r\n    const liveRawProgress = this.resolveEntryRawProgress(\r\n      object,\r\n      this.data.scroll.transformedCurrent,\r\n    );\r\n    this.applyObjectProgress(object, liveRawProgress);\r\n    const entry = this.entries.get(object.id);\r\n    if (entry) this.scheduleSingleSync(entry);\r\n    else this.scheduleSync();\r\n  }\r\n\r\n  private clearAllProgressOverrides(): void {\r\n    for (const entry of this.entries.values()) {\r\n      this.clearEntryProgressOverride(entry.object);\r\n    }\r\n  }\r\n\r\n  private applyObjectProgress(object: StringObject, rawProgress: number): void {\r\n    const normalizedRawProgress = clampProgress(rawProgress);\r\n    const easing = object.getProperty<EasingFunctionOutput>(\"easing\");\r\n    const progress = this.resolveEasedProgress(object, normalizedRawProgress);\r\n    const key = object.getProperty<string>(\"key\");\r\n\r\n    object.setProperty(\"progress-raw\", normalizedRawProgress);\r\n    object.setProperty(\"progress-value\", progress);\r\n    object.setProperty<number>(\"progress-applied\", progress);\r\n\r\n    const eventName =\r\n      object.getProperty<string>(\"event-progress-name\") ??\r\n      object.getScopedEventName(\"object:progress\");\r\n    object.setProperty(\"event-progress-name\", eventName);\r\n    if (eventName) {\r\n      this.events.emit(eventName, progress);\r\n    }\r\n\r\n    this.tools.styleTxn.run(() => {\n      if (key) {\n        this.tools.styleTxn.setVar(object.htmlElement, key, progress);\n      }\n\r\n      for (const mirror of object.mirrorObjects) {\r\n        const mirrorProgress = mirror.applyProgress(\r\n          normalizedRawProgress,\r\n          typeof easing === \"function\" ? easing : undefined,\r\n        );\r\n        mirror.setProperty(\"progress\", mirrorProgress);\r\n        if (key) {\r\n          this.tools.styleTxn.setVar(mirror.htmlElement, key, mirrorProgress);\r\n        }\r\n      }\r\n    });\r\n  }\r\n\r\n  private ensurePanel(): void {\r\n    if (this.panelRoot) {\r\n      return;\r\n    }\r\n\r\n    const panel = document.createElement(\"div\");\r\n    panel.setAttribute(\"data-string-progress-panel\", \"\");\r\n    panel.setAttribute(\"data-stdg\", \"\");\r\n    panel.setAttribute(\"data-stdg-panel\", \"\");\r\n    panel.setAttribute(\"data-stdg-progress\", \"\");\r\n    panel.setAttribute(\"data-string-devtools-theme\", \"\");\r\n    panel.setAttribute(\"data-open\", \"false\");\r\n    panel.setAttribute(\"data-target-id\", \"\");\r\n    panel.setAttribute(\"hidden\", \"\");\r\n    panel.addEventListener(\"pointerdown\", (event) => event.stopPropagation());\r\n\r\n    panel.innerHTML = `\r\n      <div data-stdg-panel-header>\r\n        <span data-string-progress-dock-title>Element ID</span>\r\n        <nav data-stdg-button-left data-string-progress-dock-play-group>\r\n          <button\r\n            type=\"button\"\r\n            data-stdg-button\r\n            data-stdg-button-toggle\r\n            data-stdg-button-icon-16\r\n            data-string-progress-dock-play-backward\r\n            aria-label=\"Play backward 100→0\"\r\n            title=\"Play backward 100→0\"\r\n            data-active=\"false\"\r\n          >\r\n            ${resolveDevtoolsIcon(16, \"play-l\")}\r\n          </button>\r\n          <button\r\n            type=\"button\"\r\n            data-stdg-button\r\n            data-stdg-button-toggle\r\n            data-stdg-button-icon-16\r\n            data-string-progress-dock-play-forward\r\n            aria-label=\"Play forward 0→100\"\r\n            title=\"Play forward 0→100\"\r\n            data-active=\"false\"\r\n          >\r\n            ${resolveDevtoolsIcon(16, \"play-r\")}\r\n          </button>\r\n        </nav>\r\n        <button\r\n          type=\"button\"\r\n          data-stdg-button\r\n          data-stdg-button-right\r\n          data-stdg-button-icon-16\r\n          data-string-progress-dock-close\r\n          aria-label=\"Close progress controller\"\r\n          title=\"Close progress controller\"\r\n        >\r\n          ${resolveDevtoolsIcon(16, \"close\")}\r\n        </button>\r\n      </div>\r\n      <div data-stdg-panel-content>\r\n        <div data-stdg-panel-field-slider-row>\r\n          <div\r\n            data-stdg-panel-field\r\n            data-stdg-panel-field-slider\r\n            data-string-progress-field\r\n          >\r\n            <label for=\"string-dev-progress-slider\">Progress</label>\r\n            <input\r\n              id=\"string-dev-progress-slider\"\r\n              type=\"range\"\r\n              min=\"0\"\r\n              max=\"1000\"\r\n              step=\"1\"\r\n              value=\"0\"\r\n              aria-label=\"Preview progress\"\r\n              data-stdg-input\r\n              data-string-progress-slider\r\n              style=\"--string-progress-slider-fill: 0%;\"\r\n            />\r\n          </div>\r\n          <div data-stdg-panel-field data-string-progress-value-card>\r\n            <input\r\n              id=\"string-dev-progress-value\"\r\n              type=\"number\"\r\n              min=\"0\"\r\n              max=\"100\"\r\n              step=\"1\"\r\n              inputmode=\"numeric\"\r\n              value=\"0\"\r\n              aria-label=\"Progress value\"\r\n              data-stdg-input\r\n              data-string-progress-value-number\r\n            />\r\n            <label\r\n              for=\"string-dev-progress-value\"\r\n              data-stdg-field-input-disable\r\n              data-string-progress-value-unit\r\n            >%</label>\r\n          </div>\r\n        </div>\r\n        <span data-field=\"eased\" hidden>0%</span>\r\n      </div>\r\n    `;\r\n\r\n    this.panelRoot = panel;\r\n    this.panelTitle = panel.querySelector(\"[data-string-progress-dock-title]\") as HTMLSpanElement;\r\n    this.panelSlider = panel.querySelector(\"[data-string-progress-slider]\") as HTMLInputElement;\r\n    this.panelValue = panel.querySelector(\r\n      \"[data-string-progress-value-number]\",\r\n    ) as HTMLInputElement;\r\n    this.panelEasedValue = panel.querySelector('[data-field=\"eased\"]') as HTMLSpanElement;\r\n\r\n    this.panelPlayForwardButton = panel.querySelector(\r\n      \"[data-string-progress-dock-play-forward]\",\r\n    ) as HTMLButtonElement;\r\n    this.panelPlayForwardButton.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      if (this.autoplayRaf !== null && this.autoplayDirection === 1) {\r\n        this.stopAutoplay();\r\n      } else {\r\n        this.startAutoplay(1);\r\n      }\r\n    });\r\n\r\n    this.panelPlayBackwardButton = panel.querySelector(\r\n      \"[data-string-progress-dock-play-backward]\",\r\n    ) as HTMLButtonElement;\r\n    this.panelPlayBackwardButton.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      if (this.autoplayRaf !== null && this.autoplayDirection === -1) {\r\n        this.stopAutoplay();\r\n      } else {\r\n        this.startAutoplay(-1);\r\n      }\r\n    });\r\n\r\n    const closeButton = panel.querySelector(\r\n      \"[data-string-progress-dock-close]\",\r\n    ) as HTMLButtonElement;\r\n    closeButton.addEventListener(\"click\", (event) => {\r\n      event.stopPropagation();\r\n      if (this.openTargetLabel) {\r\n        this.closePanel(this.openTargetLabel);\r\n      }\r\n    });\r\n\r\n    this.panelSlider.addEventListener(\"input\", this.onPanelSliderInputBind);\r\n    this.panelValue.addEventListener(\"input\", () => {\r\n      if (!this.openTargetLabel || !this.panelValue) return;\r\n      const entry = this.findEntryByTargetLabel(this.openTargetLabel);\r\n      if (!entry) return;\r\n      const percent = Math.max(0, Math.min(100, Number(this.panelValue.value)));\r\n      if (!Number.isFinite(percent)) return;\r\n      this.stopAutoplay();\r\n      const rawProgress = percent / 100;\r\n      this.autoplayProgress = rawProgress;\r\n      this.setEntryProgressOverride(entry.object, rawProgress);\r\n    });\r\n    this.panelValue.addEventListener(\"keydown\", (event) => {\r\n      if (event.key === \"Enter\") {\r\n        (event.target as HTMLInputElement).blur();\r\n      }\r\n    });\r\n\r\n    this.hudLayer.getWorldElement(this.getWorldHost()).appendChild(panel);\r\n  }\r\n\r\n  private onPanelSliderInput(): void {\r\n    if (!this.openTargetLabel || !this.panelSlider) {\r\n      return;\r\n    }\r\n\r\n    const entry = this.findEntryByTargetLabel(this.openTargetLabel);\r\n    if (!entry) {\r\n      return;\r\n    }\r\n\r\n    this.stopAutoplay();\r\n    const rawProgress = clampProgress(Number(this.panelSlider.value) / 1000);\r\n    this.autoplayProgress = rawProgress;\r\n    this.setEntryProgressOverride(entry.object, rawProgress);\r\n  }\r\n\r\n  private renderPanel(): void {\r\n    if (\r\n      !this.panelRoot ||\r\n      !this.panelTitle ||\r\n      !this.panelSlider ||\r\n      !this.panelValue ||\r\n      !this.panelEasedValue\r\n    ) {\r\n      return;\r\n    }\r\n\r\n    const activeEntry = this.openTargetLabel\r\n      ? this.findEntryByTargetLabel(this.openTargetLabel)\r\n      : null;\r\n    if (!this.enabled || !activeEntry) {\r\n      this.panelRoot.setAttribute(\"hidden\", \"\");\r\n      this.panelRoot.setAttribute(\"data-open\", \"false\");\r\n      this.panelRoot.setAttribute(\"data-target-id\", \"\");\r\n      return;\r\n    }\r\n\r\n    const targetId = this.resolveOverlayTargetId(activeEntry.object);\r\n    const targetLabel = this.getOverlayTargetLabel(activeEntry.object);\r\n    const measurement = this.measurements.get(activeEntry.object.id);\r\n    const progress = measurement ? clampProgress(measurement.progress) : 0;\r\n    const rawProgress = measurement ? clampProgress(measurement.rawProgress) : 0;\r\n\r\n    this.panelRoot.removeAttribute(\"hidden\");\r\n    this.panelRoot.setAttribute(\"data-open\", \"true\");\r\n    this.panelRoot.setAttribute(\"data-target-id\", targetId);\r\n    this.panelTitle.textContent = targetLabel;\r\n    this.panelSlider.setAttribute(\"aria-label\", `Preview progress for ${targetLabel}`);\r\n\r\n    styleTxn.setVarDirect(\r\n      this.panelSlider,\r\n      \"--string-progress-slider-fill\",\r\n      `${Math.round(rawProgress * 1000) / 10}%`,\r\n    );\r\n\r\n    const sliderValue = String(Math.round(rawProgress * 1000));\r\n    if (this.panelSlider.value !== sliderValue) {\r\n      this.panelSlider.value = sliderValue;\r\n    }\r\n\r\n    const displayValue = String(Math.round(progress * 100));\r\n    if (document.activeElement !== this.panelValue) {\r\n      this.panelValue.value = displayValue;\r\n    }\r\n\r\n    this.panelEasedValue.textContent = formatPercent(progress);\r\n  }\r\n\r\n  private findEntryByTargetLabel(targetLabel: string): ProgressEntry | null {\r\n    for (const entry of this.entries.values()) {\r\n      if (this.resolveOverlayTargetId(entry.object) === targetLabel) {\r\n        return entry;\r\n      }\r\n    }\r\n\r\n    return null;\r\n  }\r\n}\r\n\r\nexport { StringDevProgress as StringProgress };\r\n","export interface StringDevtoolState {\n  active: boolean;\n}\n\nexport interface StringDevtoolHotkey {\n  key: string;\n  shiftKey?: boolean;\n  ctrlKey?: boolean;\n  altKey?: boolean;\n  metaKey?: boolean;\n}\n\nexport interface StringDevtoolSubBadge {\n  id: string;\n  icon: string;\n  label: string;\n  /** Extra attribute used as a CSS selector hook (e.g. \"data-string-grid-global-toggle\"). */\n  selectorAttribute?: string;\n  /** Additional data-* attributes applied to the badge button. */\n  attributes?: Record<string, string | boolean | number | null | undefined>;\n  onClick: (anchorElement?: HTMLElement) => void;\n}\n\nexport interface StringDevtoolDefinition {\n  id: string;\n  label: string;\n  icon: string;\n  order?: number;\n  group?: number;\n  hotkey?: StringDevtoolHotkey;\n  subBadges?: StringDevtoolSubBadge[];\n  getState: () => StringDevtoolState;\n  setActive: (active: boolean) => void;\n  subscribe?: (listener: (state: StringDevtoolState) => void) => () => void;\n}\n\nexport interface StringDevtoolProvider {\n  getDevtoolDefinition(): StringDevtoolDefinition | null;\n}\n\nexport function isStringDevtoolProvider(value: unknown): value is StringDevtoolProvider {\n  return (\n    typeof value === \"object\" &&\n    value !== null &&\n    \"getDevtoolDefinition\" in value &&\n    typeof (value as StringDevtoolProvider).getDevtoolDefinition === \"function\"\n  );\n}\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ECG3B,IAAMC,GAAkD,CACtD,wBAAyB,UACzB,4BAA6B,oBAC7B,4BAA6B,OAC7B,4BAA6B,iCAC7B,8BAA+B,aAC/B,6BAA8B,MAC9B,iCACE,wGACF,+BAAgC,OAChC,0BAA2B,UAC3B,2BAA4B,wBAC5B,4BAA6B,yBAC7B,6BAA8B,yBAC9B,gCAAiC,OACjC,kCAAmC,MACnC,qCAAsC,IACtC,8BAA+B,cAC/B,oCAAqC,MACrC,sBAAuB,UACvB,2BAA4B,0BAC5B,iCAAkC,0BAClC,2BAA4B,0BAC5B,4BAA6B,oCAC7B,wBAAyB,2BACzB,4BAA6B,4BAC7B,4BAA6B,MAC7B,4BAA6B,OAC7B,6BAA8B,OAC9B,yBAA0B,OAC1B,gCAAiC,OACjC,kCAAmC,MACnC,8BAA+B,4BAC/B,0BAA2B,yBAC3B,6BAA8B,yBAC9B,oCAAqC,wBACvC,EAEA,SAASC,GAAUC,EAAiBC,EAAwB,CAC1D,OAAOD,EACJ,KAAK,EACL,MAAM;AAAA,CAAI,EACV,IAAKE,GAAS,GAAGD,CAAM,GAAGC,CAAI,EAAE,EAChC,KAAK;AAAA,CAAI,CACd,CAEO,SAASC,GACdC,EACAC,EAAkC,CAAC,EAC3B,CACR,IAAMC,EAAe,MAAM,QAAQF,CAAS,EAAIA,EAAU,KAAK;AAAA,CAAK,EAAIA,EAClEG,EAAS,CAAE,GAAGT,GAA2B,GAAGO,CAAU,EACtDG,EAAe,OAAO,QAAQD,CAAM,EACvC,IAAI,CAAC,CAACE,EAAMC,CAAK,IAAM,GAAGD,CAAI,KAAKC,CAAK,GAAG,EAC3C,KAAK;AAAA,CAAI,EAEZ,MAAO,GAAGJ,CAAY;AAAA,EAAOP,GAAUS,EAAc,IAAI,CAAC;AAAA,EAC5D,CAEO,SAASG,IAA4D,CAC1E,GAAI,OAAO,SAAa,IACtB,OAAO,KAGT,IAAMC,EAAU,gCACVC,EAAW,SAAS,eAAeD,CAAO,EAChD,GAAIC,aAAoB,iBACtB,OAAOA,EAGT,IAAMC,EAAQ,SAAS,cAAc,OAAO,EAC5C,OAAAA,EAAM,GAAKF,EACXE,EAAM,YAAcC,GACpB,SAAS,KAAK,YAAYD,CAAK,EACxBA,CACT,CCvEA,SAASE,IAA4B,CACnC,OAAO,OAAO,OAAW,KAAe,OAAO,OAAO,YAAe,UACvE,CAEO,SAASC,IAAiC,CAC/C,OAAKD,GAAiB,EAKpB,OAAO,WAAW,mBAAmB,EAAE,SACvC,OAAO,WAAW,uBAAuB,EAAE,QALpC,EAOX,CAEO,SAASE,GACdC,EAAwB,OAAO,OAAW,IAAc,OAAO,WAAa,KACnD,CACzB,IAAMC,EAAgBH,GAAsB,EACtCI,EAAUF,GAAiB,MAA0BC,EAE3D,MAAO,CACL,cAAAA,EACA,QAAAC,CACF,CACF,CChCA,IAAIC,GAAoB,GAExB,SAASC,GAA2BC,EAA0C,CAC5E,IAAMC,GAAcD,GAAS,IAAI,KAAK,EACtC,OAAKC,EACE,mBAAmBA,CAAU,EADZ,EAE1B,CAEO,SAASC,GAA8BF,EAAwC,CACpFF,GAAoBC,GAA2BC,CAAK,CACtD,CAEO,SAASG,GAAyBC,EAAyB,CAChE,OAAKN,GAGE,GAAGM,CAAO,KAAKN,EAAiB,GAF9BM,CAGX,CCQA,IAAMC,GAA4B,uBAC5BC,GAAgC,IAChCC,GAAsC,GACtCC,GAAqB,mBACrBC,GAA2B,8BAEjC,SAASC,GAAaC,EAAmD,CACvE,GAAI,CAACA,EAAQ,MAAO,GAEpB,IAAMC,EAAkB,CAAC,EACzB,OAAID,EAAO,SAASC,EAAM,KAAK,MAAM,EACjCD,EAAO,QAAQC,EAAM,KAAK,KAAK,EAC/BD,EAAO,UAAUC,EAAM,KAAK,OAAO,EACnCD,EAAO,SAASC,EAAM,KAAK,MAAM,EACrCA,EAAM,KAAKD,EAAO,IAAI,SAAW,EAAIA,EAAO,IAAI,YAAY,EAAIA,EAAO,GAAG,EACnEC,EAAM,KAAK,GAAG,CACvB,CAEO,IAAMC,GAAN,KAAyB,CAc9B,aAAc,CAPd,KAAQ,QAAkC,IAAI,IAC9C,KAAQ,UAAqB,GAC7B,KAAQ,gBAA2B,GAMjCC,GAAiC,EACjC,KAAK,6BAA6B,EAClC,KAAK,YAAc,KAAK,gBAAgB,EACxC,KAAK,aAAe,IAAM,CACxB,OAAO,sBAAsB,IAAM,KAAK,qBAAqB,CAAC,CAChE,EACA,KAAK,cAAiBC,GAAyB,CAC7C,IAAMC,EAASD,EAAM,OAEnBC,IACCA,aAAkB,kBACjBA,aAAkB,qBAClBA,aAAkB,mBAClBA,EAAO,oBAKTD,EAAM,UACN,CAACA,EAAM,SACP,CAACA,EAAM,QACP,CAACA,EAAM,SACPA,EAAM,OAAS,SAEfA,EAAM,eAAe,EACrB,KAAK,aAAa,CAAC,KAAK,SAAS,EAErC,EACA,OAAO,iBAAiB,UAAW,KAAK,aAAa,EACrD,OAAO,iBAAiB,SAAU,KAAK,YAAY,EACnD,KAAK,KAAO,SAAS,cAAc,KAAK,EACxC,KAAK,KAAK,aAAa,YAAa,EAAE,EACtC,KAAK,KAAK,aAAa,iBAAkB,EAAE,EAC3C,KAAK,KAAK,aAAa,iBAAkB,KAAK,YAAY,UAAY,OAAS,OAAO,EACtF,KAAK,WAAa,KAAK,iBAAiB,EACxC,KAAK,UAAY,SAAS,cAAc,KAAK,EAC7C,KAAK,UAAU,aAAa,sBAAuB,EAAE,EACrD,KAAK,UAAY,SAAS,cAAc,KAAK,EAC7C,KAAK,UAAU,aAAa,uBAAwB,EAAE,EACtD,KAAK,aAAe,KAAK,gBAAgB,EACzC,KAAK,aAAa,aAAa,+BAAgC,EAAE,EACjE,KAAK,WAAa,SAAS,cAAc,KAAK,EAC9C,KAAK,WAAW,aAAa,gCAAiC,EAAE,EAChE,KAAK,WAAW,MAAQ,cACxB,IAAME,EAAU,SAAS,cAAc,MAAM,EAC7CA,EAAQ,YAAc,IACtB,KAAK,WAAW,YAAYA,CAAO,EACnC,KAAK,KAAK,YAAY,KAAK,UAAU,EACrC,KAAK,UAAU,YAAY,KAAK,SAAS,EACzC,KAAK,UAAU,YAAY,KAAK,YAAY,EAC5C,KAAK,UAAU,YAAY,KAAK,UAAU,EAC1C,KAAK,KAAK,YAAY,KAAK,SAAS,GACnC,SAAS,MAAQ,SAAS,iBAAiB,YAAY,KAAK,IAAI,EACjE,KAAK,aAAa,KAAK,YAAY,UAAW,EAAK,CACrD,CAEA,IAAIC,EAA2C,CAC7C,GAAI,KAAK,QAAQ,IAAIA,EAAW,EAAE,EAChC,OAGF,KAAK,uBAAuBA,CAAU,EAEtC,IAAMC,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,KAAO,SACdA,EAAO,aAAa,YAAa,EAAE,EACnCA,EAAO,aAAa,mBAAoB,EAAE,EAC1CA,EAAO,aAAa,2BAA4B,EAAE,EAClDA,EAAO,aAAa,oBAAqBD,EAAW,EAAE,EACtD,IAAME,EAAcV,GAAaQ,EAAW,MAAM,EAC5CG,EAAcD,EAAc,GAAGF,EAAW,KAAK,KAAKE,CAAW,IAAMF,EAAW,MACtFC,EAAO,aAAa,aAAcE,CAAW,EAC7CF,EAAO,UAAYG,EAAoB,GAAIJ,EAAW,IAAI,EAC1DC,EAAO,MAAQE,EACfF,EAAO,iBAAiB,QAAS,IAAM,CACrC,IAAMI,EAAa,CAACL,EAAW,SAAS,EAAE,OAE1C,GADAA,EAAW,UAAUK,CAAU,EAC3B,CAACL,EAAW,UAAW,CACzB,IAAMM,EAAYN,EAAW,SAAS,EACtC,KAAK,aAAaC,EAAQD,EAAW,MAAOA,EAAW,OAAQM,CAAS,EACxE,KAAK,mBAAmBN,EAAW,GAAIM,EAAU,MAAM,CACzD,CACF,CAAC,EAED,IAAMC,EAAO,SAAS,cAAc,KAAK,EACzCA,EAAK,aAAa,YAAa,EAAE,EACjCA,EAAK,aAAa,sBAAuB,EAAE,EAC3CA,EAAK,aAAa,sBAAuBP,EAAW,EAAE,EACtDO,EAAK,YAAYN,CAAM,EAEvB,IAAIO,EAAmC,KACnCR,EAAW,WAAaA,EAAW,UAAU,OAAS,IACxDO,EAAK,aAAa,sBAAuB,EAAE,EAC3CC,EAAY,KAAK,oBAAoBR,CAAU,GAGjD,IAAMS,EAA6B,CAAC,EAChCD,GACFC,EAAQ,KAAK,GAAG,KAAK,gBAAgBF,EAAMC,CAAS,CAAC,EAGvD,IAAME,EAAcV,EAAW,UAC3BA,EAAW,UAAWW,GAAU,CAC9B,KAAK,aAAaV,EAAQD,EAAW,MAAOA,EAAW,OAAQW,CAAK,EACpE,KAAK,kBAAkBJ,EAAMC,EAAWG,EAAM,MAAM,EACpD,KAAK,mBAAmBX,EAAW,GAAIW,EAAM,MAAM,CACrD,CAAC,EACD,KAEJ,KAAK,QAAQ,IAAIX,EAAW,GAAI,CAAE,WAAAA,EAAY,OAAAC,EAAQ,KAAAM,EAAM,UAAAC,EAAW,YAAAE,EAAa,QAAAD,CAAQ,CAAC,EAC7F,KAAK,UAAU,YAAYF,CAAI,EAC/B,KAAK,YAAY,EACjB,IAAMK,EAAeZ,EAAW,SAAS,EACzC,KAAK,aAAaC,EAAQD,EAAW,MAAOA,EAAW,OAAQY,CAAY,EAC3E,KAAK,kBAAkBL,EAAMC,EAAWI,EAAa,MAAM,EAC3D,KAAK,mBAAmBZ,EAAW,GAAIY,EAAa,MAAM,CAC5D,CAEQ,gBAAgBL,EAAsBM,EAA0C,CACtF,IAAMJ,EAA6B,CAAC,GACnC,SAAS,MAAQ,SAAS,iBAAiB,YAAYI,CAAK,EAE7D,IAAIC,EAAO,GACPC,EAAgC,KAChCC,EAAoC,KACpCC,EAAkB,EAClBC,EAAkB,EAClBC,EAAoB,GAClBC,EAAWC,GAAkB,CAC7BP,IAASO,IACbP,EAAOO,EACPR,EAAM,aAAa,YAAaQ,EAAO,OAAS,OAAO,EACnDA,GAAM,KAAK,kBAAkBd,EAAMM,CAAK,EAC9C,EAEMS,EAAY,IAAMC,GAA2B,OAAO,UAAU,EAAE,QAChEC,EAAiB,IAAM,CACvBT,IAAmB,OACrB,OAAO,aAAaA,CAAc,EAClCA,EAAiB,MAEnBC,EAAqB,IACvB,EACMS,EAAmB,IAAM,CAC7BD,EAAe,EACVL,GACL,OAAO,WAAW,IAAM,CACtBA,EAAoB,EACtB,EAAG,CAAC,CACN,EAEMO,EAAgB,IAAM,CAC1B,OAAO,WAAW,IAAM,CAClBnB,EAAK,QAAQ,QAAQ,GAAKM,EAAM,QAAQ,QAAQ,GACpDO,EAAQ,EAAK,CACf,EAAG,EAAE,CACP,EAEMO,EAAqB,IAAM,CAC1BL,EAAU,GAAGF,EAAQ,EAAI,CAChC,EACAb,EAAK,iBAAiB,eAAgBoB,CAAkB,EACxDlB,EAAQ,KAAK,IAAMF,EAAK,oBAAoB,eAAgBoB,CAAkB,CAAC,EAC/E,IAAMC,EAAqB,IAAM,CAC1BN,EAAU,GAAGI,EAAc,CAClC,EACAnB,EAAK,iBAAiB,eAAgBqB,CAAkB,EACxDnB,EAAQ,KAAK,IAAMF,EAAK,oBAAoB,eAAgBqB,CAAkB,CAAC,EAC/E,IAAMC,EAAsB,IAAM,CAC3BP,EAAU,GAAGF,EAAQ,EAAI,CAChC,EACAP,EAAM,iBAAiB,eAAgBgB,CAAmB,EAC1DpB,EAAQ,KAAK,IAAMI,EAAM,oBAAoB,eAAgBgB,CAAmB,CAAC,EACjF,IAAMC,EAAsB,IAAM,CAC3BR,EAAU,GAAGI,EAAc,CAClC,EACAb,EAAM,iBAAiB,eAAgBiB,CAAmB,EAC1DrB,EAAQ,KAAK,IAAMI,EAAM,oBAAoB,eAAgBiB,CAAmB,CAAC,EACjF,IAAMC,EAAmB,IAAMX,EAAQ,EAAK,EAC5CP,EAAM,iBAAiB,mCAAoCkB,CAAgB,EAC3EtB,EAAQ,KAAK,IAAMI,EAAM,oBAAoB,mCAAoCkB,CAAgB,CAAC,EAClG,IAAMC,EAAqBnC,GAAwB,CAC5CyB,EAAU,IAEbzB,EAAM,kBAAkB,aACxBA,EAAM,OAAO,QAAQ,4BAA4B,IAInD2B,EAAe,EACfR,EAAqBnB,EAAM,UAC3BoB,EAAkBpB,EAAM,QACxBqB,EAAkBrB,EAAM,QACxBkB,EAAiB,OAAO,WAAW,IAAM,CACvCA,EAAiB,KACjBI,EAAoB,GACpBC,EAAQ,EAAI,CACd,EAAGhC,EAA6B,GAClC,EACAmB,EAAK,iBAAiB,cAAeyB,CAAiB,EACtDvB,EAAQ,KAAK,IAAMF,EAAK,oBAAoB,cAAeyB,CAAiB,CAAC,EAC7E,IAAMC,EAAqBpC,GAAwB,CACjD,GAAI,CAACyB,EAAU,GAAKP,IAAmB,MAAQlB,EAAM,YAAcmB,EACjE,OAEF,IAAMkB,EAAY,KAAK,IAAIrC,EAAM,QAAUoB,CAAe,EACpDkB,EAAY,KAAK,IAAItC,EAAM,QAAUqB,CAAe,GAExDgB,EAAY7C,IACZ8C,EAAY9C,KAEZmC,EAAe,CAEnB,EACAjB,EAAK,iBAAiB,cAAe0B,CAAiB,EACtDxB,EAAQ,KAAK,IAAMF,EAAK,oBAAoB,cAAe0B,CAAiB,CAAC,EAC7E1B,EAAK,iBAAiB,YAAakB,CAAgB,EACnDhB,EAAQ,KAAK,IAAMF,EAAK,oBAAoB,YAAakB,CAAgB,CAAC,EAC1ElB,EAAK,iBAAiB,gBAAiBkB,CAAgB,EACvDhB,EAAQ,KAAK,IAAMF,EAAK,oBAAoB,gBAAiBkB,CAAgB,CAAC,EAC9E,IAAMW,EAA4B,IAAM,CAClCd,EAAU,GAAGE,EAAe,CAClC,EACAjB,EAAK,iBAAiB,eAAgB6B,CAAyB,EAC/D3B,EAAQ,KAAK,IAAMF,EAAK,oBAAoB,eAAgB6B,CAAyB,CAAC,EACtF,IAAMC,EAAqBxC,GAAiB,CACtC,CAACyB,EAAU,GAAK,CAACH,GACrBtB,EAAM,eAAe,CACvB,EACAU,EAAK,iBAAiB,cAAe8B,CAAiB,EACtD5B,EAAQ,KAAK,IAAMF,EAAK,oBAAoB,cAAe8B,CAAiB,CAAC,EAC7E,IAAMC,EAAqBzC,GAAiB,CACrCyB,EAAU,GACfzB,EAAM,eAAe,CACvB,EACAU,EAAK,iBAAiB,cAAe+B,CAAiB,EACtD7B,EAAQ,KAAK,IAAMF,EAAK,oBAAoB,cAAe+B,CAAiB,CAAC,EAC7E,IAAMC,EAAsB1C,GAAiB,CACvC,CAACyB,EAAU,GAAK,CAACH,IACrBA,EAAoB,GACpBtB,EAAM,eAAe,EACrBA,EAAM,yBAAyB,EACjC,EACAU,EAAK,iBAAiB,QAASgC,EAAoB,EAAI,EACvD9B,EAAQ,KAAK,IAAMF,EAAK,oBAAoB,QAASgC,EAAoB,EAAI,CAAC,EAC9E1B,EAAM,iBAAiB,cAAeY,CAAgB,EACtDhB,EAAQ,KAAK,IAAMI,EAAM,oBAAoB,cAAeY,CAAgB,CAAC,EAC7EZ,EAAM,iBAAiB,gBAAiBY,CAAgB,EACxDhB,EAAQ,KAAK,IAAMI,EAAM,oBAAoB,gBAAiBY,CAAgB,CAAC,EAC/E,IAAMe,EAAsB3C,GAAiB,CACtCyB,EAAU,GACfzB,EAAM,eAAe,CACvB,EACAgB,EAAM,iBAAiB,cAAe2B,CAAkB,EACxD/B,EAAQ,KAAK,IAAMI,EAAM,oBAAoB,cAAe2B,CAAkB,CAAC,EAC/E,IAAMC,EAAsB5C,GAAiB,CACtCyB,EAAU,GACfzB,EAAM,eAAe,CACvB,EACAgB,EAAM,iBAAiB,cAAe4B,CAAkB,EACxDhC,EAAQ,KAAK,IAAMI,EAAM,oBAAoB,cAAe4B,CAAkB,CAAC,EAC/E,IAAMC,EAAe,IAAM,CACzBvB,EAAoB,EACtB,EACAN,EAAM,iBAAiB,QAAS6B,CAAY,EAC5CjC,EAAQ,KAAK,IAAMI,EAAM,oBAAoB,QAAS6B,CAAY,CAAC,EACnE,IAAMC,EAAyB9C,GAAwB,CACrD,GAAI,CAACiB,EAAM,OACX,IAAMhB,EAASD,EAAM,OACfC,aAAkB,OACpBS,EAAK,SAAST,CAAM,GAAKe,EAAM,SAASf,CAAM,GAClDsB,EAAQ,EAAK,EACf,EACA,SAAS,iBAAiB,cAAeuB,CAAqB,EAC9DlC,EAAQ,KAAK,IAAM,SAAS,oBAAoB,cAAekC,CAAqB,CAAC,EAErF,IAAMC,EAAiB,IAAI,iBAAiB,IAAM,CAC3C/B,EAAM,cAAc,sBAAsB,GAAGa,EAAc,CAClE,CAAC,EACDkB,EAAe,QAAQ/B,EAAO,CAC5B,QAAS,GACT,WAAY,GACZ,gBAAiB,CAAC,aAAa,CACjC,CAAC,EACDJ,EAAQ,KAAK,IAAMmC,EAAe,WAAW,CAAC,EAE9C,IAAMC,EAAa,IAAM,CACnB/B,GAAM,KAAK,kBAAkBP,EAAMM,CAAK,CAC9C,EACA,cAAO,iBAAiB,SAAUgC,CAAU,EAC5C,OAAO,iBAAiB,SAAUA,EAAY,EAAI,EAClDpC,EAAQ,KAAK,IAAM,OAAO,oBAAoB,SAAUoC,CAAU,CAAC,EACnEpC,EAAQ,KAAK,IAAM,OAAO,oBAAoB,SAAUoC,EAAY,EAAI,CAAC,EAEzEhC,EAAM,aAAa,YAAa,OAAO,EACvCJ,EAAQ,KAAK,IAAMI,EAAM,OAAO,CAAC,EAC1BJ,CACT,CAEQ,kBAAkBF,EAAsBM,EAA6B,CAC3E,IAAMiC,EAAOvC,EAAK,sBAAsB,EACpCgB,GAA2B,OAAO,UAAU,EAAE,SAChDV,EAAM,MAAM,KAAO,GAAG,KAAK,MAAMiC,EAAK,MAAQ,CAAC,CAAC,KAChDjC,EAAM,MAAM,IAAM,GAAG,KAAK,MAAMiC,EAAK,IAAMA,EAAK,OAAS,CAAC,CAAC,KAC3DjC,EAAM,MAAM,OAAS,KAErBA,EAAM,MAAM,KAAO,GAAG,KAAK,MAAMiC,EAAK,KAAOA,EAAK,MAAQ,CAAC,CAAC,KAC5DjC,EAAM,MAAM,IAAM,GAClBA,EAAM,MAAM,OAAS,GAAG,KAAK,MAAM,OAAO,YAAciC,EAAK,IAAM,CAAC,CAAC,KAEzE,CAEQ,oBAAoB9C,EAAqD,CAC/E,IAAMa,EAAQ,SAAS,cAAc,KAAK,EAC1CA,EAAM,aAAa,YAAa,EAAE,EAClCA,EAAM,aAAa,4BAA6B,EAAE,EAClDA,EAAM,aAAa,qBAAsB,OAAO,EAChD,QAAWkC,KAAc/C,EAAW,WAAa,CAAC,EAAG,CACnD,IAAMgD,EAAgC,CACpC,YAAa,GACb,2BAA4B,GAC5B,oBAAqBD,EAAW,GAChC,cAAe,QACf,qBAAsB,OACxB,EAIA,GAHIA,EAAW,oBACbC,EAAMD,EAAW,iBAAiB,EAAI,IAEpCA,EAAW,WACb,OAAW,CAACE,EAAKC,CAAK,IAAK,OAAO,QAAQH,EAAW,UAAU,EACzDG,GAAU,MAA+BA,IAAU,KACvDF,EAAMC,CAAG,EAAIC,IAAU,GAAO,GAAK,OAAOA,CAAK,GAGnD,IAAMC,EAAQC,GAAe,CAC3B,KAAML,EAAW,KACjB,KAAM,GACN,MAAOA,EAAW,MAClB,UAAW,CAAC,QAAQ,EACpB,MAAAC,CACF,CAAC,EACDG,EAAM,iBAAiB,cAAgBtD,GAAU,CAC/CA,EAAM,gBAAgB,CACxB,CAAC,EACDsD,EAAM,iBAAiB,QAAUtD,GAAU,CACzCA,EAAM,gBAAgB,EACjBG,EAAW,SAAS,EAAE,QACzBA,EAAW,UAAU,EAAI,EAE3B+C,EAAW,QAAQI,CAAK,EACxBA,EAAM,aAAa,cAAe,OAAO,EACzCA,EAAM,cAAc,IAAI,YAAY,mCAAoC,CAAE,QAAS,EAAK,CAAC,CAAC,CAC5F,CAAC,EACDtC,EAAM,YAAYsC,CAAK,CACzB,CACA,OAAOtC,CACT,CAEA,OAAOwC,EAAkB,CACvB,IAAMC,EAAQ,KAAK,QAAQ,IAAID,CAAE,EACjC,GAAKC,EAEL,CAAAA,EAAM,cAAc,EACpB,QAAW7C,KAAW6C,EAAM,QAAS7C,EAAQ,EAC7C6C,EAAM,KAAK,OAAO,EAClB,KAAK,QAAQ,OAAOD,CAAE,EACxB,CAEA,SAAgB,CACd,OAAO,oBAAoB,UAAW,KAAK,aAAa,EACxD,OAAO,oBAAoB,SAAU,KAAK,YAAY,EACtD,QAAWC,KAAS,KAAK,QAAQ,OAAO,EAAG,CACzCA,EAAM,cAAc,EACpB,QAAW7C,KAAW6C,EAAM,QAAS7C,EAAQ,EAC7C6C,EAAM,KAAK,OAAO,CACpB,CACA,KAAK,QAAQ,MAAM,EACnB,KAAK,KAAK,OAAO,CACnB,CAEQ,8BAAqC,CAC3C,SAAS,iBAAiBhE,EAAkB,EAAE,QAASiE,GAASA,EAAK,OAAO,CAAC,EAC7E,SAAS,iBAAiBhE,EAAwB,EAAE,QAASgE,GAASA,EAAK,OAAO,CAAC,CACrF,CAEA,OAAOC,EAAmB,CACxB,IAAMC,EAAO,KAAK,WAAW,cAAc,MAAM,EAC7CA,IAAMA,EAAK,YAAc,OAAO,KAAK,IAAI,EAAG,KAAK,MAAMD,CAAG,CAAC,CAAC,EAClE,CAEQ,aAAoB,CAC1B,IAAME,EAAU,MAAM,KAAK,KAAK,QAAQ,OAAO,CAAC,EAAE,KAAK,CAACC,EAAMC,IAAU,CACtE,IAAMC,EAAYF,EAAK,WAAW,OAAS,EACrCG,EAAaF,EAAM,WAAW,OAAS,EAC7C,OAAIC,IAAcC,EACTD,EAAYC,EAEdH,EAAK,WAAW,MAAM,cAAcC,EAAM,WAAW,KAAK,CACnE,CAAC,EAED,KAAK,UAAU,UAAY,GAC3B,KAAK,UAAU,YAAY,KAAK,gBAAgB,CAAC,EAEjD,IAAIG,EACJ,QAAWT,KAASI,EAAS,CAC3B,IAAMM,EAAeV,EAAM,WAAW,MAClCS,IAAc,QAAaC,IAAiBD,GAC9C,KAAK,UAAU,YAAY,KAAK,gBAAgB,CAAC,EAEnDA,EAAYC,EACZ,KAAK,UAAU,YAAYV,EAAM,IAAI,CACvC,CAEA,KAAK,aAAa,MAAM,QAAUI,EAAQ,OAAS,EAAI,QAAU,OACjE,KAAK,oBAAoB,CAC3B,CAEQ,iBAAmC,CACzC,IAAMO,EAAM,SAAS,cAAc,MAAM,EACzC,OAAAA,EAAI,aAAa,4BAA6B,EAAE,EACzCA,CACT,CAEQ,kBAAsC,CAC5C,IAAMhE,EAAS,SAAS,cAAc,QAAQ,EAC9C,OAAAA,EAAO,KAAO,SACdA,EAAO,aAAa,YAAa,EAAE,EACnCA,EAAO,aAAa,mBAAoB,EAAE,EAC1CA,EAAO,aAAa,yBAA0B,EAAE,EAChDA,EAAO,aAAa,2BAA4B,EAAE,EAClDA,EAAO,aAAa,iBAAkB,KAAK,YAAY,UAAY,OAAS,OAAO,EACnFA,EAAO,aAAa,aAAc,mBAAmB,EACrDA,EAAO,UAAY;AAAA,QACfG,EAAoB,GAAI,MAAM,CAAC;AAAA,QAC/BA,EAAoB,GAAI,aAAa,CAAC;AAAA,MAE1CH,EAAO,iBAAiB,QAAS,IAAM,CACrC,KAAK,aAAa,CAAC,KAAK,SAAS,CACnC,CAAC,EACMA,CACT,CAEQ,aAAaiE,EAAoBC,EAAmB,GAAY,CAQtE,GAPA,KAAK,UAAYD,EACjB,KAAK,KAAK,aAAa,iBAAkBA,EAAY,OAAS,OAAO,EACrE,KAAK,WAAW,aAAa,iBAAkBA,EAAY,OAAS,OAAO,EAC3E,KAAK,WAAW,aACd,aACAA,EAAY,yBAA2B,0BACzC,EACIA,EAAW,CACb,KAAK,gBAAkB,GACvB,QAAWZ,KAAS,KAAK,QAAQ,OAAO,EAClCA,EAAM,WAAW,SAAS,EAAE,QAC9BA,EAAM,WAAW,UAAU,EAAK,EAGpC,KAAK,gBAAkB,EACzB,KAAO,CACL,KAAK,gBAAkB,GACvB,QAAWA,KAAS,KAAK,QAAQ,OAAO,EACxB,KAAK,YAAY,OAAOA,EAAM,WAAW,EAAE,IAC3C,IACZA,EAAM,WAAW,UAAU,EAAI,EAGnC,KAAK,gBAAkB,EACzB,CACIa,IACF,KAAK,YAAY,UAAYD,EAC7B,KAAK,gBAAgB,GAEvB,KAAK,oBAAoB,CAC3B,CAEQ,qBAA4B,CAClC,IAAME,EAAU7C,GAA2B,OAAO,UAAU,EAAE,QACxD8C,EAAcD,EAAU,KAAK,UAAU,aAAe,KAAK,UAAU,YAC3E,KAAK,UAAU,MAAM,UAAYA,EAAW,KAAK,UAAY,MAAQ,GAAGC,CAAW,KAAQ,GAC3F,KAAK,UAAU,MAAM,SAAWD,EAAU,GAAK,KAAK,UAAY,MAAQ,GAAGC,CAAW,KACtF,KAAK,UAAU,MAAM,QAAU,KAAK,UAAY,IAAM,IACtD,KAAK,UAAU,MAAM,cAAgB,KAAK,UAAY,OAAS,MACjE,CAEQ,sBAA6B,CACnC,KAAK,oBAAoB,EACzB,QAAWf,KAAS,KAAK,QAAQ,OAAO,EACjCA,EAAM,WACPA,EAAM,UAAU,aAAa,WAAW,IAAM,QAClD,KAAK,kBAAkBA,EAAM,KAAMA,EAAM,SAAS,CAEtD,CAEQ,aACNrD,EACAqE,EACA7E,EACAkB,EACM,CACN,IAAMT,EAAcV,GAAaC,CAAM,EACjC8E,EAAkBrE,EAAc,GAAGoE,CAAK,KAAKpE,CAAW,IAAMoE,EACpErE,EAAO,aAAa,cAAeU,EAAM,OAAS,OAAS,OAAO,EAClEV,EAAO,aAAa,aAAc,GAAGsE,CAAe,KAAK5D,EAAM,OAAS,KAAO,KAAK,EAAE,EACtFV,EAAO,MAAQ,GAAGsE,CAAe,KAAK5D,EAAM,OAAS,KAAO,KAAK,EACnE,CAEQ,kBACNJ,EACAM,EACA2D,EACM,CACN,IAAMtB,EAAQsB,EAAS,OAAS,QAEhC,GADAjE,EAAK,aAAa,cAAe2C,CAAK,EAClC,EAACrC,EAEL,CAAAA,EAAM,aAAa,qBAAsBqC,CAAK,EAC9C,QAAWC,KAAStC,EAAM,iBAA8B,4BAA4B,EAClFsC,EAAM,aAAa,qBAAsBD,CAAK,EAC9CC,EAAM,aAAa,gBAAiBqB,EAAS,QAAU,MAAM,EAEjE,CAEQ,uBAAuBxE,EAA2C,CACxE,IAAMyE,EAAQ,KAAK,YAAY,OAAOzE,EAAW,EAAE,EACnD,GAAI,OAAOyE,GAAU,UACnB,OAIF,IAAMC,EAAe,KAAK,UAAY,GAAQD,EAC1CC,IAAiB1E,EAAW,SAAS,EAAE,QAI3CA,EAAW,UAAU0E,CAAY,CACnC,CAEQ,mBAAmBrB,EAAYmB,EAAuB,CACxD,KAAK,iBAGL,KAAK,YACT,KAAK,YAAY,OAAOnB,CAAE,EAAImB,EAC9B,KAAK,gBAAgB,EACvB,CAEQ,iBAAmC,CACzC,GAAI,CACF,IAAMG,EAAM,aAAa,QAAQ,KAAK,cAAc,EACpD,GAAI,CAACA,EACH,MAAO,CAAE,UAAW,GAAO,OAAQ,CAAC,CAAE,EAGxC,IAAMC,EAAS,KAAK,MAAMD,CAAG,EAC7B,MAAO,CACL,UAAWC,EAAO,YAAc,GAChC,OAAQA,EAAO,QAAU,OAAOA,EAAO,QAAW,SAAWA,EAAO,OAAS,CAAC,CAChF,CACF,MAAQ,CACN,MAAO,CAAE,UAAW,GAAO,OAAQ,CAAC,CAAE,CACxC,CACF,CAEQ,iBAAwB,CAC9B,GAAI,CACF,aAAa,QAAQ,KAAK,eAAgB,KAAK,UAAU,KAAK,WAAW,CAAC,CAC5E,MAAQ,CAER,CACF,CAEA,IAAY,gBAAyB,CACnC,OAAOC,GAAyB1F,EAAyB,CAC3D,CACF,ECrnBO,IAAM2F,GAAN,KAAsB,CAAtB,cACL,KAAQ,YAAoD,IAAI,IAChE,KAAQ,KAAkC,KAE1C,SAASC,EAAkD,CACrD,CAACA,GAAc,KAAK,YAAY,IAAIA,EAAW,EAAE,IAIrD,KAAK,YAAY,IAAIA,EAAW,GAAIA,CAAU,EACzC,KAAK,OACR,KAAK,KAAO,IAAIC,IAElB,KAAK,KAAK,IAAID,CAAU,EAC1B,CAEA,OAAOE,EAAmB,CACxB,KAAK,MAAM,OAAOA,CAAG,CACvB,CAEA,SAAgB,CACd,KAAK,YAAY,MAAM,EACvB,KAAK,MAAM,QAAQ,EACnB,KAAK,KAAO,IACd,CACF,ECvBO,IAAMC,GAAN,cAA6BC,CAAa,CAC/C,YAAYC,EAAwB,CAClC,MAAMA,CAAO,EACb,KAAK,QAAU,UACjB,CAEA,kBAAkBC,EAA4B,CAC5C,IAAIC,EAAiBD,EAAO,YAAY,iBAAiB,EACzD,GAAIC,GAAkB,MAAQA,GAAkB,GAAI,CAClDD,EAAO,YAAY,kBAAmB,QAAQ,EAC9C,IAAIE,EAAcC,GAAiB,CACjC,KAAK,OAAO,KAAK,QAASA,CAAK,CACjC,EACAH,EAAO,YAAY,uBAAwBE,CAAU,EACrDF,EAAO,YAAY,iBAAiB,QAASE,CAAU,CACzD,CACF,CACA,qBAAqBF,EAA4B,CAC/CA,EAAO,YAAY,kBAAmB,EAAE,EACxCA,EAAO,YAAY,oBAAoB,QAASA,EAAO,YAAY,sBAAsB,CAAC,CAC5F,CACF,ECEO,IAAMI,GAAN,cAAoCC,CAAa,CAYtD,YAAYC,EAAwB,CAClC,MAAMA,CAAO,EATf,KAAQ,OAAS,IAAI,QAUnB,KAAK,QAAU,mBACf,KAAK,gBAAgB,KAAK,CAAE,IAAK,OAAQ,KAAM,SAAU,SAAU,EAAI,CAAC,CAC1E,CAQS,kBAAkBC,EAA4B,CACrD,MAAM,kBAAkBA,CAAM,EAC9B,IAAMC,EAAKD,EAAO,YAEd,iBAAiBC,CAAE,EAAE,YAAc,YACrCA,EAAG,MAAM,UAAY,QAGvB,IAAMC,EAA8B,CAClC,QAASD,EAAG,UACZ,OAAQA,EAAG,UACX,UAAWA,EAAG,aAAeA,EAAG,aAChC,SAAU,EACV,KAAMD,EAAO,YAAoB,MAAM,GAAK,GAC5C,WAAY,GACZ,SAAU,EACZ,EAEA,KAAK,OAAO,IAAIC,EAAIC,CAAK,EAEzBD,EAAG,iBAAiB,QAAUE,GAAM,KAAK,YAAYA,EAAGF,EAAIC,CAAK,EAAG,CAAE,QAAS,EAAM,CAAC,EACtFD,EAAG,iBAAiB,SAAWE,GAAM,KAAK,eAAeA,EAAGF,EAAIC,CAAK,EAAG,CAAE,QAAS,EAAK,CAAC,EAEzF,KAAK,QAAQD,EAAIC,CAAK,CACxB,CAQS,qBAAqBF,EAA4B,CACxD,KAAK,OAAO,OAAOA,EAAO,WAAW,CACvC,CAQS,QAAQI,EAAwB,CACvC,QAAWJ,KAAU,KAAK,cAAe,CACvC,IAAMC,EAAKD,EAAO,YACZE,EAAQ,KAAK,OAAO,IAAID,CAAE,EAC3BC,GAEDA,EAAM,UAAY,CAACA,EAAM,YAC3B,KAAK,aAAaD,EAAIC,CAAK,CAE/B,CACF,CAMS,UAAiB,CACxB,QAAWF,KAAU,KAAK,cAAe,CACvC,IAAMC,EAAKD,EAAO,YACZE,EAAQ,KAAK,OAAO,IAAID,CAAE,EAC5BC,GACF,KAAK,QAAQD,EAAIC,CAAK,CAE1B,CACF,CAQQ,QAAQD,EAAiBC,EAA6B,CAC5DA,EAAM,UAAYD,EAAG,aAAeA,EAAG,YACzC,CAWQ,YAAYE,EAAeF,EAAiBC,EAA6B,CAC/E,IAAMG,EAAQF,EAAE,OAEVG,EAAgBD,EAAQ,EACxBE,EAAkBF,EAAQ,EAE1BG,EAAQN,EAAM,QAAU,GACxBO,EAAWP,EAAM,QAAUA,EAAM,UAAY,GAE9CI,GAAiBE,GAAWD,GAAmBE,IAIpDN,EAAE,eAAe,EACjBA,EAAE,gBAAgB,EAElBD,EAAM,QAAUG,EAEhBH,EAAM,OAAS,KAAK,IAAI,EAAG,KAAK,IAAIA,EAAM,OAAQA,EAAM,SAAS,CAAC,EAElEA,EAAM,SAAW,GACjBA,EAAM,WAAa,GACrB,CAQS,QAAQC,EAAqB,CACtC,CAUQ,eAAeA,EAAUF,EAAiBC,EAA6B,CACxEA,EAAM,WACTA,EAAM,QAAUD,EAAG,UACnBC,EAAM,OAASD,EAAG,UAEtB,CASQ,aAAaA,EAAiBC,EAA6B,CACjE,IAAMQ,EAAOR,EAAM,OAASA,EAAM,QAE9B,KAAK,IAAIQ,CAAI,EAAI,IACnBR,EAAM,QAAUA,EAAM,OACtBA,EAAM,SAAW,IAEjBA,EAAM,SAAWQ,EAAOR,EAAM,KAGhCD,EAAG,UAAYC,EAAM,OACvB,CACF,EC9MO,SAASS,GAAYC,EAAkE,CAC5F,IAAMC,EAAQD,EAAM,MAAM,8BAA8B,EACxD,OAAKC,EACE,CACL,GAAIA,EAAM,CAAC,EACX,MAAO,WAAWA,EAAM,CAAC,CAAC,EAC1B,IAAK,WAAWA,EAAM,CAAC,CAAC,CAC1B,EALmB,IAMrB,CCHA,SAASC,GAAMC,EAAeC,EAAeC,EAAaC,EAAeC,EAAqB,CAC5F,OAAOD,GAAUC,EAAMD,IAAUH,EAAQC,IAAWC,EAAMD,EAC5D,CAEO,IAAMI,GAAN,cAAiCC,CAAa,CACnD,YAAYC,EAAwB,CAClC,MAAMA,CAAO,EACb,KAAK,QAAU,gBACf,KAAK,gBAAkB,CACrB,GAAG,KAAK,gBACR,CAAE,IAAK,UAAW,KAAM,SAAU,SAAU,EAAG,CACjD,CACF,CAEA,kBAAkBC,EAA4B,CAC5C,IAAIC,EAAWD,EAAO,YAAY,SAAS,EACvCE,EAAaC,GAAYF,CAAkB,EAC/C,GAAIC,EAAY,CACdF,EAAO,YAAY,aAAcE,EAAW,EAAE,EAC9CF,EAAO,YAAY,QAASE,EAAW,KAAK,EAC5CF,EAAO,YAAY,MAAOE,EAAW,GAAG,EACxC,IAAIE,EAAiBC,GAAqB,CACxC,GAAIH,EAAY,CACd,IAAMI,EAAgBf,GAAMc,EAAUH,GAAY,MAAOA,GAAY,IAAK,EAAG,CAAC,EACxEK,EAAkB,KAAK,IAAI,EAAG,KAAK,IAAI,EAAGD,CAAa,CAAC,EAC9DN,EAAO,YAAY,MAAM,YAAY,mBAAoBO,EAAgB,SAAS,CAAC,EACnF,KAAK,OAAO,KAAK,KAAK,mBAAmBP,EAAQ,uBAAuB,EAAGO,CAAe,CAC5F,CACF,EACAP,EAAO,YAAY,iBAAkBI,CAAa,EAClD,KAAK,OAAO,GAAG,mBAAmBF,EAAW,EAAE,GAAIE,CAAa,CAClE,CACF,CAEA,qBAAqBJ,EAA4B,CAC/C,IAAIC,EAAWD,EAAO,YAAY,YAAY,EAC1CC,GACF,KAAK,OAAO,IAAI,mBAAmBA,CAAQ,GAAID,EAAO,YAAiB,gBAAgB,CAAC,CAE5F,CACF,ECxCA,IAAMQ,GAAmB,CAACC,EAAaC,IAAwB,CAC7D,IAAMC,EAAK,KAAK,IAAIF,EAAKC,CAAG,EACtBE,EAAK,KAAK,IAAIH,EAAKC,CAAG,EAC5B,OAAOC,EAAK,KAAK,OAAO,GAAKC,EAAKD,EACpC,EAEME,GAAsB,CAACJ,EAAaC,IAAwB,CAChE,IAAMC,EAAK,KAAK,KAAK,KAAK,IAAIF,EAAKC,CAAG,CAAC,EACjCE,EAAK,KAAK,MAAM,KAAK,IAAIH,EAAKC,CAAG,CAAC,EACxC,OAAIE,EAAKD,EAAWA,EACb,KAAK,MAAM,KAAK,OAAO,GAAKC,EAAKD,EAAK,EAAE,EAAIA,CACrD,EAEMG,GAAkBC,GAAqC,CAC3D,GAAI,MAAM,QAAQA,CAAK,GAAKA,EAAM,QAAU,EAAG,CAC7C,IAAMC,EAAI,OAAOD,EAAM,CAAC,CAAC,EACnBE,EAAI,OAAOF,EAAM,CAAC,CAAC,EACzB,GAAI,OAAO,SAASC,CAAC,GAAK,OAAO,SAASC,CAAC,EAAG,MAAO,CAACD,EAAGC,CAAC,CAC5D,CACA,OAAI,OAAOF,GAAU,UAAY,OAAO,SAASA,CAAK,EAC7C,CAAC,EAAGA,CAAK,EAEX,CAAC,EAAG,CAAC,CACd,EAEaG,GAAN,cAA2BC,CAAa,CAC7C,YAAYC,EAAwB,CAClC,MAAMA,CAAO,EACb,KAAK,QAAU,SACf,KAAK,gBAAgB,KAAK,CACxB,IAAK,gBACL,KAAM,OACN,SAAU,OACZ,CAAC,EACD,KAAK,gBAAgB,KAAK,CACxB,IAAK,cACL,KAAM,SACN,SAAU,KACZ,CAAC,CACH,CAES,kBAAkBC,EAA4B,CACrD,IAAMC,EAAKD,EAAO,YACZE,EAAQT,GAAeO,EAAO,YAAY,eAAe,CAAC,EAE1DN,EADO,OAAOM,EAAO,YAAY,aAAa,GAAK,OAAO,EAAE,YAAY,IAEnE,MACLR,GAAoBU,EAAM,CAAC,EAAGA,EAAM,CAAC,CAAC,EACtCf,GAAiBe,EAAM,CAAC,EAAGA,EAAM,CAAC,CAAC,EAEzCC,EAAS,IAAI,IAAM,CACjBA,EAAS,QAAQF,EAAI,CAAE,WAAYP,CAAM,CAAC,CAC5C,CAAC,CACH,CACF,EC3DO,IAAMU,GAAN,KAA6B,CAQlC,YACmBC,EACAC,EACjB,CAFiB,QAAAD,EACA,YAAAC,EATnB,KAAQ,WAAoC,KAC5C,KAAQ,MAA+B,KACvC,KAAQ,OAAgC,KACxC,KAAQ,UAAgC,KACxC,KAAQ,uBAAyB,GACjC,KAAQ,wBAAyC,IAK9C,CAEI,OAAOC,EAA2C,CACvD,GAAI,KAAK,YAAY,YACnB,OAAIA,GACF,KAAK,kBAAkBA,CAAI,EAEtB,KAAK,WAGd,IAAMC,EAAW,SAAS,cACxB,oCAAoC,KAAK,EAAE,IAC7C,EAEA,GAAIA,EACF,YAAK,WAAaA,EAClB,KAAK,OAASA,EAAS,cACrB,qCAAqC,KAAK,EAAE,IAC9C,EACID,GACF,KAAK,kBAAkBA,CAAI,EAEtBC,EAGT,IAAMC,EAAO,SAAS,cAAc,KAAK,EACzCA,EAAK,aAAa,iCAAkC,KAAK,EAAE,EAC3DA,EAAK,aAAa,6BAA8B,EAAE,EAClDA,EAAK,MAAM,SAAW,QACtBA,EAAK,MAAM,MAAQ,IACnBA,EAAK,MAAM,OAAS,OAAO,KAAK,MAAM,EACtCA,EAAK,MAAM,cAAgB,OAC3BA,EAAK,MAAM,SAAW,SAEtB,IAAMC,EAAS,SAAS,cAAc,KAAK,EAC3C,OAAAA,EAAO,aAAa,kCAAmC,KAAK,EAAE,EAC9DA,EAAO,MAAM,SAAW,WACxBA,EAAO,MAAM,MAAQ,IACrBA,EAAO,MAAM,cAAgB,OAC7BA,EAAO,MAAM,SAAW,SAExBD,EAAK,YAAYC,CAAM,GAEtB,SAAS,MAAQ,SAAS,iBAAiB,YAAYD,CAAI,EAC5D,KAAK,WAAaA,EAClB,KAAK,OAASC,EACd,KAAK,kBAAkBH,GAAQ,SAAS,MAAQ,SAAS,eAAe,EACjEE,CACT,CAEO,YAAoC,CACzC,OAAO,KAAK,YAAY,YAAc,KAAK,WAAa,IAC1D,CAEO,gBAAgBF,EAA2C,CAChE,YAAK,OAAOA,CAAI,EACT,KAAK,KACd,CAEO,kBAAmC,CACxC,YAAK,OAAO,EACL,KAAK,MACd,CAEO,SAAgB,CACrB,KAAK,oBAAoB,EACzB,KAAK,YAAY,OAAO,EACxB,KAAK,WAAa,KAClB,KAAK,OAAO,OAAO,EACnB,KAAK,MAAQ,KACb,KAAK,OAAS,KACd,KAAK,UAAY,IACnB,CAEQ,kBAAkBA,EAAyB,CACjD,GAAI,KAAK,YAAcA,GAAQ,KAAK,OAAO,YACzC,OAMF,GAHA,KAAK,oBAAoB,EACzB,KAAK,UAAYA,EAEb,CAAC,KAAK,MAAO,CACf,IAAMI,EAAQ,SAAS,cAAc,KAAK,EAC1CA,EAAM,aAAa,iCAAkC,KAAK,EAAE,EAC5DA,EAAM,aAAa,6BAA8B,EAAE,EACnDA,EAAM,MAAM,SAAW,WACvBA,EAAM,MAAM,IAAM,IAClBA,EAAM,MAAM,KAAO,IACnBA,EAAM,MAAM,MAAQ,MACpBA,EAAM,MAAM,OAAS,MACrBA,EAAM,MAAM,cAAgB,OAC5BA,EAAM,MAAM,SAAW,UACvBA,EAAM,MAAM,OAAS,OAAO,KAAK,MAAM,EACvC,KAAK,MAAQA,CACf,CAGEJ,IAAS,SAAS,MAClBA,IAAS,SAAS,iBAClB,OAAO,iBAAiBA,CAAI,EAAE,WAAa,WAG3C,KAAK,uBAAyB,GAC9B,KAAK,wBAA0BA,EAAK,MAAM,UAAY,KACtDA,EAAK,MAAM,SAAW,YAGxBA,EAAK,YAAY,KAAK,KAAK,CAC7B,CAEQ,qBAA4B,CAC9B,KAAK,OACP,KAAK,MAAM,OAAO,EAGhB,KAAK,WAAa,KAAK,yBACrB,KAAK,yBAA2B,MAAQ,KAAK,0BAA4B,GAC3E,KAAK,UAAU,MAAM,eAAe,UAAU,EAE9C,KAAK,UAAU,MAAM,SAAW,KAAK,yBAIzC,KAAK,uBAAyB,GAC9B,KAAK,wBAA0B,IACjC,CACF,EClIO,IAAMK,GAAN,MAAMA,EAAyB,CAA/B,cAEL,KAAiB,OAAS,IAAI,IAE9B,OAAc,aAAwC,CACpD,OAAK,KAAK,WACR,KAAK,SAAW,IAAIA,IAEf,KAAK,QACd,CAEO,QAAQC,EAAYC,EAAwC,CACjE,IAAMC,EAAW,KAAK,OAAO,IAAIF,CAAE,EACnC,GAAIE,EAAU,CACZ,GAAIA,EAAS,SAAWD,EACtB,MAAM,IAAI,MACR,0BAA0BD,CAAE,iCAAiCE,EAAS,MAAM,eAAeD,CAAM,GACnG,EAEF,OAAAC,EAAS,MAAQ,EACVA,EAAS,KAClB,CAEA,IAAMC,EAAQ,IAAIC,GAAuBJ,EAAIC,CAAM,EACnD,YAAK,OAAO,IAAID,EAAI,CAAE,MAAAG,EAAO,KAAM,EAAG,OAAAF,CAAO,CAAC,EACvCE,CACT,CAEO,QAAQH,EAAkB,CAC/B,IAAME,EAAW,KAAK,OAAO,IAAIF,CAAE,EAC9BE,IAILA,EAAS,MAAQ,EACb,EAAAA,EAAS,KAAO,KAIpBA,EAAS,MAAM,QAAQ,EACvB,KAAK,OAAO,OAAOF,CAAE,GACvB,CACF,EA1CaD,GACI,SAA4C,KADtD,IAAMM,GAANN,GCgDA,IAAMO,EAAN,cAA8BC,CAA8C,CAWjF,YAAYC,EAAwB,CAClC,MAAMA,CAAO,EARf,KAAmB,gBAAkBC,GAAyB,YAAY,EAE1E,KAAiB,uBAAyB,IAAI,IAC9C,KAAiB,iBAAmB,IAAI,IACxC,KAAQ,cAAyD,KACjE,KAAU,cAAwD,KAIhE,KAAK,MAAQ,EACbC,GAAiC,EAEjC,IAAMC,EAAgB,KAAK,YAAuC,QAC9DA,IACF,KAAK,iBAAiBA,CAAY,EAClC,KAAK,kBAAkBA,EAAa,MAAM,GAG5C,IAAMC,EAAkBD,GAAc,OAChCE,GACH,OAAOD,GAAoB,WAAaA,EAAgB,EAAIA,IAC7D,KAAK,UAAU,EACbC,GACF,KAAK,YAAY,GAAG,KAAK,gBAAgBA,CAAM,CAAC,UAAWA,CAAM,CAErE,CAEA,IAAuB,oBAA8B,CACnD,MAAO,EACT,CAEA,IAAc,gBAAsD,CAClE,OAAQ,KAAK,YAAuC,SAAS,QAC/D,CAEA,WAAWC,EAA+B,CACxC,IAAMC,EAAW,KAAK,eACtB,OAAKA,EAKD,GAAAA,EAAS,SAAW,IAKpBD,EAAO,KAAK,SAAS,aAAa,GAGlCC,EAAS,MAAM,KAAMC,GAAMF,EAAO,KAAK,SAASE,CAAC,CAAC,GAGlDD,EAAS,YAAY,KAAME,GAASH,EAAO,YAAY,aAAaG,CAAI,CAAC,GAdpE,MAAM,WAAWH,CAAM,CAmBlC,CAEU,gBAAgBI,EAA4B,CACpD,IAAMC,EACJ,KAAK,SAAY,KAAK,YAAuC,SAAS,UAAU,OAAO,CAAC,EAC1F,GAAIA,EACF,OAAOA,EAGT,IAAIC,EAAO,EACX,QAASC,EAAI,EAAGA,EAAIH,EAAW,OAAQG,GAAK,EAC1CD,EAAQA,EAAO,GAAKF,EAAW,WAAWG,CAAC,IAAO,EAGpD,MAAO,cAAcD,EAAK,SAAS,EAAE,CAAC,EACxC,CAEU,WAA2B,CACnC,OAAO,IACT,CAEO,sBAAuD,CAC5D,GAAI,CAAC,KAAK,cACR,OAAO,KAGT,IAAME,EAAS,KAAK,cACdC,EAAY,KAAK,oBAAoB,EAC3C,MAAO,CACL,GAAID,EAAO,GACX,MAAOA,EAAO,MACd,KAAMA,EAAO,KACb,MAAOA,EAAO,MACd,MAAOA,EAAO,MACd,OAAQA,EAAO,OACf,UAAWC,EAAU,OAAS,EAAIA,EAAY,OAC9C,SAAU,KAAO,CAAE,OAAQ,KAAK,sBAAsB,CAAE,GACxD,UAAYC,GAAW,CACrB,KAAK,sBAAsBA,CAAM,CACnC,EACA,UAAYC,IACV,KAAK,iBAAiB,IAAIA,CAAQ,EAClCA,EAAS,CAAE,OAAQ,KAAK,sBAAsB,CAAE,CAAC,EAC1C,IAAM,CACX,KAAK,iBAAiB,OAAOA,CAAQ,CACvC,EAEJ,CACF,CAEU,qBAAgG,CACxG,MAAO,CAAC,CACV,CAEU,iBAAiBH,EAA+C,CACxE,KAAK,cAAgBA,CACvB,CAEU,kBAAkBI,EAAoC,CAC1D,OAAO,OAAW,KAAe,CAACA,IAItC,KAAK,cAAiBC,GAAyB,CAC7C,IAAMC,EAASD,EAAM,OAEnBC,IACCA,aAAkB,kBACjBA,aAAkB,qBAClBA,aAAkB,mBAClBA,EAAO,oBAMTD,EAAM,IAAI,YAAY,IAAMD,EAAO,IAAI,YAAY,GACnDC,EAAM,YAAcD,EAAO,UAAY,KACvCC,EAAM,WAAaD,EAAO,SAAW,KACrCC,EAAM,UAAYD,EAAO,QAAU,KACnCC,EAAM,WAAaD,EAAO,SAAW,MAKvCC,EAAM,eAAe,EACrB,KAAK,sBAAsB,CAAC,KAAK,sBAAsB,CAAC,EAC1D,EAEA,OAAO,iBAAiB,UAAW,KAAK,aAAa,EACvD,CAEU,iBAAiBH,EAAkB,KAAK,sBAAsB,EAAS,CAC/E,IAAMK,EAAQ,CAAE,OAAAL,CAAO,EACvB,QAAWC,KAAY,KAAK,iBAC1BA,EAASI,CAAK,CAElB,CAEU,qBAAqBC,EAAYC,EAAwC,CACjF,IAAMC,EAAW,KAAK,uBAAuB,IAAIF,CAAE,EACnD,GAAIE,EACF,OAAOA,EAGT,IAAMC,EAAQ,KAAK,gBAAgB,QAAQH,EAAIC,CAAM,EACrD,YAAK,uBAAuB,IAAID,EAAIG,CAAK,EAClCA,CACT,CAEU,qBAAqBH,EAAkB,CAC1C,KAAK,uBAAuB,IAAIA,CAAE,IAIvC,KAAK,gBAAgB,QAAQA,CAAE,EAC/B,KAAK,uBAAuB,OAAOA,CAAE,EACvC,CAEU,YAAYI,EAAiBC,EAAmC,CACxE,IAAMH,EAAW,SAAS,eAAeE,CAAO,EAChD,GAAIF,aAAoB,iBACtB,OAAOA,EAGT,IAAMI,EAAQ,SAAS,cAAc,OAAO,EAC5C,OAAAA,EAAM,GAAKF,EACXE,EAAM,YAAcD,EACpB,SAAS,KAAK,YAAYC,CAAK,EACxBA,CACT,CAEU,cAA4B,CACpC,OAAO,KAAK,KAAK,OAAO,WAAa,SAAS,MAAQ,SAAS,eACjE,CAEU,uBAAiC,CACzC,MAAO,EACT,CAEU,sBAAsBC,EAAwB,CAAC,CAEzD,SAAgB,CACV,KAAK,gBACP,OAAO,oBAAoB,UAAW,KAAK,aAAa,EACxD,KAAK,cAAgB,MAEvB,KAAK,iBAAiB,MAAM,EAC5B,QAAWP,KAAM,KAAK,uBAAuB,KAAK,EAChD,KAAK,gBAAgB,QAAQA,CAAE,EAEjC,KAAK,uBAAuB,MAAM,EAClC,MAAM,QAAQ,CAChB,CACF,EAxNaxB,EAEJ,QAAwC,KC5B1C,IAAMgC,GAAwC,CAAC,IAAK,IAAK,IAAK,IAAI,EAMzE,IAAMC,GAAqB,CAAC,KAAM,KAAM,IAAK,CAAC,EAMvC,SAASC,GAAeC,EAAeC,EAAgC,CAC5E,IAAMC,EAAaD,EAAQ,EAAID,EAC/B,OAAOG,GAAmBD,CAAU,GAAK,GAC3C,CA+BA,IAAIE,GAAS,EAEN,SAASC,IAA+B,CAC7C,MAAO,QAAQ,KAAK,IAAI,CAAC,IAAID,IAAQ,EACvC,CAEO,SAASE,IAA6B,CAC3C,MAAO,UAAU,KAAK,IAAI,CAAC,IAAIF,IAAQ,EACzC,CAMO,SAASG,GAAqBC,EAAgB,EAA2B,CAC9E,IAAMC,EAAY,KAAK,IAAI,EAAa,KAAK,IAAI,EAAaD,CAAK,CAAC,EAC9DE,EAAwB,CAAC,EAE/B,QAASC,EAAI,EAAGA,EAAIF,EAAWE,IAAK,CAClC,IAAMC,EAAQb,GAAeY,EAAGF,CAAS,EACnCI,EAAWF,IAAMF,EAAY,EAAI,EAAKX,GAAmBa,CAAC,GAAK,EACrED,EAAQ,KAAK,CACX,GAAIJ,GAAmB,EACvB,MAAAM,EACA,SAAAC,EACA,UAAW,CAAC,CACd,CAAC,CACH,CAEA,OAAOH,CACT,CAEO,SAASI,GAA4BC,EAAuB,CACjE,OAAK,OAAO,SAASA,CAAK,EACnB,KAAK,IAAI,EAAG,KAAK,MAAMA,CAAK,CAAC,EADA,CAEtC,CAMO,SAASC,GAAeN,EAA6B,CAC1D,IAAMT,EAAQS,EAAQ,OACtB,QAASC,EAAI,EAAGA,EAAIV,EAAOU,IACzBD,EAAQC,CAAC,EAAE,MAAQZ,GAAeY,EAAGV,CAAK,CAE9C,CC3GA,IAAMgB,GAAiB,eAEvB,SAASC,GAAeC,EAA2B,CACjD,OAAOC,GAAyBH,GAAiBE,CAAS,CAC5D,CAEA,SAASE,GAAqBC,EAAuB,CACnD,GAAI,CAACA,GAAQ,OAAOA,GAAS,SAC3B,MAAO,GAGT,GAAI,MAAM,QAAQA,CAAI,EACpB,OAAOA,EAAK,OAGd,IAAMC,EAASD,EACTE,EAAU,MAAM,QAAQD,EAAO,OAAU,EAAIA,EAAO,QAAa,CAAC,EACpEE,EAAQ,EAEZ,QAAWC,KAAUF,EAAS,CAC5B,GAAI,CAACE,GAAU,OAAOA,GAAW,SAC/B,SAGF,IAAMC,EAAeD,EACfE,EAAY,MAAM,QAAQD,EAAa,SAAY,EACrDA,EAAa,UACb,MAAM,QAAQA,EAAa,KAAQ,EACjCA,EAAa,MACb,CAAC,EACPF,GAASG,EAAU,MACrB,CAEA,OAAOH,CACT,CAWO,IAAMI,GAAN,KAAkB,CAAlB,cACL,KAAQ,gBAA4C,IAAI,IACxD,KAAQ,cAA+C,IAAI,IAE3D,gBAAgBC,EAA4B,CAC1C,KAAK,gBAAgB,IAAIA,EAAQ,KAAMA,CAAO,CAChD,CAEA,WAAWC,EAAuC,CAChD,OAAO,KAAK,gBAAgB,IAAIA,CAAI,CACtC,CAEA,oBAA+C,CAC7C,OAAO,KAAK,eACd,CAEA,WAAWZ,EAAiC,CAC1C,OAAO,KAAK,eAAeA,CAAS,EAAE,OACxC,CAEA,eAAeA,EAA2B,CACxC,OAAO,KAAK,eAAeA,CAAS,EAAE,QAAQ,MAChD,CAEA,oBAAoBA,EAA2B,CAC7C,OAAO,KAAK,eAAeA,CAAS,EAAE,gBACxC,CAEA,cAAcA,EAA2B,CACvC,OAAO,KAAK,eAAeA,CAAS,EAAE,YAAY,KAAK,GAAK,QAC9D,CAEA,uBAAuBA,EAA2B,CAChD,IAAMa,EAAQ,KAAK,eAAeb,CAAS,EAC3C,OAAO,KAAK,mBAAmBa,CAAK,GAAG,OAAS,GAClD,CAEA,oBAAoBb,EAAmBc,EAA+B,CACpE,IAAMD,EAAQ,KAAK,eAAeb,CAAS,EAC3C,OAAO,KAAK,mBAAmBa,EAAOC,CAAa,GAAG,IAAMD,EAAM,QAAQA,EAAM,QAAQ,OAAS,CAAC,EAAE,EACtG,CAEA,qBAAqBb,EAAmC,CACtD,IAAMa,EAAQ,KAAK,eAAeb,CAAS,EAC3C,OAAO,KAAK,mBAAmBa,CAAK,GAAG,WAAa,CAAC,CACvD,CAEA,qBAAqBb,EAAmBc,EAAuC,CAC7E,IAAMD,EAAQ,KAAK,eAAeb,CAAS,EAC3C,OAAO,KAAK,mBAAmBa,EAAOC,CAAa,GAAG,WAAa,CAAC,CACtE,CAOA,UAAUd,EAAsC,CAC9C,IAAMa,EAAQ,KAAK,eAAeb,CAAS,EAC3C,GAAIa,EAAM,QAAQ,QAAU,EAAa,OAAO,KAGhD,IAAME,EAAiBF,EAAM,QAAQ,CAAC,EAChCG,EAAcD,EAChB,KAAK,IAAI,KAAMA,EAAe,SAAW,GAAG,EAC5C,KAEEE,EAAwB,CAC5B,GAAIC,GAAmB,EACvB,MAAO,KACP,SAAUF,EACV,UAAW,CAAC,CACd,EAEA,OAAAH,EAAM,QAAQ,QAAQI,CAAS,EAC/B,KAAK,YAAYJ,CAAK,EACtBM,GAAeN,EAAM,OAAO,EAC5B,KAAK,0BAA0BA,CAAK,EAE/BA,EAAM,QAAQ,KAAMO,GAAMA,EAAE,KAAOP,EAAM,gBAAgB,IAC5DA,EAAM,iBAAmBA,EAAM,QAAQ,CAAC,EAAE,IAG5C,KAAK,KAAKb,CAAS,EACZiB,CACT,CAMA,aAAajB,EAAmBqB,EAA2B,CACzD,IAAMR,EAAQ,KAAK,eAAeb,CAAS,EAC3C,GAAIa,EAAM,QAAQ,QAAU,EAAa,MAAO,GAEhD,IAAMS,EAAQT,EAAM,QAAQ,UAAWO,GAAMA,EAAE,KAAOC,CAAQ,EAC9D,OAAIC,IAAU,GAAW,IAEzBT,EAAM,QAAQ,OAAOS,EAAO,CAAC,EAC7BH,GAAeN,EAAM,OAAO,EAC5B,KAAK,0BAA0BA,CAAK,EAE/BA,EAAM,QAAQ,KAAMO,GAAMA,EAAE,KAAOP,EAAM,gBAAgB,IAC5DA,EAAM,iBAAmBA,EAAM,QAAQA,EAAM,QAAQ,OAAS,CAAC,EAAE,IAGnE,KAAK,KAAKb,CAAS,EACZ,GACT,CAEA,aAAaA,EAAmBqB,EAAkBE,EAAmB,GAAY,CAC/E,IAAMV,EAAQ,KAAK,eAAeb,CAAS,EACtCa,EAAM,QAAQ,KAAMN,GAAWA,EAAO,KAAOc,CAAQ,IAC1DR,EAAM,iBAAmBQ,EACrBE,GAAS,KAAK,KAAKvB,CAAS,EAClC,CAEA,qBACEA,EACAqB,EACAG,EACAD,EAAmB,GACb,CACN,IAAMV,EAAQ,KAAK,eAAeb,CAAS,EACrCO,EAASM,EAAM,QAAQ,KAAMO,GAAMA,EAAE,KAAOC,CAAQ,EACrDd,IAELA,EAAO,SAAWkB,GAA4BD,CAAQ,EACtD,KAAK,YAAYX,CAAK,EACtBM,GAAeN,EAAM,OAAO,EAC5B,KAAK,0BAA0BA,CAAK,EAChCU,GAAS,KAAK,KAAKvB,CAAS,EAClC,CAEA,eACEA,EACAK,EACAqB,EACM,CACN,IAAMC,EAAa,KAAK,iBAAiBtB,CAAO,EAC1CQ,EAA0B,CAC9B,UAAAb,EACA,QAAS2B,EACT,iBAAAD,CACF,EACA,KAAK,qBAAqBb,CAAK,EAC/B,KAAK,cAAc,IAAIb,EAAWa,CAAK,EACvC,KAAK,KAAKb,CAAS,CACrB,CAEA,aAAaA,EAAmC,CAC9C,OAAO,KAAK,qBAAqBA,CAAS,CAC5C,CAEA,YAAYA,EAAmBY,EAAmC,CAChE,IAAMD,EAAU,KAAK,gBAAgB,IAAIC,CAAI,EAC7C,GAAI,CAACD,EAAS,OAAO,KAErB,IAAMJ,EAAS,KAAK,mBAAmB,KAAK,eAAeP,CAAS,CAAC,EACrE,GAAI,CAACO,EAAQ,OAAO,KAEpB,IAAMqB,EAAyB,CAC7B,GAAIC,GAAqB,EACzB,KAAAjB,EACA,QAAS,GACT,SAAU,CAAE,GAAGD,EAAQ,YAAY,CAAE,CACvC,EAEA,OAAAJ,EAAO,UAAU,KAAKqB,CAAQ,EAC9B,KAAK,KAAK5B,CAAS,EACZ4B,CACT,CAEA,eAAe5B,EAAmB8B,EAA0B,CAC1D,IAAMvB,EAAS,KAAK,mBAAmB,KAAK,eAAeP,CAAS,CAAC,EAChEO,IACLA,EAAO,UAAYA,EAAO,UAAU,OAAQ,GAAM,EAAE,KAAOuB,CAAU,EACrE,KAAK,KAAK9B,CAAS,EACrB,CAEA,gBACEA,EACA+B,EACAC,EACAC,EACM,CACN,IAAM1B,EAAS,KAAK,mBAAmB,KAAK,eAAeP,CAAS,CAAC,EACrE,GAAI,CAACO,GAAUwB,IAAcC,EAAU,OAEvC,IAAME,EAAY3B,EAAO,UAAU,UAAW4B,GAAMA,EAAE,KAAOJ,CAAS,EAChEK,EAAc7B,EAAO,UAAU,UAAW4B,GAAMA,EAAE,KAAOH,CAAQ,EACvE,GAAIE,IAAc,IAAME,IAAgB,GAAI,OAE5C,GAAM,CAACC,CAAO,EAAI9B,EAAO,UAAU,OAAO2B,EAAW,CAAC,EAChDI,EAAmB/B,EAAO,UAAU,UAAW4B,GAAMA,EAAE,KAAOH,CAAQ,EACtEO,EAAcN,IAAc,SAAWK,EAAmBA,EAAmB,EACnF/B,EAAO,UAAU,OAAOgC,EAAa,EAAGF,CAAO,EAC/C,KAAK,KAAKrC,CAAS,CACrB,CAEA,kBAAkBA,EAAmB8B,EAA0B,CAC7D,IAAMvB,EAAS,KAAK,mBAAmB,KAAK,eAAeP,CAAS,CAAC,EACrE,GAAI,CAACO,EAAQ,OAEb,IAAM2B,EAAY3B,EAAO,UAAU,UAAW4B,GAAMA,EAAE,KAAOL,CAAU,EACvE,GAAII,IAAc,IAAMA,IAAc3B,EAAO,UAAU,OAAS,EAAG,OAEnE,GAAM,CAACqB,CAAQ,EAAIrB,EAAO,UAAU,OAAO2B,EAAW,CAAC,EACvD3B,EAAO,UAAU,KAAKqB,CAAQ,EAC9B,KAAK,KAAK5B,CAAS,CACrB,CAEA,iBAAiBA,EAAmB8B,EAA0B,CAC5D,IAAMF,EAAW,KAAK,aAAa5B,EAAW8B,CAAU,EACnDF,IACLA,EAAS,QAAU,CAACA,EAAS,QAC7B,KAAK,KAAK5B,CAAS,EACrB,CAEA,eAAeA,EAAmB8B,EAAoBU,EAAoB,CACxE,IAAMZ,EAAW,KAAK,aAAa5B,EAAW8B,CAAU,EACnDF,IACLA,EAAS,KAAOY,EAAK,KAAK,GAAK,OAC/B,KAAK,KAAKxC,CAAS,EACrB,CAEA,iBAAiBA,EAAmByC,EAAqB,CACvD,IAAM5B,EAAQ,KAAK,eAAeb,CAAS,EAC3Ca,EAAM,WAAa4B,EAAM,KAAK,GAAK,SACnC,KAAK,KAAKzC,CAAS,CACrB,CAEA,cAAcA,EAAmB8B,EAAoBY,EAAaC,EAAkB,CAClF,IAAMf,EAAW,KAAK,aAAa5B,EAAW8B,CAAU,EACnDF,IACLA,EAAS,SAASc,CAAG,EAAIC,EACzB,KAAK,KAAK3C,CAAS,EACrB,CAEA,aAAaA,EAAmB8B,EAA8C,CAC5E,OAAO,KAAK,qBAAqB9B,CAAS,EAAE,KAAMmC,GAAMA,EAAE,KAAOL,CAAU,CAC7E,CAEA,KAAK9B,EAAyB,CAC5B,IAAMa,EAAQ,KAAK,cAAc,IAAIb,CAAS,EAC9C,GAAKa,EACL,GAAI,CACF,IAAM+B,EAAU,CACd,QAAS/B,EAAM,QACf,iBAAkBA,EAAM,iBACxB,WAAYA,EAAM,YAAc,QAClC,EACMgC,EAAc9C,GAAeC,CAAS,EAC5C,aAAa,QAAQ6C,EAAa,KAAK,UAAUD,CAAO,CAAC,CAC3D,OAASE,EAAO,CACd,QAAQ,KAAK,wCAAyC,CACpD,UAAA9C,EACA,YAAaD,GAAeC,CAAS,EACrC,MAAA8C,CACF,CAAC,CACH,CACF,CAEA,KAAK9C,EAAmB+C,EAAwB,CAAC,EAAS,CACxD,GAAI,CACF,IAAMC,EAAe,CAAChD,EAAW,GAAG+C,CAAW,EACzCE,EAMD,CAAC,EAEN,QAAWC,KAAeF,EAAc,CACtC,IAAMH,EAAc9C,GAAemD,CAAW,EACxCC,EAAM,aAAa,QAAQN,CAAW,EAC5C,GAAKM,EAIL,GAAI,CACF,IAAMC,EAAS,KAAK,MAAMD,CAAG,EAC7BF,EAAW,KAAK,CACd,UAAWC,EACX,YAAAL,EACA,IAAAM,EACA,OAAAC,EACA,UAAWlD,GAAqBkD,CAAM,CACxC,CAAC,CACH,OAASN,EAAO,CACd,QAAQ,KAAK,mDAAoD,CAC/D,UAAA9C,EACA,YAAAkD,EACA,YAAAL,EACA,MAAAC,CACF,CAAC,CACH,CACF,CAEA,IAAIO,EAAoBJ,EAAW,CAAC,GAAK,KACzC,QAAWK,KAAaL,GAClB,CAACI,GAAqBC,EAAU,UAAYD,EAAkB,aAChEA,EAAoBC,GAIxB,GAAI,CAACD,EAAmB,OAExB,IAAMD,EAASC,EAAkB,OAC3BE,EAAoBF,EAAkB,UAG5C,GAAI,MAAM,QAAQD,CAAM,EAAG,CACzB,IAAMI,EAAQJ,EAAO,OAAQjB,GAAW,KAAK,gBAAgB,IAAIA,EAAE,IAAI,CAAC,EACxE,QAAWA,KAAKqB,EAAO,CACrB,IAAM7C,EAAU,KAAK,gBAAgB,IAAIwB,EAAE,IAAI,EAC3CxB,IAASwB,EAAE,SAAW,CAAE,GAAGxB,EAAQ,YAAY,EAAG,GAAGwB,EAAE,QAAS,EACtE,CACA,IAAM9B,EAAUoD,GAAqB,CAAW,EAChDpD,EAAQA,EAAQ,OAAS,CAAC,EAAE,UAAYmD,EACxC,KAAK,cAAc,IAAIxD,EAAW,CAChC,UAAAA,EACA,QAAAK,EACA,iBAAkBA,EAAQ,CAAC,EAAE,GAC7B,WAAY,QACd,CAAC,EACGkD,IAAsBvD,GACxB,KAAK,KAAKA,CAAS,EAErB,MACF,CAEA,IAAM0D,EAAa,MAAM,QAAQN,GAAQ,OAAO,EAAIA,EAAO,QAAU,KACrE,GAAI,CAACM,EAAY,OAEjB,IAAMrD,EAAU,KAAK,iBAAiBqD,CAAU,EAChD,GAAIrD,EAAQ,SAAW,EAAG,OAE1B,IAAMqB,EACJ,OAAO0B,GAAQ,kBAAqB,SAChCA,EAAO,iBACP/C,EAAQ,CAAC,EAAE,GAEXQ,EAA0B,CAC9B,UAAAb,EACA,QAAAK,EACA,iBAAAqB,EACA,WACE,OAAO0B,GAAQ,YAAe,UAAYA,EAAO,WAAW,KAAK,EAAE,OAAS,EACxEA,EAAO,WAAW,KAAK,EACvB,QACR,EACA,KAAK,qBAAqBvC,CAAK,EAC/B,KAAK,cAAc,IAAIb,EAAWa,CAAK,EACnC0C,IAAsBvD,GACxB,KAAK,KAAKA,CAAS,CAEvB,MAAQ,CAER,CACF,CAEA,OAAc,CACZ,KAAK,cAAc,MAAM,CAC3B,CAIQ,eAAeA,EAAqC,CAC1D,IAAIa,EAAQ,KAAK,cAAc,IAAIb,CAAS,EAC5C,GAAI,CAACa,EAAO,CACV,IAAMR,EAAUoD,GAAqB,CAAW,EAChD5C,EAAQ,CAAE,UAAAb,EAAW,QAAAK,EAAS,iBAAkBA,EAAQ,CAAC,EAAE,GAAI,WAAY,QAAS,EACpF,KAAK,cAAc,IAAIL,EAAWa,CAAK,CACzC,CACA,YAAK,YAAYA,CAAK,EACtB,KAAK,qBAAqBA,CAAK,EACxBA,CACT,CAEQ,iBAAiBR,EAA8B,CA8BrD,IAAMsD,EA7BWtD,EAAQ,OACtBe,GAAWA,GAAK,OAAOA,GAAM,UAAY,OAAOA,EAAE,IAAO,QAC5D,EAE0C,IAAKA,GAAW,CACxD,IAAMX,EAAY,MAAM,QAAQW,EAAE,SAAS,EACvCA,EAAE,UACF,MAAM,QAAQA,EAAE,KAAK,EACnBA,EAAE,MACF,CAAC,EAEP,MAAO,CACL,GAAIA,EAAE,GACN,MAAOA,EAAE,OAAS,IAClB,SAAUK,GACR,OAAOL,EAAE,UAAa,SAAWA,EAAE,SAAW,CAChD,EACA,UAAWX,EACR,OAAQ0B,GAAW,KAAK,gBAAgB,IAAIA,EAAE,IAAI,CAAC,EACnD,IAAKA,GAAW,CACf,IAAMxB,EAAU,KAAK,gBAAgB,IAAIwB,EAAE,IAAI,EAC/C,OAAOxB,EACH,CAAE,GAAGwB,EAAG,QAASA,EAAE,UAAY,GAAO,SAAU,CAAE,GAAGxB,EAAQ,YAAY,EAAG,GAAGwB,EAAE,QAAS,CAAE,EAC5FA,CACN,CAAC,CACL,CACF,CAAC,EAG0B,MAAM,EAAG,CAAW,EAC/C,KAAOwB,EAAQ,OAAS,GACtBA,EAAQ,KAAK,CACX,GAAIzC,GAAmB,EACvB,MAAO,IACP,SAAU,EACV,UAAW,CAAC,CACd,CAAC,EAGH,YAAK,eAAeyC,CAAO,EAC3BxC,GAAewC,CAAO,EACtB,KAAK,6BAA6BA,CAAO,EAClCA,CACT,CAEQ,YAAY9C,EAA+B,CACjD,KAAK,eAAeA,EAAM,OAAO,CACnC,CAEQ,eAAeR,EAA6B,CAClDA,EAAQ,KAAK,CAACuD,EAAGC,IAAMA,EAAE,SAAWD,EAAE,QAAQ,CAChD,CAEQ,qBAAqB/C,EAA+B,CACtDA,EAAM,QAAQ,OAAS,IACzBA,EAAM,QAAU4C,GAAqB,CAAW,GAE9C5C,EAAM,QAAQ,OAAS,IACzBA,EAAM,QAAUA,EAAM,QAAQ,MAAM,EAAG,CAAW,EAClDM,GAAeN,EAAM,OAAO,GAEzBA,EAAM,QAAQ,KAAMO,GAAMA,EAAE,KAAOP,EAAM,gBAAgB,IAC5DA,EAAM,iBAAmBA,EAAM,QAAQA,EAAM,QAAQ,OAAS,CAAC,EAAE,GAErE,CAEQ,0BAA0BA,EAA+B,CAC/D,KAAK,6BAA6BA,EAAM,OAAO,CACjD,CAEQ,6BAA6BR,EAA6B,CAEhE,GAAIA,EAAQ,SAAW,EACvB,CAAAA,EAAQA,EAAQ,OAAS,CAAC,EAAE,SAAW,EAGvC,QAAS8B,EAAI9B,EAAQ,OAAS,EAAG8B,GAAK,EAAGA,IAAK,CAC5C,IAAM2B,EAAQzD,EAAQ8B,EAAI,CAAC,EAAE,SACzB9B,EAAQ8B,CAAC,EAAE,UAAY2B,IACzBzD,EAAQ8B,CAAC,EAAE,SAAW2B,EAAQ,EAElC,EACF,CAEQ,mBAAmBjD,EAAiD,CAC1E,OAAOA,EAAM,QAAQ,KAAMO,GAAMA,EAAE,KAAOP,EAAM,gBAAgB,CAClE,CAEQ,mBAAmBA,EAAyBC,EAA+C,CACjG,QAAWP,KAAUM,EAAM,QACzB,GAAIC,GAAiBP,EAAO,SAAU,OAAOA,EAE/C,OAAOM,EAAM,QAAQA,EAAM,QAAQ,OAAS,CAAC,CAC/C,CACF,ECrhBA,IAAMkD,GAAS,6BAUFC,GAAN,KAAkB,CAOvB,YAAYC,EAAqBC,EAAoBC,EAAuB,CAH5E,KAAQ,QAAmB,GAIzB,KAAK,OAASF,EACd,KAAK,SAAWE,EAChB,KAAK,IAAM,SAAS,gBAAgBJ,GAAQ,KAAK,EACjD,KAAK,IAAI,aAAa,2BAA4B,EAAE,EACpD,KAAK,IAAI,MAAM,SAAW,WAC1B,KAAK,IAAI,MAAM,cAAgB,OAC/B,KAAK,IAAI,MAAM,gBAAkB,WAEjCG,EAAM,YAAY,KAAK,GAAG,EAC1B,KAAK,YAAY,EAEjB,KAAK,eAAiB,IAAI,eAAe,IAAM,CAC7C,KAAK,YAAY,EACjB,KAAK,WAAW,CAClB,CAAC,EACD,KAAK,eAAe,QAAQ,KAAK,MAAM,CACzC,CAEO,YAA4B,CAAE,OAAO,KAAK,GAAK,CAE/C,YAAYE,EAAcC,EAAcC,EAAeC,EAAsB,CAClF,KAAK,IAAI,MAAM,MAAQ,GAAGD,CAAK,KAC/B,KAAK,IAAI,MAAM,OAAS,GAAGC,CAAM,KACjC,KAAK,IAAI,MAAM,UAAY,eAAe,KAAK,MAAMH,CAAI,CAAC,OAAO,KAAK,MAAMC,CAAI,CAAC,QACnF,CAMA,OAAOG,EAA2BC,EAAiD,CAEjF,GADA,KAAK,SAAS,EACV,CAAC,KAAK,QACR,OAEF,GAAM,CAAE,MAAAH,EAAO,OAAAC,CAAO,EAAI,KAAK,cAAc,EAE7C,QAAWG,IAAY,CAAC,GAAGF,CAAS,EAAE,QAAQ,EAAG,CAC/C,IAAMG,EAAUF,EAAgB,IAAIC,EAAS,IAAI,EACjD,GAAKC,GAEDD,EAAS,QAAS,CACpBC,EAAQ,OAAO,KAAK,IAAKL,EAAOC,EAAQ,CACtC,GAAGG,EAAS,SACZ,aAAcA,EAAS,EACzB,CAAC,EACD,IAAME,EAAQ,KAAK,IAAI,cACrB,kBAAkBF,EAAS,EAAE,IAC/B,EACIE,IACFA,EAAM,aAAa,iBAAkBF,EAAS,IAAI,EAClDE,EAAM,aAAa,oBAAqB,MAAM,EAElD,CACF,CACF,CAEA,WAAWC,EAAwB,CACjC,KAAK,QAAUA,EACf,KAAK,IAAI,MAAM,QAAUA,EAAU,GAAK,OACnCA,GACH,KAAK,SAAS,CAElB,CAKA,UAAiB,CACf,IAAMC,EAAS,KAAK,IAAI,iBAAiB,gBAAgB,EACzD,QAASC,EAAID,EAAO,OAAS,EAAGC,GAAK,EAAGA,IACtCD,EAAOC,CAAC,EAAE,OAAO,CAErB,CAKA,cAAcC,EAAoBL,EAA4B,CAC5DA,EAAQ,MAAM,KAAK,IAAKK,CAAU,CACpC,CAKA,aAAoB,CAClB,GAAM,CAAE,MAAAV,EAAO,OAAAC,CAAO,EAAI,KAAK,cAAc,EAC7C,KAAK,IAAI,aAAa,UAAW,OAAOD,CAAK,IAAIC,CAAM,EAAE,CAC3D,CAKA,eAAmD,CACjD,MAAO,CACL,MAAO,KAAK,OAAO,YACnB,OAAQ,KAAK,OAAO,YACtB,CACF,CAKA,SAAgB,CACd,KAAK,eAAe,WAAW,EAC/B,KAAK,IAAI,OAAO,CAClB,CAKQ,kBAAyB,CACd,iBAAiB,KAAK,MAAM,EAChC,WAAa,WACxB,KAAK,OAAO,MAAM,SAAW,WAEjC,CACF,ECnIO,IAAeU,GAAf,KAAyC,CAO9C,YACEC,EACAC,EACAC,EACAC,EACA,CAPF,KAAU,KAA2B,KAQnC,KAAK,IAAMH,EACX,KAAK,MAAQC,EACb,KAAK,MAAQC,EACb,KAAK,SAAWC,CAClB,CASA,YAAYC,EAAyB,CAC9B,KAAK,MACV,KAAK,KAAK,aAAa,gBAAiBA,EAAW,OAAS,OAAO,CACrE,CAGA,UAAc,CACZ,OAAO,KAAK,KACd,CAGA,SAAgB,CACd,KAAK,MAAM,OAAO,EAClB,KAAK,KAAO,IACd,CAGU,KAAKC,EAAgB,CAC7B,KAAK,MAAQA,EACb,KAAK,SAAS,KAAK,IAAKA,CAAK,CAC/B,CAGU,aAAgC,CACxC,IAAMJ,EAAQ,SAAS,cAAc,OAAO,EAC5C,OAAAA,EAAM,YAAc,KAAK,MACzBA,EAAM,aAAa,kBAAmB,EAAE,EACjCA,CACT,CAGU,WAA4B,CACpC,IAAMK,EAAM,SAAS,cAAc,KAAK,EACxC,OAAAA,EAAI,aAAa,wBAAyB,EAAE,EACrCA,CACT,CACF,EClEA,IAAMC,GAAgB,IAChBC,GAAmB,GACnBC,GAAuB,EAEhBC,GAAN,cAAmCC,EAAyB,CAOjE,YACEC,EACAC,EACAC,EACAC,EACAC,EAAc,EACdC,EAAc,IACdC,EAAe,EACf,CACA,MAAMN,EAAKC,EAAOC,EAAcC,CAAQ,EAZ1C,KAAQ,MAAiC,KACzC,KAAQ,eAAsC,CAAC,EAY7C,KAAK,IAAMC,EACX,KAAK,IAAMC,EACX,KAAK,KAAOC,CACd,CAEA,OAAqB,CACnB,IAAMC,EAAM,KAAK,UAAU,EAC3B,OAAAA,EAAI,YAAY,KAAK,YAAY,CAAC,EAClCA,EAAI,YAAY,KAAK,eAAe,CAAC,EACrC,KAAK,KAAOA,EACLA,CACT,CAEA,SAASC,EAAqB,CAC5B,KAAK,MAAQA,EACT,KAAK,QAAO,KAAK,MAAM,MAAQ,KAAK,YAAYA,CAAK,EAC3D,CAES,YAAYC,EAAyB,CAC5C,MAAM,YAAYA,CAAQ,EACtB,KAAK,QAAO,KAAK,MAAM,SAAWA,GACtC,QAAWC,KAAU,KAAK,eACxBA,EAAO,SAAWD,CAEtB,CAEQ,gBAAiC,CACvC,IAAME,EAAU,SAAS,cAAc,KAAK,EAC5CA,EAAQ,aAAa,wBAAyB,EAAE,EAEhD,IAAMC,EAAU,SAAS,cAAc,KAAK,EAC5C,OAAAA,EAAQ,aAAa,oBAAqB,EAAE,EAC5CA,EAAQ,YAAY,KAAK,oBAAoB,KAAM,CAAC,CAAC,EACrDA,EAAQ,YAAY,KAAK,oBAAoB,OAAQ,EAAE,CAAC,EAExDD,EAAQ,YAAY,KAAK,YAAY,CAAC,EACtCA,EAAQ,YAAYC,CAAO,EACpBD,CACT,CAEQ,aAAgC,CACtC,IAAME,EAAQ,SAAS,cAAc,OAAO,EAC5C,OAAAA,EAAM,KAAO,OACbA,EAAM,UAAY,OAClBA,EAAM,aAAa,eAAgB,MAAM,EACzCA,EAAM,aAAe,MACrBA,EAAM,WAAa,GACnBA,EAAM,MAAQ,KAAK,YAAY,KAAK,KAAK,EACzCA,EAAM,aAAa,kBAAmB,EAAE,EAExCA,EAAM,iBAAiB,QAAS,IAAM,CACpCA,EAAM,OAAO,CACf,CAAC,EACDA,EAAM,iBAAiB,OAAQ,IAAM,CACnC,KAAK,YAAYA,EAAM,KAAK,CAC9B,CAAC,EACDA,EAAM,iBAAiB,UAAYC,GAAU,CAC3C,GAAIA,EAAM,MAAQ,QAAS,CACzBD,EAAM,KAAK,EACX,MACF,CACA,GAAIC,EAAM,MAAQ,SAAU,CAC1BD,EAAM,MAAQ,KAAK,YAAY,KAAK,KAAK,EACzCA,EAAM,KAAK,EACX,MACF,CACIC,EAAM,MAAQ,WAAaA,EAAM,MAAQ,cAC7CA,EAAM,eAAe,EACrB,KAAK,WAAWA,EAAM,MAAQ,UAAY,EAAI,GAAIA,CAAK,EACzD,CAAC,EACDD,EAAM,iBAAiB,QAAUC,GAAU,CACrC,SAAS,gBAAkBD,IAC/BC,EAAM,eAAe,EACrB,KAAK,WAAWA,EAAM,OAAS,EAAI,EAAI,GAAIA,CAAK,EAClD,CAAC,EACDD,EAAM,iBAAiB,YAAcC,GAAU,CACzCA,EAAM,SAAW,GACrB,KAAK,gBAAgBA,EAAOD,CAAK,CACnC,CAAC,EACDA,EAAM,iBAAiB,WAAaC,GAAU,CACxCA,EAAM,SAAW,GAAGA,EAAM,eAAe,CAC/C,CAAC,EAED,KAAK,MAAQD,EACNA,CACT,CAEQ,oBAAoBE,EAA8BC,EAAsC,CAC9F,IAAMN,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,KAAO,SACdA,EAAO,aAAa,mBAAoB,EAAE,EAC1CA,EAAO,aAAa,2BAA4B,EAAE,EAClDA,EAAO,aAAa,iBAAkBK,CAAa,EACnDL,EAAO,UAAYO,EACjB,GACAF,IAAkB,KAAO,cAAgB,eAC3C,EAEA,IAAIG,EAAc,EACdC,EAAe,EACfC,EAAgB,GAEdC,EAAW,IAAM,CACrB,OAAO,aAAaH,CAAW,EAC/B,OAAO,cAAcC,CAAY,EACjC,SAAS,oBAAoB,YAAaE,CAAQ,EAClD,SAAS,oBAAoB,gBAAiBA,CAAQ,CACxD,EAEA,OAAAX,EAAO,iBAAiB,cAAgBI,GAAU,CAC5CA,EAAM,SAAW,IAErBI,EAAc,OAAO,WAAW,IAAM,CACpCE,EAAgB,GAChB,KAAK,WAAWJ,CAAS,EACzBG,EAAe,OAAO,YAAY,IAAM,CACtC,KAAK,WAAWH,CAAS,CAC3B,EAAGpB,EAAgB,CACrB,EAAGD,EAAa,EAEhB,SAAS,iBAAiB,YAAa0B,CAAQ,EAC/C,SAAS,iBAAiB,gBAAiBA,CAAQ,EACrD,CAAC,EAEDX,EAAO,iBAAiB,QAAUI,GAAU,CAC1C,GAAIM,EAAe,CACjBA,EAAgB,GAChBN,EAAM,eAAe,EACrB,MACF,CAEA,KAAK,WAAWE,CAAS,EACzB,KAAK,OAAO,MAAM,EAClB,KAAK,OAAO,OAAO,CACrB,CAAC,EAED,KAAK,eAAe,KAAKN,CAAM,EACxBA,CACT,CAEQ,gBAAgBI,EAAmBD,EAA+B,CACxEC,EAAM,eAAe,EAErB,IAAIQ,EAAYR,EAAM,QAClBS,EAAc,EACZC,EAAiB,SAAS,KAAK,MAAM,OACrCC,EAAqB,SAAS,KAAK,MAAM,WAE/C,SAAS,KAAK,MAAM,OAAS,YAC7B,SAAS,KAAK,MAAM,WAAa,OAEjC,IAAMC,EAAW,IAAM,CACrB,SAAS,oBAAoB,YAAaC,CAAW,EACrD,SAAS,oBAAoB,UAAWD,CAAQ,EAChD,SAAS,KAAK,MAAM,OAASF,EAC7B,SAAS,KAAK,MAAM,WAAaC,CACnC,EAEME,EAAeC,GAA0B,CAC7C,IAAMC,EAASD,EAAU,QAAUN,EAInC,IAHAA,EAAYM,EAAU,QACtBL,GAAeM,EAER,KAAK,IAAIN,CAAW,GAAK1B,IAAsB,CACpD,IAAMmB,EAAYO,EAAc,EAAI,EAAI,GACxC,KAAK,WAAWP,EAAWY,CAAS,EACpCL,GAAe1B,GAAuBmB,CACxC,CACF,EAEAH,EAAM,MAAM,EACZA,EAAM,OAAO,EACb,SAAS,iBAAiB,YAAac,CAAW,EAClD,SAAS,iBAAiB,UAAWD,CAAQ,CAC/C,CAEQ,YAAYI,EAAwB,CAC1C,IAAMC,EAAS,WAAWD,EAAS,QAAQ,IAAK,GAAG,CAAC,EACpD,GAAI,MAAMC,CAAM,EAAG,CACb,KAAK,QAAO,KAAK,MAAM,MAAQ,KAAK,YAAY,KAAK,KAAK,GAC9D,MACF,CAEA,IAAMC,EAAY,KAAK,eAAeD,CAAM,EACxC,KAAK,QAAO,KAAK,MAAM,MAAQ,KAAK,YAAYC,CAAS,GAC7D,KAAK,KAAKA,CAAS,CACrB,CAEQ,WAAWhB,EAAmBF,EAAuD,CAC3F,IAAMmB,EAAanB,GAAO,SAAW,GAAKA,GAAO,OAAS,GAAM,EAC1DkB,EAAY,KAAK,eAAe,KAAK,MAAQhB,EAAY,KAAK,KAAOiB,CAAU,EACjF,KAAK,QAAO,KAAK,MAAM,MAAQ,KAAK,YAAYD,CAAS,GAC7D,KAAK,KAAKA,CAAS,CACrB,CAEQ,eAAexB,EAAuB,CAC5C,IAAM0B,EAAU,KAAK,MAAM1B,EAAQ,KAAK,IAAI,EAAI,KAAK,KAC/C2B,EAAY,KAAK,aAAa,KAAK,IAAI,EAC7C,OAAO,OAAOD,EAAQ,QAAQC,CAAS,CAAC,CAC1C,CAEQ,aAAa3B,EAAuB,CAE1C,OADc,OAAOA,CAAK,EAAE,MAAM,GAAG,EACxB,CAAC,GAAG,QAAU,CAC7B,CAEQ,YAAYA,EAAuB,CACzC,IAAM2B,EAAY,KAAK,aAAa,KAAK,IAAI,EAC7C,OAAOA,EAAY,EAAI3B,EAAM,QAAQ2B,CAAS,EAAI,OAAO3B,CAAK,CAChE,CACF,ECvOA,IAAM4B,GAAgB,IAChBC,GAAmB,GACnBC,GAAuB,EAEhBC,GAAN,MAAMA,WAA4BC,EAAyB,CAehE,YACEC,EACAC,EACAC,EACAC,EACAC,EAAc,EACdC,EAAc,IACdC,EAAe,EACfC,EAA4B,EAC5BC,EACAC,EACAC,EACAC,EACA,CACA,MAAMX,EAAKC,EAAOC,EAAcC,CAAQ,EApB1C,KAAQ,WAAsC,KAC9C,KAAQ,WAAuC,KAC/C,KAAQ,eAAsC,CAAC,EAmB7C,KAAK,IAAMC,EACX,KAAK,IAAMC,EACX,KAAK,KAAOC,EACZ,KAAK,kBAAoBC,EACzB,KAAK,YAAcC,EACnB,KAAK,OAASC,EACd,KAAK,MAAQC,EACb,KAAK,YAAcC,CACrB,CAEA,OAAqB,CACnB,IAAMC,EAAM,KAAK,UAAU,EAC3B,OAAAA,EAAI,YAAY,KAAK,YAAY,CAAC,EAClCA,EAAI,YAAY,KAAK,eAAe,CAAC,EACrC,KAAK,KAAOA,EACLA,CACT,CAEA,SAASC,EAAqB,CAC5B,KAAK,MAAQA,EACT,KAAK,aAAY,KAAK,WAAW,MAAQ,KAAK,YAAYA,CAAK,EACrE,CAES,YAAYC,EAAyB,CAC5C,MAAM,YAAYA,CAAQ,EACtB,KAAK,aAAY,KAAK,WAAW,SAAWA,GAC5C,KAAK,aAAY,KAAK,WAAW,SAAWA,GAChD,QAAWC,KAAU,KAAK,eACxBA,EAAO,SAAWD,CAEtB,CAEQ,gBAAiC,CACvC,IAAME,EAAU,SAAS,cAAc,KAAK,EAC5CA,EAAQ,aAAa,wBAAyB,EAAE,EAChD,IAAMC,EAAa,SAAS,cAAc,KAAK,EAI/C,GAHAA,EAAW,aAAa,wBAAyB,EAAE,EACnDA,EAAW,YAAY,KAAK,YAAY,CAAC,EAErC,KAAK,OAAQ,CACf,IAAMR,EAAS,SAAS,cAAc,MAAM,EAC5CA,EAAO,aAAa,yBAA0B,EAAE,EAChDA,EAAO,YAAc,KAAK,OAC1BQ,EAAW,YAAYR,CAAM,CAC/B,CAIA,GAFAO,EAAQ,YAAYC,CAAU,EAE1B,KAAK,OAAS,KAAK,MAAM,OAAS,EAAG,CACvC,IAAMC,EAAa,SAAS,cAAc,QAAQ,EAClDA,EAAW,aAAa,mBAAoB,EAAE,EAE9C,QAAWC,KAAK,KAAK,MAAO,CAC1B,IAAMC,EAAM,SAAS,cAAc,QAAQ,EAC3CA,EAAI,MAAQD,EAAE,MACdC,EAAI,YAAcD,EAAE,MACpBD,EAAW,YAAYE,CAAG,CAC5B,CAEAF,EAAW,MAAQ,KAAK,aAAe,KAAK,MAAM,CAAC,EAAE,MACrDA,EAAW,iBAAiB,SAAU,IAAM,CAC1C,KAAK,YAAcA,EAAW,MAC1B,KAAK,aAAY,KAAK,WAAW,MAAQ,KAAK,YAAY,KAAK,KAAK,GACxE,KAAK,SAAS,KAAK,IAAM,OAAQA,EAAW,KAAK,CACnD,CAAC,EAED,KAAK,WAAaA,EAClBF,EAAQ,YAAYE,CAAU,CAChC,CAEA,IAAMG,EAAU,SAAS,cAAc,KAAK,EAC5C,OAAAA,EAAQ,aAAa,oBAAqB,EAAE,EAC5CA,EAAQ,YAAY,KAAK,oBAAoB,KAAM,CAAC,CAAC,EACrDA,EAAQ,YAAY,KAAK,oBAAoB,OAAQ,EAAE,CAAC,EACxDL,EAAQ,YAAYK,CAAO,EAEpBL,CACT,CAEQ,aAAgC,CACtC,IAAMM,EAAa,SAAS,cAAc,OAAO,EACjD,OAAAA,EAAW,KAAO,OAClBA,EAAW,UAAY,OACvBA,EAAW,aAAa,eAAgB,MAAM,EAC9CA,EAAW,aAAe,MAC1BA,EAAW,WAAa,GACxBA,EAAW,MAAQ,KAAK,YAAY,KAAK,KAAK,EAC9CA,EAAW,aAAa,kBAAmB,EAAE,EAE7CA,EAAW,iBAAiB,QAAS,IAAM,CACzCA,EAAW,OAAO,CACpB,CAAC,EACDA,EAAW,iBAAiB,OAAQ,IAAM,CACxC,KAAK,iBAAiBA,CAAU,CAClC,CAAC,EACDA,EAAW,iBAAiB,UAAY,GAAM,CACxC,EAAE,MAAQ,QACZA,EAAW,KAAK,EACP,EAAE,MAAQ,UACnBA,EAAW,MAAQ,KAAK,YAAY,KAAK,KAAK,EAC9CA,EAAW,KAAK,IACP,EAAE,MAAQ,WAAa,EAAE,MAAQ,eAC1C,EAAE,eAAe,EACjB,KAAK,WAAW,EAAE,MAAQ,UAAY,EAAI,GAAI,EAAGA,CAAU,EAE/D,CAAC,EACDA,EAAW,iBAAiB,QAAUC,GAAU,CAC1C,SAAS,gBAAkBD,IAC/BC,EAAM,eAAe,EACrB,KAAK,WAAWA,EAAM,OAAS,EAAI,EAAI,GAAIA,EAAOD,CAAU,EAC9D,CAAC,EACDA,EAAW,iBAAiB,YAAcC,GAAU,CAC9CA,EAAM,SAAW,GACrB,KAAK,gBAAgBA,EAAOD,CAAU,CACxC,CAAC,EACDA,EAAW,iBAAiB,WAAaC,GAAU,CAC7CA,EAAM,SAAW,GAAGA,EAAM,eAAe,CAC/C,CAAC,EAED,KAAK,WAAaD,EACXA,CACT,CAEQ,oBAAoBE,EAA8BC,EAAsC,CAC9F,IAAMV,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,KAAO,SACdA,EAAO,aAAa,mBAAoB,EAAE,EAC1CA,EAAO,aAAa,2BAA4B,EAAE,EAClDA,EAAO,aAAa,iBAAkBS,CAAa,EACnDT,EAAO,UAAYW,EACjB,GACAF,IAAkB,KAAO,cAAgB,eAC3C,EAEA,IAAIG,EAAc,EACdC,EAAe,EACfC,EAAgB,GAEdC,EAAW,IAAM,CACrB,OAAO,aAAaH,CAAW,EAC/B,OAAO,cAAcC,CAAY,EACjC,SAAS,oBAAoB,YAAaE,CAAQ,EAClD,SAAS,oBAAoB,gBAAiBA,CAAQ,CACxD,EAEA,OAAAf,EAAO,iBAAiB,cAAgBQ,GAAU,CAC5CA,EAAM,SAAW,IAErBI,EAAc,OAAO,WAAW,IAAM,CACpCE,EAAgB,GACX,KAAK,aACV,KAAK,WAAWJ,EAAW,OAAW,KAAK,UAAU,EACrDG,EAAe,OAAO,YAAY,IAAM,CACjC,KAAK,YACV,KAAK,WAAWH,EAAW,OAAW,KAAK,UAAU,CACvD,EAAG7B,EAAgB,EACrB,EAAGD,EAAa,EAEhB,SAAS,iBAAiB,YAAamC,CAAQ,EAC/C,SAAS,iBAAiB,gBAAiBA,CAAQ,EACrD,CAAC,EAEDf,EAAO,iBAAiB,QAAUQ,GAAU,CAC1C,GAAIM,EAAe,CACjBA,EAAgB,GAChBN,EAAM,eAAe,EACrB,MACF,CAEK,KAAK,aACV,KAAK,WAAWE,EAAW,OAAW,KAAK,UAAU,EACrD,KAAK,WAAW,MAAM,EACtB,KAAK,WAAW,OAAO,EACzB,CAAC,EAED,KAAK,eAAe,KAAKV,CAAM,EACxBA,CACT,CAEQ,gBAAgBQ,EAAmBQ,EAA+B,CACxER,EAAM,eAAe,EAErB,IAAIS,EAAYT,EAAM,QAClBU,EAAc,EACZC,EAAiB,SAAS,KAAK,MAAM,OACrCC,EAAqB,SAAS,KAAK,MAAM,WAE/C,SAAS,KAAK,MAAM,OAAS,YAC7B,SAAS,KAAK,MAAM,WAAa,OAEjC,IAAMC,EAAW,IAAM,CACrB,SAAS,oBAAoB,YAAaC,CAAW,EACrD,SAAS,oBAAoB,UAAWD,CAAQ,EAChD,SAAS,KAAK,MAAM,OAASF,EAC7B,SAAS,KAAK,MAAM,WAAaC,CACnC,EAEME,EAAeC,GAA0B,CAC7C,IAAMC,EAASD,EAAU,QAAUN,EAInC,IAHAA,EAAYM,EAAU,QACtBL,GAAeM,EAER,KAAK,IAAIN,CAAW,GAAKpC,IAAsB,CACpD,IAAM4B,EAAYQ,EAAc,EAAI,EAAI,GACxC,KAAK,WAAWR,EAAWa,EAAWP,CAAK,EAC3CE,GAAepC,GAAuB4B,CACxC,CACF,EAEAM,EAAM,MAAM,EACZA,EAAM,OAAO,EACb,SAAS,iBAAiB,YAAaM,CAAW,EAClD,SAAS,iBAAiB,UAAWD,CAAQ,CAC/C,CAEQ,iBAAiBL,EAA+B,CACtD,IAAMS,EAAS,WAAWT,EAAM,MAAM,QAAQ,IAAK,GAAG,CAAC,EACvD,GAAI,MAAMS,CAAM,EAAG,CACjBT,EAAM,MAAQ,KAAK,YAAY,KAAK,KAAK,EACzC,MACF,CACA,IAAMU,EAAU,KAAK,sBAAsBD,CAAM,EACjDT,EAAM,MAAQ,KAAK,YAAYU,CAAO,EACtC,KAAK,KAAKA,CAAO,CACnB,CAEQ,WACNhB,EACAF,EACAQ,EACM,CACN,IAAMW,EAAanB,GAAO,SAAW,GAAKA,GAAO,OAAS,GAAM,EAC1DoB,EACJ,KAAK,eAAe,KAAK,KAAK,EAAIlB,EAAY,KAAK,eAAe,EAAIiB,EAClEE,EAAY,KAAK,sBAAsBD,CAAgB,EAC7DZ,EAAM,MAAQ,KAAK,YAAYa,CAAS,EACxC,KAAK,KAAKA,CAAS,CACrB,CAEQ,eAAe/B,EAAuB,CAC5C,IAAMgC,EAAU,KAAK,IAAI,KAAK,IAAK,KAAK,IAAI,KAAK,IAAKhC,CAAK,CAAC,EAC5D,GAAIf,GAAoB,cAAc,IAAI,KAAK,aAAe,EAAE,EAC9D,OAAO,OAAO+C,EAAQ,QAAQ,CAAC,CAAC,EAElC,IAAMJ,EAAU,KAAK,MAAMI,EAAU,KAAK,IAAI,EAAI,KAAK,KACjDC,EAAY,KAAK,aAAa,KAAK,IAAI,EAC7C,OAAO,OAAOL,EAAQ,QAAQK,CAAS,CAAC,CAC1C,CAEQ,sBAAsBjC,EAAuB,CACnD,IAAMkC,EAAa,KAAK,eAAe,KAAK,GAAG,EACzCC,EAAa,KAAK,eAAe,KAAK,GAAG,EACzCH,EAAU,KAAK,IAAIG,EAAY,KAAK,IAAID,EAAYlC,CAAK,CAAC,EAC1DiC,EAAY,KAAK,oBAAoB,EAC3C,GAAIhD,GAAoB,cAAc,IAAI,KAAK,aAAe,EAAE,EAAG,CACjE,IAAMmD,EAAoB,OAAOJ,EAAQ,QAAQC,CAAS,CAAC,EAC3D,OAAO,KAAK,eAAe,KAAK,eAAeG,CAAiB,CAAC,CACnE,CACA,IAAMzC,EAAc,KAAK,eAAe,EAClCiC,EAAU,KAAK,MAAMI,EAAUrC,CAAW,EAAIA,EAC9CyC,EAAoB,OAAOR,EAAQ,QAAQK,CAAS,CAAC,EAC3D,OAAO,KAAK,eAAe,KAAK,eAAeG,CAAiB,CAAC,CACnE,CAEQ,aAAapC,EAAuB,CAE1C,OADc,OAAOA,CAAK,EAAE,MAAM,GAAG,EACxB,CAAC,GAAG,QAAU,CAC7B,CAEQ,YAAYqC,EAAmB,CACrC,IAAMC,EAAe,KAAK,eAAeD,CAAC,EACpCJ,EAAY,KAAK,oBAAoB,EAC3C,OAAOA,EAAY,EAAIK,EAAa,QAAQL,CAAS,EAAI,OAAOK,CAAY,CAC9E,CAEQ,eAAetC,EAAuB,CAC5C,IAAMiC,EAAY,KAAK,oBAAoB,EAC3C,OAAO,QAAQjC,EAAQ,KAAK,mBAAmB,QAAQiC,CAAS,CAAC,CACnE,CAEQ,eAAejC,EAAuB,CAC5C,OAAOA,EAAQ,KAAK,iBACtB,CAEQ,gBAAyB,CAC/B,OAAO,KAAK,aAAe,KAAK,KAAO,KAAK,iBAC9C,CAEQ,qBAA8B,CACpC,GAAIf,GAAoB,cAAc,IAAI,KAAK,aAAe,EAAE,EAC9D,MAAO,GAET,IAAMU,EAAc,KAAK,eAAe,EACxC,OAAOA,EAAc,EAAI,KAAK,IAAI,EAAG,KAAK,aAAaA,CAAW,CAAC,EAAI,CACzE,CACF,EArUaV,GAaa,cAAgB,IAAI,IAAI,CAAC,MAAO,IAAI,CAAC,EAbxD,IAAMsD,GAANtD,GCLA,IAAMuD,GAAN,cAAkCC,EAAyB,CAA3D,kCACL,KAAQ,WAAsC,KAC9C,KAAQ,SAAoC,KAE5C,OAAqB,CACnB,IAAMC,EAAM,KAAK,UAAU,EAC3B,OAAAA,EAAI,YAAY,KAAK,YAAY,CAAC,EAClCA,EAAI,YAAY,KAAK,cAAc,CAAC,EACpC,KAAK,KAAOA,EACLA,CACT,CAEA,SAASC,EAAqB,CAC5B,KAAK,MAAQA,EACT,KAAK,aAAY,KAAK,WAAW,MAAQA,GACzC,KAAK,WAAU,KAAK,SAAS,MAAQA,EAC3C,CAES,YAAYC,EAAyB,CAC5C,MAAM,YAAYA,CAAQ,EACtB,KAAK,aAAY,KAAK,WAAW,SAAWA,GAC5C,KAAK,WAAU,KAAK,SAAS,SAAWA,EAC9C,CAEQ,eAAgC,CACtC,IAAMC,EAAQ,SAAS,cAAc,KAAK,EAC1CA,EAAM,aAAa,wBAAyB,EAAE,EAE9C,IAAMC,EAAa,SAAS,cAAc,OAAO,EACjDA,EAAW,KAAO,QAClBA,EAAW,MAAQ,KAAK,MACxBA,EAAW,aAAa,kBAAmB,EAAE,EAC7CA,EAAW,aAAa,wBAAyB,EAAE,EAEnD,IAAMC,EAAW,SAAS,cAAc,OAAO,EAC/C,OAAAA,EAAS,KAAO,OAChBA,EAAS,UAAY,OACrBA,EAAS,MAAQ,KAAK,MACtBA,EAAS,aAAa,kBAAmB,EAAE,EAE3CD,EAAW,iBAAiB,QAAS,IAAM,CACzCC,EAAS,MAAQD,EAAW,MAC5B,KAAK,KAAKA,EAAW,KAAK,CAC5B,CAAC,EAEDC,EAAS,iBAAiB,SAAU,IAAM,CACxC,IAAMC,EAAMD,EAAS,MAAM,KAAK,EAChCD,EAAW,MAAQE,EACnB,KAAK,KAAKA,CAAG,CACf,CAAC,EAED,KAAK,WAAaF,EAClB,KAAK,SAAWC,EAEhBF,EAAM,YAAYC,CAAU,EAC5BD,EAAM,YAAYE,CAAQ,EACnBF,CACT,CACF,ECzDO,IAAMI,GAAN,cAAmCC,EAAyB,CAKjE,YACEC,EACAC,EACAC,EACAC,EACAC,EACA,CACA,MAAMJ,EAAKC,EAAOC,EAAcC,CAAQ,EAV1C,KAAQ,OAAmC,KAC3C,KAAQ,eAAsC,CAAC,EAU7C,KAAK,QAAUC,CACjB,CAEA,OAAqB,CACnB,IAAMC,EAAM,KAAK,UAAU,EAC3B,OAAAA,EAAI,YAAY,KAAK,YAAY,CAAC,EAClCA,EAAI,YAAY,KAAK,cAAc,CAAC,EACpC,KAAK,KAAOA,EACLA,CACT,CAEA,SAASC,EAAqB,CAC5B,KAAK,MAAQA,EACT,KAAK,SAAQ,KAAK,OAAO,MAAQA,EACvC,CAES,YAAYC,EAAyB,CAC5C,MAAM,YAAYA,CAAQ,EACtB,KAAK,SAAQ,KAAK,OAAO,SAAWA,GACxC,QAAWC,KAAU,KAAK,eACxBA,EAAO,SAAWD,CAEtB,CAEQ,eAAgC,CACtC,IAAME,EAAQ,SAAS,cAAc,KAAK,EAC1CA,EAAM,aAAa,wBAAyB,EAAE,EAE9C,IAAMC,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,aAAa,mBAAoB,EAAE,EAE1C,QAAWC,KAAO,KAAK,QAAS,CAC9B,IAAMC,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,MAAQD,EAAI,MACnBC,EAAO,YAAcD,EAAI,MACrBA,EAAI,QAAU,KAAK,QAAOC,EAAO,SAAW,IAChDF,EAAO,YAAYE,CAAM,CAC3B,CAEAF,EAAO,iBAAiB,SAAU,IAAM,CACtC,KAAK,KAAKA,EAAO,KAAK,CACxB,CAAC,EAED,KAAK,OAASA,EAEd,IAAMG,EAAU,SAAS,cAAc,KAAK,EAC5C,OAAAA,EAAQ,aAAa,oBAAqB,EAAE,EAC5CA,EAAQ,YAAY,KAAK,oBAAoB,KAAM,EAAE,CAAC,EACtDA,EAAQ,YAAY,KAAK,oBAAoB,OAAQ,CAAC,CAAC,EAEvDJ,EAAM,YAAYC,CAAM,EACxBD,EAAM,YAAYI,CAAO,EAClBJ,CACT,CAEQ,oBAAoBK,EAA8BC,EAAsC,CAC9F,IAAMP,EAAS,SAAS,cAAc,QAAQ,EAC9C,OAAAA,EAAO,KAAO,SACdA,EAAO,aAAa,mBAAoB,EAAE,EAC1CA,EAAO,aAAa,2BAA4B,EAAE,EAClDA,EAAO,aAAa,iBAAkBM,CAAa,EACnDN,EAAO,UAAYQ,EACjB,GACAF,IAAkB,KAAO,cAAgB,eAC3C,EACAN,EAAO,iBAAiB,QAAS,IAAM,CACrC,GAAI,CAAC,KAAK,OAAQ,OAClB,IAAMS,EAAQ,KAAK,OAAO,QAAQ,OAClC,GAAIA,IAAU,EAAG,OAEjB,IAAMC,IADe,KAAK,OAAO,cACGH,GAAaE,EAASA,GAASA,EACnE,KAAK,OAAO,cAAgBC,EAC5B,KAAK,KAAK,KAAK,OAAO,KAAK,CAC7B,CAAC,EACD,KAAK,eAAe,KAAKV,CAAM,EACxBA,CACT,CACF,EC3FO,IAAMW,GAAN,cAAmCC,EAA0B,CAA7D,kCACL,KAAQ,SAAoC,KAC5C,KAAQ,OAA6B,KAErC,OAAqB,CACnB,IAAMC,EAAM,KAAK,UAAU,EAC3BA,EAAI,YAAY,KAAK,YAAY,CAAC,EAElC,IAAMC,EAAS,SAAS,cAAc,OAAO,EAC7CA,EAAO,aAAa,mBAAoB,EAAE,EAC1CA,EAAO,aAAa,eAAgB,OAAO,KAAK,KAAK,CAAC,EAEtD,IAAMC,EAAS,SAAS,cAAc,OAAO,EAC7CA,EAAO,KAAO,WACdA,EAAO,QAAU,KAAK,MACtBA,EAAO,aAAa,yBAA0B,EAAE,EAChD,KAAK,SAAWA,EAChB,KAAK,OAASD,EAEd,IAAME,EAAO,SAAS,cAAc,MAAM,EAC1C,OAAAA,EAAK,aAAa,wBAAyB,EAAE,EAE7CD,EAAO,iBAAiB,SAAU,IAAM,CACtC,IAAME,EAAOF,EAAO,QACpB,KAAK,MAAQE,EACbH,EAAO,aAAa,eAAgB,OAAOG,CAAI,CAAC,EAChD,KAAK,KAAKA,CAAI,CAChB,CAAC,EAEDH,EAAO,YAAYC,CAAM,EACzBD,EAAO,YAAYE,CAAI,EACvBH,EAAI,YAAYC,CAAM,EACtB,KAAK,KAAOD,EACLA,CACT,CAEA,SAASK,EAAsB,CAC7B,KAAK,MAAQA,EACT,KAAK,WAAU,KAAK,SAAS,QAAUA,GAC3C,KAAK,QAAQ,aAAa,eAAgB,OAAOA,CAAK,CAAC,CACzD,CAES,YAAYC,EAAyB,CAC5C,MAAM,YAAYA,CAAQ,EACtB,KAAK,WAAU,KAAK,SAAS,SAAWA,GAC5C,KAAK,QAAQ,aAAa,gBAAiBA,EAAW,OAAS,OAAO,CACxE,CACF,EC7BO,IAAMC,GAAN,KAAyB,CAAzB,cACL,KAAQ,OAA6B,CAAC,EACtC,KAAQ,aAAkC,CAAC,EAC3C,KAAQ,OAA8B,CAAC,EAWvC,MACEC,EACAC,EACAC,EACkB,CAClB,KAAK,QAAQ,EACb,KAAK,OAAS,CAAE,GAAGD,CAAO,EAC1B,IAAME,EAAe,CAACC,EAAaC,IAAe,CAChD,KAAK,OAAOD,CAAG,EAAIC,EACnB,KAAK,mBAAmB,EACxBH,EAASE,EAAKC,CAAK,CACrB,EAEMC,EAAW,SAAS,uBAAuB,EAC7CC,EAAe,SAAS,cAAc,KAAK,EAC/CA,EAAa,aAAa,0BAA2B,EAAE,EACvDD,EAAS,YAAYC,CAAY,EAEjC,QAAWC,KAAcR,EAAQ,CAC/B,GAAIQ,EAAW,OAAS,UAAW,CACjCD,EAAe,SAAS,cAAc,KAAK,EAC3CA,EAAa,aAAa,0BAA2B,EAAE,EACvDD,EAAS,YAAYC,CAAY,EACjC,QACF,CACA,IAAME,EAAQ,KAAK,YAAYD,EAAYP,EAAQE,CAAY,EAC3DM,IACF,KAAK,OAAO,KAAKA,CAAK,EACtB,KAAK,aAAa,KAAK,CAAE,WAAAD,EAAY,MAAAC,CAAM,CAAC,EAC5CF,EAAa,YAAYE,EAAM,MAAM,CAAC,EAE1C,CAEA,YAAK,mBAAmB,EAEjBH,CACT,CAKA,aAAaL,EAAmC,CAC9C,KAAK,OAAS,CAAE,GAAG,KAAK,OAAQ,GAAGA,CAAO,EAC1C,QAAWQ,KAAS,KAAK,OAAQ,CAC/B,IAAML,EAAOK,EAAc,IACvBL,GAAOA,KAAOH,GAChBQ,EAAM,SAASR,EAAOG,CAAG,CAAC,CAE9B,CACA,KAAK,mBAAmB,CAC1B,CAKA,SAAgB,CACd,QAAWK,KAAS,KAAK,OACvBA,EAAM,QAAQ,EAEhB,KAAK,OAAS,CAAC,EACf,KAAK,aAAe,CAAC,EACrB,KAAK,OAAS,CAAC,CACjB,CAEQ,YACND,EACAP,EACAC,EACyB,CACzB,OAAQM,EAAW,KAAM,CACvB,IAAK,SACH,OAAO,IAAIE,GACTF,EAAW,IACXA,EAAW,MACXP,EAAOO,EAAW,GAAG,GAAKA,EAAW,QACrCN,EACAM,EAAW,IACXA,EAAW,IACXA,EAAW,IACb,EAEF,IAAK,QACH,OAAO,IAAIG,GACTH,EAAW,IACXA,EAAW,MACXP,EAAOO,EAAW,GAAG,GAAKA,EAAW,QACrCN,EACAM,EAAW,IACXA,EAAW,IACXA,EAAW,KACXA,EAAW,kBACXA,EAAW,YACXA,EAAW,OACXA,EAAW,MACXP,EAAOO,EAAW,IAAM,MAAM,GAAKA,EAAW,WAChD,EAEF,IAAK,QACH,OAAO,IAAII,GACTJ,EAAW,IACXA,EAAW,MACXP,EAAOO,EAAW,GAAG,GAAKA,EAAW,QACrCN,CACF,EAEF,IAAK,SACH,OAAO,IAAIW,GACTL,EAAW,IACXA,EAAW,MACXP,EAAOO,EAAW,GAAG,GAAKA,EAAW,QACrCN,EACAM,EAAW,OACb,EAEF,IAAK,SACH,OAAO,IAAIM,GACTN,EAAW,IACXA,EAAW,MACXP,EAAOO,EAAW,GAAG,GAAKA,EAAW,QACrCN,CACF,EAEF,QACE,OAAO,IACX,CACF,CAEQ,oBAA2B,CACjC,QAAWa,KAAS,KAAK,aAAc,CACrC,IAAMC,EAAeD,EAAM,WAAW,aAChCE,EACJ,CAAC,CAACD,GAAgB,KAAK,OAAOA,EAAa,GAAG,IAAMA,EAAa,OACnED,EAAM,MAAM,YAAYE,CAAQ,CAClC,CACF,CACF,ECzJA,IAAMC,GAAsB,GACtBC,GAAyB,IACzBC,GAA0B,IAEnBC,GAAN,KAAc,CA2DnB,YACEC,EACAC,EACAC,EAoBAC,EACA,CA9DF,KAAQ,YAAsC,KAC9C,KAAQ,WAAqC,KAC7C,KAAQ,cAAsC,KAC9C,KAAQ,UAA4B,CAAC,EACrC,KAAQ,QAAwB,CAAC,EACjC,KAAQ,gBAAkB,SAC1B,KAAQ,iBAAmB,GAC3B,KAAQ,iBAAmB,GAC3B,KAAQ,mBAAoC,KAC5C,KAAQ,2BAA4C,KACpD,KAAQ,OAAS,GACjB,KAAQ,YAAc,GACtB,KAAQ,eAAiB,GACzB,KAAQ,qBAAuB,GAC/B,KAAQ,QAAU,GAiDhB,KAAK,OAASH,EACd,KAAK,gBAAkBC,EACvB,KAAK,MAAQC,EAAU,MACvB,KAAK,SAAWA,EAAU,SAC1B,KAAK,SAAWA,EAAU,SAC1B,KAAK,gBAAkBA,EAAU,gBACjC,KAAK,UAAYA,EAAU,UAC3B,KAAK,YAAcA,EAAU,YAC7B,KAAK,eAAiBA,EAAU,eAChC,KAAK,uBAAyBA,EAAU,uBACxC,KAAK,YAAcA,EAAU,YAC7B,KAAK,eAAiBA,EAAU,eAChC,KAAK,SAAWA,EAAU,SAC1B,KAAK,SAAWA,EAAU,SAC1B,KAAK,iBAAmBA,EAAU,iBAClC,KAAK,mBAAqBA,EAAU,mBACpC,KAAK,UAAYA,EAAU,UAC3B,KAAK,WAAaA,EAAU,WAC5B,KAAK,kBAAoBA,EAAU,kBACnC,KAAK,mBAAqBA,EAAU,mBACpC,KAAK,0BAA4B,KAAK,sBAAsB,KAAK,IAAI,EACrE,KAAK,qBAAuB,IAAM,KAAK,mBAAmB,EAE1D,KAAK,QAAU,KAAK,cAAc,EAClC,KAAK,QAAU,KAAK,cAAc,EAClC,KAAK,MAAQ,KAAK,gBAAgB,EAClC,KAAK,SAAW,KAAK,eAAe,EACpC,KAAK,YAAc,KAAK,kBAAkB,EAC1C,KAAK,YAAc,KAAK,kBAAkB,EAEtCC,GAAS,gBAAkB,IAC7B,KAAK,QAAQ,YAAY,KAAK,OAAO,EAEvC,KAAK,MAAM,YAAY,KAAK,QAAQ,EACpC,KAAK,MAAM,YAAY,KAAK,WAAW,EACvC,KAAK,MAAM,YAAY,KAAK,WAAW,EACvC,KAAK,QAAQ,YAAY,KAAK,KAAK,EACnC,SAAS,iBAAiB,cAAe,KAAK,yBAAyB,EACvE,OAAO,iBAAiB,SAAU,KAAK,oBAAoB,EAC3D,OAAO,gBAAgB,iBAAiB,SAAU,KAAK,oBAAoB,EAC3E,OAAO,gBAAgB,iBAAiB,SAAU,KAAK,oBAAoB,CAC7E,CAEA,QACEC,EACAC,EACAC,EACAC,EACAC,EACM,CACN,KAAK,UAAY,CAAC,GAAGJ,CAAS,EAC9B,KAAK,QAAU,CAAC,GAAGC,CAAO,EAC1B,KAAK,gBAAkBC,EAAW,KAAK,GAAK,SAC5C,KAAK,iBAAmBC,EACxB,KAAK,iBAAmBC,EAEtB,KAAK,oBACL,CAACJ,EAAU,KAAMK,GAAaA,EAAS,KAAO,KAAK,kBAAkB,GAErE,KAAK,eAAe,EAGpB,KAAK,4BACL,CAAC,KAAK,QAAQ,KAAMC,GAAWA,EAAO,KAAO,KAAK,0BAA0B,IAE5E,KAAK,2BAA6B,MAEpC,KAAK,YAAY,MAAQ,KAAK,gBAC9B,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,WAAW,EAChB,KAAK,kBAAkB,CACzB,CAEA,SAAgB,CACd,KAAK,eAAe,QAAQ,EAC5B,SAAS,oBAAoB,cAAe,KAAK,yBAAyB,EAC1E,OAAO,oBAAoB,SAAU,KAAK,oBAAoB,EAC9D,OAAO,gBAAgB,oBAAoB,SAAU,KAAK,oBAAoB,EAC9E,OAAO,gBAAgB,oBAAoB,SAAU,KAAK,oBAAoB,EAC1E,KAAK,aACP,KAAK,MAAM,OAAO,EAEpB,KAAK,QAAQ,OAAO,CACtB,CAEA,mBAAuC,CACrC,OAAO,KAAK,OACd,CAEA,eAAgC,CAC9B,OAAO,KAAK,OACd,CAEA,YAAYC,EAAwB,CAClC,KAAK,QAAQ,aAAa,iBAAkBA,CAAQ,EACpD,KAAK,QAAQ,aAAa,iBAAkBA,CAAQ,EACpD,KAAK,MAAM,aAAa,iBAAkBA,CAAQ,EAClD,KAAK,SAAS,aAAa,iBAAkBA,CAAQ,EACrD,KAAK,YAAY,aAAa,iBAAkBA,CAAQ,EACxD,KAAK,YAAY,aAAa,iBAAkBA,CAAQ,CAC1D,CAEA,kBAAkBC,EAAcC,EAAcC,EAAkC,WAAkB,CAChG,KAAK,QAAQ,aAAa,eAAgB,MAAM,EAChD,IAAMC,EAAkBD,IAAU,YAAc,wBAA0B,GAC1E,KAAK,QAAQ,MAAM,UAAY,eAAe,KAAK,MAAMF,CAAI,CAAC,OAAO,KAAK,MAAMC,CAAI,CAAC,SAASE,CAAe,GAC7G,KAAK,mBAAmB,CAC1B,CAEA,iBAAiBC,EAAwB,CACvC,KAAK,QAAQ,aAAa,eAAgBA,EAAU,OAAS,OAAO,CACtE,CAEA,WAAqB,CACnB,OAAO,KAAK,MACd,CAEA,2BAAqC,CACnC,OAAO,KAAK,oBACd,CAEA,WAAWC,EAAwB,CACjC,KAAK,QAAUA,EACVA,GAAS,KAAK,KAAK,EACxB,KAAK,QAAQ,MAAM,QAAUA,EAAU,GAAK,MAC9C,CAEA,WAAqB,CACnB,OAAO,KAAK,OACd,CAEQ,eAAgC,CACtC,OAAOC,GAAU,CACnB,CAEQ,eAAmC,CACzC,IAAMC,EAAUC,GAAe,CAC7B,KAAM,WACN,MAAO,qBACP,UAAW,CAAC,QAAQ,EACpB,MAAO,CACL,oBAAqB,SACrB,YAAa,QACb,aAAc,UACd,cAAe,QACf,gBAAiB,OACnB,CACF,CAAC,EACD,OAAAD,EAAQ,iBAAiB,QAAUE,GAAU,CAC3CA,EAAM,gBAAgB,EACtB,KAAK,OAAO,CACd,CAAC,EACMF,CACT,CAEQ,iBAAkC,CACxC,IAAMG,EAAQC,GAAU,EAElBC,EAASC,GAAgB,EAE/B,KAAK,YAAc,SAAS,cAAc,OAAO,EACjD,KAAK,YAAY,aAAa,kBAAmB,EAAE,EACnD,KAAK,YAAY,aAAa,wBAAyB,EAAE,EACzD,KAAK,YAAY,KAAO,OACxB,KAAK,YAAY,MAAQ,KAAK,gBAC9B,KAAK,YAAY,iBAAiB,OAAQ,IAAM,CAC9C,IAAMC,EAAY,KAAK,YAAY,MAAM,KAAK,GAAK,SAC/CA,IAAc,KAAK,kBACrB,KAAK,gBAAkBA,EACvB,KAAK,mBAAmBA,CAAS,GAEnC,KAAK,YAAY,MAAQA,CAC3B,CAAC,EACD,KAAK,YAAY,iBAAiB,UAAYL,GAAU,CACtDA,EAAM,gBAAgB,EAClBA,EAAM,MAAQ,SAAS,KAAK,YAAY,KAAK,EAC7CA,EAAM,MAAQ,WAChB,KAAK,YAAY,MAAQ,KAAK,gBAAgB,KAAK,GAAK,SACxD,KAAK,YAAY,KAAK,EAE1B,CAAC,EACD,KAAK,YAAY,iBAAiB,QAAUA,GAAU,CACpDA,EAAM,gBAAgB,EACtB,KAAK,uBAAuB,CAC9B,CAAC,EAED,KAAK,qBAAuBD,GAAe,CACzC,KAAM,UACN,MAAO,kBACP,UAAW,CAAC,SAAU,MAAM,EAC5B,MAAO,CAAE,cAAe,OAAQ,CAClC,CAAC,EACD,KAAK,qBAAqB,iBAAiB,QAAUC,GAAU,CAC7DA,EAAM,gBAAgB,EAClB,KAAK,qBAAsB,KAAK,iBAAiB,EAChD,KAAK,gBAAgB,CAC5B,CAAC,EAED,IAAMM,EAAcP,GAAe,CACjC,KAAM,QACN,MAAO,sBACP,UAAW,CAAC,OAAO,CACrB,CAAC,EACDO,EAAY,iBAAiB,QAAUN,GAAU,CAC/CA,EAAM,gBAAgB,EACtB,KAAK,KAAK,CACZ,CAAC,EAED,KAAK,gBAAkBD,GAAe,CACpC,KAAM,OACN,MAAO,mBACP,UAAW,CAAC,SAAU,MAAM,EAC5B,MAAO,CAAE,cAAe,OAAQ,CAClC,CAAC,EACD,KAAK,gBAAgB,iBAAiB,QAAUC,GAAU,CACxDA,EAAM,gBAAgB,EACtB,KAAK,aAAa,CACpB,CAAC,EAEDG,EAAO,YAAY,KAAK,WAAW,EACnCA,EAAO,YAAY,KAAK,eAAe,EACvCA,EAAO,YAAYG,CAAW,EAE9B,IAAMC,EAAa,SAAS,cAAc,KAAK,EAC/C,OAAAA,EAAW,aAAa,6BAA8B,EAAE,EAExD,KAAK,eAAiB,SAAS,cAAc,KAAK,EAClD,KAAK,eAAe,aAAa,uBAAwB,EAAE,EAE3DA,EAAW,YAAY,KAAK,oBAAoB,EAChDA,EAAW,YAAY,KAAK,cAAc,EAE1C,KAAK,cAAgBC,GAAiB,CAAE,wBAAyB,EAAG,CAAC,EAErE,KAAK,eAAiBC,GAAgB,CACpC,KAAM,OACN,MAAO,mBACP,UAAW,GACX,MAAO,CAAE,cAAe,OAAQ,CAClC,CAAC,EACD,KAAK,eAAe,iBAAiB,QAAUT,GAAU,CACvDA,EAAM,gBAAgB,EACtB,KAAK,aAAa,CACpB,CAAC,EAED,KAAK,cAAc,YAAY,KAAK,cAAc,EAElDC,EAAM,YAAYE,CAAM,EACxBF,EAAM,YAAYM,CAAU,EAC5BN,EAAM,YAAY,KAAK,aAAa,EAC7BA,CACT,CAEQ,gBAAiC,CACvC,IAAMA,EAAQC,GAAU,CAAE,aAAc,KAAM,CAAC,EACzCC,EAASC,GAAgB,EAEzBE,EAAcP,GAAe,CACjC,KAAM,QACN,MAAO,cACP,UAAW,CAAC,OAAO,CACrB,CAAC,EACD,OAAAO,EAAY,iBAAiB,QAAUN,GAAU,CAC/CA,EAAM,gBAAgB,EACtB,KAAK,cAAc,CACrB,CAAC,EACDG,EAAO,YAAYG,CAAW,EAE9B,KAAK,YAAcE,GAAiB,CAClC,iCAAkC,GAClC,6BAA8B,EAChC,CAAC,EACD,KAAK,mBAAmB,EAExBP,EAAM,YAAYE,CAAM,EACxBF,EAAM,YAAY,KAAK,WAAW,EAC3BA,CACT,CAEQ,oBAA2B,CAGjC,GAFA,KAAK,YAAY,UAAY,GAEzB,KAAK,gBAAgB,OAAS,EAAG,CACnC,IAAMS,EAAQ,SAAS,cAAc,KAAK,EAC1CA,EAAM,aAAa,kCAAmC,EAAE,EACxDA,EAAM,YAAc,6BACpB,KAAK,YAAY,YAAYA,CAAK,EAClC,MACF,CAEA,OAAW,CAAC,CAAEC,CAAO,IAAK,KAAK,gBAAiB,CAC9C,IAAMC,EAAOH,GAAgB,CAAE,KAAM,GAAI,MAAOE,EAAQ,MAAO,UAAW,EAAK,CAAC,EAChFC,EAAK,UAAY,GAAGD,EAAQ,KAAK,QAAQ,OAAQ,wBAAwB,CAAC,SAASA,EAAQ,KAAK,UAChGC,EAAK,iBAAiB,QAAUZ,GAAU,CACxCA,EAAM,gBAAgB,EACtB,KAAK,MAAMW,EAAQ,IAAI,EACvB,KAAK,cAAc,CACrB,CAAC,EACD,KAAK,YAAY,YAAYC,CAAI,CACnC,CACF,CAEQ,mBAAoC,CAC1C,IAAMX,EAAQC,GAAU,CAAE,aAAc,QAAS,CAAC,EAC5CC,EAASC,GAAgB,EAE/B,KAAK,gBAAkBL,GAAe,CACpC,KAAM,OACN,MAAO,mBACP,UAAW,CAAC,SAAU,MAAM,EAC5B,MAAO,CAAE,cAAe,OAAQ,CAClC,CAAC,EACD,KAAK,gBAAgB,iBAAiB,QAAUC,GAAU,CACxDA,EAAM,gBAAgB,EACtB,KAAK,YAAY,CACnB,CAAC,EAED,IAAMM,EAAcP,GAAe,CACjC,KAAM,QACN,MAAO,cACP,UAAW,CAAC,OAAO,CACrB,CAAC,EACDO,EAAY,iBAAiB,QAAUN,GAAU,CAC/CA,EAAM,gBAAgB,EACtB,KAAK,iBAAiB,CACxB,CAAC,EAEDG,EAAO,YAAY,KAAK,eAAe,EACvCA,EAAO,YAAYG,CAAW,EAE9B,KAAK,mBAAqBE,GAAiB,EAE3C,KAAK,gBAAkBA,GAAiB,CAAE,6BAA8B,EAAG,CAAC,EAE5E,IAAMK,EAAeJ,GAAgB,CACnC,KAAM,SACN,MAAO,SACP,UAAW,GACX,MAAO,CAAE,UAAW,QAAS,CAC/B,CAAC,EACDI,EAAa,iBAAiB,QAAUb,GAAU,CAChDA,EAAM,gBAAgB,EACtB,KAAK,SAAS,CAChB,CAAC,EAED,IAAMc,EAAeL,GAAgB,CACnC,KAAM,SACN,MAAO,SACP,UAAW,GACX,MAAO,CAAE,UAAW,QAAS,CAC/B,CAAC,EACDK,EAAa,iBAAiB,QAAUd,GAAU,CAChDA,EAAM,gBAAgB,EACtB,KAAK,SAAS,CAChB,CAAC,EAED,KAAK,gBAAgB,YAAYa,CAAY,EAC7C,KAAK,gBAAgB,YAAYC,CAAY,EAE7C,IAAMC,EAAK,SAAS,cAAc,MAAM,EACxC,OAAAA,EAAG,aAAa,qBAAsB,EAAE,EAExCd,EAAM,YAAYE,CAAM,EACxBF,EAAM,YAAY,KAAK,kBAAkB,EACzCA,EAAM,YAAYc,CAAE,EACpBd,EAAM,YAAY,KAAK,eAAe,EAC/BA,CACT,CAEQ,mBAAoC,CAC1C,IAAMA,EAAQC,GAAU,CAAE,aAAc,QAAS,CAAC,EAC5CC,EAASC,GAAgB,EAE/B,KAAK,WAAa,SAAS,cAAc,MAAM,EAC/C,KAAK,WAAW,aAAa,2BAA4B,EAAE,EAC3D,KAAK,WAAW,aAAa,wBAAyB,EAAE,EAExD,KAAK,YAAc,SAAS,cAAc,MAAM,EAChD,KAAK,YAAY,iBAAiB,QAAUJ,GAAU,CACpDA,EAAM,gBAAgB,EACtB,KAAK,kBAAkB,CACzB,CAAC,EAED,IAAMM,EAAcP,GAAe,CACjC,KAAM,QACN,MAAO,qBACP,UAAW,CAAC,OAAO,CACrB,CAAC,EACD,OAAAO,EAAY,iBAAiB,QAAUN,GAAU,CAC/CA,EAAM,gBAAgB,EACtB,KAAK,iBAAiB,CACxB,CAAC,EAEDG,EAAO,YAAY,KAAK,UAAU,EAClCA,EAAO,YAAY,KAAK,WAAW,EACnCA,EAAO,YAAYG,CAAW,EAE9B,KAAK,cAAgB,SAAS,cAAc,KAAK,EACjD,KAAK,cAAc,aAAa,8BAA+B,EAAE,EAEjEL,EAAM,YAAYE,CAAM,EACxBF,EAAM,YAAY,KAAK,aAAa,EAC7BA,CACT,CACQ,mBAA0B,CAChC,KAAK,eAAe,UAAY,GAChC,IAAMe,EAAsBC,GAAqB,CAC/C,KAAK,iBAAmBA,EACxB,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,CAC5B,EAGA,CAAC,GAAG,KAAK,OAAO,EAAE,QAAQ,EAAE,QAAS5B,GAAW,CAC9C,IAAM6B,EAAOT,GAAgB,CAAE,KAAM,GAAI,MAAO,UAAUpB,EAAO,KAAK,SAAU,CAAC,EACjF6B,EAAK,UAAY,SAAS7B,EAAO,KAAK,UACtC6B,EAAK,aAAa,cAAe,OAAO7B,EAAO,KAAO,KAAK,gBAAgB,CAAC,EAC5E6B,EAAK,aAAa,gBAAiB,OAAO7B,EAAO,KAAO,KAAK,gBAAgB,CAAC,EAC9E6B,EAAK,aAAa,YAAa7B,EAAO,KAAK,EAC3C6B,EAAK,iBAAiB,QAAUlB,GAAU,CACxCA,EAAM,gBAAgB,EACtBgB,EAAmB3B,EAAO,EAAE,EAC5B,KAAK,eAAeA,EAAO,EAAE,CAC/B,CAAC,EACD,KAAK,eAAe,YAAY6B,CAAI,CACtC,CAAC,EACD,KAAK,qBAAqB,aAAa,cAAe,OAAO,KAAK,oBAAoB,CAAC,CACzF,CAEQ,sBAA6B,CACnC,KAAK,mBAAmB,UAAY,GACpC,KAAK,gBAAgB,MAAM,QAAU,KAAK,QAAQ,QAAU,EAAc,OAAS,GACnF,GAAM,CAAE,eAAAC,EAAgB,WAAAC,CAAW,EAAI,KAAK,uBAAuB,EACnE,KAAK,mBAAmB,YAAYD,CAAc,EAClD,KAAK,mBAAmB,YAAYC,CAAU,CAChD,CAEQ,wBAAyF,CAC/F,IAAMC,EAAiB,CAAC,GAAG,KAAK,OAAO,EAAE,QAAQ,EAC3CC,EAAYD,EAAe,OAAS,EAEpCF,EAAiB,SAAS,cAAc,KAAK,EACnDA,EAAe,aAAa,8BAA+B,EAAE,EAE7D,IAAMC,EAAa,SAAS,cAAc,KAAK,EAC/CA,EAAW,aAAa,wBAAyB,EAAE,EAEnD,IAAMG,EAAU,eAAe,KAAK,IAAI,CAAC,GAEnCC,EAAgB,SAAS,cAAc,MAAM,EACnDA,EAAc,UAAYC,EAAoB,GAAI,QAAS,QAAQ,EAEnE,IAAMC,EAAc,SAAS,cAAc,OAAO,EAClDA,EAAY,GAAKH,EACjBG,EAAY,KAAO,SACnBA,EAAY,UAAY,UACxBA,EAAY,KAAO,IACnBA,EAAY,IAAM,IAClBA,EAAY,aAAa,kBAAmB,EAAE,EAE9C,IAAMC,EAAU,SAAS,cAAc,OAAO,EAC9CA,EAAQ,QAAUJ,EAClBI,EAAQ,aAAa,gCAAiC,EAAE,EACxDA,EAAQ,YAAc,KAEtBP,EAAW,YAAYI,CAAa,EACpCJ,EAAW,YAAYM,CAAW,EAClCN,EAAW,YAAYO,CAAO,EAE9B,IAAIC,EAAgC,KAChCC,EAA2C,KAC3CC,EAAc,EAEZC,EAAY,CAChBd,EACAe,EACAC,EACAC,EAAa,KACV,CACHL,GAAgB,aAAa,cAAe,OAAO,EACnDD,EAAiBX,EACjBY,EAAiBI,EACjBH,EAAcE,EACd,KAAK,2BAA6Bf,EAClCgB,EAAS,aAAa,cAAe,MAAM,EAC3CP,EAAY,MAAQ,OAAOM,CAAY,EACnCE,IACFR,EAAY,MAAM,EAClBA,EAAY,OAAO,EAEvB,EAEMS,EAAe,IAAM,CAEzB,GADI,CAACP,GACD,CAACF,EAAY,YAAa,OAC9B,IAAMU,EAAS,OAAO,SAASV,EAAY,MAAO,EAAE,EACpD,GAAI,OAAO,SAASU,CAAM,GAAKA,GAAU,EAAG,CAC1C,GAAIA,IAAWN,EAAa,OAC5BA,EAAcM,EACd,KAAK,uBAAuBR,EAAgBQ,CAAM,CACpD,MACEV,EAAY,MAAQ,OAAOI,CAAW,CAE1C,EAEAJ,EAAY,iBAAiB,UAAY1B,GAAU,CAEjD,GADAA,EAAM,gBAAgB,EAClBA,EAAM,MAAQ,QAAS,CACzBmC,EAAa,EACb,MACF,CACInC,EAAM,MAAQ,WAChB0B,EAAY,MAAQ,OAAOI,CAAW,EACtCJ,EAAY,KAAK,EAErB,CAAC,EACDA,EAAY,iBAAiB,OAAQ,IAAM,sBAAsBS,CAAY,CAAC,EAC9ET,EAAY,iBAAiB,QAAU1B,GAAUA,EAAM,gBAAgB,CAAC,EAExE,IAAIqC,EAAmF,KAoDvF,GAlDAhB,EAAe,QAAQ,CAAChC,EAAQiD,IAAU,CACxC,IAAMC,EAAa,SAAS,cAAc,KAAK,EAC/CA,EAAW,aAAa,mCAAoC,EAAE,EAE9D,IAAMC,EAAY,SAAS,cAAc,MAAM,EAI/C,GAHAA,EAAU,YAAcnD,EAAO,MAC/BkD,EAAW,YAAYC,CAAS,EAE5BlB,GAAagB,GAAS,EAAa,CACrC,IAAMG,EAAYC,GAAiB,UAAUrD,EAAO,KAAK,SAAS,EAClEoD,EAAU,iBAAiB,cAAgBzC,GAAUA,EAAM,gBAAgB,CAAC,EAC5EyC,EAAU,iBAAiB,QAAUzC,GAAU,CAC7CA,EAAM,eAAe,EACrBA,EAAM,gBAAgB,EAClB,KAAK,QAAQ,OAAS,GAAa,KAAK,eAAeX,EAAO,EAAE,CACtE,CAAC,EACDkD,EAAW,YAAYE,CAAS,CAClC,CAIA,GAFAtB,EAAe,YAAYoB,CAAU,EAEjCD,EAAQjB,EAAe,OAAS,EAAG,CACrC,IAAMsB,EAAetB,EAAeiB,EAAQ,CAAC,EACvCM,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,KAAO,SACdA,EAAO,aAAa,mBAAoB,EAAE,EAC1CA,EAAO,aAAa,oCAAqC,EAAE,EAC3DA,EAAO,aAAa,cAAe,OAAO,EAC1CA,EAAO,aAAa,aAAc,QAAQD,EAAa,KAAK,aAAa,EAEzE,IAAME,EAAa,SAAS,cAAc,MAAM,EAChDA,EAAW,YAAc,OAAOF,EAAa,QAAQ,EACrDC,EAAO,YAAYC,CAAU,EAE7BD,EAAO,iBAAiB,QAAU5C,GAAU,CAC1CA,EAAM,gBAAgB,EACtB+B,EAAUY,EAAa,GAAIA,EAAa,SAAUC,EAAQ,EAAI,CAChE,CAAC,EAEDzB,EAAe,YAAYyB,CAAM,GAG/B,KAAK,6BAA+BD,EAAa,IAChDN,IAAkB,MAAQ,KAAK,6BAA+B,QAE/DA,EAAgB,CAAE,SAAUM,EAAa,GAAI,MAAOA,EAAa,SAAU,GAAIC,CAAO,EAE1F,CACF,CAAC,EAEGP,IAAkB,KAAM,CAC1B,IAAM,EAAIA,EACVN,EAAU,EAAE,SAAU,EAAE,MAAO,EAAE,EAAE,CACrC,CAEA,MAAO,CAAE,eAAAZ,EAAgB,WAAAC,CAAW,CACtC,CAEQ,mBAA0B,CAClB,KAAK,eAAe,iBAAiB,qCAAqC,EAClF,QAASF,GAAS,CACtB,IAAM4B,EAAO5B,EAAK,aAAa,WAAW,EACpC7B,EAAS,KAAK,QAAQ,KAAM0D,GAAMA,EAAE,QAAUD,CAAI,EACnDzD,IACL6B,EAAK,aAAa,cAAe,OAAO7B,EAAO,KAAO,KAAK,gBAAgB,CAAC,EAC5E6B,EAAK,aAAa,gBAAiB,OAAO7B,EAAO,KAAO,KAAK,gBAAgB,CAAC,EAChF,CAAC,CACH,CAEQ,YAAmB,CACzB,KAAO,KAAK,eAAe,aACzB,KAAK,cAAc,YAAY,KAAK,eAAe,WAAW,EAEhE,QAAWD,KAAY,KAAK,UAAW,CACrC,IAAMuB,EAAU,KAAK,gBAAgB,IAAIvB,EAAS,IAAI,EACtD,GAAI,CAACuB,EAAS,SACd,IAAMC,EAAO,SAAS,cAAc,KAAK,EACzCA,EAAK,aAAa,4BAA6B,EAAE,EACjDA,EAAK,aAAa,mBAAoB,EAAE,EACxCA,EAAK,aAAa,0BAA2B,EAAE,EAC/CA,EAAK,aAAa,cAAe,OAAOxB,EAAS,KAAO,KAAK,kBAAkB,CAAC,EAChFwB,EAAK,UAAY,GAAGa,EAAoB,GAAI,OAAQ,QAAQ,CAAC,GAAGd,EAAQ,KAAK,QAAQ,OAAQ,wBAAwB,CAAC,SAASvB,EAAS,MAAM,KAAK,GAAKuB,EAAQ,KAAK,UACrK,IAAMqC,EAAS,KAAK,aAAa5D,EAAS,QAAS,IAAM,KAAK,SAASA,EAAS,EAAE,CAAC,EAC7E6D,EAAeP,GAAiB,UAAUtD,EAAS,MAAM,KAAK,GAAK,UAAU,EAAE,EACrF6D,EAAa,iBAAiB,QAAUjD,GAAU,CAChDA,EAAM,gBAAgB,EAClB,KAAK,qBAAuBZ,EAAS,IAAI,KAAK,iBAAiB,EACnE,KAAK,SAASA,EAAS,EAAE,CAC3B,CAAC,EACDwB,EAAK,YAAYoC,CAAM,EACvBpC,EAAK,YAAYqC,CAAY,EAC7BrC,EAAK,iBAAiB,QAAS,IAAM,CAC/B,KAAK,qBAAuBxB,EAAS,GAAI,KAAK,iBAAiB,EAC9D,KAAK,eAAeA,EAAS,EAAE,CACtC,CAAC,EAGDwB,EAAK,aAAa,YAAa,MAAM,EACrCA,EAAK,iBAAiB,YAAcZ,GAAU,CAC5CA,EAAM,gBAAgB,EACtBA,EAAM,cAAc,QAAQ,aAAcZ,EAAS,EAAE,EACrDwB,EAAK,aAAa,gBAAiB,MAAM,CAC3C,CAAC,EACDA,EAAK,iBAAiB,UAAW,IAAM,CACrCA,EAAK,gBAAgB,eAAe,EACpC,KAAK,cACF,iBAA8B,kBAAkB,EAChD,QAASsC,GAAOA,EAAG,gBAAgB,gBAAgB,CAAC,CACzD,CAAC,EACDtC,EAAK,iBAAiB,WAAaZ,GAAU,CAC3CA,EAAM,eAAe,EACrBA,EAAM,gBAAgB,EACtB,IAAMmD,EAAOvC,EAAK,sBAAsB,EAClCwC,EAAYpD,EAAM,QAAUmD,EAAK,IAAMA,EAAK,OAAS,EAAI,SAAW,QAC1E,KAAK,cACF,iBAA8B,kBAAkB,EAChD,QAASD,GAAOA,EAAG,gBAAgB,gBAAgB,CAAC,EACvDtC,EAAK,aAAa,iBAAkBwC,CAAS,CAC/C,CAAC,EACDxC,EAAK,iBAAiB,YAAcZ,GAAU,CACvCY,EAAK,SAASZ,EAAM,aAAqB,GAC5CY,EAAK,gBAAgB,gBAAgB,CAEzC,CAAC,EACDA,EAAK,iBAAiB,OAASZ,GAAU,CACvCA,EAAM,eAAe,EACrBA,EAAM,gBAAgB,EACtB,IAAMqD,EAAYrD,EAAM,cAAc,QAAQ,YAAY,EAE1D,GADAY,EAAK,gBAAgB,gBAAgB,EACjC,CAACyC,GAAaA,IAAcjE,EAAS,GAAI,OAC7C,IAAM+D,EAAOvC,EAAK,sBAAsB,EAClCwC,EACJpD,EAAM,QAAUmD,EAAK,IAAMA,EAAK,OAAS,EAAI,SAAW,QAC1D,KAAK,UAAUE,EAAWjE,EAAS,GAAIgE,CAAS,CAClD,CAAC,EAED,KAAK,cAAc,YAAYxC,CAAI,CACrC,CACA,KAAK,eAAe,aAAa,aAAc,OAAO,KAAK,UAAU,SAAW,CAAC,CAAC,EAClF,IAAM0C,EAAe,KAAK,UAAU,OAAS,EAC7C,KAAK,eAAe,MAAM,QAAUA,EAAe,OAAS,GAC5D,KAAK,gBAAgB,MAAM,QAAUA,EAAe,GAAK,MAC3D,CAEQ,mBAA0B,CAChC,GAAI,CAAC,KAAK,mBAAoB,CAC5B,KAAK,kBAAkB,EACvB,MACF,CACA,IAAMlE,EAAW,KAAK,UAAU,KAAMmE,GAAUA,EAAM,KAAO,KAAK,kBAAkB,EACpF,GAAI,CAACnE,EAAU,CACb,KAAK,eAAe,EACpB,MACF,CACA,IAAMuB,EAAU,KAAK,gBAAgB,IAAIvB,EAAS,IAAI,EACtD,GAAI,CAACuB,EAAS,CACZ,KAAK,eAAe,EACpB,MACF,CACI,KAAK,aACP,KAAK,WAAW,UAAYA,EAAQ,KAAK,QACvC,OACA,8CACF,GAEE,KAAK,cAAa,KAAK,YAAY,YAAcvB,EAAS,MAAM,KAAK,GAAKuB,EAAQ,OACtF,KAAK,eAAe,QAAQ,EAC5B,KAAK,cAAgB,IAAI6C,GACzB,IAAMC,EAAa,KAAK,cAAc,MACpC9C,EAAQ,YAAY,EACpBvB,EAAS,SACT,CAACsE,EAAKC,IAAU,KAAK,gBAAgBvE,EAAS,GAAIsE,EAAKC,CAAK,CAC9D,EACA,KAAO,KAAK,cAAc,YACxB,KAAK,cAAc,YAAY,KAAK,cAAc,UAAU,EAE9D,KAAK,cAAc,YAAYF,CAAU,EACzC,KAAK,YAAY,aAAa,YAAa,MAAM,EACjD,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,CAC1B,CAEQ,aAAaG,EAAkBC,EAAwC,CAC7E,IAAMC,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,aAAa,mBAAoB,EAAE,EACzCA,EAAM,aAAa,eAAgB,OAAOF,CAAO,CAAC,EAClD,IAAMG,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,KAAO,WACbA,EAAM,QAAUH,EAChBG,EAAM,aAAa,yBAA0B,EAAE,EAC/CA,EAAM,iBAAiB,SAAW/D,GAAU,CAC1CA,EAAM,gBAAgB,EACtB6D,EAAS,CACX,CAAC,EACD,IAAMG,EAAO,SAAS,cAAc,MAAM,EAC1C,OAAAA,EAAK,aAAa,wBAAyB,EAAE,EAC7CF,EAAM,iBAAiB,QAAU9D,GAAUA,EAAM,gBAAgB,CAAC,EAClE8D,EAAM,YAAYC,CAAK,EACvBD,EAAM,YAAYE,CAAI,EACfF,CACT,CAEQ,mBAA0B,CAChC,GAAI,CAAC,KAAK,oBAAsB,CAAC,KAAK,YAAa,OACnD,IAAM1E,EAAW,KAAK,UAAU,KAAMmE,GAAUA,EAAM,KAAO,KAAK,kBAAkB,EACpF,GAAI,CAACnE,EAAU,OACf,IAAMuB,EAAU,KAAK,gBAAgB,IAAIvB,EAAS,IAAI,EACtD,GAAI,CAACuB,EAAS,OACd,IAAMsD,EAAc7E,EAAS,MAAM,KAAK,GAAKuB,EAAQ,MAC/CuD,EAAS,KAAK,YAAY,cAChC,GAAI,CAACA,EAAQ,OACb,IAAMH,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,aAAa,kBAAmB,EAAE,EACxCA,EAAM,KAAO,OACbA,EAAM,MAAQE,EACd,IAAME,EAAS,IAAM,CACnB,IAAMC,EAAWL,EAAM,MAAM,KAAK,EAC9BK,IAAaH,GAAa,KAAK,iBAAiB7E,EAAS,GAAIgF,CAAQ,EACrEF,EAAO,SAASH,CAAK,GAAGG,EAAO,aAAa,KAAK,YAAcH,CAAK,CAC1E,EACAA,EAAM,iBAAiB,OAAQI,CAAM,EACrCJ,EAAM,iBAAiB,UAAY/D,GAAU,CACvCA,EAAM,MAAQ,SAAS+D,EAAM,KAAK,EAClC/D,EAAM,MAAQ,WAChB+D,EAAM,MAAQE,EACdF,EAAM,KAAK,EAEf,CAAC,EACDA,EAAM,iBAAiB,QAAU/D,GAAUA,EAAM,gBAAgB,CAAC,EAClE+D,EAAM,iBAAiB,cAAgB/D,GAAUA,EAAM,gBAAgB,CAAC,EACxEkE,EAAO,aAAaH,EAAO,KAAK,WAAW,EAC3CA,EAAM,MAAM,EACZA,EAAM,OAAO,CACf,CAEQ,wBAA+B,CACrC,KAAK,YAAY,OAAO,CAC1B,CAEQ,cAAqB,CAC3B,KAAK,eAAiB,GACtB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,SAAS,aAAa,YAAa,MAAM,EAC9C,KAAK,mBAAmB,CAC1B,CAEQ,eAAsB,CAC5B,KAAK,eAAiB,GACtB,KAAK,SAAS,aAAa,YAAa,OAAO,EAC/C,KAAK,mBAAmB,CAC1B,CAEQ,iBAAwB,CAC9B,KAAK,qBAAuB,GAC5B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,YAAY,aAAa,YAAa,MAAM,EACjD,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,CACzB,CAEQ,kBAAyB,CAC/B,KAAK,qBAAuB,GAC5B,KAAK,YAAY,aAAa,YAAa,OAAO,EAClD,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,CAC1B,CAEQ,kBAAyB,CAC/B,GAAI,KAAK,kBAAkB,EAAG,CAC5B,KAAK,YAAY,MAAM,eAAe,KAAK,EAC3C,MACF,CAEA,GAAI,KAAK,QAAQ,aAAa,gBAAgB,IAAM,aAAc,CAChE,KAAK,YAAY,MAAM,eAAe,KAAK,EAC3C,MACF,CAEA,IAAMM,EAAU,KAAK,qBAAqB,sBAAsB,EAC1DC,EAAgB,KAAK,MAAM,sBAAsB,EACvD,KAAK,YAAY,MAAM,IAAM,GAAGD,EAAQ,IAAMC,EAAc,GAAG,IACjE,CAEQ,eAAeC,EAA0B,CAC/C,KAAK,mBAAqBA,EAC1B,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,kBAAkB,CACzB,CAEQ,kBAAyB,CAC/B,KAAK,eAAe,EACpB,KAAK,WAAW,CAClB,CAEQ,gBAAuB,CAC7B,KAAK,mBAAqB,KAC1B,KAAK,kBAAkB,CACzB,CAEQ,mBAA0B,CAChC,IAAMC,EAAU,KAAK,cACrB,KAAK,cAAgB,KACrB,KAAK,YAAY,aAAa,YAAa,OAAO,EAClD,KAAK,mBAAmB,EACxB,OAAO,WAAW,IAAM,CAClB,KAAK,YAAY,aAAa,WAAW,IAAM,UACjDA,GAAS,QAAQ,EACjB,KAAK,cAAc,UAAY,GAC/B,KAAK,YAAY,MAAM,eAAe,KAAK,EAE/C,EAAG,GAAG,CACR,CAEQ,kBAAyB,CAC/B,GAAI,KAAK,kBAAkB,EAAG,CAC5B,KAAK,YAAY,MAAM,eAAe,KAAK,EAC3C,MACF,CAEA,GAAI,KAAK,QAAQ,aAAa,gBAAgB,IAAM,aAAc,CAChE,KAAK,YAAY,MAAM,eAAe,KAAK,EAC3C,MACF,CAEA,IAAMC,EAAe,KAAK,cAAc,cACtC,iDACF,EACA,GAAI,CAACA,EAAc,OACnB,IAAMC,EAAWD,EAAa,sBAAsB,EAC9CH,EAAgB,KAAK,MAAM,sBAAsB,EACvD,KAAK,YAAY,MAAM,IAAM,GAAGI,EAAS,IAAMJ,EAAc,GAAG,IAClE,CAEO,MAAa,CAClB,KAAK,OAAS,GACd,KAAK,MAAM,aAAa,YAAa,MAAM,EAC3C,KAAK,QAAQ,aAAa,cAAe,MAAM,EAC/C,KAAK,QAAQ,aAAa,gBAAiB,MAAM,EACjD,KAAK,mBAAmB,EACxB,KAAK,UAAU,CACjB,CAEO,MAAa,CAClB,KAAK,OAAS,GACd,KAAK,MAAM,aAAa,YAAa,OAAO,EAC5C,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,QAAQ,aAAa,cAAe,OAAO,EAChD,KAAK,QAAQ,aAAa,gBAAiB,OAAO,EAClD,KAAK,mBAAmB,EACxB,KAAK,WAAW,CAClB,CAEO,QAAe,CACf,KAAK,UACN,KAAK,OAAQ,KAAK,KAAK,EACtB,KAAK,KAAK,EACjB,CAEQ,mBAA6B,CACnC,OAAI,OAAO,OAAW,IAAoB,GACnC,OAAO,WAAW,wCAAwC,EAAE,OACrE,CAEQ,oBAA2B,CAEjC,GAAI,CADe,KAAK,kBAAkB,EACzB,CACX,KAAK,cACP,KAAK,MAAM,gBAAgB,mBAAmB,EAC9C,KAAK,MAAM,MAAM,eAAe,UAAU,EAC1C,KAAK,MAAM,MAAM,eAAe,QAAQ,EACxC,KAAK,QAAQ,YAAY,KAAK,KAAK,EACnC,KAAK,YAAc,IAErB,KAAK,QAAQ,aAAa,oBAAqB,OAAO,EACtD,KAAK,MAAM,MAAM,eAAe,MAAM,EACtC,KAAK,MAAM,MAAM,eAAe,KAAK,EACrC,KAAK,MAAM,MAAM,eAAe,OAAO,EACvC,KAAK,MAAM,MAAM,eAAe,QAAQ,EACxC,KAAK,MAAM,MAAM,eAAe,YAAY,EAC5C,MACF,CAEA,GAAI,CAAC,KAAK,OACR,OAGG,KAAK,eACP,SAAS,MAAQ,SAAS,iBAAiB,YAAY,KAAK,KAAK,EAClE,KAAK,YAAc,IAGrB,IAAMK,EAAW,OAAO,eAClBC,EAAgBD,GAAU,OAAS,OAAO,WAC1CE,EAAiBF,GAAU,QAAU,OAAO,YAC5CG,EAAiB,KAAK,IAAI,IAAKF,EAAgBrG,GAAsB,CAAC,EACtEwG,EAAkB,KAAK,IAAI,IAAKF,EAAiBtG,GAAsB,CAAC,EACxEyG,EAAQ,KAAK,IAAIxG,GAAwBsG,CAAc,EACvDG,EAAY,KAAK,IAAIxG,GAAyBsG,CAAe,EAC7DG,EAAO,KAAK,OAAOP,GAAU,YAAc,IAAMC,EAAgBI,GAAS,CAAC,EAEjF,KAAK,QAAQ,aAAa,oBAAqB,MAAM,EACrD,KAAK,MAAM,aAAa,oBAAqB,MAAM,EACnD,KAAK,MAAM,MAAM,SAAW,QAC5B,KAAK,MAAM,MAAM,KAAO,GAAGE,CAAI,KAC/B,KAAK,MAAM,MAAM,OAAS,GAAG3G,EAAmB,KAChD,KAAK,MAAM,MAAM,eAAe,KAAK,EACrC,KAAK,MAAM,MAAM,MAAQ,GAAG,KAAK,MAAMyG,CAAK,CAAC,KAC7C,KAAK,MAAM,MAAM,UAAY,GAAG,KAAK,MAAMC,CAAS,CAAC,KACrD,KAAK,MAAM,MAAM,eAAe,QAAQ,EACxC,KAAK,SAAS,MAAM,eAAe,KAAK,EACxC,KAAK,YAAY,MAAM,eAAe,KAAK,EAC3C,KAAK,YAAY,MAAM,eAAe,KAAK,CAC7C,CAEQ,sBAAsBjF,EAA2B,CACvD,GAAI,CAAC,KAAK,OAAQ,OAClB,IAAMrB,EAASqB,EAAM,OACfrB,aAAkB,OAEtB,KAAK,MAAM,SAASA,CAAM,GAC1B,KAAK,QAAQ,SAASA,CAAM,GAC5B,KAAK,SAAS,SAASA,CAAM,GAC7B,KAAK,YAAY,SAASA,CAAM,GAChC,KAAK,YAAY,SAASA,CAAM,GAIlC,KAAK,KAAK,EACZ,CACF,EC3gCO,IAAMwG,GAAN,KAAqB,CAG1B,OAAO,UAAUC,EAAuBC,EAA0C,CAChF,MAAO,CACL,EAAG,KAAK,QACR,OAAQ,kBACR,eAAgBA,EAChB,QAASD,EAAQ,IAAKE,IAAY,CAChC,GAAIA,EAAO,GACX,MAAOA,EAAO,MACd,SAAUA,EAAO,SACjB,MAAOA,EAAO,UAAU,IAAKC,IAAc,CACzC,GAAIA,EAAS,GACb,KAAMA,EAAS,KACf,QAASA,EAAS,QAClB,GAAIA,EAAS,OAAS,OAAY,CAAE,KAAMA,EAAS,IAAK,EAAI,CAAC,EAC7D,SAAU,CAAE,GAAGA,EAAS,QAAS,CACnC,EAAE,CACJ,EAAE,CACJ,CACF,CAEA,OAAO,YACLC,EACAC,EAC4D,CAC5D,GAAI,CAACD,GAAQ,OAAOA,GAAS,SAC3B,OAAO,KAGT,IAAME,EAASF,EACTG,EAAUD,EAAO,EACjBE,EAASF,EAAO,OAItB,GAHKE,IAAW,mBAAqBA,IAAW,cAAkBD,IAAY,GAAKA,IAAY,GAG3F,CAAC,MAAM,QAAQD,EAAO,OAAU,EAClC,OAAO,KAGT,IAAMN,EAAyBM,EAAO,QACnC,OACEJ,GACC,CAAC,CAACA,GACF,OAAOA,GAAW,UAClB,OAAOA,EAAO,IAAU,QAC5B,EACC,IAAI,CAACA,EAAQO,KAAW,CACvB,GAAIP,EAAO,GACX,MAAQQ,GAAmB,SAASR,EAAO,KAA2B,EAClEA,EAAO,MACP,IACJ,SAAU,KAAK,wBAAwBA,EAAO,SAAaO,CAAK,EAChE,WAAY,MAAM,QAAQP,EAAO,KAAQ,EAAIA,EAAO,MAAW,CAAC,GAC7D,OACES,GACC,CAAC,CAACA,GACF,OAAOA,GAAS,UAChB,OAAOA,EAAK,MAAY,UACxBN,EAAgB,IAAIM,EAAK,IAAiB,CAC9C,EACC,IAAKA,GAAS,CACb,IAAMC,EAAOD,EAAK,KACZE,EAAUR,EAAgB,IAAIO,CAAI,EACxC,MAAO,CACL,GAAI,OAAOD,EAAK,IAAU,SAAWA,EAAK,GAAQG,GAAqB,EACvE,KAAAF,EACA,QAASD,EAAK,UAAe,GAC7B,GAAI,OAAOA,EAAK,MAAY,UAAYA,EAAK,KACzC,CAAE,KAAMA,EAAK,IAAQ,EACrB,CAAC,EACL,SAAU,CACR,GAAGE,EAAQ,YAAY,EACvB,GAAIF,EAAK,UACT,OAAOA,EAAK,UAAgB,UAC5B,CAAC,MAAM,QAAQA,EAAK,QAAW,EAC1BA,EAAK,SACN,CAAC,CACP,CACF,CACF,CAAC,CACL,EAAE,EAEJ,GAAIX,EAAQ,SAAW,EACrB,OAAO,KAGTA,EAAQ,KAAK,CAACe,EAAMC,IAAUA,EAAM,SAAWD,EAAK,QAAQ,EAE5D,IAAME,EACJ,OAAOX,EAAO,gBAAsB,SAChCA,EAAO,eACP,OAAOA,EAAO,cAAoB,SAChCA,EAAO,aACPN,EAAQ,CAAC,EAAE,GAEbC,EAAmBD,EAAQ,KAAME,GAAWA,EAAO,KAAOe,CAAW,EACvEA,EACAjB,EAAQ,CAAC,EAAE,GAEf,MAAO,CAAE,QAAAA,EAAS,iBAAAC,CAAiB,CACrC,CAEA,OAAO,OAAOiB,EAAkBd,EAA4B,CAC1D,IAAMe,EAAO,KAAK,UAAUf,EAAM,KAAM,CAAC,EACnCgB,EAAO,IAAI,KAAK,CAACD,CAAI,EAAG,CAAE,KAAM,kBAAmB,CAAC,EACpDE,EAAM,IAAI,gBAAgBD,CAAI,EAC9BE,EAAO,SAAS,cAAc,GAAG,EACvCA,EAAK,KAAOD,EACZC,EAAK,SAAWJ,EAChBI,EAAK,MAAM,EACX,IAAI,gBAAgBD,CAAG,CACzB,CAEA,OAAO,UAA6B,CAClC,OAAO,IAAI,QAAiB,CAACE,EAASC,IAAW,CAC/C,IAAMC,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,KAAO,OACbA,EAAM,OAAS,yBAEf,IAAMC,EAAU,IAAMD,EAAM,OAAO,EAEnCA,EAAM,iBAAiB,SAAU,IAAM,CACrC,IAAME,EAAOF,EAAM,QAAQ,CAAC,EAC5B,GAAI,CAACE,EAAM,CACTD,EAAQ,EACRF,EAAO,IAAI,MAAM,kBAAkB,CAAC,EACpC,MACF,CAEA,IAAMI,EAAS,IAAI,WACnBA,EAAO,OAAS,IAAM,CACpBF,EAAQ,EACR,GAAI,CACFH,EAAQ,KAAK,MAAMK,EAAO,MAAgB,CAAC,CAC7C,MAAQ,CACNJ,EAAO,IAAI,MAAM,cAAc,CAAC,CAClC,CACF,EACAI,EAAO,QAAU,IAAM,CACrBF,EAAQ,EACRF,EAAO,IAAI,MAAM,iBAAiB,CAAC,CACrC,EACAI,EAAO,WAAWD,CAAI,CACxB,CAAC,EAEDF,EAAM,iBAAiB,SAAU,IAAM,CACrCC,EAAQ,EACRF,EAAO,IAAI,MAAM,WAAW,CAAC,CAC/B,CAAC,EAED,SAAS,KAAK,YAAYC,CAAK,EAC/BA,EAAM,MAAM,CACd,CAAC,CACH,CAEA,OAAe,wBAAwBI,EAAgBpB,EAAuB,CAC5E,OAAI,OAAOoB,GAAU,UAAY,OAAO,SAASA,CAAK,EAC7CC,GAA4BD,CAAK,EAGzB,CAAC,KAAM,KAAM,IAAK,CAAC,EACpBpB,CAAK,GAAK,KAAK,IAAI,EAAG,KAAOA,EAAQ,GAAG,CAC1D,CACF,EArKaV,GACK,QAAU,EC7B5B,IAAMgC,GAAS,6BAaOC,EAAf,KAA2B,CAyChC,MAAMC,EAAoBC,EAA0B,CAClD,IAAMC,EAAQF,EAAI,cAAc,kBAAkBC,CAAU,IAAI,EAC5DC,GAAOA,EAAM,OAAO,CAC1B,CAMU,SAASF,EAAoBC,EAAiC,CACtE,IAAIC,EAAQF,EAAI,cACd,kBAAkBC,CAAU,IAC9B,EACA,OAAKC,IACHA,EAAQ,SAAS,gBAAgBJ,GAAQ,GAAG,EAC5CI,EAAM,aAAa,eAAgBD,CAAU,EAC7CD,EAAI,YAAYE,CAAK,GAEhBA,CACT,CAKU,WACRC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAAsB,EACN,CAChB,IAAMC,EAAO,SAAS,gBAAgBZ,GAAQ,MAAM,EACpD,OAAAY,EAAK,aAAa,yBAA0B,MAAM,EAClDA,EAAK,aAAa,KAAM,OAAOP,CAAE,CAAC,EAClCO,EAAK,aAAa,KAAM,OAAON,CAAE,CAAC,EAClCM,EAAK,aAAa,KAAM,OAAOL,CAAE,CAAC,EAClCK,EAAK,aAAa,KAAM,OAAOJ,CAAE,CAAC,EAClCI,EAAK,aAAa,SAAUH,CAAK,EACjCG,EAAK,aAAa,iBAAkB,OAAOF,CAAO,CAAC,EACnDE,EAAK,aAAa,eAAgB,OAAOD,CAAW,CAAC,EAC9CC,CACT,CAKU,WACRC,EACAC,EACAC,EACAC,EACAC,EACAP,EACgB,CAChB,IAAMQ,EAAO,SAAS,gBAAgBlB,GAAQ,MAAM,EACpD,OAAAkB,EAAK,aAAa,yBAA0B,MAAM,EAClDA,EAAK,aAAa,IAAK,OAAOL,CAAC,CAAC,EAChCK,EAAK,aAAa,IAAK,OAAOJ,CAAC,CAAC,EAChCI,EAAK,aAAa,QAAS,OAAOH,CAAK,CAAC,EACxCG,EAAK,aAAa,SAAU,OAAOF,CAAM,CAAC,EAC1CE,EAAK,aAAa,OAAQD,CAAI,EAC9BC,EAAK,aAAa,eAAgB,OAAOR,CAAO,CAAC,EAC1CQ,CACT,CASU,YACRC,EACAC,EACAC,EACAC,EACQ,CACR,IAAMC,EACJ,WAAW,iBAAiB,SAAS,eAAe,EAAE,QAAQ,GAAK,GAC/DC,EACJF,aAA4B,SACxB,WAAW,iBAAiBA,CAAgB,EAAE,QAAQ,GAAKC,EAGjE,OAAQH,EAAM,CACZ,IAAK,IAAM,OAAQD,EAAQ,IAAOE,EAClC,IAAK,KAAM,OAAQF,EAAQ,IAAO,OAAO,WACzC,IAAK,KAAM,OAAQA,EAAQ,IAAO,OAAO,YACzC,IAAK,KAAM,OAAOA,EAAQK,EAC1B,IAAK,MAAO,OAAOL,EAAQI,EAC3B,QAAW,OAAOJ,CACpB,CACF,CAKU,WACRM,EACAC,EACAhB,EACAC,EAAsB,EACtBM,EAAe,OACC,CAChB,IAAMU,EAAO,SAAS,gBAAgB3B,GAAQ,MAAM,EACpD,OAAA2B,EAAK,aAAa,yBAA0B,MAAM,EAClDA,EAAK,aAAa,IAAKF,CAAC,EACxBE,EAAK,aAAa,SAAUD,CAAM,EAClCC,EAAK,aAAa,iBAAkB,OAAOjB,CAAO,CAAC,EACnDiB,EAAK,aAAa,eAAgB,OAAOhB,CAAW,CAAC,EACrDgB,EAAK,aAAa,OAAQV,CAAI,EACvBU,CACT,CACF,ECpKO,IAAMC,GAAN,MAAMA,WAAuBC,CAAY,CAAzC,kCACL,KAAS,KAAO,UAChB,KAAS,MAAQ,UACjB,KAAS,KAAO,yQAWhB,aAAmC,CACjC,MAAO,CACL,MAAO,GACP,IAAK,GACL,QAAS,KACT,OAAQ,EACR,WAAY,KACZ,MAAO,UACP,QAAS,IACT,UAAW,EACb,CACF,CAEA,aAAmC,CACjC,MAAO,CACL,CAAE,KAAM,SAAU,IAAK,QAAS,MAAO,UAAW,QAAS,GAAI,IAAK,EAAG,IAAK,GAAI,KAAM,CAAE,EACxF,CACE,KAAM,QACN,IAAK,MACL,MAAO,MACP,QAAS,GACT,IAAK,EACL,IAAK,IACL,KAAM,EACN,MAAOD,GAAe,aACtB,YAAa,IACf,EACA,CACE,KAAM,QACN,IAAK,SACL,MAAO,SACP,QAAS,EACT,IAAK,EACL,IAAK,IACL,KAAM,EACN,MAAOA,GAAe,aACtB,YAAa,IACf,EACA,CAAE,KAAM,SAAU,EAClB,CAAE,KAAM,QAAS,IAAK,QAAS,MAAO,QAAS,QAAS,SAAU,EAClE,CACE,KAAM,QACN,IAAK,UACL,MAAO,UACP,QAAS,IACT,IAAK,EACL,IAAK,EACL,KAAM,IACN,kBAAmB,IACnB,YAAa,EACf,EACA,CAAE,KAAM,SAAU,IAAK,YAAa,MAAO,aAAc,QAAS,EAAM,CAC1E,CACF,CAEA,OAAOE,EAAoBC,EAAeC,EAAgBC,EAAqC,CAC7F,IAAMC,EAAQ,KAAK,SAASJ,EAAKG,EAAS,YAAY,EAChD,CACJ,MAAAE,EACA,IAAKC,EACL,QAAAC,EACA,OAAQC,EACR,WAAAC,EACA,MAAAC,EACA,QAAAC,EACA,UAAAC,CACF,EAAIT,EAEEU,EAAmBb,EAAI,cACvBc,EAAM,KAAK,YAAYR,EAAQC,GAAW,KAAMN,EAAOY,CAAgB,EACvEE,EAAS,KAAK,YAAYP,EAAWC,GAAc,KAAMR,EAAOY,CAAgB,EAEhFG,EAAiBf,EAAQc,EAAS,EAClCE,GAAaZ,EAAQ,GAAKS,EAC1BI,GAAeF,EAAiBC,GAAaZ,EAEnD,GAAI,EAAAa,GAAe,GAEnB,QAASC,EAAI,EAAGA,EAAId,EAAOc,IAAK,CAC9B,IAAMC,EAAIL,EAASI,GAAKD,EAAcJ,GAElCF,GACFR,EAAM,YAAY,KAAK,WAAWgB,EAAG,EAAGA,EAAGlB,EAAQQ,EAAOC,CAAO,CAAC,EAClEP,EAAM,YACJ,KAAK,WAAWgB,EAAIF,EAAa,EAAGE,EAAIF,EAAahB,EAAQQ,EAAOC,CAAO,CAC7E,GAEAP,EAAM,YAAY,KAAK,WAAWgB,EAAG,EAAGF,EAAahB,EAAQQ,EAAOC,CAAO,CAAC,CAEhF,CACF,CACF,EAzGab,GAKa,aAAe,CACrC,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,IAAK,MAAO,GAAI,EACzB,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,MAAO,MAAO,KAAM,CAC/B,EAZK,IAAMuB,GAANvB,GCAA,IAAMwB,GAAN,MAAMA,WAAoBC,CAAY,CAAtC,kCACL,KAAS,KAAO,OAChB,KAAS,MAAQ,OACjB,KAAS,KAAO,yQAWhB,aAAmC,CACjC,MAAO,CACL,KAAM,QACN,MAAO,EACP,KAAM,GACN,SAAU,KACV,IAAK,EACL,QAAS,KACT,OAAQ,EACR,WAAY,KACZ,MAAO,UACP,QAAS,GACT,MAAO,MACT,CACF,CAEA,aAAmC,CACjC,MAAO,CACL,CACE,KAAM,SACN,IAAK,OACL,MAAO,OACP,QAAS,QACT,QAAS,CACP,CAAE,MAAO,QAAS,MAAO,UAAW,EACpC,CAAE,MAAO,OAAQ,MAAO,SAAU,CACpC,CACF,EACA,CACE,KAAM,SACN,IAAK,QACL,MAAO,OACP,QAAS,EACT,IAAK,EACL,IAAK,GACL,KAAM,EACN,aAAc,CAAE,IAAK,OAAQ,OAAQ,MAAO,CAC9C,EACA,CACE,KAAM,QACN,IAAK,OACL,MAAO,OACP,QAAS,GACT,IAAK,EACL,IAAK,KACL,KAAM,EACN,MAAOD,GAAY,aACnB,YAAa,KACb,aAAc,CAAE,IAAK,OAAQ,OAAQ,OAAQ,CAC/C,EACA,CACE,KAAM,QACN,IAAK,MACL,MAAO,MACP,QAAS,EACT,IAAK,EACL,IAAK,IACL,KAAM,EACN,MAAOA,GAAY,aACnB,YAAa,IACf,EACA,CACE,KAAM,QACN,IAAK,SACL,MAAO,SACP,QAAS,EACT,IAAK,EACL,IAAK,IACL,KAAM,EACN,MAAOA,GAAY,aACnB,YAAa,IACf,EACA,CAAE,KAAM,SAAU,EAClB,CAAE,KAAM,QAAS,IAAK,QAAS,MAAO,QAAS,QAAS,SAAU,EAClE,CACE,KAAM,QACN,IAAK,UACL,MAAO,UACP,QAAS,GACT,IAAK,EACL,IAAK,EACL,KAAM,IACN,kBAAmB,IACnB,YAAa,EACf,EACA,CACE,KAAM,SACN,IAAK,QACL,MAAO,QACP,QAAS,OACT,QAAS,CACP,CAAE,MAAO,OAAQ,MAAO,OAAQ,EAChC,CAAE,MAAO,OAAQ,MAAO,MAAO,CACjC,CACF,CACF,CACF,CAEA,OAAOE,EAAoBC,EAAeC,EAAgBC,EAAqC,CAC7F,IAAMC,EAAQ,KAAK,SAASJ,EAAKG,EAAS,YAAY,EAChD,CACJ,KAAAE,EACA,MAAAC,EACA,KAAMC,EACN,SAAAC,EACA,IAAKC,EACL,QAAAC,EACA,OAAQC,EACR,WAAAC,EACA,MAAAC,EACA,QAAAC,EACA,MAAAC,CACF,EAAIZ,EAEEa,EAAmBhB,EAAI,cACvBiB,EAAM,KAAK,YAAYR,EAAQC,GAAW,KAAMR,EAAQc,CAAgB,EACxEE,EAAS,KAAK,YAAYP,EAAWC,GAAc,KAAMV,EAAQc,CAAgB,EACjFG,EAAkBjB,EAASgB,EAAS,EAE1C,GAAI,EAAAC,GAAmB,GAEvB,GAAId,IAAS,QACX,KAAK,cAAcD,EAAOH,EAAOkB,EAAiBD,EAAQZ,EAAOW,EAAKJ,EAAOC,EAASC,CAAK,MACtF,CACL,IAAMK,EAAO,KAAK,YAAYb,EAASC,GAAY,KAAMN,EAAQc,CAAgB,EACjF,GAAII,GAAQ,EAAG,OACf,KAAK,aAAahB,EAAOH,EAAOkB,EAAiBD,EAAQE,EAAMH,EAAKJ,EAAOC,EAASC,CAAK,CAC3F,CACF,CAEQ,cACNX,EACAH,EACAoB,EACAH,EACAZ,EACAW,EACAJ,EACAC,EACAC,EACM,CACN,GAAIA,IAAU,OAAQ,CACpB,IAAMO,GAAcD,GAAaf,EAAQ,GAAKW,GAAOX,EACrD,GAAIgB,GAAc,EAAG,OACrB,QAASC,EAAI,EAAGA,EAAIjB,EAAOiB,IAAK,CAC9B,IAAMC,EAAIN,EAASK,GAAKD,EAAaL,GACrCb,EAAM,YAAY,KAAK,WAAW,EAAGoB,EAAGvB,EAAOqB,EAAYT,EAAOC,CAAO,CAAC,CAC5E,CACF,KAAO,CACL,GAAIR,IAAU,EAAG,CACf,IAAMkB,EAAIN,EAASG,EAAY,EAC/BjB,EAAM,YAAY,KAAK,WAAW,EAAGoB,EAAGvB,EAAOuB,EAAGX,EAAOC,CAAO,CAAC,EACjE,MACF,CACA,IAAMW,EAAOJ,GAAaf,EAAQ,GAClC,QAASiB,EAAI,EAAGA,EAAIjB,EAAOiB,IAAK,CAC9B,IAAMC,EAAIN,EAASK,EAAIE,EACvBrB,EAAM,YAAY,KAAK,WAAW,EAAGoB,EAAGvB,EAAOuB,EAAGX,EAAOC,CAAO,CAAC,CACnE,CACF,CACF,CAEQ,aACNV,EACAH,EACAoB,EACAH,EACAE,EACAH,EACAJ,EACAC,EACAC,EACM,CACN,GAAIA,IAAU,OAAQ,CACpB,IAAMU,EAAOL,EAAOH,EACpB,QAASO,EAAI,EAAGA,EAAIH,EAAWG,GAAKC,EAAM,CACxC,IAAMC,EAAI,KAAK,IAAIN,EAAMC,EAAYG,CAAC,EACtCpB,EAAM,YAAY,KAAK,WAAW,EAAGc,EAASM,EAAGvB,EAAOyB,EAAGb,EAAOC,CAAO,CAAC,CAC5E,CACF,KACE,SAASU,EAAI,EAAGA,GAAKH,EAAWG,GAAKJ,EACnChB,EAAM,YAAY,KAAK,WAAW,EAAGc,EAASM,EAAGvB,EAAOiB,EAASM,EAAGX,EAAOC,CAAO,CAAC,CAGzF,CACF,EAvMahB,GAKa,aAAe,CACrC,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,IAAK,MAAO,GAAI,EACzB,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,MAAO,MAAO,KAAM,CAC/B,EAZK,IAAM6B,GAAN7B,GCAA,IAAM8B,GAAN,cAA4BC,CAAY,CAAxC,kCACL,KAAS,KAAO,SAChB,KAAS,MAAQ,SACjB,KAAS,KAAO,0NAEhB,aAAmC,CACjC,MAAO,CACL,aAAc,GACd,eAAgB,GAChB,MAAO,UACP,QAAS,GACT,OAAQ,EACV,CACF,CAEA,aAAmC,CACjC,MAAO,CACL,CAAE,KAAM,SAAU,IAAK,eAAgB,MAAO,WAAY,QAAS,EAAK,EACxE,CAAE,KAAM,SAAU,IAAK,iBAAkB,MAAO,aAAc,QAAS,EAAK,EAC5E,CAAE,KAAM,SAAU,EAClB,CAAE,KAAM,QAAS,IAAK,QAAS,MAAO,QAAS,QAAS,SAAU,EAClE,CACE,KAAM,QACN,IAAK,UACL,MAAO,UACP,QAAS,GACT,IAAK,EACL,IAAK,EACL,KAAM,IACN,kBAAmB,IACnB,YAAa,EACf,EACA,CAAE,KAAM,SAAU,IAAK,SAAU,MAAO,SAAU,QAAS,EAAK,CAClE,CACF,CAEA,OAAOC,EAAoBC,EAAeC,EAAgBC,EAAqC,CAC7F,IAAMC,EAAQ,KAAK,SAASJ,EAAKG,EAAS,YAAY,EAChD,CAAE,aAAAE,EAAc,eAAAC,EAAgB,MAAAC,EAAO,QAAAC,EAAS,OAAAC,CAAO,EAAIN,EAC3DO,EAAWD,EAAS,MAAQ,OAElC,GAAIJ,EAAc,CAChB,IAAMM,EAAO,KAAK,WAAWV,EAAQ,EAAG,EAAGA,EAAQ,EAAGC,EAAQK,EAAOC,CAAO,EACxEC,GAAQE,EAAK,aAAa,mBAAoBD,CAAQ,EAC1DN,EAAM,YAAYO,CAAI,CACxB,CAEA,GAAIL,EAAgB,CAClB,IAAMK,EAAO,KAAK,WAAW,EAAGT,EAAS,EAAGD,EAAOC,EAAS,EAAGK,EAAOC,CAAO,EACzEC,GAAQE,EAAK,aAAa,mBAAoBD,CAAQ,EAC1DN,EAAM,YAAYO,CAAI,CACxB,CACF,CACF,ECrDO,IAAMC,GAAN,cAAkCC,CAAY,CAA9C,kCACL,KAAS,KAAO,iBAChB,KAAS,MAAQ,SACjB,KAAS,KAAO,2tCAEhB,aAAmC,CACjC,MAAO,CACL,MAAO,UACP,QAAS,GACT,kBAAmB,EACrB,CACF,CAEA,aAAmC,CACjC,MAAO,CACL,CAAE,KAAM,QAAS,IAAK,QAAS,MAAO,QAAS,QAAS,SAAU,EAClE,CACE,KAAM,QACN,IAAK,UACL,MAAO,UACP,QAAS,GACT,IAAK,EACL,IAAK,EACL,KAAM,IACN,kBAAmB,IACnB,YAAa,EACf,EACA,CAAE,KAAM,SAAU,IAAK,oBAAqB,MAAO,cAAe,QAAS,EAAK,CAClF,CACF,CAEA,OAAOC,EAAoBC,EAAeC,EAAgBC,EAAqC,CAC7F,IAAMC,EAAQ,KAAK,SAASJ,EAAKG,EAAS,YAAY,EAChD,CAAE,MAAAE,EAAO,QAAAC,EAAS,kBAAAC,CAAkB,EAAIJ,EAExCK,EAAUP,EAAQ,EAClBQ,EAAUP,EAAS,EAWzB,GARAE,EAAM,YAAY,KAAK,WAAWI,EAAS,EAAGA,EAASN,EAAQG,EAAOC,CAAO,CAAC,EAC9EF,EAAM,YAAY,KAAK,WAAWI,EAAU,EAAG,EAAGA,EAAU,EAAGN,EAAQG,EAAOC,CAAO,CAAC,EAGtFF,EAAM,YAAY,KAAK,WAAW,EAAGK,EAASR,EAAOQ,EAASJ,EAAOC,CAAO,CAAC,EAC7EF,EAAM,YAAY,KAAK,WAAW,EAAGK,EAAU,EAAGR,EAAOQ,EAAU,EAAGJ,EAAOC,CAAO,CAAC,EAGjFC,EAAmB,CACrB,IAAMG,EAAS,CACb,CAACF,EAASC,CAAO,EACjB,CAACD,EAAU,EAAGC,CAAO,EACrB,CAACD,EAASC,EAAU,CAAC,EACrB,CAACD,EAAU,EAAGC,EAAU,CAAC,CAC3B,EAEA,OAAW,CAACE,EAAIC,CAAE,IAAKF,EAAQ,CAC7B,IAAMG,EAAS,SAAS,gBAAgB,6BAA8B,QAAQ,EAC9EA,EAAO,aAAa,KAAM,OAAOF,CAAE,CAAC,EACpCE,EAAO,aAAa,KAAM,OAAOD,CAAE,CAAC,EACpCC,EAAO,aAAa,IAAK,GAAG,EAC5BA,EAAO,aAAa,OAAQR,CAAK,EACjCQ,EAAO,aAAa,eAAgB,OAAOP,EAAU,GAAG,CAAC,EACzDF,EAAM,YAAYS,CAAM,CAC1B,CACF,CACF,CACF,ECvEA,IAAMC,GAAM,aAUCC,GAAN,cAAqCC,CAAY,CAAjD,kCACL,KAAS,KAAO,mBAChB,KAAS,MAAQ,SACjB,KAAS,KAAO,0NAEhB,aAAmC,CACjC,MAAO,CACL,MAAO,EACP,WAAY,GACZ,MAAO,UACP,QAAS,EACX,CACF,CAEA,aAAmC,CACjC,MAAO,CACL,CAAE,KAAM,SAAU,IAAK,QAAS,MAAO,QAAS,QAAS,EAAG,IAAK,EAAG,IAAK,GAAI,KAAM,CAAE,EACrF,CAAE,KAAM,SAAU,IAAK,aAAc,MAAO,cAAe,QAAS,EAAK,EACzE,CAAE,KAAM,SAAU,EAClB,CAAE,KAAM,QAAS,IAAK,QAAS,MAAO,QAAS,QAAS,SAAU,EAClE,CACE,KAAM,QACN,IAAK,UACL,MAAO,UACP,QAAS,GACT,IAAK,EACL,IAAK,EACL,KAAM,IACN,kBAAmB,IACnB,YAAa,EACf,CACF,CACF,CAEA,OAAOC,EAAoBC,EAAeC,EAAgBC,EAAqC,CAC7F,IAAMC,EAAQ,KAAK,SAASJ,EAAKG,EAAS,YAAY,EAChD,CAAE,MAAAE,EAAO,WAAAC,EAAY,MAAAC,EAAO,QAAAC,CAAQ,EAAIL,EAG1CM,EAAYC,EACZT,EAAQC,GAAUL,IACpBa,EAAKR,EACLO,EAAKC,EAAKb,KAEVY,EAAKR,EACLS,EAAKD,EAAKZ,IAEZ,IAAMc,GAAMV,EAAQQ,GAAM,EACpBG,GAAMV,EAASQ,GAAM,EAG3B,GAAID,EAAKR,EAAQ,GAAKS,EAAKR,EAAS,EAAG,CACrC,IAAMW,EAAS,KAAK,WAClB,KAAKF,CAAE,IAAIC,CAAE,MAAMD,EAAKF,CAAE,IAAIG,CAAE,MAAMD,EAAKF,CAAE,IAAIG,EAAKF,CAAE,MAAMC,CAAE,IAAIC,EAAKF,CAAE,KAC3EH,EACAC,EAAU,GACV,CACF,EACAK,EAAO,aAAa,mBAAoB,KAAK,EAC7CT,EAAM,YAAYS,CAAM,CAC1B,CAGA,IAAIC,EAAIH,EACNI,EAAIH,EACJI,EAAIP,EACJQ,EAAIP,EACFQ,EAAU,GACVC,EAAU,GAEd,QAASC,EAAI,EAAGA,EAAIf,GACd,EAAAW,EAAI,GAAKC,EAAI,GADQG,IAAK,CAE9B,IAAMC,EAAMD,EAAI,EACVE,EAAI,KAAK,IAAIN,EAAGC,CAAC,EACnBM,EAAaC,EAEjB,OAAQH,EAAK,CACX,IAAK,GAAG,CAENE,EAAMT,EAAIE,EAAIM,EACdE,EAAMT,EACFC,EAAIM,EAAI,IAAKlB,EAAM,YAAY,KAAK,WAAWmB,EAAKR,EAAGQ,EAAKR,EAAIE,EAAGV,EAAOC,CAAO,CAAC,EAElFF,IAEEa,IACFD,EAAU,KAAKK,EAAMD,CAAC,IAAIE,CAAG,GAC7BL,EAAU,IAEZD,GAAW,MAAMI,CAAC,IAAIA,CAAC,UAAUC,CAAG,IAAIC,EAAMF,CAAC,IAGjDN,GAAKM,EACL,KACF,CACA,IAAK,GAAG,CAENC,EAAMT,EACNU,EAAMT,EAAIE,EAAIK,EACVL,EAAIK,EAAI,IAAKlB,EAAM,YAAY,KAAK,WAAWU,EAAGU,EAAKV,EAAIE,EAAGQ,EAAKjB,EAAOC,CAAO,CAAC,EAElFF,IAEEa,IACFD,EAAU,KAAKK,EAAMD,CAAC,IAAIE,EAAMF,CAAC,GACjCH,EAAU,IAEZD,GAAW,MAAMI,CAAC,IAAIA,CAAC,UAAUC,CAAG,IAAIC,CAAG,IAG7CP,GAAKK,EACL,KACF,CACA,IAAK,GAAG,CAENC,EAAMT,EACNU,EAAMT,EACFC,EAAIM,EAAI,IACVlB,EAAM,YAAY,KAAK,WAAWU,EAAIQ,EAAGP,EAAGD,EAAIQ,EAAGP,EAAIE,EAAGV,EAAOC,CAAO,CAAC,EAEvEF,IAEEa,IACFD,EAAU,KAAKK,CAAG,IAAIC,EAAMF,CAAC,GAC7BH,EAAU,IAEZD,GAAW,MAAMI,CAAC,IAAIA,CAAC,UAAUC,EAAMD,CAAC,IAAIE,CAAG,IAGjDV,GAAKQ,EACLN,GAAKM,EACL,KACF,CACA,IAAK,GAAG,CAENC,EAAMT,EACNU,EAAMT,EACFE,EAAIK,EAAI,IACVlB,EAAM,YAAY,KAAK,WAAWU,EAAGC,EAAIO,EAAGR,EAAIE,EAAGD,EAAIO,EAAGf,EAAOC,CAAO,CAAC,EAEvEF,IAEEa,IACFD,EAAU,KAAKK,CAAG,IAAIC,CAAG,GACzBL,EAAU,IAEZD,GAAW,MAAMI,CAAC,IAAIA,CAAC,UAAUC,EAAMD,CAAC,IAAIE,EAAMF,CAAC,IAGrDP,GAAKO,EACLL,GAAKK,EACL,KACF,CACF,CACF,CAEIhB,GAAcY,GAChBd,EAAM,YAAY,KAAK,WAAWc,EAASX,EAAOC,EAAU,GAAK,GAAG,CAAC,CAEzE,CACF,EC1KA,IAAMiB,GAAS,6BASFC,GAAN,MAAMA,WAAuBC,CAAY,CAAzC,kCAIL,KAAS,KAAO,WAChB,KAAS,MAAQ,OACjB,KAAS,KAAO,mnBAWhB,aAAmC,CACjC,MAAO,CACL,KAAM,GACN,SAAU,KACV,QAAS,IACT,MAAO,MACP,MAAO,UACP,QAAS,EACX,CACF,CAEA,aAAmC,CACjC,MAAO,CACL,CACE,KAAM,QACN,IAAK,OACL,MAAO,OACP,QAAS,GACT,IAAK,EACL,IAAK,IACL,KAAM,EACN,MAAOD,GAAe,aACtB,YAAa,IACf,EACA,CAAE,KAAM,QAAS,IAAK,UAAW,MAAO,OAAQ,QAAS,IAAK,IAAK,GAAK,IAAK,EAAG,KAAM,EAAI,EAC1F,CACE,KAAM,SACN,IAAK,QACL,MAAO,QACP,QAAS,MACT,QAAS,CACP,CAAE,MAAO,MAAO,MAAO,YAAQ,EAC/B,CAAE,MAAO,QAAS,MAAO,SAAU,CACrC,CACF,EACA,CAAE,KAAM,SAAU,EAClB,CAAE,KAAM,QAAS,IAAK,QAAS,MAAO,QAAS,QAAS,SAAU,EAClE,CACE,KAAM,QACN,IAAK,UACL,MAAO,UACP,QAAS,GACT,IAAK,EACL,IAAK,EACL,KAAM,IACN,kBAAmB,IACnB,YAAa,EACf,CACF,CACF,CAEA,OAAOE,EAAoBC,EAAeC,EAAgBC,EAAqC,CAC7F,IAAMC,EAAQ,KAAK,SAASJ,EAAKG,EAAS,YAAY,EAChD,CAAE,KAAME,EAAS,SAAAC,EAAU,QAAAC,EAAS,MAAAC,EAAO,MAAAC,EAAO,QAAAC,CAAQ,EAAIP,EAE9DQ,EAAc,KAAK,YACvBN,EACAC,GAAY,KACZ,KAAK,IAAIL,EAAOC,CAAM,EACtBF,EAAI,aACN,EACMY,EAAO,KAAK,YAAYX,EAAOC,EAAQS,EAAaH,CAAK,EAC/D,GAAII,EAAO,EAAG,OAEd,IAAMC,EAAY,KAAK,aAAaV,EAAS,YAAY,EACnDW,EAAO,KAAK,QAAQd,CAAG,EACvBe,EAAU,SAAS,gBAAgBlB,GAAQ,SAAS,EAC1DkB,EAAQ,aAAa,KAAMF,CAAS,EACpCE,EAAQ,aAAa,+BAAgCZ,EAAS,YAAY,EAC1EY,EAAQ,aAAa,eAAgB,gBAAgB,EACrDA,EAAQ,aAAa,QAAS,OAAOH,CAAI,CAAC,EAC1CG,EAAQ,aAAa,SAAU,OAAOH,CAAI,CAAC,EAC3CG,EAAQ,aAAa,IAAK,OAAOH,EAAO,CAAC,CAAC,EAC1CG,EAAQ,aAAa,IAAK,OAAOH,EAAO,CAAC,CAAC,EAE1C,IAAMI,EAASJ,EAAO,EAEtB,GAAIJ,IAAU,QACZO,EAAQ,YACN,KAAK,WACHC,EAAST,EAAU,EACnBS,EACAA,EAAST,EAAU,EACnBS,EACAP,EACAC,EACA,EACF,CACF,EACAK,EAAQ,YACN,KAAK,WACHC,EACAA,EAAST,EAAU,EACnBS,EACAA,EAAST,EAAU,EACnBE,EACAC,EACA,EACF,CACF,MACK,CACL,IAAMO,EAAS,SAAS,gBAAgBpB,GAAQ,QAAQ,EACxDoB,EAAO,aAAa,KAAM,OAAOD,CAAM,CAAC,EACxCC,EAAO,aAAa,KAAM,OAAOD,CAAM,CAAC,EACxCC,EAAO,aAAa,IAAK,OAAOV,CAAO,CAAC,EACxCU,EAAO,aAAa,OAAQR,CAAK,EACjCQ,EAAO,aAAa,eAAgB,OAAOP,CAAO,CAAC,EACnDK,EAAQ,YAAYE,CAAM,CAC5B,CAEAH,EAAK,YAAYC,CAAO,EAExB,IAAMG,EAAO,KAAK,WAAW,EAAG,EAAGjB,EAAOC,EAAQ,QAAQW,CAAS,IAAK,CAAC,EACzEK,EAAK,aAAa,eAAgB,GAAG,EACrCd,EAAM,YAAYc,CAAI,CACxB,CAES,MAAMlB,EAAoBmB,EAA0B,CAC3D,MAAM,MAAMnB,EAAKmB,CAAU,EAEXnB,EAAI,cAAc,kCAAkCmB,CAAU,IAAI,GACzE,OAAO,CAClB,CAEQ,QAAQnB,EAAoC,CAClD,IAAIc,EAAOd,EAAI,cAAc,MAAM,EACnC,OAAKc,IACHA,EAAO,SAAS,gBAAgBjB,GAAQ,MAAM,EAC9CG,EAAI,aAAac,EAAMd,EAAI,UAAU,GAEhCc,CACT,CAEQ,aAAaK,EAA4B,CAC/C,MAAO,2BAA2BA,EAAW,QAAQ,kBAAmB,GAAG,CAAC,EAC9E,CAEQ,YAAYlB,EAAeC,EAAgBU,EAAcJ,EAAuB,CAEtF,IAAMY,EAAiB,KAAK,IAAIR,EAAM,CAAO,EACvCS,EACJb,IAAU,QAAUV,GAAe,gBAAkBA,GAAe,cAGtE,OAFuB,KAAK,MAAMG,EAAQmB,CAAc,EAAI,KAAK,MAAMlB,EAASkB,CAAc,GAExEC,EACbD,EAGF,KAAK,IAAIA,EAAgB,KAAK,KAAMnB,EAAQC,EAAUmB,CAAQ,CAAC,CACxE,CACF,EAvKavB,GACa,cAAgB,KAD7BA,GAEa,gBAAkB,IAF/BA,GAQa,aAAe,CACrC,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,IAAK,MAAO,GAAI,EACzB,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,KAAM,MAAO,IAAK,EAC3B,CAAE,MAAO,MAAO,MAAO,KAAM,CAC/B,EAfK,IAAMwB,GAANxB,GCVA,IAAMyB,GAA8C,wCAmBpD,IAAMC,GAAN,KAA0B,CAA1B,cACL,KAAiB,QAAU,IAAI,IAE/B,SAASC,EAAYC,EAAeC,EAAa,EAAS,CACxD,KAAK,QAAQ,IAAIF,EAAI,CAAE,MAAAC,EAAO,WAAAC,CAAW,CAAC,CAC5C,CAEA,WAAWF,EAAkB,CAC3B,KAAK,QAAQ,OAAOA,CAAE,CACxB,CAEA,cACEG,EACAC,EACAC,EACa,CACb,IAAMC,EAAS,KAAK,UAAU,EACxBC,EAAQD,EAAO,UAAW,GAAM,EAAE,KAAOH,CAAS,EAEpDK,EAAa,EACjB,QAASC,EAAI,EAAGA,EAAIF,EAAOE,GAAK,EAC9BD,GAAcF,EAAOG,CAAC,EAAE,WAG1B,MAAO,CACL,KAAML,EAAW,EAAgBI,EAAa,GAC9C,KAAMH,EAAW,CACnB,CACF,CAEA,uBACEK,EACAC,EACAC,EACAC,EACQ,CACR,IAAMC,EAAiC,CAAC,EACpCC,EAAUL,EAAQ,cAEtB,KAAOK,GAAS,CACd,IAAMC,EACJD,EAAQ,aAAa,WAAW,GAAKA,EAAQ,aAAa,gBAAgB,EAC5E,GAAIC,EAAY,CACd,IAAMC,EAASJ,EAAsBG,CAAU,EAC3CC,GACFH,EAAgB,KAAKG,CAAM,CAE/B,CACAF,EAAUA,EAAQ,aACpB,CAEA,IAAIG,EAAS,EACTC,EAAe,GAEnB,KAAOA,GAAc,CACnBA,EAAe,GAEf,QAAWF,KAAUH,EACnB,GACE,KAAK,IAAIG,EAAO,KAAON,CAAQ,EAAI,IACnC,KAAK,IAAIM,EAAO,MAAQL,EAAWM,EAAO,EAAI,GAC9C,CACAA,GAAU,GACVC,EAAe,GACf,KACF,CAEJ,CAEA,OAAOD,CACT,CAEA,kBAAyB,CACvB,OAAO,cAAc,IAAI,YAAYE,EAA2C,CAAC,CACnF,CAEQ,WAAkD,CACxD,IAAMC,EAA6C,CAAC,EACpD,OAAW,CAACrB,EAAIsB,CAAK,IAAK,KAAK,QAC7BD,EAAK,KAAK,CAAE,GAAArB,EAAI,GAAGsB,CAAM,CAAC,EAE5B,OAAAD,EAAK,KAAK,CAACE,EAAGC,IACRD,EAAE,QAAUC,EAAE,MAAcD,EAAE,MAAQC,EAAE,MACrCD,EAAE,GAAG,cAAcC,EAAE,EAAE,CAC/B,EACMH,CACT,CACF,EAEaI,GAAsB,IAAI1B,GC5GhC,SAAS2B,IAAuB,CACrC,MAAO;AAAA,MACHC,GAAwB,CAAC,0BAA2B,mBAAmB,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAgF/E,CChEA,IAAMC,GAAwB,+BACxBC,GAA2B,eAC3BC,EAAyB,aAM/B,SAASC,GAAiBC,EAAsBC,EAA8B,CAC5E,IAAMC,EAAWF,EAAQ,aAAaJ,EAAqB,GAAG,KAAK,EACnE,GAAIM,EACF,OAAOA,EAGT,IAAMC,EACJH,EAAQ,aAAa,gBAAgB,GAAG,KAAK,GAC7CA,EAAQ,aAAa,WAAW,GAAG,KAAK,GACxC,GAEF,GAAIG,GAAoB,CAACN,GAAyB,KAAKM,CAAgB,EAAG,CACxE,IAAMC,EAAM,UAAU,OAAO,SAAS,QAAQ,IAAID,CAAgB,GAClE,OAAAH,EAAQ,aAAaJ,GAAuBQ,CAAG,EACxCA,CACT,CAEA,IAAMC,EAAQL,EAAQ,GAAG,KAAK,EAC9B,GAAIK,EAAO,CACT,IAAMD,EAAM,OAAO,OAAO,SAAS,QAAQ,IAAIC,CAAK,GACpD,OAAAL,EAAQ,aAAaJ,GAAuBQ,CAAG,EACxCA,CACT,CAEA,IAAMA,EAAM,QAAQ,OAAO,SAAS,QAAQ,IAAIE,GAAoBN,CAAO,CAAC,GAC5E,OAAAA,EAAQ,aAAaJ,GAAuBQ,CAAG,EACxCA,CACT,CAEA,SAASG,GACPP,EACAC,EACAO,EACU,CACV,IAAMC,EAAW,OAAO,SAAS,SAC3BJ,EAAQL,EAAQ,GAAG,KAAK,EACxBG,EACJH,EAAQ,aAAa,gBAAgB,GAAG,KAAK,GAC7CA,EAAQ,aAAa,WAAW,GAAG,KAAK,GACxC,GAEIU,EAAa,CACjBL,EAAQ,OAAOI,CAAQ,IAAIJ,CAAK,GAAK,GACrCF,GAAoB,CAACN,GAAyB,KAAKM,CAAgB,EAC/D,UAAUM,CAAQ,IAAIN,CAAgB,GACtC,GACJE,EACAF,EACAF,EAAO,GAAG,KAAK,CACjB,EAAE,OAAO,OAAO,EAEhB,OAAOS,EAAW,OAChB,CAACC,EAAWC,IAAUD,IAAcH,GAAaE,EAAW,QAAQC,CAAS,IAAMC,CACrF,CACF,CAEA,SAASN,GAAoBN,EAA8B,CACzD,IAAMa,EAAqB,CAAC,EACxBC,EAA8Bd,EAElC,KAAOc,GAAWA,IAAY,SAAS,MAAQA,IAAY,SAAS,iBAAiB,CACnF,IAAMC,EAA6BD,EAAQ,cACrCE,EAAMF,EAAQ,QAAQ,YAAY,EACpCF,EAAQ,EAEZ,GAAIG,EAAQ,CACV,IAAIE,EAAUH,EAAQ,uBACtB,KAAOG,GACDA,EAAQ,UAAYH,EAAQ,UAC9BF,GAAS,GAEXK,EAAUA,EAAQ,sBAEtB,CAIA,GAFAJ,EAAS,QAAQ,GAAGG,CAAG,gBAAgBJ,CAAK,GAAG,EAE3CG,GAAQ,GAAI,CACdF,EAAS,QAAQ,IAAIE,EAAO,EAAE,EAAE,EAChC,KACF,CAEAD,EAAUC,CACZ,CAEA,OAAOF,EAAS,KAAK,GAAG,CAC1B,CAEA,SAASK,GAAiBlB,EAA8B,CACtD,IAAImB,EAAQ,EACRL,EAAUd,EAAQ,cAEtB,KAAOc,GACDA,EAAQ,aAAa,uBAAuB,IAC9CK,GAAS,GAEXL,EAAUA,EAAQ,cAGpB,OAAOK,CACT,CAiCO,IAAMC,GAAN,cAA8BC,CAAgB,CA4BnD,YAAYC,EAAwB,CAClC,MAAMA,CAAO,EA5Bf,KAAQ,YAA2B,IAAIC,GAGvC,KAAQ,SAAqC,IAAI,IACjD,KAAQ,KAA6B,IAAI,IACzC,KAAQ,WAAuC,IAAI,IACnD,KAAQ,eAAgD,IAAI,IAC5D,KAAQ,oBAA2D,IAAI,IACvE,KAAQ,QAAmB,GAC3B,KAAQ,aAAe,GACvB,KAAQ,iBAAmB,GAE3B,KAAQ,WAAoC,KAC5C,KAAQ,cAAoC,KAC5C,KAAQ,UAA4B,KACpC,KAAQ,eAAqC,KAc3C,KAAK,gBAAkB,CAAC,EACxB,KAAK,aAAe,KAAK,qBAAqB,wBAAyB,KAAK,EAC5E,KAAK,cAAgB,KAAK,qBAAqB,eAAgB,KAAK,EACpE,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,CAChC,CAIA,QAAe,CACb,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,CACxB,CAEmB,qBAA+C,CAChE,MAAO,CACL,CACE,GAAI,kBACJ,KAAM,WACN,MAAO,4BACP,kBAAmB,iCACnB,QAAUC,GAAkB,KAAK,kBAAkBA,CAAa,CAClE,CACF,CACF,CAEA,kBAAkBvB,EAA4B,CAC5C,IAAMD,EAAUC,EAAO,YACjBwB,EAAY1B,GAAiBC,EAASC,CAAM,EAC5CyB,EAAcnB,GAAwBP,EAASC,EAAQwB,CAAS,EACtEzB,EAAQ,aAAa,wBAAyB,EAAE,EAChD,IAAM2B,EAAYT,GAAiBlB,CAAO,EAC1CA,EAAQ,aAAa,yBAA0B,OAAO2B,CAAS,CAAC,EAChE3B,EAAQ,MAAM,YAAY,6BAA8B,KAAK,EAC7D,KAAK,WAAW,IAAIyB,EAAWzB,CAAO,EAEtC,KAAK,YAAY,KAAKyB,EAAWC,CAAW,EAE5C,IAAME,EAAe,KAAK,aAAa,gBAAgB,KAAK,aAAa,CAAC,EACpEC,EAAU,IAAIC,GAAY9B,EAAS4B,EAAc,IAAM,CACtD,KAAK,UACV,KAAK,cAAcH,CAAS,EAC5B,KAAK,oBAAoB,EAC3B,CAAC,EACD,KAAK,SAAS,IAAIA,EAAWI,CAAO,EAEpC,IAAME,EAAM,IAAIC,GAAQhC,EAAS,KAAK,YAAY,mBAAmB,EAAG,CACtE,MAAQiC,GAAS,KAAK,UAAUR,EAAWQ,CAAI,EAC/C,SAAWC,GAAO,KAAK,aAAaT,EAAWS,CAAE,EACjD,SAAWA,GAAO,KAAK,aAAaT,EAAWS,CAAE,EACjD,gBAAiB,CAACA,EAAI9B,EAAK+B,IAAU,KAAK,oBAAoBV,EAAWS,EAAI9B,EAAK+B,CAAK,EACvF,UAAW,CAACC,EAAWC,EAAUC,IAC/B,KAAK,cAAcb,EAAWW,EAAWC,EAAUC,CAAS,EAC9D,YAAcJ,GAAO,KAAK,gBAAgBT,EAAWS,CAAE,EACvD,eAAiBK,GAAa,KAAK,mBAAmBd,EAAWc,CAAQ,EACzE,uBAAwB,CAACA,EAAUC,IACjC,KAAK,2BAA2Bf,EAAWc,EAAUC,CAAQ,EAC/D,YAAa,IAAM,KAAK,gBAAgBf,CAAS,EACjD,eAAiBc,GAAa,KAAK,mBAAmBd,EAAWc,CAAQ,EACzE,SAAU,IAAM,KAAK,aAAad,CAAS,EAC3C,SAAU,IAAM,KAAK,aAAaA,CAAS,EAC3C,iBAAkB,CAACgB,EAAYC,IAC7B,KAAK,qBAAqBjB,EAAWgB,EAAYC,CAAI,EACvD,mBAAqBC,GAAU,KAAK,uBAAuBlB,EAAWkB,CAAK,EAC3E,UAAW,IAAM,KAAK,cAAclB,CAAS,EAC7C,WAAY,IAAM,KAAK,eAAeA,CAAS,EAC/C,kBAAmB,IAAM,KAAK,sBAAsBA,CAAS,EAC7D,mBAAoB,IAAM,KAAK,uBAAuBA,CAAS,CACjE,CAAC,EACD,KAAK,KAAK,IAAIA,EAAWM,CAAG,EAC5BA,EAAI,YAAYN,CAAS,EACzB,KAAK,mBAAmB,EACxB,KAAK,cAAc,gBAAgB,KAAK,aAAa,CAAC,EAAE,YAAYM,EAAI,cAAc,CAAC,EACvF,KAAK,eAAe,IAAIN,EAAW,CAAE,OAAAxB,EAAQ,IAAA8B,EAAK,MAAOJ,CAAU,CAAC,EAEpE,KAAK,cAAcF,CAAS,EAC5B,KAAK,WAAWA,CAAS,EACzBI,EAAQ,WAAW,KAAK,OAAO,EAC/BE,EAAI,WAAW,KAAK,OAAO,EAC3B,sBAAsB,IAAM,KAAK,oBAAoB,CAAC,CACxD,CAEA,qBAAqB9B,EAA4B,CAC/C,IAAMD,EAAUC,EAAO,YACjBwB,EAAY1B,GAAiBC,EAASC,CAAM,EAClD,KAAK,eAAewB,CAAS,CAC/B,CAEA,UAAiB,CACf,OAAW,CAACA,EAAWI,CAAO,IAAK,KAAK,SACtCA,EAAQ,YAAY,EACpB,KAAK,cAAcJ,CAAS,EAC5B,KAAK,WAAWA,CAAS,EAE3B,KAAK,mBAAmB,EACxB,KAAK,eAAe,YAAY,EAChC,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,CAC3B,CAEA,UAAiB,CACV,KAAK,UACV,KAAK,aAAe,GACtB,CAEA,iBAAwB,CACtB,GAAI,GAAC,KAAK,SAAW,CAAC,KAAK,cAC3B,MAAK,2BAA2B,EAChC,KAAK,aAAe,GACpB,OAAW,CAACA,EAAWmB,CAAK,IAAK,KAAK,eACpC,KAAK,wBAAwBA,EAAO,KAAK,oBAAoB,IAAInB,CAAS,CAAC,EAE7E,KAAK,iBAAmB,GAC1B,CAEA,UAAiB,CACf,GAAI,GAAC,KAAK,SAAW,CAAC,KAAK,kBAC3B,QAAW,CAACA,EAAWmB,CAAK,IAAK,KAAK,eACpC,KAAK,wBAAwBA,EAAO,KAAK,oBAAoB,IAAInB,CAAS,CAAC,EAE7E,KAAK,iBAAmB,GAC1B,CAEA,cAAqB,CACd,KAAK,SACV,KAAK,oBAAoB,CAC3B,CAEA,SAAgB,CACd,OAAW,CAACS,CAAE,IAAK,KAAK,SACtB,KAAK,eAAeA,CAAE,EAExB,KAAK,kBAAkB,EACvB,KAAK,YAAY,MAAM,EACvB,MAAM,QAAQ,CAChB,CAEO,WAAWW,EAAwB,CACxC,GAAI,KAAK,UAAYA,EAIrB,MAAK,QAAUA,EACf,QAAWhB,KAAW,KAAK,SAAS,OAAO,EACzCA,EAAQ,WAAWgB,CAAO,EAE5B,QAAWd,KAAO,KAAK,KAAK,OAAO,EACjCA,EAAI,WAAWc,CAAO,EAQxB,GANA,KAAK,eAAe,WAAWA,CAAO,EACtC,KAAK,WAAW,WAAWA,CAAO,EAC7BA,GACH,KAAK,WAAW,KAAK,EAEvB,KAAK,uBAAuB,EACxBA,EAAS,CACX,QAAWpB,KAAa,KAAK,SAAS,KAAK,EACzC,KAAK,cAAcA,CAAS,EAE9B,KAAK,aAAa,EAClB,KAAK,oBAAoB,CAC3B,MACE,KAAK,iBAAmB,GAE1B,KAAK,iBAAiB,EACxB,CAEO,WAAqB,CAC1B,OAAO,KAAK,OACd,CAEU,uBAAiC,CACzC,OAAO,KAAK,OACd,CAEU,sBAAsBqB,EAAuB,CACrD,KAAK,WAAWA,CAAM,CACxB,CAIQ,UAAUrB,EAAmBQ,EAAoB,CACvD,KAAK,YAAY,YAAYR,EAAWQ,CAAI,EAC5C,KAAK,cAAcR,CAAS,EAC5B,KAAK,WAAWA,CAAS,CAC3B,CAEQ,aAAaA,EAAmBgB,EAA0B,CAChE,IAAMM,EAAW,KAAK,YAAY,aAAatB,EAAWgB,CAAU,EACpE,GAAIM,EAAU,CACZ,IAAMC,EAAU,KAAK,YAAY,WAAWD,EAAS,IAAI,EACnDlB,EAAU,KAAK,SAAS,IAAIJ,CAAS,EACvCuB,GAAWnB,GACbA,EAAQ,cAAcY,EAAYO,CAAO,CAE7C,CACA,KAAK,YAAY,eAAevB,EAAWgB,CAAU,EACrD,KAAK,WAAWhB,CAAS,CAC3B,CAEQ,aAAaA,EAAmBgB,EAA0B,CAChE,KAAK,YAAY,iBAAiBhB,EAAWgB,CAAU,EACvD,KAAK,cAAchB,CAAS,EAC5B,KAAK,WAAWA,CAAS,CAC3B,CAEQ,oBACNA,EACAgB,EACArC,EACA+B,EACM,CACN,KAAK,YAAY,cAAcV,EAAWgB,EAAYrC,EAAK+B,CAAK,EAChE,KAAK,cAAcV,CAAS,CAC9B,CAEQ,cACNA,EACAW,EACAC,EACAC,EACM,CACN,KAAK,YAAY,gBAAgBb,EAAWW,EAAWC,EAAUC,CAAS,EAC1E,KAAK,cAAcb,CAAS,EAC5B,KAAK,WAAWA,CAAS,CAC3B,CAEQ,gBAAgBA,EAAmBgB,EAA0B,CACnE,KAAK,YAAY,kBAAkBhB,EAAWgB,CAAU,EACxD,KAAK,cAAchB,CAAS,EAC5B,KAAK,WAAWA,CAAS,CAC3B,CAEQ,mBAAmBA,EAAmBc,EAAwB,CACpE,KAAK,YAAY,aAAad,EAAWc,CAAQ,EACjD,KAAK,cAAcd,CAAS,EAC5B,KAAK,WAAWA,CAAS,CAC3B,CAEQ,2BAA2BA,EAAmBc,EAAkBC,EAAwB,CAC9F,KAAK,YAAY,qBAAqBf,EAAWc,EAAUC,CAAQ,EACnE,KAAK,6BAA6Bf,CAAS,EAC3C,KAAK,cAAcA,CAAS,EAC5B,KAAK,WAAWA,CAAS,CAC3B,CAEQ,gBAAgBA,EAAyB,CAC/C,KAAK,YAAY,UAAUA,CAAS,EACpC,KAAK,6BAA6BA,CAAS,EAC3C,KAAK,cAAcA,CAAS,EAC5B,KAAK,WAAWA,CAAS,CAC3B,CAEQ,mBAAmBA,EAAmBc,EAAwB,CACpE,KAAK,YAAY,aAAad,EAAWc,CAAQ,EACjD,KAAK,6BAA6Bd,CAAS,EAC3C,KAAK,cAAcA,CAAS,EAC5B,KAAK,WAAWA,CAAS,CAC3B,CAEQ,qBAAqBA,EAAmBgB,EAAoBC,EAAoB,CACtF,KAAK,YAAY,eAAejB,EAAWgB,EAAYC,CAAI,EAC3D,KAAK,WAAWjB,CAAS,CAC3B,CAEQ,uBAAuBA,EAAmBkB,EAAqB,CACrE,KAAK,YAAY,iBAAiBlB,EAAWkB,CAAK,EAClD,KAAK,WAAWlB,CAAS,CAC3B,CAEQ,cAAcA,EAAyB,CAC7C,KAAK,eAAeA,CAAS,EAC7B,KAAK,cAAcA,CAAS,EAC5B,KAAK,WAAWA,CAAS,CAC3B,CAEQ,eAAeA,EAAyB,CAC9C,KAAK,eAAeA,CAAS,EAC7B,KAAK,cAAcA,CAAS,EAC5B,KAAK,WAAWA,CAAS,CAC3B,CAEQ,sBAAsBA,EAAyB,CACrD,KAAK,cAAcA,CAAS,EAC5B,KAAK,WAAWA,CAAS,CAC3B,CAEQ,uBAAuBA,EAAyB,CACtD,KAAK,cAAcA,CAAS,EAC5B,KAAK,WAAWA,CAAS,CAC3B,CAEQ,aAAaA,EAAyB,CAC5C,IAAMwB,EAAU,KAAK,YAAY,WAAWxB,CAAS,EAC/CyB,EAAmB,KAAK,YAAY,oBAAoBzB,CAAS,EACjE0B,EAAOC,GAAe,UAAUH,EAASC,CAAgB,EACzDG,EAAO5B,EAAU,QAAQ,cAAe,GAAG,EAAE,YAAY,GAAK,UACpE2B,GAAe,OAAO,eAAeC,CAAI,QAASF,CAAI,CACxD,CAEQ,aAAa1B,EAAyB,CAC5C2B,GAAe,SAAS,EACrB,KAAME,GAAQ,CACb,IAAMC,EAASH,GAAe,YAAYE,EAAK,KAAK,YAAY,mBAAmB,CAAC,EAC/EC,IACL,KAAK,YAAY,eAAe9B,EAAW8B,EAAO,QAASA,EAAO,gBAAgB,EAClF,KAAK,6BAA6B9B,CAAS,EAC3C,KAAK,cAAcA,CAAS,EAC5B,KAAK,WAAWA,CAAS,EAC3B,CAAC,EACA,MAAM,IAAM,CAEb,CAAC,CACL,CAIQ,cAAcA,EAAyB,CAC7C,GAAIA,IAAc3B,EAAwB,CACxC,KAAK,aAAa,EAClB,MACF,CAEA,IAAM+B,EAAU,KAAK,SAAS,IAAIJ,CAAS,EAC3C,GAAI,CAACI,EAAS,OAEd,IAAME,EAAM,KAAK,KAAK,IAAIN,CAAS,EAC7B+B,EAAgB,KAAK,KAAK,SAAS,aAAe,OAAO,WACzDC,EAAY1B,GAAK,UAAU,EAC7B,KAAK,YAAY,qBAAqBN,CAAS,EAC/C,KAAK,YAAY,qBAAqBA,EAAW+B,CAAa,EAClE3B,EAAQ,OAAO4B,EAAW,KAAK,YAAY,mBAAmB,CAAC,CACjE,CAEQ,eAAehC,EAAyB,CAC9C,KAAK,6BAA6BA,CAAS,CAC7C,CAEQ,6BAA6BA,EAAyB,CAC5D,IAAM+B,EAAgB,KAAK,KAAK,SAAS,aAAe,OAAO,WACzDE,EAAmB,KAAK,YAAY,oBAAoBjC,EAAW+B,CAAa,EAC7D,KAAK,YAAY,oBAAoB/B,CAAS,IAC9CiC,GACvB,KAAK,YAAY,aAAajC,EAAWiC,EAAkB,EAAK,CAEpE,CAEQ,WAAWjC,EAAyB,CAC1C,GAAIA,IAAc3B,EAAwB,CACxC,KAAK,iBAAiB,EACtB,MACF,CAEA,IAAMiC,EAAM,KAAK,KAAK,IAAIN,CAAS,EACnC,GAAI,CAACM,EAAK,OAEV,IAAMyB,EAAgB,KAAK,KAAK,SAAS,aAAe,OAAO,WACzDE,EAAmB,KAAK,YAAY,oBAAoBjC,EAAW+B,CAAa,EACjFzB,EAAI,UAAU,GACQ,KAAK,YAAY,oBAAoBN,CAAS,IAC9CiC,GACvB,KAAK,YAAY,aAAajC,EAAWiC,EAAkB,EAAK,EAGpE,IAAMR,EAAmB,KAAK,YAAY,oBAAoBzB,CAAS,EACjEgC,EAAY,KAAK,YAAY,qBAAqBhC,CAAS,EAC3DwB,EAAU,KAAK,YAAY,WAAWxB,CAAS,EAC/CkC,EAAa,KAAK,YAAY,cAAclC,CAAS,EAC3DM,EAAI,QAAQ0B,EAAWR,EAASU,EAAYT,EAAkBQ,CAAgB,CAChF,CAIQ,kBAAyB,CAC/B,GAAI,KAAK,eAAiB,KAAK,UAAW,OAE1C,IAAME,EAAS,KAAK,aAAa,iBAAiB,EAE5CC,EAAO,SAAS,cAAc,KAAK,EACzCA,EAAK,aAAa,+BAAgC,EAAE,EACpDA,EAAK,MAAM,SAAW,WACtBA,EAAK,MAAM,MAAQ,IACnBA,EAAK,MAAM,cAAgB,OAC3BD,EAAO,YAAYC,CAAI,EACvB,KAAK,WAAaA,EAClB,KAAK,mBAAmB,EAExB,KAAK,YAAY,KAAK/D,CAAsB,EAE5C,IAAM+B,EAAU,IAAIC,GAAY+B,EAAMD,EAAQ,IAAM,CAC7C,KAAK,SACV,KAAK,aAAa,CACpB,CAAC,EACD,KAAK,cAAgB/B,EACrBA,EAAQ,WAAW,KAAK,OAAO,EAC/BA,EAAQ,YAAY,EAAG,EAAGgC,EAAK,YAAaA,EAAK,YAAY,EAE7D,IAAM9B,EAAM,IAAIC,GACd6B,EACA,KAAK,YAAY,mBAAmB,EACpC,CACE,MAAQ5B,GAAS,KAAK,UAAUnC,EAAwBmC,CAAI,EAC5D,SAAWC,GAAO,KAAK,aAAapC,EAAwBoC,CAAE,EAC9D,SAAWA,GAAO,KAAK,aAAapC,EAAwBoC,CAAE,EAC9D,gBAAiB,CAACA,EAAI9B,EAAK+B,IACzB,KAAK,oBAAoBrC,EAAwBoC,EAAI9B,EAAK+B,CAAK,EACjE,UAAW,CAACC,EAAWC,EAAUC,IAC/B,KAAK,cAAcxC,EAAwBsC,EAAWC,EAAUC,CAAS,EAC3E,YAAcJ,GAAO,KAAK,gBAAgBpC,EAAwBoC,CAAE,EACpE,eAAiBK,GAAa,KAAK,mBAAmBzC,EAAwByC,CAAQ,EACtF,uBAAwB,CAACA,EAAUC,IACjC,KAAK,2BAA2B1C,EAAwByC,EAAUC,CAAQ,EAC5E,YAAa,IAAM,KAAK,gBAAgB1C,CAAsB,EAC9D,eAAiByC,GAAa,KAAK,mBAAmBzC,EAAwByC,CAAQ,EACtF,SAAU,IAAM,KAAK,aAAazC,CAAsB,EACxD,SAAU,IAAM,KAAK,aAAaA,CAAsB,EACxD,iBAAkB,CAAC2C,EAAYC,IAC7B,KAAK,qBAAqB5C,EAAwB2C,EAAYC,CAAI,EACpE,mBAAqBC,GAAU,KAAK,uBAAuB7C,EAAwB6C,CAAK,EACxF,UAAW,IAAM,CACf,KAAK,eAAe7C,CAAsB,EAC1C,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,CAC/B,EACA,WAAY,IAAM,CAChB,KAAK,eAAeA,CAAsB,EAC1C,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,wBAAwB,CAC/B,EACA,kBAAmB,IAAM,KAAK,iBAAiB,EAC/C,mBAAoB,IAAM,KAAK,iBAAiB,CAClD,EACA,CAAE,cAAe,EAAM,CACzB,EACA,KAAK,UAAYiC,EACjBA,EAAI,YAAYjC,CAAsB,EACtCiC,EAAI,WAAW,KAAK,OAAO,EAE3B,IAAM+B,EAAY,KAAK,cAAc,iBAAiB,EAChDC,EAAUhC,EAAI,cAAc,EAClCgC,EAAQ,aAAa,8BAA+B,EAAE,EACtDA,EAAQ,MAAM,SAAW,WACzBA,EAAQ,MAAM,KAAO,OACrBA,EAAQ,MAAM,OAAS,OACvBA,EAAQ,MAAM,cAAgB,OAC9BD,EAAU,YAAYC,CAAO,EAC7BhC,EAAI,iBAAiB,EAAI,EAEzB,KAAK,aAAa,EAClB,KAAK,iBAAiB,CACxB,CAEQ,oBAA2B,CACjC,IAAM8B,EAAO,KAAK,WAClB,GAAI,CAACA,EAAM,OACX,IAAMG,EAAQ,KAAK,KAAK,SAAS,aAAe,OAAO,WACjDC,EAAS,KAAK,KAAK,SAAS,cAAgB,OAAO,YACzDJ,EAAK,MAAM,MAAQ,GAAGG,CAAK,KAC3BH,EAAK,MAAM,OAAS,GAAGI,CAAM,KAC7B,KAAK,eAAe,YAAY,EAAG,EAAGD,EAAOC,CAAM,CACrD,CAEQ,cAAqB,CAC3B,IAAMpC,EAAU,KAAK,cACrB,GAAI,CAACA,EAAS,OACd,IAAME,EAAM,KAAK,UACXyB,EAAgB,KAAK,KAAK,SAAS,aAAe,OAAO,WACzDC,EAAY1B,GAAK,UAAU,EAC7B,KAAK,YAAY,qBAAqBjC,CAAsB,EAC5D,KAAK,YAAY,qBAAqBA,EAAwB0D,CAAa,EAC/E3B,EAAQ,OAAO4B,EAAW,KAAK,YAAY,mBAAmB,CAAC,CACjE,CAEQ,kBAAyB,CAC/B,IAAM1B,EAAM,KAAK,UACjB,GAAI,CAACA,EAAK,OACV,IAAMyB,EAAgB,KAAK,KAAK,SAAS,aAAe,OAAO,WACzDE,EAAmB,KAAK,YAAY,oBACxC5D,EACA0D,CACF,EACKzB,EAAI,UAAU,GACQ,KAAK,YAAY,oBAAoBjC,CAAsB,IAC3D4D,GACvB,KAAK,YAAY,aAAa5D,EAAwB4D,EAAkB,EAAK,EAGjF,IAAMR,EAAmB,KAAK,YAAY,oBAAoBpD,CAAsB,EAC9E2D,EAAY,KAAK,YAAY,qBAAqB3D,CAAsB,EACxEmD,EAAU,KAAK,YAAY,WAAWnD,CAAsB,EAC5D6D,EAAa,KAAK,YAAY,cAAc7D,CAAsB,EACxEiC,EAAI,QAAQ0B,EAAWR,EAASU,EAAYT,EAAkBQ,CAAgB,CAChF,CAEQ,kBAAkBlC,EAAmC,CAC3D,KAAK,iBAAiB,EAClBA,IACF,KAAK,eAAiBA,GAExB,KAAK,0BAA0BA,CAAa,EAC5C,KAAK,WAAW,OAAO,EACvB,KAAK,wBAAwB,CAC/B,CAEQ,yBAAgC,CACtC,GAAI,CAAC,KAAK,eAAgB,OAC1B,IAAM0C,EAAO,KAAK,WAAW,UAAU,GAAK,GAC5C,KAAK,eAAe,aAAa,cAAeA,EAAO,OAAS,OAAO,EACvE,KAAK,eAAe,aAAa,gBAAiBA,EAAO,OAAS,OAAO,CAC3E,CAEQ,0BAA0B1C,EAAmC,CACnE,GAAI,CAACA,GAAiB,CAAC,KAAK,UAC1B,OAGF,IAAMuC,EAAU,KAAK,UAAU,cAAc,EACvCH,EAAS,KAAK,cAAc,iBAAiB,EAC7CO,EAAa3C,EAAc,sBAAsB,EACjD4C,EAAaR,EAAO,sBAAsB,EAChDG,EAAQ,MAAM,KAAO,GAAG,KAAK,MAAMI,EAAW,MAAQC,EAAW,IAAI,CAAC,KACtEL,EAAQ,MAAM,IAAM,GAAG,KAAK,MAAMI,EAAW,IAAMC,EAAW,IAAM,EAAE,CAAC,KACvEL,EAAQ,MAAM,OAAS,OACvBA,EAAQ,MAAM,UAAY,EAC5B,CAEQ,mBAA0B,CAChC,KAAK,eAAe,QAAQ,EAC5B,KAAK,cAAgB,KACrB,KAAK,WAAW,QAAQ,EACxB,KAAK,UAAY,KACjB,KAAK,YAAY,OAAO,EACxB,KAAK,WAAa,IACpB,CAEQ,eAAetC,EAAyB,CAC9C,KAAK,SAAS,IAAIA,CAAS,GAAG,QAAQ,EACtC,KAAK,SAAS,OAAOA,CAAS,EAC9B,KAAK,KAAK,IAAIA,CAAS,GAAG,QAAQ,EAClC,KAAK,KAAK,OAAOA,CAAS,EAC1B,KAAK,eAAe,OAAOA,CAAS,EACpC,KAAK,oBAAoB,OAAOA,CAAS,EACzC,KAAK,WAAW,IAAIA,CAAS,GAAG,gBAAgB,uBAAuB,EACvE,KAAK,WAAW,IAAIA,CAAS,GAAG,gBAAgB,wBAAwB,EACxE,KAAK,WAAW,IAAIA,CAAS,GAAG,gBAAgB7B,EAAqB,EACrE,KAAK,WAAW,IAAI6B,CAAS,GAAG,MAAM,eAAe,4BAA4B,EACjF,KAAK,WAAW,OAAOA,CAAS,CAClC,CAEQ,oBAA2B,CACnB,KAAK,cAAc,OAAO,KAAK,aAAa,CAAC,EACrD,aAAa,iCAAkC,EAAE,CACzD,CAEQ,wBAA+B,CAEvC,CAEQ,qBAA4B,CAClC,KAAK,mBAAmB,EACxB,KAAK,aAAe,GACpB,KAAK,2BAA2B,EAChC,KAAK,aAAe,GACpB,OAAW,CAACA,EAAWmB,CAAK,IAAK,KAAK,eACpC,KAAK,wBAAwBA,EAAO,KAAK,oBAAoB,IAAInB,CAAS,CAAC,EAE7E,KAAK,iBAAmB,EAC1B,CAEQ,4BAAmC,CACzC,OAAW,CAACA,EAAWmB,CAAK,IAAK,KAAK,eACpC,KAAK,oBAAoB,IAAInB,EAAW,KAAK,eAAemB,CAAK,CAAC,CAEtE,CAEQ,eAAeA,EAAiD,CAEtE,IAAM5C,EADS4C,EAAM,OACE,YACvB,GAAI,CAAC,KAAK,SAAW,CAAC5C,GAAW,CAACA,EAAQ,YACxC,MAAO,CAAE,QAAS,GAAO,KAAM,EAAG,KAAM,EAAG,aAAc,CAAE,EAG7D,IAAMqE,EAAa,KAAK,sBAAsB,EACxCC,EAAY,KAAK,qBAAqB,EACtCC,EAAOvE,EAAQ,sBAAsB,EACrCgE,EAAQO,EAAK,OAASvE,EAAQ,aAAeA,EAAQ,aAAe,EACpEiE,EAASM,EAAK,QAAUvE,EAAQ,cAAgBA,EAAQ,cAAgB,EACxEwE,EAAWD,EAAK,KAAOF,EACvBI,EAAWF,EAAK,IAAMD,EAE5B,GAAIN,GAAS,GAAKC,GAAU,EAC1B,MAAO,CAAE,QAAS,GAAO,KAAM,EAAG,KAAM,EAAG,aAAc,CAAE,EAG7D,IAAMS,EAAiB,KAAK,KAAK,SAAS,cAAgB,OAAO,YAC3DlB,EAAgB,KAAK,KAAK,SAAS,aAAe,OAAO,WACzDmB,EAAeJ,EAAK,KACpBK,EAAcL,EAAK,IAOzB,GALEK,EAAcX,EAAS,GACvBW,EAAcF,GACdC,EAAeX,EAAQ,GACvBW,EAAenB,EAGf,MAAO,CAAE,QAAS,GAAO,KAAM,EAAG,KAAM,EAAG,aAAc,CAAE,EAG7D,IAAMqB,EAAcL,EAAWR,EACzBc,EAAkBL,EAClBM,EAAe,KAAK,0BAA0BnC,EAAOiC,EAAaC,CAAe,EAEvF,MAAO,CACL,QAAS,GACT,KAAMD,EACN,KAAMC,EAAkBC,EACxB,aAAAA,EACA,YAAaP,EACb,YAAaC,EACb,MAAAT,EACA,OAAAC,CACF,CACF,CAEQ,wBACNrB,EACAoC,EACM,CACN,GAAI,CAACA,GAAe,CAACA,EAAY,QAAS,CACxCpC,EAAM,IAAI,iBAAiB,EAAK,EAChCA,EAAM,OAAO,YAAY,MAAM,YAAY,6BAA8B,KAAK,EAC9E,MACF,CAEAA,EAAM,IAAI,iBAAiB,EAAI,EAC/BA,EAAM,OAAO,YAAY,MAAM,YAC7B,6BACA,GAAGoC,EAAY,YAAY,IAC7B,EACApC,EAAM,IAAI,kBAAkBoC,EAAY,KAAMA,EAAY,KAAM,WAAW,EAE3E,IAAMnD,EAAU,KAAK,SAAS,IAAI9B,GAAiB6C,EAAM,OAAO,YAAaA,EAAM,MAAM,CAAC,EAExFf,GACAmD,EAAY,aAAe,MAC3BA,EAAY,aAAe,MAC3BA,EAAY,OAAS,MACrBA,EAAY,QAAU,MAEtBnD,EAAQ,YACNmD,EAAY,YACZA,EAAY,YACZA,EAAY,MACZA,EAAY,MACd,CAEJ,CAEU,cAA4B,CACpC,OAAO,KAAK,KAAK,OAAO,WAAa,SAAS,MAAQ,SAAS,eACjE,CAEQ,cAAc/E,EAA8B,CAClD,IAAMgF,EAAQhF,EAAO,YAAoB,OAAO,EAC1CiF,EAAOjF,EAAO,YAAoB,MAAM,EAC9C,OAAIgF,GAAS,MAAQC,GAAQ,MAAQA,EAAO,EACnCD,EAEFhF,EAAO,YAAoB,gBAAgB,GAAK,CACzD,CAEQ,uBAAgC,CAEtC,OADiB,KAAK,KAAK,OAAO,kBACjB,YAAc,CACjC,CAEQ,sBAA+B,CAErC,OADiB,KAAK,KAAK,OAAO,kBACjB,WAAa,CAChC,CAEQ,0BACN2C,EACAiC,EACAM,EACQ,CACR,OAAOC,GAAoB,uBACzBxC,EAAM,OAAO,YACbiC,EACAM,EACCE,GAAe,CACd,IAAMC,EAAiB,KAAK,cAAc,IAAI,IAAID,CAAU,EAC5D,GAAI,CAACC,EACH,OAAO,KAGT,IAAMC,EACJD,EAAe,YAAoB,cAAc,GACjDA,EAAe,YAAY,aAC3BA,EAAe,YAAY,aAC3B,EAEF,MAAO,CACL,MACGA,EAAe,YAAoB,iBAAiB,GAAK,GAAKC,EACjE,KAAM,KAAK,cAAcD,CAAc,CACzC,CACF,CACF,CACF,CAEQ,yBAAgC,CACtC,IAAME,EAAyB,CAC7B,IAAIC,GACJ,IAAIC,GACJ,IAAIC,GACJ,IAAIC,GACJ,IAAIC,GACJ,IAAIC,EACN,EAEA,QAAW9C,KAAWwC,EACpB,KAAK,YAAY,gBAAgBxC,CAAO,CAE5C,CAEQ,0BAAiC,CACvC,IAAM+C,EAAW,KAAK,SAAS,SAC/B,GAAKA,EAEL,QAAW/C,KAAW+C,EACpB,KAAK,YAAY,gBAAgB/C,CAAO,CAE5C,CACF,EA/vBa5B,GAiBK,QAAU,CACxB,GAAI,SACJ,MAAO,SACP,KAAM,SACN,MAAO,GACP,MAAO,EACP,OAAQ,CAAE,IAAK,IAAK,SAAU,EAAK,EACnC,OAAQ4E,GACR,SAAU,CAAE,OAAQ,GAAO,KAAM,CAAC,QAAQ,CAAE,CAC9C,EC3LK,IAAMC,GAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAA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","names":["index_exports","__export","CursorReactiveModule","DOMBatcher","GridAdapter","ScrollController","StringAnchor","StringCursor","StringData","StringDelayLerpTracker","StringDevIconRegistry","StringDevInview","StringDevLayout","StringDevModule","StringDevOverlayRegistry","StringDevProgress","StringDevRulers","StringFPSTracker","StringForm","StringGlide","StringImpulse","StringLazy","StringLerp","StringLerpTracker","StringLoading","StringMagnetic","StringMasonry","StringModule","StringObject","StringParallax","StringPositionTracker","StringProgress","StringProgressPart","StringRandom","StringResponsive","StringScrollContainer","StringScrollbar","StringScroller","StringSequence","StringSplit","StringSpotlight","StringTune","StringVideoAutoplay","buildDevtoolsThemeBlock","ensureStringDevtoolsSharedStyles","frameDOM","resolveDevtoolsIcon","styleTxn","__toCommonJS","CursorController","smoothing","context","e","cursorData","now","dt","tX","tY","sX","sY","stepX","stepY","data","lerp","t","EventManager","eventName","initialPayload","callback","id","fullEvent","payload","set","value","visible","ModuleManager","data","module","i","type","e","_data","added","removed","lifecycle","arg","arg2","modules","len","mod","StringMirrorObject","id","element","parent","key","value","easing","rawProgress","fallback","StringObject","id","element","EventManager","prefix","suffix","cached","eventName","suffixMap","cachedWithSuffix","key","value","module","blocked","active","index","tokens","token","i","len","mirror","DOMBatcher","task","priority","contexts","module","object","element","attributes","globalId","rect","windowSize","sortByPriority","a","b","error","ModuleLifecyclePermissions","EMPTY_CONTEXT","StringModule","context","ModuleLifecyclePermissions","element","object","boundingRect","top","height","globalId","attributes","key","type","fallback","transform","resolvedFallback","attributeFallback","raw","parsed","host","scroller","rect","computedStyle","fallbackSize","docLeft","docTop","width","hostRect","elementOffset","hostOffset","parsedWidth","parsedHeight","left","current","windowSize","start","size","offsetStart","offsetEnd","startElement","startViewport","endElement","endViewport","startPosition","endPosition","startBias","endBias","inviewTop","inviewBottom","value","parsedBreakpoint","breakpoints","item","val","token","mode","id","array","index","lastIndex","activeObject","activeIndex","applyFn","copyFn","mirror","prefix","suffix","clearStyles","el","i","mirrors","previousActiveOnPage","data","event","added","removed","ObjectManager","data","modules","events","tools","DOMBatcher","el","idAttr","key","object","StringObject","keysAttr","attributes","coreModules","i","m","connectableModules","allModules","inviewFallbackModule","StringModule","batchContexts","write","item","enabled","module","element","shouldConnect","isConnected","root","targets","maybeAdd","id","obj","nodes","windowSize","all","mirror","mirrorIds","copyFromId","ids","singleId","parent","existingIds","existing","mirrorId","StringMirrorObject","easingAttr","rawProgress","progressValue","parentEasing","mirrorProgress","raw","attrList","attr","start","end","progressCallback","entries","e","outsideProp","outsideAttrValue","outsideAttrNormalized","outsideAttrFlag","isOutsideContainer","observerRoot","progressObserver","observer","mutations","shouldNotifyDOMRebuild","mutationIndex","mutation","mutationHasElementNodes","removedIndex","node","queryStringNodes","child","queryMirrorNodes","addedIndex","queryAddedStringNodes","copyFrom","queryAddedMirrorNodes","childCopyFrom","q","isCanRebuild","scrollPos","activeStart","activeEnd","activeMin","activeMax","wasActive","isActive","inviewStart","inviewEnd","wasInView","isNowInView","direction","distToStart","distToEnd","buffer","windowMin","windowMax","a","b","list","value","low","high","mid","parts","result","chunks","tokens","chunk","match","modeRaw","normalizedModeRaw","values","current","bracketDepth","char","SCROLL_CLASS_NAMES","ScrollController","context","dir","container","current","e","scrollData","isDown","newState","rootClasses","SCROLL_CLASS_NAMES","rules","len","currentScroll","i","rule","shouldTrigger","id","position","immediate","StringScrollDefault","ScrollController","context","lerped","delta","now","e","scrollTop","positionDelta","timeDelta","normalizedDelta","position","immediate","StringScrollDisable","ScrollController","context","e","StringScrollSmooth","ScrollController","context","scrollData","scale","e","isScrollingUp","atTop","atBottom","nativeScrollTop","positionDelta","position","immediate","current","target","delta","speed","speedAccelerate","bottomPosition","out","scrollForce","nextTarget","lerped","nextDelta","nextCurrent","ScrollManager","context","StringScrollSmooth","StringScrollDefault","StringScrollDisable","name","controller","isCurrentMode","existing","rule","mode","newMode","e","events","engine","id","CursorState","RenderState","ScrollState","SystemState","TimeState","ViewportState","StringData","ScrollState","ViewportState","CursorState","RenderState","TimeState","SystemState","BoundingClientRectTool","element","DOMAttributeTool","element","key","fallback","RecordAttributeTool","record","name","fallback","TransformNullifyTool","element","rect","values","a","b","c","d","e","f","det","RelativePositionTool","transformTool","TransformNullifyTool","element","container","containerRect","elRect","LerpTool","from","to","progress","UnitParserTool","value","element","viewportHeight","baseRem","boundingRect","parts","s","sum","part","v","isNegative","result","AdaptiveLerpTool","value","inMin","inMax","outMin","outMax","t","HORIZONTAL_KEYWORDS","VERTICAL_KEYWORDS","OriginParserTool","value","raw","options","s","index","parts","single","parsed","first","second","firstIsVerticalOnly","secondIsHorizontalOnly","val","axis","num","ColorParserTool","value","str","hex","ch","r","g","b","a","rgbMatch","v","hslMatch","h","l","s","hue2rgb","p","q","t","EasingFunctionTool","easing","def","match","x1","y1","x2","y2","t","cx","bx","ax","cy","by","ay","sampleCurveX","sampleCurveY","sampleCurveDerivativeX","solveCurveX","x","epsilon","t0","t1","t2","d2","i","MagneticPullTool","distance","radius","strength","proximity","LerpColorTool","from","to","progress","LerpVector2Tool","from","to","progress","TransformScaleParserTool","value","str","matrixValues","matrixNumbers","scaleValue","scaleNumbers","scaleXValue","scaleNumber","scale3dValue","matrix3dValues","error","SplitOptionsParserTool","attributeValue","options","part","trimmedPart","match","fullOptionKey","params","p","parsedParam","str","_","letter","result","param","randomMatch","first","second","RuleParserTool","value","result","current","depth","i","c","ruleStr","match","key","params","s","colonIndex","paramsString","ValidationTool","v","params","normalized","digitCount","context","targetKey","otherValue","value","min","max","length","limit","rules","type","errors","rule","beforeInputValidatorFn","inputValidatorFn","inputValid","beforeInputValid","key","files","allowed","p","file","limitKb","maxBytes","item","mime","ext","name","parts","mode","target","currentDate","referenceDate","token","contextualValue","today","date","timestamp","pattern","allowEmpty","stringValue","source","flags","trimmed","lastSlashIndex","a","b","segments","segment","num","hextetPattern","StyleTxn","el","key","value","style","vars","currentVars","k","v","props","currentProps","fn","alreadyOpen","error","styleTxn","DefaultToolsContainer","DOMAttributeTool","RecordAttributeTool","TransformNullifyTool","BoundingClientRectTool","RelativePositionTool","UnitParserTool","LerpTool","AdaptiveLerpTool","OriginParserTool","ColorParserTool","ValidationTool","EasingFunctionTool","MagneticPullTool","LerpColorTool","LerpVector2Tool","TransformScaleParserTool","SplitOptionsParserTool","RuleParserTool","styleTxn","isCoarsePointer","mm","touch","narrow","targetStates","CURSOR_EPSILON","DEFAULT_CURSOR_ID","CURSOR_PORTAL_SELECTOR","CURSOR_PORTAL_CONTENT_SELECTOR","MIN_FRAME_DELTA","roundTo","value","precision","scale","getTargetState","object","state","StringCursor","StringModule","context","isCoarsePointer","globalId","element","attributes","rect","data","now","dt","cursorX","cursorY","isOver","isDisabled","baseLerp","frameLerp","dimensions","halfWidth","halfHeight","width","height","cx","cy","elementX","elementY","px","py","dx","dy","isMoving","enterMode","alignment","visualX","visualY","lerpedX","lerpedY","updatedX","updatedY","pixelChanged","offsetX","offsetY","mouseX","mouseY","targetX","targetY","newMouseX","newMouseY","stepX","stepY","smoothedX","smoothedY","prev","bucket","portal","cursorClass","added","removed","node","id","customLerp","content","existing","attrSources","source","raw","clamped","nodes","cb","ids","selected","normalized","portals","fallbackBucket","currentX","currentY","factor","fpsAdjustedLerp","safeDt","normalizedVelocityX","normalizedVelocityY","nextX","nextY","x","y","pixelX","pixelY","floatNum","roundedX","roundedY","vars","extraVars","prevPx","prevPy","angle","angleDeg","apply","el","styleTxn","v","base","clampedBase","frames","adjusted","cachedWidth","cachedHeight","fallbackWidth","fallbackHeight","rawHalfWidth","rawHalfHeight","mousePos","size","offset","obj","StringImpulse","StringModule","context","object","observer","_e","cursorVelocityX","cursorVelocityY","mouseX","mouseY","rect","w","side01","positionStrength","isContinuousPush","isLatched","objectVelocityX","objectVelocityY","rotationStrength","centerX","centerY","relativeX","relativeY","torque","angularVelocityDeg","originValue","x","y","attrName","dataAttrName","mutations","mutation","newValue","normalizedX","normalizedY","_","objectItem","isUnderCursor","i","offsetX","offsetY","velocityX","velocityY","positionTension","positionFriction","maxVelocity","maxOffset","velocityDecay","angleDeg","rotationTension","rotationFriction","maxAngularVelocityDeg","maxRotationAngleDeg","sleepEpsilon","isPositionAsleep","isRotationAsleep","positionUpdateThreshold","rotationUpdateThreshold","prevCssX","prevCssY","prevCssRot","cssTranslateX","cssTranslateY","cssRotateDeg","needsPositionUpdate","needsRotationUpdate","el","styleTxn","FrameDOM","fn","mQueue","i","e","wQueue","frameDOM","RESIZE_DEBOUNCE_MS","CONSTANTS","parseTime","val","n","getResponsiveValue","data","windowWidth","sorted","a","b","matched","e","StringMasonry","StringModule","context","object","el","styleTxn","state","id","timeNow","activeAnimations","elapsed","progress","ease","currentH","item","pProgressRaw","pProgress","pEaseVal","sProgressRaw","sProgress","sEaseVal","o","initialRect","roCallback","entries","rect","containerStyle","padL","padR","contentWidth","columns","gap","columnWidth","moCallback","muts","needsLayout","m","htmlEl","height","animateHeight","animate","reason","frameDOM","container","children","containerRect","padT","allowHeightAnim","layoutParamsSame","childrenHash","prevWidths","s","itemHeights","heightsHash","h","width","colHeights","now","hasMovement","maxMoveDuration","index","colIndex","minH","i","targetX","targetY","targetW","posDuration","sizeDuration","invPosDur","invSizeDur","posEase","sizeEase","itemState","startX","startY","newContainerHeight","viewportHeight","isFromBottom","scrollAdjustment","targetScroll","ww","manualCols","manualGap","colsData","gapData","root","img","imageEl","handler","cleanupSingle","unsub","StringMagnetic","StringModule","context","globalId","object","element","attributes","e","i","rect","centerX","centerY","dx","dy","distance","radius","strength","factor","data","magneticX","magneticY","lerp","targetMagneticX","targetMagneticY","lerpX","lerpY","eventName","x","y","el","styleTxn","CursorReactiveModule","StringModule","context","isCoarsePointer","object","id","obj","data","allowFallback","near","target","mx","my","targets","maxDistanceSq","cx","cy","dx","dy","d2","frameDOM","styleTxn","TAU","RAD2DEG","clamp01","v","shortestArc","from","to","d","DEFAULT_SPOTLIGHT_KERNEL","pointerDx","pointerDy","pointerDist","deadzone","distMax","lerp","currentAngle","currentDist","currentTargetAngle","prevDeg","prevDist","angleEps","distEps","forceImmediate","forceEmit","bypassDeadzone","out","targetAngle","targetDist","angle","dist","nextA","factor","degRaw","angleChanged","distChanged","SCROLL_UPDATE_OPTIONS","INITIALIZE_OPTIONS","spotState","getSpot","o","s","StringSpotlight","CursorReactiveModule","context","id","obj","el","attrs","frameDOM","styleTxn","data","targets","list","i","object","options","dx","dy","angleDeg","distance","apply","ASPECT_CLASS","isSvgSource","src","lower","parsePng","b","d","parseJpeg","o","m","len","parseWebp","i","chunkHeader","chunkSize","dataOffset","w","h","b0","b1","b2","b3","tryParseDims","buffer","ct","c","fetchImageStreamWithDims","opts","onDims","res","reader","PROBE_CAP","TRY_STEP","probe","probeLen","lastTriedLen","chunks","dims","announced","done","value","part","toCopy","view","full","blob","blobUrl","StringLazy","StringModule","context","img","object","element","state","listener","data","inviewEventName","raw","inView","crossOrigin","referrerPolicy","ac","finalize","loaded","onLoad","onError","StringLoading","StringModule","context","StringInview","StringModule","visitor","object","StringResponsiveQueryDevice","config","enable","min","max","query","StringResponsive","StringModule","context","isMobileMedia","isTabletMedia","isLaptopMedia","isDesktopMedia","element","showElement","StringAnchor","StringModule","context","tuple","xRaw","yRaw","x","y","object","anchor","el","ACCELERATION_STEP","MIN_DISPLACEMENT","MAX_DISPLACEMENT","MIN_VELOCITY","MAX_VELOCITY","StringGlide","StringModule","context","object","glideFactor","glideValue","eventName","transformCompute","globalId","element","attributes","i","objects","isDirectionUp","isConditionMet","data","dispNum","styleTxn","transform","needsVarUpdate","needsTransformUpdate","StringLerp","StringModule","context","object","styleTxn","i","data","velocity","len","force","lerp","prevLerp","lerpStr","eventName","clearCustomProperty","el","mirrors","STRING_DEV_PROGRESS_OVERRIDE_KEY","DEFAULT_PROGRESS_KERNEL","scroll","start","difference","raw","starts","differences","out","length","i","diff","StringProgress","StringModule","context","globalId","object","element","attributes","rawProgress","EPS","startPosition","differencePosition","overrideRawProgress","normalizedRaw","easing","progress","windowSize","data","len","styleTxn","key","parentEasing","eventName","mirror","eased","clearCustomProperty","el","mirrors","StringParallax","StringProgress","context","object","progress","factor","start","end","sign","screenSize","translation","globalId","element","attributes","bias","windowSize","data","i","styleTxn","transformData","StringScrollbarHorizontal","data","scrollbar","thumb","onScrollTo","contentWidth","visibleWidth","thumbSize","e","deltaY","newScrollPosition","StringScrollbarVertical","data","scrollbar","thumb","onScrollTo","contentSize","visibleSize","thumbSize","contentHeight","visibleHeight","e","deltaY","newScrollPosition","maxScroll","clamped","StringScrollbar","StringModule","context","position","data","style","StringScrollbarHorizontal","StringScrollbarVertical","e","SPLIT_ELEMENT_CLASS","getWholeWordSplitClass","word","first","ch","cls","getWordWrappers","shouldTrimGeneratedGap","currentWord","nextWord","options","currentWrappers","nextWrappers","i","BuildDOMTree","layoutLines","fontMetrics","fragment","hasLine","hasOption","localCharIndex","hasChar","totalWords","line","charsCount","w","linesCount","wordsGlobalCount","extraProps","li","isLastInLayout","container","wordsForLine","SPLIT_ELEMENT_CLASS","applyStyles","wrapperStack","appendTarget","wi","isLast","targetWrappers","commonLen","wInfo","wEl","name","value","original","wordText","c","hasWord","wordEl","wholeWordClass","char","charIndex","charNode","charEl","nextChar","kerning","splitClassChar","textNode","nextNoSpace","lineText","el","calculatedValues","val","isOptionEnabled","varName","generateVariableName","type","align","group","item","norm","key","OPAQUE_TAGS","getElementAttributes","el","attrs","i","attr","tokenCounter","BuildTokens","nodes","tokens","pushWithMeta","t","extra","processNode","node","carryMeta","tag","classes","extraMeta","child","wrapperInfo","currentWrappers","text","id","n","FontMetrics","element","canvas","cs","font","char","width","charA","charB","pair","key","widthWithKerning","widthWithoutKerning","kerning","word","totalWidth","i","prevChar","createCloneMeasurementSource","element","context","measurementWidth","clone","nodeMap","originalWalker","cloneWalker","originalNode","cloneNode","node","FlexMeasureAdapter","_element","createLiveMeasurementSource","node","InlineFlowMeasureAdapter","_element","context","_context","adapters","FlexMeasureAdapter","InlineFlowMeasureAdapter","getOwnContentWidth","container","cs","rect","borderLeft","borderRight","paddingLeft","paddingRight","getBlockContainerContentWidth","el","display","getLayoutMeasureContext","element","style","ownContentWidth","blockContainerContentWidth","isInlineLike","contentWidth","resolveLayoutMeasureAdapter","context","adapter","wrappersEqual","a","b","w","i","measureTokens","tokens","source","fontMetrics","options","range","measured","isAfterElement","lastTokenWasSpace","prevMeasuredWasText","prevTokenWrappers","tokenIndex","token","shouldTrimInlineGap","raw","hadLeadingSpace","hadTrailingSpace","currentWrappers","wordRe","match","wIdx","word","domRect","measureNode","wouldJoinPrev","sameWrappers","accurateWidth","rect","wordMeta","prev","index","findPrevMeaningfulToken","next","findNextMeaningfulToken","isInlineJoinCandidate","prevWrappers","getWrapperIds","nextWrappers","wrapper","LayoutMeasurer","tokens","container","fontMetrics","options","context","getLayoutMeasureContext","source","resolveLayoutMeasureAdapter","measureTokens","LINE_TOLERANCE","SplitMeasuredTokens","measured","container","fontMetrics","lines","currentLine","y","charIndexGlobal","wordIndexGlobal","currentLineBrowserRight","mt","token","isBefore","isAfter","wordText","splitClass","joinPrev","chars","currentXInWord","i","ch","prev","charWidth","kerning","charRect","pc","lastChar","currentY","baselineY","wordBrowserRight","target","charsBeforeAll","acc","w","baseInWord","c","mergeRects","wordIndexInLine","charsBefore","processedWord","rect","rects","left","r","top","right","bottom","StringSplit","StringModule","context","rebuild","object","element","options","debugEnabled","isAlreadySplit","originalHtml","originalText","cs","currentContentWidth","lastWidth","attr","fragment","result","extraProps","value","key","restoreAfter","html","temp","raw","stage","payload","globalObject","store","current","style","baseline","debugPayload","rect","lineHeight","tokens","measured","layoutLines","token","item","line","word","char","lines","child","childEl","index","lineStyle","display","i","marker","el","d","layoutWidth","padding","parentContentWidth","fontMetrics","FontMetrics","frag","ch","BuildTokens","LayoutMeasurer","SplitMeasuredTokens","fitContext","fitExtraProps","dom","BuildDOMTree","v","k","currentFontSize","elementContentWidth","widestLineWidth","w","contentWidth","pcs","lineHeightPx","hasLineSplit","hasCharSplit","lineWidth","widestLine","best","l","targetFontSize","renderedLines","resultLines","renderedLine","resultLine","provisional","corrected","finalFontSize","textHeightAtFit","scope","provisionalFontSize","targetWidth","applyToChars","baselineWidth","trialWidth","slope","fontSize","chars","restore","width","previous","walker","textNode","parent","inChar","inLeafElement","range","node","leaf","browserWordWidthSum","spacesWidth","scalableWidth","opt","total","min","max","centerIdx","countChars","ln","acc","totalWords","totalCharsGlobal","acc2","li","totalCharsInLine","cvs","str","StringDelayLerpTracker","StringModule","context","data","d","ctx","w","h","val","i","x","y","canvas","width","position","ATTR_FPS","StringFPSTracker","StringModule","context","_data","visible","fps","fpsStr","el","mutations","needsRescan","mutation","node","styleId","style","StringLerpTracker","StringModule","context","data","v","ctx","w","h","val","i","x","y","position","ATTR_VAL","ATTR_VAL_PCT","ATTR_DIR","StringPositionTracker","StringModule","context","data","current","target","contentHeight","windowHeight","val","maxScroll","valPct","direction","valStr","el","pctStr","visible","mutations","needsRescan","mutation","node","styleId","style","Debounce","func","delay","timeoutId","args","context","StringFPS","time","fps","now","elapsed","callback","StringVideoAutoplay","StringModule","context","object","videoElement","started","element","err","SequenceState","SequenceProgressVars","_StringSequence","StringModule","context","e","data","current","max","target","dir","els","el","trigger","parsed","object","get","k","seq","attr","key","match","slider","value","settings","global","group","obj","sliders","p","step","sequence","enteringDuration","leavingDuration","active","m","attrKey","seqAttr","v","easing","idx","transitionProgress","direction","duration","instant","toStep","customDuration","fromStep","prevLeaving","enteringGroup","leavingGroup","transition","progress","prev","leaving","enteringProg","leavingProg","state","rawProgress","currentState","currentDir","styleTxn","SequenceProgressVars","t","elapsed","payload","from","to","entering","SequenceState","StringSequence","_StringForm","StringModule","context","globalId","object","element","attributes","existingEvents","evt","form","fieldEntries","fieldValues","field","idx","submitCallback","event","allValid","data","processedRadioKeys","entry","key","rules","needsContext","value","valid","errors","firstInvalidEntry","added","removed","phase","errorBlock","groupBlock","message","span","eventSuffix","el","ruleString","events","preferredIndex","registeredIndex","supportsRealtime","inputEventType","inputHandler","target","beforeInputHandler","inputEvent","start","end","nextVal","index","i","registered","node","elements","nodes","state","owner","entries","stateEntries","values","existing","fallbackIdx","parsed","rule","fieldKey","override","needsOverride","lookupKey","checked","opt","attr","type","StringForm","CenterCache","obj","el","st","id","o","r","HoverTracker","obj","el","enter","leave","st","DEVTOOLS_ICONS","_StringDevIconRegistry","icon","DEVTOOLS_ICONS","sprite","symbol","size","name","modifiers","id","extraAttrs","m","svg","StringDevIconRegistry","resolveDevtoolsIcon","makeBadge","targetId","el","makePanel","attrs","k","v","e","makePanelHeader","makePanelContent","makeIconButton","options","icon","size","label","modifiers","mod","resolveDevtoolsIcon","makeDeleteButton","makePanelButton","withLabel","CORE_STYLES","STRING_DEV_DEFAULT_TOKENS","indentCss","cssText","indent","line","buildDevtoolsThemeBlock","selectors","overrides","selectorText","tokens","declarations","name","value","ensureStringDevtoolsSharedStyles","styleId","existing","style","CORE_STYLES","canUseMatchMedia","isCoarsePointerDevice","getStringDevViewportPolicy","viewportWidth","coarsePointer","compact","storageScopeToken","normalizeStorageScopeToken","value","normalized","setStringDevStorageScopeToken","scopeStringDevStorageKey","baseKey","DEVTOOLS_DOCK_STORAGE_KEY","SUB_BADGE_LONG_PRESS_DELAY_MS","SUB_BADGE_LONG_PRESS_MOVE_TOLERANCE","DOCK_ROOT_SELECTOR","SUB_BADGE_GROUP_SELECTOR","formatHotkey","hotkey","parts","StringDevtoolsDock","ensureStringDevtoolsSharedStyles","event","target","fpsSpan","definition","button","hotkeyLabel","buttonLabel","resolveDevtoolsIcon","nextActive","nextState","slot","subBadges","cleanup","unsubscribe","state","currentState","group","open","longPressTimer","longPressPointerId","longPressStartX","longPressStartY","suppressNextClick","setOpen","next","isCompact","getStringDevViewportPolicy","clearLongPress","releaseLongPress","scheduleClose","onSlotPointerEnter","onSlotPointerLeave","onGroupPointerEnter","onGroupPointerLeave","onSubBadgeAction","onSlotPointerDown","onSlotPointerMove","distanceX","distanceY","onSlotPointerLeaveCompact","onSlotContextMenu","onSlotSelectStart","onSlotClickCapture","onGroupContextMenu","onGroupSelectStart","onGroupClick","onDocumentPointerDown","activeObserver","reposition","rect","descriptor","attrs","key","value","badge","makeIconButton","id","entry","node","fps","span","ordered","left","right","leftOrder","rightOrder","lastGroup","currentGroup","sep","collapsed","persist","compact","contentSize","label","labelWithHotkey","active","saved","targetActive","raw","parsed","scopeStringDevStorageKey","DevtoolsManager","definition","StringDevtoolsDock","fps","StringScroller","StringModule","context","object","isScrollInited","wheelEvent","event","StringScrollContainer","StringModule","context","object","el","state","e","data","delta","isScrollingUp","isScrollingDown","atTop","atBottom","diff","parsePartOf","value","match","remap","value","from1","to1","from2","to2","StringProgressPart","StringModule","context","object","partOfId","partOfData","parsePartOf","progressEvent","progress","sliceProgress","clampedProgress","getRandomInRange","min","max","lo","hi","getRandomIntInRange","normalizeRange","value","a","b","StringRandom","StringModule","context","object","el","range","styleTxn","StringDevViewportLayer","id","zIndex","host","existing","root","screen","world","_StringDevOverlayRegistry","id","zIndex","existing","layer","StringDevViewportLayer","StringDevOverlayRegistry","StringDevModule","StringModule","context","StringDevOverlayRegistry","ensureStringDevtoolsSharedStyles","staticConfig","rawStaticStyles","styles","object","connects","k","attr","stylesText","firstKey","hash","i","config","subBadges","active","listener","hotkey","event","target","state","id","zIndex","existing","layer","styleId","cssText","style","_active","GRID_LAYOUT_LABELS","DEFAULT_MIN_WIDTHS","getLayoutLabel","index","total","labelIndex","GRID_LAYOUT_LABELS","nextId","createGridInstanceId","createGridLayoutId","createDefaultLayouts","count","safeCount","layouts","i","label","minWidth","normalizeGridLayoutMinWidth","value","reassignLabels","STORAGE_PREFIX","getStorageSlot","elementId","scopeStringDevStorageKey","countSerializedGrids","data","object","layouts","total","layout","layoutObject","instances","GridManager","adapter","type","state","viewportWidth","currentLargest","newMinWidth","newLayout","createGridLayoutId","reassignLabels","l","layoutId","index","persist","minWidth","normalizeGridLayoutMinWidth","selectedLayoutId","normalized","instance","createGridInstanceId","instanceId","draggedId","targetId","placement","fromIndex","i","targetIndex","dragged","normalizedTarget","insertIndex","name","title","key","value","payload","storageSlot","error","fallbackIds","candidateIds","candidates","candidateId","raw","parsed","selectedCandidate","candidate","resolvedStorageId","valid","createDefaultLayouts","rawLayouts","clamped","a","b","below","SVG_NS","GridOverlay","target","world","onResize","docX","docY","width","height","instances","adapterRegistry","instance","adapter","group","enabled","groups","i","instanceId","StringDevUIField","key","label","defaultValue","onChange","disabled","value","row","HOLD_DELAY_MS","HOLD_INTERVAL_MS","DRAG_PIXELS_PER_STEP","StringDevFieldNumber","StringDevUIField","key","label","defaultValue","onChange","min","max","step","row","value","disabled","button","control","stepper","input","event","directionName","direction","resolveDevtoolsIcon","holdTimeout","holdInterval","suppressClick","stopHold","previousX","accumulated","previousCursor","previousUserSelect","stopDrag","onMouseMove","moveEvent","deltaX","rawValue","parsed","nextValue","multiplier","snapped","precision","HOLD_DELAY_MS","HOLD_INTERVAL_MS","DRAG_PIXELS_PER_STEP","_StringDevFieldRange","StringDevUIField","key","label","defaultValue","onChange","min","max","step","displayMultiplier","displayStep","suffix","units","currentUnit","row","value","disabled","button","control","inputShell","unitSelect","u","opt","stepper","valueInput","event","directionName","direction","resolveDevtoolsIcon","holdTimeout","holdInterval","suppressClick","stopHold","input","previousX","accumulated","previousCursor","previousUserSelect","stopDrag","onMouseMove","moveEvent","deltaX","parsed","snapped","multiplier","displayNextValue","nextValue","clamped","precision","displayMin","displayMax","normalizedDisplay","v","displayValue","StringDevFieldRange","StringDevFieldColor","StringDevUIField","row","value","disabled","shell","colorInput","hexLabel","val","StringDevFieldSelect","StringDevUIField","key","label","defaultValue","onChange","options","row","value","disabled","button","shell","select","opt","option","stepper","directionName","direction","resolveDevtoolsIcon","count","nextIndex","StringDevFieldToggle","StringDevUIField","row","toggle","hidden","knob","next","value","disabled","StringDevUIBuilder","schema","values","onChange","handleChange","key","value","fragment","currentGroup","descriptor","field","StringDevFieldNumber","StringDevFieldRange","StringDevFieldColor","StringDevFieldSelect","StringDevFieldToggle","entry","disabledWhen","disabled","MOBILE_PANEL_MARGIN","MOBILE_PANEL_MAX_WIDTH","MOBILE_PANEL_MAX_HEIGHT","GridHUD","target","adapterRegistry","callbacks","options","instances","layouts","panelTitle","selectedLayoutId","resolvedLayoutId","instance","layout","targetId","docX","docY","align","anchorTransform","visible","enabled","makeBadge","trigger","makeIconButton","event","panel","makePanel","header","makePanelHeader","nextTitle","closeButton","responsive","makePanelContent","makePanelButton","empty","adapter","item","exportButton","importButton","hr","activateChipLayout","layoutId","chip","breakpointsRow","inputField","orderedLayouts","canDelete","inputId","fieldIconWrap","resolveDevtoolsIcon","editorInput","pxLabel","activeLayoutId","activeMarkerEl","activeValue","setActive","currentValue","markerEl","focusInput","commitEditor","parsed","initialMarker","index","segmentDiv","labelSpan","deleteBtn","makeDeleteButton","largerLayout","marker","markerSpan","mode","l","toggle","deleteButton","el","rect","placement","draggedId","hasInstances","entry","StringDevUIBuilder","settingsEl","key","value","checked","onChange","label","input","knob","currentName","parent","commit","nextName","btnRect","containerRect","instanceId","builder","selectedItem","itemRect","viewport","viewportWidth","viewportHeight","availableWidth","availableHeight","width","maxHeight","left","GridSerializer","layouts","selectedLayoutId","layout","instance","data","adapterRegistry","object","version","source","index","GRID_LAYOUT_LABELS","grid","type","adapter","createGridInstanceId","left","right","rawSelected","filename","json","blob","url","link","resolve","reject","input","cleanup","file","reader","value","normalizeGridLayoutMinWidth","SVG_NS","GridAdapter","svg","instanceId","group","x1","y1","x2","y2","color","opacity","strokeWidth","line","x","y","width","height","fill","rect","value","unit","dimension","referenceElement","rootFontSize","elementFontSize","d","stroke","path","_ColumnsAdapter","GridAdapter","svg","width","height","settings","group","count","rawGap","gapUnit","rawMargin","marginUnit","color","opacity","showLines","referenceElement","gap","margin","availableWidth","totalGaps","columnWidth","i","x","ColumnsAdapter","_RowsAdapter","GridAdapter","svg","width","height","settings","group","mode","count","rawSize","sizeUnit","rawGap","gapUnit","rawMargin","marginUnit","color","opacity","style","referenceElement","gap","margin","availableHeight","size","available","bandHeight","i","y","step","h","RowsAdapter","CenterAdapter","GridAdapter","svg","width","height","settings","group","showVertical","showHorizontal","color","opacity","dashed","dashAttr","line","RuleOfThirdsAdapter","GridAdapter","svg","width","height","settings","group","color","opacity","showIntersections","third_w","third_h","points","cx","cy","circle","PHI","GoldenRectangleAdapter","GridAdapter","svg","width","height","settings","group","depth","showSpiral","color","opacity","gw","gh","gx","gy","border","x","y","w","h","spiralD","isFirst","i","dir","s","sqX","sqY","SVG_NS","_DotGridAdapter","GridAdapter","svg","width","height","settings","group","rawStep","stepUnit","dotSize","shape","color","opacity","desiredStep","step","patternId","defs","pattern","center","circle","rect","instanceId","normalizedStep","maxCells","DotGridAdapter","STRING_DEVTOOLS_OVERLAY_LAYOUT_CHANGE_EVENT","OverlaySlotRegistry","id","order","badgeCount","overlayId","contentX","contentY","sorted","index","slotOffset","i","element","baseDocX","baseDocY","resolveAncestorAnchor","ancestorAnchors","current","ancestorId","anchor","offset","hasCollision","STRING_DEVTOOLS_OVERLAY_LAYOUT_CHANGE_EVENT","list","entry","a","b","overlaySlotRegistry","buildGridCSS","buildDevtoolsThemeBlock","GRID_STORAGE_KEY_ATTR","AUTO_STRING_OBJECT_ID_RE","GLOBAL_GRID_ELEMENT_ID","resolveElementId","element","object","existing","declaredStringId","key","domId","buildElementPathKey","resolveLegacyElementIds","primaryId","pathname","candidates","candidate","index","segments","current","parent","tag","sibling","resolveGridDepth","depth","StringDevLayout","StringDevModule","context","GridManager","anchorElement","elementId","fallbackIds","gridDepth","overlayWorld","overlay","GridOverlay","hud","GridHUD","type","id","value","draggedId","targetId","placement","layoutId","minWidth","instanceId","name","title","entry","enabled","active","instance","adapter","layouts","selectedLayoutId","data","GridSerializer","slug","raw","result","viewportWidth","instances","resolvedLayoutId","panelTitle","screen","host","hudScreen","hudRoot","width","height","open","anchorRect","screenRect","scrollLeft","scrollTop","rect","contentX","contentY","viewportHeight","viewportLeft","viewportTop","triggerDocX","baseTriggerDocY","stackOffsetY","measurement","start","size","triggerDocY","overlaySlotRegistry","ancestorId","ancestorObject","ancestorWidth","builtIn","ColumnsAdapter","RowsAdapter","CenterAdapter","GoldenRectangleAdapter","RuleOfThirdsAdapter","DotGridAdapter","external","buildGridCSS","RULERS_CSS","_nextId","createRulerLineId","STORAGE_PREFIX","RulersManager","elementId","modeId","scopeStringDevStorageKey","axis","position","targetLabel","targetSelector","targetEdge","line","createRulerLineId","key","state","lineId","l","serialized","raw","lines","SnapEngine","opts","axis","scrollX","scrollY","viewportWidth","viewportHeight","lines","excludeLineId","extraCandidates","el","rect","rawDocPos","bestDist","best","c","dist","stepped","pos","vw","vh","grid","count","marginLeft","marginRight","gap","usableWidth","colWidth","i","left","right","center","height","period","rangeStart","rangeEnd","firstRow","axisLines","line","a","b","base","prev","next","DefaultMode","docPos","CenterMode","axis","viewportSize","scroll","center","viewportWidth","viewportHeight","scrollX","scrollY","RULER_MODES","MODE_ORDER","startPointerDrag","startEvent","handlers","originEl","startX","startY","pointerId","threshold","started","disposed","dispose","onMove","onEnd","onCancel","onKey","e","dx","dy","scrollLocks","pageScrollLocks","selectionLocks","snapshot","targetSnapshots","captureSnapshot","html","body","ensureSnapshot","resolveScrollTarget","target","preventTouchScroll","event","lockScrollTarget","existing","unlockScrollTarget","applyLocks","scrollTarget","syncLocks","releasedScrollTarget","lockPageInteraction","options","lockScroll","lockSelection","released","RULER_THICKNESS","RULER_THICKNESS_MOBILE","RULER_PLATE_BACKGROUND_COLOR","RULER_PLATE_BACKGROUND_OPACITY","RULER_PLATE_BORDER_COLOR","RULER_PLATE_BORDER_OPACITY","RULER_TICK_COLOR","RULER_TICK_FONT_SIZE","RULER_TICK_FONT","RULER_TICK_LABEL_OFFSET_TOP","RULER_TICK_LABEL_OFFSET_LEFT","RULER_TICK_LONG_SIZE","RULER_TICK_SHORT_SIZE","RULER_TICK_LONG_SIZE_MOBILE","RULER_TICK_SHORT_SIZE_MOBILE","COL_EDGE_COLOR","COL_CENTER_COLOR","COL_BG_COLOR","COL_LABEL_COLOR","COL_LABEL_FONT_SIZE","COL_LABEL_FONT","ROW_EDGE_COLOR","ROW_CENTER_COLOR","ROW_BG_COLOR","fillRectWithAlpha","ctx","color","alpha","x","y","width","height","resolveCSSUnit","value","axis","viewportWidth","viewportHeight","match","num","DEFAULT_OPTIONS","COLUMNS_COLOR_DEFAULT","ROWS_COLOR_DEFAULT","RulersOverlay","callbacks","options","host","viewportLayer","RULER_MODES","SnapEngine","screenRoot","worldRoot","lines","scrollX","scrollY","contentWidth","contentHeight","metricsChanged","rx","ry","visible","mode","el","line","entry","side","canvas","div","worldWidth","worldHeight","grids","c","grid","vw","vh","count","marginLeft","marginRight","gap","usableWidth","colWidth","i","period","length","thickness","offset","tickStep","labelInterval","isTop","compact","showTickLabels","halfThickness","longTick","shortTick","startDoc","startScreen","screenPos","docPos","displayValue","showLabel","tickLen","tickStart","cl","marginPx","gapPx","layout","columns","left","right","center","candidates","n","rl","sizePx","endDoc","docY","topScreen","bottomScreen","bgTop","bgBottom","centerScreen","rangeStart","rangeEnd","firstRow","fixedLines","expectedKeys","fl","key","id","l","labelEl","e","vSize","scroll","displayPos","positionLabel","nextLabel","referenceLineIds","lineId","refIds","start","end","centerY","centerX","type","result","rawPos","pos","cls","sKey","dsKey","snapResult","edge","m","colIndex","rect","releaseInteractionLock","ghost","ghostLabel","onMove","ev","rawDocPos","cleanup","startPointerDrag","finalPos","binding","startPointer","startDocPosition","delta","rulerThickness","chromeWidth","chromeHeight","getStringDevViewportPolicy","clientPos","viewportPos","release","lockPageInteraction","trackedRelease","KEY_PREFIX","StringDevPersistedState","options","current","legacyKey","scopedLegacyKey","scopeStringDevStorageKey","migrated","value","key","raw","parsed","validated","GLOBAL_ELEMENT_ID","DEFAULT_TRIGGERS","StringDevRulers","StringDevModule","context","RulersManager","StringDevPersistedState","raw","RULER_MODES","triggers","data","lines","active","t","handler","e","eventName","el","fn","h","event","name","action","value","overlaySlotRegistry","elementId","s","snapStep","snapToElements","snapThreshold","snapSelector","layoutGrids","rulersColumns","rulersMargin","rulersGap","columnLayout","rulersRowSize","rulersRowGap","rowLayout","RulersOverlay","axis","position","targetLabel","targetSelector","targetEdge","lineId","line","nextIdx","MODE_ORDER","modeId","lineColor","lineOpacityRaw","lineOpacity","container","horizontal","scrollX","scrollY","RULERS_CSS","RULERS_LEFT_PANEL_WIDTH","RULERS_TOP_PANEL_HEIGHT","BADGE_RULER_OFFSET_X","BADGE_RULER_OFFSET_Y","RULERS_HIDDEN_ATTRIBUTE","RULERS_LEFT_SELECTOR","RULERS_TOP_SELECTOR","VIEWPORT_ANCHOR_MAP","resolveOverlayAnchor","raw","StringDevOverlayModule","StringDevModule","context","STRING_DEVTOOLS_OVERLAY_LAYOUT_CHANGE_EVENT","object","entry","enabled","active","_enabled","id","ids","measured","entryId","e","bMetrics","measurement","styleTxn","root","layer","overlaySlotRegistry","element","depth","current","init","badge","state","existingLabel","labelEl","key","value","elementId","className","classSelector","name","stringId","anchor","metrics","_object","_anchor","_metrics","contentX","contentY","scrollLeft","scrollTop","x","y","geometry","width","height","viewportHeight","viewportWidth","viewportLeft","viewportTop","isOffscreen","baseAnchorX","baseAnchorY","collisionOffset","effectiveAnchorCache","resolveEffectiveAnchor","targetObject","cached","targetElement","targetGeometry","targetContentX","targetContentY","targetWidth","targetHeight","targetAnchor","targetAdjustment","targetRulerOffset","targetBaseX","targetBaseY","targetCollisionOffset","ancestorId","ancestorObject","effective","resolvedAnchor","axis","start","size","liveRect","liveMetrics","measuredSize","layoutHeight","rect","host","scroller","hostRect","BADGE_SLOT_STEP","StringDevBadgeOverlayModule","StringDevOverlayModule","object","targetId","depth","cleanup","entry","descriptors","world","descriptor","badge","managedBadge","onClick","event","groupEl","makeBadge","primaryBadge","subscriptions","group","metrics","measurements","slotItems","seenGroups","slot","items","groupId","i","index","item","representativeBadge","slotConfig","step","offsetX","offsetY","position","measurement","positionedGroups","pos","_enabled","_object","_badge","_targetId","_depth","_entry","_measurement","shared","anchorOffsetX","anchorOffsetY","left","right","top","bottom","INVIEW_CSS","ENTER_MARKER_SHIFT_X","MARKER_VIEWPORT_EDGE_GAP","MARKER_VIEWPORT_OVERFLOW_GUARD","MARKER_FALLBACK_WIDTH","MARKER_FALLBACK_HEIGHT","MARKER_CONNECTOR_WIDTH","fixedTranslate","x","y","clampPercent","value","clamp","min","max","EMPTY_GEOMETRY","StringDevInview","StringDevBadgeOverlayModule","StringDevPersistedState","raw","v","out","targetId","next","_object","_targetId","_depth","object","_badge","savedEnabled","outline","enterConnector","exitConnector","enterMarker","enterMarkerLabel","exitMarker","exitMarkerLabel","world","extra","entry","onInviewChange","enterCleanup","exitCleanup","metrics","badges","entryEnabled","stickyGeometry","geometryVisible","contentX","contentY","width","height","scrollTop","viewportHeight","startViewport","endViewport","startElement","endElement","inviewStartPosition","inviewEndPosition","topAnchor","bottomAnchor","startVpOffset","resolveOverlayAnchor","endVpOffset","enterTrigger","exitTrigger","enterMarkerSize","exitMarkerSize","enterMarkerWidth","enterMarkerHeight","exitMarkerWidth","exitMarkerHeight","enterMarkerOverride","exitMarkerOverride","enterAnchorXPercent","exitAnchorXPercent","enterAnchorDocX","exitAnchorDocX","enterConnectorDocX","enterConnectorDocY","enterConnectorWidth","enterConnectorHeight","exitConnectorDocX","exitConnectorDocY","exitConnectorWidth","exitConnectorHeight","enterMarkerDocX","exitMarkerDocX","documentBottom","enterMarkerPastTop","exitMarkerPastTop","enterMarkerPastBottom","exitMarkerPastBottom","enterMarkerFlippedY","exitMarkerFlippedY","enterMarkerDocY","exitMarkerDocY","enterInView","exitInView","markersVisible","measurement","outlineVisible","m","styleTxn","part","inviewAttr","_event","badge","isActive","resolveDevtoolsIcon","state","hiddenBadges","id","isInView","isBlocked","objectId","enabled","changed","kind","dragHandles","onPointerDown","event","element","elementRect","markerWidth","currentOffset","currentXPercent","anchorClientX","pointerOffsetX","badgeWorld","activeBadges","el","startPointerDrag","moveEvent","liveElementRect","nextAnchorClientX","nextXPercent","handle","offset","existing","viewportLabel","marker","labelNode","label","title","rect","size","liveMetrics","viewportWidth","elementDocLeft","elementWidth","percent","desiredAnchorDocX","scrollLeft","edgeInset","viewportMinX","viewportMaxX","connectorHalfWidth","minAnchorDocX","maxAnchorDocX","allowedMin","allowedMax","anchorDocX","minAnchorClientX","maxAnchorClientX","clampedAnchorClientX","policy","getStringDevViewportPolicy","compactValue","pointerValue","name","INVIEW_CSS","bindOutsideClick","panel","onOutside","options","handler","event","target","ignored","PROGRESS_CSS","clampProgress","raw","epsilon","formatPercent","value","percent","StringDevProgress","StringDevOverlayModule","context","object","targetLabel","hud","makeBadge","badge","resolveDevtoolsIcon","onBadgeClick","event","entry","metrics","targetId","currentScroll","key","startPosition","differencePosition","endPosition","rawProgress","progress","measurement","styleTxn","enabled","bindOutsideClick","huds","direction","duration","lastTime","tick","time","delta","isPlaying","isForward","isBackward","overrideRawProgress","STRING_DEV_PROGRESS_OVERRIDE_KEY","easing","liveRawProgress","normalizedRawProgress","eventName","mirror","mirrorProgress","panel","activeEntry","sliderValue","displayValue","PROGRESS_CSS","isStringDevtoolProvider","value","isTouchDevice","_StringTune","StringFPS","Debounce","DefaultToolsContainer","StringData","EventManager","ModuleManager","ObjectManager","CenterCache","HoverTracker","DevtoolsManager","CursorController","ScrollManager","time","value","normalized","container","speed","mode","visible","enabled","type","objectClass","settings","selector","node","effectiveSettings","module","isStringDevtoolProvider","StringDevModule","token","requestId","response","allowed","pending","data","name","factory","controller","ScrollController","Constructor","eventName","callback","id","rule","fps","StringInview","htmlFontSize","fontSizeNumber","element","connectTargetId","setStringDevStorageScopeToken","event","mutationsList","i","mutation","force","shouldForce","e","frameDOM","styleTxn","html","isMobileBucket","elapsed","scroll","width","height","newScrollHeight","newContainerTopPosition","rect","transformScale","isTouch","isTouchDevice","isDesktop","widthChanged","heightChanged","heightDiff","scrollHeightChanged","shouldRebuild","elementScrollTop","resolved","position","immediate","offset","target","host","scroller","hostRect","StringTune"]}