Full Code of wisp-forest/owo-lib for AI

braid-ui 1fb7971326ba cached
813 files
2.5 MB
701.0k tokens
5999 symbols
1 requests
Download .txt
Showing preview only (2,810K chars total). Download the full file or copy to clipboard to get everything.
Repository: wisp-forest/owo-lib
Branch: braid-ui
Commit: 1fb7971326ba
Files: 813
Total size: 2.5 MB

Directory structure:
gitextract_0mpxqol_/

├── .github/
│   └── workflows/
│       └── build.yml
├── .gitignore
├── LICENSE
├── README.md
├── braid-reload-agent/
│   ├── .gitattributes
│   ├── .gitignore
│   ├── build.gradle.kts
│   ├── gradle/
│   │   ├── libs.versions.toml
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradlew
│   ├── gradlew.bat
│   ├── settings.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── io/
│                   └── wispforest/
│                       └── BraidReloadAgent.java
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── jitpack.yml
├── owo-sentinel/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── java/
│           │   └── io/
│           │       └── wispforest/
│           │           └── owosentinel/
│           │               ├── DownloadTask.java
│           │               ├── Maldenhagen.java
│           │               ├── OwoSentinel.java
│           │               ├── SentinelConsole.java
│           │               └── SentinelWindow.java
│           └── resources/
│               └── fabric.mod.json
├── owo-ui.xsd
├── settings.gradle
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── io/
│   │   │       └── wispforest/
│   │   │           └── owo/
│   │   │               ├── Owo.java
│   │   │               ├── blockentity/
│   │   │               │   ├── LinearProcess.java
│   │   │               │   └── LinearProcessExecutor.java
│   │   │               ├── braid/
│   │   │               │   ├── animation/
│   │   │               │   │   ├── AlignmentLerp.java
│   │   │               │   │   ├── Animation.java
│   │   │               │   │   ├── AutomaticallyAnimatedWidget.java
│   │   │               │   │   ├── ColorLerp.java
│   │   │               │   │   ├── DoubleLerp.java
│   │   │               │   │   ├── Easing.java
│   │   │               │   │   ├── InsetsLerp.java
│   │   │               │   │   ├── Lerp.java
│   │   │               │   │   └── NullableLerp.java
│   │   │               │   ├── core/
│   │   │               │   │   ├── Aabb2d.java
│   │   │               │   │   ├── Alignment.java
│   │   │               │   │   ├── AppState.java
│   │   │               │   │   ├── BraidGraphics.java
│   │   │               │   │   ├── BraidHotReloadCallback.java
│   │   │               │   │   ├── BraidRenderPipelines.java
│   │   │               │   │   ├── BraidScreen.java
│   │   │               │   │   ├── BraidUtils.java
│   │   │               │   │   ├── BraidWindow.java
│   │   │               │   │   ├── BraidWindowScheduler.java
│   │   │               │   │   ├── Color.java
│   │   │               │   │   ├── CompoundListenable.java
│   │   │               │   │   ├── Constraints.java
│   │   │               │   │   ├── EventBinding.java
│   │   │               │   │   ├── Insets.java
│   │   │               │   │   ├── KeyModifiers.java
│   │   │               │   │   ├── LayoutAxis.java
│   │   │               │   │   ├── Listenable.java
│   │   │               │   │   ├── ListenableValue.java
│   │   │               │   │   ├── RelativePosition.java
│   │   │               │   │   ├── Size.java
│   │   │               │   │   ├── Surface.java
│   │   │               │   │   ├── TextLayout.java
│   │   │               │   │   ├── TextureSurface.java
│   │   │               │   │   ├── cursor/
│   │   │               │   │   │   ├── CursorController.java
│   │   │               │   │   │   ├── CursorStyle.java
│   │   │               │   │   │   └── SystemCursorStyle.java
│   │   │               │   │   ├── element/
│   │   │               │   │   │   ├── BraidBlockElement.java
│   │   │               │   │   │   ├── BraidDashedLineElement.java
│   │   │               │   │   │   ├── BraidEntityElement.java
│   │   │               │   │   │   └── BraidItemElement.java
│   │   │               │   │   └── events/
│   │   │               │   │       ├── CharInputEvent.java
│   │   │               │   │       ├── CloseEvent.java
│   │   │               │   │       ├── FilesDroppedEvent.java
│   │   │               │   │       ├── KeyPressEvent.java
│   │   │               │   │       ├── KeyReleaseEvent.java
│   │   │               │   │       ├── MouseButtonPressEvent.java
│   │   │               │   │       ├── MouseButtonReleaseEvent.java
│   │   │               │   │       ├── MouseMoveEvent.java
│   │   │               │   │       ├── MouseScrollEvent.java
│   │   │               │   │       └── UserEvent.java
│   │   │               │   ├── display/
│   │   │               │   │   ├── BraidDisplay.java
│   │   │               │   │   ├── BraidDisplayBinding.java
│   │   │               │   │   └── DisplayQuad.java
│   │   │               │   ├── framework/
│   │   │               │   │   ├── BuildContext.java
│   │   │               │   │   ├── instance/
│   │   │               │   │   │   ├── CustomWidgetTransform.java
│   │   │               │   │   │   ├── Hit.java
│   │   │               │   │   │   ├── HitTestState.java
│   │   │               │   │   │   ├── InspectorProperty.java
│   │   │               │   │   │   ├── InstanceHost.java
│   │   │               │   │   │   ├── LeafWidgetInstance.java
│   │   │               │   │   │   ├── MouseListener.java
│   │   │               │   │   │   ├── MultiChildWidgetInstance.java
│   │   │               │   │   │   ├── OptionalChildWidgetInstance.java
│   │   │               │   │   │   ├── SingleChildWidgetInstance.java
│   │   │               │   │   │   ├── TooltipProvider.java
│   │   │               │   │   │   ├── WidgetInstance.java
│   │   │               │   │   │   └── WidgetTransform.java
│   │   │               │   │   ├── proxy/
│   │   │               │   │   │   ├── BuildScope.java
│   │   │               │   │   │   ├── ComposedProxy.java
│   │   │               │   │   │   ├── InheritedProxy.java
│   │   │               │   │   │   ├── InstanceWidgetProxy.java
│   │   │               │   │   │   ├── LeafInstanceWidgetProxy.java
│   │   │               │   │   │   ├── MultiChildInstanceWidgetProxy.java
│   │   │               │   │   │   ├── OptionalChildInstanceWidgetProxy.java
│   │   │               │   │   │   ├── ProxyHost.java
│   │   │               │   │   │   ├── SingleChildInstanceWidgetProxy.java
│   │   │               │   │   │   ├── StatefulProxy.java
│   │   │               │   │   │   ├── StatelessProxy.java
│   │   │               │   │   │   ├── WidgetProxy.java
│   │   │               │   │   │   └── WidgetState.java
│   │   │               │   │   └── widget/
│   │   │               │   │       ├── InheritedWidget.java
│   │   │               │   │       ├── InstanceWidget.java
│   │   │               │   │       ├── Key.java
│   │   │               │   │       ├── LeafInstanceWidget.java
│   │   │               │   │       ├── MultiChildInstanceWidget.java
│   │   │               │   │       ├── OptionalChildInstanceWidget.java
│   │   │               │   │       ├── SingleChildInstanceWidget.java
│   │   │               │   │       ├── StatefulWidget.java
│   │   │               │   │       ├── StatelessWidget.java
│   │   │               │   │       ├── Widget.java
│   │   │               │   │       └── WidgetSetupCallback.java
│   │   │               │   ├── util/
│   │   │               │   │   ├── BraidGuiRenderer.java
│   │   │               │   │   ├── BraidHudElement.java
│   │   │               │   │   ├── BraidToast.java
│   │   │               │   │   ├── BraidTooltipComponent.java
│   │   │               │   │   ├── EmbedderRoot.java
│   │   │               │   │   ├── kdl/
│   │   │               │   │   │   ├── BraidKdlEndecs.java
│   │   │               │   │   │   ├── KdlDeserializer.java
│   │   │               │   │   │   ├── KdlElement.java
│   │   │               │   │   │   ├── KdlEntityWidget.java
│   │   │               │   │   │   ├── KdlMapper.java
│   │   │               │   │   │   └── WidgetEndec.java
│   │   │               │   │   └── layers/
│   │   │               │   │       ├── AnchorJustification.java
│   │   │               │   │       ├── BraidLayersBinding.java
│   │   │               │   │       ├── Justify.java
│   │   │               │   │       ├── LayerAlignment.java
│   │   │               │   │       └── LayerContext.java
│   │   │               │   └── widgets/
│   │   │               │       ├── BraidApp.java
│   │   │               │       ├── BraidLogo.java
│   │   │               │       ├── Dialog.java
│   │   │               │       ├── HoverStyledLabel.java
│   │   │               │       ├── Marquee.java
│   │   │               │       ├── Navigator.java
│   │   │               │       ├── SpriteWidget.java
│   │   │               │       ├── animated/
│   │   │               │       │   ├── AnimatedAlign.java
│   │   │               │       │   ├── AnimatedBox.java
│   │   │               │       │   ├── AnimatedPadding.java
│   │   │               │       │   └── AnimatedSized.java
│   │   │               │       ├── basic/
│   │   │               │       │   ├── Align.java
│   │   │               │       │   ├── AspectRatio.java
│   │   │               │       │   ├── Blur.java
│   │   │               │       │   ├── Box.java
│   │   │               │       │   ├── Builder.java
│   │   │               │       │   ├── Center.java
│   │   │               │       │   ├── Clip.java
│   │   │               │       │   ├── Constrain.java
│   │   │               │       │   ├── ConstraintWidget.java
│   │   │               │       │   ├── ControlsOverride.java
│   │   │               │       │   ├── CustomDraw.java
│   │   │               │       │   ├── EmptyWidget.java
│   │   │               │       │   ├── HitTestTrap.java
│   │   │               │       │   ├── HoverableBuilder.java
│   │   │               │       │   ├── IntrinsicHeight.java
│   │   │               │       │   ├── IntrinsicWidth.java
│   │   │               │       │   ├── LayoutBuilder.java
│   │   │               │       │   ├── ListenableBuilder.java
│   │   │               │       │   ├── MouseArea.java
│   │   │               │       │   ├── Padding.java
│   │   │               │       │   ├── Panel.java
│   │   │               │       │   ├── RotatedLayout.java
│   │   │               │       │   ├── Sized.java
│   │   │               │       │   ├── TextureWidget.java
│   │   │               │       │   ├── Tooltip.java
│   │   │               │       │   ├── Transform.java
│   │   │               │       │   ├── Visibility.java
│   │   │               │       │   └── VisitorWidget.java
│   │   │               │       ├── button/
│   │   │               │       │   ├── Button.java
│   │   │               │       │   ├── ButtonPanel.java
│   │   │               │       │   ├── ButtonStyle.java
│   │   │               │       │   ├── Clickable.java
│   │   │               │       │   ├── DefaultButtonStyle.java
│   │   │               │       │   └── MessageButton.java
│   │   │               │       ├── checkbox/
│   │   │               │       │   ├── Checkbox.java
│   │   │               │       │   ├── CheckboxStyle.java
│   │   │               │       │   ├── DefaultCheckboxStyle.java
│   │   │               │       │   └── TogglingClickable.java
│   │   │               │       ├── collapsible/
│   │   │               │       │   ├── Collapsible.java
│   │   │               │       │   ├── CollapsibleCallback.java
│   │   │               │       │   └── LazyCollapsible.java
│   │   │               │       ├── combobox/
│   │   │               │       │   ├── ComboBox.java
│   │   │               │       │   ├── ComboBoxButtons.java
│   │   │               │       │   └── ComboBoxButtonsState.java
│   │   │               │       ├── cycle/
│   │   │               │       │   ├── Cycler.java
│   │   │               │       │   ├── CyclingButton.java
│   │   │               │       │   ├── CyclingClickable.java
│   │   │               │       │   └── MessageCyclingButton.java
│   │   │               │       ├── drag/
│   │   │               │       │   ├── DragArena.java
│   │   │               │       │   ├── DragArenaElement.java
│   │   │               │       │   ├── DragArenaInstance.java
│   │   │               │       │   └── DragParentData.java
│   │   │               │       ├── eventstream/
│   │   │               │       │   ├── BraidEventSource.java
│   │   │               │       │   ├── BraidEventStream.java
│   │   │               │       │   └── StreamListenerState.java
│   │   │               │       ├── flex/
│   │   │               │       │   ├── Column.java
│   │   │               │       │   ├── CrossAxisAlignment.java
│   │   │               │       │   ├── Flex.java
│   │   │               │       │   ├── FlexInstance.java
│   │   │               │       │   ├── FlexParentData.java
│   │   │               │       │   ├── Flexible.java
│   │   │               │       │   ├── MainAxisAlignment.java
│   │   │               │       │   └── Row.java
│   │   │               │       ├── focus/
│   │   │               │       │   ├── FocusClickArea.java
│   │   │               │       │   ├── FocusLevel.java
│   │   │               │       │   ├── FocusPolicy.java
│   │   │               │       │   ├── FocusScope.java
│   │   │               │       │   ├── FocusStateProvider.java
│   │   │               │       │   ├── FocusTraversalDirection.java
│   │   │               │       │   ├── Focusable.java
│   │   │               │       │   └── RootFocusScope.java
│   │   │               │       ├── grid/
│   │   │               │       │   └── Grid.java
│   │   │               │       ├── inspector/
│   │   │               │       │   ├── BraidInspector.java
│   │   │               │       │   ├── CollapsibleEntry.java
│   │   │               │       │   ├── InspectorState.java
│   │   │               │       │   ├── InspectorWidget.java
│   │   │               │       │   ├── InstanceDetails.java
│   │   │               │       │   ├── InstancePicker.java
│   │   │               │       │   ├── InstanceTitle.java
│   │   │               │       │   ├── InstanceTreeView.java
│   │   │               │       │   └── RevealInstanceEvent.java
│   │   │               │       ├── intents/
│   │   │               │       │   ├── Action.java
│   │   │               │       │   ├── Actions.java
│   │   │               │       │   ├── AdjustIntent.java
│   │   │               │       │   ├── Intent.java
│   │   │               │       │   ├── Interactable.java
│   │   │               │       │   ├── PrimaryActionIntent.java
│   │   │               │       │   ├── SecondaryActionIntent.java
│   │   │               │       │   ├── ShortcutDecoder.java
│   │   │               │       │   ├── ShortcutTrigger.java
│   │   │               │       │   ├── Shortcuts.java
│   │   │               │       │   ├── TraverseFocusAction.java
│   │   │               │       │   ├── TraverseFocusIntent.java
│   │   │               │       │   ├── Trigger.java
│   │   │               │       │   └── TriggerType.java
│   │   │               │       ├── label/
│   │   │               │       │   ├── DefaultLabelStyle.java
│   │   │               │       │   ├── Label.java
│   │   │               │       │   ├── LabelStyle.java
│   │   │               │       │   └── RawLabel.java
│   │   │               │       ├── object/
│   │   │               │       │   ├── BlockWidget.java
│   │   │               │       │   ├── EntityWidget.java
│   │   │               │       │   ├── ItemStackWidget.java
│   │   │               │       │   └── RawBlockWidget.java
│   │   │               │       ├── overlay/
│   │   │               │       │   ├── Overlay.java
│   │   │               │       │   ├── OverlayEntry.java
│   │   │               │       │   ├── OverlayEntryBuilder.java
│   │   │               │       │   ├── OverlayParentData.java
│   │   │               │       │   ├── OverlayProvider.java
│   │   │               │       │   ├── RawOverlay.java
│   │   │               │       │   └── RawOverlayElement.java
│   │   │               │       ├── owoui/
│   │   │               │       │   ├── OwoUIWidget.java
│   │   │               │       │   └── OwoUIWidgetWrapper.java
│   │   │               │       ├── recipeviewer/
│   │   │               │       │   ├── RecipeViewerExclusionZone.java
│   │   │               │       │   ├── RecipeViewerStack.java
│   │   │               │       │   └── StackDropArea.java
│   │   │               │       ├── scroll/
│   │   │               │       │   ├── ButtonScrollbar.java
│   │   │               │       │   ├── DefaultScrollAnimationSettings.java
│   │   │               │       │   ├── FlatScrollbar.java
│   │   │               │       │   ├── HorizontallyScrollable.java
│   │   │               │       │   ├── RawScrollView.java
│   │   │               │       │   ├── ScrollAnimationSettings.java
│   │   │               │       │   ├── ScrollController.java
│   │   │               │       │   ├── Scrollable.java
│   │   │               │       │   ├── ScrollableWithBars.java
│   │   │               │       │   ├── Scrollbar.java
│   │   │               │       │   └── VerticallyScrollable.java
│   │   │               │       ├── sharedstate/
│   │   │               │       │   ├── ShareableState.java
│   │   │               │       │   ├── SharedState.java
│   │   │               │       │   └── SharedStateProvider.java
│   │   │               │       ├── slider/
│   │   │               │       │   ├── DefaultSliderHandle.java
│   │   │               │       │   ├── Incrementor.java
│   │   │               │       │   ├── SliderStyle.java
│   │   │               │       │   ├── drag/
│   │   │               │       │   │   ├── Drag.java
│   │   │               │       │   │   ├── DragFunction.java
│   │   │               │       │   │   ├── MessageDrag.java
│   │   │               │       │   │   └── RawDrag.java
│   │   │               │       │   ├── range/
│   │   │               │       │   │   ├── DefaultRangeSliderStyle.java
│   │   │               │       │   │   ├── MessageRangeSlider.java
│   │   │               │       │   │   ├── RangeSlider.java
│   │   │               │       │   │   ├── RangeSliderCallback.java
│   │   │               │       │   │   └── RangeSliderStyle.java
│   │   │               │       │   ├── slider/
│   │   │               │       │   │   ├── DefaultSliderStyle.java
│   │   │               │       │   │   ├── MessageSlider.java
│   │   │               │       │   │   ├── Slider.java
│   │   │               │       │   │   ├── SliderCallback.java
│   │   │               │       │   │   └── SliderFunction.java
│   │   │               │       │   └── xlyder/
│   │   │               │       │       ├── DefaultXlyderStyle.java
│   │   │               │       │       ├── MessageXlyder.java
│   │   │               │       │       ├── Xlyder.java
│   │   │               │       │       └── XlyderCallback.java
│   │   │               │       ├── splitpane/
│   │   │               │       │   ├── MultiSplitPane.java
│   │   │               │       │   └── SplitPane.java
│   │   │               │       ├── stack/
│   │   │               │       │   ├── Stack.java
│   │   │               │       │   ├── StackBase.java
│   │   │               │       │   └── StackParentData.java
│   │   │               │       ├── textinput/
│   │   │               │       │   ├── CopyTextIntent.java
│   │   │               │       │   ├── DeleteLineIntent.java
│   │   │               │       │   ├── DeleteTextIntent.java
│   │   │               │       │   ├── EditableText.java
│   │   │               │       │   ├── InsertNewlineIntent.java
│   │   │               │       │   ├── InsertTabIntent.java
│   │   │               │       │   ├── MaxLengthFormatter.java
│   │   │               │       │   ├── MoveCursorIntent.java
│   │   │               │       │   ├── PasteTextIntent.java
│   │   │               │       │   ├── PatternFormatter.java
│   │   │               │       │   ├── SelectAllIntent.java
│   │   │               │       │   ├── TeleportCursorIntent.java
│   │   │               │       │   ├── TextBox.java
│   │   │               │       │   ├── TextEditingController.java
│   │   │               │       │   ├── TextEditingValue.java
│   │   │               │       │   ├── TextInput.java
│   │   │               │       │   └── TextSelection.java
│   │   │               │       ├── vanilla/
│   │   │               │       │   ├── VanillaWidget.java
│   │   │               │       │   └── VanillaWidgetWrapper.java
│   │   │               │       └── window/
│   │   │               │           ├── Window.java
│   │   │               │           └── WindowController.java
│   │   │               ├── client/
│   │   │               │   ├── OwoClient.java
│   │   │               │   ├── screens/
│   │   │               │   │   ├── MenuNetworkingInternals.java
│   │   │               │   │   ├── MenuUtils.java
│   │   │               │   │   ├── OwoAbstractContainerMenu.java
│   │   │               │   │   ├── ScreenhandlerMessageData.java
│   │   │               │   │   ├── SlotGenerator.java
│   │   │               │   │   ├── SyncedProperty.java
│   │   │               │   │   └── ValidatingSlot.java
│   │   │               │   └── texture/
│   │   │               │       ├── AnimatedTextureDrawable.java
│   │   │               │       └── SpriteSheetMetadata.java
│   │   │               ├── command/
│   │   │               │   ├── EnumArgumentType.java
│   │   │               │   └── debug/
│   │   │               │       ├── CcaDataCommand.java
│   │   │               │       ├── DumpdataCommand.java
│   │   │               │       ├── HealCommand.java
│   │   │               │       ├── MakeLootContainerCommand.java
│   │   │               │       └── OwoDebugCommands.java
│   │   │               ├── compat/
│   │   │               │   ├── emi/
│   │   │               │   │   ├── EmiStackUtil.java
│   │   │               │   │   └── OwoEmiPlugin.java
│   │   │               │   ├── modmenu/
│   │   │               │   │   └── OwoModMenuPlugin.java
│   │   │               │   └── rei/
│   │   │               │       ├── OwoReiPlugin.java
│   │   │               │       ├── ReiStackUtil.java
│   │   │               │       ├── ReiUIAdapter.java
│   │   │               │       └── ReiWidgetComponent.java
│   │   │               ├── config/
│   │   │               │   ├── ConfigAP.java
│   │   │               │   ├── ConfigSynchronizer.java
│   │   │               │   ├── ConfigWrapper.java
│   │   │               │   ├── Option.java
│   │   │               │   ├── OwoConfigCommand.java
│   │   │               │   ├── annotation/
│   │   │               │   │   ├── Config.java
│   │   │               │   │   ├── ExcludeFromScreen.java
│   │   │               │   │   ├── Expanded.java
│   │   │               │   │   ├── Hook.java
│   │   │               │   │   ├── Modmenu.java
│   │   │               │   │   ├── Nest.java
│   │   │               │   │   ├── PredicateConstraint.java
│   │   │               │   │   ├── RangeConstraint.java
│   │   │               │   │   ├── RegexConstraint.java
│   │   │               │   │   ├── RestartRequired.java
│   │   │               │   │   ├── SectionHeader.java
│   │   │               │   │   ├── Sync.java
│   │   │               │   │   └── WithAlpha.java
│   │   │               │   └── ui/
│   │   │               │       ├── ConfigScreen.java
│   │   │               │       ├── ConfigScreenProviders.java
│   │   │               │       ├── OptionComponentFactory.java
│   │   │               │       ├── OptionComponents.java
│   │   │               │       ├── RestartRequiredScreen.java
│   │   │               │       └── component/
│   │   │               │           ├── ConfigEnumButton.java
│   │   │               │           ├── ConfigSlider.java
│   │   │               │           ├── ConfigTextBox.java
│   │   │               │           ├── ConfigToggleButton.java
│   │   │               │           ├── ListOptionContainer.java
│   │   │               │           ├── OptionValueProvider.java
│   │   │               │           └── SearchAnchorComponent.java
│   │   │               ├── ext/
│   │   │               │   ├── DerivedComponentMap.java
│   │   │               │   └── OwoItem.java
│   │   │               ├── itemgroup/
│   │   │               │   ├── Icon.java
│   │   │               │   ├── ItemGroupReference.java
│   │   │               │   ├── OwoItemGroup.java
│   │   │               │   ├── OwoItemSettingsExtension.java
│   │   │               │   ├── gui/
│   │   │               │   │   ├── ItemGroupButton.java
│   │   │               │   │   ├── ItemGroupButtonWidget.java
│   │   │               │   │   └── ItemGroupTab.java
│   │   │               │   └── json/
│   │   │               │       ├── OwoItemGroupLoader.java
│   │   │               │       └── WrapperGroup.java
│   │   │               ├── mixin/
│   │   │               │   ├── AbstractContainerMenuInvoker.java
│   │   │               │   ├── AbstractContainerMenuMixin.java
│   │   │               │   ├── ClientCommonPacketListenerImplAccessor.java
│   │   │               │   ├── ClientConfigurationPacketListenerImplMixin.java
│   │   │               │   ├── ClientHandshakePacketListenerImplAccessor.java
│   │   │               │   ├── ConnectionMixin.java
│   │   │               │   ├── Copenhagen.java
│   │   │               │   ├── GuiGraphicsMixin.java
│   │   │               │   ├── MainMixin.java
│   │   │               │   ├── MinecraftMixin.java
│   │   │               │   ├── ServerCommonPacketListenerImplAccessor.java
│   │   │               │   ├── ServerPlayerGameModeMixin.java
│   │   │               │   ├── ServerPlayerMixin.java
│   │   │               │   ├── SetComponentsFunctionAccessor.java
│   │   │               │   ├── TagLoaderMixin.java
│   │   │               │   ├── braid/
│   │   │               │   │   ├── ClickableStyleFinderAccessor.java
│   │   │               │   │   ├── GameRendererAccessor.java
│   │   │               │   │   ├── GuiRendererAccessor.java
│   │   │               │   │   ├── GuiRendererMixin.java
│   │   │               │   │   ├── KeyboardHandlerMixin.java
│   │   │               │   │   ├── LevelRendererMixin.java
│   │   │               │   │   ├── Matrix3x2fStackAccessor.java
│   │   │               │   │   ├── RenderTypeInvoker.java
│   │   │               │   │   ├── ScreenMixin.java
│   │   │               │   │   └── ToastManagerMixin.java
│   │   │               │   ├── ext/
│   │   │               │   │   ├── ItemMixin.java
│   │   │               │   │   ├── ItemStackMixin.java
│   │   │               │   │   ├── PatchedDataComponentMapAccessor.java
│   │   │               │   │   └── PatchedDataComponentMapMixin.java
│   │   │               │   ├── extension/
│   │   │               │   │   ├── SimpleJsonResourceReloadListenerMixin.java
│   │   │               │   │   ├── json5/
│   │   │               │   │   │   ├── FallbackResourceManagerMixin.java
│   │   │               │   │   │   ├── FileToIdConverterMixin.java
│   │   │               │   │   │   ├── LanguageReaderMixin.java
│   │   │               │   │   │   └── MultiPackResourceManagerMixin.java
│   │   │               │   │   └── recipe/
│   │   │               │   │       ├── RecipeManagerAccessor.java
│   │   │               │   │       └── ResultSlotMixin.java
│   │   │               │   ├── itemgroup/
│   │   │               │   │   ├── CreativeModeInventoryScreenAccessor.java
│   │   │               │   │   ├── CreativeModeInventoryScreenMixin.java
│   │   │               │   │   ├── CreativeModeTabAccessor.java
│   │   │               │   │   ├── EffectsInInventoryMixin.java
│   │   │               │   │   ├── ItemMixin.java
│   │   │               │   │   ├── ItemSettingsMixin.java
│   │   │               │   │   ├── MinecraftMixin.java
│   │   │               │   │   └── MixinCreativeModeInventoryScreenMixin.java
│   │   │               │   ├── registry/
│   │   │               │   │   ├── MappedRegistryMixin.java
│   │   │               │   │   └── ReferenceAccessor.java
│   │   │               │   ├── serialization/
│   │   │               │   │   ├── CachedRegistryInfoGetterAccessor.java
│   │   │               │   │   ├── CompoundTagMixin.java
│   │   │               │   │   ├── DataComponentTypeBuilderMixin.java
│   │   │               │   │   ├── DataResultMixin.java
│   │   │               │   │   ├── DelegatingOpsAccessor.java
│   │   │               │   │   ├── FriendlyByteBufMixin.java
│   │   │               │   │   ├── RegistryOpsAccessor.java
│   │   │               │   │   ├── TagValueInputMixin.java
│   │   │               │   │   ├── TagValueOutputMixin.java
│   │   │               │   │   ├── ValueInputMixin.java
│   │   │               │   │   └── ValueOutputMixin.java
│   │   │               │   ├── shader/
│   │   │               │   │   └── GlProgramAccessor.java
│   │   │               │   ├── text/
│   │   │               │   │   ├── ClientLanguageMixin.java
│   │   │               │   │   ├── ComponentSerializationMixin.java
│   │   │               │   │   ├── LanguageMixin.java
│   │   │               │   │   ├── TranslatableContentsAccessor.java
│   │   │               │   │   ├── TranslatableContentsMixin.java
│   │   │               │   │   └── stapi/
│   │   │               │   │       └── SystemDelegatedLanguageFixin.java
│   │   │               │   ├── tweaks/
│   │   │               │   │   ├── EditBoxMixin.java
│   │   │               │   │   ├── EulaMixin.java
│   │   │               │   │   ├── LevelSettingsMixin.java
│   │   │               │   │   └── OperatingSystemMixin.java
│   │   │               │   └── ui/
│   │   │               │       ├── AbstractContainerScreenMixin.java
│   │   │               │       ├── AbstractSliderButtonMixin.java
│   │   │               │       ├── AbstractWidgetMixin.java
│   │   │               │       ├── ChatScreenMixin.java
│   │   │               │       ├── CubeMapMixin.java
│   │   │               │       ├── EditBoxMixin.java
│   │   │               │       ├── GuiRendererMixin.java
│   │   │               │       ├── MinecraftMixin.java
│   │   │               │       ├── MultiLineEditBoxMixin.java
│   │   │               │       ├── ScreenMixin.java
│   │   │               │       ├── SlotAccessor.java
│   │   │               │       ├── SlotMixin.java
│   │   │               │       ├── access/
│   │   │               │       │   ├── AbstractWidgetAccessor.java
│   │   │               │       │   ├── BaseOwoHandledScreenAccessor.java
│   │   │               │       │   ├── BlockEntityAccessor.java
│   │   │               │       │   ├── ButtonAccessor.java
│   │   │               │       │   ├── CheckboxAccessor.java
│   │   │               │       │   ├── EditBoxAccessor.java
│   │   │               │       │   ├── EntityRendererAccessor.java
│   │   │               │       │   ├── GlCommandEncoderAccessor.java
│   │   │               │       │   ├── GuiGraphicsAccessor.java
│   │   │               │       │   ├── MultiLineEditBoxAccessor.java
│   │   │               │       │   ├── MultilineTextFieldAccessor.java
│   │   │               │       │   ├── RenderSystemAccessor.java
│   │   │               │       │   └── TextBoxComponentAccessor.java
│   │   │               │       ├── display/
│   │   │               │       │   ├── GameRendererMixin.java
│   │   │               │       │   ├── GuiMixin.java
│   │   │               │       │   ├── MinecraftMixin.java
│   │   │               │       │   └── MouseHandlerMixin.java
│   │   │               │       └── layers/
│   │   │               │           ├── AbstractContainerScreenAccessor.java
│   │   │               │           ├── KeyboardHandlerMixin.java
│   │   │               │           ├── MouseHandlerMixin.java
│   │   │               │           └── ScreenMixin.java
│   │   │               ├── moddata/
│   │   │               │   ├── ModDataConsumer.java
│   │   │               │   └── ModDataLoader.java
│   │   │               ├── network/
│   │   │               │   ├── ClientAccess.java
│   │   │               │   ├── NetworkException.java
│   │   │               │   ├── OwoClientConnectionExtension.java
│   │   │               │   ├── OwoHandshake.java
│   │   │               │   ├── OwoNetChannel.java
│   │   │               │   ├── QueuedChannelSet.java
│   │   │               │   └── ServerAccess.java
│   │   │               ├── ops/
│   │   │               │   ├── ItemOps.java
│   │   │               │   ├── LevelOps.java
│   │   │               │   ├── LootOps.java
│   │   │               │   └── TextOps.java
│   │   │               ├── particles/
│   │   │               │   ├── ClientParticles.java
│   │   │               │   └── systems/
│   │   │               │       ├── ParticleSystem.java
│   │   │               │       ├── ParticleSystemController.java
│   │   │               │       └── ParticleSystemExecutor.java
│   │   │               ├── registration/
│   │   │               │   ├── ComplexRegistryAction.java
│   │   │               │   ├── RegistryHelper.java
│   │   │               │   ├── annotations/
│   │   │               │   │   ├── AssignedName.java
│   │   │               │   │   ├── IterationIgnored.java
│   │   │               │   │   └── RegistryNamespace.java
│   │   │               │   └── reflect/
│   │   │               │       ├── AutoRegistryContainer.java
│   │   │               │       ├── BlockEntityRegistryContainer.java
│   │   │               │       ├── FieldProcessingSubject.java
│   │   │               │       ├── FieldRegistrationHandler.java
│   │   │               │       └── SimpleFieldProcessingSubject.java
│   │   │               ├── renderdoc/
│   │   │               │   ├── RenderDoc.java
│   │   │               │   ├── RenderdocLibrary.java
│   │   │               │   └── RenderdocScreen.java
│   │   │               ├── serialization/
│   │   │               │   ├── CodecUtils.java
│   │   │               │   ├── EndecRecipeSerializer.java
│   │   │               │   ├── OwoDataComponentTypeBuilder.java
│   │   │               │   ├── RegistriesAttribute.java
│   │   │               │   ├── endec/
│   │   │               │   │   ├── EitherEndec.java
│   │   │               │   │   ├── KeyedEndecDecodeError.java
│   │   │               │   │   ├── KeyedEndecEncodeError.java
│   │   │               │   │   ├── MinecraftEndecs.java
│   │   │               │   │   ├── NonNullListEndec.java
│   │   │               │   │   └── StructEitherEndec.java
│   │   │               │   └── format/
│   │   │               │       ├── ContextHolder.java
│   │   │               │       ├── DynamicOpsWithContext.java
│   │   │               │       ├── edm/
│   │   │               │       │   └── EdmOps.java
│   │   │               │       └── nbt/
│   │   │               │           ├── NbtDeserializer.java
│   │   │               │           ├── NbtEndec.java
│   │   │               │           └── NbtSerializer.java
│   │   │               ├── text/
│   │   │               │   ├── CursedTranslatableContents.java
│   │   │               │   ├── CustomTextRegistry.java
│   │   │               │   ├── InsertingTextContent.java
│   │   │               │   ├── LanguageAccess.java
│   │   │               │   ├── NestedLangHandler.java
│   │   │               │   ├── TextLanguage.java
│   │   │               │   └── TranslationContext.java
│   │   │               ├── ui/
│   │   │               │   ├── base/
│   │   │               │   │   ├── BaseOwoContainerScreen.java
│   │   │               │   │   ├── BaseOwoScreen.java
│   │   │               │   │   ├── BaseOwoToast.java
│   │   │               │   │   ├── BaseOwoTooltipComponent.java
│   │   │               │   │   ├── BaseParentUIComponent.java
│   │   │               │   │   ├── BaseUIComponent.java
│   │   │               │   │   ├── BaseUIModelContainerScreen.java
│   │   │               │   │   └── BaseUIModelScreen.java
│   │   │               │   ├── component/
│   │   │               │   │   ├── BlockComponent.java
│   │   │               │   │   ├── BoxComponent.java
│   │   │               │   │   ├── BraidComponent.java
│   │   │               │   │   ├── ButtonComponent.java
│   │   │               │   │   ├── CheckboxComponent.java
│   │   │               │   │   ├── ColorPickerComponent.java
│   │   │               │   │   ├── DiscreteSliderComponent.java
│   │   │               │   │   ├── DropdownComponent.java
│   │   │               │   │   ├── EntityComponent.java
│   │   │               │   │   ├── ItemComponent.java
│   │   │               │   │   ├── LabelComponent.java
│   │   │               │   │   ├── SliderComponent.java
│   │   │               │   │   ├── SlimSliderComponent.java
│   │   │               │   │   ├── SmallCheckboxComponent.java
│   │   │               │   │   ├── SpacerComponent.java
│   │   │               │   │   ├── SpriteComponent.java
│   │   │               │   │   ├── TextAreaComponent.java
│   │   │               │   │   ├── TextBoxComponent.java
│   │   │               │   │   ├── TextureComponent.java
│   │   │               │   │   ├── UIComponents.java
│   │   │               │   │   └── VanillaWidgetComponent.java
│   │   │               │   ├── container/
│   │   │               │   │   ├── CollapsibleContainer.java
│   │   │               │   │   ├── DraggableContainer.java
│   │   │               │   │   ├── FlowLayout.java
│   │   │               │   │   ├── GridLayout.java
│   │   │               │   │   ├── OverlayContainer.java
│   │   │               │   │   ├── ScrollContainer.java
│   │   │               │   │   ├── StackLayout.java
│   │   │               │   │   ├── UIContainers.java
│   │   │               │   │   └── WrappingParentUIComponent.java
│   │   │               │   ├── core/
│   │   │               │   │   ├── Animatable.java
│   │   │               │   │   ├── AnimatableProperty.java
│   │   │               │   │   ├── Animation.java
│   │   │               │   │   ├── Color.java
│   │   │               │   │   ├── CursorStyle.java
│   │   │               │   │   ├── Easing.java
│   │   │               │   │   ├── HorizontalAlignment.java
│   │   │               │   │   ├── Insets.java
│   │   │               │   │   ├── OwoUIAdapter.java
│   │   │               │   │   ├── OwoUIGraphics.java
│   │   │               │   │   ├── OwoUIPipelines.java
│   │   │               │   │   ├── ParentUIComponent.java
│   │   │               │   │   ├── PositionedRectangle.java
│   │   │               │   │   ├── Positioning.java
│   │   │               │   │   ├── Size.java
│   │   │               │   │   ├── Sizing.java
│   │   │               │   │   ├── Surface.java
│   │   │               │   │   ├── UIComponent.java
│   │   │               │   │   └── VerticalAlignment.java
│   │   │               │   ├── event/
│   │   │               │   │   ├── CharTyped.java
│   │   │               │   │   ├── ClientRenderCallback.java
│   │   │               │   │   ├── FocusGained.java
│   │   │               │   │   ├── FocusLost.java
│   │   │               │   │   ├── KeyPress.java
│   │   │               │   │   ├── MouseDown.java
│   │   │               │   │   ├── MouseDrag.java
│   │   │               │   │   ├── MouseEnter.java
│   │   │               │   │   ├── MouseLeave.java
│   │   │               │   │   ├── MouseScroll.java
│   │   │               │   │   ├── MouseUp.java
│   │   │               │   │   └── WindowResizeCallback.java
│   │   │               │   ├── hud/
│   │   │               │   │   ├── Hud.java
│   │   │               │   │   ├── HudContainer.java
│   │   │               │   │   └── HudInspectorScreen.java
│   │   │               │   ├── inject/
│   │   │               │   │   ├── GreedyInputUIComponent.java
│   │   │               │   │   └── UIComponentStub.java
│   │   │               │   ├── layers/
│   │   │               │   │   ├── Layer.java
│   │   │               │   │   └── Layers.java
│   │   │               │   ├── parsing/
│   │   │               │   │   ├── ConfigureHotReloadScreen.java
│   │   │               │   │   ├── IncompatibleUIModelException.java
│   │   │               │   │   ├── UIModel.java
│   │   │               │   │   ├── UIModelLoader.java
│   │   │               │   │   ├── UIModelParsingException.java
│   │   │               │   │   └── UIParsing.java
│   │   │               │   ├── renderstate/
│   │   │               │   │   ├── BlockElementRenderState.java
│   │   │               │   │   ├── BlurQuadElementRenderState.java
│   │   │               │   │   ├── CircleElementRenderState.java
│   │   │               │   │   ├── CubeMapElementRenderState.java
│   │   │               │   │   ├── EntityElementRenderState.java
│   │   │               │   │   ├── GradientQuadElementRenderState.java
│   │   │               │   │   ├── LineElementRenderState.java
│   │   │               │   │   ├── OwoItemElementRenderState.java
│   │   │               │   │   ├── OwoSpecialGuiElementRenderers.java
│   │   │               │   │   └── RingElementRenderState.java
│   │   │               │   └── util/
│   │   │               │       ├── CommandOpenedScreen.java
│   │   │               │       ├── CursorAdapter.java
│   │   │               │       ├── Delta.java
│   │   │               │       ├── DisposableScreen.java
│   │   │               │       ├── FocusHandler.java
│   │   │               │       ├── MatrixStackTransformer.java
│   │   │               │       ├── MountingHelper.java
│   │   │               │       ├── NinePatchTexture.java
│   │   │               │       ├── SpriteUtilInvoker.java
│   │   │               │       ├── UIErrorToast.java
│   │   │               │       └── UISounds.java
│   │   │               └── util/
│   │   │                   ├── DataExtensionUtil.java
│   │   │                   ├── EventSource.java
│   │   │                   ├── EventStream.java
│   │   │                   ├── ImplementedContainer.java
│   │   │                   ├── KawaiiUtil.java
│   │   │                   ├── Maldenhagen.java
│   │   │                   ├── NumberReflection.java
│   │   │                   ├── Observable.java
│   │   │                   ├── OwoFreezer.java
│   │   │                   ├── RecipeRemainderStorage.java
│   │   │                   ├── ReflectionUtils.java
│   │   │                   ├── Scary.java
│   │   │                   ├── ServicesFrozenException.java
│   │   │                   ├── StackTraceSupplier.java
│   │   │                   ├── TagInjector.java
│   │   │                   ├── VectorRandomUtils.java
│   │   │                   ├── VectorSerializer.java
│   │   │                   ├── ViewerStack.java
│   │   │                   ├── Wisdom.java
│   │   │                   └── pond/
│   │   │                       ├── BraidGuiRendererExtension.java
│   │   │                       ├── OwoAbstractContainerMenuExtension.java
│   │   │                       ├── OwoCreativeInventoryScreenExtensions.java
│   │   │                       ├── OwoItemExtensions.java
│   │   │                       ├── OwoScreenExtension.java
│   │   │                       ├── OwoSimpleRegistryExtensions.java
│   │   │                       ├── OwoSlotExtension.java
│   │   │                       ├── OwoTextRendererExtension.java
│   │   │                       └── package-info.java
│   │   └── resources/
│   │       ├── META-INF/
│   │       │   └── services/
│   │       │       └── javax.annotation.processing.Processor
│   │       ├── architectury.common.json
│   │       ├── assets/
│   │       │   └── owo/
│   │       │       ├── lang/
│   │       │       │   ├── en_us.json5
│   │       │       │   └── tt_ru.json5
│   │       │       ├── nine_patch_textures/
│   │       │       │   ├── braid_combobox/
│   │       │       │   │   ├── active.json
│   │       │       │   │   ├── disabled.json
│   │       │       │   │   └── hovered.json
│   │       │       │   ├── braid_debug_focused.json
│   │       │       │   ├── braid_debug_highlighted.json
│   │       │       │   ├── braid_inspector_selected.json
│   │       │       │   ├── button/
│   │       │       │   │   ├── active.json
│   │       │       │   │   ├── disabled.json
│   │       │       │   │   └── hovered.json
│   │       │       │   ├── panel/
│   │       │       │   │   ├── dark.json
│   │       │       │   │   ├── default.json
│   │       │       │   │   └── inset.json
│   │       │       │   ├── scrollbar/
│   │       │       │   │   ├── track.json
│   │       │       │   │   ├── vanilla_flat.json
│   │       │       │   │   ├── vanilla_horizontal.json
│   │       │       │   │   ├── vanilla_horizontal_disabled.json
│   │       │       │   │   ├── vanilla_vertical.json
│   │       │       │   │   └── vanilla_vertical_disabled.json
│   │       │       │   └── slim_slider_track.json
│   │       │       ├── owo_ui/
│   │       │       │   ├── config.xml
│   │       │       │   ├── configure_hot_reload.xml
│   │       │       │   └── restart_required.xml
│   │       │       ├── shaders/
│   │       │       │   └── core/
│   │       │       │       ├── blur.fsh
│   │       │       │       ├── blur.vsh
│   │       │       │       └── spectrum.fsh
│   │       │       ├── sounds/
│   │       │       │   └── ui_interaction.ogg
│   │       │       └── sounds.json
│   │       ├── fabric.mod.json
│   │       ├── owo-json5
│   │       ├── owo.accesswidener
│   │       └── owo.mixins.json
│   └── testmod/
│       ├── java/
│       │   └── io/
│       │       └── wispforest/
│       │           ├── owo/
│       │           │   └── samples/
│       │           │       └── braid/
│       │           │           ├── BraidSamplesItem.java
│       │           │           ├── LayoutWidgetExamples.java
│       │           │           ├── SharedCounter.java
│       │           │           ├── SimpleCounter.java
│       │           │           └── layout/
│       │           │               ├── BottomRightLogo.java
│       │           │               ├── Checkerboard.java
│       │           │               ├── LargeLogo.java
│       │           │               ├── LavaLogo.java
│       │           │               ├── NormalRow.java
│       │           │               ├── PaddedColumn.java
│       │           │               ├── PaddedLogo.java
│       │           │               ├── RGBStack.java
│       │           │               ├── SizeFactorLogo.java
│       │           │               ├── SquishedLogo.java
│       │           │               └── VerticalFlex.java
│       │           └── uwu/
│       │               ├── EpicMenu.java
│       │               ├── FabledBananasClass.java
│       │               ├── Uwu.java
│       │               ├── block/
│       │               │   ├── BraidDisplayBlock.java
│       │               │   └── BraidDisplayBlockEntity.java
│       │               ├── blockentity/
│       │               │   └── ProcessBlockEntity.java
│       │               ├── client/
│       │               │   ├── Bikeshed.java
│       │               │   ├── BraidDisplayBlockEntityRenderer.java
│       │               │   ├── ComponentTestScreen.java
│       │               │   ├── EpicContainerModelScreen.java
│       │               │   ├── EpicContainerScreen.java
│       │               │   ├── HudTestWidget.java
│       │               │   ├── LayersTestWidget.java
│       │               │   ├── ParseFailScreen.java
│       │               │   ├── ScissorTestScreen.java
│       │               │   ├── SelectUwuScreenScreen.java
│       │               │   ├── SizingTestScreen.java
│       │               │   ├── SmolComponentTestScreen.java
│       │               │   ├── TestConfigScreen.java
│       │               │   ├── TestParseScreen.java
│       │               │   ├── TooManyComponentsScreen.java
│       │               │   ├── UwuClient.java
│       │               │   ├── UwuConfigScreen.java
│       │               │   └── braid/
│       │               │       ├── SliderTests.java
│       │               │       └── TestSelector.java
│       │               ├── config/
│       │               │   ├── UowouConfigModel.java
│       │               │   └── UwuConfigModel.java
│       │               ├── items/
│       │               │   ├── UwuBraidItem.java
│       │               │   ├── UwuCounterItem.java
│       │               │   ├── UwuItems.java
│       │               │   ├── UwuScreenShardItem.java
│       │               │   └── UwuTestStickItem.java
│       │               ├── mixin/
│       │               │   ├── GlRenderPassMixin.java
│       │               │   └── TitleScreenMixin.java
│       │               ├── network/
│       │               │   ├── DispatchedInterface.java
│       │               │   ├── DispatchedSubclassOne.java
│       │               │   ├── DispatchedSubclassTwo.java
│       │               │   ├── KeycodePacket.java
│       │               │   ├── MaldingPacket.java
│       │               │   ├── NullablePacket.java
│       │               │   ├── SealedSubclassOne.java
│       │               │   ├── SealedSubclassTwo.java
│       │               │   ├── SealedTestClass.java
│       │               │   ├── StringPacket.java
│       │               │   ├── UwuNetworkExample.java
│       │               │   ├── UwuNetworkTest.java
│       │               │   └── UwuOptionalNetExample.java
│       │               ├── recipe/
│       │               │   └── UwuShapedRecipe.java
│       │               ├── rei/
│       │               │   ├── UiCategory.java
│       │               │   └── UwuReiPlugin.java
│       │               └── text/
│       │                   └── BasedTextContent.java
│       └── resources/
│           ├── assets/
│           │   ├── uowou/
│           │   │   ├── items/
│           │   │   │   └── owo_ingot.json5
│           │   │   └── models/
│           │   │       └── item/
│           │   │           └── owo_ingot.json5
│           │   └── uwu/
│           │       ├── blockstates/
│           │       │   └── braid_display.json5
│           │       ├── items/
│           │       │   ├── braid.json5
│           │       │   ├── braid_display.json5
│           │       │   ├── braid_samples.json5
│           │       │   ├── screen_shard.json
│           │       │   ├── screen_shard.json5
│           │       │   ├── test_stick.json
│           │       │   └── test_stick.json5
│           │       ├── lang/
│           │       │   └── en_us.json5
│           │       ├── models/
│           │       │   ├── block/
│           │       │   │   └── braid_display.json5
│           │       │   └── item/
│           │       │       ├── braid.json5
│           │       │       └── counter.json5
│           │       ├── nine_patch_textures/
│           │       │   └── contributors_panel.json5
│           │       ├── owo_ui/
│           │       │   ├── config.xml
│           │       │   ├── expand_gap_test.xml
│           │       │   ├── focus_cycle_test.xml
│           │       │   ├── parse_fail.xml
│           │       │   ├── smol_components.xml
│           │       │   ├── test_element_one.xml
│           │       │   └── test_element_two.xml
│           │       └── textures/
│           │           └── gui/
│           │               └── bikeshed.png.mcmeta
│           ├── data/
│           │   └── uwu/
│           │       ├── item_group_tabs/
│           │       │   ├── crab_group.json5
│           │       │   ├── food_and_drink_button.json5
│           │       │   ├── ingredients_extension.json5
│           │       │   └── ingredients_extension_2.json5
│           │       ├── recipe/
│           │       │   ├── test_recipe.json5
│           │       │   ├── uwu_shaped_recipe.json5
│           │       │   └── what_the_bucket_doin.json5
│           │       └── tags/
│           │           └── item/
│           │               └── tab_2_content.json5
│           ├── fabric.mod.json
│           ├── owo-json5
│           └── uwu.mixins.json
└── stylesheet.css

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/workflows/build.yml
================================================
# Automatically build the project and run any configured tests for every push
# and submitted pull request. This can help catch issues that only occur on
# certain platforms or Java versions, and provides a first line of defence
# against bad commits.

name: build
on: [pull_request, push]

jobs:
  build:
    strategy:
      matrix:
        # Use these Java versions
        java: [
            21    # Minimum supported by Minecraft
        ]
        # and run on both Linux and Windows
        os: [ubuntu-22.04]
    runs-on: ${{ matrix.os }}
    steps:
      - name: checkout repository
        uses: actions/checkout@v2
      - name: validate gradle wrapper
        uses: gradle/wrapper-validation-action@v1
      - name: setup jdk ${{ matrix.java }}
        uses: actions/setup-java@v1
        with:
          java-version: ${{ matrix.java }}
      - name: make gradle wrapper executable
        if: ${{ runner.os != 'Windows' }}
        run: chmod +x ./gradlew
      - name: build
        run: ./gradlew build
      - name: capture build artifacts
        if: ${{ runner.os == 'Linux' && matrix.java == '21' }} # Only upload artifacts built from latest java on one OS
        uses: actions/upload-artifact@v4
        with:
          name: Artifacts
          path: build/libs/


================================================
FILE: .gitignore
================================================
# User-specific stuff
.idea/

*.iml
*.ipr
*.iws

# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

*~

# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*

# KDE directory preferences
.directory

# Linux trash folder which might appear on any partition or disk
.Trash-*

# .nfs files are created when an open file is removed but is still being accessed
.nfs*

# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db

# Dump file
*.stackdump

# Folder config file
[Dd]esktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp

# Windows shortcuts
*.lnk

.gradle
build/

# Ignore Gradle GUI config
gradle-app.setting

# Cache of project
.gradletasknamecache

**/build/

# Common working directory
run/

# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar

# generated sources
/src/*/generated/


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2021 

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.


================================================
FILE: README.md
================================================
<h1 align="center">
    <img src="https://i.imgur.com/VXjFso4.png">
    <br>
    oωo (owo-lib)
    <br>
    <a href="https://www.curseforge.com/minecraft/mc-mods/owo-lib">
        <img src="https://img.shields.io/badge/-CurseForge-gray?style=for-the-badge&logo=curseforge&labelColor=orange">
    </a>
    <a href="https://modrinth.com/mod/owo-lib">
        <img src="https://img.shields.io/badge/-modrinth-gray?style=for-the-badge&labelColor=green&labelWidth=15&logo=appveyor&logoColor=white">
    </a>
    <br>
    <a href="https://github.com/wisp-forest/owo-lib/releases">
        <img src="https://img.shields.io/github/v/release/glisco03/owo-lib?logo=github&style=for-the-badge">
    </a>
    <a href="https://discord.gg/xrwHKktV2d">
        <img src="https://img.shields.io/discord/825828008644313089?label=wisp%20forest&logo=discord&logoColor=white&style=for-the-badge">
    </a>
</h1>
    
## Overview

A general utility, GUI and config library for modding on Fabric. oωo is generally aimed at reducing code verbosity and making development more ergonomic. It covers a wide range of features from networking and serialization over GUI applications and configuration to data handling and registration. 

**Build Setup:**
```properties
# https://maven.wispforest.io/io/wispforest/owo-lib/
owo_version=...
```

```groovy
repositories {
    maven { url 'https://maven.wispforest.io' }
}

<...>

dependencies {
    modImplementation "io.wispforest:owo-lib:${project.owo_version}"
    // only if you plan to use owo-config
    annotationProcessor "io.wispforest:owo-lib:${project.owo_version}"
    
    // include this if you don't want force your users to install owo
    // sentinel will warn them and give the option to download it automatically
    include "io.wispforest:owo-sentinel:${project.owo_version}"
}
```

<details>
<summary><strong>Kotlin DSL</strong></summary>
    
```kotlin
repositories {
    maven("https://maven.wispforest.io")
}
    
dependencies {
    modImplementation("io.wispforest:owo-lib:${properties["owo_version"]}")
    // only if you plan to use owo-config
    annotationProcessor("io.wispforest:owo-lib:${properties["owo_version"]}")
    
    // include this if you don't want force your users to install owo
    // sentinel will warn them and give the option to download it automatically
    include("io.wispforest:owo-sentinel:${properties["owo_version"]}")
} 
```
    
</details>

You can check the latest version on the [Releases](https://github.com/wisp-forest/owo-lib/releases) page

owo is documented in two main ways:
 - There is rich, detailed JavaDoc throughout the entire codebase
 - There is a wiki with in-depth explanations and tutorials for most of owo's features over at https://docs.wispforest.io/owo/features

## Features

This is by no means an exhaustive list, for a more complete overview head to https://docs.wispforest.io/owo/features

 - [owo-ui](https://docs.wispforest.io/owo/ui), a fully-featured declarative UI library for building dynamic, beautiful screens with blazingly fast development times
 - [owo-config](https://docs.wispforest.io/owo/config), a built-in, customizable configuration system built on top of owo-ui. It provides many of the same features as [Cloth Config](https://modrinth.com/mod/cloth-config) while many new conveniences, like server-client config synchronization, added on top
 - A fully automatic [registration system](https://docs.wispforest.io/owo/registration) that is designed to be as generic as possible. It is simple and non-verbose to use for basic registries, yet the underlying API tree is flexible and can also be used for many custom registration solutions
 - [Item Group extensions](https://docs.wispforest.io/owo/item-groups) which allow for sub-tabs inside your mod's group as well as a host of other features like custom buttons, textures and item variant handling
 - A fully-featured [networking layer](https://docs.wispforest.io/owo/networking) with fully automatic serialization, handshaking to ensure client compatibility and a built-in solution for triggering parametrized particle events in a side-agnostic manner
 - Client-sided particle helpers that allow for easily composing multi-particle effects
 - Rich text translations, allowing you to use Minecraft's text component format in your language files to provide styled text without any code


================================================
FILE: braid-reload-agent/.gitattributes
================================================
#
# https://help.github.com/articles/dealing-with-line-endings/
#
# Linux start script should use lf
/gradlew        text eol=lf

# These are Windows script files and should use crlf
*.bat           text eol=crlf



================================================
FILE: braid-reload-agent/.gitignore
================================================
# Ignore Gradle project-specific cache directory
.gradle

# Ignore Gradle build output directory
build


================================================
FILE: braid-reload-agent/build.gradle.kts
================================================
plugins {
    application
    `maven-publish`
}

repositories {
    mavenCentral()
}

dependencies {}

version = "0.1.0"
group = "io.wispforest"

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(21)
    }
}

tasks.jar {
    manifest.attributes(
        "Premain-Class" to "io.wispforest.BraidReloadAgent"
    )
}

publishing {
    publications {
        create<MavenPublication>("maven") {
            from(components["java"])
        }
    }

    val env = System.getenv()
    if (env.contains("MAVEN_URL")) {
        repositories {
            maven {
                url = uri(env["MAVEN_URL"]!!)
                credentials {
                    username = env["MAVEN_USER"]
                    password = env["MAVEN_PASSWORD"]
                }
            }
        }
    }
}

================================================
FILE: braid-reload-agent/gradle/libs.versions.toml
================================================
# This file was generated by the Gradle 'init' task.
# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format

[versions]
guava = "33.0.0-jre"
junit-jupiter = "5.10.2"

[libraries]
guava = { module = "com.google.guava:guava", version.ref = "guava" }
junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit-jupiter" }


================================================
FILE: braid-reload-agent/gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists


================================================
FILE: braid-reload-agent/gradlew
================================================
#!/bin/sh

#
# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

##############################################################################
#
#   Gradle start up script for POSIX generated by Gradle.
#
#   Important for running:
#
#   (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
#       noncompliant, but you have some other compliant shell such as ksh or
#       bash, then to run this script, type that shell name before the whole
#       command line, like:
#
#           ksh Gradle
#
#       Busybox and similar reduced shells will NOT work, because this script
#       requires all of these POSIX shell features:
#         * functions;
#         * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
#           «${var#prefix}», «${var%suffix}», and «$( cmd )»;
#         * compound commands having a testable exit status, especially «case»;
#         * various built-in commands including «command», «set», and «ulimit».
#
#   Important for patching:
#
#   (2) This script targets any POSIX shell, so it avoids extensions provided
#       by Bash, Ksh, etc; in particular arrays are avoided.
#
#       The "traditional" practice of packing multiple parameters into a
#       space-separated string is a well documented source of bugs and security
#       problems, so this is (mostly) avoided, by progressively accumulating
#       options in "$@", and eventually passing that to Java.
#
#       Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
#       and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
#       see the in-line comments for details.
#
#       There are tweaks for specific operating systems such as AIX, CygWin,
#       Darwin, MinGW, and NonStop.
#
#   (3) This script is generated from the Groovy template
#       https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
#       within the Gradle project.
#
#       You can find Gradle at https://github.com/gradle/gradle/.
#
##############################################################################

# Attempt to set APP_HOME

# Resolve links: $0 may be a link
app_path=$0

# Need this for daisy-chained symlinks.
while
    APP_HOME=${app_path%"${app_path##*/}"}  # leaves a trailing /; empty if no leading path
    [ -h "$app_path" ]
do
    ls=$( ls -ld "$app_path" )
    link=${ls#*' -> '}
    case $link in             #(
      /*)   app_path=$link ;; #(
      *)    app_path=$APP_HOME$link ;;
    esac
done

# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum

warn () {
    echo "$*"
} >&2

die () {
    echo
    echo "$*"
    echo
    exit 1
} >&2

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "$( uname )" in                #(
  CYGWIN* )         cygwin=true  ;; #(
  Darwin* )         darwin=true  ;; #(
  MSYS* | MINGW* )  msys=true    ;; #(
  NONSTOP* )        nonstop=true ;;
esac

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar


# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD=$JAVA_HOME/jre/sh/java
    else
        JAVACMD=$JAVA_HOME/bin/java
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD=java
    if ! command -v java >/dev/null 2>&1
    then
        die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
fi

# Increase the maximum file descriptors if we can.
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
    case $MAX_FD in #(
      max*)
        # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
        # shellcheck disable=SC2039,SC3045
        MAX_FD=$( ulimit -H -n ) ||
            warn "Could not query maximum file descriptor limit"
    esac
    case $MAX_FD in  #(
      '' | soft) :;; #(
      *)
        # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
        # shellcheck disable=SC2039,SC3045
        ulimit -n "$MAX_FD" ||
            warn "Could not set maximum file descriptor limit to $MAX_FD"
    esac
fi

# Collect all arguments for the java command, stacking in reverse order:
#   * args from the command line
#   * the main class name
#   * -classpath
#   * -D...appname settings
#   * --module-path (only if needed)
#   * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.

# For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then
    APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
    CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )

    JAVACMD=$( cygpath --unix "$JAVACMD" )

    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    for arg do
        if
            case $arg in                                #(
              -*)   false ;;                            # don't mess with options #(
              /?*)  t=${arg#/} t=/${t%%/*}              # looks like a POSIX filepath
                    [ -e "$t" ] ;;                      #(
              *)    false ;;
            esac
        then
            arg=$( cygpath --path --ignore --mixed "$arg" )
        fi
        # Roll the args list around exactly as many times as the number of
        # args, so each arg winds up back in the position where it started, but
        # possibly modified.
        #
        # NB: a `for` loop captures its iteration list before it begins, so
        # changing the positional parameters here affects neither the number of
        # iterations, nor the values presented in `arg`.
        shift                   # remove old arg
        set -- "$@" "$arg"      # push replacement arg
    done
fi


# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Collect all arguments for the java command:
#   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
#     and any embedded shellness will be escaped.
#   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
#     treated as '${Hostname}' itself on the command line.

set -- \
        "-Dorg.gradle.appname=$APP_BASE_NAME" \
        -classpath "$CLASSPATH" \
        org.gradle.wrapper.GradleWrapperMain \
        "$@"

# Stop when "xargs" is not available.
if ! command -v xargs >/dev/null 2>&1
then
    die "xargs is not available"
fi

# Use "xargs" to parse quoted args.
#
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
#
# In Bash we could simply go:
#
#   readarray ARGS < <( xargs -n1 <<<"$var" ) &&
#   set -- "${ARGS[@]}" "$@"
#
# but POSIX shell has neither arrays nor command substitution, so instead we
# post-process each arg (as a line of input to sed) to backslash-escape any
# character that might be a shell metacharacter, then use eval to reverse
# that process (while maintaining the separation between arguments), and wrap
# the whole thing up as a single "set" statement.
#
# This will of course break if any of these variables contains a newline or
# an unmatched quote.
#

eval "set -- $(
        printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
        xargs -n1 |
        sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
        tr '\n' ' '
    )" '"$@"'

exec "$JAVACMD" "$@"


================================================
FILE: braid-reload-agent/gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem      https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem

@if "%DEBUG%"=="" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute

echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto execute

echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2

goto fail

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar


@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*

:end
@rem End local scope for the variables with windows NT shell
if %ERRORLEVEL% equ 0 goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
set EXIT_CODE=%ERRORLEVEL%
if %EXIT_CODE% equ 0 set EXIT_CODE=1
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
exit /b %EXIT_CODE%

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: braid-reload-agent/settings.gradle.kts
================================================
plugins {
    // Apply the foojay-resolver plugin to allow automatic download of JDKs
    id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
}


================================================
FILE: braid-reload-agent/src/main/java/io/wispforest/BraidReloadAgent.java
================================================
package io.wispforest;

import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.Instrumentation;
import java.security.ProtectionDomain;
import java.util.*;

public class BraidReloadAgent {
    public static void premain(String agentArgs, Instrumentation instrumentation) {
        instrumentation.addTransformer(new RedefinitionListener());
    }
}

class RedefinitionListener implements ClassFileTransformer {

    private final Map<String, Integer> classHashes = new HashMap<>();
    private final Set<String> classesToWaitFor = new HashSet<>(Set.of(
        "io/wispforest/owo/braid/framework/widget/Widget",
        "io/wispforest/owo/braid/framework/proxy/WidgetState",
        "io/wispforest/owo/braid/core/BraidHotReloadCallback"
    ));

    private ClassLoader braidClassLoader;
    private boolean logSetupComplete = false;

    @Override
    public byte[] transform(Module module, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
        if (this.logSetupComplete) {
            this.logSetupComplete = false;

            fallible(() -> {
                var callbackClass = Class.forName("io.wispforest.owo.braid.core.BraidHotReloadCallback", false, this.braidClassLoader);
                callbackClass.getMethod("setupComplete").invoke(null);
            });
        }

        if (!this.classesToWaitFor.isEmpty()) {
            if (this.classesToWaitFor.contains(className)) {
                this.classesToWaitFor.remove(className);

                if (this.braidClassLoader == null) {
                    this.braidClassLoader = loader;
                }

                if (this.classesToWaitFor.isEmpty()) {
                    this.logSetupComplete = true;
                }
            }

            return ClassFileTransformer.super.transform(module, loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
        }

        fallible(() -> {
            var widgetClass = Class.forName("io.wispforest.owo.braid.framework.widget.Widget", false, this.braidClassLoader);
            var widgetStateClass = Class.forName("io.wispforest.owo.braid.framework.proxy.WidgetState", false, this.braidClassLoader);
            var callbackClass = Class.forName("io.wispforest.owo.braid.core.BraidHotReloadCallback", false, this.braidClassLoader);

            if (classBeingRedefined != null) {
                if (widgetClass.isAssignableFrom(classBeingRedefined) || widgetStateClass.isAssignableFrom(classBeingRedefined)) {
                    var newHash = Arrays.hashCode(classfileBuffer);

                    if (!this.classHashes.containsKey(className) || this.classHashes.get(className) != newHash) {
                        callbackClass.getMethod("invoke").invoke(null);
                    }

                    this.classHashes.put(className, newHash);
                }
            }
        });

        return ClassFileTransformer.super.transform(module, loader, className, classBeingRedefined, protectionDomain, classfileBuffer);
    }

    private static void fallible(Fallible fallible) {
        fallible.run();
    }
}

interface Fallible {
    void body() throws Throwable;

    default void run() {
        try {
            this.body();
        } catch (Throwable error) {
            System.err.println("(braid reload agent) hotswap error: " + error.getMessage());
            //noinspection CallToPrintStackTrace
            error.printStackTrace();
        }
    }
}

================================================
FILE: build.gradle
================================================
//file:noinspection GradlePackageVersionRange
plugins {
    id 'net.fabricmc.fabric-loom-remap' version '1.15-SNAPSHOT'
    id 'maven-publish'
}

allprojects {
    apply plugin: "java"
    apply plugin: "fabric-loom"
    apply plugin: "maven-publish"

    def ENV = System.getenv()

    version = "${project.mod_version}+${rootProject.minecraft_base_version}"
    group = rootProject.maven_group

    base {
        archivesName = project.archives_base_name
    }

    dependencies {
        minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
        mappings loom.officialMojangMappings()
        modImplementation "net.fabricmc:fabric-loader:${rootProject.loader_version}"

        modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
    }

    processResources {
        inputs.property "version", project.version
        filteringCharset "UTF-8"

        filesMatching("fabric.mod.json") {
            expand "version": project.version
        }
    }

    def targetJavaVersion = 21
    tasks.withType(JavaCompile).configureEach {
        // ensure that the encoding is set to UTF-8, no matter what the system default is
        // this fixes some edge cases with special characters not displaying correctly
        // see http://yodaconditions.net/blog/fix-for-java-file-encoding-problems-with-gradle.html
        // If Javadoc is generated, this must be specified in that task too.
        it.options.encoding = "UTF-8"
        if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) {
            it.options.release = targetJavaVersion
        }

        options.compilerArgs << "-Xmaxerrs" << "69420"
    }

    java {
        def javaVersion = JavaVersion.toVersion(targetJavaVersion)
        if (JavaVersion.current() < javaVersion) {
            toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
        }
        // Loom will automatically attach sourcesJar to a RemapSourcesJar task and to the "build" task
        // if it is present.
        // If you remove this line, sources will not be generated.
        withSourcesJar()
    }

    jar {
        from("LICENSE") {
            rename { "${it}_${project.base.archivesName.get()}" }
        }
    }

    publishing {
        publications {
            mavenJava(MavenPublication) {
                from components.java
            }
        }

        repositories {
            maven {
                url ENV.MAVEN_URL
                credentials {
                    username ENV.MAVEN_USER
                    password ENV.MAVEN_PASSWORD
                }
            }
        }
    }
}

repositories {
    maven { url "https://maven.terraformersmc.com/releases/" }
    maven { url "https://maven.shedaniel.me/" }
    maven {
        url "https://api.modrinth.com/maven"
        content {
            includeGroup "maven.modrinth"
        }
    }
    maven { url "https://maven.nucleoid.xyz/" }
    maven { url 'https://maven.wispforest.io' }
    maven { url 'https://jitpack.io' }
}

sourceSets {
    testmod {
        runtimeClasspath += main.runtimeClasspath
        compileClasspath += main.compileClasspath
    }
}

loom {
    runs {
        testmodClient {
            client()
            ideConfigGenerated project.rootProject == project
            name = "Testmod Client"
            source sourceSets.testmod
        }
        testmodServer {
            server()
            ideConfigGenerated project.rootProject == project
            name = "Testmod Server"
            source sourceSets.testmod
        }
    }

    accessWidenerPath = file("src/main/resources/owo.accesswidener")
}

dependencies {
//    modLocalRuntime("me.shedaniel:RoughlyEnoughItems-fabric:${project.rei_version}")
    modCompileOnly("me.shedaniel:RoughlyEnoughItems-default-plugin-fabric:${project.rei_version}") {
        exclude "group": "net.fabricmc.fabric-api"
    }
    modCompileOnly("me.shedaniel:RoughlyEnoughItems-api-fabric:${project.rei_version}") {
        exclude "group": "net.fabricmc.fabric-api"
    }

    modCompileOnly("dev.emi:emi-fabric:${project.emi_version}") {
        exclude "group": "net.fabricmc.fabric-api"
    }
//    modLocalRuntime("dev.emi:emi-fabric:${project.emi_version}")

    modCompileOnly("com.terraformersmc:modmenu:${project.modmenu_version}")
//    modLocalRuntime("com.terraformersmc:modmenu:${project.modmenu_version}")

    include api("io.wispforest:endec:0.1.12")
    include api("io.wispforest.endec:netty:0.1.6")
    include api("io.wispforest.endec:gson:0.1.7")
    include api("io.wispforest.endec:jankson:0.1.7")

    include api("blue.endless:jankson:${project.jankson_version}")
    include api("com.github.kdl-org:kdl4j:${project.kdl_version}")

    modCompileOnly("xyz.nucleoid:server-translations-api:${project.stapi_version}")

    testmodImplementation sourceSets.main.output
    testmodAnnotationProcessor sourceSets.main.output
}

javadoc {
    options.stylesheetFile = new File(projectDir, "stylesheet.css")
    options.tags = ["apiNote", "implNote", "implSpec"]
    options.addStringOption("Xdoclint:-missing", "-quiet")
    options.encoding = 'UTF-8'
}

================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists


================================================
FILE: gradle.properties
================================================
# Done to increase the memory available to gradle.
org.gradle.jvmargs=-Xmx2G
# Fabric Properties
# check these on https://fabricmc.net/develop
minecraft_base_version=1.21.11
minecraft_version=1.21.11
yarn_mappings=1.21.11+build.2
loader_version=0.18.2
# Mod Properties
mod_version=0.13.0
maven_group=io.wispforest
archives_base_name=owo-lib
# Dependencies
fabric_version=0.141.2+1.21.11

# https://maven.shedaniel.me/me/shedaniel/RoughlyEnoughItems-fabric/
rei_version=21.9.812

# https://maven.terraformersmc.com/releases/dev/emi/emi-fabric/
emi_version=1.1.18+1.21.1

# https://search.maven.org/artifact/blue.endless/jankson
jankson_version=1.2.2

# https://jitpack.io/#kdl-org/kdl4j
kdl_version=1.0.1

# https://maven.terraformersmc.com/releases/com/terraformersmc/modmenu
modmenu_version=17.0.0-alpha.1

# https://maven.nucleoid.xyz/xyz/nucleoid/server-translations-api/
stapi_version=2.5.2+1.21.9-pre3


================================================
FILE: gradlew
================================================
#!/usr/bin/env sh

#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn () {
    echo "$*"
}

die () {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
  NONSTOP* )
    nonstop=true
    ;;
esac

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar


# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
    
    JAVACMD=`cygpath --unix "$JAVACMD"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=`expr $i + 1`
    done
    case $i in
        0) set -- ;;
        1) set -- "$args0" ;;
        2) set -- "$args0" "$args1" ;;
        3) set -- "$args0" "$args1" "$args2" ;;
        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Escape application args
save () {
    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
    echo " "
}
APP_ARGS=`save "$@"`

# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"

exec "$JAVACMD" "$@"


================================================
FILE: gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem      https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem

@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem  Gradle startup script for Windows
@rem
@rem ##########################################################################

@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal

set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi

@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome

set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init

echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe

if exist "%JAVA_EXE%" goto init

echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.

goto fail

:init
@rem Get command-line arguments, handling Windows variants

if not "%OS%" == "Windows_NT" goto win9xME_args

:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2

:win9xME_args_slurp
if "x%~1" == "x" goto execute

set CMD_LINE_ARGS=%*

:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar


@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd

:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1

:mainEnd
if "%OS%"=="Windows_NT" endlocal

:omega


================================================
FILE: jitpack.yml
================================================
jdk:
  - openjdk21

================================================
FILE: owo-sentinel/build.gradle
================================================
loom {
    runConfigs.client.ideConfigGenerated = true

    mods {
        "owo-sentinel" {
            sourceSet sourceSets.main
        }
    }
}

================================================
FILE: owo-sentinel/gradle.properties
================================================
archives_base_name=owo-sentinel


================================================
FILE: owo-sentinel/src/main/java/io/wispforest/owosentinel/DownloadTask.java
================================================
package io.wispforest.owosentinel;

import javax.swing.*;
import java.util.function.Consumer;

public class DownloadTask extends SwingWorker<Void, Void> {

    private final Runnable whenDone;
    private final Consumer<String> logger;

    public DownloadTask(Consumer<String> logger, Runnable whenDone) {
        this.logger = logger;
        this.whenDone = whenDone;
    }

    @Override
    protected void done() {
        whenDone.run();
    }

    @Override
    protected Void doInBackground() {
        try {
            OwoSentinel.downloadAndInstall(logger);
        } catch (Exception e) {
            logger.accept("Download failed!");
            OwoSentinel.LOGGER.error("Download failed", e);
        }
        return null;
    }
}


================================================
FILE: owo-sentinel/src/main/java/io/wispforest/owosentinel/Maldenhagen.java
================================================
package io.wispforest.owosentinel;

import net.fabricmc.loader.api.LanguageAdapter;
import net.fabricmc.loader.api.ModContainer;

public class Maldenhagen implements LanguageAdapter {
    @Override
    public <T> T create(ModContainer mod, String value, Class<T> type) {
        throw new UnsupportedOperationException();
    }

    static {
        OwoSentinel.launch();
    }
}


================================================
FILE: owo-sentinel/src/main/java/io/wispforest/owosentinel/OwoSentinel.java
================================================
package io.wispforest.owosentinel;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.awt.*;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.function.Consumer;

public class OwoSentinel {
    public static final Logger LOGGER = LogManager.getLogger("oωo-sentinel");
    private static final Gson GSON = new Gson();

    public static final String OWO_EXPLANATION = """
            oωo-lib is a library used by most mods under the
            Wisp Forest domain to ease development. This is
            simply a convenient installer, as oωo is missing from your
            installation. Should you not trust it, feel free to head to the
            repository and download oωo yourself.
            """;

    public static final boolean FORCE_HEADLESS = Boolean.getBoolean("owo.sentinel.forceHeadless");

    public static void launch() {
        if (FabricLoader.getInstance().isModLoaded("owo-impl")) return;

        try {
            if (System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("mac") || GraphicsEnvironment.isHeadless() || FORCE_HEADLESS) {
                SentinelConsole.run();
            } else {
                SentinelWindow.open();
            }
        } catch (Exception e) {
            LOGGER.error("Error thrown while opening sentinel! Exiting", e);
            System.exit(1);
        }

        System.exit(0);
    }

    public static List<String> listOwoDependents() {
        var list = new ArrayList<String>();
        var used = new HashSet<String>();

        for (var mod : FabricLoader.getInstance().getAllMods()) {
            for (var dependency : mod.getMetadata().getDependencies()) {
                if (!dependency.getModId().equals("owo") && !dependency.getModId().equals("owo-lib")) continue;
                list.add(mod.getMetadata().getName() + " (explicit dependency)");
                used.add(mod.getMetadata().getId());
            }
        }

        FabricLoader.getInstance()
                .getModContainer("owo-sentinel")
                .flatMap(ModContainer::getContainingMod)
                .ifPresent(mod -> {
                    if (used.contains(mod.getMetadata().getId())) return;

                    list.add(mod.getMetadata().getName() + " (included sentinel)");
                });

        return list;
    }

    @SuppressWarnings("deprecation")
    public static void downloadAndInstall(Consumer<String> logger) throws Exception {
        logger.accept("Fetching versions");
        final URL url = new URL("https://api.modrinth.com/v2/project/owo-lib/version?game_versions=[%22" + FabricLoader.getInstance().getRawGameVersion() + "%22]&loaders=[%22fabric%22]");

        final var response = GSON.fromJson(new InputStreamReader(url.openStream()), JsonArray.class);

        final var targetVersion = FabricLoader.getInstance().getModContainer("owo-sentinel").orElseThrow().getMetadata().getVersion().getFriendlyString();

        JsonObject latestVersion = null;

        for (var version : response) {
            final var versionObject = version.getAsJsonObject();

            if (versionObject.get("version_number").getAsString().equals(targetVersion)) {
                latestVersion = versionObject;
                break;
            }
        }

        if (latestVersion != null) {
            final var firstFile = latestVersion
                    .get("files").getAsJsonArray().get(0).getAsJsonObject();

            final var versionUrl = firstFile
                    .get("url").getAsString();

            final var versionFilename = firstFile
                    .get("filename").getAsString();

            logger.accept("Found matching version: " + latestVersion.get("version_number").getAsString());

            final var filePath = FabricLoader.getInstance().getGameDir().resolve("mods").resolve(versionFilename);

            logger.accept("Downloading...");

            try (final var modStream = new URL(versionUrl).openStream()) {
                Files.copy(modStream, filePath, StandardCopyOption.REPLACE_EXISTING);
            }

            logger.accept("Success!");
        } else {
            logger.accept("No matching version found");
        }
    }
}


================================================
FILE: owo-sentinel/src/main/java/io/wispforest/owosentinel/SentinelConsole.java
================================================
package io.wispforest.owosentinel;

import java.util.Locale;
import java.util.Scanner;

public class SentinelConsole {
    public static void run() throws Exception {
        System.out.println("oωo-lib is required to run the following mods:");

        for (String dependent : OwoSentinel.listOwoDependents()) {
            System.out.println("- " + dependent);
        }

        System.out.println("\n" + OwoSentinel.OWO_EXPLANATION);
        System.out.print("Download and install (Y/n): ");

        Scanner in = new Scanner(System.in);
        boolean install = false;

        try {
            String answer = in.next();

            install = answer.isBlank() || answer.toLowerCase(Locale.ROOT).startsWith("y");
        } catch (Exception e) {
            System.out.println("<stdin blocked>");
        }

        if (install) {
            OwoSentinel.downloadAndInstall(System.out::println);
        } else {
            System.out.println("You can install oωo-lib at https://modrinth.com/mod/owo-lib.");
        }
    }
}


================================================
FILE: owo-sentinel/src/main/java/io/wispforest/owosentinel/SentinelWindow.java
================================================
package io.wispforest.owosentinel;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.URI;

public class SentinelWindow {
    public static void open() throws Exception {
        // Fix AA
        System.setProperty("awt.useSystemAAFontSettings", "lcd");
        System.setProperty("swing.aatext", "true");

        // Force GTK if available
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        for (var laf : UIManager.getInstalledLookAndFeels()) {
            if (!"GTK+".equals(laf.getName())) continue;
            UIManager.setLookAndFeel(laf.getClassName());
        }

        // ------
        // Window
        // ------

        JFrame window = new JFrame("oωo-sentinel");
        window.setVisible(false);

        //noinspection ConstantConditions
        final var owoIconImage = ImageIO.read(OwoSentinel.class.getClassLoader()
                .getResourceAsStream("owo_sentinel_icon.png"));

        window.setIconImage(owoIconImage);
        window.setMinimumSize(new Dimension(0, 250));
        window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        window.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosed(WindowEvent e) {
                System.exit(0);
            }
        });
        window.setLocationByPlatform(true);

        // -----
        // Title
        // -----

        final var titleLabel = new JLabel("oωo-lib is required to run the following mods", new ImageIcon(owoIconImage), SwingConstants.LEFT);
        titleLabel.setFont(titleLabel.getFont().deriveFont(titleLabel.getFont().getSize() * 1.25f));
        titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
        titleLabel.setBorder(new EmptyBorder(0, 15, 0, 15));
        window.getContentPane().add(titleLabel, BorderLayout.NORTH);

        // ----------
        // Dependents
        // ----------

        var dependents = "<html><center><b>" + String.join("<br>", OwoSentinel.listOwoDependents()) + "<p>\u200B";

        final var dependentsLabel = new JLabel(dependents);
        final var defaultDepFont = dependentsLabel.getFont();

        dependentsLabel.setFont(defaultDepFont.deriveFont(defaultDepFont.getSize() * 1.1f));
        dependentsLabel.setHorizontalAlignment(SwingConstants.CENTER);

        window.getContentPane().add(dependentsLabel, BorderLayout.CENTER);

        // -------
        // Buttons
        // -------

        var buttonsPanel = new JPanel();

        // Download

        final var downloadButton = new JButton("Download and install");

        final var progressBar = new JProgressBar();
        progressBar.setIndeterminate(true);

        downloadButton.addActionListener(e -> {
            downloadButton.setEnabled(false);
            downloadButton.add(progressBar);
            downloadButton.updateUI();

            titleLabel.setText("Installing oωo-lib");
            window.getContentPane().remove(dependentsLabel);

            final var logBox = new JTextArea();
            logBox.setEditable(false);
            logBox.setMargin(new Insets(15, 15, 15, 15));
            final var scrollPane = new JScrollPane(logBox);
            scrollPane.setBorder(new EmptyBorder(0, 15, 0, 15));
            window.getContentPane().add(scrollPane, BorderLayout.CENTER);

            var task = new DownloadTask(s -> {
                OwoSentinel.LOGGER.info(s);
                logBox.setText(logBox.getText() + (logBox.getText().isBlank() ? "" : "\n") + s);
                scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMaximum());
            }, () -> {
                progressBar.setVisible(false);
                titleLabel.setText("");
                downloadButton.setText("Installed");
            });
            task.execute();
        });

        // What is this

        final var whatIsThisButton = new JButton("What is this?");
        whatIsThisButton.addActionListener(e -> {
            String[] options = {"Open GitHub", "OK"};

            int selection = JOptionPane.showOptionDialog(window, OwoSentinel.OWO_EXPLANATION, "oωo-sentinel",
                    JOptionPane.YES_NO_OPTION, JOptionPane.INFORMATION_MESSAGE, new ImageIcon(owoIconImage),
                    options, options[0]);

            if (selection == 0 && Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
                try {
                    Desktop.getDesktop().browse(URI.create("https://github.com/wisp-forest/owo-lib"));
                } catch (IOException ignored) {}
            }
        });

        // Exit

        final var exitButton = new JButton("Close");
        exitButton.addActionListener(e -> window.dispose());

        // Panel setup

        buttonsPanel.add(downloadButton);
        buttonsPanel.add(whatIsThisButton);
        buttonsPanel.add(exitButton);

        // ---------------
        // Window creation
        // ---------------

        window.getContentPane().add(buttonsPanel, BorderLayout.SOUTH);

        window.pack();
        window.setVisible(true);
        window.requestFocus();

        synchronized (SentinelWindow.class) {
            SentinelWindow.class.wait();
        }
    }
}


================================================
FILE: owo-sentinel/src/main/resources/fabric.mod.json
================================================
{
  "schemaVersion": 1,
  "id": "owo-sentinel",
  "version": "${version}",
  "name": "oωo-sentinel",
  "description": "makes u download oωo",
  "authors": [
    "glisco"
  ],
  "contact": {},
  "license": "MIT",
  "icon": "owo_sentinel_icon.png",
  "environment": "*",
  "provides": [
    "owo",
    "owo-lib"
  ],
  "languageAdapters": {
    "maldenhagen": "io.wispforest.owosentinel.Maldenhagen"
  },
  "depends": {
    "fabricloader": "*",
    "minecraft": ">=1.18"
  },
  "custom": {
    "modmenu": {
      "links": {
        "modmenu.discord": "https://discord.gg/xrwHKktV2d"
      },
      "badges": [
        "library"
      ]
    }
  }
}


================================================
FILE: owo-ui.xsd
================================================
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
           elementFormDefault="qualified"
           vc:minVersion="1.1">

    <xs:element name="owo-ui">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="components" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:group ref="anyComponent"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="templates" minOccurs="0">
                    <xs:complexType>
                        <xs:sequence maxOccurs="unbounded">
                            <xs:choice>
                                <xs:element name="template">
                                    <xs:complexType>
                                        <xs:sequence>
                                            <xs:group ref="anyComponent"/>
                                        </xs:sequence>
                                        <xs:attribute name="name" type="xs:Name" use="required"/>
                                    </xs:complexType>
                                </xs:element>
                                <xs:any processContents="lax"/>
                            </xs:choice>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>

    <xs:group name="anyComponent">
        <xs:choice>
            <xs:element name="label" type="owo-ui-label-component"/>
            <xs:element name="button" type="owo-ui-button-component"/>
            <xs:element name="textured-button" type="owo-ui-textured-button-component"/>
            <xs:element name="box" type="owo-ui-box-component"/>
            <xs:element name="text-box" type="owo-ui-text-field-component"/>
            <xs:element name="entity" type="owo-ui-entity-component"/>
            <xs:element name="button" type="owo-ui-button-component"/>
            <xs:element name="slider" type="owo-ui-slider-component"/>
            <xs:element name="discrete-slider" type="owo-ui-discrete-slider-component"/>
            <xs:element name="checkbox" type="owo-ui-checkbox-component"/>
            <xs:element name="item" type="owo-ui-item-component"/>
            <xs:element name="block" type="owo-ui-block-component"/>
            <xs:element name="sprite" type="owo-ui-sprite-component"/>
            <xs:element name="texture" type="owo-ui-texture-component"/>
            <xs:element name="collapsible" type="owo-ui-collapsible-container"/>
            <xs:element name="draggable" type="owo-ui-draggable-container"/>
            <xs:element name="flow-layout" type="owo-ui-flow-layout"/>
            <xs:element name="grid-layout" type="owo-ui-grid-layout"/>
            <xs:element name="stack-layout" type="owo-ui-stack-layout"/>
            <xs:element name="scroll" type="owo-ui-scroll-container"/>
            <xs:element name="dropdown" type="owo-ui-dropdown-component"/>
            <xs:element name="color-picker" type="owo-ui-color-picker-component"/>
            <xs:element name="small-checkbox" type="owo-ui-small-checkbox-component"/>
            <xs:element name="slim-slider" type="owo-ui-slim-slider-component"/>
            <xs:element name="text-area" type="owo-ui-text-area-component"/>
            <xs:element name="spacer" type="owo-ui-spacer-component"/>
            <xs:element name="template">
                <xs:complexType>
                    <xs:sequence minOccurs="0" maxOccurs="unbounded">
                        <xs:any processContents="lax"/>
                    </xs:sequence>
                    <xs:attribute name="name" type="xs:string" use="required"/>
                </xs:complexType>
            </xs:element>
            <xs:any processContents="lax"/>
        </xs:choice>
    </xs:group>

    <xs:complexType name="componentList">
        <xs:choice maxOccurs="unbounded" minOccurs="0">
            <xs:group ref="anyComponent"/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="owo-ui-insets">
        <xs:annotation>
            <xs:documentation>
                Insets describing an offset on each side of a rectangle.
                Elements which occur after one another override each other, meaning
                that a `bottom` element after an `all` element will only redefine
                the bottom offset and leave the rest intact
            </xs:documentation>
        </xs:annotation>

        <xs:all>
            <xs:element type="xs:integer" name="top" minOccurs="0"/>
            <xs:element type="xs:integer" name="bottom" minOccurs="0"/>
            <xs:element type="xs:integer" name="left" minOccurs="0"/>
            <xs:element type="xs:integer" name="right" minOccurs="0"/>
            <xs:element type="xs:integer" name="all" minOccurs="0"/>
            <xs:element type="xs:integer" name="horizontal" minOccurs="0"/>
            <xs:element type="xs:integer" name="vertical" minOccurs="0"/>
        </xs:all>
    </xs:complexType>

    <xs:simpleType name="positioningValueType">
        <xs:restriction base="xs:string">
            <xs:pattern value="-?\d+,-?\d+"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="owo-ui-positioning">
        <xs:annotation>
            <xs:documentation>
                Any of the three positioning types supported by owo-ui,
                with the content formatted as `{horizontal},{vertical}`, eg `25,50`
            </xs:documentation>
        </xs:annotation>

        <xs:simpleContent>
            <xs:extension base="positioningValueType">
                <xs:attribute name="type" use="required">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:enumeration value="absolute"/>
                            <xs:enumeration value="relative"/>
                            <xs:enumeration value="layout"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:attribute>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="sizingDeclarationType">
        <xs:simpleContent>
            <xs:extension base="xs:integer">
                <xs:attribute name="method" use="required">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:enumeration value="content"/>
                            <xs:enumeration value="fixed"/>
                            <xs:enumeration value="fill"/>
                            <xs:enumeration value="expand"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:attribute>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-sizing">
        <xs:annotation>
            <xs:documentation>
                A container for the horizontal and vertical sizing
                declaration, each of which may occur once
            </xs:documentation>
        </xs:annotation>

        <xs:all>
            <xs:element name="horizontal" type="sizingDeclarationType" minOccurs="0"/>
            <xs:element name="vertical" type="sizingDeclarationType" minOccurs="0"/>
        </xs:all>
    </xs:complexType>

    <xs:complexType name="owo-ui-text">
        <xs:annotation>
            <xs:documentation>
                Some literal or translated text, depending on whether
                the `translate` attribute is `true`
            </xs:documentation>
        </xs:annotation>

        <xs:simpleContent>
            <xs:extension base="xs:string">
                <xs:attribute name="translate">
                    <xs:simpleType>
                        <xs:restriction base="xs:boolean"/>
                    </xs:simpleType>
                </xs:attribute>
            </xs:extension>
        </xs:simpleContent>
    </xs:complexType>

    <xs:simpleType name="owo-ui-color">
        <xs:annotation>
            <xs:documentation>
                A standard integer color in either `#AARRGGBB` or `#RRGGBB` format.
                Alternatively, the all-lowercase name of any of Minecraft's 16 text colors
            </xs:documentation>
        </xs:annotation>

        <xs:union>
            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:pattern value="#([A-Fa-f\d]{2}){3,4}"/>
                </xs:restriction>
            </xs:simpleType>

            <xs:simpleType>
                <xs:restriction base="xs:string">
                    <xs:enumeration value="black"/>
                    <xs:enumeration value="dark-blue"/>
                    <xs:enumeration value="dark-green"/>
                    <xs:enumeration value="dark-aqua"/>
                    <xs:enumeration value="dark-red"/>
                    <xs:enumeration value="dark-purple"/>
                    <xs:enumeration value="gold"/>
                    <xs:enumeration value="gray"/>
                    <xs:enumeration value="dark-gray"/>
                    <xs:enumeration value="blue"/>
                    <xs:enumeration value="green"/>
                    <xs:enumeration value="aqua"/>
                    <xs:enumeration value="red"/>
                    <xs:enumeration value="light-purple"/>
                    <xs:enumeration value="yellow"/>
                    <xs:enumeration value="white"/>
                </xs:restriction>
            </xs:simpleType>
        </xs:union>
    </xs:simpleType>

    <xs:simpleType name="owo-ui-vertical-alignment">
        <xs:restriction base="xs:string">
            <xs:enumeration value="top"/>
            <xs:enumeration value="center"/>
            <xs:enumeration value="bottom"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="owo-ui-horizontal-alignment">
        <xs:restriction base="xs:string">
            <xs:enumeration value="left"/>
            <xs:enumeration value="center"/>
            <xs:enumeration value="right"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:complexType name="owo-ui-surface">
        <xs:annotation>
            <xs:documentation>
                One or multiple surfaces chained together. If multiple surfaces
                appear in this declaration, they are chained together in order of
                appearance via the `and(...)` method
            </xs:documentation>
        </xs:annotation>

        <xs:choice maxOccurs="unbounded">
            <xs:element name="panel">
                <xs:annotation>
                    <xs:documentation>
                        A standard Minecraft panel, optionally with a dark texture
                    </xs:documentation>
                </xs:annotation>
                <xs:complexType>
                    <xs:attribute name="dark" type="xs:boolean"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="panel-inset">
                <xs:annotation>
                    <xs:documentation>
                        An inset into a panel, used to create an area
                        enclosed by a standard light panel
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="panel-with-inset" type="xs:unsignedInt">
                <xs:annotation>
                    <xs:documentation>
                        A panel inset bordered by a standard light panel
                        of the specified width on each border
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="tiled">
                <xs:annotation>
                    <xs:documentation>
                        A simple surface repeating the given texture, just like the
                        options background does with the dirt texture
                    </xs:documentation>
                </xs:annotation>
                <xs:complexType>
                    <xs:simpleContent>
                        <xs:extension base="minecraft-identifier">
                            <xs:attribute name="texture-width" type="xs:unsignedInt"/>
                            <xs:attribute name="texture-height" type="xs:unsignedInt"/>
                        </xs:extension>
                    </xs:simpleContent>
                </xs:complexType>
            </xs:element>
            <xs:element name="blur">
                <xs:annotation>
                    <xs:documentation>
                        A simple, colorless surface that blurs everything
                        underneath itself
                    </xs:documentation>
                </xs:annotation>
                <xs:complexType>
                    <xs:attribute name="quality" type="xs:float" use="required"/>
                    <xs:attribute name="size" type="xs:float" use="required"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="options-background">
                <xs:annotation>
                    <xs:documentation>
                        The standard Minecraft options background,
                        usually a repeating dirt texture
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="vanilla-translucent">
                <xs:annotation>
                    <xs:documentation>
                        The standard dark translucent background
                        most Vanilla UIs use
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element name="tooltip">
                <xs:annotation>
                    <xs:documentation>
                        The same renderer used by vanilla item
                        and UI element tooltips
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element type="owo-ui-color" name="outline">
                <xs:annotation>
                    <xs:documentation>
                        A simple rectangular outline of the specified color
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
            <xs:element type="owo-ui-color" name="flat">
                <xs:annotation>
                    <xs:documentation>
                        A flat rectangle of the specified color
                    </xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="owo-ui-scrollbar">
        <xs:choice>
            <xs:element type="owo-ui-color" name="flat"/>
            <xs:element name="vanilla"/>
            <xs:element name="vanilla-flat"/>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="owo-ui-dropdown-entries">
        <xs:choice maxOccurs="unbounded">
            <xs:element name="divider"/>
            <xs:element type="owo-ui-text" name="text"/>
            <xs:element name="button">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element type="owo-ui-text" name="text"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="checkbox">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element type="owo-ui-text" name="text"/>
                        <xs:element type="xs:boolean" name="checked"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="nested">
                <xs:complexType>
                    <xs:complexContent>
                        <xs:extension base="owo-ui-dropdown-entries">
                            <xs:attribute type="xs:string" name="name"/>
                            <xs:attribute type="xs:boolean" name="translate"/>
                        </xs:extension>
                    </xs:complexContent>
                </xs:complexType>
            </xs:element>
        </xs:choice>
    </xs:complexType>

    <xs:complexType name="owo-ui-button-renderer">
        <xs:choice>
            <xs:element name="vanilla"/>
            <xs:element name="flat">
                <xs:complexType>
                    <xs:attribute type="owo-ui-color" name="color" use="required"/>
                    <xs:attribute type="owo-ui-color" name="hovered-color" use="required"/>
                    <xs:attribute type="owo-ui-color" name="disabled-color" use="required"/>
                </xs:complexType>
            </xs:element>
            <xs:element name="texture">
                <xs:complexType>
                    <xs:attribute type="minecraft-identifier" name="texture" use="required"/>
                    <xs:attribute type="xs:unsignedInt" name="u" use="required"/>
                    <xs:attribute type="xs:unsignedInt" name="v" use="required"/>
                    <xs:attribute type="xs:unsignedInt" name="texture-width" use="required"/>
                    <xs:attribute type="xs:unsignedInt" name="texture-height" use="required"/>
                </xs:complexType>
            </xs:element>
        </xs:choice>
    </xs:complexType>

    <xs:simpleType name="owo-ui-axis-direction">
        <xs:restriction base="xs:string">
            <xs:enumeration value="vertical"/>
            <xs:enumeration value="horizontal"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:simpleType name="minecraft-identifier">
        <xs:annotation>
            <xs:documentation>
                A standard Minecraft identifier, optionally with the
                namespace omitted and defaulted to `minecraft`
            </xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:pattern value="([a-z0-9_.-]+:)?[a-z0-9/._-]+"/>
        </xs:restriction>
    </xs:simpleType>

    <xs:group name="componentProps">
        <xs:choice>
            <xs:element type="owo-ui-insets" name="margins" minOccurs="0"/>
            <xs:element type="owo-ui-positioning" name="positioning" minOccurs="0"/>
            <xs:element type="owo-ui-sizing" name="sizing" minOccurs="0"/>
            <xs:element type="owo-ui-text" name="tooltip-text" minOccurs="0"/>
            <xs:element name="cursor-style" minOccurs="0">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:enumeration value="pointer"/>
                        <xs:enumeration value="text"/>
                        <xs:enumeration value="hand"/>
                        <xs:enumeration value="move"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:element>
        </xs:choice>
    </xs:group>

    <xs:group name="parentComponentProps">
        <xs:choice>
            <xs:group ref="componentProps" maxOccurs="unbounded"/>
            <xs:element type="owo-ui-insets" name="padding" minOccurs="0"/>
            <xs:element type="owo-ui-surface" name="surface" minOccurs="0"/>
            <xs:element type="owo-ui-horizontal-alignment" name="horizontal-alignment" minOccurs="0"/>
            <xs:element type="owo-ui-vertical-alignment" name="vertical-alignment" minOccurs="0"/>
            <xs:element type="xs:boolean" name="allow-overflow" minOccurs="0"/>
        </xs:choice>
    </xs:group>

    <xs:group name="vanillaWidgetProps">
        <xs:choice>
            <xs:group ref="parentComponentProps" maxOccurs="unbounded"/>
            <xs:element type="xs:boolean" name="active" minOccurs="0"/>
        </xs:choice>
    </xs:group>

    <xs:complexType name="componentType">
        <xs:attribute name="id"/>
    </xs:complexType>

    <xs:complexType name="owo-ui-label-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="componentProps"/>
                    <xs:element type="owo-ui-text" name="text" minOccurs="0"/>
                    <xs:element type="xs:unsignedInt" name="max-width" minOccurs="0"/>
                    <xs:element type="xs:unsignedInt" name="line-height" minOccurs="0"/>
                    <xs:element type="xs:unsignedInt" name="line-spacing" minOccurs="0"/>
                    <xs:element type="owo-ui-color" name="color" minOccurs="0"/>
                    <xs:element type="xs:boolean" name="shadow" minOccurs="0"/>
                    <xs:element type="owo-ui-vertical-alignment" name="vertical-text-alignment" minOccurs="0"/>
                    <xs:element type="owo-ui-horizontal-alignment" name="horizontal-text-alignment" minOccurs="0"/>
                </xs:choice>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-spacer-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:group ref="componentProps"/>
                <xs:attribute name="percent" type="xs:unsignedInt"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-box-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="componentProps"/>
                    <xs:choice minOccurs="0">
                        <xs:element type="owo-ui-color" name="color"/>
                        <xs:sequence>
                            <xs:element type="owo-ui-color" name="start-color"/>
                            <xs:element type="owo-ui-color" name="end-color"/>
                        </xs:sequence>
                    </xs:choice>
                    <xs:element type="xs:boolean" name="fill" minOccurs="0"/>
                    <xs:element name="direction" minOccurs="0">
                        <xs:simpleType>
                            <xs:restriction base="xs:string">
                                <xs:enumeration value="top-to-bottom"/>
                                <xs:enumeration value="left-to-right"/>
                                <xs:enumeration value="right-to-left"/>
                                <xs:enumeration value="bottom-to-top"/>
                            </xs:restriction>
                        </xs:simpleType>
                    </xs:element>
                </xs:choice>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-checkbox-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="vanillaWidgetProps"/>
                    <xs:element type="xs:boolean" name="checked" minOccurs="0"/>
                    <xs:element type="owo-ui-text" name="text" minOccurs="0"/>
                </xs:choice>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-button-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="vanillaWidgetProps"/>
                    <xs:element type="owo-ui-text" name="text" minOccurs="0"/>
                    <xs:element type="owo-ui-button-renderer" name="renderer" minOccurs="0"/>
                </xs:choice>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-textured-button-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="vanillaWidgetProps"/>
                    <xs:element type="owo-ui-text" name="text" minOccurs="0"/>
                </xs:choice>
                <xs:attribute name="texture" type="minecraft-identifier" use="required"/>
                <xs:attribute name="width" type="xs:integer" use="required"/>
                <xs:attribute name="height" type="xs:integer" use="required"/>
                <xs:attribute name="u" type="xs:integer"/>
                <xs:attribute name="v" type="xs:integer"/>
                <xs:attribute name="texture-width" type="xs:integer"/>
                <xs:attribute name="texture-height" type="xs:integer"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-text-field-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="vanillaWidgetProps"/>
                    <xs:element type="xs:string" name="text" minOccurs="0"/>
                    <xs:element type="xs:unsignedInt" name="max-length" minOccurs="0"/>
                    <xs:element type="xs:boolean" name="show-background" minOccurs="0"/>
                </xs:choice>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-text-area-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="vanillaWidgetProps"/>
                    <xs:element type="xs:string" name="text" minOccurs="0"/>
                    <xs:element type="xs:unsignedInt" name="max-length" minOccurs="0"/>
                    <xs:element type="xs:unsignedInt" name="max-lines" minOccurs="0"/>
                    <xs:element type="xs:boolean" name="display-char-count" minOccurs="0"/>
                </xs:choice>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-color-picker-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="componentProps"/>
                    <xs:element type="xs:unsignedInt" name="selector-width" minOccurs="0"/>
                    <xs:element type="xs:unsignedInt" name="selector-padding" minOccurs="0"/>
                    <xs:element type="xs:boolean" name="show-alpha" minOccurs="0"/>
                    <xs:element type="owo-ui-color" name="selected-color" minOccurs="0"/>
                </xs:choice>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-small-checkbox-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="componentProps"/>
                    <xs:element type="owo-ui-text" name="label" minOccurs="0"/>
                    <xs:element type="xs:boolean" name="label-shadow" minOccurs="0"/>
                    <xs:element type="xs:boolean" name="checked" minOccurs="0"/>
                </xs:choice>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-slim-slider-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="componentProps"/>
                    <xs:element type="xs:double" name="step-size" minOccurs="0"/>
                    <xs:element type="xs:double" name="min" minOccurs="0"/>
                    <xs:element type="xs:double" name="max" minOccurs="0"/>
                    <xs:element type="xs:double" name="value" minOccurs="0"/>
                </xs:choice>
                <xs:attribute name="direction" type="owo-ui-axis-direction" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-slider-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="vanillaWidgetProps"/>
                    <xs:element type="owo-ui-text" name="text" minOccurs="0"/>
                    <xs:element type="xs:double" name="value" minOccurs="0"/>
                </xs:choice>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-discrete-slider-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="vanillaWidgetProps"/>
                    <xs:element type="xs:unsignedInt" name="decimal-places" minOccurs="0"/>
                    <xs:element type="xs:double" name="value" minOccurs="0"/>
                </xs:choice>
                <xs:attribute name="min" type="xs:double" use="required"/>
                <xs:attribute name="max" type="xs:double" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-entity-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="componentProps"/>
                    <xs:element type="xs:float" name="scale" minOccurs="0"/>
                    <xs:element type="xs:boolean" name="look-at-cursor" minOccurs="0"/>
                    <xs:element type="xs:boolean" name="mouse-rotation" minOccurs="0"/>
                    <xs:element type="xs:boolean" name="scale-to-fit" minOccurs="0"/>
                </xs:choice>
                <xs:attribute name="type" type="xs:string" use="required"/>
                <xs:attribute name="nbt" type="xs:string"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-item-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="componentProps"/>
                    <xs:element type="xs:string" name="stack" minOccurs="0"/>
                    <xs:element type="xs:boolean" name="show-overlay" minOccurs="0"/>
                    <xs:element type="xs:boolean" name="set-tooltip-from-stack" minOccurs="0"/>
                </xs:choice>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-block-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:group ref="componentProps"/>
                <xs:attribute name="state" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-sprite-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice>
                    <xs:group ref="componentProps"/>
                    <xs:element name="blend" type="xs:boolean" minOccurs="0"/>
                </xs:choice>
                <xs:attribute name="atlas" type="minecraft-identifier" use="required"/>
                <xs:attribute name="sprite" type="minecraft-identifier" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-texture-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:choice maxOccurs="unbounded">
                    <xs:group ref="componentProps"/>
                    <xs:element name="blend" type="xs:boolean" minOccurs="0"/>
                    <xs:element name="visible-area" minOccurs="0">
                        <xs:complexType>
                            <xs:all>
                                <xs:element name="x" type="xs:unsignedInt" minOccurs="0"/>
                                <xs:element name="y" type="xs:unsignedInt" minOccurs="0"/>
                                <xs:element name="width" type="xs:unsignedInt" minOccurs="0"/>
                                <xs:element name="height" type="xs:unsignedInt" minOccurs="0"/>
                            </xs:all>
                        </xs:complexType>
                    </xs:element>
                </xs:choice>
                <xs:attribute name="texture" type="minecraft-identifier" use="required"/>
                <xs:attribute name="u" type="xs:integer"/>
                <xs:attribute name="v" type="xs:integer"/>
                <xs:attribute name="region-width" type="xs:integer"/>
                <xs:attribute name="region-height" type="xs:integer"/>
                <xs:attribute name="texture-width" type="xs:integer"/>
                <xs:attribute name="texture-height" type="xs:integer"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-dropdown-component">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:sequence>
                    <xs:choice maxOccurs="unbounded">
                        <xs:group ref="parentComponentProps"/>
                        <xs:element type="xs:boolean" name="close-when-not-hovered" minOccurs="0"/>
                        <xs:element type="owo-ui-dropdown-entries" name="entries" minOccurs="0"/>
                    </xs:choice>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-flow-layout">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:sequence>
                    <xs:element type="componentList" name="children"/>
                    <xs:choice maxOccurs="unbounded">
                        <xs:element type="xs:integer" name="gap" minOccurs="0"/>
                        <xs:group ref="parentComponentProps" maxOccurs="unbounded"/>
                    </xs:choice>
                </xs:sequence>
                <xs:attribute name="direction" use="required">
                    <xs:simpleType>
                        <xs:restriction base="xs:string">
                            <xs:enumeration value="vertical"/>
                            <xs:enumeration value="horizontal"/>
                            <xs:enumeration value="ltr-text-flow"/>
                        </xs:restriction>
                    </xs:simpleType>
                </xs:attribute>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-grid-layout">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:sequence>
                    <xs:element type="componentList" name="children"/>
                    <xs:group ref="parentComponentProps" maxOccurs="unbounded"/>
                </xs:sequence>
                <xs:attribute name="rows" type="xs:unsignedInt" use="required"/>
                <xs:attribute name="columns" type="xs:unsignedInt" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-stack-layout">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:sequence>
                    <xs:element type="componentList" name="children"/>
                    <xs:group ref="parentComponentProps" maxOccurs="unbounded"/>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-collapsible-container">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:sequence>
                    <xs:element type="componentList" name="children"/>
                    <xs:choice maxOccurs="unbounded">
                        <xs:group ref="parentComponentProps"/>
                        <xs:element type="owo-ui-text" name="text" minOccurs="0"/>
                    </xs:choice>
                </xs:sequence>
                <xs:attribute name="expanded" type="xs:boolean"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-draggable-container">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:sequence>
                    <xs:group ref="anyComponent"/>
                    <xs:choice maxOccurs="unbounded">
                        <xs:group ref="parentComponentProps"/>
                        <xs:element type="xs:unsignedInt" name="forehead-size" minOccurs="0"/>
                    </xs:choice>
                </xs:sequence>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>

    <xs:complexType name="owo-ui-scroll-container">
        <xs:complexContent>
            <xs:extension base="componentType">
                <xs:sequence>
                    <xs:group ref="anyComponent"/>
                    <xs:choice maxOccurs="unbounded">
                        <xs:group ref="parentComponentProps"/>
                        <xs:element type="xs:unsignedInt" name="scrollbar-thiccness" minOccurs="0"/>
                        <xs:element type="xs:unsignedInt" name="fixed-scrollbar-length" minOccurs="0"/>
                        <xs:element type="owo-ui-color" name="scrollbar-color" minOccurs="0"/>
                        <xs:element type="owo-ui-scrollbar" name="scrollbar" minOccurs="0"/>
                    </xs:choice>
                </xs:sequence>
                <xs:attribute name="direction" type="owo-ui-axis-direction" use="required"/>
            </xs:extension>
        </xs:complexContent>
    </xs:complexType>
</xs:schema>

================================================
FILE: settings.gradle
================================================
pluginManagement {
    repositories {
        maven {
            name = 'Fabric'
            url = 'https://maven.fabricmc.net/'
        }
        gradlePluginPortal()
    }
}

include 'owo-sentinel'

================================================
FILE: src/main/java/io/wispforest/owo/Owo.java
================================================
package io.wispforest.owo;

import io.wispforest.owo.client.screens.MenuNetworkingInternals;
import io.wispforest.owo.command.debug.OwoDebugCommands;
import io.wispforest.owo.ops.LootOps;
import io.wispforest.owo.text.CustomTextRegistry;
import io.wispforest.owo.text.InsertingTextContent;
import io.wispforest.owo.util.Wisdom;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.Identifier;
import net.minecraft.server.MinecraftServer;
import org.jetbrains.annotations.ApiStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static io.wispforest.owo.ops.TextOps.withColor;

public class Owo implements ModInitializer {

    public static final String MOD_ID = "owo";
    /**
     * Whether oωo debug is enabled, this defaults to {@code true} in a development environment.
     * To override that behavior, add the {@code -Dowo.debug=false} java argument
     */
    public static final boolean DEBUG;
    public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID);
    private static MinecraftServer SERVER;

    public static final Component PREFIX = Component.empty().withStyle(ChatFormatting.GRAY)
        .append(withColor("o", 0x3955e5))
        .append(withColor("ω", 0x13a6f0))
        .append(withColor("o", 0x3955e5))
        .append(Component.literal(" > ").withStyle(ChatFormatting.GRAY));

    static {
        boolean debug = FabricLoader.getInstance().isDevelopmentEnvironment();
        if (System.getProperty("owo.debug") != null) debug = Boolean.getBoolean("owo.debug");
        if (Boolean.getBoolean("owo.forceDisableDebug")) {
            LOGGER.warn("Deprecated system property 'owo.forceDisableDebug=true' was used - use 'owo.debug=false' instead");
            debug = false;
        }

        DEBUG = debug;
    }

    @Override
    @ApiStatus.Internal
    public void onInitialize() {
        LootOps.registerListener();
        CustomTextRegistry.register("index", InsertingTextContent.CODEC);
        MenuNetworkingInternals.init();

        ServerLifecycleEvents.SERVER_STARTING.register(server -> SERVER = server);
        ServerLifecycleEvents.SERVER_STOPPED.register(server -> SERVER = null);

        Wisdom.spread();

        if (!DEBUG) return;

        OwoDebugCommands.register();
    }

    @ApiStatus.Internal
    public static void debugWarn(Logger logger, String message) {
        if (!DEBUG) return;
        logger.warn(message);
    }

    @ApiStatus.Internal
    public static void debugWarn(Logger logger, String message, Object... params) {
        if (!DEBUG) return;
        logger.warn(message, params);
    }

    /**
     * @return The currently active minecraft server instance. If running
     * on a physical client, this will return the integrated server while in
     * a local singleplayer world and {@code null} otherwise
     */
    public static MinecraftServer currentServer() {
        return SERVER;
    }

    // "eh it's only like 10-15 of them what's the big deal" - glisco, while writing the 52nd hardcoded Identifier.of("owo", ...)
    @ApiStatus.Internal
    public static Identifier id(String path) {
        return Identifier.fromNamespaceAndPath(MOD_ID, path);
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/blockentity/LinearProcess.java
================================================
package io.wispforest.owo.blockentity;

import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.world.level.Level;

import java.util.function.BiConsumer;
import java.util.function.Predicate;

/**
 * Represents a process made of steps than can be executed tick by tick using a respective
 * {@link LinearProcessExecutor}. This can, for example, be used on BlockEntities that perform
 * rituals or similar activities that are made of consecutive steps.
 * <p>
 * A process defines the pattern of steps and events that shall be followed, thus there is one (usually static)
 * instance of it. You then create a new instance of {@link LinearProcessExecutor} using the
 * {@link #createExecutor(Object)} method for each instance of your BlockEntity of whatever else if supposed to run it
 * <p>
 * To create a new process, call {@link #LinearProcess(int)} with the length it should have. A process always has the same
 * length. Then, in the constructor of each object that will use an executor, use {@link #createExecutor(Object)} to
 * obtain an instance. This then has to be told whether it lives on the client or server using
 * {@link #configureExecutor(LinearProcessExecutor, boolean)}. On a BlockEntity this can be achieved by overriding
 * {@link net.minecraft.world.level.block.entity.BlockEntity#setLevel(Level)} and configuring after the super call using the provided
 * world
 * <p>
 * Steps and events should be added to process once, ideally in the {@code static} initializer block of the containing class.
 * After the process is complete, call {@link #finish()} to prevent further changes
 *
 * @param <T> The type of object this process will be executed on,
 *            a {@link net.minecraft.world.level.block.entity.BlockEntity} in most cases
 */
public class LinearProcess<T> {

    private final Int2ObjectMap<BiConsumer<LinearProcessExecutor<T>, T>> clientEventTable = new Int2ObjectOpenHashMap<>();
    private final Int2ObjectMap<LinearProcessExecutor.ProcessStep<T>> clientProcessStepTable = new Int2ObjectOpenHashMap<>();

    private final Int2ObjectMap<BiConsumer<LinearProcessExecutor<T>, T>> serverEventTable = new Int2ObjectOpenHashMap<>();
    private final Int2ObjectMap<LinearProcessExecutor.ProcessStep<T>> serverProcessStepTable = new Int2ObjectOpenHashMap<>();

    private Predicate<LinearProcessExecutor<T>> condition = tLinearProcessExecutor -> true;

    private final int processLength;
    private boolean finished = false;

    /**
     * Creates a new process
     *
     * @param processLength The length of the process. This is immutable
     */
    public LinearProcess(int processLength) {
        this.processLength = processLength;
    }

    /**
     * Creates a new executor for the given target object
     *
     * @param target The object the executor should operate on
     * @return The created executor. This is not ready for use yet
     * @see #configureExecutor(LinearProcessExecutor, boolean)
     */
    public LinearProcessExecutor<T> createExecutor(T target) {
        if (!finished) throw new IllegalStateException("Illegal attempt to create executor for unfinished process");
        return new LinearProcessExecutor<>(target, processLength, condition, serverProcessStepTable);
    }

    /**
     * Configures an executor to use either the
     * server or client instructions
     *
     * @param executor The executor to configure
     * @param client   {@code true} if the client instructions should be used
     */
    public void configureExecutor(LinearProcessExecutor<T> executor, boolean client) {
        if (!finished) throw new IllegalStateException("Illegal attempt to configure executor using unfinished process");

        if (client) {
            executor.configure(clientEventTable, clientProcessStepTable);
        } else {
            executor.configure(serverEventTable, serverProcessStepTable);
        }
    }

    /**
     * Adds a new step to this process on both client and server
     *
     * @param when     When the step should start
     * @param length   How long it should last
     * @param executor The code to be run each tick while the step is active
     */
    public void addCommonStep(int when, int length, BiConsumer<LinearProcessExecutor<T>, T> executor) {
        checkForIllegalModification();
        var step = new LinearProcessExecutor.ProcessStep<>(length, executor);
        clientProcessStepTable.put(when, step);
        serverProcessStepTable.put(when, step);
    }

    /**
     * @see #addCommonStep(int, int, BiConsumer)
     */
    public void addClientStep(int when, int length, BiConsumer<LinearProcessExecutor<T>, T> executor) {
        checkForIllegalModification();
        var step = new LinearProcessExecutor.ProcessStep<>(length, executor);
        clientProcessStepTable.put(when, step);
    }

    /**
     * @see #addCommonStep(int, int, BiConsumer)
     */
    public void addServerStep(int when, int length, BiConsumer<LinearProcessExecutor<T>, T> executor) {
        checkForIllegalModification();
        var step = new LinearProcessExecutor.ProcessStep<>(length, executor);
        serverProcessStepTable.put(when, step);
    }

    /**
     * Adds an event that is executed once, on both client and server
     *
     * @param when     When the event should occur
     * @param executor The code to be run on the given tick
     * @see #addClientEvent(int, BiConsumer)
     * @see #addServerEvent(int, BiConsumer)
     */
    public void addCommonEvent(int when, BiConsumer<LinearProcessExecutor<T>, T> executor) {
        eventAtIndex(when, clientEventTable, executor);
        eventAtIndex(when, serverEventTable, executor);
    }

    /**
     * @see #addCommonEvent(int, BiConsumer)
     */
    public void addClientEvent(int when, BiConsumer<LinearProcessExecutor<T>, T> executor) {
        eventAtIndex(when, clientEventTable, executor);
    }

    /**
     * @see #addCommonEvent(int, BiConsumer)
     */
    public void addServerEvent(int when, BiConsumer<LinearProcessExecutor<T>, T> executor) {
        eventAtIndex(when, serverEventTable, executor);
    }

    /**
     * Defines code to be run when this process has successfully
     * finished, on both client and server
     *
     * @param executor The code to be run
     * @see #whenFinishedClient(BiConsumer)
     * @see #whenFinishedServer(BiConsumer)
     */
    public void whenFinishedCommon(BiConsumer<LinearProcessExecutor<T>, T> executor) {
        eventAtIndex(LinearProcessExecutor.FINISH_EVENT_INDEX, clientEventTable, executor);
        eventAtIndex(LinearProcessExecutor.FINISH_EVENT_INDEX, serverEventTable, executor);
    }

    /**
     * @see #whenFinishedCommon(BiConsumer)
     */
    public void whenFinishedServer(BiConsumer<LinearProcessExecutor<T>, T> executor) {
        eventAtIndex(LinearProcessExecutor.FINISH_EVENT_INDEX, serverEventTable, executor);
    }

    /**
     * @see #whenFinishedCommon(BiConsumer)
     */
    public void whenFinishedClient(BiConsumer<LinearProcessExecutor<T>, T> executor) {
        eventAtIndex(LinearProcessExecutor.FINISH_EVENT_INDEX, clientEventTable, executor);
    }

    /**
     * Defines code to be run on both client and server when this process
     * is unexpectedly cancelled mid-execution, use this to clean up after you.
     *
     * @param executor The code to be run
     * @see #onCancelledClient(BiConsumer)
     * @see #onCancelledServer(BiConsumer)
     */
    public void onCancelledCommon(BiConsumer<LinearProcessExecutor<T>, T> executor) {
        eventAtIndex(LinearProcessExecutor.CANCEL_EVENT_INDEX, clientEventTable, executor);
        eventAtIndex(LinearProcessExecutor.CANCEL_EVENT_INDEX, serverEventTable, executor);
    }

    /**
     * @see #onCancelledCommon(BiConsumer)
     */
    public void onCancelledServer(BiConsumer<LinearProcessExecutor<T>, T> executor) {
        eventAtIndex(LinearProcessExecutor.CANCEL_EVENT_INDEX, serverEventTable, executor);
    }

    /**
     * @see #onCancelledCommon(BiConsumer)
     */
    public void onCancelledClient(BiConsumer<LinearProcessExecutor<T>, T> executor) {
        eventAtIndex(LinearProcessExecutor.CANCEL_EVENT_INDEX, clientEventTable, executor);
    }

    /**
     * Defines a condition that has to be met every tick this process runs,
     * otherwise it cancels itself
     *
     * @param condition The condition that should be satisfied during the entire
     *                  process execution
     */
    public void runConditionally(Predicate<LinearProcessExecutor<T>> condition) {
        this.condition = condition;
    }

    /**
     * Marks this process and completely built and ready for execution
     */
    public void finish() {
        this.finished = true;
    }

    private void checkForIllegalModification() {
        if (finished) throw new IllegalStateException("Illegal attempt to modify finished process");
    }

    private void eventAtIndex(int index, Int2ObjectMap<BiConsumer<LinearProcessExecutor<T>, T>> eventTable, BiConsumer<LinearProcessExecutor<T>, T> executor) {
        checkForIllegalModification();
        eventTable.put(index, executor);
    }

}


================================================
FILE: src/main/java/io/wispforest/owo/blockentity/LinearProcessExecutor.java
================================================
package io.wispforest.owo.blockentity;

import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.nbt.CompoundTag;
import org.jetbrains.annotations.ApiStatus;

import java.util.HashSet;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Predicate;

/**
 * A handler that executes the steps defined in a {@link LinearProcess}. Each object that is
 * supposed to run the process needs an instance of this, and each instance of this refers back
 * to the object it operates on
 *
 * @param <T> The type of object this executor operates on
 */
public class LinearProcessExecutor<T> {

    public static final int CANCEL_EVENT_INDEX = -1;
    public static final int FINISH_EVENT_INDEX = -2;

    private final T target;
    private final int processLength;

    private final Predicate<LinearProcessExecutor<T>> condition;
    private Int2ObjectMap<BiConsumer<LinearProcessExecutor<T>, T>> eventTable;
    private Int2ObjectMap<ProcessStep<T>> processStepTable;

    private final Set<ProcessStep.Info<T>> activeSteps = new HashSet<>();

    private int processTick = 0;

    protected LinearProcessExecutor(T target, int processLength, Predicate<LinearProcessExecutor<T>> condition, Int2ObjectMap<ProcessStep<T>> serverStepTable) {
        this.target = target;
        this.processLength = processLength;
        this.condition = condition;
        this.eventTable = null;
        this.processStepTable = serverStepTable;
    }

    protected void configure(Int2ObjectMap<BiConsumer<LinearProcessExecutor<T>, T>> eventTable, Int2ObjectMap<ProcessStep<T>> processStepTable) {
        this.eventTable = eventTable;
        this.processStepTable = processStepTable;
    }

    public void tick() {
        if (this.eventTable == null) throw new IllegalStateException("Illegal attempt to tick unconfigured executor");

        if (!this.running()) return;

        if (this.cancelIfAppropriate()) return;
        if (this.finishIfAppropriate()) return;

        int tableIndex = processTick - 1;

        if (this.eventTable.containsKey(tableIndex)) this.eventTable.get(tableIndex).accept(this, this.target);
        if (this.processStepTable.containsKey(tableIndex)) this.activeSteps.add(this.processStepTable.get(tableIndex).createInfo(tableIndex));

        this.activeSteps.removeIf(stepInfo -> !stepInfo.tick(this));

        this.processTick++;
    }

    /**
     * Attempts to begin execution
     *
     * @return {@code true} if execution will start next tick,
     * {@code false} if execution is already running
     */
    public boolean begin() {
        if (this.processTick != 0) return false;

        this.processTick = 1;
        return true;
    }

    /**
     * @return {@code true} if this executor is currently running
     */
    @SuppressWarnings("BooleanMethodIsAlwaysInverted")
    public boolean running() {
        return this.processTick > 0;
    }

    /**
     * @return The last processing tick this executor completed
     */
    public int getProcessTick() {
        return processTick;
    }

    /**
     * @return The object this executor is operating on
     */
    public T getTarget() {
        return target;
    }

    /**
     * Attempts to instantly cancel execution
     *
     * @return {@code true} if execution was successfully cancelled,
     * {@code false} if this executor was not running
     */
    public boolean cancel() {
        if (!this.running()) return false;

        this.processTick = 0;
        this.activeSteps.clear();

        if (this.eventTable.containsKey(CANCEL_EVENT_INDEX)) this.eventTable.get(CANCEL_EVENT_INDEX).accept(this, this.target);

        return true;
    }

    private boolean finishIfAppropriate() {
        if (!this.running()) return false;
        if (this.processTick < processLength) return false;

        if (this.eventTable.containsKey(FINISH_EVENT_INDEX)) this.eventTable.get(FINISH_EVENT_INDEX).accept(this, this.target);

        this.processTick = 0;
        this.activeSteps.clear();
        return true;
    }

    private boolean cancelIfAppropriate() {
        if (this.condition.test(this)) return false;
        this.cancel();
        return true;
    }

    /**
     * Saves the state of this executor
     *
     * @param targetTag The nbt to write state into
     */
    public void writeState(CompoundTag targetTag) {
        targetTag.putInt("ProcessTick", processTick);
    }

    /**
     * Restores the saved state of this executor
     *
     * @param targetTag The nbt to read state from
     */
    public void readState(CompoundTag targetTag) {
        this.processTick = targetTag.getIntOr("ProcessTick", 0);

        activeSteps.clear();
        processStepTable.forEach((index, step) -> {
            if (processTick >= index && processTick <= index + step.length) {
                activeSteps.add(step.createInfo(index, processTick - index));
            }
        });
    }

    @ApiStatus.Internal
    public record ProcessStep<T>(int length, BiConsumer<LinearProcessExecutor<T>, T> executor) {

        public Info<T> createInfo(int index) {
            return new Info<>(index, this);
        }

        public Info<T> createInfo(int index, int tick) {
            return new Info<>(index, tick, this);
        }

        public static final class Info<T> {

            private final ProcessStep<T> step;
            private final int index;

            private int tick = 0;

            public Info(int index, ProcessStep<T> step) {
                this.index = index;
                this.step = step;
            }

            public Info(int index, int tick, ProcessStep<T> step) {
                this.index = index;
                this.tick = tick;
                this.step = step;
            }

            public boolean tick(LinearProcessExecutor<T> target) {
                this.tick++;
                if (this.tick == step.length) return false;

                this.step.executor.accept(target, target.getTarget());

                return true;
            }
        }
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/animation/AlignmentLerp.java
================================================
package io.wispforest.owo.braid.animation;

import io.wispforest.owo.braid.core.Alignment;
import net.minecraft.util.Mth;

public class AlignmentLerp extends Lerp<Alignment> {

    public AlignmentLerp(Alignment start, Alignment end) {
        super(start, end);
    }

    @Override
    protected Alignment at(double t) {
        return Alignment.of(
            Mth.lerp(t, this.start.horizontal(), this.end.horizontal()),
            Mth.lerp(t, this.start.vertical(), this.end.vertical())
        );
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/animation/Animation.java
================================================
package io.wispforest.owo.braid.animation;

import io.wispforest.owo.braid.framework.proxy.ProxyHost;
import net.minecraft.util.Mth;
import org.jetbrains.annotations.Nullable;

import java.time.Duration;

public class Animation {

    private final Scheduler scheduler;
    private final Listener listener;
    private final @Nullable FinishListener finishListener;

    public Easing easing;
    public Duration duration;

    private double progress;
    private @Nullable Target target;

    public Animation(Easing easing, Duration duration, Scheduler scheduler, Listener listener, @Nullable FinishListener finishListener, Target startFrom) {
        this.easing = easing;
        this.duration = duration;
        this.scheduler = scheduler;
        this.listener = listener;
        this.finishListener = finishListener;
        this.progress = startFrom.targetProgress;
    }

    public Animation(Easing easing, Duration duration, Scheduler scheduler, Listener listener, Target startFrom) {
        this(easing, duration, scheduler, listener, null, startFrom);
    }

    public @Nullable Target target() {
        return this.target;
    }

    public double progress() {
        return this.easing.apply((float) this.progress);
    }

    public void towards(Target target) {
        this.towards(target, true);
    }

    public void towards(Target target, boolean restart) {
        if (restart) {
            this.progress = 1 - target.targetProgress;
        }

        if (this.target == null) {
            this.scheduler.schedule(this::callback);
        }

        this.target = target;
    }

    public void pause() {
        this.target = null;
    }

    public void stop() {
        this.stop(null);
    }

    public void stop(@Nullable Target at) {
        if (this.target == null && at == null) return;

        this.progress = at != null ? at.targetProgress : this.target.targetProgress;
        this.target = null;
    }

    private void callback(Duration delta) {
        if (this.target == null) return;

        this.progress = Mth.clamp(
            this.progress + this.target.direction * delta.toNanos() / (double) this.duration.toNanos(),
            0,
            1
        );

        this.listener.onUpdate(this.easing.apply((float) this.progress));

        if (Math.abs(this.progress - this.target.targetProgress) > EPSILON) {
            this.scheduler.schedule(this::callback);
        } else {
            if (this.finishListener != null) {
                this.finishListener.onFinished(this.target);
            }

            this.progress = this.target.targetProgress;
            this.target = null;
        }
    }

    // ---

    private static final double EPSILON = 1e-3;

    // ---

    public enum Target {
        START(-1, 0),
        END(1, 1);

        public final long direction;
        public final double targetProgress;

        Target(long direction, double targetProgress) {
            this.direction = direction;
            this.targetProgress = targetProgress;
        }
    }

    @FunctionalInterface
    public interface Listener {
        void onUpdate(double progress);
    }

    @FunctionalInterface
    public interface FinishListener {
        void onFinished(Target atTarget);
    }

    @FunctionalInterface
    public interface Scheduler {
        void schedule(ProxyHost.AnimationCallback callback);
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/animation/AutomaticallyAnimatedWidget.java
================================================
package io.wispforest.owo.braid.animation;

import io.wispforest.owo.braid.framework.proxy.WidgetState;
import io.wispforest.owo.braid.framework.widget.StatefulWidget;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Duration;
import java.util.Objects;

public abstract class AutomaticallyAnimatedWidget extends StatefulWidget {

    private static final Logger log = LoggerFactory.getLogger(AutomaticallyAnimatedWidget.class);
    public final Duration duration;
    public final Easing easing;

    protected AutomaticallyAnimatedWidget(Duration duration, Easing easing) {
        this.duration = duration;
        this.easing = easing;
    }

    @Override
    public abstract State<?> createState();

    @SuppressWarnings({"unchecked", "rawtypes"})
    public static abstract class State<T extends AutomaticallyAnimatedWidget> extends WidgetState<T> {

        private Animation animation;
        private LerpVisitor activeVisitor;

        private void callback(double progress) {
            this.setState(() -> {});
        }

        @Override
        public void init() {
            this.animation = new Animation(
                this.widget().easing,
                this.widget().duration,
                this::scheduleAnimationCallback,
                this::callback,
                Animation.Target.END
            );

            this.visitLerps((previous, targetValue, factory) -> {
                return factory.make(targetValue, targetValue);
            });
        }

        @Override
        public void didUpdateWidget(AutomaticallyAnimatedWidget oldWidget) {
            var restartAnimation = new MutableBoolean(this.widget().easing != oldWidget.easing);
            this.animation.duration = this.widget().duration;

            if (restartAnimation.isFalse()) {
                this.visitLerps((previous, targetValue, factory) -> {
                    if (!Objects.equals(previous.end, targetValue)) {
                        restartAnimation.setTrue();
                    }

                    return previous;
                });
            }

            if (restartAnimation.isTrue()) {
                this.visitLerps((previous, targetValue, factory) -> factory.make(previous.compute(this.animationValue()), targetValue));
                this.animation.easing = this.widget().easing;
                this.animation.towards(Animation.Target.END);
            }
        }

        private void visitLerps(LerpVisitor visitor) {
            this.activeVisitor = visitor;
            this.updateLerps();
        }

        // ---

        protected double animationValue() {
            return this.animation.progress();
        }

        protected <L extends Lerp<V>, V> L visitLerp(@Nullable Lerp<V> previous, V targetValue, Lerp.Factory<L, V> factory) {
            return (L) this.activeVisitor.visit(previous, targetValue, factory);
        }

        protected <L extends Lerp<V>, V> L visitNullableLerp(@Nullable Lerp<V> previous, V targetValue, Lerp.Factory<L, V> factory) {
            return (L) this.activeVisitor.visit(previous, targetValue, (start, end) -> new NullableLerp(start, end, factory));
        }

        protected abstract void updateLerps();
    }

    @FunctionalInterface
    private interface LerpVisitor<L extends Lerp<V>, V> {
        L visit(@Nullable Lerp<V> previous, V targetValue, Lerp.Factory<L, V> factory);
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/animation/ColorLerp.java
================================================
package io.wispforest.owo.braid.animation;

import io.wispforest.owo.braid.core.Color;

public class ColorLerp extends Lerp<Color> {

    public ColorLerp(Color start, Color end) {
        super(start, end);
    }

    @Override
    protected Color at(double t) {
        return Color.mix(t, this.start, this.end);
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/animation/DoubleLerp.java
================================================
package io.wispforest.owo.braid.animation;

import net.minecraft.util.Mth;

public class DoubleLerp extends Lerp<Double> {

    public DoubleLerp(Double start, Double end) {
        super(start, end);
    }

    @Override
    protected Double at(double t) {
        return Mth.lerp(t, this.start, this.end);
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/animation/Easing.java
================================================
package io.wispforest.owo.braid.animation;

public class Easing {

    public static final Easing LINEAR = new Easing(x -> x);
    public static final Easing IN_QUAD = new Easing(x -> x * x);
    public static final Easing OUT_QUAD = new Easing(x -> 1.0 - (1.0 - x) * (1.0 - x));
    public static final Easing IN_OUT_QUAD = new Easing(x -> x < 0.5 ? 2.0 * x * x : 1.0 - Math.pow(-2.0 * x + 2.0, 2.0) / 2.0);
    public static final Easing IN_CUBIC = new Easing(x -> x * x * x);
    public static final Easing OUT_CUBIC = new Easing(x -> 1.0 - Math.pow(1.0 - x, 3));
    public static final Easing IN_OUT_CUBIC = new Easing(x -> x < 0.5 ? 4.0 * x * x * x : 1.0 - Math.pow(-2.0 * x + 2.0, 3.0) / 2.0);
    public static final Easing IN_QUART = new Easing(x -> x * x * x * x);
    public static final Easing OUT_QUART = new Easing(x -> 1.0 - Math.pow(1.0 - x, 4.0));
    public static final Easing IN_OUT_QUART = new Easing(x -> x < 0.5 ? 8.0 * x * x * x * x : 1.0 - Math.pow(-2.0 * x + 2.0, 4.0) / 2.0);
    public static final Easing IN_QUINT = new Easing(x -> x * x * x * x * x);
    public static final Easing OUT_QUINT = new Easing(x -> 1.0 - Math.pow(1.0 - x, 5.0));
    public static final Easing IN_OUT_QUINT = new Easing(x -> x < 0.5 ? 16.0 * x * x * x * x * x : 1.0 - Math.pow(-2.0 * x + 2.0, 5.0) / 2.0);
    public static final Easing IN_SINE = new Easing(x -> 1.0 - Math.cos((x * Math.PI) / 2.0));
    public static final Easing OUT_SINE = new Easing(x -> Math.sin((x * Math.PI) / 2.0));
    public static final Easing IN_OUT_SINE = new Easing(x -> -(Math.cos(Math.PI * x) - 1) / 2.0);
    public static final Easing IN_EXPO = new Easing(x -> x == 0.0 ? 0.0 : Math.pow(2.0, 10.0 * x - 10.0));
    public static final Easing OUT_EXPO = new Easing(x -> x == 1.0 ? 1.0 : 1.0 - Math.pow(2.0, -10.0 * x));
    public static final Easing IN_OUT_EXPO = new Easing(x -> x == 0.0 ? 0.0 : x == 1.0 ? 1.0 : x < 0.5 ? Math.pow(2.0, 20.0 * x - 10.0) / 2.0 : (2.0 - Math.pow(2.0, -20.0 * x + 10.0)) / 2.0);
    public static final Easing IN_CIRC = new Easing(x -> 1.0 - Math.sqrt(1.0 - Math.pow(x, 2.0)));
    public static final Easing OUT_CIRC = new Easing(x -> Math.sqrt(1.0 - Math.pow(x - 1.0, 2.0)));
    public static final Easing IN_OUT_CIRC = new Easing(x -> x < 0.5 ? (1.0 - Math.sqrt(1.0 - Math.pow(2.0 * x, 2.0))) / 2 : (Math.sqrt(1.0 - Math.pow(-2.0 * x + 2.0, 2.0)) + 1.0) / 2.0);

    public static final Easing OUT_BOUNCE = new Easing(x -> {
        var n1 = 7.5625;
        var d1 = 2.75;

        if (x < 1 / d1) {
            return n1 * x * x;
        } else if (x < 2 / d1) {
            return n1 * (x -= 1.5 / d1) * x + 0.75;
        } else if (x < 2.5 / d1) {
            return n1 * (x -= 2.25 / d1) * x + 0.9375;
        } else {
            return n1 * (x -= 2.625 / d1) * x + 0.984375;
        }
    });

    // ---

    private final Function function;
    public Easing(Function function) {
        this.function = function;
    }

    public final double apply(double x) {
        if (x == 0 || x == 1) return x;
        return this.compute(x);
    }

    protected double compute(double x) {
        return this.function.compute(x);
    }

    @FunctionalInterface
    public interface Function {
        double compute(double x);
    }
}

================================================
FILE: src/main/java/io/wispforest/owo/braid/animation/InsetsLerp.java
================================================
package io.wispforest.owo.braid.animation;

import io.wispforest.owo.braid.core.Insets;
import net.minecraft.util.Mth;

public class InsetsLerp extends Lerp<Insets> {

    public InsetsLerp(Insets start, Insets end) {
        super(start, end);
    }

    @Override
    protected Insets at(double t) {
        return Insets.of(
            Mth.lerp(t, this.start.top(), this.end.top()),
            Mth.lerp(t, this.start.bottom(), this.end.bottom()),
            Mth.lerp(t, this.start.left(), this.end.left()),
            Mth.lerp(t, this.start.right(), this.end.right())
        );
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/animation/Lerp.java
================================================
package io.wispforest.owo.braid.animation;

public abstract class Lerp<T> {

    public final T start;
    public final T end;

    protected Lerp(T start, T end) {
        this.start = start;
        this.end = end;
    }

    public T compute(double t) {
        if (t - EPSILON <= 0) return this.start;
        if (t + EPSILON >= 1) return this.end;

        return this.at(t);
    }

    protected abstract T at(double t);

    // ---

    private static final double EPSILON = 1e-4;

    // ---

    @FunctionalInterface
    public interface Factory<T extends Lerp<V>, V> {
        T make(V start, V end);
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/animation/NullableLerp.java
================================================
package io.wispforest.owo.braid.animation;

import org.jetbrains.annotations.Nullable;

public class NullableLerp<T> extends Lerp<T> {

    private final @Nullable Lerp<T> delegate;

    public NullableLerp(@Nullable T start, @Nullable T end, Lerp.Factory<Lerp<T>, T> delegateFactory) {
        super(start, end);
        if (start != null) {
            this.delegate = delegateFactory.make(start, end);
        } else {
            this.delegate = null;
        }
    }

    @Override
    protected T at(double t) {
        return this.delegate != null ? this.delegate.at(t) : this.end;
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/Aabb2d.java
================================================
package io.wispforest.owo.braid.core;

import org.joml.Matrix3x2f;
import org.joml.Vector2f;

public class Aabb2d {

    public double x;
    public double y;
    public double width;
    public double height;

    public Aabb2d(double x, double y, double width, double height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }

    public double minX() {
        return this.x;
    }

    public double maxX() {
        return this.x + this.width;
    }

    public double minY() {
        return this.y;
    }

    public double maxY() {
        return this.y + this.height;
    }

    public Aabb2d transform(Matrix3x2f matrix) {
        var topLeft = matrix.transformPosition((float) this.x, (float) this.y, new Vector2f());
        var topRight = matrix.transformPosition((float) (this.x + this.width), (float) this.y, new Vector2f());
        var bottomLeft = matrix.transformPosition((float) this.x, (float) (this.y + this.height), new Vector2f());
        var bottomRight = matrix.transformPosition((float) (this.x + this.width), (float) (this.y + this.height), new Vector2f());

        this.x = Math.min(Math.min(Math.min(topLeft.x, topRight.x), bottomLeft.x), bottomRight.x);
        this.width = Math.max(Math.max(Math.max(topLeft.x, topRight.x), bottomLeft.x), bottomRight.x) - this.x;

        this.y = Math.min(Math.min(Math.min(topLeft.y, topRight.y), bottomLeft.y), bottomRight.y);
        this.height = Math.max(Math.max(Math.max(topLeft.y, topRight.y), bottomLeft.y), bottomRight.y) - this.y;

        return this;
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/Alignment.java
================================================
package io.wispforest.owo.braid.core;

import org.jetbrains.annotations.ApiStatus;

public record Alignment(double horizontal, double vertical) {
    public static final Alignment TOP_LEFT = Alignment.of(0, 0);
    public static final Alignment TOP = Alignment.of(.5, 0);
    public static final Alignment TOP_RIGHT = Alignment.of(1, 0);
    public static final Alignment LEFT = Alignment.of(0, .5);
    public static final Alignment CENTER = Alignment.of(.5, .5);
    public static final Alignment RIGHT = Alignment.of(1, .5);
    public static final Alignment BOTTOM_LEFT = Alignment.of(0, 1);
    public static final Alignment BOTTOM = Alignment.of(.5, 1);
    public static final Alignment BOTTOM_RIGHT = Alignment.of(1, 1);

    // ---

    @ApiStatus.Internal
    @Deprecated(forRemoval = true)
    public Alignment {}

    public static Alignment of(double horizontal, double vertical) {
        return new Alignment(horizontal, vertical);
    }

    public double alignHorizontal(double space, double object) {
        return Math.floor((space - object) * horizontal);
    }

    public double alignVertical(double space, double object) {
        return Math.floor((space - object) * vertical);
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/AppState.java
================================================
package io.wispforest.owo.braid.core;

import com.google.common.collect.Iterables;
import com.mojang.blaze3d.opengl.GlStateManager;
import io.wispforest.owo.braid.core.cursor.CursorStyle;
import io.wispforest.owo.braid.core.events.*;
import io.wispforest.owo.braid.framework.BuildContext;
import io.wispforest.owo.braid.framework.instance.*;
import io.wispforest.owo.braid.framework.proxy.BuildScope;
import io.wispforest.owo.braid.framework.proxy.ProxyHost;
import io.wispforest.owo.braid.framework.proxy.SingleChildInstanceWidgetProxy;
import io.wispforest.owo.braid.framework.proxy.WidgetProxy;
import io.wispforest.owo.braid.framework.widget.InheritedWidget;
import io.wispforest.owo.braid.framework.widget.SingleChildInstanceWidget;
import io.wispforest.owo.braid.framework.widget.Widget;
import io.wispforest.owo.braid.widgets.basic.Tooltip;
import io.wispforest.owo.braid.widgets.basic.VisitorWidget;
import io.wispforest.owo.braid.widgets.eventstream.BraidEventStream;
import io.wispforest.owo.braid.widgets.focus.FocusClickArea;
import io.wispforest.owo.braid.widgets.focus.RootFocusScope;
import io.wispforest.owo.braid.widgets.inspector.BraidInspector;
import io.wispforest.owo.braid.widgets.inspector.InstancePicker;
import io.wispforest.owo.util.EventSource;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.network.chat.Style;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector2d;
import org.joml.Vector2dc;
import org.joml.Vector2f;
import org.lwjgl.glfw.GLFW;
import org.slf4j.Logger;

import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.function.Consumer;

public class AppState implements InstanceHost, ProxyHost {

    public final @Nullable Logger logger;
    private final Minecraft client;

    public final Surface surface;
    public final EventBinding eventBinding;

    private final BuildScope rootBuildScope = new BuildScope();
    private Deque<AnimationCallback> animationCallbacks = new LinkedList<>();
    private final PriorityQueue<ScheduledCallback> callbacks = new PriorityQueue<>();
    private Deque<Runnable> postLayoutCallbacks = new LinkedList<>();
    private final String name;
    private final RootProxy root;

    private final Vector2d cursorPosition = new Vector2d();

    private Set<MouseListener> hovered = new HashSet<>();
    private final WeakHashMap<MouseListener, MousePosition> mousePositions = new WeakHashMap<>();
    private @Nullable MouseListener dragging = null;
    private @Nullable CursorStyle draggingCursorStyle = null;
    private int draggingButton = -1;
    private KeyModifiers draggingModifiers = null;
    private boolean dragStarted = false;

    private static final Duration MIN_GRACE_PERIOD = Duration.ofMillis(200);
    private static final Duration MAX_GRACE_PERIOD = Duration.ofMillis(500);
    private static final int SCROLL_MOVEMENT_THRESHOLD = 5;

    private @Nullable HitTestState scrollHit = null;
    private Vector2d scrollPos = new Vector2d();
    private Instant lastScrollTime = Instant.EPOCH;

    private final BraidEventStream<RootFocusScope.KeyDownEvent> keyDownStream = new BraidEventStream<>();
    private final BraidEventStream<RootFocusScope.KeyUpEvent> keyUpStream = new BraidEventStream<>();
    private final BraidEventStream<RootFocusScope.CharEvent> charStream = new BraidEventStream<>();

    private final BraidHotReloadCallback.Listener reloadListener;
    private final EventSource<?>.Subscription resizeSubscription;
    private final List<Runnable> onTerminate = new ArrayList<>();
    private boolean running = true;

    private final BraidInspector inspector = new BraidInspector(this);

    public AppState(
        @Nullable Logger logger,
        @Nullable String name,
        Minecraft client,
        Surface surface,
        EventBinding eventBinding,
        Widget root
    ) {
        this.logger = logger;
        this.client = client;

        this.surface = surface;
        this.eventBinding = eventBinding;

        this.name = name != null ? name : root.getClass().getName();
        this.root = new RootWidget(
            new AppWidget(
                this,
                new InstancePicker(
                    this.inspector.onPick(),
                    this.inspector::revealInstance,
                    new RootFocusScope(
                        this.keyDownStream.source(),
                        this.keyUpStream.source(),
                        this.charStream.source(),
                        new UserRoot(
                            widgetProxy -> inspector.rootProxy = widgetProxy,
                            widgetInstance -> inspector.rootInstance = widgetInstance,
                            root
                        )
                    )
                )
            ),
            this.rootBuildScope
        ).proxy();
        this.root.bootstrap(this, this);
        this.scheduleLayout(this.rootInstance());

        this.reloadListener = BraidHotReloadCallback.register();
        this.resizeSubscription = this.surface.onResize().subscribe((newWidth, newHeight) -> {
            this.rootInstance().markNeedsLayout();
        });
    }

    public boolean running() {
        return this.running;
    }

    public void onTerminate(Runnable callback) {
        this.onTerminate.add(callback);
    }

    public void scheduleShutdown() {
        this.running = false;
        this.onTerminate.forEach(Runnable::run);
    }

    public void activateInspector() {
        this.inspector.activate();
    }

    private @Nullable TooltipState activeTooltip;

    public void draw(GuiGraphics graphics) {
        this.surface.beginRendering();

        graphics.push();
        this.rootInstance().transform.transformToParent(graphics.pose());

        var braidContext = BraidGraphics.create(graphics, this.surface);

        GlStateManager._enableScissorTest();
        this.rootInstance().draw(braidContext);
        GlStateManager._disableScissorTest();

        if (this.activeTooltip != null) {
            if (this.activeTooltip.components() != null) braidContext.drawTooltip(this.client.font, this.activeTooltip.x(), this.activeTooltip.y(), this.activeTooltip.components());
            if (this.activeTooltip.style() != null) graphics.renderComponentHoverEffect(this.client.font, this.activeTooltip.style(), this.activeTooltip.x(), this.activeTooltip.y());
        }

        graphics.pop();

        this.surface.endRendering();
    }

    public void processEvents(float frameDeltaInTicks) {
        this.pollAndDispatchEvents();

        var state = this.hitTest();

        var tooltipSupplier = state.firstWhere(hit -> hit.instance() instanceof TooltipProvider);
        if (tooltipSupplier != null) {
            var tooltip = (TooltipProvider) tooltipSupplier.instance();
            var components = tooltip.getTooltipComponentsAt(tooltipSupplier.x(), tooltipSupplier.y());
            var style = tooltip.getStyleAt(tooltipSupplier.x(), tooltipSupplier.y());

            if (components != null || style != null) this.activeTooltip = new TooltipState(components, style, (int) this.cursorPosition.x, (int) this.cursorPosition.y);
        } else {
            this.activeTooltip = null;
        }

        // ---

        var nowHovered = new HashSet<MouseListener>();
        for (var hit : Iterables.filter(state.occludedTrace(), hit -> hit.instance() instanceof MouseListener)) {
            var listener = (MouseListener) hit.instance();

            nowHovered.add(listener);

            if (this.hovered.contains(listener)) {
                this.hovered.remove(listener);
            } else {
                listener.onMouseEnter();
            }

            var mousePosition = this.mousePositions.getOrDefault(listener, MousePosition.ORIGIN);
            if (mousePosition.x() != hit.x() || mousePosition.y() != hit.y()) {
                listener.onMouseMove(hit.x(), hit.y());
                this.mousePositions.put(listener, new MousePosition(hit.x(), hit.y()));
            }
        }

        for (var noLongerHovered : this.hovered) {
            noLongerHovered.onMouseExit();
        }

        this.hovered = nowHovered;

        // ---

        @Nullable CursorStyle activeStyle = null;
        if (this.dragging != null) {
            activeStyle = this.draggingCursorStyle;
        } else {
            var cursorStyleSource = state.firstWhere(
                (hit) ->
                    hit.instance() instanceof MouseListener &&
                        ((MouseListener) hit.instance()).cursorStyleAt(hit.x(), hit.y()) != null
            );

            if (cursorStyleSource != null) {
                activeStyle = ((MouseListener) cursorStyleSource.instance()).cursorStyleAt(
                    cursorStyleSource.x(),
                    cursorStyleSource.y()
                );
            }
        }

        this.surface.setCursorStyle(activeStyle != null ? activeStyle : CursorStyle.NONE);

        // ---

        if (this.reloadListener.poll()) {
            this.rebuildRoot();
        }

        if (!this.animationCallbacks.isEmpty()) {
            var callbacksForThisFrame = this.animationCallbacks;
            this.animationCallbacks = new LinkedList<>();

            while (!callbacksForThisFrame.isEmpty()) {
                callbacksForThisFrame.poll().run(Duration.ofMillis((long) (frameDeltaInTicks * 50)));
            }
        }

        var now = Instant.now();
        while (!this.callbacks.isEmpty() && this.callbacks.peek().after().isBefore(now)) {
            this.callbacks.poll().callback().run();
        }

        var anyTreeMutations = false;

        anyTreeMutations |= this.rootBuildScope.rebuildDirtyProxies();
        anyTreeMutations |= this.flushLayoutQueue();

        if (anyTreeMutations) {
            this.inspector.refresh();
        }

        if (!this.postLayoutCallbacks.isEmpty()) {
            var callbacksForThisFrame = this.postLayoutCallbacks;
            this.postLayoutCallbacks = new LinkedList<>();

            while (!callbacksForThisFrame.isEmpty()) {
                callbacksForThisFrame.poll().run();
            }
        }
    }

    private void pollAndDispatchEvents() {
        var events = this.eventBinding.poll();

        for (var slot : events) {
            switch (slot.event) {
                case MouseButtonPressEvent(int button, KeyModifiers modifiers) -> {
                    this.scrollHit = null;
                    var state = this.hitTest();

                    state.firstWhere(hit -> {
                        if (!(hit.instance() instanceof FocusClickArea.Instance instance)) return false;

                        instance.widget().clickCallback.run();
                        return true;
                    });

                    var clicked = state.firstWhere(
                        (hit) -> hit.instance() instanceof MouseListener && ((MouseListener) hit.instance()).onMouseDown(hit.x(), hit.y(), button, modifiers)
                    );

                    if (clicked != null) {
                        slot.markHandled();

                        if (this.dragging == null) {
                            this.dragging = (MouseListener) clicked.instance();
                            this.draggingCursorStyle = ((MouseListener) clicked.instance()).cursorStyleAt(
                                clicked.x(),
                                clicked.y()
                            );
                            this.dragStarted = false;
                            this.draggingButton = button;
                            this.draggingModifiers = modifiers;
                        }
                    }
                }
                case MouseMoveEvent(double x, double y) -> {
                    slot.markHandled();

                    var deltaX = x - this.cursorPosition.x;
                    var deltaY = y - this.cursorPosition.y;
                    if (deltaX == 0 && deltaY == 0) break;

                    this.cursorPosition.x = x;
                    this.cursorPosition.y = y;
                    if (this.cursorPosition.distance(this.scrollPos) > SCROLL_MOVEMENT_THRESHOLD) this.scrollHit = null;

                    if (!(this.dragging instanceof WidgetInstance<?>)) break;

                    if (!this.dragStarted) {
                        this.dragging.onMouseDragStart(draggingButton, draggingModifiers);
                        this.dragStarted = true;
                    }

                    var globalTransform = ((WidgetInstance<?>) this.dragging).computeGlobalTransform();
                    var coordinates = new Vector2f((float) x, (float) y);
                    globalTransform.transformPosition(coordinates);

                    // apply *only the rotation* of the instance's transform
                    // to the mouse movement
                    var delta = new Vector2f((float) deltaX, (float) deltaY);
                    globalTransform.transformDirection(delta);

                    this.dragging.onMouseDrag(coordinates.x, coordinates.y, delta.x, delta.y);
                }
                case MouseButtonReleaseEvent(int button, KeyModifiers modifiers) -> {
                    this.scrollHit = null;
                    var state = this.hitTest();
                    var unClicked = state.firstWhere(
                        (hit) -> hit.instance() instanceof MouseListener && ((MouseListener) hit.instance()).onMouseUp(hit.x(), hit.y(), button, modifiers)
                    );

                    if (unClicked != null) {
                        slot.markHandled();
                    }

                    if (this.draggingButton == button) {
                        if (this.dragStarted && this.dragging != null) {
                            this.dragging.onMouseDragEnd();
                        }

                        this.dragging = null;
                    }
                }
                case MouseScrollEvent(double xOffset, double yOffset) -> {
                    var now = Instant.now();
                    var grace = this.cursorPosition.distance(this.scrollPos) > SCROLL_MOVEMENT_THRESHOLD ? MIN_GRACE_PERIOD : MAX_GRACE_PERIOD;
                    if (this.scrollHit == null || now.minus(grace).isAfter(this.lastScrollTime) ) this.scrollHit = this.hitTest();
                    this.lastScrollTime = now;
                    this.scrollPos = new Vector2d(this.cursorPosition);
                    var scrolled = this.scrollHit.firstWhere(
                        (hit) -> hit.instance() instanceof MouseListener &&
                            ((MouseListener) hit.instance()).onMouseScroll(
                                hit.x(),
                                hit.y(),
                                xOffset,
                                yOffset
                            )
                    );

                    if (scrolled != null) {
                        slot.markHandled();
                    }
                }
                case KeyPressEvent(int keyCode, int scancode, KeyModifiers modifiers) -> {
                    if (keyCode == GLFW.GLFW_KEY_R && modifiers.shift() && modifiers.alt()) {
                        this.rebuildRoot();
                        slot.markHandled();

                        break;
                    }

                    if (keyCode == GLFW.GLFW_KEY_I && modifiers.ctrl() && modifiers.shift()) {
                        this.inspector.activate();
                        slot.markHandled();

                        break;
                    }

                    var event = new RootFocusScope.KeyDownEvent(keyCode, modifiers);
                    this.keyDownStream.sink().onEvent(event);

                    if (event.handled()) {
                        slot.markHandled();
                    }
                }
                case KeyReleaseEvent(int keycode, int scancode, KeyModifiers modifiers) -> {
                    var event = new RootFocusScope.KeyUpEvent(keycode, modifiers);
                    this.keyUpStream.sink().onEvent(event);

                    if (event.handled()) {
                        slot.markHandled();
                    }
                }
                case CharInputEvent(char codepoint, KeyModifiers modifiers) -> {
                    var event = new RootFocusScope.CharEvent(codepoint, modifiers);
                    this.charStream.sink().onEvent(event);

                    if (event.handled()) {
                        slot.markHandled();
                    }
                }
                case FilesDroppedEvent filesDroppedEvent -> {}
                case CloseEvent ignored -> {
                    slot.markHandled();
                    this.scheduleShutdown();
                }
            }
        }
    }

    public void rebuildRoot() {
        var before = Instant.now();

        this.root.reassemble();

        var elapsed = ChronoUnit.MICROS.between(before, Instant.now());
        if (this.logger != null) this.logger.debug("completed full app rebuild in {}us", elapsed);
    }

    public void dispose() {
        this.inspector.close();

        this.reloadListener.unregister();
        this.resizeSubscription.cancel();

        this.surface.dispose();
        this.root.unmount();
    }

    private HitTestState hitTest() {
        return this.hitTest(this.cursorPosition.x, this.cursorPosition.y);
    }

    public HitTestState hitTest(double x, double y) {
        var state = new HitTestState();
        this.rootInstance().hitTest(x, y, state);

        return state;
    }

    // ---

    @Override
    public Minecraft client() {
        return this.client;
    }

    public SingleChildWidgetInstance<?> rootInstance() {
        return this.root.instance();
    }

    // ---

    private List<WidgetInstance<?>> layoutQueue = new ArrayList<>();
    private boolean mergeToLayoutQueue = false;

    private boolean flushLayoutQueue() {
        if (this.layoutQueue.isEmpty()) return false;

        while (!this.layoutQueue.isEmpty()) {
            var queue = this.layoutQueue;
            this.layoutQueue = new ArrayList<>();

            queue.sort(Comparator.naturalOrder());
            for (var idx = 0; idx < queue.size(); idx++) {
                var instance = queue.get(idx);

                if (this.mergeToLayoutQueue) {
                    this.mergeToLayoutQueue = false;

                    if (!this.layoutQueue.isEmpty()) {
                        this.layoutQueue.addAll(queue.subList(idx, queue.size()));
                        break;
                    }
                }

                if (instance.needsLayout()) {
                    instance.layout(
                        instance.hasParent()
                            ? instance.constraints()
                            : Constraints.tight(Size.of(this.surface.width(), this.surface.height()))
                    );
                }
            }

            this.mergeToLayoutQueue = false;
        }

        return true;
    }

    @Override
    public void scheduleLayout(WidgetInstance<?> instance) {
        this.layoutQueue.add(instance);
    }

    @Override
    public void notifySubtreeRebuild() {
        this.mergeToLayoutQueue = true;
    }

    @Override
    public void scheduleAnimationCallback(AnimationCallback callback) {
        this.animationCallbacks.offer(callback);
    }

    @Override
    public long scheduleDelayedCallback(Duration delay, Runnable callback) {
        var id = ScheduledCallback.nextId++;
        this.callbacks.add(new ScheduledCallback(
            Instant.now().plus(delay),
            callback, id
        ));
        return id;
    }

    @Override
    public void cancelDelayedCallback(long id) {
        this.callbacks.removeIf(scheduledCallback -> scheduledCallback.id() == id);
    }

    @Override
    public void schedulePostLayoutCallback(Runnable callback) {
        this.postLayoutCallbacks.offer(callback);
    }

    @Override
    public Vector2dc cursorPosition() {
        return this.cursorPosition;
    }

    @Override
    public String toString() {
        return String.format("%s (AppState@%s)", this.name, Integer.toHexString(hashCode()));
    }

    // ---

    public static String formatName(String category, Widget userRoot) {
        var classPath = userRoot.getClass().getName().split("\\.");
        return String.format("%s[%s]", category, classPath[classPath.length - 1]);
    }

    public static String formatName(String category, Widget userRoot, String... attributes) {
        var classPath = userRoot.getClass().getName().split("\\.");
        return String.format("%s[%s, %s]", category, String.join(", ", attributes), classPath[classPath.length - 1]);
    }

    public static AppState of(BuildContext context) {
        //noinspection DataFlowIssue
        return context.getAncestor(AppWidget.class).app;
    }
}

record ScheduledCallback(Instant after, Runnable callback, long id) implements Comparable<ScheduledCallback> {
    //"fuck you we starting at 7" -chyz
    public static long nextId = 7;

    @Override
    public int compareTo(@NotNull ScheduledCallback o) {
        return this.after.compareTo(o.after);
    }
}

class RootWidget extends SingleChildInstanceWidget {

    public final BuildScope rootBuildScope;

    public RootWidget(Widget child, BuildScope rootBuildScope) {
        super(child);
        this.rootBuildScope = rootBuildScope;
    }

    @Override
    public RootProxy proxy() {
        return new RootProxy(this);
    }

    @Override
    public RootInstance instantiate() {
        return new RootInstance(this);
    }
}

class RootProxy extends SingleChildInstanceWidgetProxy {
    public RootProxy(RootWidget widget) {
        super(widget);
    }

    @Override
    public BuildScope buildScope() {
        return ((RootWidget) this.widget()).rootBuildScope;
    }

    @Override
    public boolean mounted() {
        return this.bootstrapped;
    }

    private boolean bootstrapped = false;

    void bootstrap(InstanceHost instanceHost, ProxyHost proxyHost) {
        this.bootstrapped = true;
        this.lifecycle = Lifecycle.LIVE;

        this.rootSetHost(proxyHost);

        rebuild();
        this.setDepth(0);

        this.instance.setDepth(0);
        this.instance.attachHost(instanceHost);
    }
}

class RootInstance extends SingleChildWidgetInstance.ShrinkWrap<RootWidget> {

    public RootInstance(RootWidget widget) {
        super(widget);
    }
}

class UserRoot extends VisitorWidget {

    public final Consumer<WidgetProxy> proxyCallback;
    public final Consumer<WidgetInstance<?>> instanceCallback;

    public UserRoot(Consumer<WidgetProxy> proxyCallback, Consumer<WidgetInstance<?>> instanceCallback, Widget child) {
        super(child);
        this.proxyCallback = proxyCallback;
        this.instanceCallback = instanceCallback;
    }

    private static final Visitor<UserRoot> VISITOR = (widget, instance) -> {
        widget.instanceCallback.accept(instance);
    };

    @Override
    public Proxy<?> proxy() {
        var proxy = new Proxy<>(this, VISITOR);
        this.proxyCallback.accept(proxy);

        return proxy;
    }
}

class AppWidget extends InheritedWidget {

    public final AppState app;

    protected AppWidget(AppState app, Widget child) {
        super(child);
        this.app = app;
    }

    @Override
    public boolean mustRebuildDependents(InheritedWidget newWidget) {
        if (((AppWidget) newWidget).app != this.app) {
            throw new UnsupportedOperationException("changing the AppState of a widget tree is not supported");
        }

        return false;
    }
}

record TooltipState(@Nullable List<ClientTooltipComponent> components, @Nullable Style style, int x, int y) {}

record MousePosition(double x, double y) {
    public static final MousePosition ORIGIN = new MousePosition(0, 0);
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/BraidGraphics.java
================================================
package io.wispforest.owo.braid.core;

import com.mojang.blaze3d.pipeline.RenderPipeline;
import io.wispforest.owo.braid.core.element.BraidDashedLineElement;
import io.wispforest.owo.mixin.braid.Matrix3x2fStackAccessor;
import io.wispforest.owo.mixin.ui.access.GuiGraphicsAccessor;
import io.wispforest.owo.ui.core.OwoUIGraphics;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.navigation.ScreenRectangle;
import net.minecraft.client.gui.render.state.GuiRenderState;
import org.joml.Matrix3x2f;
import org.joml.Matrix3x2fStack;
import org.joml.Matrix3x2fc;

import java.util.function.Consumer;

public class BraidGraphics extends OwoUIGraphics {

    private final Surface surface;

    protected BraidGraphics(Minecraft client, GuiRenderState renderState, int mouseX, int mouseY, Consumer<Runnable> setTooltipDrawer, Surface surface) {
        super(client, renderState, mouseX, mouseY, setTooltipDrawer);
        this.surface = surface;
    }

    public static BraidGraphics create(GuiGraphics grpahics, Surface surface) {
        var braidContext = new BraidGraphics(
            Minecraft.getInstance(),
            grpahics.guiRenderState,
            ((GuiGraphicsAccessor) grpahics).owo$getMouseX(),
            ((GuiGraphicsAccessor) grpahics).owo$getMouseY(),
            ((GuiGraphicsAccessor) grpahics)::owo$setDeferredTooltip,
            surface
        );
        ((GuiGraphicsAccessor) braidContext).owo$setScissorStack(((GuiGraphicsAccessor) grpahics).owo$getScissorStack());
        ((GuiGraphicsAccessor) braidContext).owo$setPose(new MatrixStack(((GuiGraphicsAccessor) grpahics).owo$getPose()));

        return braidContext;
    }

    @Override
    public int guiWidth() {
        return this.surface.width();
    }

    @Override
    public int guiHeight() {
        return this.surface.height();
    }

    public void buildRectOutline(double x, double y, double width, double height, RectEdgeBuilder builder) {
        builder.edge(x, y, x + width, y);
        builder.edge(x, y + height, x + width, y + height);

        builder.edge(x, y, x, y + height);
        builder.edge(x + width, y, x + width, y + height);
    }

    public void drawDashedLine(RenderPipeline pipeline, double x1, double y1, double x2, double y2, double thiccness, double segmentLength, Color color) {
        this.guiRenderState.submitGuiElement(new BraidDashedLineElement(
            color,
            thiccness,
            segmentLength,
            pipeline,
            new Matrix3x2f(this.pose()),
            new ScreenRectangle((int) x1, (int) y1, (int) (x2 - x1), (int) (y2 - y1)),
            this.scissorStack.peek()
        ));
    }

    @FunctionalInterface
    public interface RectEdgeBuilder {
        void edge(double x1, double y1, double x2, double y2);
    }

    @SuppressWarnings("ExternalizableWithoutPublicNoArgConstructor")
    public static class MatrixStack extends Matrix3x2fStack {

        public MatrixStack(Matrix3x2fc source) {
            super(16);
            this.mul(source);
        }

        @Override
        public Matrix3x2fStack pushMatrix() {
            var accessor = (Matrix3x2fStackAccessor) this;

            if (accessor.owo$getCurr() == accessor.owo$getMats().length) {
                var newMats = new Matrix3x2f[accessor.owo$getMats().length * 2];
                System.arraycopy(accessor.owo$getMats(), 0, newMats, 0, accessor.owo$getMats().length);
                for (int idx = newMats.length / 2; idx < newMats.length; idx++) {
                    newMats[idx] = new Matrix3x2f();
                }

                accessor.owo$setMats(newMats);
            }

            return super.pushMatrix();
        }
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/BraidHotReloadCallback.java
================================================
package io.wispforest.owo.braid.core;

import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;

public final class BraidHotReloadCallback {

    private static final Set<Listener> LISTENERS = new HashSet<>();
    public static final Logger LOGGER = LoggerFactory.getLogger("braid reload agent");

    public static Listener register() {
        var listener = new Listener();
        LISTENERS.add(listener);

        return listener;
    }

    @ApiStatus.Internal
    public static void setupComplete() {
        LOGGER.info("setup complete, debounce time is {}ms", Listener.DEBOUNCE_TIME);
    }

    @ApiStatus.Internal
    public static void invoke() {
        for (var listener : LISTENERS) {
            listener.triggered.set(true);
        }
    }

    public static class Listener {

        private static final int DEBOUNCE_TIME = Integer.getInteger("owo.braid.hotswapDebounceTime", 250);

        private final AtomicBoolean triggered = new AtomicBoolean();
        private @Nullable Instant lastTriggerTimestamp = null;

        public boolean poll() {
            if (this.triggered.getAndSet(false)) {
                this.lastTriggerTimestamp = Instant.now();
            }

            if (this.lastTriggerTimestamp != null && ChronoUnit.MILLIS.between(this.lastTriggerTimestamp, Instant.now()) > DEBOUNCE_TIME) {
                this.lastTriggerTimestamp = null;
                return true;
            }

            return false;
        }

        public void unregister() {
            LISTENERS.remove(this);
        }
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/BraidRenderPipelines.java
================================================
package io.wispforest.owo.braid.core;

import com.mojang.blaze3d.pipeline.RenderPipeline;
import io.wispforest.owo.Owo;
import net.minecraft.client.renderer.RenderPipelines;
import org.jetbrains.annotations.ApiStatus;

public class BraidRenderPipelines {
    public static final RenderPipeline TEXTURED_DEFAULT = RenderPipeline.builder(RenderPipelines.GUI_TEXTURED_SNIPPET)
        .withLocation(Owo.id("pipeline/braid_textured_default"))
        .build();

    public static final RenderPipeline TEXTURED_NEAREST = RenderPipeline.builder(RenderPipelines.GUI_TEXTURED_SNIPPET)
        .withLocation(Owo.id("pipeline/braid_textured_nearest"))
        .build();

    public static final RenderPipeline TEXTURED_BILINEAR = RenderPipeline.builder(RenderPipelines.GUI_TEXTURED_SNIPPET)
        .withLocation(Owo.id("pipeline/braid_textured_bilinear"))
        .build();

    @ApiStatus.Internal
    public static void register() {
        RenderPipelines.register(TEXTURED_DEFAULT);
        RenderPipelines.register(TEXTURED_NEAREST);
        RenderPipelines.register(TEXTURED_BILINEAR);
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/BraidScreen.java
================================================
package io.wispforest.owo.braid.core;

import io.wispforest.owo.braid.core.events.*;
import io.wispforest.owo.braid.framework.BuildContext;
import io.wispforest.owo.braid.framework.widget.InheritedWidget;
import io.wispforest.owo.braid.framework.widget.Widget;
import io.wispforest.owo.braid.widgets.BraidApp;
import io.wispforest.owo.ui.util.DisposableScreen;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.input.CharacterEvent;
import net.minecraft.client.input.KeyEvent;
import net.minecraft.client.input.MouseButtonEvent;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.Nullable;

public class BraidScreen extends Screen implements DisposableScreen {

    protected final EventBinding eventBinding = new EventBinding.Default();
    protected final Surface.Default surface = new Surface.Default();

    protected final Settings settings;
    protected final Widget rootWidget;
    public AppState state;

    public BraidScreen(Settings settings, Widget rootWidget) {
        super(Component.empty());
        this.settings = settings;
        this.rootWidget = rootWidget;
    }

    public BraidScreen(Widget rootWidget) {
        this(new Settings(), rootWidget);
    }

    @Override
    protected void init() {
        super.init();

        if (this.state == null) {
            var widget = this.settings.useBraidAppWidget
                ? new BraidApp(this.rootWidget)
                : this.rootWidget;

            this.state = new AppState(
                null,
                AppState.formatName("BraidScreen", this.rootWidget),
                this.minecraft,
                this.surface,
                this.eventBinding,
                new BraidScreenProvider(this, widget)
            );
        }
    }

    @Override
    public void render(GuiGraphics graphics, int mouseX, int mouseY, float delta) {
        super.render(graphics, mouseX, mouseY, delta);

        this.eventBinding.add(new MouseMoveEvent(mouseX, mouseY));
        this.state.processEvents(
            this.minecraft.getDeltaTracker().getGameTimeDeltaTicks()
        );

        this.state.draw(graphics);
    }

    @Override
    public void dispose() {
        this.state.dispose();
    }

    @Override
    public boolean isPauseScreen() {
        return this.settings.shouldPause;
    }

    @Override
    public boolean mouseClicked(MouseButtonEvent click, boolean doubled) {
        this.eventBinding.add(new MouseButtonPressEvent(click.button(), click.modifiers()));
        return true;
    }

    @Override
    public boolean mouseReleased(MouseButtonEvent click) {
        this.eventBinding.add(new MouseButtonReleaseEvent(click.button(), click.modifiers()));
        return true;
    }

    @Override
    public boolean mouseScrolled(double mouseX, double mouseY, double horizontalAmount, double verticalAmount) {
        this.eventBinding.add(new MouseScrollEvent(horizontalAmount, verticalAmount));
        return true;
    }

    @Override
    public boolean keyPressed(KeyEvent input) {
        this.eventBinding.add(new KeyPressEvent(input.key(), input.scancode(), input.modifiers()));
        return super.keyPressed(input);
    }

    @Override
    public boolean keyReleased(KeyEvent input) {
        this.eventBinding.add(new KeyReleaseEvent(input.key(), input.scancode(), input.modifiers()));
        return true;
    }

    @Override
    public boolean charTyped(CharacterEvent input) {
        this.eventBinding.add(new CharInputEvent((char) input.codepoint(), input.modifiers()));
        return true;
    }

    // ---

    public static @Nullable BraidScreen maybeOf(BuildContext context) {
        var provider = context.getAncestor(BraidScreenProvider.class);
        return provider != null ? provider.screen : null;
    }

    public static class Settings {
        public boolean shouldPause = true;
        public boolean useBraidAppWidget = true;
    }
}

class BraidScreenProvider extends InheritedWidget {

    public final BraidScreen screen;

    public BraidScreenProvider(BraidScreen screen, Widget child) {
        super(child);
        this.screen = screen;
    }

    @Override
    public boolean mustRebuildDependents(InheritedWidget newWidget) {
        return false;
    }
}

================================================
FILE: src/main/java/io/wispforest/owo/braid/core/BraidUtils.java
================================================
package io.wispforest.owo.braid.core;

import java.util.function.BiFunction;

public class BraidUtils {
    public static <S, T> T fold(Iterable<S> values, T initial, BiFunction<T, S, T> step) {
        var result = initial;
        for (var value : values) {
            result = step.apply(result, value);
        }

        return result;
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/BraidWindow.java
================================================
package io.wispforest.owo.braid.core;

import com.mojang.blaze3d.opengl.GlDebug;
import com.mojang.blaze3d.opengl.GlTexture;
import com.mojang.blaze3d.pipeline.TextureTarget;
import com.mojang.blaze3d.systems.RenderSystem;
import io.wispforest.owo.Owo;
import io.wispforest.owo.braid.core.cursor.CursorController;
import io.wispforest.owo.braid.core.cursor.CursorStyle;
import io.wispforest.owo.braid.core.events.*;
import io.wispforest.owo.braid.framework.widget.Widget;
import io.wispforest.owo.braid.util.BraidGuiRenderer;
import io.wispforest.owo.util.EventSource;
import io.wispforest.owo.util.EventStream;
import net.minecraft.client.Minecraft;
import org.apache.commons.lang3.mutable.MutableLong;
import org.lwjgl.glfw.*;
import org.lwjgl.opengl.GL32;
import org.lwjgl.system.NativeResource;

import java.nio.file.InvalidPathException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;

// TODO: consider somehow getting notified or polling
//       for changes in the gui scale option so we can react
//       instantly when it changes rather than on next resize
public class BraidWindow implements Surface {

    public final EventBinding eventBinding = new WindowEventBinding(this);

    public final long handle;
    private final List<NativeResource> resources = new ArrayList<>();

    private final EventStream<ResizeCallback> onResize = ResizeCallback.newStream();
    private TextureTarget remoteTarget;
    private int localFbo;

    public final BraidGuiRenderer guiRenderer;

    private final CursorController cursorController;

    private int framebufferWidth;
    private int framebufferHeight;

    private int scaledWidth;
    private int scaledHeight;
    private int scaleFactor;

    public BraidWindow(long handle) {
        this.handle = handle;
        this.cursorController = new CursorController(this.handle);

        this.guiRenderer = new BraidGuiRenderer(Minecraft.getInstance());

        var framebufferWidthOut = new int[1];
        var framebufferHeightOut = new int[1];
        GLFW.glfwGetFramebufferSize(this.handle, framebufferWidthOut, framebufferHeightOut);

        this.framebufferWidth = framebufferWidthOut[0];
        this.framebufferHeight = framebufferHeightOut[0];
        this.remoteTarget = new TextureTarget("braid window", this.framebufferWidth, this.framebufferHeight, true);
        this.recreateLocalFbo();

        GLFW.glfwSetWindowCloseCallback(this.handle, this.storeNativeResource(GLFWWindowCloseCallback.create(window -> {
            this.eventBinding.add(CloseEvent.INSTANCE);
        })));

        GLFW.glfwSetFramebufferSizeCallback(this.handle, this.storeNativeResource(GLFWFramebufferSizeCallback.create((window, width, height) -> {
            this.framebufferWidth = width;
            this.framebufferHeight = height;

            withContext(Minecraft.getInstance().getWindow().handle(), () -> {
                this.remoteTarget.destroyBuffers();
                this.remoteTarget = new TextureTarget("braid window", this.framebufferWidth, this.framebufferHeight, true);
            });

            this.recreateLocalFbo();

            this.onResize.sink().onResize(this.scaledWidth, this.scaledHeight);
        })));

        GLFW.glfwSetMouseButtonCallback(this.handle, this.storeNativeResource(GLFWMouseButtonCallback.create((window, button, action, mods) -> {
            this.eventBinding.add(switch (action) {
                case GLFW.GLFW_PRESS -> new MouseButtonPressEvent(button, new KeyModifiers(mods));
                case GLFW.GLFW_RELEASE -> new MouseButtonReleaseEvent(button, new KeyModifiers(mods));
                default -> throw new UnsupportedOperationException("incompatible glfw event type");
            });
        })));

        GLFW.glfwSetCursorPosCallback(this.handle, this.storeNativeResource(GLFWCursorPosCallback.create((window, mouseX, mouseY) -> {
            this.eventBinding.add(new MouseMoveEvent(
                mouseX / this.scaleFactor,
                mouseY / this.scaleFactor
            ));
        })));

        GLFW.glfwSetScrollCallback(this.handle, this.storeNativeResource(GLFWScrollCallback.create((window, xOffset, yOffset) -> {
            this.eventBinding.add(new MouseScrollEvent(xOffset, yOffset));
        })));

        GLFW.glfwSetKeyCallback(this.handle, this.storeNativeResource(GLFWKeyCallback.create((window, key, scancode, action, mods) -> {
            this.eventBinding.add(switch (action) {
                case GLFW.GLFW_PRESS, GLFW.GLFW_REPEAT -> new KeyPressEvent(key, scancode, new KeyModifiers(mods));
                case GLFW.GLFW_RELEASE -> new KeyReleaseEvent(key, scancode, new KeyModifiers(mods));
                default -> throw new UnsupportedOperationException("incompatible glfw event type");
            });
        })));

        GLFW.glfwSetCharModsCallback(this.handle, this.storeNativeResource(GLFWCharModsCallback.create((window, codepoint, mods) -> {
            this.eventBinding.add(new CharInputEvent((char) codepoint, new KeyModifiers(mods)));
        })));

        GLFW.glfwSetDropCallback(this.handle, this.storeNativeResource(GLFWDropCallback.create((window, count, names) -> {
            var paths = new ArrayList<Path>(count);

            for (int pathIdx = 0; pathIdx < count; pathIdx++) {
                var pathString = GLFWDropCallback.getName(names, pathIdx);

                try {
                    paths.add(Paths.get(pathString));
                } catch (InvalidPathException e) {
                    Owo.LOGGER.error("Failed to parse path '{}'", pathString, e);
                }
            }

            if (!paths.isEmpty()) {
                this.eventBinding.add(new FilesDroppedEvent(paths));
            }
        })));
    }

    private void recreateLocalFbo() {
        withContext(this.handle, () -> {
            if (this.localFbo != 0) {
                GL32.glDeleteFramebuffers(this.localFbo);
            }

            this.localFbo = GL32.glGenFramebuffers();
            GL32.glBindFramebuffer(GL32.GL_FRAMEBUFFER, this.localFbo);
            GL32.glFramebufferTexture2D(GL32.GL_FRAMEBUFFER, GL32.GL_COLOR_ATTACHMENT0, GL32.GL_TEXTURE_2D, ((GlTexture) this.remoteTarget.getColorTexture()).glId(), 0);

            if (GL32.glCheckFramebufferStatus(GL32.GL_FRAMEBUFFER) != GL32.GL_FRAMEBUFFER_COMPLETE) {
                throw new UnsupportedOperationException("Failed to initialize local FBO");
            }
        });

        this.recalculateScale();
    }

    private void recalculateScale() {
        var guiScale = Minecraft.getInstance().options.guiScale().get();
        var forceUnicodeFont = Minecraft.getInstance().options.forceUnicodeFont().get();

        var factor = 1;

        while (
            factor != guiScale
                && factor < this.framebufferWidth
                && factor < this.framebufferHeight
                && this.framebufferWidth / (factor + 1) >= 320
                && this.framebufferHeight / (factor + 1) >= 240
        ) {
            ++factor;
        }

        if (forceUnicodeFont && factor % 2 != 0) {
            ++factor;
        }

        this.scaleFactor = factor;

        var scaledWidth = (int) ((double) this.framebufferWidth / this.scaleFactor);
        this.scaledWidth = (double) this.framebufferWidth / this.scaleFactor > (double) scaledWidth ? scaledWidth + 1 : scaledWidth;

        var scaledHeight = (int) ((double) this.framebufferHeight / this.scaleFactor);
        this.scaledHeight = (double) this.framebufferHeight / this.scaleFactor > (double) scaledHeight ? scaledHeight + 1 : scaledHeight;
    }

    public static BraidWindow create(String title, int width, int height) {
        var handleOut = new MutableLong();
        withContext(0, () -> {
            GLFW.glfwWindowHint(GLFW.GLFW_CLIENT_API, GLFW.GLFW_OPENGL_API);
            GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_CREATION_API, GLFW.GLFW_NATIVE_CONTEXT_API);
            GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MAJOR, 3);
            GLFW.glfwWindowHint(GLFW.GLFW_CONTEXT_VERSION_MINOR, 2);
            GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_PROFILE, GLFW.GLFW_OPENGL_CORE_PROFILE);
            GLFW.glfwWindowHint(GLFW.GLFW_OPENGL_FORWARD_COMPAT, GLFW.GLFW_TRUE);

            var handle = GLFW.glfwCreateWindow(width, height, title, 0, Minecraft.getInstance().getWindow().handle());

            if (handle == 0) {
                throw new UnsupportedOperationException("Failed to create a GLFW window");
            }

            GLFW.glfwMakeContextCurrent(handle);
            GLFW.glfwSwapInterval(0);

            GlDebug.enableDebugCallback(Minecraft.getInstance().options.glDebugVerbosity, true, new HashSet<>());

            handleOut.setValue(handle);
        });

        return new BraidWindow(handleOut.longValue());
    }

    public static OpenResult open(String title, int width, int height, Widget widget) {
        var window = create(title, width, height);
        var app = new AppState(
            Owo.LOGGER,
            AppState.formatName("BraidWindow", widget, title),
            Minecraft.getInstance(),
            window,
            window.eventBinding,
            widget
        );

        BraidWindowScheduler.add(window, app);
        return new OpenResult(app, window);
    }

    // ---

    @Override
    public void dispose() {
        GLFW.glfwDestroyWindow(this.handle);
        this.cursorController.dispose();

        this.guiRenderer.close();

        this.remoteTarget.destroyBuffers();

        for (var resource : this.resources) {
            resource.free();
        }
    }

    // ---

    @Override
    public int width() {
        return this.scaledWidth;
    }

    @Override
    public int height() {
        return this.scaledHeight;
    }

    @Override
    public double scaleFactor() {
        return this.scaleFactor;
    }

    @Override
    public EventSource<ResizeCallback> onResize() {
        return this.onResize.source();
    }

    @Override
    public CursorStyle currentCursorStyle() {
        return this.cursorController.currentStyle();
    }

    @Override
    public void setCursorStyle(CursorStyle style) {
        this.cursorController.setStyle(style);
    }

    // ---

    @Override
    public void beginRendering() {
        RenderSystem.getDevice().createCommandEncoder().clearColorAndDepthTextures(
            this.remoteTarget.getColorTexture(),
            0xFF000000,
            this.remoteTarget.getDepthTexture(),
            1
        );
    }

    @Override
    public void endRendering() {
        this.guiRenderer.render(new BraidGuiRenderer.Target(
            this.remoteTarget,
            this
        ));

        // ---

        withContext(this.handle, () -> {
            GL32.glBindFramebuffer(GL32.GL_READ_FRAMEBUFFER, this.localFbo);
            GL32.glBindFramebuffer(GL32.GL_DRAW_FRAMEBUFFER, 0);

            GL32.glBlitFramebuffer(
                0, 0, this.framebufferWidth, this.framebufferHeight,
                0, 0, this.framebufferWidth, this.framebufferHeight,
                GL32.GL_COLOR_BUFFER_BIT,
                GL32.GL_NEAREST
            );

            GLFW.glfwSwapBuffers(this.handle);
        });
    }

    // ---

    private <R extends NativeResource> R storeNativeResource(R resource) {
        this.resources.add(resource);
        return resource;
    }

    public static void withContext(long contextHandle, Runnable fn) {
        var activeContext = GLFW.glfwGetCurrentContext();

        try {
            GLFW.glfwMakeContextCurrent(contextHandle);
            fn.run();
        } finally {
            GLFW.glfwMakeContextCurrent(activeContext);
        }
    }

    // ---

    public static class WindowEventBinding extends EventBinding {

        public final BraidWindow window;

        public WindowEventBinding(BraidWindow window) {
            this.window = window;
        }

        @Override
        public boolean isKeyPressed(int keyCode) {
            return GLFW.glfwGetKey(this.window.handle, keyCode) == GLFW.GLFW_PRESS;
        }
    }

    public record OpenResult(AppState state, BraidWindow window) {}
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/BraidWindowScheduler.java
================================================
package io.wispforest.owo.braid.core;

import io.wispforest.owo.ui.event.ClientRenderCallback;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.minecraft.client.Minecraft;

import java.util.ArrayList;
import java.util.List;

public class BraidWindowScheduler {

    private static final List<App> APPS = new ArrayList<>();

    public static void add(BraidWindow window, AppState app) {
        APPS.add(new App(window, app));
    }

    private static void frame() {
        for (var app : new ArrayList<>(APPS)) {
            if (!app.state().running()) {
                app.state().dispose();

                APPS.remove(app);
                continue;
            }

            app.state().processEvents(
                Minecraft.getInstance().getDeltaTracker().getGameTimeDeltaTicks()
            );

            app.state().draw(app.surface().guiRenderer.newGraphics(app.state().cursorPosition().x(), app.state().cursorPosition().y()));
        }
    }

    static {
        ClientRenderCallback.BEFORE_SWAP.register(client -> frame());
        ClientLifecycleEvents.CLIENT_STOPPING.register(client -> {
            APPS.forEach(app -> app.state().dispose());
            APPS.clear();
        });
    }
}

record App(BraidWindow surface, AppState state) {}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/Color.java
================================================
package io.wispforest.owo.braid.core;

import net.minecraft.ChatFormatting;
import net.minecraft.util.Mth;

public class Color {

    public static final Color RED = Color.values(1, 0, 0);
    public static final Color YELLOW = Color.values(1, 1, 0);
    public static final Color GREEN = Color.values(0, 1, 0);
    public static final Color AQUA = Color.values(0, 1, 1);
    public static final Color BLUE = Color.values(0, 0, 1);
    public static final Color MAGENTA = Color.values(1, 0, 1);
    public static final Color WHITE = Color.values(1, 1, 1);
    public static final Color BLACK = Color.values(0, 0, 0);

    //

    public final double r, g, b, a;

    private Color(double r, double g, double b, double a) {
        this.r = r;
        this.g = g;
        this.b = b;
        this.a = a;
    }

    // ---

    public Color(int argb) {
        this(
            ((argb >> 16) & 0xFF) / 255.0,
            ((argb >> 8) & 0xFF) / 255.0,
            (argb & 0xFF) / 255.0,
            (argb >>> 24) / 255.0
        );
    }

    public static Color values(double r, double g, double b, double a) {
        return new Color(r, g, b, a);
    }

    public static Color values(double r, double g, double b) {
        return values(r, g, b, 1);
    }

    public static Color rgb(int rgb) {
        return values(
            ((rgb >> 16) & 0xFF) / 255.0,
            ((rgb >> 8) & 0xFF) / 255.0,
            (rgb & 0xFF) / 255.0
        );
    }

    public static Color hsv(double hue, double saturation, double value, double alpha) {
        // we call .5e-7f the magic "do not turn a hue value of 1f into yellow" constant
        return new Color((int) (alpha * 255) << 24 | Mth.hsvToRgb((float) (hue - .5e-7f), (float) saturation, (float) value));
    }

    public static Color hsv(double hue, double saturation, double value) {
        return hsv(hue, saturation, value, 1);
    }

    public static Color formatting(ChatFormatting formatting) {
        var rgb = formatting.getColor();
        return rgb(rgb != null ? rgb : 0);
    }

    public static Color mix(double t, Color a, Color b) {
        return Color.values(
            Mth.lerp(t, a.r, b.r),
            Mth.lerp(t, a.g, b.g),
            Mth.lerp(t, a.b, b.b),
            Mth.lerp(t, a.a, b.a)
        );
    }

    public static Color randomHue() {
        return hsv(Math.random(), .75, 1);
    }

    // ---

    public io.wispforest.owo.ui.core.Color toOwoUi() {
        return new io.wispforest.owo.ui.core.Color(
            (float) this.r, (float) this.g, (float) this.b, (float) this.a
        );
    }

    public String toHexString(boolean includeAlpha) {
        return includeAlpha
            ? String.format("#%08X", this.argb())
            : String.format("#%06X", this.rgb());
    }

    //

    public Color withR(double r) {
        return new Color(r, this.g, this.b, this.a);
    }

    public Color withG(double g) {
        return new Color(this.r, g, this.b, this.a);
    }

    public Color withB(double b) {
        return new Color(this.r, this.g, b, this.a);
    }

    public Color withA(double a) {
        return new Color(this.r, this.g, this.b, a);
    }

    // ---

    public int rgb() {
        return (int) (this.r * 255) << 16
            | (int) (this.g * 255) << 8
            | (int) (this.b * 255);
    }

    public int argb() {
        return (int) (this.a * 255) << 24
            | (int) (this.r * 255) << 16
            | (int) (this.g * 255) << 8
            | (int) (this.b * 255);
    }

    public float[] hsv() {
        return this.toOwoUi().hsv();
    }

    @Override
    public boolean equals(Object o) {
        if (o == null || this.getClass() != o.getClass()) return false;

        var other = (Color) o;
        return this.r == other.r
            && this.g == other.g
            && this.b == other.b
            && this.a == other.a;
    }

    @Override
    public int hashCode() {
        int result = Double.hashCode(r);
        result = 31 * result + Double.hashCode(g);
        result = 31 * result + Double.hashCode(b);
        result = 31 * result + Double.hashCode(a);
        return result;
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/CompoundListenable.java
================================================
package io.wispforest.owo.braid.core;

import java.util.ArrayList;
import java.util.List;

public class CompoundListenable extends Listenable {

    protected final Runnable listener = this::notifyListeners;
    protected final List<Listenable> children = new ArrayList<>();

    public CompoundListenable(Listenable... initialChildren) {
        for (var child : initialChildren) {
            this.addChild(child);
        }
    }

    public void addChild(Listenable child) {
        this.children.add(child);
        child.addListener(this.listener);
    }

    public void removeChild(Listenable child) {
        this.children.remove(child);
        child.removeListener(this.listener);
    }

    public void clear() {
        for (var child : this.children) {
            child.removeListener(this.listener);
        }

        this.children.clear();
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/Constraints.java
================================================
package io.wispforest.owo.braid.core;

import net.minecraft.util.Mth;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;

public record Constraints(double minWidth, double minHeight, double maxWidth, double maxHeight) {

    private static final Constraints UNCONSTRAINED = new Constraints(0, 0, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);

    @ApiStatus.Internal
    @Deprecated(forRemoval = true)
    public Constraints {}

    public static Constraints unconstrained() {
        return UNCONSTRAINED;
    }

    public static Constraints of(double minWidth, double minHeight, double maxWidth, double maxHeight) {
        return new Constraints(minWidth, minHeight, maxWidth, maxHeight);
    }

    public static Constraints ofMinWidth(double minWidth) {
        return new Constraints(minWidth, 0, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
    }

    public static Constraints ofMinHeight(double minHeight) {
        return new Constraints(0, minHeight, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
    }

    public static Constraints ofMaxWidth(double maxWidth) {
        return new Constraints(0, 0, maxWidth, Double.POSITIVE_INFINITY);
    }

    public static Constraints ofMaxHeight(double maxHeight) {
        return new Constraints(0, 0, Double.POSITIVE_INFINITY, maxHeight);
    }

    public static Constraints only(@Nullable Double minWidth, @Nullable Double minHeight, @Nullable Double maxWidth, @Nullable Double maxHeight) {
        return new Constraints(
            minWidth != null ? minWidth : 0,
            minHeight != null ? minHeight : 0,
            maxWidth != null ? maxWidth : Double.POSITIVE_INFINITY,
            maxHeight != null ? maxHeight : Double.POSITIVE_INFINITY
        );
    }

    public static Constraints tight(Size exactSize) {
        return new Constraints(exactSize.width(), exactSize.height(), exactSize.width(), exactSize.height());
    }

    public static Constraints loose(Size maxSize) {
        return new Constraints(0, 0, maxSize.width(), maxSize.height());
    }

    public static Constraints tightOnAxis(@Nullable Double horizontal, @Nullable Double vertical) {
        return only(horizontal, vertical, horizontal, vertical);
    }

    // ---

    public Constraints withMinWidth(double minWidth) {
        return new Constraints(minWidth, this.minHeight, this.maxWidth, this.maxHeight);
    }

    public Constraints withMinHeight(double minHeight) {
        return new Constraints(this.minWidth, minHeight, this.maxWidth, this.maxHeight);
    }

    public Constraints withMaxWidth(double maxWidth) {
        return new Constraints(this.minWidth, this.minHeight, maxWidth, this.maxHeight);
    }

    public Constraints withMaxHeight(double maxHeight) {
        return new Constraints(this.minWidth, this.minHeight, this.maxWidth, maxHeight);
    }

    // ---

    public double minOnAxis(LayoutAxis axis) {
        return switch (axis) {
            case HORIZONTAL -> this.minWidth();
            case VERTICAL -> this.minHeight();
        };
    }

    public double maxOnAxis(LayoutAxis axis) {
        return switch (axis) {
            case HORIZONTAL -> this.maxWidth();
            case VERTICAL -> this.maxHeight();
        };
    }

    public double maxFiniteOrMinOnAxis(LayoutAxis axis) {
        return switch (axis) {
            case HORIZONTAL -> this.maxFiniteOrMinWidth();
            case VERTICAL -> this.maxFiniteOrMinHeight();
        };
    }

    public double maxFiniteOrMinWidth() {
        return this.hasBoundedWidth() ? this.maxWidth() : this.minWidth();
    }

    public double maxFiniteOrMinHeight() {
        return this.hasBoundedHeight() ? this.maxHeight() : this.minHeight();
    }

    // ---

    public Constraints asLoose() {
        return this.isLoose() ? this : new Constraints(0, 0, this.maxWidth, this.maxHeight);
    }

    public Constraints respecting(Constraints other) {
        if (this.minWidth >= other.minWidth && this.minWidth <= other.maxWidth
            && this.maxWidth >= other.minWidth && this.maxWidth <= other.maxWidth
            && this.minHeight >= other.minHeight && this.minHeight <= other.maxHeight
            && this.maxHeight >= other.minHeight && this.maxHeight <= other.maxHeight) {
            return this;
        }

        return new Constraints(
            Mth.clamp(this.minWidth, other.minWidth, other.maxWidth),
            Mth.clamp(this.minHeight, other.minHeight, other.maxHeight),
            Mth.clamp(this.maxWidth, other.minWidth, other.maxWidth),
            Mth.clamp(this.maxHeight, other.minHeight, other.maxHeight)
        );
    }

    public boolean hasLooseWidth() {
        return this.minWidth == 0;
    }

    public boolean hasLooseHeight() {
        return this.minHeight == 0;
    }

    public boolean hasTightWidth() {
        return this.minWidth == this.maxWidth;
    }

    public boolean hasTightHeight() {
        return this.minHeight == this.maxHeight;
    }

    public boolean isLoose() {
        return this.hasLooseWidth() && this.hasLooseHeight();
    }

    public boolean isTight() {
        return this.hasTightWidth() && this.hasTightHeight();
    }

    public boolean hasBoundedWidth() {
        return this.maxWidth < Double.POSITIVE_INFINITY;
    }

    public boolean hasBoundedHeight() {
        return this.maxHeight < Double.POSITIVE_INFINITY;
    }

    public Size minSize() {
        return Size.of(this.minWidth, this.minHeight);
    }

    public Size maxSize() {
        return Size.of(this.maxWidth, this.maxHeight);
    }

    public Size maxFiniteOrMinSize() {
        return Size.of(
            this.maxFiniteOrMinWidth(),
            this.maxFiniteOrMinHeight()
        );
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/EventBinding.java
================================================
package io.wispforest.owo.braid.core;

import com.mojang.blaze3d.platform.InputConstants;
import io.wispforest.owo.braid.core.events.UserEvent;
import net.minecraft.client.Minecraft;
import org.lwjgl.glfw.GLFW;

import java.util.ArrayList;
import java.util.List;

public abstract class EventBinding {

    private final List<EventSlot> bufferedEvents = new ArrayList<>();

    public EventSlot add(UserEvent event) {
        var slot = new EventSlot(event);
        this.bufferedEvents.add(slot);

        return slot;
    }

    List<EventSlot> poll() {
        var events = new ArrayList<>(this.bufferedEvents);
        this.bufferedEvents.clear();

        return events;
    }

    public abstract boolean isKeyPressed(int keyCode);

    public KeyModifiers activeModifiers() {
        return new KeyModifiers(
            (this.isKeyPressed(GLFW.GLFW_KEY_LEFT_SHIFT) || this.isKeyPressed(GLFW.GLFW_KEY_RIGHT_SHIFT) ? GLFW.GLFW_MOD_SHIFT : 0)
            | (this.isKeyPressed(GLFW.GLFW_KEY_LEFT_CONTROL) || this.isKeyPressed(GLFW.GLFW_KEY_RIGHT_CONTROL) ? GLFW.GLFW_MOD_CONTROL : 0)
            | (this.isKeyPressed(GLFW.GLFW_KEY_LEFT_ALT) || this.isKeyPressed(GLFW.GLFW_KEY_RIGHT_ALT) ? GLFW.GLFW_MOD_ALT : 0)
            | (this.isKeyPressed(GLFW.GLFW_KEY_RIGHT_SUPER) || this.isKeyPressed(GLFW.GLFW_KEY_RIGHT_SUPER) ? GLFW.GLFW_MOD_SUPER : 0)
            | (this.isKeyPressed(GLFW.GLFW_KEY_NUM_LOCK) ? GLFW.GLFW_MOD_NUM_LOCK : 0)
            | (this.isKeyPressed(GLFW.GLFW_KEY_CAPS_LOCK) ? GLFW.GLFW_MOD_CAPS_LOCK : 0)
        );
    }

    public static class EventSlot {
        final UserEvent event;
        private boolean handled = false;

        public EventSlot(UserEvent event) {
            this.event = event;
        }

        public boolean handled() {
            return this.handled;
        }

        void markHandled() {
            this.handled = true;
        }
    }

    // ---

    public static class Headless extends EventBinding {
        @Override
        public boolean isKeyPressed(int keyCode) {
            return false;
        }
    }

    public static class Default extends EventBinding {
        @Override
        public boolean isKeyPressed(int keyCode) {
            return InputConstants.isKeyDown(Minecraft.getInstance().getWindow(), keyCode);
        }
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/Insets.java
================================================
package io.wispforest.owo.braid.core;

import org.jetbrains.annotations.ApiStatus;

public record Insets(double top, double bottom, double left, double right) {

    private static final Insets NONE = new Insets(0, 0, 0, 0);

    @ApiStatus.Internal
    @Deprecated(forRemoval = true)
    public Insets {}

    // ---

    public static Insets of(double top, double bottom, double left, double right) {
        return new Insets(top, bottom, left, right);
    }

    public static Insets all(double inset) {
        return new Insets(inset, inset, inset, inset);
    }

    public static Insets both(double horizontal, double vertical) {
        return new Insets(vertical, vertical, horizontal, horizontal);
    }

    public static Insets top(double top) {
        return new Insets(top, 0, 0, 0);
    }

    public static Insets bottom(double bottom) {
        return new Insets(0, bottom, 0, 0);
    }

    public static Insets left(double left) {
        return new Insets(0, 0, left, 0);
    }

    public static Insets right(double right) {
        return new Insets(0, 0, 0, right);
    }

    public static Insets vertical(double inset) {
        return new Insets(inset, inset, 0, 0);
    }

    public static Insets horizontal(double inset) {
        return new Insets(0, 0, inset, inset);
    }

    public static Insets none() {
        return NONE;
    }

    // ---

    public Insets withTop(double top) {
        return new Insets(top, this.bottom, this.left, this.right);
    }

    public Insets withBottom(double bottom) {
        return new Insets(this.top, bottom, this.left, this.right);
    }

    public Insets withLeft(double left) {
        return new Insets(this.top, this.bottom, left, this.right);
    }

    public Insets withRight(double right) {
        return new Insets(this.top, this.bottom, this.left, right);
    }

    public double horizontal() {
        return this.left + this.right;
    }

    public double vertical() {
        return this.top + this.bottom;
    }
}


================================================
FILE: src/main/java/io/wispforest/owo/braid/core/KeyModifiers.java
================================================
package io.wispforest.owo.braid.core;

import it.unimi.dsi.fastutil.ints.IntList;

import static org.lwjgl.glfw.GLFW.*;

public record KeyModifiers(int bitMask) {
    public static final KeyModifiers NONE = new KeyModifiers(0);

    public boolean shift() {
        return (this.bitMask & GLFW_MOD_SHIFT) != 0;
    }

    public boolean ctrl() {
        return (this.bitMask & GLFW_MOD_CONTROL) != 0;
    }

    public boolean alt() {
        return (this.bitMask & GLFW_MOD_ALT) != 0;
    }

    public boolean meta() {
        return (this.bitMask & GLFW_MOD_SUPER) != 0;
    }

    public boolean capsLock() {
        return (this.bitMask & GLFW_MOD_CAPS_
Download .txt
gitextract_0mpxqol_/

├── .github/
│   └── workflows/
│       └── build.yml
├── .gitignore
├── LICENSE
├── README.md
├── braid-reload-agent/
│   ├── .gitattributes
│   ├── .gitignore
│   ├── build.gradle.kts
│   ├── gradle/
│   │   ├── libs.versions.toml
│   │   └── wrapper/
│   │       ├── gradle-wrapper.jar
│   │       └── gradle-wrapper.properties
│   ├── gradlew
│   ├── gradlew.bat
│   ├── settings.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── io/
│                   └── wispforest/
│                       └── BraidReloadAgent.java
├── build.gradle
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── jitpack.yml
├── owo-sentinel/
│   ├── build.gradle
│   ├── gradle.properties
│   └── src/
│       └── main/
│           ├── java/
│           │   └── io/
│           │       └── wispforest/
│           │           └── owosentinel/
│           │               ├── DownloadTask.java
│           │               ├── Maldenhagen.java
│           │               ├── OwoSentinel.java
│           │               ├── SentinelConsole.java
│           │               └── SentinelWindow.java
│           └── resources/
│               └── fabric.mod.json
├── owo-ui.xsd
├── settings.gradle
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── io/
│   │   │       └── wispforest/
│   │   │           └── owo/
│   │   │               ├── Owo.java
│   │   │               ├── blockentity/
│   │   │               │   ├── LinearProcess.java
│   │   │               │   └── LinearProcessExecutor.java
│   │   │               ├── braid/
│   │   │               │   ├── animation/
│   │   │               │   │   ├── AlignmentLerp.java
│   │   │               │   │   ├── Animation.java
│   │   │               │   │   ├── AutomaticallyAnimatedWidget.java
│   │   │               │   │   ├── ColorLerp.java
│   │   │               │   │   ├── DoubleLerp.java
│   │   │               │   │   ├── Easing.java
│   │   │               │   │   ├── InsetsLerp.java
│   │   │               │   │   ├── Lerp.java
│   │   │               │   │   └── NullableLerp.java
│   │   │               │   ├── core/
│   │   │               │   │   ├── Aabb2d.java
│   │   │               │   │   ├── Alignment.java
│   │   │               │   │   ├── AppState.java
│   │   │               │   │   ├── BraidGraphics.java
│   │   │               │   │   ├── BraidHotReloadCallback.java
│   │   │               │   │   ├── BraidRenderPipelines.java
│   │   │               │   │   ├── BraidScreen.java
│   │   │               │   │   ├── BraidUtils.java
│   │   │               │   │   ├── BraidWindow.java
│   │   │               │   │   ├── BraidWindowScheduler.java
│   │   │               │   │   ├── Color.java
│   │   │               │   │   ├── CompoundListenable.java
│   │   │               │   │   ├── Constraints.java
│   │   │               │   │   ├── EventBinding.java
│   │   │               │   │   ├── Insets.java
│   │   │               │   │   ├── KeyModifiers.java
│   │   │               │   │   ├── LayoutAxis.java
│   │   │               │   │   ├── Listenable.java
│   │   │               │   │   ├── ListenableValue.java
│   │   │               │   │   ├── RelativePosition.java
│   │   │               │   │   ├── Size.java
│   │   │               │   │   ├── Surface.java
│   │   │               │   │   ├── TextLayout.java
│   │   │               │   │   ├── TextureSurface.java
│   │   │               │   │   ├── cursor/
│   │   │               │   │   │   ├── CursorController.java
│   │   │               │   │   │   ├── CursorStyle.java
│   │   │               │   │   │   └── SystemCursorStyle.java
│   │   │               │   │   ├── element/
│   │   │               │   │   │   ├── BraidBlockElement.java
│   │   │               │   │   │   ├── BraidDashedLineElement.java
│   │   │               │   │   │   ├── BraidEntityElement.java
│   │   │               │   │   │   └── BraidItemElement.java
│   │   │               │   │   └── events/
│   │   │               │   │       ├── CharInputEvent.java
│   │   │               │   │       ├── CloseEvent.java
│   │   │               │   │       ├── FilesDroppedEvent.java
│   │   │               │   │       ├── KeyPressEvent.java
│   │   │               │   │       ├── KeyReleaseEvent.java
│   │   │               │   │       ├── MouseButtonPressEvent.java
│   │   │               │   │       ├── MouseButtonReleaseEvent.java
│   │   │               │   │       ├── MouseMoveEvent.java
│   │   │               │   │       ├── MouseScrollEvent.java
│   │   │               │   │       └── UserEvent.java
│   │   │               │   ├── display/
│   │   │               │   │   ├── BraidDisplay.java
│   │   │               │   │   ├── BraidDisplayBinding.java
│   │   │               │   │   └── DisplayQuad.java
│   │   │               │   ├── framework/
│   │   │               │   │   ├── BuildContext.java
│   │   │               │   │   ├── instance/
│   │   │               │   │   │   ├── CustomWidgetTransform.java
│   │   │               │   │   │   ├── Hit.java
│   │   │               │   │   │   ├── HitTestState.java
│   │   │               │   │   │   ├── InspectorProperty.java
│   │   │               │   │   │   ├── InstanceHost.java
│   │   │               │   │   │   ├── LeafWidgetInstance.java
│   │   │               │   │   │   ├── MouseListener.java
│   │   │               │   │   │   ├── MultiChildWidgetInstance.java
│   │   │               │   │   │   ├── OptionalChildWidgetInstance.java
│   │   │               │   │   │   ├── SingleChildWidgetInstance.java
│   │   │               │   │   │   ├── TooltipProvider.java
│   │   │               │   │   │   ├── WidgetInstance.java
│   │   │               │   │   │   └── WidgetTransform.java
│   │   │               │   │   ├── proxy/
│   │   │               │   │   │   ├── BuildScope.java
│   │   │               │   │   │   ├── ComposedProxy.java
│   │   │               │   │   │   ├── InheritedProxy.java
│   │   │               │   │   │   ├── InstanceWidgetProxy.java
│   │   │               │   │   │   ├── LeafInstanceWidgetProxy.java
│   │   │               │   │   │   ├── MultiChildInstanceWidgetProxy.java
│   │   │               │   │   │   ├── OptionalChildInstanceWidgetProxy.java
│   │   │               │   │   │   ├── ProxyHost.java
│   │   │               │   │   │   ├── SingleChildInstanceWidgetProxy.java
│   │   │               │   │   │   ├── StatefulProxy.java
│   │   │               │   │   │   ├── StatelessProxy.java
│   │   │               │   │   │   ├── WidgetProxy.java
│   │   │               │   │   │   └── WidgetState.java
│   │   │               │   │   └── widget/
│   │   │               │   │       ├── InheritedWidget.java
│   │   │               │   │       ├── InstanceWidget.java
│   │   │               │   │       ├── Key.java
│   │   │               │   │       ├── LeafInstanceWidget.java
│   │   │               │   │       ├── MultiChildInstanceWidget.java
│   │   │               │   │       ├── OptionalChildInstanceWidget.java
│   │   │               │   │       ├── SingleChildInstanceWidget.java
│   │   │               │   │       ├── StatefulWidget.java
│   │   │               │   │       ├── StatelessWidget.java
│   │   │               │   │       ├── Widget.java
│   │   │               │   │       └── WidgetSetupCallback.java
│   │   │               │   ├── util/
│   │   │               │   │   ├── BraidGuiRenderer.java
│   │   │               │   │   ├── BraidHudElement.java
│   │   │               │   │   ├── BraidToast.java
│   │   │               │   │   ├── BraidTooltipComponent.java
│   │   │               │   │   ├── EmbedderRoot.java
│   │   │               │   │   ├── kdl/
│   │   │               │   │   │   ├── BraidKdlEndecs.java
│   │   │               │   │   │   ├── KdlDeserializer.java
│   │   │               │   │   │   ├── KdlElement.java
│   │   │               │   │   │   ├── KdlEntityWidget.java
│   │   │               │   │   │   ├── KdlMapper.java
│   │   │               │   │   │   └── WidgetEndec.java
│   │   │               │   │   └── layers/
│   │   │               │   │       ├── AnchorJustification.java
│   │   │               │   │       ├── BraidLayersBinding.java
│   │   │               │   │       ├── Justify.java
│   │   │               │   │       ├── LayerAlignment.java
│   │   │               │   │       └── LayerContext.java
│   │   │               │   └── widgets/
│   │   │               │       ├── BraidApp.java
│   │   │               │       ├── BraidLogo.java
│   │   │               │       ├── Dialog.java
│   │   │               │       ├── HoverStyledLabel.java
│   │   │               │       ├── Marquee.java
│   │   │               │       ├── Navigator.java
│   │   │               │       ├── SpriteWidget.java
│   │   │               │       ├── animated/
│   │   │               │       │   ├── AnimatedAlign.java
│   │   │               │       │   ├── AnimatedBox.java
│   │   │               │       │   ├── AnimatedPadding.java
│   │   │               │       │   └── AnimatedSized.java
│   │   │               │       ├── basic/
│   │   │               │       │   ├── Align.java
│   │   │               │       │   ├── AspectRatio.java
│   │   │               │       │   ├── Blur.java
│   │   │               │       │   ├── Box.java
│   │   │               │       │   ├── Builder.java
│   │   │               │       │   ├── Center.java
│   │   │               │       │   ├── Clip.java
│   │   │               │       │   ├── Constrain.java
│   │   │               │       │   ├── ConstraintWidget.java
│   │   │               │       │   ├── ControlsOverride.java
│   │   │               │       │   ├── CustomDraw.java
│   │   │               │       │   ├── EmptyWidget.java
│   │   │               │       │   ├── HitTestTrap.java
│   │   │               │       │   ├── HoverableBuilder.java
│   │   │               │       │   ├── IntrinsicHeight.java
│   │   │               │       │   ├── IntrinsicWidth.java
│   │   │               │       │   ├── LayoutBuilder.java
│   │   │               │       │   ├── ListenableBuilder.java
│   │   │               │       │   ├── MouseArea.java
│   │   │               │       │   ├── Padding.java
│   │   │               │       │   ├── Panel.java
│   │   │               │       │   ├── RotatedLayout.java
│   │   │               │       │   ├── Sized.java
│   │   │               │       │   ├── TextureWidget.java
│   │   │               │       │   ├── Tooltip.java
│   │   │               │       │   ├── Transform.java
│   │   │               │       │   ├── Visibility.java
│   │   │               │       │   └── VisitorWidget.java
│   │   │               │       ├── button/
│   │   │               │       │   ├── Button.java
│   │   │               │       │   ├── ButtonPanel.java
│   │   │               │       │   ├── ButtonStyle.java
│   │   │               │       │   ├── Clickable.java
│   │   │               │       │   ├── DefaultButtonStyle.java
│   │   │               │       │   └── MessageButton.java
│   │   │               │       ├── checkbox/
│   │   │               │       │   ├── Checkbox.java
│   │   │               │       │   ├── CheckboxStyle.java
│   │   │               │       │   ├── DefaultCheckboxStyle.java
│   │   │               │       │   └── TogglingClickable.java
│   │   │               │       ├── collapsible/
│   │   │               │       │   ├── Collapsible.java
│   │   │               │       │   ├── CollapsibleCallback.java
│   │   │               │       │   └── LazyCollapsible.java
│   │   │               │       ├── combobox/
│   │   │               │       │   ├── ComboBox.java
│   │   │               │       │   ├── ComboBoxButtons.java
│   │   │               │       │   └── ComboBoxButtonsState.java
│   │   │               │       ├── cycle/
│   │   │               │       │   ├── Cycler.java
│   │   │               │       │   ├── CyclingButton.java
│   │   │               │       │   ├── CyclingClickable.java
│   │   │               │       │   └── MessageCyclingButton.java
│   │   │               │       ├── drag/
│   │   │               │       │   ├── DragArena.java
│   │   │               │       │   ├── DragArenaElement.java
│   │   │               │       │   ├── DragArenaInstance.java
│   │   │               │       │   └── DragParentData.java
│   │   │               │       ├── eventstream/
│   │   │               │       │   ├── BraidEventSource.java
│   │   │               │       │   ├── BraidEventStream.java
│   │   │               │       │   └── StreamListenerState.java
│   │   │               │       ├── flex/
│   │   │               │       │   ├── Column.java
│   │   │               │       │   ├── CrossAxisAlignment.java
│   │   │               │       │   ├── Flex.java
│   │   │               │       │   ├── FlexInstance.java
│   │   │               │       │   ├── FlexParentData.java
│   │   │               │       │   ├── Flexible.java
│   │   │               │       │   ├── MainAxisAlignment.java
│   │   │               │       │   └── Row.java
│   │   │               │       ├── focus/
│   │   │               │       │   ├── FocusClickArea.java
│   │   │               │       │   ├── FocusLevel.java
│   │   │               │       │   ├── FocusPolicy.java
│   │   │               │       │   ├── FocusScope.java
│   │   │               │       │   ├── FocusStateProvider.java
│   │   │               │       │   ├── FocusTraversalDirection.java
│   │   │               │       │   ├── Focusable.java
│   │   │               │       │   └── RootFocusScope.java
│   │   │               │       ├── grid/
│   │   │               │       │   └── Grid.java
│   │   │               │       ├── inspector/
│   │   │               │       │   ├── BraidInspector.java
│   │   │               │       │   ├── CollapsibleEntry.java
│   │   │               │       │   ├── InspectorState.java
│   │   │               │       │   ├── InspectorWidget.java
│   │   │               │       │   ├── InstanceDetails.java
│   │   │               │       │   ├── InstancePicker.java
│   │   │               │       │   ├── InstanceTitle.java
│   │   │               │       │   ├── InstanceTreeView.java
│   │   │               │       │   └── RevealInstanceEvent.java
│   │   │               │       ├── intents/
│   │   │               │       │   ├── Action.java
│   │   │               │       │   ├── Actions.java
│   │   │               │       │   ├── AdjustIntent.java
│   │   │               │       │   ├── Intent.java
│   │   │               │       │   ├── Interactable.java
│   │   │               │       │   ├── PrimaryActionIntent.java
│   │   │               │       │   ├── SecondaryActionIntent.java
│   │   │               │       │   ├── ShortcutDecoder.java
│   │   │               │       │   ├── ShortcutTrigger.java
│   │   │               │       │   ├── Shortcuts.java
│   │   │               │       │   ├── TraverseFocusAction.java
│   │   │               │       │   ├── TraverseFocusIntent.java
│   │   │               │       │   ├── Trigger.java
│   │   │               │       │   └── TriggerType.java
│   │   │               │       ├── label/
│   │   │               │       │   ├── DefaultLabelStyle.java
│   │   │               │       │   ├── Label.java
│   │   │               │       │   ├── LabelStyle.java
│   │   │               │       │   └── RawLabel.java
│   │   │               │       ├── object/
│   │   │               │       │   ├── BlockWidget.java
│   │   │               │       │   ├── EntityWidget.java
│   │   │               │       │   ├── ItemStackWidget.java
│   │   │               │       │   └── RawBlockWidget.java
│   │   │               │       ├── overlay/
│   │   │               │       │   ├── Overlay.java
│   │   │               │       │   ├── OverlayEntry.java
│   │   │               │       │   ├── OverlayEntryBuilder.java
│   │   │               │       │   ├── OverlayParentData.java
│   │   │               │       │   ├── OverlayProvider.java
│   │   │               │       │   ├── RawOverlay.java
│   │   │               │       │   └── RawOverlayElement.java
│   │   │               │       ├── owoui/
│   │   │               │       │   ├── OwoUIWidget.java
│   │   │               │       │   └── OwoUIWidgetWrapper.java
│   │   │               │       ├── recipeviewer/
│   │   │               │       │   ├── RecipeViewerExclusionZone.java
│   │   │               │       │   ├── RecipeViewerStack.java
│   │   │               │       │   └── StackDropArea.java
│   │   │               │       ├── scroll/
│   │   │               │       │   ├── ButtonScrollbar.java
│   │   │               │       │   ├── DefaultScrollAnimationSettings.java
│   │   │               │       │   ├── FlatScrollbar.java
│   │   │               │       │   ├── HorizontallyScrollable.java
│   │   │               │       │   ├── RawScrollView.java
│   │   │               │       │   ├── ScrollAnimationSettings.java
│   │   │               │       │   ├── ScrollController.java
│   │   │               │       │   ├── Scrollable.java
│   │   │               │       │   ├── ScrollableWithBars.java
│   │   │               │       │   ├── Scrollbar.java
│   │   │               │       │   └── VerticallyScrollable.java
│   │   │               │       ├── sharedstate/
│   │   │               │       │   ├── ShareableState.java
│   │   │               │       │   ├── SharedState.java
│   │   │               │       │   └── SharedStateProvider.java
│   │   │               │       ├── slider/
│   │   │               │       │   ├── DefaultSliderHandle.java
│   │   │               │       │   ├── Incrementor.java
│   │   │               │       │   ├── SliderStyle.java
│   │   │               │       │   ├── drag/
│   │   │               │       │   │   ├── Drag.java
│   │   │               │       │   │   ├── DragFunction.java
│   │   │               │       │   │   ├── MessageDrag.java
│   │   │               │       │   │   └── RawDrag.java
│   │   │               │       │   ├── range/
│   │   │               │       │   │   ├── DefaultRangeSliderStyle.java
│   │   │               │       │   │   ├── MessageRangeSlider.java
│   │   │               │       │   │   ├── RangeSlider.java
│   │   │               │       │   │   ├── RangeSliderCallback.java
│   │   │               │       │   │   └── RangeSliderStyle.java
│   │   │               │       │   ├── slider/
│   │   │               │       │   │   ├── DefaultSliderStyle.java
│   │   │               │       │   │   ├── MessageSlider.java
│   │   │               │       │   │   ├── Slider.java
│   │   │               │       │   │   ├── SliderCallback.java
│   │   │               │       │   │   └── SliderFunction.java
│   │   │               │       │   └── xlyder/
│   │   │               │       │       ├── DefaultXlyderStyle.java
│   │   │               │       │       ├── MessageXlyder.java
│   │   │               │       │       ├── Xlyder.java
│   │   │               │       │       └── XlyderCallback.java
│   │   │               │       ├── splitpane/
│   │   │               │       │   ├── MultiSplitPane.java
│   │   │               │       │   └── SplitPane.java
│   │   │               │       ├── stack/
│   │   │               │       │   ├── Stack.java
│   │   │               │       │   ├── StackBase.java
│   │   │               │       │   └── StackParentData.java
│   │   │               │       ├── textinput/
│   │   │               │       │   ├── CopyTextIntent.java
│   │   │               │       │   ├── DeleteLineIntent.java
│   │   │               │       │   ├── DeleteTextIntent.java
│   │   │               │       │   ├── EditableText.java
│   │   │               │       │   ├── InsertNewlineIntent.java
│   │   │               │       │   ├── InsertTabIntent.java
│   │   │               │       │   ├── MaxLengthFormatter.java
│   │   │               │       │   ├── MoveCursorIntent.java
│   │   │               │       │   ├── PasteTextIntent.java
│   │   │               │       │   ├── PatternFormatter.java
│   │   │               │       │   ├── SelectAllIntent.java
│   │   │               │       │   ├── TeleportCursorIntent.java
│   │   │               │       │   ├── TextBox.java
│   │   │               │       │   ├── TextEditingController.java
│   │   │               │       │   ├── TextEditingValue.java
│   │   │               │       │   ├── TextInput.java
│   │   │               │       │   └── TextSelection.java
│   │   │               │       ├── vanilla/
│   │   │               │       │   ├── VanillaWidget.java
│   │   │               │       │   └── VanillaWidgetWrapper.java
│   │   │               │       └── window/
│   │   │               │           ├── Window.java
│   │   │               │           └── WindowController.java
│   │   │               ├── client/
│   │   │               │   ├── OwoClient.java
│   │   │               │   ├── screens/
│   │   │               │   │   ├── MenuNetworkingInternals.java
│   │   │               │   │   ├── MenuUtils.java
│   │   │               │   │   ├── OwoAbstractContainerMenu.java
│   │   │               │   │   ├── ScreenhandlerMessageData.java
│   │   │               │   │   ├── SlotGenerator.java
│   │   │               │   │   ├── SyncedProperty.java
│   │   │               │   │   └── ValidatingSlot.java
│   │   │               │   └── texture/
│   │   │               │       ├── AnimatedTextureDrawable.java
│   │   │               │       └── SpriteSheetMetadata.java
│   │   │               ├── command/
│   │   │               │   ├── EnumArgumentType.java
│   │   │               │   └── debug/
│   │   │               │       ├── CcaDataCommand.java
│   │   │               │       ├── DumpdataCommand.java
│   │   │               │       ├── HealCommand.java
│   │   │               │       ├── MakeLootContainerCommand.java
│   │   │               │       └── OwoDebugCommands.java
│   │   │               ├── compat/
│   │   │               │   ├── emi/
│   │   │               │   │   ├── EmiStackUtil.java
│   │   │               │   │   └── OwoEmiPlugin.java
│   │   │               │   ├── modmenu/
│   │   │               │   │   └── OwoModMenuPlugin.java
│   │   │               │   └── rei/
│   │   │               │       ├── OwoReiPlugin.java
│   │   │               │       ├── ReiStackUtil.java
│   │   │               │       ├── ReiUIAdapter.java
│   │   │               │       └── ReiWidgetComponent.java
│   │   │               ├── config/
│   │   │               │   ├── ConfigAP.java
│   │   │               │   ├── ConfigSynchronizer.java
│   │   │               │   ├── ConfigWrapper.java
│   │   │               │   ├── Option.java
│   │   │               │   ├── OwoConfigCommand.java
│   │   │               │   ├── annotation/
│   │   │               │   │   ├── Config.java
│   │   │               │   │   ├── ExcludeFromScreen.java
│   │   │               │   │   ├── Expanded.java
│   │   │               │   │   ├── Hook.java
│   │   │               │   │   ├── Modmenu.java
│   │   │               │   │   ├── Nest.java
│   │   │               │   │   ├── PredicateConstraint.java
│   │   │               │   │   ├── RangeConstraint.java
│   │   │               │   │   ├── RegexConstraint.java
│   │   │               │   │   ├── RestartRequired.java
│   │   │               │   │   ├── SectionHeader.java
│   │   │               │   │   ├── Sync.java
│   │   │               │   │   └── WithAlpha.java
│   │   │               │   └── ui/
│   │   │               │       ├── ConfigScreen.java
│   │   │               │       ├── ConfigScreenProviders.java
│   │   │               │       ├── OptionComponentFactory.java
│   │   │               │       ├── OptionComponents.java
│   │   │               │       ├── RestartRequiredScreen.java
│   │   │               │       └── component/
│   │   │               │           ├── ConfigEnumButton.java
│   │   │               │           ├── ConfigSlider.java
│   │   │               │           ├── ConfigTextBox.java
│   │   │               │           ├── ConfigToggleButton.java
│   │   │               │           ├── ListOptionContainer.java
│   │   │               │           ├── OptionValueProvider.java
│   │   │               │           └── SearchAnchorComponent.java
│   │   │               ├── ext/
│   │   │               │   ├── DerivedComponentMap.java
│   │   │               │   └── OwoItem.java
│   │   │               ├── itemgroup/
│   │   │               │   ├── Icon.java
│   │   │               │   ├── ItemGroupReference.java
│   │   │               │   ├── OwoItemGroup.java
│   │   │               │   ├── OwoItemSettingsExtension.java
│   │   │               │   ├── gui/
│   │   │               │   │   ├── ItemGroupButton.java
│   │   │               │   │   ├── ItemGroupButtonWidget.java
│   │   │               │   │   └── ItemGroupTab.java
│   │   │               │   └── json/
│   │   │               │       ├── OwoItemGroupLoader.java
│   │   │               │       └── WrapperGroup.java
│   │   │               ├── mixin/
│   │   │               │   ├── AbstractContainerMenuInvoker.java
│   │   │               │   ├── AbstractContainerMenuMixin.java
│   │   │               │   ├── ClientCommonPacketListenerImplAccessor.java
│   │   │               │   ├── ClientConfigurationPacketListenerImplMixin.java
│   │   │               │   ├── ClientHandshakePacketListenerImplAccessor.java
│   │   │               │   ├── ConnectionMixin.java
│   │   │               │   ├── Copenhagen.java
│   │   │               │   ├── GuiGraphicsMixin.java
│   │   │               │   ├── MainMixin.java
│   │   │               │   ├── MinecraftMixin.java
│   │   │               │   ├── ServerCommonPacketListenerImplAccessor.java
│   │   │               │   ├── ServerPlayerGameModeMixin.java
│   │   │               │   ├── ServerPlayerMixin.java
│   │   │               │   ├── SetComponentsFunctionAccessor.java
│   │   │               │   ├── TagLoaderMixin.java
│   │   │               │   ├── braid/
│   │   │               │   │   ├── ClickableStyleFinderAccessor.java
│   │   │               │   │   ├── GameRendererAccessor.java
│   │   │               │   │   ├── GuiRendererAccessor.java
│   │   │               │   │   ├── GuiRendererMixin.java
│   │   │               │   │   ├── KeyboardHandlerMixin.java
│   │   │               │   │   ├── LevelRendererMixin.java
│   │   │               │   │   ├── Matrix3x2fStackAccessor.java
│   │   │               │   │   ├── RenderTypeInvoker.java
│   │   │               │   │   ├── ScreenMixin.java
│   │   │               │   │   └── ToastManagerMixin.java
│   │   │               │   ├── ext/
│   │   │               │   │   ├── ItemMixin.java
│   │   │               │   │   ├── ItemStackMixin.java
│   │   │               │   │   ├── PatchedDataComponentMapAccessor.java
│   │   │               │   │   └── PatchedDataComponentMapMixin.java
│   │   │               │   ├── extension/
│   │   │               │   │   ├── SimpleJsonResourceReloadListenerMixin.java
│   │   │               │   │   ├── json5/
│   │   │               │   │   │   ├── FallbackResourceManagerMixin.java
│   │   │               │   │   │   ├── FileToIdConverterMixin.java
│   │   │               │   │   │   ├── LanguageReaderMixin.java
│   │   │               │   │   │   └── MultiPackResourceManagerMixin.java
│   │   │               │   │   └── recipe/
│   │   │               │   │       ├── RecipeManagerAccessor.java
│   │   │               │   │       └── ResultSlotMixin.java
│   │   │               │   ├── itemgroup/
│   │   │               │   │   ├── CreativeModeInventoryScreenAccessor.java
│   │   │               │   │   ├── CreativeModeInventoryScreenMixin.java
│   │   │               │   │   ├── CreativeModeTabAccessor.java
│   │   │               │   │   ├── EffectsInInventoryMixin.java
│   │   │               │   │   ├── ItemMixin.java
│   │   │               │   │   ├── ItemSettingsMixin.java
│   │   │               │   │   ├── MinecraftMixin.java
│   │   │               │   │   └── MixinCreativeModeInventoryScreenMixin.java
│   │   │               │   ├── registry/
│   │   │               │   │   ├── MappedRegistryMixin.java
│   │   │               │   │   └── ReferenceAccessor.java
│   │   │               │   ├── serialization/
│   │   │               │   │   ├── CachedRegistryInfoGetterAccessor.java
│   │   │               │   │   ├── CompoundTagMixin.java
│   │   │               │   │   ├── DataComponentTypeBuilderMixin.java
│   │   │               │   │   ├── DataResultMixin.java
│   │   │               │   │   ├── DelegatingOpsAccessor.java
│   │   │               │   │   ├── FriendlyByteBufMixin.java
│   │   │               │   │   ├── RegistryOpsAccessor.java
│   │   │               │   │   ├── TagValueInputMixin.java
│   │   │               │   │   ├── TagValueOutputMixin.java
│   │   │               │   │   ├── ValueInputMixin.java
│   │   │               │   │   └── ValueOutputMixin.java
│   │   │               │   ├── shader/
│   │   │               │   │   └── GlProgramAccessor.java
│   │   │               │   ├── text/
│   │   │               │   │   ├── ClientLanguageMixin.java
│   │   │               │   │   ├── ComponentSerializationMixin.java
│   │   │               │   │   ├── LanguageMixin.java
│   │   │               │   │   ├── TranslatableContentsAccessor.java
│   │   │               │   │   ├── TranslatableContentsMixin.java
│   │   │               │   │   └── stapi/
│   │   │               │   │       └── SystemDelegatedLanguageFixin.java
│   │   │               │   ├── tweaks/
│   │   │               │   │   ├── EditBoxMixin.java
│   │   │               │   │   ├── EulaMixin.java
│   │   │               │   │   ├── LevelSettingsMixin.java
│   │   │               │   │   └── OperatingSystemMixin.java
│   │   │               │   └── ui/
│   │   │               │       ├── AbstractContainerScreenMixin.java
│   │   │               │       ├── AbstractSliderButtonMixin.java
│   │   │               │       ├── AbstractWidgetMixin.java
│   │   │               │       ├── ChatScreenMixin.java
│   │   │               │       ├── CubeMapMixin.java
│   │   │               │       ├── EditBoxMixin.java
│   │   │               │       ├── GuiRendererMixin.java
│   │   │               │       ├── MinecraftMixin.java
│   │   │               │       ├── MultiLineEditBoxMixin.java
│   │   │               │       ├── ScreenMixin.java
│   │   │               │       ├── SlotAccessor.java
│   │   │               │       ├── SlotMixin.java
│   │   │               │       ├── access/
│   │   │               │       │   ├── AbstractWidgetAccessor.java
│   │   │               │       │   ├── BaseOwoHandledScreenAccessor.java
│   │   │               │       │   ├── BlockEntityAccessor.java
│   │   │               │       │   ├── ButtonAccessor.java
│   │   │               │       │   ├── CheckboxAccessor.java
│   │   │               │       │   ├── EditBoxAccessor.java
│   │   │               │       │   ├── EntityRendererAccessor.java
│   │   │               │       │   ├── GlCommandEncoderAccessor.java
│   │   │               │       │   ├── GuiGraphicsAccessor.java
│   │   │               │       │   ├── MultiLineEditBoxAccessor.java
│   │   │               │       │   ├── MultilineTextFieldAccessor.java
│   │   │               │       │   ├── RenderSystemAccessor.java
│   │   │               │       │   └── TextBoxComponentAccessor.java
│   │   │               │       ├── display/
│   │   │               │       │   ├── GameRendererMixin.java
│   │   │               │       │   ├── GuiMixin.java
│   │   │               │       │   ├── MinecraftMixin.java
│   │   │               │       │   └── MouseHandlerMixin.java
│   │   │               │       └── layers/
│   │   │               │           ├── AbstractContainerScreenAccessor.java
│   │   │               │           ├── KeyboardHandlerMixin.java
│   │   │               │           ├── MouseHandlerMixin.java
│   │   │               │           └── ScreenMixin.java
│   │   │               ├── moddata/
│   │   │               │   ├── ModDataConsumer.java
│   │   │               │   └── ModDataLoader.java
│   │   │               ├── network/
│   │   │               │   ├── ClientAccess.java
│   │   │               │   ├── NetworkException.java
│   │   │               │   ├── OwoClientConnectionExtension.java
│   │   │               │   ├── OwoHandshake.java
│   │   │               │   ├── OwoNetChannel.java
│   │   │               │   ├── QueuedChannelSet.java
│   │   │               │   └── ServerAccess.java
│   │   │               ├── ops/
│   │   │               │   ├── ItemOps.java
│   │   │               │   ├── LevelOps.java
│   │   │               │   ├── LootOps.java
│   │   │               │   └── TextOps.java
│   │   │               ├── particles/
│   │   │               │   ├── ClientParticles.java
│   │   │               │   └── systems/
│   │   │               │       ├── ParticleSystem.java
│   │   │               │       ├── ParticleSystemController.java
│   │   │               │       └── ParticleSystemExecutor.java
│   │   │               ├── registration/
│   │   │               │   ├── ComplexRegistryAction.java
│   │   │               │   ├── RegistryHelper.java
│   │   │               │   ├── annotations/
│   │   │               │   │   ├── AssignedName.java
│   │   │               │   │   ├── IterationIgnored.java
│   │   │               │   │   └── RegistryNamespace.java
│   │   │               │   └── reflect/
│   │   │               │       ├── AutoRegistryContainer.java
│   │   │               │       ├── BlockEntityRegistryContainer.java
│   │   │               │       ├── FieldProcessingSubject.java
│   │   │               │       ├── FieldRegistrationHandler.java
│   │   │               │       └── SimpleFieldProcessingSubject.java
│   │   │               ├── renderdoc/
│   │   │               │   ├── RenderDoc.java
│   │   │               │   ├── RenderdocLibrary.java
│   │   │               │   └── RenderdocScreen.java
│   │   │               ├── serialization/
│   │   │               │   ├── CodecUtils.java
│   │   │               │   ├── EndecRecipeSerializer.java
│   │   │               │   ├── OwoDataComponentTypeBuilder.java
│   │   │               │   ├── RegistriesAttribute.java
│   │   │               │   ├── endec/
│   │   │               │   │   ├── EitherEndec.java
│   │   │               │   │   ├── KeyedEndecDecodeError.java
│   │   │               │   │   ├── KeyedEndecEncodeError.java
│   │   │               │   │   ├── MinecraftEndecs.java
│   │   │               │   │   ├── NonNullListEndec.java
│   │   │               │   │   └── StructEitherEndec.java
│   │   │               │   └── format/
│   │   │               │       ├── ContextHolder.java
│   │   │               │       ├── DynamicOpsWithContext.java
│   │   │               │       ├── edm/
│   │   │               │       │   └── EdmOps.java
│   │   │               │       └── nbt/
│   │   │               │           ├── NbtDeserializer.java
│   │   │               │           ├── NbtEndec.java
│   │   │               │           └── NbtSerializer.java
│   │   │               ├── text/
│   │   │               │   ├── CursedTranslatableContents.java
│   │   │               │   ├── CustomTextRegistry.java
│   │   │               │   ├── InsertingTextContent.java
│   │   │               │   ├── LanguageAccess.java
│   │   │               │   ├── NestedLangHandler.java
│   │   │               │   ├── TextLanguage.java
│   │   │               │   └── TranslationContext.java
│   │   │               ├── ui/
│   │   │               │   ├── base/
│   │   │               │   │   ├── BaseOwoContainerScreen.java
│   │   │               │   │   ├── BaseOwoScreen.java
│   │   │               │   │   ├── BaseOwoToast.java
│   │   │               │   │   ├── BaseOwoTooltipComponent.java
│   │   │               │   │   ├── BaseParentUIComponent.java
│   │   │               │   │   ├── BaseUIComponent.java
│   │   │               │   │   ├── BaseUIModelContainerScreen.java
│   │   │               │   │   └── BaseUIModelScreen.java
│   │   │               │   ├── component/
│   │   │               │   │   ├── BlockComponent.java
│   │   │               │   │   ├── BoxComponent.java
│   │   │               │   │   ├── BraidComponent.java
│   │   │               │   │   ├── ButtonComponent.java
│   │   │               │   │   ├── CheckboxComponent.java
│   │   │               │   │   ├── ColorPickerComponent.java
│   │   │               │   │   ├── DiscreteSliderComponent.java
│   │   │               │   │   ├── DropdownComponent.java
│   │   │               │   │   ├── EntityComponent.java
│   │   │               │   │   ├── ItemComponent.java
│   │   │               │   │   ├── LabelComponent.java
│   │   │               │   │   ├── SliderComponent.java
│   │   │               │   │   ├── SlimSliderComponent.java
│   │   │               │   │   ├── SmallCheckboxComponent.java
│   │   │               │   │   ├── SpacerComponent.java
│   │   │               │   │   ├── SpriteComponent.java
│   │   │               │   │   ├── TextAreaComponent.java
│   │   │               │   │   ├── TextBoxComponent.java
│   │   │               │   │   ├── TextureComponent.java
│   │   │               │   │   ├── UIComponents.java
│   │   │               │   │   └── VanillaWidgetComponent.java
│   │   │               │   ├── container/
│   │   │               │   │   ├── CollapsibleContainer.java
│   │   │               │   │   ├── DraggableContainer.java
│   │   │               │   │   ├── FlowLayout.java
│   │   │               │   │   ├── GridLayout.java
│   │   │               │   │   ├── OverlayContainer.java
│   │   │               │   │   ├── ScrollContainer.java
│   │   │               │   │   ├── StackLayout.java
│   │   │               │   │   ├── UIContainers.java
│   │   │               │   │   └── WrappingParentUIComponent.java
│   │   │               │   ├── core/
│   │   │               │   │   ├── Animatable.java
│   │   │               │   │   ├── AnimatableProperty.java
│   │   │               │   │   ├── Animation.java
│   │   │               │   │   ├── Color.java
│   │   │               │   │   ├── CursorStyle.java
│   │   │               │   │   ├── Easing.java
│   │   │               │   │   ├── HorizontalAlignment.java
│   │   │               │   │   ├── Insets.java
│   │   │               │   │   ├── OwoUIAdapter.java
│   │   │               │   │   ├── OwoUIGraphics.java
│   │   │               │   │   ├── OwoUIPipelines.java
│   │   │               │   │   ├── ParentUIComponent.java
│   │   │               │   │   ├── PositionedRectangle.java
│   │   │               │   │   ├── Positioning.java
│   │   │               │   │   ├── Size.java
│   │   │               │   │   ├── Sizing.java
│   │   │               │   │   ├── Surface.java
│   │   │               │   │   ├── UIComponent.java
│   │   │               │   │   └── VerticalAlignment.java
│   │   │               │   ├── event/
│   │   │               │   │   ├── CharTyped.java
│   │   │               │   │   ├── ClientRenderCallback.java
│   │   │               │   │   ├── FocusGained.java
│   │   │               │   │   ├── FocusLost.java
│   │   │               │   │   ├── KeyPress.java
│   │   │               │   │   ├── MouseDown.java
│   │   │               │   │   ├── MouseDrag.java
│   │   │               │   │   ├── MouseEnter.java
│   │   │               │   │   ├── MouseLeave.java
│   │   │               │   │   ├── MouseScroll.java
│   │   │               │   │   ├── MouseUp.java
│   │   │               │   │   └── WindowResizeCallback.java
│   │   │               │   ├── hud/
│   │   │               │   │   ├── Hud.java
│   │   │               │   │   ├── HudContainer.java
│   │   │               │   │   └── HudInspectorScreen.java
│   │   │               │   ├── inject/
│   │   │               │   │   ├── GreedyInputUIComponent.java
│   │   │               │   │   └── UIComponentStub.java
│   │   │               │   ├── layers/
│   │   │               │   │   ├── Layer.java
│   │   │               │   │   └── Layers.java
│   │   │               │   ├── parsing/
│   │   │               │   │   ├── ConfigureHotReloadScreen.java
│   │   │               │   │   ├── IncompatibleUIModelException.java
│   │   │               │   │   ├── UIModel.java
│   │   │               │   │   ├── UIModelLoader.java
│   │   │               │   │   ├── UIModelParsingException.java
│   │   │               │   │   └── UIParsing.java
│   │   │               │   ├── renderstate/
│   │   │               │   │   ├── BlockElementRenderState.java
│   │   │               │   │   ├── BlurQuadElementRenderState.java
│   │   │               │   │   ├── CircleElementRenderState.java
│   │   │               │   │   ├── CubeMapElementRenderState.java
│   │   │               │   │   ├── EntityElementRenderState.java
│   │   │               │   │   ├── GradientQuadElementRenderState.java
│   │   │               │   │   ├── LineElementRenderState.java
│   │   │               │   │   ├── OwoItemElementRenderState.java
│   │   │               │   │   ├── OwoSpecialGuiElementRenderers.java
│   │   │               │   │   └── RingElementRenderState.java
│   │   │               │   └── util/
│   │   │               │       ├── CommandOpenedScreen.java
│   │   │               │       ├── CursorAdapter.java
│   │   │               │       ├── Delta.java
│   │   │               │       ├── DisposableScreen.java
│   │   │               │       ├── FocusHandler.java
│   │   │               │       ├── MatrixStackTransformer.java
│   │   │               │       ├── MountingHelper.java
│   │   │               │       ├── NinePatchTexture.java
│   │   │               │       ├── SpriteUtilInvoker.java
│   │   │               │       ├── UIErrorToast.java
│   │   │               │       └── UISounds.java
│   │   │               └── util/
│   │   │                   ├── DataExtensionUtil.java
│   │   │                   ├── EventSource.java
│   │   │                   ├── EventStream.java
│   │   │                   ├── ImplementedContainer.java
│   │   │                   ├── KawaiiUtil.java
│   │   │                   ├── Maldenhagen.java
│   │   │                   ├── NumberReflection.java
│   │   │                   ├── Observable.java
│   │   │                   ├── OwoFreezer.java
│   │   │                   ├── RecipeRemainderStorage.java
│   │   │                   ├── ReflectionUtils.java
│   │   │                   ├── Scary.java
│   │   │                   ├── ServicesFrozenException.java
│   │   │                   ├── StackTraceSupplier.java
│   │   │                   ├── TagInjector.java
│   │   │                   ├── VectorRandomUtils.java
│   │   │                   ├── VectorSerializer.java
│   │   │                   ├── ViewerStack.java
│   │   │                   ├── Wisdom.java
│   │   │                   └── pond/
│   │   │                       ├── BraidGuiRendererExtension.java
│   │   │                       ├── OwoAbstractContainerMenuExtension.java
│   │   │                       ├── OwoCreativeInventoryScreenExtensions.java
│   │   │                       ├── OwoItemExtensions.java
│   │   │                       ├── OwoScreenExtension.java
│   │   │                       ├── OwoSimpleRegistryExtensions.java
│   │   │                       ├── OwoSlotExtension.java
│   │   │                       ├── OwoTextRendererExtension.java
│   │   │                       └── package-info.java
│   │   └── resources/
│   │       ├── META-INF/
│   │       │   └── services/
│   │       │       └── javax.annotation.processing.Processor
│   │       ├── architectury.common.json
│   │       ├── assets/
│   │       │   └── owo/
│   │       │       ├── lang/
│   │       │       │   ├── en_us.json5
│   │       │       │   └── tt_ru.json5
│   │       │       ├── nine_patch_textures/
│   │       │       │   ├── braid_combobox/
│   │       │       │   │   ├── active.json
│   │       │       │   │   ├── disabled.json
│   │       │       │   │   └── hovered.json
│   │       │       │   ├── braid_debug_focused.json
│   │       │       │   ├── braid_debug_highlighted.json
│   │       │       │   ├── braid_inspector_selected.json
│   │       │       │   ├── button/
│   │       │       │   │   ├── active.json
│   │       │       │   │   ├── disabled.json
│   │       │       │   │   └── hovered.json
│   │       │       │   ├── panel/
│   │       │       │   │   ├── dark.json
│   │       │       │   │   ├── default.json
│   │       │       │   │   └── inset.json
│   │       │       │   ├── scrollbar/
│   │       │       │   │   ├── track.json
│   │       │       │   │   ├── vanilla_flat.json
│   │       │       │   │   ├── vanilla_horizontal.json
│   │       │       │   │   ├── vanilla_horizontal_disabled.json
│   │       │       │   │   ├── vanilla_vertical.json
│   │       │       │   │   └── vanilla_vertical_disabled.json
│   │       │       │   └── slim_slider_track.json
│   │       │       ├── owo_ui/
│   │       │       │   ├── config.xml
│   │       │       │   ├── configure_hot_reload.xml
│   │       │       │   └── restart_required.xml
│   │       │       ├── shaders/
│   │       │       │   └── core/
│   │       │       │       ├── blur.fsh
│   │       │       │       ├── blur.vsh
│   │       │       │       └── spectrum.fsh
│   │       │       ├── sounds/
│   │       │       │   └── ui_interaction.ogg
│   │       │       └── sounds.json
│   │       ├── fabric.mod.json
│   │       ├── owo-json5
│   │       ├── owo.accesswidener
│   │       └── owo.mixins.json
│   └── testmod/
│       ├── java/
│       │   └── io/
│       │       └── wispforest/
│       │           ├── owo/
│       │           │   └── samples/
│       │           │       └── braid/
│       │           │           ├── BraidSamplesItem.java
│       │           │           ├── LayoutWidgetExamples.java
│       │           │           ├── SharedCounter.java
│       │           │           ├── SimpleCounter.java
│       │           │           └── layout/
│       │           │               ├── BottomRightLogo.java
│       │           │               ├── Checkerboard.java
│       │           │               ├── LargeLogo.java
│       │           │               ├── LavaLogo.java
│       │           │               ├── NormalRow.java
│       │           │               ├── PaddedColumn.java
│       │           │               ├── PaddedLogo.java
│       │           │               ├── RGBStack.java
│       │           │               ├── SizeFactorLogo.java
│       │           │               ├── SquishedLogo.java
│       │           │               └── VerticalFlex.java
│       │           └── uwu/
│       │               ├── EpicMenu.java
│       │               ├── FabledBananasClass.java
│       │               ├── Uwu.java
│       │               ├── block/
│       │               │   ├── BraidDisplayBlock.java
│       │               │   └── BraidDisplayBlockEntity.java
│       │               ├── blockentity/
│       │               │   └── ProcessBlockEntity.java
│       │               ├── client/
│       │               │   ├── Bikeshed.java
│       │               │   ├── BraidDisplayBlockEntityRenderer.java
│       │               │   ├── ComponentTestScreen.java
│       │               │   ├── EpicContainerModelScreen.java
│       │               │   ├── EpicContainerScreen.java
│       │               │   ├── HudTestWidget.java
│       │               │   ├── LayersTestWidget.java
│       │               │   ├── ParseFailScreen.java
│       │               │   ├── ScissorTestScreen.java
│       │               │   ├── SelectUwuScreenScreen.java
│       │               │   ├── SizingTestScreen.java
│       │               │   ├── SmolComponentTestScreen.java
│       │               │   ├── TestConfigScreen.java
│       │               │   ├── TestParseScreen.java
│       │               │   ├── TooManyComponentsScreen.java
│       │               │   ├── UwuClient.java
│       │               │   ├── UwuConfigScreen.java
│       │               │   └── braid/
│       │               │       ├── SliderTests.java
│       │               │       └── TestSelector.java
│       │               ├── config/
│       │               │   ├── UowouConfigModel.java
│       │               │   └── UwuConfigModel.java
│       │               ├── items/
│       │               │   ├── UwuBraidItem.java
│       │               │   ├── UwuCounterItem.java
│       │               │   ├── UwuItems.java
│       │               │   ├── UwuScreenShardItem.java
│       │               │   └── UwuTestStickItem.java
│       │               ├── mixin/
│       │               │   ├── GlRenderPassMixin.java
│       │               │   └── TitleScreenMixin.java
│       │               ├── network/
│       │               │   ├── DispatchedInterface.java
│       │               │   ├── DispatchedSubclassOne.java
│       │               │   ├── DispatchedSubclassTwo.java
│       │               │   ├── KeycodePacket.java
│       │               │   ├── MaldingPacket.java
│       │               │   ├── NullablePacket.java
│       │               │   ├── SealedSubclassOne.java
│       │               │   ├── SealedSubclassTwo.java
│       │               │   ├── SealedTestClass.java
│       │               │   ├── StringPacket.java
│       │               │   ├── UwuNetworkExample.java
│       │               │   ├── UwuNetworkTest.java
│       │               │   └── UwuOptionalNetExample.java
│       │               ├── recipe/
│       │               │   └── UwuShapedRecipe.java
│       │               ├── rei/
│       │               │   ├── UiCategory.java
│       │               │   └── UwuReiPlugin.java
│       │               └── text/
│       │                   └── BasedTextContent.java
│       └── resources/
│           ├── assets/
│           │   ├── uowou/
│           │   │   ├── items/
│           │   │   │   └── owo_ingot.json5
│           │   │   └── models/
│           │   │       └── item/
│           │   │           └── owo_ingot.json5
│           │   └── uwu/
│           │       ├── blockstates/
│           │       │   └── braid_display.json5
│           │       ├── items/
│           │       │   ├── braid.json5
│           │       │   ├── braid_display.json5
│           │       │   ├── braid_samples.json5
│           │       │   ├── screen_shard.json
│           │       │   ├── screen_shard.json5
│           │       │   ├── test_stick.json
│           │       │   └── test_stick.json5
│           │       ├── lang/
│           │       │   └── en_us.json5
│           │       ├── models/
│           │       │   ├── block/
│           │       │   │   └── braid_display.json5
│           │       │   └── item/
│           │       │       ├── braid.json5
│           │       │       └── counter.json5
│           │       ├── nine_patch_textures/
│           │       │   └── contributors_panel.json5
│           │       ├── owo_ui/
│           │       │   ├── config.xml
│           │       │   ├── expand_gap_test.xml
│           │       │   ├── focus_cycle_test.xml
│           │       │   ├── parse_fail.xml
│           │       │   ├── smol_components.xml
│           │       │   ├── test_element_one.xml
│           │       │   └── test_element_two.xml
│           │       └── textures/
│           │           └── gui/
│           │               └── bikeshed.png.mcmeta
│           ├── data/
│           │   └── uwu/
│           │       ├── item_group_tabs/
│           │       │   ├── crab_group.json5
│           │       │   ├── food_and_drink_button.json5
│           │       │   ├── ingredients_extension.json5
│           │       │   └── ingredients_extension_2.json5
│           │       ├── recipe/
│           │       │   ├── test_recipe.json5
│           │       │   ├── uwu_shaped_recipe.json5
│           │       │   └── what_the_bucket_doin.json5
│           │       └── tags/
│           │           └── item/
│           │               └── tab_2_content.json5
│           ├── fabric.mod.json
│           ├── owo-json5
│           └── uwu.mixins.json
└── stylesheet.css
Download .txt
Showing preview only (493K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (5999 symbols across 678 files)

FILE: braid-reload-agent/src/main/java/io/wispforest/BraidReloadAgent.java
  class BraidReloadAgent (line 9) | public class BraidReloadAgent {
    method premain (line 10) | public static void premain(String agentArgs, Instrumentation instrumen...
  class RedefinitionListener (line 15) | class RedefinitionListener implements ClassFileTransformer {
    method transform (line 27) | @Override
    method fallible (line 75) | private static void fallible(Fallible fallible) {
  type Fallible (line 80) | interface Fallible {
    method body (line 81) | void body() throws Throwable;
    method run (line 83) | default void run() {

FILE: owo-sentinel/src/main/java/io/wispforest/owosentinel/DownloadTask.java
  class DownloadTask (line 6) | public class DownloadTask extends SwingWorker<Void, Void> {
    method DownloadTask (line 11) | public DownloadTask(Consumer<String> logger, Runnable whenDone) {
    method done (line 16) | @Override
    method doInBackground (line 21) | @Override

FILE: owo-sentinel/src/main/java/io/wispforest/owosentinel/Maldenhagen.java
  class Maldenhagen (line 6) | public class Maldenhagen implements LanguageAdapter {
    method create (line 7) | @Override

FILE: owo-sentinel/src/main/java/io/wispforest/owosentinel/OwoSentinel.java
  class OwoSentinel (line 22) | public class OwoSentinel {
    method launch (line 36) | public static void launch() {
    method listOwoDependents (line 53) | public static List<String> listOwoDependents() {
    method downloadAndInstall (line 77) | @SuppressWarnings("deprecation")

FILE: owo-sentinel/src/main/java/io/wispforest/owosentinel/SentinelConsole.java
  class SentinelConsole (line 6) | public class SentinelConsole {
    method run (line 7) | public static void run() throws Exception {

FILE: owo-sentinel/src/main/java/io/wispforest/owosentinel/SentinelWindow.java
  class SentinelWindow (line 12) | public class SentinelWindow {
    method open (line 13) | public static void open() throws Exception {

FILE: src/main/java/io/wispforest/owo/Owo.java
  class Owo (line 22) | public class Owo implements ModInitializer {
    method onInitialize (line 50) | @Override
    method debugWarn (line 67) | @ApiStatus.Internal
    method debugWarn (line 73) | @ApiStatus.Internal
    method currentServer (line 84) | public static MinecraftServer currentServer() {
    method id (line 89) | @ApiStatus.Internal

FILE: src/main/java/io/wispforest/owo/blockentity/LinearProcess.java
  class LinearProcess (line 32) | public class LinearProcess<T> {
    method LinearProcess (line 50) | public LinearProcess(int processLength) {
    method createExecutor (line 61) | public LinearProcessExecutor<T> createExecutor(T target) {
    method configureExecutor (line 73) | public void configureExecutor(LinearProcessExecutor<T> executor, boole...
    method addCommonStep (line 90) | public void addCommonStep(int when, int length, BiConsumer<LinearProce...
    method addClientStep (line 100) | public void addClientStep(int when, int length, BiConsumer<LinearProce...
    method addServerStep (line 109) | public void addServerStep(int when, int length, BiConsumer<LinearProce...
    method addCommonEvent (line 123) | public void addCommonEvent(int when, BiConsumer<LinearProcessExecutor<...
    method addClientEvent (line 131) | public void addClientEvent(int when, BiConsumer<LinearProcessExecutor<...
    method addServerEvent (line 138) | public void addServerEvent(int when, BiConsumer<LinearProcessExecutor<...
    method whenFinishedCommon (line 150) | public void whenFinishedCommon(BiConsumer<LinearProcessExecutor<T>, T>...
    method whenFinishedServer (line 158) | public void whenFinishedServer(BiConsumer<LinearProcessExecutor<T>, T>...
    method whenFinishedClient (line 165) | public void whenFinishedClient(BiConsumer<LinearProcessExecutor<T>, T>...
    method onCancelledCommon (line 177) | public void onCancelledCommon(BiConsumer<LinearProcessExecutor<T>, T> ...
    method onCancelledServer (line 185) | public void onCancelledServer(BiConsumer<LinearProcessExecutor<T>, T> ...
    method onCancelledClient (line 192) | public void onCancelledClient(BiConsumer<LinearProcessExecutor<T>, T> ...
    method runConditionally (line 203) | public void runConditionally(Predicate<LinearProcessExecutor<T>> condi...
    method finish (line 210) | public void finish() {
    method checkForIllegalModification (line 214) | private void checkForIllegalModification() {
    method eventAtIndex (line 218) | private void eventAtIndex(int index, Int2ObjectMap<BiConsumer<LinearPr...

FILE: src/main/java/io/wispforest/owo/blockentity/LinearProcessExecutor.java
  class LinearProcessExecutor (line 19) | public class LinearProcessExecutor<T> {
    method LinearProcessExecutor (line 35) | protected LinearProcessExecutor(T target, int processLength, Predicate...
    method configure (line 43) | protected void configure(Int2ObjectMap<BiConsumer<LinearProcessExecuto...
    method tick (line 48) | public void tick() {
    method begin (line 72) | public boolean begin() {
    method running (line 82) | @SuppressWarnings("BooleanMethodIsAlwaysInverted")
    method getProcessTick (line 90) | public int getProcessTick() {
    method getTarget (line 97) | public T getTarget() {
    method cancel (line 107) | public boolean cancel() {
    method finishIfAppropriate (line 118) | private boolean finishIfAppropriate() {
    method cancelIfAppropriate (line 129) | private boolean cancelIfAppropriate() {
    method writeState (line 140) | public void writeState(CompoundTag targetTag) {
    method readState (line 149) | public void readState(CompoundTag targetTag) {
    method createInfo (line 163) | public Info<T> createInfo(int index) {
    method createInfo (line 167) | public Info<T> createInfo(int index, int tick) {
    class Info (line 171) | public static final class Info<T> {
      method Info (line 178) | public Info(int index, ProcessStep<T> step) {
      method Info (line 183) | public Info(int index, int tick, ProcessStep<T> step) {
      method tick (line 189) | public boolean tick(LinearProcessExecutor<T> target) {

FILE: src/main/java/io/wispforest/owo/braid/animation/AlignmentLerp.java
  class AlignmentLerp (line 6) | public class AlignmentLerp extends Lerp<Alignment> {
    method AlignmentLerp (line 8) | public AlignmentLerp(Alignment start, Alignment end) {
    method at (line 12) | @Override

FILE: src/main/java/io/wispforest/owo/braid/animation/Animation.java
  class Animation (line 9) | public class Animation {
    method Animation (line 21) | public Animation(Easing easing, Duration duration, Scheduler scheduler...
    method Animation (line 30) | public Animation(Easing easing, Duration duration, Scheduler scheduler...
    method target (line 34) | public @Nullable Target target() {
    method progress (line 38) | public double progress() {
    method towards (line 42) | public void towards(Target target) {
    method towards (line 46) | public void towards(Target target, boolean restart) {
    method pause (line 58) | public void pause() {
    method stop (line 62) | public void stop() {
    method stop (line 66) | public void stop(@Nullable Target at) {
    method callback (line 73) | private void callback(Duration delta) {
    type Target (line 102) | public enum Target {
      method Target (line 109) | Target(long direction, double targetProgress) {
    type Listener (line 115) | @FunctionalInterface
      method onUpdate (line 117) | void onUpdate(double progress);
    type FinishListener (line 120) | @FunctionalInterface
      method onFinished (line 122) | void onFinished(Target atTarget);
    type Scheduler (line 125) | @FunctionalInterface
      method schedule (line 127) | void schedule(ProxyHost.AnimationCallback callback);

FILE: src/main/java/io/wispforest/owo/braid/animation/AutomaticallyAnimatedWidget.java
  class AutomaticallyAnimatedWidget (line 13) | public abstract class AutomaticallyAnimatedWidget extends StatefulWidget {
    method AutomaticallyAnimatedWidget (line 19) | protected AutomaticallyAnimatedWidget(Duration duration, Easing easing) {
    method createState (line 24) | @Override
    class State (line 27) | @SuppressWarnings({"unchecked", "rawtypes"})
      method callback (line 33) | private void callback(double progress) {
      method init (line 37) | @Override
      method didUpdateWidget (line 52) | @Override
      method visitLerps (line 74) | private void visitLerps(LerpVisitor visitor) {
      method animationValue (line 81) | protected double animationValue() {
      method visitLerp (line 85) | protected <L extends Lerp<V>, V> L visitLerp(@Nullable Lerp<V> previ...
      method visitNullableLerp (line 89) | protected <L extends Lerp<V>, V> L visitNullableLerp(@Nullable Lerp<...
      method updateLerps (line 93) | protected abstract void updateLerps();
    type LerpVisitor (line 96) | @FunctionalInterface
      method visit (line 98) | L visit(@Nullable Lerp<V> previous, V targetValue, Lerp.Factory<L, V...

FILE: src/main/java/io/wispforest/owo/braid/animation/ColorLerp.java
  class ColorLerp (line 5) | public class ColorLerp extends Lerp<Color> {
    method ColorLerp (line 7) | public ColorLerp(Color start, Color end) {
    method at (line 11) | @Override

FILE: src/main/java/io/wispforest/owo/braid/animation/DoubleLerp.java
  class DoubleLerp (line 5) | public class DoubleLerp extends Lerp<Double> {
    method DoubleLerp (line 7) | public DoubleLerp(Double start, Double end) {
    method at (line 11) | @Override

FILE: src/main/java/io/wispforest/owo/braid/animation/Easing.java
  class Easing (line 3) | public class Easing {
    method Easing (line 46) | public Easing(Function function) {
    method apply (line 50) | public final double apply(double x) {
    method compute (line 55) | protected double compute(double x) {
    type Function (line 59) | @FunctionalInterface
      method compute (line 61) | double compute(double x);

FILE: src/main/java/io/wispforest/owo/braid/animation/InsetsLerp.java
  class InsetsLerp (line 6) | public class InsetsLerp extends Lerp<Insets> {
    method InsetsLerp (line 8) | public InsetsLerp(Insets start, Insets end) {
    method at (line 12) | @Override

FILE: src/main/java/io/wispforest/owo/braid/animation/Lerp.java
  class Lerp (line 3) | public abstract class Lerp<T> {
    method Lerp (line 8) | protected Lerp(T start, T end) {
    method compute (line 13) | public T compute(double t) {
    method at (line 20) | protected abstract T at(double t);
    type Factory (line 28) | @FunctionalInterface
      method make (line 30) | T make(V start, V end);

FILE: src/main/java/io/wispforest/owo/braid/animation/NullableLerp.java
  class NullableLerp (line 5) | public class NullableLerp<T> extends Lerp<T> {
    method NullableLerp (line 9) | public NullableLerp(@Nullable T start, @Nullable T end, Lerp.Factory<L...
    method at (line 18) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/Aabb2d.java
  class Aabb2d (line 6) | public class Aabb2d {
    method Aabb2d (line 13) | public Aabb2d(double x, double y, double width, double height) {
    method minX (line 20) | public double minX() {
    method maxX (line 24) | public double maxX() {
    method minY (line 28) | public double minY() {
    method maxY (line 32) | public double maxY() {
    method transform (line 36) | public Aabb2d transform(Matrix3x2f matrix) {

FILE: src/main/java/io/wispforest/owo/braid/core/Alignment.java
  method of (line 22) | public static Alignment of(double horizontal, double vertical) {
  method alignHorizontal (line 26) | public double alignHorizontal(double space, double object) {
  method alignVertical (line 30) | public double alignVertical(double space, double object) {

FILE: src/main/java/io/wispforest/owo/braid/core/AppState.java
  class AppState (line 42) | public class AppState implements InstanceHost, ProxyHost {
    method AppState (line 86) | public AppState(
    method running (line 130) | public boolean running() {
    method onTerminate (line 134) | public void onTerminate(Runnable callback) {
    method scheduleShutdown (line 138) | public void scheduleShutdown() {
    method activateInspector (line 143) | public void activateInspector() {
    method draw (line 149) | public void draw(GuiGraphics graphics) {
    method processEvents (line 171) | public void processEvents(float frameDeltaInTicks) {
    method pollAndDispatchEvents (line 275) | private void pollAndDispatchEvents() {
    method rebuildRoot (line 425) | public void rebuildRoot() {
    method dispose (line 434) | public void dispose() {
    method hitTest (line 444) | private HitTestState hitTest() {
    method hitTest (line 448) | public HitTestState hitTest(double x, double y) {
    method client (line 457) | @Override
    method rootInstance (line 462) | public SingleChildWidgetInstance<?> rootInstance() {
    method flushLayoutQueue (line 471) | private boolean flushLayoutQueue() {
    method scheduleLayout (line 506) | @Override
    method notifySubtreeRebuild (line 511) | @Override
    method scheduleAnimationCallback (line 516) | @Override
    method scheduleDelayedCallback (line 521) | @Override
    method cancelDelayedCallback (line 531) | @Override
    method schedulePostLayoutCallback (line 536) | @Override
    method cursorPosition (line 541) | @Override
    method toString (line 546) | @Override
    method formatName (line 553) | public static String formatName(String category, Widget userRoot) {
    method formatName (line 558) | public static String formatName(String category, Widget userRoot, Stri...
    method of (line 563) | public static AppState of(BuildContext context) {
  method compareTo (line 573) | @Override
  class RootWidget (line 579) | class RootWidget extends SingleChildInstanceWidget {
    method RootWidget (line 583) | public RootWidget(Widget child, BuildScope rootBuildScope) {
    method proxy (line 588) | @Override
    method instantiate (line 593) | @Override
  class RootProxy (line 599) | class RootProxy extends SingleChildInstanceWidgetProxy {
    method RootProxy (line 600) | public RootProxy(RootWidget widget) {
    method buildScope (line 604) | @Override
    method mounted (line 609) | @Override
    method bootstrap (line 616) | void bootstrap(InstanceHost instanceHost, ProxyHost proxyHost) {
  class RootInstance (line 630) | class RootInstance extends SingleChildWidgetInstance.ShrinkWrap<RootWidg...
    method RootInstance (line 632) | public RootInstance(RootWidget widget) {
  class UserRoot (line 637) | class UserRoot extends VisitorWidget {
    method UserRoot (line 642) | public UserRoot(Consumer<WidgetProxy> proxyCallback, Consumer<WidgetIn...
    method proxy (line 652) | @Override
  class AppWidget (line 661) | class AppWidget extends InheritedWidget {
    method AppWidget (line 665) | protected AppWidget(AppState app, Widget child) {
    method mustRebuildDependents (line 670) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/BraidGraphics.java
  class BraidGraphics (line 18) | public class BraidGraphics extends OwoUIGraphics {
    method BraidGraphics (line 22) | protected BraidGraphics(Minecraft client, GuiRenderState renderState, ...
    method create (line 27) | public static BraidGraphics create(GuiGraphics grpahics, Surface surfa...
    method guiWidth (line 42) | @Override
    method guiHeight (line 47) | @Override
    method buildRectOutline (line 52) | public void buildRectOutline(double x, double y, double width, double ...
    method drawDashedLine (line 60) | public void drawDashedLine(RenderPipeline pipeline, double x1, double ...
    type RectEdgeBuilder (line 72) | @FunctionalInterface
      method edge (line 74) | void edge(double x1, double y1, double x2, double y2);
    class MatrixStack (line 77) | @SuppressWarnings("ExternalizableWithoutPublicNoArgConstructor")
      method MatrixStack (line 80) | public MatrixStack(Matrix3x2fc source) {
      method pushMatrix (line 85) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/BraidHotReloadCallback.java
  class BraidHotReloadCallback (line 14) | public final class BraidHotReloadCallback {
    method register (line 19) | public static Listener register() {
    method setupComplete (line 26) | @ApiStatus.Internal
    method invoke (line 31) | @ApiStatus.Internal
    class Listener (line 38) | public static class Listener {
      method poll (line 45) | public boolean poll() {
      method unregister (line 58) | public void unregister() {

FILE: src/main/java/io/wispforest/owo/braid/core/BraidRenderPipelines.java
  class BraidRenderPipelines (line 8) | public class BraidRenderPipelines {
    method register (line 21) | @ApiStatus.Internal

FILE: src/main/java/io/wispforest/owo/braid/core/BraidScreen.java
  class BraidScreen (line 17) | public class BraidScreen extends Screen implements DisposableScreen {
    method BraidScreen (line 26) | public BraidScreen(Settings settings, Widget rootWidget) {
    method BraidScreen (line 32) | public BraidScreen(Widget rootWidget) {
    method init (line 36) | @Override
    method render (line 56) | @Override
    method dispose (line 68) | @Override
    method isPauseScreen (line 73) | @Override
    method mouseClicked (line 78) | @Override
    method mouseReleased (line 84) | @Override
    method mouseScrolled (line 90) | @Override
    method keyPressed (line 96) | @Override
    method keyReleased (line 102) | @Override
    method charTyped (line 108) | @Override
    method maybeOf (line 116) | public static @Nullable BraidScreen maybeOf(BuildContext context) {
    class Settings (line 121) | public static class Settings {
  class BraidScreenProvider (line 127) | class BraidScreenProvider extends InheritedWidget {
    method BraidScreenProvider (line 131) | public BraidScreenProvider(BraidScreen screen, Widget child) {
    method mustRebuildDependents (line 136) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/BraidUtils.java
  class BraidUtils (line 5) | public class BraidUtils {
    method fold (line 6) | public static <S, T> T fold(Iterable<S> values, T initial, BiFunction<...

FILE: src/main/java/io/wispforest/owo/braid/core/BraidWindow.java
  class BraidWindow (line 31) | public class BraidWindow implements Surface {
    method BraidWindow (line 53) | public BraidWindow(long handle) {
    method recreateLocalFbo (line 136) | private void recreateLocalFbo() {
    method recalculateScale (line 154) | private void recalculateScale() {
    method create (line 183) | public static BraidWindow create(String title, int width, int height) {
    method open (line 210) | public static OpenResult open(String title, int width, int height, Wid...
    method dispose (line 227) | @Override
    method width (line 243) | @Override
    method height (line 248) | @Override
    method scaleFactor (line 253) | @Override
    method onResize (line 258) | @Override
    method currentCursorStyle (line 263) | @Override
    method setCursorStyle (line 268) | @Override
    method beginRendering (line 275) | @Override
    method endRendering (line 285) | @Override
    method storeNativeResource (line 311) | private <R extends NativeResource> R storeNativeResource(R resource) {
    method withContext (line 316) | public static void withContext(long contextHandle, Runnable fn) {
    class WindowEventBinding (line 329) | public static class WindowEventBinding extends EventBinding {
      method WindowEventBinding (line 333) | public WindowEventBinding(BraidWindow window) {
      method isKeyPressed (line 337) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/BraidWindowScheduler.java
  class BraidWindowScheduler (line 10) | public class BraidWindowScheduler {
    method add (line 14) | public static void add(BraidWindow window, AppState app) {
    method frame (line 18) | private static void frame() {

FILE: src/main/java/io/wispforest/owo/braid/core/Color.java
  class Color (line 6) | public class Color {
    method Color (line 21) | private Color(double r, double g, double b, double a) {
    method Color (line 30) | public Color(int argb) {
    method values (line 39) | public static Color values(double r, double g, double b, double a) {
    method values (line 43) | public static Color values(double r, double g, double b) {
    method rgb (line 47) | public static Color rgb(int rgb) {
    method hsv (line 55) | public static Color hsv(double hue, double saturation, double value, d...
    method hsv (line 60) | public static Color hsv(double hue, double saturation, double value) {
    method formatting (line 64) | public static Color formatting(ChatFormatting formatting) {
    method mix (line 69) | public static Color mix(double t, Color a, Color b) {
    method randomHue (line 78) | public static Color randomHue() {
    method toOwoUi (line 84) | public io.wispforest.owo.ui.core.Color toOwoUi() {
    method toHexString (line 90) | public String toHexString(boolean includeAlpha) {
    method withR (line 98) | public Color withR(double r) {
    method withG (line 102) | public Color withG(double g) {
    method withB (line 106) | public Color withB(double b) {
    method withA (line 110) | public Color withA(double a) {
    method rgb (line 116) | public int rgb() {
    method argb (line 122) | public int argb() {
    method hsv (line 129) | public float[] hsv() {
    method equals (line 133) | @Override
    method hashCode (line 144) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/CompoundListenable.java
  class CompoundListenable (line 6) | public class CompoundListenable extends Listenable {
    method CompoundListenable (line 11) | public CompoundListenable(Listenable... initialChildren) {
    method addChild (line 17) | public void addChild(Listenable child) {
    method removeChild (line 22) | public void removeChild(Listenable child) {
    method clear (line 27) | public void clear() {

FILE: src/main/java/io/wispforest/owo/braid/core/Constraints.java
  method unconstrained (line 15) | public static Constraints unconstrained() {
  method of (line 19) | public static Constraints of(double minWidth, double minHeight, double m...
  method ofMinWidth (line 23) | public static Constraints ofMinWidth(double minWidth) {
  method ofMinHeight (line 27) | public static Constraints ofMinHeight(double minHeight) {
  method ofMaxWidth (line 31) | public static Constraints ofMaxWidth(double maxWidth) {
  method ofMaxHeight (line 35) | public static Constraints ofMaxHeight(double maxHeight) {
  method only (line 39) | public static Constraints only(@Nullable Double minWidth, @Nullable Doub...
  method tight (line 48) | public static Constraints tight(Size exactSize) {
  method loose (line 52) | public static Constraints loose(Size maxSize) {
  method tightOnAxis (line 56) | public static Constraints tightOnAxis(@Nullable Double horizontal, @Null...
  method withMinWidth (line 62) | public Constraints withMinWidth(double minWidth) {
  method withMinHeight (line 66) | public Constraints withMinHeight(double minHeight) {
  method withMaxWidth (line 70) | public Constraints withMaxWidth(double maxWidth) {
  method withMaxHeight (line 74) | public Constraints withMaxHeight(double maxHeight) {
  method minOnAxis (line 80) | public double minOnAxis(LayoutAxis axis) {
  method maxOnAxis (line 87) | public double maxOnAxis(LayoutAxis axis) {
  method maxFiniteOrMinOnAxis (line 94) | public double maxFiniteOrMinOnAxis(LayoutAxis axis) {
  method maxFiniteOrMinWidth (line 101) | public double maxFiniteOrMinWidth() {
  method maxFiniteOrMinHeight (line 105) | public double maxFiniteOrMinHeight() {
  method asLoose (line 111) | public Constraints asLoose() {
  method respecting (line 115) | public Constraints respecting(Constraints other) {
  method hasLooseWidth (line 131) | public boolean hasLooseWidth() {
  method hasLooseHeight (line 135) | public boolean hasLooseHeight() {
  method hasTightWidth (line 139) | public boolean hasTightWidth() {
  method hasTightHeight (line 143) | public boolean hasTightHeight() {
  method isLoose (line 147) | public boolean isLoose() {
  method isTight (line 151) | public boolean isTight() {
  method hasBoundedWidth (line 155) | public boolean hasBoundedWidth() {
  method hasBoundedHeight (line 159) | public boolean hasBoundedHeight() {
  method minSize (line 163) | public Size minSize() {
  method maxSize (line 167) | public Size maxSize() {
  method maxFiniteOrMinSize (line 171) | public Size maxFiniteOrMinSize() {

FILE: src/main/java/io/wispforest/owo/braid/core/EventBinding.java
  class EventBinding (line 11) | public abstract class EventBinding {
    method add (line 15) | public EventSlot add(UserEvent event) {
    method poll (line 22) | List<EventSlot> poll() {
    method isKeyPressed (line 29) | public abstract boolean isKeyPressed(int keyCode);
    method activeModifiers (line 31) | public KeyModifiers activeModifiers() {
    class EventSlot (line 42) | public static class EventSlot {
      method EventSlot (line 46) | public EventSlot(UserEvent event) {
      method handled (line 50) | public boolean handled() {
      method markHandled (line 54) | void markHandled() {
    class Headless (line 61) | public static class Headless extends EventBinding {
      method isKeyPressed (line 62) | @Override
    class Default (line 68) | public static class Default extends EventBinding {
      method isKeyPressed (line 69) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/Insets.java
  method of (line 15) | public static Insets of(double top, double bottom, double left, double r...
  method all (line 19) | public static Insets all(double inset) {
  method both (line 23) | public static Insets both(double horizontal, double vertical) {
  method top (line 27) | public static Insets top(double top) {
  method bottom (line 31) | public static Insets bottom(double bottom) {
  method left (line 35) | public static Insets left(double left) {
  method right (line 39) | public static Insets right(double right) {
  method vertical (line 43) | public static Insets vertical(double inset) {
  method horizontal (line 47) | public static Insets horizontal(double inset) {
  method none (line 51) | public static Insets none() {
  method withTop (line 57) | public Insets withTop(double top) {
  method withBottom (line 61) | public Insets withBottom(double bottom) {
  method withLeft (line 65) | public Insets withLeft(double left) {
  method withRight (line 69) | public Insets withRight(double right) {
  method horizontal (line 73) | public double horizontal() {
  method vertical (line 77) | public double vertical() {

FILE: src/main/java/io/wispforest/owo/braid/core/KeyModifiers.java
  method shift (line 10) | public boolean shift() {
  method ctrl (line 14) | public boolean ctrl() {
  method alt (line 18) | public boolean alt() {
  method meta (line 22) | public boolean meta() {
  method capsLock (line 26) | public boolean capsLock() {
  method numLock (line 30) | public boolean numLock() {
  method isModifier (line 34) | public static boolean isModifier(int keyCode) {
  method both (line 38) | public static KeyModifiers both(KeyModifiers a, KeyModifiers b) {

FILE: src/main/java/io/wispforest/owo/braid/core/LayoutAxis.java
  type LayoutAxis (line 5) | public enum LayoutAxis {
    method choose (line 9) | public <T> T choose(T horizontal, T vertical) {
    method chooseCompute (line 16) | public <T> T chooseCompute(Supplier<T> horizontal, Supplier<T> vertica...
    method createSize (line 23) | public Size createSize(double extent, double crossExtent) {
    method opposite (line 30) | public LayoutAxis opposite() {

FILE: src/main/java/io/wispforest/owo/braid/core/Listenable.java
  class Listenable (line 6) | public abstract class Listenable {
    method addListener (line 10) | public void addListener(Runnable listener) {
    method removeListener (line 14) | public void removeListener(Runnable listener) {
    method notifyListeners (line 18) | protected void notifyListeners() {

FILE: src/main/java/io/wispforest/owo/braid/core/ListenableValue.java
  class ListenableValue (line 3) | public class ListenableValue<V> extends Listenable {
    method ListenableValue (line 7) | public ListenableValue(V value) {
    method value (line 11) | public V value() {
    method setValue (line 15) | public void setValue(V value) {

FILE: src/main/java/io/wispforest/owo/braid/core/RelativePosition.java
  method convertTo (line 11) | public Vector2d convertTo(BuildContext ancestor) {

FILE: src/main/java/io/wispforest/owo/braid/core/Size.java
  method zero (line 17) | public static Size zero() {
  method of (line 21) | public static Size of(double width, double height) {
  method square (line 25) | public static Size square(double sideLength) {
  method max (line 29) | public static Size max(Size a, Size b) {
  method withInsets (line 35) | public Size withInsets(Insets insets) {
  method with (line 39) | public Size with(@Nullable Double width, @Nullable Double height) {
  method floor (line 43) | public Size floor() {
  method ceil (line 47) | public Size ceil() {
  method getExtent (line 51) | public double getExtent(LayoutAxis axis) {
  method constrained (line 58) | public Size constrained(Constraints constraints) {

FILE: src/main/java/io/wispforest/owo/braid/core/Surface.java
  type Surface (line 11) | public interface Surface {
    method width (line 13) | int width();
    method height (line 14) | int height();
    method scaleFactor (line 15) | double scaleFactor();
    method onResize (line 17) | EventSource<ResizeCallback> onResize();
    method currentCursorStyle (line 19) | CursorStyle currentCursorStyle();
    method setCursorStyle (line 20) | void setCursorStyle(CursorStyle style);
    method beginRendering (line 22) | void beginRendering();
    method endRendering (line 23) | void endRendering();
    method dispose (line 25) | void dispose();
    class Default (line 27) | class Default implements Surface {
      method Default (line 34) | public Default() {
      method width (line 47) | @Override
      method height (line 52) | @Override
      method scaleFactor (line 57) | @Override
      method onResize (line 62) | @Override
      method currentCursorStyle (line 67) | @Override
      method setCursorStyle (line 72) | @Override
      method beginRendering (line 77) | @Override
      method endRendering (line 80) | @Override
      method dispose (line 83) | @Override
    type ResizeCallback (line 89) | interface ResizeCallback {
      method onResize (line 90) | void onResize(int newWidth, int newHeight);
      method newStream (line 92) | static EventStream<ResizeCallback> newStream() {

FILE: src/main/java/io/wispforest/owo/braid/core/TextLayout.java
  class TextLayout (line 10) | public class TextLayout {
    method measure (line 12) | public static EditMetrics measure(Font font, String text, Style baseSt...
    method substring (line 49) | public String substring(String fullContent) {
    method substring (line 57) | public Component substring(String fullContent) {

FILE: src/main/java/io/wispforest/owo/braid/core/TextureSurface.java
  class TextureSurface (line 18) | public class TextureSurface implements Surface {
    method TextureSurface (line 30) | public TextureSurface(int width, int height) {
    method resize (line 40) | public void resize(int width, int height) {
    method texture (line 47) | public GpuTextureView texture() {
    method width (line 51) | @Override
    method height (line 56) | @Override
    method scaleFactor (line 61) | @Override
    method onResize (line 66) | @Override
    method currentCursorStyle (line 71) | @Override
    method setCursorStyle (line 76) | @Override
    method beginRendering (line 83) | @Override
    method endRendering (line 93) | @Override
    method dispose (line 101) | @Override
    class TextureSurfaceTexture (line 109) | public class TextureSurfaceTexture extends AbstractTexture {
      method TextureSurfaceTexture (line 111) | public TextureSurfaceTexture() {
      method sync (line 116) | private void sync() {
      method close (line 121) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/cursor/CursorController.java
  class CursorController (line 8) | public class CursorController {
    method CursorController (line 16) | public CursorController(long windowHandle) {
    method currentStyle (line 20) | public CursorStyle currentStyle() {
    method setStyle (line 24) | public void setStyle(CursorStyle style) {
    method dispose (line 40) | public void dispose() {

FILE: src/main/java/io/wispforest/owo/braid/core/cursor/CursorStyle.java
  type CursorStyle (line 8) | public sealed interface CursorStyle permits SystemCursorStyle {
    method allocate (line 21) | long allocate();
    method forDraggingAlong (line 23) | static CursorStyle forDraggingAlong(LayoutAxis axis, Matrix3x2f transf...

FILE: src/main/java/io/wispforest/owo/braid/core/cursor/SystemCursorStyle.java
  class SystemCursorStyle (line 5) | public final class SystemCursorStyle implements CursorStyle {
    method SystemCursorStyle (line 8) | SystemCursorStyle(int glfwId) {
    method allocate (line 12) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/element/BraidBlockElement.java
  method x0 (line 30) | @Override
  method x1 (line 35) | @Override
  method y0 (line 40) | @Override
  method y1 (line 45) | @Override
  method scale (line 50) | @Override
  method pose (line 55) | @Override
  method scissorArea (line 60) | @Override
  method bounds (line 65) | @Override
  class Renderer (line 74) | public static class Renderer extends PictureInPictureRenderer<BraidBlock...
    method Renderer (line 76) | public Renderer(MultiBufferSource.BufferSource vertexConsumers) {
    method getRenderStateClass (line 80) | @Override
    method renderToTexture (line 85) | @Override
    method getTranslateY (line 109) | @Override
    method getTextureLabel (line 114) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/element/BraidDashedLineElement.java
  method buildVertices (line 22) | @Override
  method pipeline (line 48) | @Override
  method textureSetup (line 53) | @Override
  method scissorArea (line 58) | @Override
  method bounds (line 63) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/element/BraidEntityElement.java
  method x0 (line 27) | @Override
  method x1 (line 32) | @Override
  method y0 (line 37) | @Override
  method y1 (line 42) | @Override
  method scale (line 47) | @Override
  method pose (line 52) | @Override
  method scissorArea (line 57) | @Override
  method bounds (line 62) | @Override
  class Renderer (line 71) | public static class Renderer extends PictureInPictureRenderer<BraidEntit...
    method Renderer (line 75) | public Renderer(MultiBufferSource.BufferSource vertexConsumers) {
    method getRenderStateClass (line 79) | @Override
    method renderToTexture (line 84) | @Override
    method getTranslateY (line 98) | @Override
    method getTextureLabel (line 103) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/element/BraidItemElement.java
  method x0 (line 26) | @Override
  method x1 (line 31) | @Override
  method y0 (line 36) | @Override
  method y1 (line 41) | @Override
  method scale (line 46) | @Override
  method pose (line 51) | @Override
  method scissorArea (line 56) | @Override
  method bounds (line 61) | @Override
  class Renderer (line 70) | public static class Renderer extends PictureInPictureRenderer<BraidItemE...
    method Renderer (line 72) | public Renderer(MultiBufferSource.BufferSource vertexConsumers) {
    method getRenderStateClass (line 76) | @Override
    method renderToTexture (line 81) | @Override
    method getTranslateY (line 98) | @Override
    method getTextureLabel (line 103) | @Override

FILE: src/main/java/io/wispforest/owo/braid/core/events/CharInputEvent.java
  method CharInputEvent (line 6) | public CharInputEvent(char codepoint, int modifiers) {

FILE: src/main/java/io/wispforest/owo/braid/core/events/CloseEvent.java
  type CloseEvent (line 3) | public enum CloseEvent implements UserEvent {

FILE: src/main/java/io/wispforest/owo/braid/core/events/KeyPressEvent.java
  method KeyPressEvent (line 6) | public KeyPressEvent(int keyCode, int scancode, int modifiers) {

FILE: src/main/java/io/wispforest/owo/braid/core/events/KeyReleaseEvent.java
  method KeyReleaseEvent (line 6) | public KeyReleaseEvent(int keycode, int scancode, int modifiers) {

FILE: src/main/java/io/wispforest/owo/braid/core/events/MouseButtonPressEvent.java
  method MouseButtonPressEvent (line 6) | public MouseButtonPressEvent(int button, int modifiers) {

FILE: src/main/java/io/wispforest/owo/braid/core/events/MouseButtonReleaseEvent.java
  method MouseButtonReleaseEvent (line 6) | public MouseButtonReleaseEvent(int button, int modifiers) {

FILE: src/main/java/io/wispforest/owo/braid/core/events/UserEvent.java
  type UserEvent (line 3) | public sealed interface UserEvent permits

FILE: src/main/java/io/wispforest/owo/braid/display/BraidDisplay.java
  class BraidDisplay (line 21) | public class BraidDisplay {
    method BraidDisplay (line 35) | public BraidDisplay(DisplayQuad quad, int surfaceWidth, int surfaceHei...
    method renderAutomatically (line 48) | public BraidDisplay renderAutomatically() {
    method updateAndDrawApp (line 53) | public void updateAndDrawApp() {
    method render (line 63) | public void render(PoseStack matrices, SubmitNodeCollector queue, int ...

FILE: src/main/java/io/wispforest/owo/braid/display/BraidDisplayBinding.java
  class BraidDisplayBinding (line 16) | public class BraidDisplayBinding {
    method activate (line 22) | public static void activate(BraidDisplay display) {
    method deactivate (line 26) | public static void deactivate(BraidDisplay display) {
    method queryTargetDisplay (line 34) | @ApiStatus.Internal
    method onDisplayHit (line 50) | @ApiStatus.Internal
    method updateAndDrawDisplays (line 60) | @ApiStatus.Internal
    method renderAutomaticDisplays (line 67) | @ApiStatus.Internal

FILE: src/main/java/io/wispforest/owo/braid/display/DisplayQuad.java
  class DisplayQuad (line 8) | public final class DisplayQuad {
    method DisplayQuad (line 14) | public DisplayQuad(Vec3 pos, Vec3 top, Vec3 left) {
    method unproject (line 21) | public Vec3 unproject(Vector2dc point) {
    method hitTest (line 25) | public @Nullable HitTestResult hitTest(Vec3 origin, Vec3 direction) {

FILE: src/main/java/io/wispforest/owo/braid/framework/BuildContext.java
  type BuildContext (line 6) | public interface BuildContext {
    method getAncestor (line 7) | <T> @Nullable T getAncestor(Class<T> ancestorClass, Object inheritedKey);
    method getAncestor (line 9) | default <T> @Nullable T getAncestor(Class<T> ancestorClass) {
    method dependOnAncestor (line 13) | <T> @Nullable T dependOnAncestor(Class<T> ancestorClass, Object inheri...
    method dependOnAncestor (line 15) | default <T> @Nullable T dependOnAncestor(Class<T> ancestorClass, Objec...
    method dependOnAncestor (line 19) | default <T> @Nullable T dependOnAncestor(Class<T> ancestorClass) {
    method instance (line 27) | WidgetInstance<?> instance();

FILE: src/main/java/io/wispforest/owo/braid/framework/instance/CustomWidgetTransform.java
  class CustomWidgetTransform (line 6) | public class CustomWidgetTransform extends WidgetTransform {
    method setMatrix (line 14) | public void setMatrix(Matrix3x2f matrix) {
    method matrix (line 18) | public Matrix3x2f matrix() {
    method setApplyAtCenter (line 22) | public void setApplyAtCenter(boolean applyToCenter) {
    method applyAtCenter (line 26) | public boolean applyAtCenter() {
    method toParent (line 30) | protected Matrix3x2fc toParent() {
    method toWidget (line 47) | protected Matrix3x2fc toWidget() {
    method transformToParent (line 55) | @Override
    method transformToParent (line 60) | @Override
    method transformToWidget (line 65) | @Override
    method transformToWidget (line 70) | @Override
    method toParentCoordinates (line 75) | @Override
    method toWidgetCoordinates (line 83) | @Override
    method recompute (line 91) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/instance/HitTestState.java
  class HitTestState (line 12) | public class HitTestState {
    method anyHit (line 15) | public boolean anyHit() {
    method firstHit (line 19) | public Hit firstHit() {
    method trace (line 23) | public Iterable<Hit> trace() {
    method occludedTrace (line 27) | public Iterable<Hit> occludedTrace() {
    method firstWhere (line 55) | public @Nullable Hit firstWhere(Predicate<Hit> predicate) {
    method addHit (line 59) | public void addHit(WidgetInstance<?> instance, double x, double y) {

FILE: src/main/java/io/wispforest/owo/braid/framework/instance/InstanceHost.java
  type InstanceHost (line 7) | public interface InstanceHost {
    method client (line 8) | Minecraft client();
    method scheduleLayout (line 16) | void scheduleLayout(WidgetInstance<?> instance);
    method notifySubtreeRebuild (line 24) | void notifySubtreeRebuild();
    method schedulePostLayoutCallback (line 26) | void schedulePostLayoutCallback(Runnable callback);
    method cursorPosition (line 28) | Vector2dc cursorPosition();

FILE: src/main/java/io/wispforest/owo/braid/framework/instance/LeafWidgetInstance.java
  class LeafWidgetInstance (line 5) | public abstract class LeafWidgetInstance<T extends InstanceWidget> exten...
    method LeafWidgetInstance (line 7) | public LeafWidgetInstance(T widget) {
    method visitChildren (line 11) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/instance/MouseListener.java
  type MouseListener (line 7) | public interface MouseListener {
    method cursorStyleAt (line 8) | default @Nullable CursorStyle cursorStyleAt(double x, double y) {
    method onMouseDown (line 12) | default boolean onMouseDown(double x, double y, int button, KeyModifie...
    method onMouseUp (line 15) | default boolean onMouseUp(double x, double y, int button, KeyModifiers...
    method onMouseEnter (line 19) | default void onMouseEnter() {}
    method onMouseMove (line 20) | default void onMouseMove(double toX, double toY) {}
    method onMouseExit (line 21) | default void onMouseExit() {}
    method onMouseDragStart (line 22) | default void onMouseDragStart(int button, KeyModifiers modifiers) {}
    method onMouseDrag (line 23) | default void onMouseDrag(double x, double y, double dx, double dy) {}
    method onMouseDragEnd (line 24) | default void onMouseDragEnd() {}
    method onMouseScroll (line 26) | default boolean onMouseScroll(double x, double y, double horizontal, d...

FILE: src/main/java/io/wispforest/owo/braid/framework/instance/MultiChildWidgetInstance.java
  class MultiChildWidgetInstance (line 11) | public abstract class MultiChildWidgetInstance<T extends MultiChildInsta...
    method MultiChildWidgetInstance (line 15) | public MultiChildWidgetInstance(T widget) {
    method draw (line 19) | @Override
    method visitChildren (line 26) | @Override
    method insertChild (line 33) | public void insertChild(int index, WidgetInstance<?> child) {
    method computeFirstBaselineOffset (line 40) | protected OptionalDouble computeFirstBaselineOffset() {
    method computeHighestBaselineOffset (line 51) | protected OptionalDouble computeHighestBaselineOffset() {
    method baselineMin (line 60) | private static OptionalDouble baselineMin(OptionalDouble a, OptionalDo...

FILE: src/main/java/io/wispforest/owo/braid/framework/instance/OptionalChildWidgetInstance.java
  class OptionalChildWidgetInstance (line 11) | public abstract class OptionalChildWidgetInstance<T extends InstanceWidg...
    method OptionalChildWidgetInstance (line 15) | public OptionalChildWidgetInstance(T widget) {
    method draw (line 19) | @Override
    method visitChildren (line 26) | @Override
    method child (line 33) | public WidgetInstance<?> child() {
    method setChild (line 38) | public void setChild(@Nullable WidgetInstance<?> value) {
    class ShrinkWrap (line 45) | public static abstract class ShrinkWrap<T extends InstanceWidget> exte...
      method ShrinkWrap (line 47) | public ShrinkWrap(T widget) {
      method doLayout (line 51) | @Override
      method measureIntrinsicWidth (line 56) | @Override
      method measureIntrinsicHeight (line 61) | @Override
      method measureBaselineOffset (line 66) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/instance/SingleChildWidgetInstance.java
  class SingleChildWidgetInstance (line 10) | public abstract class SingleChildWidgetInstance<T extends InstanceWidget...
    method SingleChildWidgetInstance (line 14) | public SingleChildWidgetInstance(T widget) {
    method draw (line 18) | @Override
    method visitChildren (line 23) | @Override
    method child (line 28) | public WidgetInstance<?> child() {
    method setChild (line 33) | public void setChild(WidgetInstance<?> value) {
    class ShrinkWrap (line 40) | public static abstract class ShrinkWrap<T extends InstanceWidget> exte...
      method ShrinkWrap (line 42) | public ShrinkWrap(T widget) {
      method doLayout (line 46) | @Override
      method measureIntrinsicWidth (line 51) | @Override
      method measureIntrinsicHeight (line 56) | @Override
      method measureBaselineOffset (line 61) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/instance/TooltipProvider.java
  type TooltipProvider (line 9) | public interface TooltipProvider {
    method getTooltipComponentsAt (line 10) | @Nullable List<ClientTooltipComponent> getTooltipComponentsAt(double x...
    method getStyleAt (line 12) | @Nullable

FILE: src/main/java/io/wispforest/owo/braid/framework/instance/WidgetInstance.java
  class WidgetInstance (line 24) | public abstract class WidgetInstance<T extends InstanceWidget> implement...
    method debugParentHasDependency (line 43) | public boolean debugParentHasDependency() {
    method WidgetInstance (line 54) | public WidgetInstance(T widget) {
    method createTransform (line 58) | protected WidgetTransform createTransform() {
    method layout (line 64) | public final Size layout(Constraints constraints) {
    method doLayout (line 78) | protected abstract void doLayout(Constraints constraints);
    method measureIntrinsicWidth (line 80) | protected abstract double measureIntrinsicWidth(double height);
    method measureIntrinsicHeight (line 81) | protected abstract double measureIntrinsicHeight(double width);
    method getIntrinsicWidth (line 85) | public double getIntrinsicWidth(double height) {
    method getIntrinsicHeight (line 89) | public double getIntrinsicHeight(double width) {
    method measureBaselineOffset (line 93) | protected abstract OptionalDouble measureBaselineOffset();
    method getBaselineOffset (line 96) | public OptionalDouble getBaselineOffset() {
    method draw (line 104) | public abstract void draw(BraidGraphics graphics);
    method visitChildren (line 106) | public abstract void visitChildren(Visitor visitor);
    method attachHost (line 110) | public void attachHost(InstanceHost host) {
    method adopt (line 119) | protected <W extends @Nullable WidgetInstance<?>> W adopt(W child) {
    method debugListInspectorProperties (line 133) | public List<InspectorProperty> debugListInspectorProperties() {
    method debugHasVisualizers (line 137) | public boolean debugHasVisualizers() {
    method debugDrawVisualizers (line 141) | protected void debugDrawVisualizers(BraidGraphics graphics) {}
    method drawChild (line 145) | protected void drawChild(BraidGraphics ctx, WidgetInstance<?> child) {
    method sizeToChild (line 166) | protected void sizeToChild(Constraints constraints, @Nullable WidgetIn...
    method clearLayoutCache (line 175) | public void clearLayoutCache(boolean recursive) {
    method markNeedsLayout (line 183) | @SuppressWarnings("OptionalAssignedToNull")
    method dispose (line 200) | @MustBeInvokedByOverriders
    method ancestors (line 210) | public List<WidgetInstance<?>> ancestors() {
    method hitTest (line 222) | public void hitTest(double x, double y, HitTestState state) {
    method hitTestSelf (line 236) | protected boolean hitTestSelf(double x, double y) {
    method computeGlobalTransform (line 240) | public Matrix3x2f computeGlobalTransform() {
    method computeTransformFrom (line 244) | public Matrix3x2f computeTransformFrom(@Nullable WidgetInstance<?> anc...
    method computeGlobalBounds (line 257) | public AABB computeGlobalBounds() {
    method computeGlobalPosition (line 266) | public Vector2d computeGlobalPosition() {
    method constraints (line 276) | public @Nullable Constraints constraints() {
    method depth (line 280) | public int depth() {
    method setDepth (line 284) | public void setDepth(int depth) {
    method host (line 294) | public InstanceHost host() {
    method needsLayout (line 298) | public boolean needsLayout() {
    method isRelayoutBoundary (line 302) | public boolean isRelayoutBoundary() {
    method hasParent (line 306) | public boolean hasParent() {
    method setWidget (line 310) | public void setWidget(T widget) {
    method widget (line 314) | public T widget() {
    method parent (line 318) | public WidgetInstance<?> parent() {
    method addPostAttachCallback (line 325) | public static void addPostAttachCallback(WidgetInstance<?> instance, R...
    method compareTo (line 331) | @Override
    type Visitor (line 338) | @FunctionalInterface
      method visit (line 340) | void visit(WidgetInstance<?> child);

FILE: src/main/java/io/wispforest/owo/braid/framework/instance/WidgetTransform.java
  class WidgetTransform (line 10) | public class WidgetTransform {
    method setX (line 14) | public void setX(double x) {
    method x (line 18) | public double x() {
    method setY (line 22) | public void setY(double y) {
    method y (line 26) | public double y() {
    method setWidth (line 30) | public void setWidth(double width) {
    method width (line 41) | public double width() {
    method setHeight (line 45) | public void setHeight(double height) {
    method height (line 56) | public double height() {
    method setSize (line 60) | public void setSize(Size size) {
    method toSize (line 67) | public Size toSize() {
    method transformToParent (line 71) | public void transformToParent(Matrix3x2f mat) {
    method transformToParent (line 75) | public void transformToParent(Matrix3x2fStack matrices) {
    method transformToWidget (line 79) | public void transformToWidget(Matrix3x2f mat) {
    method transformToWidget (line 83) | public void transformToWidget(Matrix3x2fStack matrices) {
    method toParentCoordinates (line 87) | public void toParentCoordinates(Vector2d vec) {
    method toWidgetCoordinates (line 91) | public void toWidgetCoordinates(Vector2d vec) {
    method setExtent (line 95) | public void setExtent(LayoutAxis axis, double value) {
    method getExtent (line 102) | public double getExtent(LayoutAxis axis) {
    method setCoordinate (line 109) | public void setCoordinate(LayoutAxis axis, double value) {
    method getCoordinate (line 116) | public double getCoordinate(LayoutAxis axis) {
    method setState (line 123) | protected void setState(Runnable action) {
    method recompute (line 128) | public void recompute() {}

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/BuildScope.java
  class BuildScope (line 12) | public class BuildScope {
    method BuildScope (line 18) | public BuildScope(@Nullable Runnable scheduleRebuild) {
    method BuildScope (line 22) | public BuildScope() {
    method scheduleRebuild (line 28) | public void scheduleRebuild(WidgetProxy proxy) {
    method rebuildDirtyProxies (line 37) | public boolean rebuildDirtyProxies() {
    method nextDirtyIndex (line 58) | private int nextDirtyIndex(int idx) {
    method isMissed (line 74) | private static boolean isMissed(WidgetProxy proxy) {

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/ComposedProxy.java
  class ComposedProxy (line 7) | public abstract non-sealed class ComposedProxy extends WidgetProxy {
    method ComposedProxy (line 11) | public ComposedProxy(Widget widget) {
    method child (line 15) | public WidgetProxy child() {
    method visitChildren (line 19) | @Override
    method instance (line 28) | @Override
    method notifyDescendantInstance (line 33) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/InheritedProxy.java
  class InheritedProxy (line 11) | public class InheritedProxy extends ComposedProxy {
    method InheritedProxy (line 15) | public InheritedProxy(InheritedWidget widget) {
    method addDependency (line 19) | public void addDependency(WidgetProxy dependent, @Nullable Object depe...
    method removeDependent (line 23) | public void removeDependent(WidgetProxy dependent) {
    method mustRebuildDependent (line 27) | protected boolean mustRebuildDependent(WidgetProxy dependent) {
    method notifyDependent (line 31) | public void notifyDependent(WidgetProxy dependent) {
    method mount (line 35) | @Override
    method updateWidget (line 44) | @Override
    method doRebuild (line 59) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/InstanceWidgetProxy.java
  class InstanceWidgetProxy (line 12) | public abstract non-sealed class InstanceWidgetProxy extends WidgetProxy {
    method InstanceWidgetProxy (line 18) | protected InstanceWidgetProxy(InstanceWidget widget) {
    method instance (line 26) | @Override
    method mount (line 31) | @Override
    method updateSlot (line 47) | @Override
    method unmount (line 53) | @Override
    method updateWidget (line 60) | @Override
    method notifyAncestors (line 66) | private void notifyAncestors() {

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/LeafInstanceWidgetProxy.java
  class LeafInstanceWidgetProxy (line 8) | public class LeafInstanceWidgetProxy extends InstanceWidgetProxy {
    method LeafInstanceWidgetProxy (line 9) | public LeafInstanceWidgetProxy(LeafInstanceWidget widget) {
    method visitChildren (line 13) | @Override
    method notifyDescendantInstance (line 16) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/MultiChildInstanceWidgetProxy.java
  class MultiChildInstanceWidgetProxy (line 19) | public class MultiChildInstanceWidgetProxy extends InstanceWidgetProxy {
    method MultiChildInstanceWidgetProxy (line 23) | public MultiChildInstanceWidgetProxy(MultiChildInstanceWidget widget) {
    method instance (line 27) | @Override
    method visitChildren (line 33) | @Override
    method updateWidget (line 40) | @Override
    method doRebuild (line 46) | @Override
    method notifyDescendantInstance (line 170) | @Override
    method copyInto (line 175) | @SuppressWarnings("SameParameterValue")

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/OptionalChildInstanceWidgetProxy.java
  class OptionalChildInstanceWidgetProxy (line 10) | public class OptionalChildInstanceWidgetProxy extends InstanceWidgetProxy {
    method OptionalChildInstanceWidgetProxy (line 14) | public OptionalChildInstanceWidgetProxy(OptionalChildInstanceWidget wi...
    method instance (line 18) | @Override
    method updateWidget (line 23) | @Override
    method doRebuild (line 29) | @Override
    method notifyDescendantInstance (line 39) | @Override
    method visitChildren (line 44) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/ProxyHost.java
  type ProxyHost (line 7) | public interface ProxyHost {
    method client (line 9) | Minecraft client();
    method scheduleAnimationCallback (line 11) | void scheduleAnimationCallback(AnimationCallback callback);
    method scheduleDelayedCallback (line 13) | long scheduleDelayedCallback(Duration delay, Runnable callback);
    method cancelDelayedCallback (line 15) | void cancelDelayedCallback(long id);
    method schedulePostLayoutCallback (line 17) | void schedulePostLayoutCallback(Runnable callback);
    type AnimationCallback (line 19) | interface AnimationCallback {
      method run (line 20) | void run(Duration delta);

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/SingleChildInstanceWidgetProxy.java
  class SingleChildInstanceWidgetProxy (line 10) | public class SingleChildInstanceWidgetProxy extends InstanceWidgetProxy {
    method SingleChildInstanceWidgetProxy (line 13) | public SingleChildInstanceWidgetProxy(SingleChildInstanceWidget widget) {
    method instance (line 17) | @Override
    method updateWidget (line 22) | @Override
    method doRebuild (line 28) | @Override
    method notifyDescendantInstance (line 34) | @Override
    method visitChildren (line 39) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/StatefulProxy.java
  class StatefulProxy (line 7) | public class StatefulProxy extends ComposedProxy {
    method StatefulProxy (line 12) | public StatefulProxy(StatefulWidget widget) {
    method state (line 21) | public WidgetState<?> state() {
    method mount (line 25) | @Override
    method notifyDependenciesChanged (line 33) | @Override
    method unmount (line 39) | @Override
    method updateWidget (line 45) | @Override
    method doRebuild (line 56) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/StatelessProxy.java
  class StatelessProxy (line 7) | public class StatelessProxy extends ComposedProxy {
    method StatelessProxy (line 8) | public StatelessProxy(StatelessWidget widget) {
    method mount (line 12) | @Override
    method updateWidget (line 18) | @Override
    method doRebuild (line 24) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/WidgetProxy.java
  class WidgetProxy (line 16) | public abstract sealed class WidgetProxy implements BuildContext, Compar...
    method WidgetProxy (line 32) | public WidgetProxy(Widget widget) {
    method mount (line 37) | public void mount(WidgetProxy parent, @Nullable Object slot) {
    method updateSlot (line 52) | @MustBeInvokedByOverriders
    method unmount (line 57) | public void unmount() {
    method markNeedsRebuild (line 70) | public void markNeedsRebuild() {
    method reassemble (line 77) | public void reassemble() {
    method refreshChild (line 84) | protected @Nullable WidgetProxy refreshChild(@Nullable WidgetProxy chi...
    method updateWidget (line 111) | @MustBeInvokedByOverriders
    method rebuild (line 117) | public final void rebuild() {
    method rebuild (line 121) | public final void rebuild(boolean force) {
    method doRebuild (line 127) | @MustBeInvokedByOverriders
    method getAncestor (line 134) | @Override
    method dependOnAncestor (line 148) | @Override
    method notifyDependenciesChanged (line 168) | public void notifyDependenciesChanged() {
    method visitChildren (line 174) | public abstract void visitChildren(Visitor visitor);
    method instance (line 176) | @Override
    method notifyDescendantInstance (line 179) | public abstract void notifyDescendantInstance(@Nullable WidgetInstance...
    method widget (line 183) | public Widget widget() {
    method parent (line 187) | public @Nullable WidgetProxy parent() {
    method mounted (line 191) | public boolean mounted() {
    method buildScope (line 195) | public BuildScope buildScope() {
    method slot (line 200) | public @Nullable Object slot() {
    method host (line 204) | public ProxyHost host() {
    method needsRebuild (line 208) | public boolean needsRebuild() {
    method depth (line 212) | public int depth() {
    method setDepth (line 216) | public void setDepth(int depth) {
    method rootSetHost (line 228) | protected void rootSetHost(ProxyHost host) {
    method compareTo (line 234) | @Override
    type Visitor (line 241) | @FunctionalInterface
      method visit (line 243) | void visit(WidgetProxy child);
    type Lifecycle (line 246) | public enum Lifecycle {
  type Visitors (line 251) | enum Visitors implements WidgetProxy.Visitor {
    method Visitors (line 257) | Visitors(WidgetProxy.Visitor delegate) {
    method visit (line 261) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/proxy/WidgetState.java
  class WidgetState (line 12) | public abstract class WidgetState<T extends StatefulWidget> {
    method build (line 17) | public abstract Widget build(BuildContext context);
    method context (line 19) | public BuildContext context() {
    method init (line 27) | public void init() {}
    method dispose (line 28) | public void dispose() {}
    method didUpdateWidget (line 30) | public void didUpdateWidget(T oldWidget) {}
    method notifyDependenciesChanged (line 31) | public void notifyDependenciesChanged() {}
    method setState (line 33) | public final void setState(Runnable fn) {
    method scheduleDelayedCallback (line 40) | public final long scheduleDelayedCallback(Duration after, Runnable cal...
    method cancelDelayedCallback (line 44) | public final void cancelDelayedCallback(long id) {
    method scheduleAnimationCallback (line 48) | public final void scheduleAnimationCallback(ProxyHost.AnimationCallbac...
    method schedulePostLayoutCallback (line 52) | public final void schedulePostLayoutCallback(Runnable callback) {
    method widget (line 56) | public T widget() {

FILE: src/main/java/io/wispforest/owo/braid/framework/widget/InheritedWidget.java
  class InheritedWidget (line 6) | public abstract class InheritedWidget extends Widget {
    method InheritedWidget (line 9) | protected InheritedWidget(Widget child) {
    method proxy (line 13) | @Override
    method inheritedKey (line 20) | public Object inheritedKey() {
    method mustRebuildDependents (line 24) | public abstract boolean mustRebuildDependents(InheritedWidget newWidget);

FILE: src/main/java/io/wispforest/owo/braid/framework/widget/InstanceWidget.java
  class InstanceWidget (line 5) | public abstract class InstanceWidget extends Widget {
    method instantiate (line 6) | public abstract WidgetInstance<?> instantiate();

FILE: src/main/java/io/wispforest/owo/braid/framework/widget/Key.java
  class Key (line 6) | public class Key {
    method Key (line 10) | private Key(String value) {
    method of (line 14) | public static Key of(@NotNull String value) {
    method equals (line 21) | @Override
    method hashCode (line 29) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/widget/LeafInstanceWidget.java
  class LeafInstanceWidget (line 7) | public abstract class LeafInstanceWidget extends InstanceWidget {
    method instantiate (line 9) | @Override
    method proxy (line 12) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/widget/MultiChildInstanceWidget.java
  class MultiChildInstanceWidget (line 9) | public abstract class MultiChildInstanceWidget extends InstanceWidget {
    method MultiChildInstanceWidget (line 12) | protected MultiChildInstanceWidget(List<? extends Widget> children) {
    method instantiate (line 16) | @Override
    method proxy (line 19) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/widget/OptionalChildInstanceWidget.java
  class OptionalChildInstanceWidget (line 8) | public abstract class OptionalChildInstanceWidget extends InstanceWidget {
    method OptionalChildInstanceWidget (line 11) | public OptionalChildInstanceWidget(@Nullable Widget child) {
    method instantiate (line 15) | @Override
    method proxy (line 18) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/widget/SingleChildInstanceWidget.java
  class SingleChildInstanceWidget (line 7) | public abstract class SingleChildInstanceWidget extends InstanceWidget {
    method SingleChildInstanceWidget (line 11) | protected SingleChildInstanceWidget(Widget child) {
    method instantiate (line 15) | @Override
    method proxy (line 18) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/widget/StatefulWidget.java
  class StatefulWidget (line 7) | public abstract class StatefulWidget extends Widget {
    method createState (line 8) | public abstract WidgetState<?> createState();
    method proxy (line 10) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/widget/StatelessWidget.java
  class StatelessWidget (line 7) | public abstract class StatelessWidget extends Widget {
    method build (line 9) | public abstract Widget build(BuildContext context);
    method proxy (line 11) | @Override

FILE: src/main/java/io/wispforest/owo/braid/framework/widget/Widget.java
  class Widget (line 9) | public abstract class Widget {
    method freeze (line 12) | @ApiStatus.Internal
    method assertMutable (line 17) | protected final void assertMutable() {
    method key (line 25) | public Widget key(Key key) {
    method key (line 32) | public @Nullable Key key() {
    method proxy (line 38) | public abstract WidgetProxy proxy();
    method canUpdate (line 40) | public static boolean canUpdate(Widget oldWidget, Widget newWidget) {
    method noSetup (line 44) | public static <T extends Widget> WidgetSetupCallback<T> noSetup() {
  class ImmutableWidgetError (line 53) | class ImmutableWidgetError extends Error {
    method ImmutableWidgetError (line 54) | public ImmutableWidgetError() {

FILE: src/main/java/io/wispforest/owo/braid/framework/widget/WidgetSetupCallback.java
  type WidgetSetupCallback (line 3) | public interface WidgetSetupCallback<T extends Widget> {
    method setup (line 4) | void setup(T widget);
    method compose (line 6) | default WidgetSetupCallback<T> compose(WidgetSetupCallback<? super T> ...
    method andThen (line 13) | default WidgetSetupCallback<T> andThen(WidgetSetupCallback<? super T> ...

FILE: src/main/java/io/wispforest/owo/braid/util/BraidGuiRenderer.java
  class BraidGuiRenderer (line 18) | public class BraidGuiRenderer extends GuiRenderer {
    method BraidGuiRenderer (line 22) | public BraidGuiRenderer(Minecraft client) {
    method newGraphics (line 33) | public GuiGraphics newGraphics(double mouseX, double mouseY) {
    method trySetFabricState (line 43) | private void trySetFabricState() {
    method render (line 63) | public void render(Target target) {
    method render (line 68) | @Override

FILE: src/main/java/io/wispforest/owo/braid/util/BraidHudElement.java
  class BraidHudElement (line 15) | public class BraidHudElement implements HudElement {
    method BraidHudElement (line 20) | public BraidHudElement(Widget widget) {
    method app (line 32) | public @Nullable AppState app() {
    method render (line 36) | @Override
    method setupAppState (line 50) | protected void setupAppState() {
    method resetAppState (line 61) | protected void resetAppState() {

FILE: src/main/java/io/wispforest/owo/braid/util/BraidToast.java
  class BraidToast (line 23) | public class BraidToast implements Toast {
    method BraidToast (line 31) | private BraidToast(@Nullable Duration timeout, @Nullable Object token,...
    method show (line 55) | public static void show(@Nullable Duration timeout, @Nullable Object t...
    method hideWithToken (line 59) | public static void hideWithToken(Object token) {
    method hide (line 66) | public static void hide(BuildContext context) {
    method dispose (line 75) | @ApiStatus.Internal
    method render (line 80) | @Override
    method width (line 85) | @Override
    method height (line 90) | @Override
    method update (line 99) | @Override
    method getWantedVisibility (line 111) | @Override
    method getToken (line 116) | @Override
  class BraidToastProvider (line 122) | class BraidToastProvider extends InheritedWidget {
    method BraidToastProvider (line 126) | public BraidToastProvider(BraidToast toast, Widget child) {
    method mustRebuildDependents (line 131) | @Override

FILE: src/main/java/io/wispforest/owo/braid/util/BraidTooltipComponent.java
  class BraidTooltipComponent (line 18) | public class BraidTooltipComponent implements ClientTooltipComponent {
    method BraidTooltipComponent (line 23) | public BraidTooltipComponent(Widget widget) {
    method renderImage (line 46) | @Override
    method getWidth (line 53) | @Override
    method getHeight (line 58) | @Override
    method run (line 68) | @Override

FILE: src/main/java/io/wispforest/owo/braid/util/EmbedderRoot.java
  class EmbedderRoot (line 9) | public class EmbedderRoot extends SingleChildInstanceWidget {
    method EmbedderRoot (line 13) | public EmbedderRoot(Consumer<Instance> instanceListener, Widget child) {
    method instantiate (line 18) | @Override
    class Instance (line 26) | public static class Instance extends SingleChildWidgetInstance.ShrinkW...
      method Instance (line 27) | public Instance(EmbedderRoot widget) {

FILE: src/main/java/io/wispforest/owo/braid/util/kdl/BraidKdlEndecs.java
  class BraidKdlEndecs (line 27) | public final class BraidKdlEndecs {
    method BraidKdlEndecs (line 28) | private BraidKdlEndecs() {}
    type TransformStep (line 75) | private sealed interface TransformStep {

FILE: src/main/java/io/wispforest/owo/braid/util/kdl/KdlDeserializer.java
  class KdlDeserializer (line 15) | public class KdlDeserializer extends RecursiveDeserializer<KdlElement> i...
    method KdlDeserializer (line 19) | public KdlDeserializer(KdlNode rootNode, List<KdlMapper> mappers) {
    method readAny (line 24) | @Override
    method decodeElement (line 34) | private void decodeElement(SerializationContext ctx, Serializer<?> vis...
    method readByte (line 71) | @Override
    method readShort (line 76) | @Override
    method readInt (line 81) | @Override
    method readLong (line 86) | @Override
    method readFloat (line 91) | @Override
    method readDouble (line 96) | @Override
    method readVarInt (line 101) | @Override
    method readVarLong (line 106) | @Override
    method readBoolean (line 111) | @Override
    method readString (line 116) | @Override
    method readBytes (line 121) | @Override
    method readOptional (line 126) | @Override
    method expectElement (line 134) | private <K extends KdlElement> K expectElement(SerializationContext ct...
    method expectPrimitive (line 142) | private <V> V expectPrimitive(SerializationContext ctx, Class<V> clazz) {
    method sequence (line 151) | @Override
    method map (line 156) | @Override
    method struct (line 161) | @Override
    class Struct (line 166) | private class Struct implements Deserializer.Struct {
      method Struct (line 170) | private Struct(KdlNode node) {
      method field (line 174) | @Override
      method tryMap (line 196) | private @Nullable KdlElement tryMap(String key) {
    class Sequence (line 212) | private class Sequence<V> implements Deserializer.Sequence<V> {
      method Sequence (line 219) | private Sequence(SerializationContext ctx, Endec<V> elementEndec, Li...
      method estimatedSize (line 226) | @Override
      method hasNext (line 231) | @Override
      method next (line 236) | @Override

FILE: src/main/java/io/wispforest/owo/braid/util/kdl/KdlElement.java
  type KdlElement (line 8) | public sealed interface KdlElement {

FILE: src/main/java/io/wispforest/owo/braid/util/kdl/KdlEntityWidget.java
  class KdlEntityWidget (line 27) | public class KdlEntityWidget extends StatefulWidget {
    method KdlEntityWidget (line 36) | public KdlEntityWidget(double scale, EntitySpec spec, EntityWidget.Dis...
    method createState (line 44) | @Override
    class State (line 49) | public static class State extends WidgetState<KdlEntityWidget> {
      method init (line 53) | @Override
      method didUpdateWidget (line 58) | @Override
      method recreateEntity (line 65) | private void recreateEntity() {
      method build (line 78) | @Override

FILE: src/main/java/io/wispforest/owo/braid/util/kdl/WidgetEndec.java
  class WidgetEndec (line 41) | public class WidgetEndec {
    method register (line 61) | public static <W extends Widget> void register(Identifier key, Class<W...
    method register (line 65) | @ApiStatus.Internal

FILE: src/main/java/io/wispforest/owo/braid/util/layers/BraidLayersBinding.java
  class BraidLayersBinding (line 34) | public class BraidLayersBinding {
    method add (line 36) | public static void add(Predicate<Screen> screenPredicate, Widget widge...
    method tryHandleEvent (line 42) | @ApiStatus.Internal
    method renderLayers (line 55) | @ApiStatus.Internal
    method setupLayers (line 74) | private static void setupLayers(Screen screen) {
    class LayerSurface (line 110) | private static class LayerSurface extends Surface.Default {
      method setCursorStyle (line 114) | @Override
      method currentCursorStyle (line 119) | @Override

FILE: src/main/java/io/wispforest/owo/braid/util/layers/Justify.java
  class Justify (line 8) | public class Justify extends SingleChildInstanceWidget {
    method Justify (line 13) | public Justify(double x, double y, Widget child) {
    method instantiate (line 19) | @Override
    class Instance (line 24) | public static class Instance extends SingleChildWidgetInstance.ShrinkW...
      method Instance (line 26) | public Instance(Justify widget) {
      method setWidget (line 30) | @Override
      method doLayout (line 36) | @Override
      method justify (line 42) | private void justify() {

FILE: src/main/java/io/wispforest/owo/braid/util/layers/LayerAlignment.java
  class LayerAlignment (line 26) | public class LayerAlignment extends StatefulWidget {
    method LayerAlignment (line 32) | private LayerAlignment(Function<BuildContext, @Nullable Vector2d> offs...
    method atVanillaWidget (line 38) | public static LayerAlignment atVanillaWidget(Predicate<AbstractWidget>...
    method atVanillaWidget (line 42) | public static LayerAlignment atVanillaWidget(Predicate<AbstractWidget>...
    method atContainerScreenCoordinates (line 58) | public static LayerAlignment atContainerScreenCoordinates(double xOffs...
    method createState (line 71) | @Override
    class State (line 76) | public static class State extends WidgetState<LayerAlignment> {
      method init (line 81) | @Override
      method didUpdateWidget (line 86) | @Override
      method notifyDependenciesChanged (line 92) | @Override
      method scheduleOverlayUpdate (line 97) | private void scheduleOverlayUpdate() {
      method prepareWidget (line 120) | private Widget prepareWidget() {
      method build (line 127) | @Override

FILE: src/main/java/io/wispforest/owo/braid/util/layers/LayerContext.java
  class LayerContext (line 23) | public class LayerContext extends StatefulWidget {
    method LayerContext (line 29) | public LayerContext(BraidEventSource<Unit> refreshEvents, Screen conte...
    method createState (line 35) | @Override
    class State (line 40) | public static class State extends StreamListenerState<LayerContext> {
      method init (line 42) | @Override
      method build (line 47) | @Override
    method of (line 58) | private static LayerContextScope of(BuildContext context) {
    method findWidget (line 67) | public static AbstractWidget findWidget(BuildContext context, Predicat...
    method screenOf (line 85) | public static Screen screenOf(BuildContext context) {
    method containerScreenRootOf (line 89) | public static @Nullable Vector2d containerScreenRootOf(BuildContext co...
    method collectChildren (line 99) | private static void collectChildren(GuiEventListener element, List<Abs...
  class LayerContextScope (line 107) | class LayerContextScope extends InheritedWidget {
    method LayerContextScope (line 111) | public LayerContextScope(Widget child, Screen contextScreen) {
    method mustRebuildDependents (line 116) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/BraidApp.java
  class BraidApp (line 18) | public class BraidApp extends StatelessWidget {
    method BraidApp (line 22) | public BraidApp(Widget child) {
    method build (line 26) | @Override
    class BaseRoute (line 117) | public static class BaseRoute extends StatelessWidget {
      method BaseRoute (line 121) | public BaseRoute(Widget route) {
      method build (line 125) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/BraidLogo.java
  class BraidLogo (line 12) | public class BraidLogo extends StatelessWidget {
    method build (line 13) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/Dialog.java
  class Dialog (line 13) | public class Dialog extends StatelessWidget {
    method Dialog (line 19) | public Dialog(Color barrierColor, boolean barrierCanDismiss, Widget ch...
    method Dialog (line 25) | public Dialog(Color barrierColor, Widget child) {
    method Dialog (line 29) | public Dialog(boolean barrierCanDismiss, Widget child) {
    method Dialog (line 33) | public Dialog(Widget child) {
    method build (line 37) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/HoverStyledLabel.java
  class HoverStyledLabel (line 12) | public class HoverStyledLabel extends StatefulWidget {
    method HoverStyledLabel (line 17) | public HoverStyledLabel(Component defaultText, Style hoverStyle) {
    method createState (line 22) | @Override
    class State (line 27) | public static class State extends WidgetState<HoverStyledLabel> {
      method build (line 31) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/Marquee.java
  class Marquee (line 20) | public class Marquee extends StatefulWidget {
    method Marquee (line 30) | public Marquee(@Nullable WidgetSetupCallback<Marquee> setup, Widget ch...
    method Marquee (line 35) | public Marquee(Widget child) {
    method easing (line 39) | public Marquee easing(Easing easing) {
    method easing (line 45) | public Easing easing() {
    method minDuration (line 49) | public Marquee minDuration(Duration minDuration) {
    method minDuration (line 55) | public Marquee minDuration(long millis) {
    method minDuration (line 59) | public Duration minDuration() {
    method durationPerPixel (line 63) | public Marquee durationPerPixel(Duration durationPerPixel) {
    method durationPerPixel (line 69) | public Marquee durationPerPixel(long millisPerPixel) {
    method durationPerPixel (line 73) | public Duration durationPerPixel() {
    method pauseTime (line 77) | public Marquee pauseTime(Duration pauseTime) {
    method pauseTime (line 83) | public Marquee pauseTime(long millis) {
    method pauseTime (line 87) | public Duration pauseTime() {
    method pauseWhileHovered (line 91) | public Marquee pauseWhileHovered(boolean pauseWhileHovered) {
    method pauseWhileHovered (line 96) | public boolean pauseWhileHovered() {
    method axis (line 100) | public Marquee axis(LayoutAxis axis) {
    method axis (line 106) | public LayoutAxis axis() {
    method createState (line 110) | @Override
    class State (line 115) | public static class State extends WidgetState<Marquee> {
      method init (line 123) | @Override
      method didUpdateWidget (line 143) | @Override
      method updateAnimationDuration (line 151) | private void updateAnimationDuration() {
      method onAnimationStep (line 158) | private void onAnimationStep(double progress) {
      method onAnimationFinished (line 162) | private void onAnimationFinished(Animation.Target atTarget) {
      method build (line 172) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/Navigator.java
  class Navigator (line 15) | public class Navigator extends StatelessWidget {
    method Navigator (line 19) | public Navigator(@Nullable Widget initialRoute) {
    method build (line 23) | @Override
    method pushOverlay (line 36) | public static void pushOverlay(BuildContext context, Widget route) {
    method push (line 40) | public static void push(BuildContext context, Widget route) {
    method pop (line 44) | public static void pop(BuildContext context) {
  class NavigationState (line 51) | class NavigationState extends ShareableState {
    method NavigationState (line 55) | public NavigationState(@Nullable Widget initialRoute) {
    method displayedRoutes (line 60) | public List<Widget> displayedRoutes() {
    method push (line 64) | public void push(Widget route, boolean overlay) {
    method pop (line 69) | public void pop() {
    method updateDisplayedRoutes (line 74) | private void updateDisplayedRoutes() {

FILE: src/main/java/io/wispforest/owo/braid/widgets/SpriteWidget.java
  class SpriteWidget (line 17) | public class SpriteWidget extends LeafInstanceWidget {
    method SpriteWidget (line 23) | public SpriteWidget(Material spriteIdentifier) {
    method SpriteWidget (line 27) | public SpriteWidget(Identifier spriteIdentifier) {
    method instantiate (line 31) | @Override
    class Instance (line 36) | public static class Instance extends LeafWidgetInstance<SpriteWidget> {
      method Instance (line 40) | public Instance(SpriteWidget widget) {
      method setWidget (line 44) | @Override
      method findSprite (line 52) | protected TextureAtlasSprite findSprite() {
      method doLayout (line 62) | @Override
      method measureIntrinsicWidth (line 74) | @Override
      method measureIntrinsicHeight (line 79) | @Override
      method measureBaselineOffset (line 84) | @Override
      method draw (line 89) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/animated/AnimatedAlign.java
  class AnimatedAlign (line 13) | public class AnimatedAlign extends AutomaticallyAnimatedWidget {
    method AnimatedAlign (line 18) | public AnimatedAlign(Duration duration, Easing easing, Alignment align...
    method createState (line 24) | @Override
    class State (line 29) | public static class State extends AutomaticallyAnimatedWidget.State<An...
      method updateLerps (line 33) | @Override
      method build (line 38) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/animated/AnimatedBox.java
  class AnimatedBox (line 14) | public class AnimatedBox extends AutomaticallyAnimatedWidget {
    method AnimatedBox (line 20) | public AnimatedBox(Duration duration, Easing easing, Color color, bool...
    method AnimatedBox (line 27) | public AnimatedBox(Duration duration, Easing easing, Color color, bool...
    method AnimatedBox (line 31) | public AnimatedBox(Duration duration, Easing easing, Color color) {
    method createState (line 35) | @Override
    class State (line 40) | public static class State extends AutomaticallyAnimatedWidget.State<An...
      method updateLerps (line 44) | @Override
      method build (line 49) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/animated/AnimatedPadding.java
  class AnimatedPadding (line 14) | public class AnimatedPadding extends AutomaticallyAnimatedWidget {
    method AnimatedPadding (line 18) | public AnimatedPadding(Duration duration, Easing easing, Insets insets...
    method createState (line 24) | @Override
    class State (line 29) | public static class State extends AutomaticallyAnimatedWidget.State<An...
      method updateLerps (line 33) | @Override
      method build (line 38) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/animated/AnimatedSized.java
  class AnimatedSized (line 14) | public class AnimatedSized extends AutomaticallyAnimatedWidget {
    method AnimatedSized (line 20) | public AnimatedSized(Duration duration, Easing easing, @Nullable Doubl...
    method createState (line 27) | @Override
    class State (line 32) | public static class State extends AutomaticallyAnimatedWidget.State<An...
      method updateLerps (line 37) | @Override
      method build (line 43) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Align.java
  class Align (line 14) | public class Align extends SingleChildInstanceWidget {
    method Align (line 20) | public Align(Alignment alignment, @Nullable Double widthFactor, @Nulla...
    method Align (line 27) | public Align(Alignment alignment, Widget child) {
    method instantiate (line 31) | @Override
    class Instance (line 36) | public static class Instance extends SingleChildWidgetInstance<Align> {
      method Instance (line 38) | public Instance(Align widget) {
      method setWidget (line 42) | @Override
      method doLayout (line 54) | @Override
      method measureIntrinsicWidth (line 76) | @Override
      method measureIntrinsicHeight (line 81) | @Override
      method measureBaselineOffset (line 86) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/AspectRatio.java
  class AspectRatio (line 11) | public class AspectRatio extends SingleChildInstanceWidget {
    method AspectRatio (line 15) | public AspectRatio(double ratio, Widget child) {
    method instantiate (line 20) | @Override
    method applyAspectRatioToMaxSize (line 27) | public static Size applyAspectRatioToMaxSize(Constraints constraints, ...
    method applyAspectRatio (line 41) | public static Size applyAspectRatio(Constraints constraints, Size size) {
    class Instance (line 75) | public static class Instance extends SingleChildWidgetInstance<AspectR...
      method Instance (line 77) | public Instance(AspectRatio widget) {
      method setWidget (line 81) | @Override
      method doLayout (line 89) | @Override
      method measureIntrinsicWidth (line 97) | @Override
      method measureIntrinsicHeight (line 102) | @Override
      method measureBaselineOffset (line 107) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Blur.java
  class Blur (line 11) | public class Blur extends SingleChildInstanceWidget {
    method Blur (line 17) | public Blur(float quality, float size, boolean blurChild, Widget child) {
    method instantiate (line 24) | @Override
    class Instance (line 29) | public static class Instance extends SingleChildWidgetInstance.ShrinkW...
      method Instance (line 31) | public Instance(Blur widget) {
      method draw (line 35) | @Override
      method drawBlur (line 48) | private void drawBlur(BraidGraphics ctx) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Box.java
  class Box (line 10) | public class Box extends OptionalChildInstanceWidget {
    method Box (line 15) | public Box(Color color, boolean outline, @Nullable Widget child) {
    method Box (line 21) | public Box(Color color, @Nullable Widget child) {
    method Box (line 25) | public Box(Color color, boolean outline) {
    method Box (line 29) | public Box(Color color) {
    method instantiate (line 33) | @Override
    class Instance (line 38) | public static class Instance extends OptionalChildWidgetInstance.Shrin...
      method Instance (line 40) | public Instance(Box widget) {
      method draw (line 44) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Builder.java
  class Builder (line 7) | public class Builder extends StatelessWidget {
    method Builder (line 10) | public Builder(WidgetBuilder builder) {
    method build (line 14) | @Override
    type WidgetBuilder (line 19) | @FunctionalInterface
      method build (line 21) | Widget build(BuildContext context);

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Center.java
  class Center (line 7) | public class Center extends Align {
    method Center (line 8) | public Center(@Nullable Double widthFactor, @Nullable Double heightFac...
    method Center (line 12) | public Center(Widget child) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Clip.java
  class Clip (line 12) | public class Clip extends SingleChildInstanceWidget {
    method Clip (line 17) | public Clip(boolean clipHitTest, boolean clipDrawing, Widget child) {
    method Clip (line 23) | public Clip(Widget child) {
    method instantiate (line 27) | @Override
    class Instance (line 32) | public static class Instance extends SingleChildWidgetInstance.ShrinkW...
      method Instance (line 34) | public Instance(Clip widget) {
      method draw (line 38) | @Override
      method hitTest (line 50) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Constrain.java
  class Constrain (line 6) | public class Constrain extends ConstraintWidget {
    method Constrain (line 10) | public Constrain(Constraints constraints, Widget child) {
    method constraints (line 15) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/ConstraintWidget.java
  class ConstraintWidget (line 12) | public abstract class ConstraintWidget extends SingleChildInstanceWidget {
    method ConstraintWidget (line 14) | protected ConstraintWidget(Widget child) {
    method constraints (line 18) | protected abstract Constraints constraints();
    method instantiate (line 20) | @Override
    class Instance (line 25) | public static class Instance extends SingleChildWidgetInstance<Constra...
      method Instance (line 27) | public Instance(ConstraintWidget widget) {
      method setWidget (line 31) | @Override
      method doLayout (line 41) | @Override
      method measureIntrinsicWidth (line 46) | @Override
      method measureIntrinsicHeight (line 51) | @Override
      method measureBaselineOffset (line 56) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/ControlsOverride.java
  class ControlsOverride (line 12) | public class ControlsOverride extends InheritedWidget {
    method ControlsOverride (line 16) | public ControlsOverride(boolean disableControls, Widget child) {
    method mustRebuildDependents (line 21) | @Override
    method controlsDisabled (line 26) | public static boolean controlsDisabled(BuildContext context) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/CustomDraw.java
  class CustomDraw (line 11) | public class CustomDraw extends LeafInstanceWidget {
    method CustomDraw (line 15) | public CustomDraw(CustomDrawFunction function) {
    method instantiate (line 19) | @Override
    type CustomDrawFunction (line 24) | @FunctionalInterface
      method draw (line 26) | void draw(BraidGraphics graphics, WidgetTransform transform);
    class Instance (line 29) | public static class Instance extends LeafWidgetInstance<CustomDraw> {
      method Instance (line 31) | public Instance(CustomDraw widget) {
      method doLayout (line 35) | @Override
      method draw (line 41) | @Override
      method measureIntrinsicWidth (line 46) | @Override
      method measureIntrinsicHeight (line 51) | @Override
      method measureBaselineOffset (line 56) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/EmptyWidget.java
  class EmptyWidget (line 8) | public class EmptyWidget extends StatelessWidget {
    method EmptyWidget (line 12) | private EmptyWidget() {}
    method build (line 14) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/HitTestTrap.java
  class HitTestTrap (line 6) | public class HitTestTrap extends VisitorWidget {
    method HitTestTrap (line 10) | public HitTestTrap(boolean occludeHitTest, Widget child) {
    method HitTestTrap (line 15) | public HitTestTrap(Widget child) {
    method proxy (line 27) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/HoverableBuilder.java
  class HoverableBuilder (line 10) | public class HoverableBuilder extends StatefulWidget {
    method HoverableBuilder (line 14) | public HoverableBuilder(HoverableBuilderCallback builder, @NotNull Wid...
    method HoverableBuilder (line 19) | public HoverableBuilder(HoverableBuilderCallbackWithoutChild builder) {
    method HoverableBuilder (line 24) | public HoverableBuilder(Widget notHovered, Widget hovered) {
    method createState (line 28) | @Override
    class State (line 33) | public static class State extends WidgetState<HoverableBuilder> {
      method build (line 37) | @Override
    type HoverableBuilderCallback (line 48) | @FunctionalInterface
      method build (line 50) | Widget build(BuildContext hoverableContext, boolean hovered, Widget ...
    type HoverableBuilderCallbackWithoutChild (line 53) | @FunctionalInterface
      method build (line 55) | Widget build(BuildContext hoverableContext, boolean hovered);

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/IntrinsicHeight.java
  class IntrinsicHeight (line 10) | public class IntrinsicHeight extends SingleChildInstanceWidget {
    method IntrinsicHeight (line 12) | public IntrinsicHeight(Widget child) {
    method instantiate (line 16) | @Override
    class Instance (line 21) | public static class Instance extends SingleChildWidgetInstance<Intrins...
      method Instance (line 23) | public Instance(IntrinsicHeight widget) {
      method doLayout (line 27) | @Override
      method measureIntrinsicWidth (line 41) | @Override
      method measureIntrinsicHeight (line 46) | @Override
      method measureBaselineOffset (line 51) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/IntrinsicWidth.java
  class IntrinsicWidth (line 10) | public class IntrinsicWidth extends SingleChildInstanceWidget {
    method IntrinsicWidth (line 12) | public IntrinsicWidth(Widget child) {
    method instantiate (line 16) | @Override
    class Instance (line 21) | public static class Instance extends SingleChildWidgetInstance<Intrins...
      method Instance (line 23) | public Instance(IntrinsicWidth widget) {
      method doLayout (line 27) | @Override
      method measureIntrinsicWidth (line 41) | @Override
      method measureIntrinsicHeight (line 46) | @Override
      method measureBaselineOffset (line 51) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/LayoutBuilder.java
  class LayoutBuilder (line 16) | public class LayoutBuilder extends InstanceWidget {
    method LayoutBuilder (line 20) | public LayoutBuilder(Callback builder) {
    method instantiate (line 24) | @Override
    method proxy (line 29) | @Override
    class Proxy (line 34) | public static class Proxy extends InstanceWidgetProxy {
      method Proxy (line 41) | protected Proxy(InstanceWidget widget) {
      method instance (line 46) | @Override
      method buildScope (line 51) | @Override
      method updateWidget (line 56) | @Override
      method rebuild (line 62) | protected void rebuild(Constraints constraints) {
      method notifyDescendantInstance (line 69) | @Override
      method visitChildren (line 74) | @Override
    class Instance (line 82) | public static class Instance extends OptionalChildWidgetInstance.Shrin...
      method Instance (line 86) | public Instance(LayoutBuilder widget) {
      method doLayout (line 90) | @Override
    type Callback (line 99) | @FunctionalInterface
      method build (line 101) | Widget build(BuildContext context, Constraints constraints);

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/ListenableBuilder.java
  class ListenableBuilder (line 11) | public class ListenableBuilder extends StatefulWidget {
    method ListenableBuilder (line 17) | public ListenableBuilder(Listenable listenable, ListenableBuilderFunct...
    method ListenableBuilder (line 23) | public ListenableBuilder(Listenable listenable, ListenableBuilderWithC...
    method createState (line 29) | @Override
    class State (line 34) | public static class State extends WidgetState<ListenableBuilder> {
      method init (line 38) | @Override
      method didUpdateWidget (line 43) | @Override
      method build (line 51) | @Override
      method dispose (line 56) | @Override
    type ListenableBuilderFunction (line 64) | @FunctionalInterface
      method build (line 66) | Widget build(BuildContext listenableContext);
    type ListenableBuilderWithChildFunction (line 69) | @FunctionalInterface
      method build (line 71) | Widget build(BuildContext listenableContext, Widget child);

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/MouseArea.java
  class MouseArea (line 12) | public class MouseArea extends SingleChildInstanceWidget {
    method MouseArea (line 25) | public MouseArea(
    method clickCallback (line 33) | public MouseArea clickCallback(@Nullable ClickCallback clickCallback) {
    method clickCallback (line 39) | public @Nullable ClickCallback clickCallback() {
    method releaseCallback (line 43) | public MouseArea releaseCallback(@Nullable ReleaseCallback releaseCall...
    method releaseCallback (line 49) | public @Nullable ReleaseCallback releaseCallback() {
    method enterCallback (line 53) | public MouseArea enterCallback(@Nullable EnterCallback enterCallback) {
    method enterCallback (line 59) | public @Nullable EnterCallback enterCallback() {
    method moveCallback (line 63) | public MouseArea moveCallback(@Nullable MoveCallback moveCallback) {
    method moveCallback (line 69) | public @Nullable MoveCallback moveCallback() {
    method exitCallback (line 73) | public MouseArea exitCallback(@Nullable ExitCallback exitCallback) {
    method exitCallback (line 79) | public @Nullable ExitCallback exitCallback() {
    method dragStartCallback (line 83) | public MouseArea dragStartCallback(@Nullable DragStartCallback dragSta...
    method dragStartCallback (line 89) | public @Nullable DragStartCallback dragStartCallback() {
    method dragCallback (line 93) | public MouseArea dragCallback(@Nullable DragCallback dragCallback) {
    method dragCallback (line 99) | public @Nullable DragCallback dragCallback() {
    method dragEndCallback (line 103) | public MouseArea dragEndCallback(@Nullable DragEndCallback dragEndCall...
    method dragEndCallback (line 109) | public @Nullable DragEndCallback dragEndCallback() {
    method scrollCallback (line 113) | public MouseArea scrollCallback(@Nullable ScrollCallback scrollCallbac...
    method scrollCallback (line 119) | public @Nullable ScrollCallback scrollCallback() {
    method cursorStyleSupplier (line 123) | public MouseArea cursorStyleSupplier(@Nullable CursorStyleSupplier cur...
    method cursorStyle (line 129) | public MouseArea cursorStyle(@Nullable CursorStyle style) {
    method cursorStyleSupplier (line 133) | public @Nullable CursorStyleSupplier cursorStyleSupplier() {
    method instantiate (line 137) | @Override
    type ClickCallback (line 142) | @FunctionalInterface
      method onClick (line 144) | boolean onClick(double x, double y, int button, KeyModifiers modifie...
    type ReleaseCallback (line 147) | @FunctionalInterface
      method onRelease (line 149) | boolean onRelease(double x, double y, int button, KeyModifiers modif...
    type EnterCallback (line 152) | @FunctionalInterface
      method onMouseEnter (line 154) | void onMouseEnter();
    type MoveCallback (line 157) | @FunctionalInterface
      method onMouseMove (line 159) | void onMouseMove(double toX, double toY);
    type ExitCallback (line 162) | @FunctionalInterface
      method onMouseExit (line 164) | void onMouseExit();
    type DragStartCallback (line 167) | @FunctionalInterface
      method onDragStart (line 169) | void onDragStart(int button, KeyModifiers modifiers);
    type DragCallback (line 172) | @FunctionalInterface
      method onDrag (line 174) | void onDrag(double x, double y, double dx, double dy);
    type DragEndCallback (line 177) | @FunctionalInterface
      method onDragEnd (line 179) | void onDragEnd();
    type ScrollCallback (line 182) | @FunctionalInterface
      method onScroll (line 184) | boolean onScroll(double horizontal, double vertical);
    type CursorStyleSupplier (line 187) | @FunctionalInterface
      method getCursorStyle (line 189) | @Nullable CursorStyle getCursorStyle(double x, double y);
    class Instance (line 192) | public static class Instance extends SingleChildWidgetInstance.ShrinkW...
      method Instance (line 194) | public Instance(MouseArea widget) {
      method cursorStyleAt (line 198) | @Override
      method onMouseDown (line 204) | @Override
      method onMouseUp (line 213) | @Override
      method onMouseEnter (line 222) | @Override
      method onMouseMove (line 227) | @Override
      method onMouseExit (line 232) | @Override
      method onMouseDragStart (line 237) | @Override
      method onMouseDrag (line 242) | @Override
      method onMouseDragEnd (line 247) | @Override
      method onMouseScroll (line 252) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Padding.java
  class Padding (line 14) | public class Padding extends OptionalChildInstanceWidget {
    method Padding (line 18) | public Padding(Insets insets, @Nullable Widget child) {
    method Padding (line 23) | public Padding(Insets insets) {
    method Padding (line 27) | public Padding(Size size) {
    method instantiate (line 32) | @Override
    class Instance (line 37) | public static class Instance extends OptionalChildWidgetInstance<Paddi...
      method Instance (line 39) | public Instance(Padding widget) {
      method setWidget (line 43) | @Override
      method doLayout (line 51) | @Override
      method measureIntrinsicWidth (line 70) | @Override
      method measureIntrinsicHeight (line 76) | @Override
      method measureBaselineOffset (line 82) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Panel.java
  class Panel (line 13) | public class Panel extends OptionalChildInstanceWidget {
    method Panel (line 23) | public Panel(@Nullable Identifier texture, @Nullable Widget child) {
    method Panel (line 28) | public Panel(Identifier texture) {
    method instantiate (line 32) | @Override
    class Instance (line 37) | public static class Instance extends OptionalChildWidgetInstance.Shrin...
      method Instance (line 39) | public Instance(Panel widget) {
      method draw (line 43) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/RotatedLayout.java
  class RotatedLayout (line 14) | public class RotatedLayout extends SingleChildInstanceWidget {
    method RotatedLayout (line 18) | public RotatedLayout(int increments, Widget child) {
    method instantiate (line 23) | @Override
    class Instance (line 28) | public static class Instance extends SingleChildWidgetInstance<Rotated...
      method Instance (line 30) | public Instance(RotatedLayout widget) {
      method createTransform (line 35) | @Override
      method isVertical (line 45) | private boolean isVertical() {
      method setWidget (line 49) | @Override
      method doLayout (line 61) | @Override
      method measureIntrinsicWidth (line 83) | @Override
      method measureIntrinsicHeight (line 88) | @Override
      method measureBaselineOffset (line 93) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Sized.java
  class Sized (line 8) | public class Sized extends ConstraintWidget {
    method Sized (line 13) | public Sized(@Nullable Double width, @Nullable Double height, Widget c...
    method Sized (line 19) | public Sized(@Nullable Integer width, @Nullable Integer height, Widget...
    method Sized (line 23) | public Sized(double width, double height, Widget child) {
    method Sized (line 27) | public Sized(Size size, Widget child) {
    method constraints (line 31) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/TextureWidget.java
  class TextureWidget (line 13) | public class TextureWidget extends OptionalChildInstanceWidget {
    method TextureWidget (line 20) | public TextureWidget(Identifier texture, Wrap wrap, Filter filter, Col...
    method TextureWidget (line 28) | public TextureWidget(Identifier texture, Wrap wrap, Color color, @Null...
    method TextureWidget (line 32) | public TextureWidget(Identifier texture, Wrap wrap, Filter filter, Col...
    method TextureWidget (line 36) | public TextureWidget(Identifier texture, Wrap wrap, Color color) {
    method instantiate (line 40) | @Override
    type Wrap (line 47) | public enum Wrap {
    type Filter (line 51) | public enum Filter {
    class Instance (line 57) | public static class Instance extends OptionalChildWidgetInstance<Textu...
      method Instance (line 61) | public Instance(TextureWidget widget) {
      method attachHost (line 65) | @Override
      method setWidget (line 71) | @Override
      method refreshTextureSize (line 77) | private void refreshTextureSize() {
      method imageAspectRatio (line 91) | private double imageAspectRatio() {
      method doLayout (line 96) | @Override
      method measureIntrinsicWidth (line 109) | @Override
      method measureIntrinsicHeight (line 118) | @Override
      method measureBaselineOffset (line 127) | @Override
      method draw (line 132) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Tooltip.java
  class Tooltip (line 17) | public class Tooltip extends SingleChildInstanceWidget {
    method Tooltip (line 22) | public Tooltip(@NotNull List<ClientTooltipComponent> tooltip, Widget c...
    method Tooltip (line 28) | public Tooltip(Collection<Component> tooltip, Widget child) {
    method Tooltip (line 35) | public Tooltip(Component tooltip, Widget child) {
    method instantiate (line 41) | @Override
    class Instance (line 46) | public static class Instance extends SingleChildWidgetInstance.ShrinkW...
      method Instance (line 49) | public Instance(Tooltip widget) {
      method attachHost (line 53) | @Override
      method setWidget (line 59) | @Override
      method setup (line 65) | private void setup() {
      method getTooltipComponentsAt (line 75) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Transform.java
  class Transform (line 12) | public class Transform extends SingleChildInstanceWidget {
    method Transform (line 16) | public Transform(Matrix3x2f matrix, Widget child) {
    method instantiate (line 21) | @Override
    class Instance (line 26) | public static class Instance extends SingleChildWidgetInstance.ShrinkW...
      method Instance (line 28) | public Instance(Transform widget) {
      method setWidget (line 33) | @Override
      method createTransform (line 46) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/Visibility.java
  class Visibility (line 13) | public class Visibility extends SingleChildInstanceWidget {
    method Visibility (line 18) | public Visibility(boolean visible, boolean reportSize, Widget child) {
    method Visibility (line 24) | public Visibility(boolean visible, Widget child) {
    method instantiate (line 28) | @Override
    class Instance (line 33) | public static class Instance extends SingleChildWidgetInstance<Visibil...
      method Instance (line 35) | public Instance(Visibility widget) {
      method setWidget (line 39) | @Override
      method doLayout (line 50) | @Override
      method measureIntrinsicWidth (line 60) | @Override
      method measureIntrinsicHeight (line 65) | @Override
      method measureBaselineOffset (line 70) | @Override
      method draw (line 75) | @Override
      method hitTest (line 81) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/basic/VisitorWidget.java
  class VisitorWidget (line 9) | public abstract class VisitorWidget extends Widget {
    method VisitorWidget (line 12) | protected VisitorWidget(Widget child) {
    method proxy (line 16) | @Override
    class Proxy (line 19) | public static class Proxy<T extends VisitorWidget> extends ComposedPro...
      method Proxy (line 24) | public Proxy(Widget widget, VisitorWidget.Visitor<T> visitor) {
      method mount (line 29) | @Override
      method updateWidget (line 35) | @Override
      method doRebuild (line 41) | @Override
      method notifyDescendantInstance (line 51) | @Override
    type Visitor (line 58) | @FunctionalInterface
      method visit (line 60) | void visit(T widget, WidgetInstance<?> instance);

FILE: src/main/java/io/wispforest/owo/braid/widgets/button/Button.java
  class Button (line 13) | public class Button extends StatelessWidget {
    method Button (line 19) | public Button(@Nullable ButtonStyle style, @Nullable BooleanSupplier o...
    method Button (line 25) | public Button(@Nullable ButtonStyle style, @Nullable Runnable onClick,...
    method Button (line 29) | public Button(@Nullable BooleanSupplier onClick, Widget child) {
    method Button (line 33) | public Button(@Nullable Runnable onClick, Widget child) {
    method Button (line 37) | public Button(@Nullable ButtonStyle style, boolean active, BooleanSupp...
    method Button (line 41) | public Button(@Nullable ButtonStyle style, boolean active, Runnable on...
    method Button (line 45) | public Button(boolean active, BooleanSupplier onClick, Widget child) {
    method Button (line 49) | public Button(boolean active, Runnable onClick, Widget child) {
    method build (line 53) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/button/ButtonPanel.java
  class ButtonPanel (line 11) | public class ButtonPanel extends StatelessWidget {
    method ButtonPanel (line 15) | public ButtonPanel(boolean active, Widget child) {
    method build (line 20) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/button/ButtonStyle.java
  method overriding (line 13) | public ButtonStyle overriding(ButtonStyle other) {
  type ContentBuilder (line 23) | @FunctionalInterface
    method build (line 25) | Widget build(boolean active, Widget child);

FILE: src/main/java/io/wispforest/owo/braid/widgets/button/Clickable.java
  class Clickable (line 15) | public class Clickable extends StatelessWidget {
    method Clickable (line 21) | public Clickable(@Nullable BooleanSupplier onClick, @Nullable SoundEve...
    method Clickable (line 27) | public Clickable(@Nullable BooleanSupplier onClick, Widget child) {
    method Clickable (line 31) | public Clickable(boolean active, BooleanSupplier onClick, @Nullable So...
    method Clickable (line 35) | public Clickable(boolean active, BooleanSupplier onClick, Widget child) {
    method build (line 39) | @Override
    method alwaysClick (line 58) | public static @Nullable BooleanSupplier alwaysClick(@Nullable Runnable...

FILE: src/main/java/io/wispforest/owo/braid/widgets/button/DefaultButtonStyle.java
  class DefaultButtonStyle (line 9) | public class DefaultButtonStyle extends InheritedWidget {
    method DefaultButtonStyle (line 13) | public DefaultButtonStyle(ButtonStyle style, Widget child) {
    method merge (line 18) | public static Widget merge(ButtonStyle style, Widget child) {
    method mustRebuildDependents (line 25) | @Override
    method maybeOf (line 30) | public static @Nullable ButtonStyle maybeOf(BuildContext context) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/button/MessageButton.java
  class MessageButton (line 13) | public class MessageButton extends StatelessWidget {
    method MessageButton (line 18) | public MessageButton(Component text, @Nullable Runnable onClick) {
    method MessageButton (line 23) | public MessageButton(Component text, boolean active, Runnable onClick) {
    method build (line 27) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/checkbox/Checkbox.java
  class Checkbox (line 17) | public class Checkbox extends StatelessWidget {
    method Checkbox (line 23) | public Checkbox(@Nullable CheckboxStyle style, boolean checked, @Nulla...
    method Checkbox (line 29) | public Checkbox(boolean checked, @Nullable CheckboxCallback onUpdate) {
    method Checkbox (line 33) | public Checkbox(@Nullable CheckboxStyle style, boolean checked, boolea...
    method Checkbox (line 37) | public Checkbox(boolean checked, boolean active, CheckboxCallback onUp...
    method build (line 41) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/checkbox/CheckboxStyle.java
  method overriding (line 18) | public CheckboxStyle overriding(CheckboxStyle other) {
  type BackgroundBuilder (line 28) | @FunctionalInterface
    method build (line 30) | Widget build(boolean active);

FILE: src/main/java/io/wispforest/owo/braid/widgets/checkbox/DefaultCheckboxStyle.java
  class DefaultCheckboxStyle (line 9) | public class DefaultCheckboxStyle extends InheritedWidget {
    method DefaultCheckboxStyle (line 13) | public DefaultCheckboxStyle(CheckboxStyle style, Widget child) {
    method merge (line 18) | public static Widget merge(CheckboxStyle style, Widget child) {
    method mustRebuildDependents (line 25) | @Override
    method maybeOf (line 30) | public static @Nullable CheckboxStyle maybeOf(BuildContext context) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/checkbox/TogglingClickable.java
  class TogglingClickable (line 10) | public class TogglingClickable extends StatelessWidget {
    method TogglingClickable (line 17) | public TogglingClickable(boolean checked, @Nullable CheckboxCallback o...
    method TogglingClickable (line 24) | public TogglingClickable(boolean checked, @Nullable CheckboxCallback o...
    method TogglingClickable (line 28) | public TogglingClickable(boolean checked, boolean active, @Nullable So...
    method TogglingClickable (line 32) | public TogglingClickable(boolean checked, boolean active, CheckboxCall...
    method build (line 36) | @Override
    type CheckboxCallback (line 45) | @FunctionalInterface
      method accept (line 47) | void accept(boolean nowChecked);

FILE: src/main/java/io/wispforest/owo/braid/widgets/collapsible/Collapsible.java
  class Collapsible (line 23) | public class Collapsible extends StatefulWidget {
    method Collapsible (line 33) | public Collapsible(boolean showVerticalRule, boolean collapsed, Collap...
    method createState (line 41) | @Override
    class State (line 46) | public static class State extends WidgetState<Collapsible> {
      method build (line 50) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/collapsible/CollapsibleCallback.java
  type CollapsibleCallback (line 3) | @FunctionalInterface
    method onToggled (line 5) | void onToggled(boolean nowCollapsed);

FILE: src/main/java/io/wispforest/owo/braid/widgets/collapsible/LazyCollapsible.java
  class LazyCollapsible (line 10) | public class LazyCollapsible extends StatefulWidget {
    method LazyCollapsible (line 19) | public LazyCollapsible(boolean showVerticalRule, boolean collapsed, Co...
    method createState (line 27) | @Override
    class State (line 32) | public static class State extends WidgetState<LazyCollapsible> {
      method build (line 36) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/combobox/ComboBox.java
  class ComboBox (line 39) | public class ComboBox<T> extends StatefulWidget {
    method ComboBox (line 53) | public ComboBox(Function<T, Component> optionToName, List<T> options, ...
    method ComboBox (line 60) | public ComboBox(List<T> options, @Nullable T selectedOption, SelectCal...
    method createState (line 64) | @Override
    method optionNames (line 69) | public List<Component> optionNames() {
    method nameOption (line 73) | public Component nameOption(@Nullable T option) {
    type SelectCallback (line 79) | public interface SelectCallback<T> {
      method onSelect (line 80) | void onSelect(T option);
    class State (line 83) | private static class State<T> extends WidgetState<ComboBox<T>> {
      method isOpen (line 93) | private boolean isOpen() {
      method init (line 97) | @Override
      method didUpdateWidget (line 104) | @Override
      method dispose (line 111) | @Override
      method textListener (line 119) | private void textListener() {
      method resetTextInput (line 139) | private void resetTextInput() {
      method select (line 147) | private void select(T option) {
      method trySelectHighlightedValue (line 156) | private void trySelectHighlightedValue() {
      method cycle (line 171) | private void cycle(int offset) {
      method open (line 192) | private void open() {
      method close (line 214) | private void close() {
      method build (line 220) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/combobox/ComboBoxButtons.java
  class ComboBoxButtons (line 24) | class ComboBoxButtons<T> extends StatelessWidget {
    method ComboBoxButtons (line 31) | public ComboBoxButtons(ListenableValue<ComboBoxButtonsState<T>> state,...
    method build (line 38) | @Override
    class HighlightableButton (line 91) | private static class HighlightableButton<T> extends StatefulWidget {
      method HighlightableButton (line 98) | public HighlightableButton(ComboBox.SelectCallback<T> onSelect, T op...
      method createState (line 105) | @Override
      class State (line 110) | public static class State<T> extends WidgetState<HighlightableButton...
        method didUpdateWidget (line 112) | @Override
        method build (line 119) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/cycle/Cycler.java
  class Cycler (line 11) | public class Cycler<T> extends StatelessWidget {
    method Cycler (line 22) | public Cycler(List<T> values, T currentValue, boolean wrap, CyclerCall...
    method Cycler (line 30) | public Cycler(List<T> values, T currentValue, CyclerCallback<T> onChan...
    method forBoolean (line 34) | public static Cycler<Boolean> forBoolean(boolean value, boolean wrap, ...
    method forBoolean (line 38) | public static Cycler<Boolean> forBoolean(boolean value, CyclerCallback...
    method forEnum (line 42) | @SuppressWarnings("unchecked")
    method forEnum (line 47) | public static <T extends Enum<T>> Cycler<T> forEnum(T value, CyclerCal...
    method build (line 51) | @Override
    type CyclerCallback (line 65) | @FunctionalInterface
      method cycle (line 67) | void cycle(T newValue, int newIndex);
    type CyclingWidgetBuilder (line 70) | @FunctionalInterface
      method build (line 72) | Widget build(T currentValue, int currentIndex, CycleFunction cycle);
    type CycleFunction (line 75) | @FunctionalInterface
      method cycle (line 77) | boolean cycle(int amount);
      method forScroll (line 79) | default boolean forScroll(double amount) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/cycle/CyclingButton.java
  class CyclingButton (line 14) | public class CyclingButton<T> extends StatelessWidget {
    method CyclingButton (line 22) | public CyclingButton(List<T> values, T currentValue, boolean wrap, @Nu...
    method CyclingButton (line 30) | public CyclingButton(List<T> values, T currentValue, boolean wrap, Cyc...
    method CyclingButton (line 34) | public CyclingButton(List<T> values, T currentValue, @Nullable Cycler....
    method CyclingButton (line 38) | public CyclingButton(List<T> values, T currentValue, Cycler.CyclerCall...
    method forBoolean (line 42) | public static CyclingButton<Boolean> forBoolean(boolean value, @Nullab...
    method forBoolean (line 46) | public static CyclingButton<Boolean> forBoolean(boolean value, Cycler....
    method forEnum (line 50) | public static <T extends Enum<T>> CyclingButton<T> forEnum(T value, bo...
    method forEnum (line 54) | public static <T extends Enum<T>> CyclingButton<T> forEnum(T value, bo...
    method forEnum (line 58) | public static <T extends Enum<T>> CyclingButton<T> forEnum(T value, @N...
    method forEnum (line 62) | public static <T extends Enum<T>> CyclingButton<T> forEnum(T value, Cy...
    method build (line 66) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/cycle/CyclingClickable.java
  class CyclingClickable (line 18) | public class CyclingClickable extends StatelessWidget {
    method CyclingClickable (line 25) | public CyclingClickable(@Nullable Cycler.CycleFunction cycle, @Nullabl...
    method build (line 32) | @Override
    method cycleCallback (line 61) | private <I extends Intent> Action.Callback<I> cycleCallback(Cycler.Cyc...

FILE: src/main/java/io/wispforest/owo/braid/widgets/cycle/MessageCyclingButton.java
  class MessageCyclingButton (line 15) | public class MessageCyclingButton<T> extends StatelessWidget {
    method MessageCyclingButton (line 24) | public MessageCyclingButton(List<T> values, T currentValue, boolean wr...
    method MessageCyclingButton (line 32) | public MessageCyclingButton(List<T> values, T currentValue, boolean wr...
    method MessageCyclingButton (line 36) | public MessageCyclingButton(List<T> values, T currentValue, Component ...
    method MessageCyclingButton (line 40) | public MessageCyclingButton(List<T> values, T currentValue, Component ...
    method forBoolean (line 44) | public static MessageCyclingButton<Boolean> forBoolean(boolean value, ...
    method forBoolean (line 48) | public static MessageCyclingButton<Boolean> forBoolean(boolean value, ...
    method forEnum (line 52) | public static <T extends Enum<T>> MessageCyclingButton<T> forEnum(T va...
    method forEnum (line 56) | public static <T extends Enum<T>> MessageCyclingButton<T> forEnum(T va...
    method forEnum (line 60) | public static <T extends Enum<T>> MessageCyclingButton<T> forEnum(T va...
    method forEnum (line 64) | public static <T extends Enum<T>> MessageCyclingButton<T> forEnum(T va...
    method build (line 68) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/drag/DragArena.java
  class DragArena (line 10) | public class DragArena extends MultiChildInstanceWidget {
    method DragArena (line 12) | public DragArena(List<? extends Widget> children) {
    method DragArena (line 16) | public DragArena(Widget... children) {
    method instantiate (line 20) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/drag/DragArenaElement.java
  class DragArenaElement (line 6) | public class DragArenaElement extends VisitorWidget {
    method DragArenaElement (line 9) | public DragArenaElement(double x, double y, Widget child) {
    method proxy (line 26) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/drag/DragArenaInstance.java
  class DragArenaInstance (line 9) | public class DragArenaInstance extends MultiChildWidgetInstance<DragAren...
    method DragArenaInstance (line 11) | public DragArenaInstance(DragArena widget) {
    method adopt (line 15) | @Override
    method doLayout (line 24) | @Override
    method measureIntrinsicWidth (line 37) | @Override
    method measureIntrinsicHeight (line 42) | @Override
    method measureBaselineOffset (line 47) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/drag/DragParentData.java
  class DragParentData (line 3) | public class DragParentData {
    method DragParentData (line 5) | public DragParentData(double x, double y) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/eventstream/BraidEventSource.java
  class BraidEventSource (line 6) | public class BraidEventSource<T> extends EventSource<BraidEventStream.Li...
    method BraidEventSource (line 7) | BraidEventSource(EventStream<BraidEventStream.Listener<T>> stream) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/eventstream/BraidEventStream.java
  class BraidEventStream (line 5) | public class BraidEventStream<T> extends EventStream<BraidEventStream.Li...
    method BraidEventStream (line 7) | public BraidEventStream() {
    method source (line 13) | @Override
    type Listener (line 18) | public interface Listener<T> {
      method onEvent (line 19) | void onEvent(T event);

FILE: src/main/java/io/wispforest/owo/braid/widgets/eventstream/StreamListenerState.java
  class StreamListenerState (line 12) | public abstract class StreamListenerState<T extends StatefulWidget> exte...
    method streamListen (line 15) | protected <S> void streamListen(Function<T, @Nullable BraidEventSource...
    method didUpdateWidget (line 21) | @Override
    method dispose (line 30) | @Override
    class SubscriptionData (line 40) | private static class SubscriptionData<W, T> {
      method SubscriptionData (line 47) | private SubscriptionData(W widget, Function<W, @Nullable BraidEventS...
      method listenOn (line 54) | private void listenOn(W widget) {
      method update (line 61) | public void update(W newWidget) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/flex/Column.java
  class Column (line 13) | public class Column extends Flex {
    method Column (line 14) | public Column(
    method Column (line 24) | public Column(
    method Column (line 33) | public Column(
    method Column (line 43) | public Column(
    method Column (line 52) | public Column(
    method Column (line 60) | public Column(

FILE: src/main/java/io/wispforest/owo/braid/widgets/flex/CrossAxisAlignment.java
  type CrossAxisAlignment (line 3) | public enum CrossAxisAlignment {
    method computeChildOffset (line 16) | @SuppressWarnings("DuplicateBranchesInSwitch")

FILE: src/main/java/io/wispforest/owo/braid/widgets/flex/Flex.java
  class Flex (line 31) | public class Flex extends MultiChildInstanceWidget {
    method Flex (line 45) | public Flex(
    method Flex (line 70) | public Flex(
    method instantiate (line 79) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/flex/FlexInstance.java
  class FlexInstance (line 15) | public class FlexInstance extends MultiChildWidgetInstance<Flex> {
    method FlexInstance (line 17) | public FlexInstance(Flex widget) {
    method setWidget (line 21) | @Override
    method doLayout (line 33) | @Override
    method measureIntrinsicWidth (line 121) | @Override
    method measureIntrinsicHeight (line 126) | @Override
    method measureBaselineOffset (line 131) | @Override
    method measureMainAxis (line 139) | @SuppressWarnings("DataFlowIssue")
    method measureCrossAxis (line 169) | @SuppressWarnings("DataFlowIssue")

FILE: src/main/java/io/wispforest/owo/braid/widgets/flex/FlexParentData.java
  class FlexParentData (line 3) | public class FlexParentData {
    method FlexParentData (line 5) | public FlexParentData(double flexFactor) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/flex/Flexible.java
  class Flexible (line 14) | public class Flexible extends VisitorWidget {
    method Flexible (line 20) | public Flexible(double flexFactor, Widget child) {
    method Flexible (line 26) | public Flexible(Widget child) {
    method proxy (line 40) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/flex/MainAxisAlignment.java
  type MainAxisAlignment (line 3) | public enum MainAxisAlignment {
    method leadingSpace (line 24) | @SuppressWarnings("DuplicateBranchesInSwitch")
    method between (line 36) | @SuppressWarnings("DuplicateBranchesInSwitch")

FILE: src/main/java/io/wispforest/owo/braid/widgets/flex/Row.java
  class Row (line 13) | public class Row extends Flex {
    method Row (line 14) | public Row(
    method Row (line 24) | public Row(
    method Row (line 33) | public Row(
    method Row (line 43) | public Row(
    method Row (line 52) | public Row(
    method Row (line 60) | public Row(

FILE: src/main/java/io/wispforest/owo/braid/widgets/focus/FocusClickArea.java
  class FocusClickArea (line 7) | public class FocusClickArea extends SingleChildInstanceWidget {
    method FocusClickArea (line 11) | public FocusClickArea(Runnable clickCallback, Widget child) {
    method instantiate (line 16) | @Override
    class Instance (line 21) | public static class Instance extends SingleChildWidgetInstance.ShrinkW...
      method Instance (line 22) | public Instance(FocusClickArea widget) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/focus/FocusLevel.java
  type FocusLevel (line 3) | public enum FocusLevel {

FILE: src/main/java/io/wispforest/owo/braid/widgets/focus/FocusPolicy.java
  class FocusPolicy (line 7) | public class FocusPolicy extends InheritedWidget {
    method FocusPolicy (line 11) | public FocusPolicy(boolean clickFocus, Widget child) {
    method mustRebuildDependents (line 16) | @Override
    method of (line 23) | public static FocusPolicy of(BuildContext context) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/focus/FocusScope.java
  class FocusScope (line 23) | public class FocusScope extends Focusable {
    method FocusScope (line 25) | public FocusScope(WidgetSetupCallback<FocusScope> setupCallback, Widge...
    method proxy (line 29) | @Override
    method createState (line 34) | @Override
    class State (line 39) | public static class State extends Focusable.State<FocusScope> {
      method updateFocus (line 50) | public void updateFocus(@Nullable Focusable.State<?> primary, @Nulla...
      method updateFocus (line 54) | public void updateFocus(@Nullable Focusable.State<?> primary, @Nulla...
      method onFocusableDisposed (line 104) | void onFocusableDisposed(Focusable.State<?> descendant) {
      method primaryFocus (line 115) | @Override
      method traverseFocus (line 127) | @Override
      method traverseFocusLogical (line 135) | private void traverseFocusLogical(boolean forwards) {
      method tryTraverseFocusHistory (line 151) | private boolean tryTraverseFocusHistory(FocusTraversalDirection dire...
      method traverseFocusDirectional (line 170) | private void traverseFocusDirectional(FocusTraversalDirection direct...
      method filterCandidate (line 208) | private boolean filterCandidate(FocusTraversalCandidate candidate, A...
      method filterInBand (line 218) | private boolean filterInBand(FocusTraversalCandidate candidate, AABB...
      method sortInBand (line 226) | private Comparator<FocusTraversalCandidate> sortInBand(Vector2d focu...
      method sortOutOfBand (line 240) | private Comparator<FocusTraversalCandidate> sortOutOfBand(Vector2d f...
      method onFocusChange (line 250) | @Override
      method onKeyDown (line 265) | @Override
      method onKeyUp (line 276) | @Override
      method onChar (line 287) | @Override
      method onClick (line 298) | @Override
      method build (line 304) | @Override
      method maybeOf (line 343) | static @Nullable FocusScope.State maybeOf(BuildContext context) {
  class FocusScopeProxy (line 352) | class FocusScopeProxy extends StatefulProxy {
    method FocusScopeProxy (line 353) | public FocusScopeProxy(FocusScope widget) {
    method mount (line 357) | @Override
    method collectFocusDescendants (line 368) | private static void collectFocusDescendants(WidgetProxy proxy, List<Fo...
  method of (line 386) | public static FocusTraversalCandidate of(Focusable.State<?> state) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/focus/FocusStateProvider.java
  class FocusStateProvider (line 7) | class FocusStateProvider<F extends Focusable.State<?>> extends Inherited...
    method FocusStateProvider (line 14) | public FocusStateProvider(F state, Class<F> stateClass, @Nullable Focu...
    method inheritedKey (line 22) | @Override
    method mustRebuildDependents (line 27) | @Override
    method keyOf (line 35) | public static <F extends Focusable.State<?>> Object keyOf(Class<F> sta...

FILE: src/main/java/io/wispforest/owo/braid/widgets/focus/FocusTraversalDirection.java
  type FocusTraversalDirection (line 3) | public enum FocusTraversalDirection {
    method opposite (line 12) | public FocusTraversalDirection opposite() {

FILE: src/main/java/io/wispforest/owo/braid/widgets/focus/Focusable.java
  class Focusable (line 16) | public class Focusable extends StatefulWidget {
    method Focusable (line 32) | public Focusable(WidgetSetupCallback<Focusable> setupCallback, Widget ...
    method maybeOf (line 39) | public static @Nullable State<?> maybeOf(BuildContext context) {
    method of (line 46) | public static State<?> of(BuildContext context) {
    method levelOf (line 53) | public static @Nullable FocusLevel levelOf(BuildContext context) {
    method isFocused (line 58) | public static boolean isFocused(BuildContext context) {
    method shouldShowHighlight (line 62) | public static boolean shouldShowHighlight(BuildContext context) {
    method keyDownCallback (line 68) | public Focusable keyDownCallback(@Nullable KeyDownCallback keyDownCall...
    method keyDownCallback (line 74) | public @Nullable KeyDownCallback keyDownCallback() {
    method keyUpCallback (line 78) | public Focusable keyUpCallback(@Nullable KeyUpCallback keyUpCallback) {
    method keyUpCallback (line 84) | public @Nullable KeyUpCallback keyUpCallback() {
    method charCallback (line 88) | public Focusable charCallback(@Nullable CharCallback charCallback) {
    method charCallback (line 94) | public @Nullable CharCallback charCallback() {
    method focusGainedCallback (line 98) | public Focusable focusGainedCallback(@Nullable FocusGainedCallback foc...
    method focusGainedCallback (line 104) | public @Nullable FocusGainedCallback focusGainedCallback() {
    method focusLostCallback (line 108) | public Focusable focusLostCallback(@Nullable FocusLostCallback focusLo...
    method focusLostCallback (line 114) | public @Nullable FocusLostCallback focusLostCallback() {
    method focusLevelChangedCallback (line 118) | public Focusable focusLevelChangedCallback(@Nullable FocusLevelChanged...
    method focusLevelChangedCallback (line 124) | public @Nullable FocusLevelChangedCallback focusLevelChangedCallback() {
    method skipTraversal (line 128) | public Focusable skipTraversal(boolean skipTraversal) {
    method skipTraversal (line 134) | public boolean skipTraversal() {
    method autoFocus (line 138) | public Focusable autoFocus(boolean autoFocus) {
    method autoFocus (line 144) | public boolean autoFocus() {
    method clickFocus (line 148) | public Focusable clickFocus(@Nullable Boolean clickFocus) {
    method clickFocus (line 154) | public @Nullable Boolean clickFocus() {
    method createState (line 158) | @Override
    type KeyDownCallback (line 163) | @FunctionalInterface
      method onKeyDown (line 165) | boolean onKeyDown(int keyCode, KeyModifiers modifiers);
    type KeyUpCallback (line 168) | @FunctionalInterface
      method onKeyUp (line 170) | boolean onKeyUp(int keyCode, KeyModifiers modifiers);
    type CharCallback (line 173) | @FunctionalInterface
      method onChar (line 175) | boolean onChar(int charCode, KeyModifiers modifiers);
    type FocusGainedCallback (line 178) | @FunctionalInterface
      method onFocusGained (line 180) | void onFocusGained();
    type FocusLostCallback (line 183) | @FunctionalInterface
      method onFocusLost (line 185) | void onFocusLost();
    type FocusLevelChangedCallback (line 188) | @FunctionalInterface
      method onFocusLevelChanged (line 190) | void onFocusLevelChanged(@Nullable FocusLevel level);
    class State (line 193) | public static class State<F extends Focusable> extends WidgetState<F> {
      method debugDepth (line 201) | public int debugDepth() {
      method primaryFocus (line 205) | public State<?> primaryFocus() {
      method ancestors (line 209) | public Stream<State<?>> ancestors() {
      method requestFocus (line 217) | public void requestFocus() {
      method requestFocus (line 221) | public void requestFocus(FocusLevel level) {
      method unfocus (line 227) | public void unfocus() {
      method traverseFocus (line 233) | public void traverseFocus(FocusTraversalDirection direction) {
      method onFocusChange (line 239) | void onFocusChange(@Nullable FocusLevel newLevel) {
      method onClick (line 266) | void onClick() {
      method onKeyDown (line 273) | boolean onKeyDown(int keyCode, KeyModifiers modifiers) {
      method onKeyUp (line 284) | boolean onKeyUp(int keyCode, KeyModifiers modifiers) {
      method onChar (line 295) | boolean onChar(int charCode, KeyModifiers modifiers) {
      method init (line 306) | @Override
      method dispose (line 318) | @Override
      method build (line 325) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/focus/RootFocusScope.java
  class RootFocusScope (line 12) | public class RootFocusScope extends StatefulWidget {
    method RootFocusScope (line 19) | public RootFocusScope(
    method createState (line 31) | @Override
    class State (line 36) | public static class State extends StreamListenerState<RootFocusScope> {
      method init (line 40) | @Override
      method build (line 47) | @Override
    class FocusEvent (line 69) | private static class FocusEvent {
      method handled (line 72) | public boolean handled() {
    class KeyDownEvent (line 77) | public static final class KeyDownEvent extends FocusEvent {
      method KeyDownEvent (line 81) | public KeyDownEvent(int keyCode, KeyModifiers modifiers) {
    class KeyUpEvent (line 87) | public static final class KeyUpEvent extends FocusEvent {
      method KeyUpEvent (line 91) | public KeyUpEvent(int keyCode, KeyModifiers modifiers) {
    class CharEvent (line 97) | public static final class CharEvent extends FocusEvent {
      method CharEvent (line 101) | public CharEvent(int charCode, KeyModifiers modifiers) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/grid/Grid.java
  class Grid (line 25) | public class Grid extends MultiChildInstanceWidget {
    method Grid (line 31) | public Grid(LayoutAxis mainAxis, int crossAxisCells, CellFit cellFit, ...
    method Grid (line 38) | public Grid(LayoutAxis mainAxis, int crossAxisCells, CellFit cellFit, ...
    method Grid (line 42) | public Grid(LayoutAxis mainAxis, int crossAxisCells, CellFit cellFit, ...
    method Grid (line 46) | public Grid(LayoutAxis mainAxis, int crossAxisCells, CellFit cellFit, ...
    method instantiate (line 50) | @Override
    class Instance (line 55) | public static class Instance extends MultiChildWidgetInstance<Grid> {
      method Instance (line 60) | public Instance(Grid widget) {
      method setWidget (line 64) | @Override
      method doLayout (line 76) | @Override
      method debugListInspectorProperties (line 175) | @Override
      method debugHasVisualizers (line 185) | @Override
      method debugDrawVisualizers (line 190) | @Override
      method measureIntrinsicWidth (line 244) | @Override
      method measureIntrinsicHeight (line 251) | @Override
      method measureCrossAxis (line 258) | protected double[] measureCrossAxis(double mainAxisCellSize) {
      method measureMainAxis (line 281) | protected double[] measureMainAxis(double crossAxisCellSize) {
      method measureBaselineOffset (line 310) | @Override
    class CellFit (line 316) | public static sealed abstract class CellFit {
      method isTight (line 318) | public abstract boolean isTight();
      method loose (line 320) | public static CellFit loose() {
      method loose (line 324) | public static CellFit loose(Alignment alignment) {
      method tight (line 328) | public static CellFit tight() {
      class Tight (line 332) | public static final class Tight extends CellFit {
        method isTight (line 335) | @Override
      class Loose (line 341) | public static final class Loose extends CellFit {
        method Loose (line 343) | public Loose(Alignment alignment) {this.alignment = alignment;}
        method isTight (line 345) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/inspector/BraidInspector.java
  class BraidInspector (line 13) | public class BraidInspector {
    method BraidInspector (line 27) | public BraidInspector(AppState subject) {
    method onPick (line 31) | public BraidEventSource<Unit> onPick() {
    method pick (line 35) | public void pick() {
    method onRefresh (line 39) | public BraidEventSource<Unit> onRefresh() {
    method onReveal (line 43) | public BraidEventSource<RevealInstanceEvent> onReveal() {
    method activate (line 47) | public void activate() {
    method revealInstance (line 79) | public void revealInstance(WidgetInstance<?> instance) {
    method refresh (line 84) | public void refresh() {
    method close (line 88) | public void close() {

FILE: src/main/java/io/wispforest/owo/braid/widgets/inspector/CollapsibleEntry.java
  class CollapsibleEntry (line 18) | public class CollapsibleEntry extends StatefulWidget {
    method CollapsibleEntry (line 25) | public CollapsibleEntry(BraidEventSource<Unit> onExpand, boolean start...
    method createState (line 32) | @Override
    class State (line 37) | public static class State extends StreamListenerState<CollapsibleEntry> {
      method expand (line 41) | private void expand(Unit unit) {
      method init (line 47) | @Override
      method build (line 53) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/inspector/InspectorState.java
  class InspectorState (line 6) | public class InspectorState extends ShareableState {

FILE: src/main/java/io/wispforest/owo/braid/widgets/inspector/InspectorWidget.java
  class InspectorWidget (line 35) | public class InspectorWidget extends StatefulWidget {
    method InspectorWidget (line 41) | public InspectorWidget(WidgetProxy rootProxy, WidgetInstance<?> rootIn...
    method createState (line 47) | @Override
    class State (line 52) | public static class State extends StreamListenerState<InspectorWidget> {
      method init (line 57) | @Override
      method build (line 73) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/inspector/InstanceDetails.java
  class InstanceDetails (line 33) | public class InstanceDetails extends StatefulWidget {
    method createState (line 35) | @Override
    class State (line 40) | public static class State extends WidgetState<InstanceDetails> {
      method build (line 41) | @Override
      method gatherProperties (line 111) | private static List<Component> gatherProperties(WidgetInstance<?> in...
      method colorRows (line 136) | private static List<Widget> colorRows(Color alternateColor, int cros...
      method rounded (line 159) | private static String rounded(double value) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/inspector/InstancePicker.java
  class InstancePicker (line 25) | public class InstancePicker extends StatefulWidget {
    method InstancePicker (line 31) | public InstancePicker(BraidEventSource<Unit> activateEvents, PickCallb...
    method createState (line 37) | @Override
    class State (line 42) | public static class State extends StreamListenerState<InstancePicker> {
      method init (line 49) | @Override
      method build (line 56) | @Override
    type PickCallback (line 104) | @FunctionalInterface
      method onPick (line 106) | void onPick(WidgetInstance<?> pickedInstance);

FILE: src/main/java/io/wispforest/owo/braid/widgets/inspector/InstanceTitle.java
  class InstanceTitle (line 24) | public class InstanceTitle extends StatefulWidget {
    method InstanceTitle (line 26) | public InstanceTitle(WidgetInstance<?> instance) {
    method createState (line 30) | @Override
    class State (line 35) | public static class State extends WidgetState<InstanceTitle> {
      method build (line 39) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/inspector/InstanceTreeView.java
  class InstanceTreeView (line 29) | public class InstanceTreeView extends StatefulWidget {
    method InstanceTreeView (line 34) | public InstanceTreeView(BraidEventSource<RevealInstanceEvent> revealEv...
    method createState (line 39) | @Override
    class State (line 44) | public static class State extends StreamListenerState<InstanceTreeView> {
      method reveal (line 51) | private void reveal() {
      method init (line 57) | @Override
      method didUpdateWidget (line 73) | @Override
      method build (line 82) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/inspector/RevealInstanceEvent.java
  class RevealInstanceEvent (line 9) | public class RevealInstanceEvent {
    method RevealInstanceEvent (line 13) | public RevealInstanceEvent(WidgetInstance<?> instance) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/Action.java
  class Action (line 5) | public abstract class Action<I extends Intent> {
    method isActive (line 7) | public boolean isActive(BuildContext context, I intent) {
    method invoke (line 11) | public abstract void invoke(BuildContext context, I intent);
    method callback (line 13) | public static <I extends Intent> Action<I> callback(Callback<I> callba...
    class CallbackAction (line 17) | public static class CallbackAction<I extends Intent> extends Action<I> {
      method CallbackAction (line 21) | public CallbackAction(Callback<I> callback) {
      method invoke (line 25) | @Override
    type Callback (line 31) | @FunctionalInterface
      method invoke (line 33) | void invoke(BuildContext actionCtx, I intent);

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/Actions.java
  class Actions (line 15) | public class Actions extends StatefulWidget {
    method Actions (line 24) | public Actions(@Nullable WidgetSetupCallback<Actions> setup, Widget ch...
    method focusable (line 30) | public Actions focusable(boolean focusable) {
    method focusable (line 36) | public boolean focusable() {
    method autoFocus (line 40) | public Actions autoFocus(boolean autoFocus) {
    method autoFocus (line 46) | public boolean autoFocus() {
    method skipTraversal (line 50) | public Actions skipTraversal(boolean skipTraversal) {
    method skipTraversal (line 56) | public boolean skipTraversal() {
    method actions (line 60) | public Actions actions(Map<Class<? extends Intent>, Action<?>> actions) {
    method addAction (line 66) | public <I extends Intent> Actions addAction(Class<I> intentType, Actio...
    method addCallbackAction (line 75) | public <I extends Intent> Actions addCallbackAction(Class<I> intentTyp...
    method actions (line 80) | public Map<Class<? extends Intent>, Action<?>> actions() {
    method createState (line 84) | @Override
    method invoke (line 91) | public static boolean invoke(BuildContext context, Intent intent) {
    method actionForIntent (line 101) | @SuppressWarnings({"unchecked"})
    class State (line 120) | public static class State extends WidgetState<Actions> {
      method build (line 121) | @Override
  class ActionsProvider (line 134) | class ActionsProvider extends InheritedWidget {
    method ActionsProvider (line 138) | public ActionsProvider(Actions.State state, Widget child) {
    method mustRebuildDependents (line 143) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/AdjustIntent.java
  type Direction (line 4) | public enum Direction {
    method offset (line 7) | public int offset() {

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/Intent.java
  type Intent (line 3) | public interface Intent {}

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/Interactable.java
  class Interactable (line 17) | public class Interactable extends StatefulWidget {
    method Interactable (line 34) | public Interactable(
    method primary (line 44) | public static Widget primary(@Nullable Runnable onClick, @Nullable Wid...
    method primary (line 62) | public static Widget primary(Runnable onClick, Widget child) {
    method enterCallback (line 68) | public Interactable enterCallback(@Nullable MouseArea.EnterCallback en...
    method enterCallback (line 74) | public @Nullable MouseArea.EnterCallback enterCallback() {
    method exitCallback (line 78) | public Interactable exitCallback(@Nullable MouseArea.ExitCallback exit...
    method exitCallback (line 84) | public @Nullable MouseArea.ExitCallback exitCallback() {
    method cursorStyleSupplier (line 88) | public Interactable cursorStyleSupplier(@Nullable MouseArea.CursorStyl...
    method cursorStyle (line 94) | public Interactable cursorStyle(@Nullable CursorStyle style) {
    method cursorStyleSupplier (line 98) | public @Nullable MouseArea.CursorStyleSupplier cursorStyleSupplier() {
    method focusGainedCallback (line 102) | public Interactable focusGainedCallback(@Nullable Focusable.FocusGaine...
    method focusGainedCallback (line 108) | public @Nullable Focusable.FocusGainedCallback focusGainedCallback() {
    method focusLostCallback (line 112) | public Interactable focusLostCallback(@Nullable Focusable.FocusLostCal...
    method focusLostCallback (line 118) | public @Nullable Focusable.FocusLostCallback focusLostCallback() {
    method skipTraversal (line 122) | public Interactable skipTraversal(boolean skipTraversal) {
    method skipTraversal (line 128) | public boolean skipTraversal() {
    method autoFocus (line 132) | public Interactable autoFocus(boolean autoFocus) {
    method autoFocus (line 138) | public boolean autoFocus() {
    method actions (line 142) | public Interactable actions(Map<Class<? extends Intent>, Action<?>> ac...
    method addAction (line 148) | public <I extends Intent> Interactable addAction(Class<I> intentType, ...
    method addCallbackAction (line 157) | public <I extends Intent> Interactable addCallbackAction(Class<I> inte...
    method actions (line 162) | public Map<Class<? extends Intent>, Action<?>> actions() {
    method createState (line 166) | @Override
    class State (line 179) | public static class State extends WidgetState<Interactable> {
      method build (line 180) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/PrimaryActionIntent.java
  class PrimaryActionIntent (line 3) | public class PrimaryActionIntent implements Intent {
    method PrimaryActionIntent (line 4) | private PrimaryActionIntent() {}

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/SecondaryActionIntent.java
  class SecondaryActionIntent (line 3) | public class SecondaryActionIntent implements Intent {
    method SecondaryActionIntent (line 4) | private SecondaryActionIntent() {}

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/ShortcutDecoder.java
  class ShortcutDecoder (line 24) | public class ShortcutDecoder extends StatefulWidget {
    method ShortcutDecoder (line 38) | public ShortcutDecoder(
    method enterCallback (line 46) | public ShortcutDecoder enterCallback(@Nullable MouseArea.EnterCallback...
    method enterCallback (line 52) | public @Nullable MouseArea.EnterCallback enterCallback() {
    method exitCallback (line 56) | public ShortcutDecoder exitCallback(@Nullable MouseArea.ExitCallback e...
    method exitCallback (line 62) | public @Nullable MouseArea.ExitCallback exitCallback() {
    method cursorStyleSupplier (line 66) | public ShortcutDecoder cursorStyleSupplier(@Nullable MouseArea.CursorS...
    method cursorStyle (line 72) | public ShortcutDecoder cursorStyle(@Nullable CursorStyle style) {
    method cursorStyleSupplier (line 76) | public @Nullable MouseArea.CursorStyleSupplier cursorStyleSupplier() {
    method focusGainedCallback (line 80) | public ShortcutDecoder focusGainedCallback(@Nullable Focusable.FocusGa...
    method focusGainedCallback (line 86) | public @Nullable Focusable.FocusGainedCallback focusGainedCallback() {
    method focusLostCallback (line 90) | public ShortcutDecoder focusLostCallback(@Nullable Focusable.FocusLost...
    method focusLostCallback (line 96) | public @Nullable Focusable.FocusLostCallback focusLostCallback() {
    method skipTraversal (line 100) | public ShortcutDecoder skipTraversal(boolean skipTraversal) {
    method skipTraversal (line 106) | public boolean skipTraversal() {
    method autoFocus (line 110) | public ShortcutDecoder autoFocus(boolean autoFocus) {
    method autoFocus (line 116) | public boolean autoFocus() {
    method shortcuts (line 120) | public ShortcutDecoder shortcuts(Map<List<ShortcutTrigger>, Listener> ...
    method addShortcut (line 126) | public ShortcutDecoder addShortcut(List<ShortcutTrigger> triggers, Lis...
    method addShortcut (line 132) | public ShortcutDecoder addShortcut(ShortcutTrigger trigger, Listener a...
    method shortcuts (line 136) | public Map<List<ShortcutTrigger>, Listener> shortcuts() {
    method createState (line 140) | @Override
    type Listener (line 145) | @FunctionalInterface
      method trigger (line 147) | boolean trigger(TriggerType type);
    class State (line 150) | public static class State extends WidgetState<ShortcutDecoder> {
      method init (line 156) | @Override
      method didUpdateWidget (line 161) | @Override
      method buildSequences (line 166) | private void buildSequences() {
      method build (line 170) | @Override
      method stepShortcuts (line 195) | private boolean stepShortcuts(Function<ShortcutTrigger, ShortcutTrig...
      method dispatch (line 266) | private boolean dispatch(@Nullable ShortcutDecoder.State.ShortcutSeq...
      type ShortcutTriggerResult (line 288) | private enum ShortcutTriggerResult {
      type ShortcutSequenceStep (line 301) | private enum ShortcutSequenceStep {
      class ShortcutSequence (line 307) | private static class ShortcutSequence {
        method ShortcutSequence (line 317) | public ShortcutSequence(List<ShortcutTrigger> triggers, Listener c...
        method step (line 327) | public ShortcutSequenceStep step(Function<ShortcutTrigger, Shortcu...

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/ShortcutTrigger.java
  method of (line 51) | public static ShortcutTrigger of(ShortcutTrigger... triggers) {
  method of (line 55) | public static ShortcutTrigger of(ShortcutTrigger actionTrigger, Trigger....
  method ShortcutTrigger (line 61) | public ShortcutTrigger(Collection<Trigger> triggers) {
  method ShortcutTrigger (line 65) | public ShortcutTrigger(Trigger... triggers) {
  method withModifiers (line 69) | public ShortcutTrigger withModifiers(@Nullable KeyModifiers modifiers) {
  method isTriggeredByMouseButton (line 78) | public boolean isTriggeredByMouseButton(int button, KeyModifiers modifie...
  method isTriggeredByKeyCode (line 82) | public boolean isTriggeredByKeyCode(int keyCode, KeyModifiers modifiers) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/Shortcuts.java
  class Shortcuts (line 17) | public class Shortcuts extends StatefulWidget {
    method Shortcuts (line 31) | public Shortcuts(Map<List<ShortcutTrigger>, Intent> shortcuts, @Nullab...
    method enterCallback (line 37) | public Shortcuts enterCallback(@Nullable MouseArea.EnterCallback enter...
    method enterCallback (line 43) | public @Nullable MouseArea.EnterCallback enterCallback() {
    method exitCallback (line 47) | public Shortcuts exitCallback(@Nullable MouseArea.ExitCallback exitCal...
    method exitCallback (line 53) | public @Nullable MouseArea.ExitCallback exitCallback() {
    method cursorStyleSupplier (line 57) | public Shortcuts cursorStyleSupplier(@Nullable MouseArea.CursorStyleSu...
    method cursorStyle (line 63) | public Shortcuts cursorStyle(@Nullable CursorStyle style) {
    method cursorStyleSupplier (line 67) | public @Nullable MouseArea.CursorStyleSupplier cursorStyleSupplier() {
    method focusGainedCallback (line 71) | public Shortcuts focusGainedCallback(@Nullable Focusable.FocusGainedCa...
    method focusGainedCallback (line 77) | public @Nullable Focusable.FocusGainedCallback focusGainedCallback() {
    method focusLostCallback (line 81) | public Shortcuts focusLostCallback(@Nullable Focusable.FocusLostCallba...
    method focusLostCallback (line 87) | public @Nullable Focusable.FocusLostCallback focusLostCallback() {
    method skipTraversal (line 91) | public Shortcuts skipTraversal(boolean skipTraversal) {
    method skipTraversal (line 97) | public boolean skipTraversal() {
    method autoFocus (line 101) | public Shortcuts autoFocus(boolean autoFocus) {
    method autoFocus (line 107) | public boolean autoFocus() {
    method createState (line 111) | @Override
    class State (line 116) | public static class State extends WidgetState<Shortcuts> {
      method init (line 120) | @Override
      method didUpdateWidget (line 125) | @Override
      method buildListeners (line 130) | private void buildListeners() {
      method build (line 144) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/TraverseFocusAction.java
  class TraverseFocusAction (line 6) | public class TraverseFocusAction extends Action<TraverseFocusIntent> {
    method invoke (line 7) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/Trigger.java
  type Trigger (line 8) | public sealed interface Trigger {
    method isTriggered (line 10) | boolean isTriggered(int button, @Nullable KeyModifiers modifiers);
    method withModifiers (line 12) | Trigger withModifiers(@Nullable KeyModifiers modifiers);
    method ofKey (line 14) | static Trigger.Key ofKey(int keyCode, @Nullable KeyModifiers modifiers) {
    method ofKey (line 18) | static Trigger.Key ofKey(int keyCode) {
    method ofMouse (line 22) | static Trigger.Mouse ofMouse(int button, @Nullable KeyModifiers modifi...
    method ofMouse (line 26) | static Trigger.Mouse ofMouse(int button) {
    method Key (line 32) | public Key(int keyCode) {
    method isTriggered (line 36) | @Override
    method withModifiers (line 41) | @Override
    method Mouse (line 51) | public Mouse(int button) {
    method isTriggered (line 55) | @Override
    method withModifiers (line 60) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/intents/TriggerType.java
  type TriggerType (line 3) | public enum TriggerType {

FILE: src/main/java/io/wispforest/owo/braid/widgets/label/DefaultLabelStyle.java
  class DefaultLabelStyle (line 9) | public class DefaultLabelStyle extends InheritedWidget {
    method DefaultLabelStyle (line 13) | public DefaultLabelStyle(LabelStyle style, Widget child) {
    method merge (line 18) | public static Widget merge(LabelStyle style, Widget child) {
    method mustRebuildDependents (line 25) | @Override
    method maybeOf (line 30) | public static @Nullable LabelStyle maybeOf(BuildContext context) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/label/Label.java
  class Label (line 10) | public class Label extends StatelessWidget {
    method Label (line 17) | public Label(@Nullable LabelStyle style, boolean softWrap, Overflow ov...
    method Label (line 24) | public Label(@Nullable LabelStyle style, boolean softWrap, Component t...
    method Label (line 28) | public Label(boolean softWrap, Component text) {
    method Label (line 32) | public Label(Overflow overflow, Component text) {
    method Label (line 36) | public Label(Component text) {
    method literal (line 40) | public static Label literal(String text) {
    method build (line 44) | @Override
    type Overflow (line 65) | public enum Overflow {

FILE: src/main/java/io/wispforest/owo/braid/widgets/label/LabelStyle.java
  method overriding (line 12) | public LabelStyle overriding(LabelStyle other) {
  method fillDefaults (line 21) | public LabelStyle fillDefaults() {

FILE: src/main/java/io/wispforest/owo/braid/widgets/label/RawLabel.java
  class RawLabel (line 33) | public class RawLabel extends LeafInstanceWidget {
    method RawLabel (line 40) | public RawLabel(LabelStyle style, boolean softWrap, boolean ellipsize,...
    method instantiate (line 47) | @Override
    class Instance (line 52) | public static class Instance extends LeafWidgetInstance<RawLabel> impl...
      method Instance (line 62) | public Instance(RawLabel widget) {
      method setWidget (line 66) | @Override
      method wrapText (line 79) | protected List<FormattedCharSequence> wrapText(Font font, int maxWid...
      method measureText (line 100) | protected TextMetrics measureText(Font font, List<FormattedCharSeque...
      method doLayout (line 116) | @Override
      method measureIntrinsicWidth (line 130) | @Override
      method measureIntrinsicHeight (line 136) | @Override
      method measureBaselineOffset (line 142) | @Override
      method draw (line 147) | @Override
      method collectText (line 167) | public void collectText(ActiveTextCollector collector) {
      method getTooltipComponentsAt (line 180) | @Override
      method getStyleAt (line 186) | @Override
      method onMouseDown (line 197) | @Override
      method cursorStyleAt (line 203) | @Override
      class StyleCollector (line 211) | public static class StyleCollector extends ActiveTextCollector.Click...
        method StyleCollector (line 213) | public StyleCollector(Font font, int clickX, int clickY) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/object/BlockWidget.java
  class BlockWidget (line 22) | public class BlockWidget extends StatefulWidget {
    method BlockWidget (line 29) | private BlockWidget(BlockState blockState, @Nullable BlockEntity block...
    method BlockWidget (line 36) | public BlockWidget(BlockState blockState, @Nullable BlockEntity blockE...
    method BlockWidget (line 40) | public BlockWidget(BlockState blockState, @Nullable BlockEntity blockE...
    method BlockWidget (line 44) | public BlockWidget(BlockState blockState, @Nullable CompoundTag blockE...
    method BlockWidget (line 48) | public BlockWidget(BlockState blockState, @Nullable CompoundTag blockE...
    method BlockWidget (line 52) | public BlockWidget(BlockState blockState, Consumer<Matrix4f> transform) {
    method BlockWidget (line 56) | public BlockWidget(BlockState blockState) {
    method createState (line 60) | @Override
    class State (line 65) | public static class State extends WidgetState<BlockWidget> {
      method init (line 69) | @Override
      method didUpdateWidget (line 74) | @Override
      method resetBlockEntity (line 85) | private void resetBlockEntity() {
      method build (line 91) | @Override
      method prepareBlockEntity (line 102) | private static @Nullable BlockEntity prepareBlockEntity(BlockState s...

FILE: src/main/java/io/wispforest/owo/braid/widgets/object/EntityWidget.java
  class EntityWidget (line 20) | public class EntityWidget extends LeafInstanceWidget {
    method EntityWidget (line 30) | public EntityWidget(double scale, Entity entity, @Nullable WidgetSetup...
    method displayMode (line 36) | public EntityWidget displayMode(DisplayMode displayMode) {
    method displayMode (line 41) | public DisplayMode displayMode() {
    method scaleToFit (line 45) | public EntityWidget scaleToFit(boolean scaleToFit) {
    method scaleToFit (line 50) | public boolean scaleToFit() {
    method showNametag (line 54) | public EntityWidget showNametag(boolean showNametag) {
    method showNametag (line 59) | public boolean showNametag() {
    method transform (line 63) | public EntityWidget transform(Consumer<Matrix4f> transform) {
    method transform (line 68) | public @Nullable Consumer<Matrix4f> transform() {
    method instantiate (line 72) | @Override
    class Instance (line 77) | public static class Instance extends LeafWidgetInstance<EntityWidget> {
      method Instance (line 81) | public Instance(EntityWidget widget) {
      method setWidget (line 85) | @Override
      method doLayout (line 94) | @Override
      method measureIntrinsicWidth (line 106) | @Override
      method measureIntrinsicHeight (line 111) | @Override
      method measureBaselineOffset (line 116) | @Override
      method draw (line 121) | @Override
    type DisplayMode (line 212) | public enum DisplayMode {

FILE: src/main/java/io/wispforest/owo/braid/widgets/object/ItemStackWidget.java
  class ItemStackWidget (line 24) | public class ItemStackWidget extends LeafInstanceWidget {
    method ItemStackWidget (line 32) | public ItemStackWidget(ItemStack stack, @Nullable WidgetSetupCallback<...
    method ItemStackWidget (line 37) | public ItemStackWidget(ItemStack stack) {
    method showOverlay (line 41) | public ItemStackWidget showOverlay(boolean showOverlay) {
    method showOverlay (line 47) | public boolean showOverlay() {
    method displayContext (line 51) | public ItemStackWidget displayContext(ItemDisplayContext displayContex...
    method displayContext (line 58) | public ItemDisplayContext displayContext() {
    method lightOverride (line 62) | public ItemStackWidget lightOverride(@Nullable LightOverride lightOver...
    method lightOverride (line 68) | public @Nullable LightOverride lightOverride() {
    method transform (line 72) | public ItemStackWidget transform(@Nullable Consumer<Matrix4f> transfor...
    method transform (line 77) | public @Nullable Consumer<Matrix4f> transform() {
    method instantiate (line 81) | @Override
    class Instance (line 86) | public static class Instance extends LeafWidgetInstance<ItemStackWidge...
      method Instance (line 90) | public Instance(ItemStackWidget widget) {
      method doLayout (line 94) | @Override
      method measureIntrinsicWidth (line 100) | @Override
      method measureIntrinsicHeight (line 105) | @Override
      method measureBaselineOffset (line 110) | @Override
      method draw (line 115) | @Override
    type LightOverride (line 159) | public enum LightOverride {

FILE: src/main/java/io/wispforest/owo/braid/widgets/object/RawBlockWidget.java
  class RawBlockWidget (line 23) | public class RawBlockWidget extends LeafInstanceWidget {
    method RawBlockWidget (line 29) | public RawBlockWidget(BlockState blockState, @Nullable BlockEntity blo...
    method instantiate (line 35) | @Override
    class Instance (line 42) | public static class Instance extends LeafWidgetInstance<RawBlockWidget> {
      method Instance (line 46) | public Instance(RawBlockWidget widget) {
      method doLayout (line 50) | @Override
      method measureIntrinsicWidth (line 56) | @Override
      method measureIntrinsicHeight (line 61) | @Override
      method measureBaselineOffset (line 66) | @Override
      method draw (line 71) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/overlay/Overlay.java
  class Overlay (line 20) | public class Overlay extends StatefulWidget {
    method Overlay (line 24) | public Overlay(Widget child) {
    method createState (line 28) | @Override
    method maybeOf (line 35) | public static @Nullable State maybeOf(BuildContext context) {
    method of (line 40) | public static State of(BuildContext context) {
    class State (line 49) | public static class State extends WidgetState<Overlay> {
      method add (line 51) | public OverlayEntry add(OverlayEntryBuilder builder) {
      method build (line 75) | @SuppressWarnings("DataFlowIssue")

FILE: src/main/java/io/wispforest/owo/braid/widgets/overlay/OverlayEntry.java
  class OverlayEntry (line 8) | public class OverlayEntry {
    method OverlayEntry (line 21) | OverlayEntry(Overlay.State owner, @Nullable Runnable onRemove, Widget ...
    method setState (line 33) | public void setState(Runnable fn) {
    method remove (line 37) | public void remove() {

FILE: src/main/java/io/wispforest/owo/braid/widgets/overlay/OverlayEntryBuilder.java
  class OverlayEntryBuilder (line 7) | public class OverlayEntryBuilder {
    method OverlayEntryBuilder (line 15) | public OverlayEntryBuilder(Widget widget, RelativePosition position) {
    method onRemove (line 20) | public OverlayEntryBuilder onRemove(Runnable onRemove) {
    method dismissOverlayOnClick (line 25) | public OverlayEntryBuilder dismissOverlayOnClick() {
    method occludeHitTest (line 30) | public OverlayEntryBuilder occludeHitTest() {

FILE: src/main/java/io/wispforest/owo/braid/widgets/overlay/OverlayParentData.java
  class OverlayParentData (line 3) | public class OverlayParentData {
    method OverlayParentData (line 5) | public OverlayParentData(double x, double y) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/overlay/OverlayProvider.java
  class OverlayProvider (line 6) | class OverlayProvider extends InheritedWidget {
    method OverlayProvider (line 10) | protected OverlayProvider(Overlay.State state, Widget child) {
    method mustRebuildDependents (line 15) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/overlay/RawOverlay.java
  class RawOverlay (line 11) | public class RawOverlay extends MultiChildInstanceWidget {
    method RawOverlay (line 13) | public RawOverlay(List<? extends RawOverlayElement> children) {
    method RawOverlay (line 17) | public RawOverlay(RawOverlayElement... children) {
    method instantiate (line 21) | @Override
    class Instance (line 26) | public static class Instance extends MultiChildWidgetInstance<RawOverl...
      method Instance (line 28) | public Instance(RawOverlay widget) {
      method doLayout (line 32) | @Override
      method measureIntrinsicWidth (line 45) | @Override
      method measureIntrinsicHeight (line 50) | @Override
      method measureBaselineOffset (line 55) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/overlay/RawOverlayElement.java
  class RawOverlayElement (line 6) | public class RawOverlayElement extends VisitorWidget {
    method RawOverlayElement (line 9) | public RawOverlayElement(double x, double y, Widget child) {
    method proxy (line 26) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/owoui/OwoUIWidget.java
  class OwoUIWidget (line 15) | public class OwoUIWidget extends StatefulWidget {
    method OwoUIWidget (line 18) | public OwoUIWidget(Supplier<ParentUIComponent> componentSupplier) {
    method createState (line 22) | @Override
    class State (line 27) | public static class State extends WidgetState<OwoUIWidget> {
      method init (line 31) | @Override
      method build (line 36) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/owoui/OwoUIWidgetWrapper.java
  class OwoUIWidgetWrapper (line 23) | public class OwoUIWidgetWrapper extends LeafInstanceWidget {
    method OwoUIWidgetWrapper (line 26) | public OwoUIWidgetWrapper(ParentUIComponent rootComponent) {
    method instantiate (line 30) | @Override
    class Instance (line 35) | public static class Instance extends LeafWidgetInstance<OwoUIWidgetWra...
      method Instance (line 41) | public Instance(OwoUIWidgetWrapper widget) {
      method doLayout (line 45) | @Override
      method measureIntrinsicWidth (line 56) | @Override
      method measureIntrinsicHeight (line 68) | @Override
      method measureBaselineOffset (line 80) | @Override
      method onMouseMove (line 85) | @Override
      method onMouseExit (line 91) | @Override
      method onFocusLost (line 97) | public void onFocusLost() {
      method cursorStyleAt (line 101) | @Override
      method onMouseDown (line 122) | @Override
      method onMouseUp (line 127) | @Override
      method onMouseScroll (line 132) | @Override
      method onMouseDragStart (line 137) | @Override
      method onMouseDrag (line 142) | @Override
      method onMouseDragEnd (line 147) | @Override
      method onKeyDown (line 152) | public boolean onKeyDown(int keyCode, KeyModifiers modifiers) {
      method onChar (line 156) | public boolean onChar(int charCode, KeyModifiers modifiers) {
      method draw (line 160) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/recipeviewer/RecipeViewerExclusionZone.java
  class RecipeViewerExclusionZone (line 7) | public class RecipeViewerExclusionZone extends SingleChildInstanceWidget {
    method RecipeViewerExclusionZone (line 8) | public RecipeViewerExclusionZone(Widget child) {
    method instantiate (line 12) | @Override
    class Instance (line 17) | public static class Instance extends SingleChildWidgetInstance.ShrinkW...
      method Instance (line 18) | public Instance(RecipeViewerExclusionZone widget) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/recipeviewer/RecipeViewerStack.java
  class RecipeViewerStack (line 10) | public class RecipeViewerStack extends SingleChildInstanceWidget {
    method RecipeViewerStack (line 13) | public RecipeViewerStack(Supplier<ViewerStack> stackProvider, Widget c...
    method instantiate (line 18) | @Override
    class Instance (line 23) | public static class Instance extends SingleChildWidgetInstance.ShrinkW...
      method Instance (line 24) | public Instance(RecipeViewerStack widget) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/recipeviewer/StackDropArea.java
  class StackDropArea (line 11) | public class StackDropArea extends SingleChildInstanceWidget {
    method StackDropArea (line 15) | public StackDropArea(Predicate<ViewerStack> stackPredicate, Consumer<V...
    method instantiate (line 21) | @Override
    class Instance (line 26) | public static class Instance extends SingleChildWidgetInstance.ShrinkW...
      method Instance (line 27) | public Instance(StackDropArea widget) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/scroll/ButtonScrollbar.java
  class ButtonScrollbar (line 7) | public class ButtonScrollbar extends Scrollbar {
    method ButtonScrollbar (line 9) | public ButtonScrollbar(LayoutAxis axis, ScrollController controller) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/scroll/DefaultScrollAnimationSettings.java
  class DefaultScrollAnimationSettings (line 8) | public class DefaultScrollAnimationSettings extends InheritedWidget {
    method DefaultScrollAnimationSettings (line 12) | public DefaultScrollAnimationSettings(ScrollAnimationSettings settings...
    method mustRebuildDependents (line 17) | @Override
    method maybeOf (line 24) | public static @Nullable ScrollAnimationSettings maybeOf(BuildContext c...

FILE: src/main/java/io/wispforest/owo/braid/widgets/scroll/FlatScrollbar.java
  class FlatScrollbar (line 10) | public class FlatScrollbar extends Scrollbar {
    method FlatScrollbar (line 11) | public FlatScrollbar(LayoutAxis axis, ScrollController controller, Col...

FILE: src/main/java/io/wispforest/owo/braid/widgets/scroll/HorizontallyScrollable.java
  class HorizontallyScrollable (line 6) | public class HorizontallyScrollable extends Scrollable {
    method HorizontallyScrollable (line 7) | public HorizontallyScrollable(@Nullable ScrollController controller, @...
    method HorizontallyScrollable (line 11) | public HorizontallyScrollable(Widget child) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/scroll/RawScrollView.java
  class RawScrollView (line 11) | public class RawScrollView extends SingleChildInstanceWidget {
    method RawScrollView (line 16) | public RawScrollView(
    method instantiate (line 26) | @Override
    class Instance (line 31) | public static class Instance extends SingleChildWidgetInstance<RawScro...
      method Instance (line 36) | public Instance(RawScrollView widget) {
      method setWidget (line 45) | @Override
      method doLayout (line 68) | @Override
      method updateMaxOffset (line 105) | private void updateMaxOffset(@Nullable ScrollController controller, ...
      method measureIntrinsicWidth (line 114) | @Override
      method measureIntrinsicHeight (line 119) | @Override
      method measureBaselineOffset (line 124) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/scroll/ScrollController.java
  class ScrollController (line 12) | public class ScrollController extends Listenable {
    method ScrollController (line 17) | public ScrollController(WidgetState<?> contextState) {
    method ScrollController (line 21) | public ScrollController(Animation.Scheduler callbackScheduler) {
    method animateTo (line 35) | public void animateTo(double offset, Duration duration, Easing easing) {
    method animateBy (line 43) | public void animateBy(double by, Duration duration, Easing easing) {
    method jumpTo (line 47) | public void jumpTo(double offset) {
    method jumpBy (line 56) | public void jumpBy(double by) {
    method setOffset (line 60) | private void setOffset(double offset) {
    method clampOffset (line 69) | private double clampOffset(double offset) {
    method offset (line 73) | public double offset() {
    method setMaxOffset (line 77) | boolean setMaxOffset(double maxOffset) {
    method sendMaxOffsetNotification (line 89) | void sendMaxOffsetNotification() {
    method maxOffset (line 94) | public double maxOffset() {

FILE: src/main/java/io/wispforest/owo/braid/widgets/scroll/Scrollable.java
  class Scrollable (line 21) | public class Scrollable extends StatefulWidget {
    method Scrollable (line 30) | public Scrollable(
    method createState (line 46) | @Override
    method reveal (line 53) | public static void reveal(BuildContext context) {
    method reveal (line 57) | public static void reveal(BuildContext context, Insets padding) {
    method revealAabb (line 61) | public static void revealAabb(BuildContext context, Aabb2d box) {
    method maybeOf (line 65) | public static @Nullable State maybeOf(BuildContext context) {
    method of (line 70) | public static State of(BuildContext context) {
    class State (line 79) | public static class State extends WidgetState<Scrollable> {
      method reveal (line 86) | private void reveal(BuildContext context, Insets padding) {
      method revealAabb (line 103) | private void revealAabb(BuildContext context, Aabb2d box) {
      method init (line 135) | @Override
      method didUpdateWidget (line 144) | @Override
      method build (line 173) | @Override
  class ScrollableProvider (line 229) | class ScrollableProvider extends InheritedWidget {
    method ScrollableProvider (line 233) | public ScrollableProvider(Scrollable.State state, Widget child) {
    method mustRebuildDependents (line 238) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/scroll/ScrollableWithBars.java
  class ScrollableWithBars (line 21) | public class ScrollableWithBars extends StatefulWidget {
    method ScrollableWithBars (line 30) | public ScrollableWithBars(@Nullable ScrollController horizontalControl...
    method createState (line 39) | @Override
    class State (line 44) | public static class State extends WidgetState<ScrollableWithBars> {
      method updateControllers (line 49) | private void updateControllers() {
      method init (line 57) | @Override
      method didUpdateWidget (line 62) | @Override
      method build (line 67) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/scroll/Scrollbar.java
  class Scrollbar (line 15) | public class Scrollbar extends StatelessWidget {
    method Scrollbar (line 22) | public Scrollbar(LayoutAxis axis, ScrollController controller, @Nullab...
    method build (line 29) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/scroll/VerticallyScrollable.java
  class VerticallyScrollable (line 6) | public class VerticallyScrollable extends Scrollable {
    method VerticallyScrollable (line 7) | public VerticallyScrollable(@Nullable ScrollController controller, @Nu...
    method VerticallyScrollable (line 11) | public VerticallyScrollable(Widget child) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/sharedstate/ShareableState.java
  class ShareableState (line 3) | public abstract class ShareableState {
    method setState (line 6) | public final void setState(Runnable fn) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/sharedstate/SharedState.java
  class SharedState (line 13) | public class SharedState<T extends ShareableState> extends StatefulWidget {
    method SharedState (line 17) | public SharedState(Supplier<T> initState, Widget child) {
    method createState (line 22) | @Override
    method get (line 27) | public static <T extends ShareableState> T get(BuildContext context, C...
    method getWithoutDependency (line 34) | public static <T extends ShareableState> T getWithoutDependency(BuildC...
    method select (line 41) | public static <T extends ShareableState, S> S select(BuildContext cont...
    method set (line 51) | public static <T extends ShareableState> void set(BuildContext context...
    class State (line 58) | public static class State<T extends ShareableState> extends WidgetStat...
      method init (line 62) | @Override
      method build (line 70) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/sharedstate/SharedStateProvider.java
  class SharedStateProvider (line 13) | public final class SharedStateProvider<T extends ShareableState> extends...
    method SharedStateProvider (line 19) | public SharedStateProvider(SharedState.State<T> state, int generation,...
    method proxy (line 27) | @Override
    method inheritedKey (line 32) | @Override
    method mustRebuildDependents (line 37) | @Override
    method keyOf (line 42) | public static Object keyOf(Class<? extends ShareableState> stateClass) {
    method dependencyOf (line 46) | public static <T> Object dependencyOf(Class<T> stateClass, @Nullable O...
    class Proxy (line 50) | public static class Proxy<T extends ShareableState> extends InheritedP...
      method Proxy (line 55) | public Proxy(SharedStateProvider<T> widget) {
      method addDependency (line 59) | @SuppressWarnings("unchecked")
      method mustRebuildDependent (line 85) | @SuppressWarnings("unchecked")
      method notifyDependent (line 99) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/DefaultSliderHandle.java
  class DefaultSliderHandle (line 9) | public class DefaultSliderHandle extends StatelessWidget {
    method DefaultSliderHandle (line 13) | public DefaultSliderHandle(boolean active) {
    method build (line 17) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/Incrementor.java
  class Incrementor (line 21) | public class Incrementor extends StatelessWidget {
    method Incrementor (line 26) | public Incrementor(
    method Incrementor (line 36) | public Incrementor(@Nullable DoubleConsumer callback, Widget child) {
    method Incrementor (line 40) | public Incrementor(LayoutAxis axis, @Nullable DoubleConsumer callback,...
    method build (line 48) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/SliderStyle.java
  method overriding (line 15) | public SliderStyle<HandleSize> overriding(SliderStyle<HandleSize> other) {
  method getDefault (line 26) | public static <HandleSize> SliderStyle<HandleSize> getDefault() {
  type HandleBuilder (line 31) | @FunctionalInterface
    method build (line 33) | Widget build(boolean active);

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/drag/Drag.java
  class Drag (line 10) | public class Drag extends RawDrag {
    method Drag (line 12) | public Drag(
    method Drag (line 26) | public Drag(
    method min (line 35) | @Override
    method min (line 40) | @Override
    method max (line 45) | @Override
    method max (line 50) | @Override
    method range (line 55) | @Override
    method range (line 60) | @Override
    method step (line 65) | @Override
    method step (line 70) | @Override
    method dragFunction (line 75) | @Override
    method axis (line 80) | @Override
    method vertical (line 85) | @Override
    method wrap (line 90) | @Override
    method dragMultiplier (line 95) | @Override
    method incrementStep (line 100) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/drag/DragFunction.java
  type DragFunction (line 5) | public interface DragFunction {
    method deltaValue (line 7) | double deltaValue(double currentValue, @Nullable Double min, @Nullable...

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/drag/MessageDrag.java
  class MessageDrag (line 14) | public class MessageDrag extends StatelessWidget {
    method MessageDrag (line 22) | public MessageDrag(
    method MessageDrag (line 34) | public MessageDrag(
    method build (line 44) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/drag/RawDrag.java
  class RawDrag (line 17) | public class RawDrag extends StatefulWidget {
    method RawDrag (line 33) | public RawDrag(
    method min (line 45) | public RawDrag min(@Nullable Double min) {
    method min (line 51) | public RawDrag min(double min) {
    method min (line 57) | public @Nullable Double min() {
    method max (line 61) | public RawDrag max(@Nullable Double max) {
    method max (line 67) | public RawDrag max(double max) {
    method max (line 73) | public @Nullable Double max() {
    method range (line 77) | public RawDrag range(@Nullable Double min, @Nullable Double max) {
    method range (line 84) | public RawDrag range(double min, double max) {
    method step (line 91) | public RawDrag step(@Nullable Double step) {
    method step (line 97) | public RawDrag step(double step) {
    method step (line 103) | public @Nullable Double step() {
    method dragFunction (line 107) | public RawDrag dragFunction(DragFunction dragFunction) {
    method dragFunction (line 113) | public DragFunction dragFunction() {
    method axis (line 117) | public RawDrag axis(LayoutAxis axis) {
    method vertical (line 123) | public RawDrag vertical() {
    method axis (line 127) | public LayoutAxis axis() {
    method wrap (line 131) | public RawDrag wrap(boolean wrap) {
    method wrap (line 137) | public boolean wrap() {
    method dragMultiplier (line 141) | public RawDrag dragMultiplier(double dragMultiplier) {
    method dragMultiplier (line 147) | public double dragMultiplier() {
    method incrementStep (line 151) | public RawDrag incrementStep(double incrementStep) {
    method incrementStep (line 157) | public @Nullable Double incrementStep() {
    method createState (line 162) | @Override
    class State (line 167) | public static class State extends WidgetState<RawDrag> {
      method init (line 176) | @Override
      method build (line 189) | @Override
      method move (line 230) | protected void move(Constraints constraints, double deltaAlongAxis) {
      method increment (line 246) | protected void increment(Constraints constraints, double increment) {
      method applyValueBounded (line 258) | protected void applyValueBounded(double newValue) {
      method applyValueUnbounded (line 287) | protected void applyValueUnbounded(double newValue) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/range/DefaultRangeSliderStyle.java
  class DefaultRangeSliderStyle (line 9) | public class DefaultRangeSliderStyle extends InheritedWidget {
    method DefaultRangeSliderStyle (line 13) | public DefaultRangeSliderStyle(RangeSliderStyle style, Widget child) {
    method merge (line 18) | public static Widget merge(RangeSliderStyle style, Widget child) {
    method mustRebuildDependents (line 25) | @Override
    method maybeOf (line 30) | public static @Nullable RangeSliderStyle maybeOf(BuildContext context) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/range/MessageRangeSlider.java
  class MessageRangeSlider (line 13) | public class MessageRangeSlider extends StatelessWidget {
    method MessageRangeSlider (line 20) | public MessageRangeSlider(
    method MessageRangeSlider (line 34) | public MessageRangeSlider(
    method build (line 45) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/range/RangeSlider.java
  class RangeSlider (line 23) | public class RangeSlider extends StatefulWidget {
    method RangeSlider (line 38) | public RangeSlider(
    method RangeSlider (line 50) | public RangeSlider(
    method min (line 64) | public RangeSlider min(double min) {
    method min (line 70) | public double min() {
    method max (line 74) | public RangeSlider max(double max) {
    method max (line 80) | public double max() {
    method range (line 84) | public RangeSlider range(double min, double max) {
    method minRange (line 91) | public RangeSlider minRange(double minRange) {
    method minRange (line 97) | public double minRange() {
    method maxRange (line 101) | public RangeSlider maxRange(double maxRange) {
    method maxRange (line 107) | public double maxRange() {
    method clampRange (line 111) | public RangeSlider clampRange(double minRange, double maxRange) {
    method step (line 118) | public RangeSlider step(@Nullable Double step) {
    method step (line 124) | public RangeSlider step(double step) {
    method step (line 130) | public @Nullable Double step() {
    method sliderFunction (line 134) | public RangeSlider sliderFunction(SliderFunction function) {
    method sliderFunction (line 140) | public SliderFunction sliderFunction() {
    method axis (line 144) | public RangeSlider axis(LayoutAxis axis) {
    method vertical (line 150) | public RangeSlider vertical() {
    method axis (line 154) | public LayoutAxis axis() {
    method incrementStep (line 158) | public RangeSlider incrementStep(double incrementStep) {
    method incrementStep (line 164) | public @Nullable Double incrementStep() {
    method style (line 168) | public RangeSlider style(RangeSliderStyle style) {
    method style (line 174) | public @Nullable RangeSliderStyle style() {
    method createState (line 178) | @Override
    class State (line 183) | public static class State extends WidgetState<RangeSlider> {
      method init (line 198) | @Override
      method build (line 210) | @Override
      method handleAt (line 322) | protected Handle handleAt(Constraints constraints, double x, double ...
      method isInHandle (line 341) | protected boolean isInHandle(Constraints constraints, double x, doub...
      method isInRange (line 350) | protected boolean isInRange(Constraints constraints, double x, doubl...
      method nearestHandle (line 359) | protected Handle nearestHandle(Constraints constraints, double x, do...
      method normalizedValueAt (line 368) | protected double normalizedValueAt(Constraints constraints, double x...
      method setAbsolute (line 382) | protected double setAbsolute(Constraints constraints, double x, doub...
      method move (line 406) | protected void move(Constraints constraints, double dx, double dy) {
      method increment (line 440) | protected void increment(double increment) {
      method applyValue (line 463) | protected void applyValue(double newNormalizedMin, double newNormali...
      method minRangeNorm (line 481) | protected double minRangeNorm() {
      method maxRangeNorm (line 489) | protected double maxRangeNorm() {
      type Handle (line 497) | protected enum Handle {

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/range/RangeSliderCallback.java
  type RangeSliderCallback (line 3) | @FunctionalInterface
    method accept (line 5) | void accept(double newMin, double newMax);

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/range/RangeSliderStyle.java
  method overriding (line 18) | public RangeSliderStyle overriding(RangeSliderStyle other) {
  type HandleBuilder (line 33) | @FunctionalInterface
    method build (line 35) | Widget build(boolean active);

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/slider/DefaultSliderStyle.java
  class DefaultSliderStyle (line 10) | public class DefaultSliderStyle extends InheritedWidget {
    method DefaultSliderStyle (line 14) | public DefaultSliderStyle(SliderStyle<Double> style, Widget child) {
    method merge (line 19) | public static Widget merge(SliderStyle<Double> style, Widget child) {
    method mustRebuildDependents (line 26) | @Override
    method maybeOf (line 31) | public static @Nullable SliderStyle<Double> maybeOf(BuildContext conte...

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/slider/MessageSlider.java
  class MessageSlider (line 13) | public class MessageSlider extends StatelessWidget {
    method MessageSlider (line 21) | public MessageSlider(
    method MessageSlider (line 33) | public MessageSlider(
    method build (line 43) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/slider/Slider.java
  class Slider (line 26) | public class Slider extends StatefulWidget {
    method Slider (line 39) | public Slider(
    method Slider (line 49) | public Slider(
    method min (line 58) | public Slider min(double min) {
    method min (line 64) | public double min() {
    method max (line 68) | public Slider max(double max) {
    method max (line 74) | public double max() {
    method range (line 78) | public Slider range(double min, double max) {
    method step (line 85) | public Slider step(@Nullable Double step) {
    method step (line 91) | public Slider step(double step) {
    method step (line 97) | public @Nullable Double step() {
    method function (line 101) | public Slider function(SliderFunction sliderFunction) {
    method function (line 107) | public SliderFunction function() {
    method axis (line 111) | public Slider axis(LayoutAxis axis) {
    method vertical (line 117) | public Slider vertical() {
    method axis (line 121) | public LayoutAxis axis() {
    method incrementStep (line 125) | public Slider incrementStep(double incrementStep) {
    method incrementStep (line 131) | public @Nullable Double incrementStep() {
    method style (line 135) | public Slider style(SliderStyle<Double> style) {
    method style (line 141) | public @Nullable SliderStyle<Double> style() {
    method createState (line 145) | @Override
    class State (line 150) | public static class State extends WidgetState<Slider> {
      method build (line 161) | @Override
      method isInHandle (line 243) | protected boolean isInHandle(Constraints constraints, double x, doub...
      method move (line 254) | protected void move(Constraints constraints, double dx, double dy) {
      method setAbsolute (line 260) | protected double setAbsolute(Constraints constraints, double x, doub...
      method applyValue (line 270) | protected void applyValue(double newNormalizedValue) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/slider/SliderCallback.java
  type SliderCallback (line 3) | @FunctionalInterface
    method accept (line 5) | void accept(double newValue);

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/slider/SliderFunction.java
  type SliderFunction (line 7) | public interface SliderFunction {
    method normalize (line 8) | double normalize(double value, double min, double max);
    method deNormalize (line 10) | double deNormalize(double normalizedValue, double min, double max);
    method normalize (line 13) | @Override
    method deNormalize (line 18) | @Override
    method normalize (line 26) | @Override
    method deNormalize (line 45) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/xlyder/DefaultXlyderStyle.java
  class DefaultXlyderStyle (line 11) | public class DefaultXlyderStyle extends InheritedWidget {
    method DefaultXlyderStyle (line 15) | public DefaultXlyderStyle(SliderStyle<Size> style, Widget child) {
    method merge (line 20) | public static Widget merge(SliderStyle<Size> style, Widget child) {
    method mustRebuildDependents (line 27) | @Override
    method maybeOf (line 32) | public static @Nullable SliderStyle<Size> maybeOf(BuildContext context) {

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/xlyder/MessageXlyder.java
  class MessageXlyder (line 15) | public class MessageXlyder extends StatelessWidget {
    method MessageXlyder (line 23) | public MessageXlyder(
    method MessageXlyder (line 35) | public MessageXlyder(
    method MessageXlyder (line 45) | public MessageXlyder(
    method MessageXlyder (line 54) | public MessageXlyder(
    method build (line 64) | @Override
    type XlyderMessageProvider (line 80) | @FunctionalInterface
      method getMessage (line 82) | Component getMessage(double x, double y);

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/xlyder/Xlyder.java
  class Xlyder (line 29) | public class Xlyder extends StatefulWidget {
    method Xlyder (line 44) | public Xlyder(
    method Xlyder (line 54) | public Xlyder(
    method Xlyder (line 63) | public Xlyder(
    method Xlyder (line 71) | public Xlyder(
    method min (line 80) | public Xlyder min(Vector2d min) {
    method min (line 86) | public Xlyder min(double minX, double minY) {
    method min (line 92) | public Xlyder min(double min) {
    method min (line 98) | public Vector2dc min() {
    method minX (line 102) | public Xlyder minX(double minX) {
    method minX (line 108) | public double minX() {
    method minY (line 112) | public Xlyder minY(double minY) {
    method minY (line 118) | public double minY() {
    method max (line 122) | public Xlyder max(Vector2d max) {
    method max (line 128) | public Xlyder max(double maxX, double maxY) {
    method max (line 134) | public Xlyder max(double max) {
    method max (line 140) | public Vector2dc max() {
    method maxX (line 144) | public Xlyder maxX(double maxX) {
    method maxX (line 150) | public double maxX() {
    method maxY (line 154) | public Xlyder maxY(double maxY) {
    method maxY (line 160) | public double maxY() {
    method range (line 164) | public Xlyder range(Vector2d min, Vector2d max) {
    method range (line 171) | public Xlyder range(double minX, double minY, double maxX, double maxY) {
    method range (line 178) | public Xlyder range(double min, double max) {
    method rangeX (line 185) | public Xlyder rangeX(double minX, double maxX) {
    method rangeY (line 192) | public Xlyder rangeY(double minY, double maxY) {
    method step (line 199) | public Xlyder step(@Nullable Double step) {
    method step (line 206) | public Xlyder step(double step) {
    method stepX (line 213) | public Xlyder stepX(@Nullable Double xStep) {
    method stepX (line 219) | public Xlyder stepX(double xStep) {
    method stepX (line 225) | public @Nullable Double stepX() {
    method stepY (line 229) | public Xlyder stepY(@Nullable Double yStep) {
    method stepY (line 235) | public Xlyder stepY(double yStep) {
    method stepY (line 241) | public @Nullable Double stepY() {
    method sliderFunction (line 245) | public Xlyder sliderFunction(SliderFunction sliderFunction) {
    method sliderFunctionX (line 252) | public Xlyder sliderFunctionX(SliderFunction xSliderFunction) {
    method sliderFunctionX (line 258) | public SliderFunction sliderFunctionX() {
    method sliderFunctionY (line 262) | public Xlyder sliderFunctionY(SliderFunction ySliderFunction) {
    method sliderFunctionY (line 268) | public SliderFunction sliderFunctionY() {
    method incrementStep (line 272) | public Xlyder incrementStep(@Nullable Double incrementStep) {
    method incrementStep (line 279) | public Xlyder incrementStep(double incrementStep) {
    method incrementStepX (line 286) | public Xlyder incrementStepX(@Nullable Double xIncrementStep) {
    method incrementStepX (line 292) | public Xlyder incrementStepX(double xIncrementStep) {
    method incrementStepX (line 298) | public @Nullable Double incrementStepX() {
    method incrementStepY (line 302) | public Xlyder incrementStepY(@Nullable Double yIncrementStep) {
    method incrementStepY (line 308) | public Xlyder incrementStepY(double yIncrementStep) {
    method incrementStepY (line 314) | public @Nullable Double incrementStepY() {
    method style (line 318) | public Xlyder style(SliderStyle<Size> style) {
    method style (line 324) | public @Nullable SliderStyle<Size> style() {
    method createState (line 328) | @Override
    class State (line 333) | public static class State extends WidgetState<Xlyder> {
      method init (line 343) | @Override
      method build (line 356) | @Override
      method isInHandle (line 422) | protected boolean isInHandle(Constraints constraints, double x, doub...
      method move (line 434) | protected void move(Constraints constraints, double dx, double dy) {
      method setAbsolute (line 446) | protected Vector2dc setAbsolute(Constraints constraints, double x, d...
      method applyValue (line 458) | protected void applyValue(@Nullable Double newNormalizedX, @Nullable...

FILE: src/main/java/io/wispforest/owo/braid/widgets/slider/xlyder/XlyderCallback.java
  type XlyderCallback (line 3) | @FunctionalInterface
    method accept (line 5) | void accept(double newX, double newY);

FILE: src/main/java/io/wispforest/owo/braid/widgets/splitpane/MultiSplitPane.java
  class MultiSplitPane (line 26) | public class MultiSplitPane extends StatefulWidget {
    method MultiSplitPane (line 33) | public MultiSplitPane(
    method createState (line 45) | @Override
  class MultiSplitPaneState (line 51) | class MultiSplitPaneState extends WidgetState<MultiSplitPane> {
    method build (line 55) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/splitpane/SplitPane.java
  class SplitPane (line 22) | public class SplitPane extends StatefulWidget {
    method SplitPane (line 28) | public SplitPane(Widget firstChild, Widget secondChild, LayoutAxis axi...
    method createState (line 34) | @Override
  class SplitPaneState (line 40) | class SplitPaneState extends WidgetState<SplitPane> {
    method build (line 44) | @Override

FILE: src/main/java/io/wispforest/owo/braid/widgets/stack/Stack.java
  class Stack (line 16) | public class Stack extends MultiChildInstanceWidget {
    method Stack (line 20) | public Stack(Alignment alignment, List<? extends Widget> children) {
    method Stack (line 25) | public Stack(List<? extends Widget> children) {
    method Stack (line 29) | public Stack(Alignment alignment, Widget... children) {
    method Stack (line 33) | public Stack(Widget... children) {
    method instantiate (line 37) | @Override
    class Insta
Condensed preview — 813 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,761K chars).
[
  {
    "path": ".github/workflows/build.yml",
    "chars": 1284,
    "preview": "# Automatically build the project and run any configured tests for every push\n# and submitted pull request. This can hel"
  },
  {
    "path": ".gitignore",
    "chars": 1676,
    "preview": "# User-specific stuff\n.idea/\n\n*.iml\n*.ipr\n*.iws\n\n# IntelliJ\nout/\n# mpeltonen/sbt-idea plugin\n.idea_modules/\n\n# JIRA plug"
  },
  {
    "path": "LICENSE",
    "chars": 1067,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2021 \n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "README.md",
    "chars": 4356,
    "preview": "<h1 align=\"center\">\n    <img src=\"https://i.imgur.com/VXjFso4.png\">\n    <br>\n    oωo (owo-lib)\n    <br>\n    <a href=\"htt"
  },
  {
    "path": "braid-reload-agent/.gitattributes",
    "chars": 214,
    "preview": "#\n# https://help.github.com/articles/dealing-with-line-endings/\n#\n# Linux start script should use lf\n/gradlew        tex"
  },
  {
    "path": "braid-reload-agent/.gitignore",
    "chars": 103,
    "preview": "# Ignore Gradle project-specific cache directory\n.gradle\n\n# Ignore Gradle build output directory\nbuild\n"
  },
  {
    "path": "braid-reload-agent/build.gradle.kts",
    "chars": 804,
    "preview": "plugins {\n    application\n    `maven-publish`\n}\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {}\n\nversion = \"0.1.0\""
  },
  {
    "path": "braid-reload-agent/gradle/libs.versions.toml",
    "chars": 376,
    "preview": "# This file was generated by the Gradle 'init' task.\n# https://docs.gradle.org/current/userguide/platforms.html#sub::tom"
  },
  {
    "path": "braid-reload-agent/gradle/wrapper/gradle-wrapper.properties",
    "chars": 250,
    "preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
  },
  {
    "path": "braid-reload-agent/gradlew",
    "chars": 8683,
    "preview": "#!/bin/sh\n\n#\n# Copyright © 2015-2021 the original authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Lice"
  },
  {
    "path": "braid-reload-agent/gradlew.bat",
    "chars": 2918,
    "preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
  },
  {
    "path": "braid-reload-agent/settings.gradle.kts",
    "chars": 163,
    "preview": "plugins {\n    // Apply the foojay-resolver plugin to allow automatic download of JDKs\n    id(\"org.gradle.toolchains.fooj"
  },
  {
    "path": "braid-reload-agent/src/main/java/io/wispforest/BraidReloadAgent.java",
    "chars": 3623,
    "preview": "package io.wispforest;\n\nimport java.lang.instrument.ClassFileTransformer;\nimport java.lang.instrument.IllegalClassFormat"
  },
  {
    "path": "build.gradle",
    "chars": 5163,
    "preview": "//file:noinspection GradlePackageVersionRange\nplugins {\n    id 'net.fabricmc.fabric-loom-remap' version '1.15-SNAPSHOT'\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 202,
    "preview": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributi"
  },
  {
    "path": "gradle.properties",
    "chars": 907,
    "preview": "# Done to increase the memory available to gradle.\norg.gradle.jvmargs=-Xmx2G\n# Fabric Properties\n# check these on https:"
  },
  {
    "path": "gradlew",
    "chars": 5770,
    "preview": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0"
  },
  {
    "path": "gradlew.bat",
    "chars": 2954,
    "preview": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \""
  },
  {
    "path": "jitpack.yml",
    "chars": 18,
    "preview": "jdk:\n  - openjdk21"
  },
  {
    "path": "owo-sentinel/build.gradle",
    "chars": 147,
    "preview": "loom {\n    runConfigs.client.ideConfigGenerated = true\n\n    mods {\n        \"owo-sentinel\" {\n            sourceSet source"
  },
  {
    "path": "owo-sentinel/gradle.properties",
    "chars": 32,
    "preview": "archives_base_name=owo-sentinel\n"
  },
  {
    "path": "owo-sentinel/src/main/java/io/wispforest/owosentinel/DownloadTask.java",
    "chars": 747,
    "preview": "package io.wispforest.owosentinel;\n\nimport javax.swing.*;\nimport java.util.function.Consumer;\n\npublic class DownloadTask"
  },
  {
    "path": "owo-sentinel/src/main/java/io/wispforest/owosentinel/Maldenhagen.java",
    "chars": 380,
    "preview": "package io.wispforest.owosentinel;\n\nimport net.fabricmc.loader.api.LanguageAdapter;\nimport net.fabricmc.loader.api.ModCo"
  },
  {
    "path": "owo-sentinel/src/main/java/io/wispforest/owosentinel/OwoSentinel.java",
    "chars": 4611,
    "preview": "package io.wispforest.owosentinel;\n\nimport com.google.gson.Gson;\nimport com.google.gson.JsonArray;\nimport com.google.gso"
  },
  {
    "path": "owo-sentinel/src/main/java/io/wispforest/owosentinel/SentinelConsole.java",
    "chars": 1034,
    "preview": "package io.wispforest.owosentinel;\n\nimport java.util.Locale;\nimport java.util.Scanner;\n\npublic class SentinelConsole {\n "
  },
  {
    "path": "owo-sentinel/src/main/java/io/wispforest/owosentinel/SentinelWindow.java",
    "chars": 5416,
    "preview": "package io.wispforest.owosentinel;\n\nimport javax.imageio.ImageIO;\nimport javax.swing.*;\nimport javax.swing.border.EmptyB"
  },
  {
    "path": "owo-sentinel/src/main/resources/fabric.mod.json",
    "chars": 646,
    "preview": "{\n  \"schemaVersion\": 1,\n  \"id\": \"owo-sentinel\",\n  \"version\": \"${version}\",\n  \"name\": \"oωo-sentinel\",\n  \"description\": \"m"
  },
  {
    "path": "owo-ui.xsd",
    "chars": 38070,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n           xmlns:vc=\"http:"
  },
  {
    "path": "settings.gradle",
    "chars": 200,
    "preview": "pluginManagement {\n    repositories {\n        maven {\n            name = 'Fabric'\n            url = 'https://maven.fabri"
  },
  {
    "path": "src/main/java/io/wispforest/owo/Owo.java",
    "chars": 3391,
    "preview": "package io.wispforest.owo;\n\nimport io.wispforest.owo.client.screens.MenuNetworkingInternals;\nimport io.wispforest.owo.co"
  },
  {
    "path": "src/main/java/io/wispforest/owo/blockentity/LinearProcess.java",
    "chars": 9217,
    "preview": "package io.wispforest.owo.blockentity;\n\nimport it.unimi.dsi.fastutil.ints.Int2ObjectMap;\nimport it.unimi.dsi.fastutil.in"
  },
  {
    "path": "src/main/java/io/wispforest/owo/blockentity/LinearProcessExecutor.java",
    "chars": 6070,
    "preview": "package io.wispforest.owo.blockentity;\n\nimport it.unimi.dsi.fastutil.ints.Int2ObjectMap;\nimport net.minecraft.nbt.Compou"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/animation/AlignmentLerp.java",
    "chars": 512,
    "preview": "package io.wispforest.owo.braid.animation;\n\nimport io.wispforest.owo.braid.core.Alignment;\nimport net.minecraft.util.Mth"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/animation/Animation.java",
    "chars": 3395,
    "preview": "package io.wispforest.owo.braid.animation;\n\nimport io.wispforest.owo.braid.framework.proxy.ProxyHost;\nimport net.minecra"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/animation/AutomaticallyAnimatedWidget.java",
    "chars": 3519,
    "preview": "package io.wispforest.owo.braid.animation;\n\nimport io.wispforest.owo.braid.framework.proxy.WidgetState;\nimport io.wispfo"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/animation/ColorLerp.java",
    "chars": 323,
    "preview": "package io.wispforest.owo.braid.animation;\n\nimport io.wispforest.owo.braid.core.Color;\n\npublic class ColorLerp extends L"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/animation/DoubleLerp.java",
    "chars": 316,
    "preview": "package io.wispforest.owo.braid.animation;\n\nimport net.minecraft.util.Mth;\n\npublic class DoubleLerp extends Lerp<Double>"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/animation/Easing.java",
    "chars": 3266,
    "preview": "package io.wispforest.owo.braid.animation;\n\npublic class Easing {\n\n    public static final Easing LINEAR = new Easing(x "
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/animation/InsetsLerp.java",
    "chars": 594,
    "preview": "package io.wispforest.owo.braid.animation;\n\nimport io.wispforest.owo.braid.core.Insets;\nimport net.minecraft.util.Mth;\n\n"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/animation/Lerp.java",
    "chars": 619,
    "preview": "package io.wispforest.owo.braid.animation;\n\npublic abstract class Lerp<T> {\n\n    public final T start;\n    public final "
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/animation/NullableLerp.java",
    "chars": 597,
    "preview": "package io.wispforest.owo.braid.animation;\n\nimport org.jetbrains.annotations.Nullable;\n\npublic class NullableLerp<T> ext"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/Aabb2d.java",
    "chars": 1598,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport org.joml.Matrix3x2f;\nimport org.joml.Vector2f;\n\npublic class Aabb2d {\n\n   "
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/Alignment.java",
    "chars": 1211,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport org.jetbrains.annotations.ApiStatus;\n\npublic record Alignment(double horiz"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/AppState.java",
    "chars": 24148,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport com.google.common.collect.Iterables;\nimport com.mojang.blaze3d.opengl.GlSt"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/BraidGraphics.java",
    "chars": 3755,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport com.mojang.blaze3d.pipeline.RenderPipeline;\nimport io.wispforest.owo.braid"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/BraidHotReloadCallback.java",
    "chars": 1803,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport org.jetbrains.annotations.ApiStatus;\nimport org.jetbrains.annotations.Null"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/BraidRenderPipelines.java",
    "chars": 1091,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport com.mojang.blaze3d.pipeline.RenderPipeline;\nimport io.wispforest.owo.Owo;\n"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/BraidScreen.java",
    "chars": 4318,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport io.wispforest.owo.braid.core.events.*;\nimport io.wispforest.owo.braid.fram"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/BraidUtils.java",
    "chars": 350,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport java.util.function.BiFunction;\n\npublic class BraidUtils {\n    public stati"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/BraidWindow.java",
    "chars": 12225,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport com.mojang.blaze3d.opengl.GlDebug;\nimport com.mojang.blaze3d.opengl.GlText"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/BraidWindowScheduler.java",
    "chars": 1310,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport io.wispforest.owo.ui.event.ClientRenderCallback;\nimport net.fabricmc.fabri"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/Color.java",
    "chars": 4157,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport net.minecraft.ChatFormatting;\nimport net.minecraft.util.Mth;\n\npublic class"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/CompoundListenable.java",
    "chars": 866,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class CompoundListenab"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/Constraints.java",
    "chars": 5754,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport net.minecraft.util.Mth;\nimport org.jetbrains.annotations.ApiStatus;\nimport"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/EventBinding.java",
    "chars": 2311,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport com.mojang.blaze3d.platform.InputConstants;\nimport io.wispforest.owo.braid"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/Insets.java",
    "chars": 2011,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport org.jetbrains.annotations.ApiStatus;\n\npublic record Insets(double top, dou"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/KeyModifiers.java",
    "chars": 1315,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport it.unimi.dsi.fastutil.ints.IntList;\n\nimport static org.lwjgl.glfw.GLFW.*;\n"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/LayoutAxis.java",
    "chars": 937,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport java.util.function.Supplier;\n\npublic enum LayoutAxis {\n    HORIZONTAL,\n   "
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/Listenable.java",
    "chars": 482,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic abstract class Listena"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/ListenableValue.java",
    "chars": 349,
    "preview": "package io.wispforest.owo.braid.core;\n\npublic class ListenableValue<V> extends Listenable {\n\n    private V value;\n\n    p"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/RelativePosition.java",
    "chars": 963,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport com.google.common.base.Preconditions;\nimport io.wispforest.owo.Owo;\nimport"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/Size.java",
    "chars": 1746,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport net.minecraft.util.Mth;\nimport org.jetbrains.annotations.ApiStatus;\nimport"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/Surface.java",
    "chars": 2733,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport com.mojang.blaze3d.platform.Window;\nimport io.wispforest.owo.braid.core.cu"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/TextLayout.java",
    "chars": 1846,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport net.minecraft.client.gui.Font;\nimport net.minecraft.network.chat.Component"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/TextureSurface.java",
    "chars": 3498,
    "preview": "package io.wispforest.owo.braid.core;\n\nimport com.mojang.blaze3d.pipeline.TextureTarget;\nimport com.mojang.blaze3d.syste"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/cursor/CursorController.java",
    "chars": 1265,
    "preview": "package io.wispforest.owo.braid.core.cursor;\n\nimport org.lwjgl.glfw.GLFW;\n\nimport java.util.HashMap;\nimport java.util.Ma"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/cursor/CursorStyle.java",
    "chars": 1900,
    "preview": "package io.wispforest.owo.braid.core.cursor;\n\nimport io.wispforest.owo.braid.core.LayoutAxis;\nimport net.minecraft.util."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/cursor/SystemCursorStyle.java",
    "chars": 350,
    "preview": "package io.wispforest.owo.braid.core.cursor;\n\nimport org.lwjgl.glfw.GLFW;\n\npublic final class SystemCursorStyle implemen"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/element/BraidBlockElement.java",
    "chars": 3708,
    "preview": "package io.wispforest.owo.braid.core.element;\n\nimport com.mojang.blaze3d.platform.Lighting;\nimport com.mojang.blaze3d.ve"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/element/BraidDashedLineElement.java",
    "chars": 2440,
    "preview": "package io.wispforest.owo.braid.core.element;\n\nimport com.mojang.blaze3d.pipeline.RenderPipeline;\nimport com.mojang.blaz"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/element/BraidEntityElement.java",
    "chars": 3200,
    "preview": "package io.wispforest.owo.braid.core.element;\n\nimport com.mojang.blaze3d.platform.Lighting;\nimport com.mojang.blaze3d.ve"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/element/BraidItemElement.java",
    "chars": 3234,
    "preview": "package io.wispforest.owo.braid.core.element;\n\nimport com.mojang.blaze3d.platform.Lighting;\nimport com.mojang.blaze3d.ve"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/events/CharInputEvent.java",
    "chars": 310,
    "preview": "package io.wispforest.owo.braid.core.events;\n\nimport io.wispforest.owo.braid.core.KeyModifiers;\n\npublic record CharInput"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/events/CloseEvent.java",
    "chars": 108,
    "preview": "package io.wispforest.owo.braid.core.events;\n\npublic enum CloseEvent implements UserEvent {\n    INSTANCE;\n}\n"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/events/FilesDroppedEvent.java",
    "chars": 171,
    "preview": "package io.wispforest.owo.braid.core.events;\n\nimport java.nio.file.Path;\nimport java.util.List;\n\npublic record FilesDrop"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/events/KeyPressEvent.java",
    "chars": 338,
    "preview": "package io.wispforest.owo.braid.core.events;\n\nimport io.wispforest.owo.braid.core.KeyModifiers;\n\npublic record KeyPressE"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/events/KeyReleaseEvent.java",
    "chars": 342,
    "preview": "package io.wispforest.owo.braid.core.events;\n\nimport io.wispforest.owo.braid.core.KeyModifiers;\n\npublic record KeyReleas"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/events/MouseButtonPressEvent.java",
    "chars": 313,
    "preview": "package io.wispforest.owo.braid.core.events;\n\nimport io.wispforest.owo.braid.core.KeyModifiers;\n\npublic record MouseButt"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/events/MouseButtonReleaseEvent.java",
    "chars": 317,
    "preview": "package io.wispforest.owo.braid.core.events;\n\nimport io.wispforest.owo.braid.core.KeyModifiers;\n\npublic record MouseButt"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/events/MouseMoveEvent.java",
    "chars": 119,
    "preview": "package io.wispforest.owo.braid.core.events;\n\npublic record MouseMoveEvent(double x, double y) implements UserEvent {}\n"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/events/MouseScrollEvent.java",
    "chars": 133,
    "preview": "package io.wispforest.owo.braid.core.events;\n\npublic record MouseScrollEvent(double xOffset, double yOffset) implements "
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/core/events/UserEvent.java",
    "chars": 287,
    "preview": "package io.wispforest.owo.braid.core.events;\n\npublic sealed interface UserEvent permits\n    CloseEvent,\n    CharInputEve"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/display/BraidDisplay.java",
    "chars": 3585,
    "preview": "package io.wispforest.owo.braid.display;\n\nimport com.mojang.blaze3d.pipeline.BlendFunction;\nimport com.mojang.blaze3d.pi"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/display/BraidDisplayBinding.java",
    "chars": 2638,
    "preview": "package io.wispforest.owo.braid.display;\n\nimport com.mojang.blaze3d.vertex.PoseStack;\nimport io.wispforest.owo.braid.cor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/display/DisplayQuad.java",
    "chars": 1393,
    "preview": "package io.wispforest.owo.braid.display;\n\nimport net.minecraft.world.phys.Vec3;\nimport org.jetbrains.annotations.Nullabl"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/BuildContext.java",
    "chars": 1094,
    "preview": "package io.wispforest.owo.braid.framework;\n\nimport io.wispforest.owo.braid.framework.instance.WidgetInstance;\nimport org"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/CustomWidgetTransform.java",
    "chars": 2555,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\nimport org.jetbrains.annotations.Nullable;\nimport org.joml.*;\n\npubl"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/Hit.java",
    "chars": 122,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\npublic record Hit(WidgetInstance<?> instance, double x, double y) {"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/HitTestState.java",
    "chars": 1825,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\nimport com.google.common.collect.FluentIterable;\nimport org.jetbrai"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/InspectorProperty.java",
    "chars": 167,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\nimport net.minecraft.network.chat.Component;\n\npublic record Inspect"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/InstanceHost.java",
    "chars": 1051,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\nimport io.wispforest.owo.braid.widgets.basic.LayoutBuilder;\nimport "
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/LeafWidgetInstance.java",
    "chars": 352,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\nimport io.wispforest.owo.braid.framework.widget.InstanceWidget;\n\npu"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/MouseListener.java",
    "chars": 1001,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\nimport io.wispforest.owo.braid.core.KeyModifiers;\nimport io.wispfor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/MultiChildWidgetInstance.java",
    "chars": 2006,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\nimport io.wispforest.owo.braid.core.BraidGraphics;\nimport io.wispfo"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/OptionalChildWidgetInstance.java",
    "chars": 2142,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\nimport com.google.common.base.Preconditions;\nimport io.wispforest.o"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/SingleChildWidgetInstance.java",
    "chars": 1881,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\nimport com.google.common.base.Preconditions;\nimport io.wispforest.o"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/TooltipProvider.java",
    "chars": 461,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\nimport net.minecraft.client.gui.screens.inventory.tooltip.ClientToo"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/WidgetInstance.java",
    "chars": 10691,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\nimport com.google.common.base.Preconditions;\nimport io.wispforest.o"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/instance/WidgetTransform.java",
    "chars": 3270,
    "preview": "package io.wispforest.owo.braid.framework.instance;\n\nimport io.wispforest.owo.Owo;\nimport io.wispforest.owo.braid.core.L"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/BuildScope.java",
    "chars": 2114,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport io.wispforest.owo.Owo;\nimport org.jetbrains.annotations.Nullabl"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/ComposedProxy.java",
    "chars": 944,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport io.wispforest.owo.braid.framework.instance.WidgetInstance;\nimpo"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/InheritedProxy.java",
    "chars": 1963,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport io.wispforest.owo.braid.framework.widget.InheritedWidget;\nimpor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/InstanceWidgetProxy.java",
    "chars": 2150,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport com.google.common.base.Preconditions;\nimport io.wispforest.owo."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/LeafInstanceWidgetProxy.java",
    "chars": 715,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport com.google.common.base.Preconditions;\nimport io.wispforest.owo."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/MultiChildInstanceWidgetProxy.java",
    "chars": 6650,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport com.google.common.base.Preconditions;\nimport io.wispforest.owo."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/OptionalChildInstanceWidgetProxy.java",
    "chars": 1639,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport io.wispforest.owo.braid.framework.instance.OptionalChildWidgetI"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/ProxyHost.java",
    "chars": 483,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport net.minecraft.client.Minecraft;\n\nimport java.time.Duration;\n\npu"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/SingleChildInstanceWidgetProxy.java",
    "chars": 1482,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport io.wispforest.owo.braid.framework.instance.SingleChildWidgetIns"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/StatefulProxy.java",
    "chars": 1790,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport io.wispforest.owo.braid.framework.widget.StatefulWidget;\nimport"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/StatelessProxy.java",
    "chars": 863,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport io.wispforest.owo.braid.framework.widget.StatelessWidget;\nimpor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/WidgetProxy.java",
    "chars": 7437,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport com.google.common.base.Preconditions;\nimport io.wispforest.owo."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/proxy/WidgetState.java",
    "chars": 1896,
    "preview": "package io.wispforest.owo.braid.framework.proxy;\n\nimport com.google.common.base.Preconditions;\nimport io.wispforest.owo."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/widget/InheritedWidget.java",
    "chars": 604,
    "preview": "package io.wispforest.owo.braid.framework.widget;\n\nimport io.wispforest.owo.braid.framework.proxy.InheritedProxy;\nimport"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/widget/InstanceWidget.java",
    "chars": 227,
    "preview": "package io.wispforest.owo.braid.framework.widget;\n\nimport io.wispforest.owo.braid.framework.instance.WidgetInstance;\n\npu"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/widget/Key.java",
    "chars": 722,
    "preview": "package io.wispforest.owo.braid.framework.widget;\n\nimport com.google.common.base.Preconditions;\nimport org.jetbrains.ann"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/widget/LeafInstanceWidget.java",
    "chars": 498,
    "preview": "package io.wispforest.owo.braid.framework.widget;\n\nimport io.wispforest.owo.braid.framework.instance.LeafWidgetInstance;"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/widget/MultiChildInstanceWidget.java",
    "chars": 717,
    "preview": "package io.wispforest.owo.braid.framework.widget;\n\nimport io.wispforest.owo.braid.framework.instance.MultiChildWidgetIns"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/widget/OptionalChildInstanceWidget.java",
    "chars": 727,
    "preview": "package io.wispforest.owo.braid.framework.widget;\n\nimport io.wispforest.owo.braid.framework.instance.OptionalChildWidget"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/widget/SingleChildInstanceWidget.java",
    "chars": 656,
    "preview": "package io.wispforest.owo.braid.framework.widget;\n\nimport io.wispforest.owo.braid.framework.instance.SingleChildWidgetIn"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/widget/StatefulWidget.java",
    "chars": 434,
    "preview": "package io.wispforest.owo.braid.framework.widget;\n\nimport io.wispforest.owo.braid.framework.proxy.StatefulProxy;\nimport "
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/widget/StatelessWidget.java",
    "chars": 439,
    "preview": "package io.wispforest.owo.braid.framework.widget;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wisp"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/widget/Widget.java",
    "chars": 1439,
    "preview": "package io.wispforest.owo.braid.framework.widget;\n\nimport io.wispforest.owo.braid.framework.proxy.WidgetProxy;\nimport or"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/framework/widget/WidgetSetupCallback.java",
    "chars": 524,
    "preview": "package io.wispforest.owo.braid.framework.widget;\n\npublic interface WidgetSetupCallback<T extends Widget> {\n    void set"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/BraidGuiRenderer.java",
    "chars": 2827,
    "preview": "package io.wispforest.owo.braid.util;\n\nimport com.mojang.blaze3d.buffers.GpuBufferSlice;\nimport com.mojang.blaze3d.pipel"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/BraidHudElement.java",
    "chars": 1971,
    "preview": "package io.wispforest.owo.braid.util;\n\nimport io.wispforest.owo.Owo;\nimport io.wispforest.owo.braid.core.AppState;\nimpor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/BraidToast.java",
    "chars": 3994,
    "preview": "package io.wispforest.owo.braid.util;\n\nimport com.google.common.base.Preconditions;\nimport io.wispforest.owo.Owo;\nimport"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/BraidTooltipComponent.java",
    "chars": 2262,
    "preview": "package io.wispforest.owo.braid.util;\n\nimport io.wispforest.owo.Owo;\nimport io.wispforest.owo.braid.core.Alignment;\nimpo"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/EmbedderRoot.java",
    "chars": 938,
    "preview": "package io.wispforest.owo.braid.util;\n\nimport io.wispforest.owo.braid.framework.instance.SingleChildWidgetInstance;\nimpo"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/kdl/BraidKdlEndecs.java",
    "chars": 6596,
    "preview": "package io.wispforest.owo.braid.util.kdl;\n\nimport com.mojang.brigadier.StringReader;\nimport com.mojang.brigadier.excepti"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/kdl/KdlDeserializer.java",
    "chars": 8733,
    "preview": "package io.wispforest.owo.braid.util.kdl;\n\nimport dev.kdl.KdlNode;\nimport dev.kdl.KdlValue;\nimport io.wispforest.endec.*"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/kdl/KdlElement.java",
    "chars": 370,
    "preview": "package io.wispforest.owo.braid.util.kdl;\n\nimport dev.kdl.KdlNode;\nimport dev.kdl.KdlValue;\n\nimport java.util.List;\n\npub"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/kdl/KdlEntityWidget.java",
    "chars": 4103,
    "preview": "package io.wispforest.owo.braid.util.kdl;\n\nimport com.mojang.brigadier.StringReader;\nimport com.mojang.brigadier.excepti"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/kdl/KdlMapper.java",
    "chars": 2879,
    "preview": "package io.wispforest.owo.braid.util.kdl;\n\nimport dev.kdl.KdlNode;\nimport dev.kdl.KdlString;\n\nimport java.util.List;\nimp"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/kdl/WidgetEndec.java",
    "chars": 17813,
    "preview": "package io.wispforest.owo.braid.util.kdl;\n\nimport io.wispforest.endec.Endec;\nimport io.wispforest.endec.SelfDescribedDes"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/layers/AnchorJustification.java",
    "chars": 2820,
    "preview": "package io.wispforest.owo.braid.util.layers;\n\npublic record AnchorJustification(double anchorX, double anchorY, double w"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/layers/BraidLayersBinding.java",
    "chars": 6593,
    "preview": "package io.wispforest.owo.braid.util.layers;\n\nimport com.google.common.base.Suppliers;\nimport com.mojang.blaze3d.platfor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/layers/Justify.java",
    "chars": 1346,
    "preview": "package io.wispforest.owo.braid.util.layers;\n\nimport io.wispforest.owo.braid.core.Constraints;\nimport io.wispforest.owo."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/layers/LayerAlignment.java",
    "chars": 5064,
    "preview": "package io.wispforest.owo.braid.util.layers;\n\nimport io.wispforest.owo.braid.core.RelativePosition;\nimport io.wispforest"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/util/layers/LayerContext.java",
    "chars": 3956,
    "preview": "package io.wispforest.owo.braid.util.layers;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wispfores"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/BraidApp.java",
    "chars": 7537,
    "preview": "package io.wispforest.owo.braid.widgets;\n\nimport com.google.common.collect.ImmutableMap;\nimport io.wispforest.owo.braid."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/BraidLogo.java",
    "chars": 856,
    "preview": "package io.wispforest.owo.braid.widgets;\n\nimport io.wispforest.owo.Owo;\nimport io.wispforest.owo.braid.core.Color;\nimpor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/Dialog.java",
    "chars": 2005,
    "preview": "package io.wispforest.owo.braid.widgets;\n\nimport io.wispforest.owo.braid.core.Color;\nimport io.wispforest.owo.braid.fram"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/HoverStyledLabel.java",
    "chars": 1445,
    "preview": "package io.wispforest.owo.braid.widgets;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wispforest.ow"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/Marquee.java",
    "chars": 6628,
    "preview": "package io.wispforest.owo.braid.widgets;\n\nimport io.wispforest.owo.braid.animation.Animation;\nimport io.wispforest.owo.b"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/Navigator.java",
    "chars": 2712,
    "preview": "package io.wispforest.owo.braid.widgets;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wispforest.ow"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/SpriteWidget.java",
    "chars": 3258,
    "preview": "package io.wispforest.owo.braid.widgets;\n\nimport io.wispforest.owo.braid.core.BraidGraphics;\nimport io.wispforest.owo.br"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/animated/AnimatedAlign.java",
    "chars": 1421,
    "preview": "package io.wispforest.owo.braid.widgets.animated;\n\nimport io.wispforest.owo.braid.animation.AlignmentLerp;\nimport io.wis"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/animated/AnimatedBox.java",
    "chars": 1811,
    "preview": "package io.wispforest.owo.braid.widgets.animated;\n\nimport io.wispforest.owo.braid.animation.AutomaticallyAnimatedWidget;"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/animated/AnimatedPadding.java",
    "chars": 1448,
    "preview": "package io.wispforest.owo.braid.widgets.animated;\n\nimport io.wispforest.owo.braid.animation.AutomaticallyAnimatedWidget;"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/animated/AnimatedSized.java",
    "chars": 1759,
    "preview": "package io.wispforest.owo.braid.widgets.animated;\n\nimport io.wispforest.owo.braid.animation.AutomaticallyAnimatedWidget;"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Align.java",
    "chars": 3516,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Alignment;\nimport io.wispforest.owo."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/AspectRatio.java",
    "chars": 3262,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Constraints;\nimport io.wispforest.ow"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Blur.java",
    "chars": 1818,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.BraidGraphics;\nimport io.wispforest."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Box.java",
    "chars": 1663,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.BraidGraphics;\nimport io.wispforest."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Builder.java",
    "chars": 623,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wispfor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Center.java",
    "chars": 475,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Alignment;\nimport io.wispforest.owo."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Clip.java",
    "chars": 1934,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.BraidGraphics;\nimport io.wispforest."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Constrain.java",
    "chars": 476,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Constraints;\nimport io.wispforest.ow"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/ConstraintWidget.java",
    "chars": 1973,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Constraints;\nimport io.wispforest.ow"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/ControlsOverride.java",
    "chars": 1147,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wispfor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/CustomDraw.java",
    "chars": 1679,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.BraidGraphics;\nimport io.wispforest."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/EmptyWidget.java",
    "chars": 531,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Insets;\nimport io.wispforest.owo.bra"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/HitTestTrap.java",
    "chars": 859,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.framework.instance.WidgetInstance;\nimport"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/HoverableBuilder.java",
    "chars": 1976,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wispfor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/IntrinsicHeight.java",
    "chars": 1680,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Constraints;\nimport io.wispforest.ow"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/IntrinsicWidth.java",
    "chars": 1678,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Constraints;\nimport io.wispforest.ow"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/LayoutBuilder.java",
    "chars": 3049,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Constraints;\nimport io.wispforest.ow"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/ListenableBuilder.java",
    "chars": 2358,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Listenable;\nimport io.wispforest.owo"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/MouseArea.java",
    "chars": 8118,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.KeyModifiers;\nimport io.wispforest.o"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Padding.java",
    "chars": 3114,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Constraints;\nimport io.wispforest.ow"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Panel.java",
    "chars": 1697,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.Owo;\nimport io.wispforest.owo.braid.core.BraidG"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/RotatedLayout.java",
    "chars": 3384,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Constraints;\nimport io.wispforest.ow"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Sized.java",
    "chars": 1094,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.Constraints;\nimport io.wispforest.ow"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/TextureWidget.java",
    "chars": 5719,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.*;\nimport io.wispforest.owo.braid.fr"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Tooltip.java",
    "chars": 2636,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.framework.instance.InstanceHost;\nimport i"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Transform.java",
    "chars": 1561,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.framework.instance.CustomWidgetTransform;"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/Visibility.java",
    "chars": 2812,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.core.BraidGraphics;\nimport io.wispforest."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/basic/VisitorWidget.java",
    "chars": 1939,
    "preview": "package io.wispforest.owo.braid.widgets.basic;\n\nimport io.wispforest.owo.braid.framework.instance.WidgetInstance;\nimport"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/button/Button.java",
    "chars": 2738,
    "preview": "package io.wispforest.owo.braid.widgets.button;\n\nimport io.wispforest.owo.braid.core.Insets;\nimport io.wispforest.owo.br"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/button/ButtonPanel.java",
    "chars": 1256,
    "preview": "package io.wispforest.owo.braid.widgets.button;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wispfo"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/button/ButtonStyle.java",
    "chars": 881,
    "preview": "package io.wispforest.owo.braid.widgets.button;\n\nimport io.wispforest.owo.braid.core.Insets;\nimport io.wispforest.owo.br"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/button/Clickable.java",
    "chars": 2163,
    "preview": "package io.wispforest.owo.braid.widgets.button;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wispfo"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/button/DefaultButtonStyle.java",
    "chars": 1280,
    "preview": "package io.wispforest.owo.braid.widgets.button;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wispfo"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/button/MessageButton.java",
    "chars": 1439,
    "preview": "package io.wispforest.owo.braid.widgets.button;\n\nimport io.wispforest.owo.braid.core.Color;\nimport io.wispforest.owo.bra"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/checkbox/Checkbox.java",
    "chars": 3744,
    "preview": "package io.wispforest.owo.braid.widgets.checkbox;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wisp"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/checkbox/CheckboxStyle.java",
    "chars": 2142,
    "preview": "package io.wispforest.owo.braid.widgets.checkbox;\n\nimport io.wispforest.owo.Owo;\nimport io.wispforest.owo.braid.framewor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/checkbox/DefaultCheckboxStyle.java",
    "chars": 1302,
    "preview": "package io.wispforest.owo.braid.widgets.checkbox;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wisp"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/checkbox/TogglingClickable.java",
    "chars": 1783,
    "preview": "package io.wispforest.owo.braid.widgets.checkbox;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wisp"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/collapsible/Collapsible.java",
    "chars": 3865,
    "preview": "package io.wispforest.owo.braid.widgets.collapsible;\n\nimport io.wispforest.owo.Owo;\nimport io.wispforest.owo.braid.core."
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/collapsible/CollapsibleCallback.java",
    "chars": 158,
    "preview": "package io.wispforest.owo.braid.widgets.collapsible;\n\n@FunctionalInterface\npublic interface CollapsibleCallback {\n    vo"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/collapsible/LazyCollapsible.java",
    "chars": 1695,
    "preview": "package io.wispforest.owo.braid.widgets.collapsible;\n\nimport io.wispforest.owo.braid.core.Insets;\nimport io.wispforest.o"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/combobox/ComboBox.java",
    "chars": 11070,
    "preview": "package io.wispforest.owo.braid.widgets.combobox;\n\nimport io.wispforest.owo.Owo;\nimport io.wispforest.owo.braid.core.Ins"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/combobox/ComboBoxButtons.java",
    "chars": 6171,
    "preview": "package io.wispforest.owo.braid.widgets.combobox;\n\nimport io.wispforest.owo.braid.core.*;\nimport io.wispforest.owo.braid"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/combobox/ComboBoxButtonsState.java",
    "chars": 190,
    "preview": "package io.wispforest.owo.braid.widgets.combobox;\n\nimport java.util.List;\nimport java.util.OptionalInt;\n\nrecord ComboBox"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/cycle/Cycler.java",
    "chars": 3158,
    "preview": "package io.wispforest.owo.braid.widgets.cycle;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wispfor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/cycle/CyclingButton.java",
    "chars": 4152,
    "preview": "package io.wispforest.owo.braid.widgets.cycle;\n\nimport io.wispforest.owo.braid.framework.BuildContext;\nimport io.wispfor"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/cycle/CyclingClickable.java",
    "chars": 3026,
    "preview": "package io.wispforest.owo.braid.widgets.cycle;\n\nimport io.wispforest.owo.braid.core.cursor.CursorStyle;\nimport io.wispfo"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/cycle/MessageCyclingButton.java",
    "chars": 3873,
    "preview": "package io.wispforest.owo.braid.widgets.cycle;\n\nimport io.wispforest.owo.braid.core.Color;\nimport io.wispforest.owo.brai"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/drag/DragArena.java",
    "chars": 660,
    "preview": "package io.wispforest.owo.braid.widgets.drag;\n\nimport io.wispforest.owo.braid.framework.instance.MultiChildWidgetInstanc"
  },
  {
    "path": "src/main/java/io/wispforest/owo/braid/widgets/drag/DragArenaElement.java",
    "chars": 835,
    "preview": "package io.wispforest.owo.braid.widgets.drag;\n\nimport io.wispforest.owo.braid.framework.widget.Widget;\nimport io.wispfor"
  }
]

// ... and 613 more files (download for full content)

About this extraction

This page contains the full source code of the wisp-forest/owo-lib GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 813 files (2.5 MB), approximately 701.0k tokens, and a symbol index with 5999 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!