# Auto-generated by nodebpy.assets.generate_asset_api — do not edit manually.
from typing import TYPE_CHECKING, Literal
from ...builder import (
    AssetGeometryGroup,
    BooleanSocket,
    BundleSocket,
    BundledLibrary,
    ClosureSocket,
    CollectionSocket,
    FloatSocket,
    GeometrySocket,
    ImageSocket,
    IntegerSocket,
    MaterialSocket,
    MatrixSocket,
    MenuSocket,
    ObjectSocket,
    RotationSocket,
    SocketAccessor,
    StringSocket,
    VectorSocket,
)
from ...types import (
    InputBoolean,
    InputBundle,
    InputClosure,
    InputCollection,
    InputFloat,
    InputGeometry,
    InputImage,
    InputInteger,
    InputMaterial,
    InputMatrix,
    InputMenu,
    InputObject,
    InputRotation,
    InputString,
    InputVector,
)


class Array(AssetGeometryGroup):
    """
    Array

    Parameters
    ----------
    geometry : InputGeometry
        Geometry that is duplicated
    shape : InputMenu | Literal["Line", "Circle", "Curve", "Transform"]
        Method used for arranging the duplicates
    count_method : InputMenu | Literal["Count", "Distance"]
        Method to choose the number of duplicates
    count : InputInteger
        The number of copies to generate
    distance : InputFloat
        The distance along the curve between copies
    angular_distance : InputFloat
        The angle along the circle arc between copies
    per_curve : InputBoolean
        Specify the number of copies for each curve separately
    offset_method : InputMenu | Literal["Relative", "Offset", "Endpoint"]
        Method to interpret the offset parameters
    transform_reference : InputMenu | Literal["Inputs", "Object"]
        Define the transform locally or with an object's transform
    translation : InputVector
        Translation accumulated for each copy
    offset : InputVector
        Amount to move each copy relative to its bounding box size
    rotation : InputRotation
        Rotation accumulated for each copy
    scale : InputVector
        Scale accumulated for each copy
    central_axis : InputMenu | Literal["X", "Y", "Z"]
        The up direction for the circle shape
    circle_segment : InputMenu | Literal["Full", "Arc"]
        Whether the copies should fan out in a full circle or an arc
    sweep_angle : InputFloat
        Total angle used to fan out the copies in a circular arc
    radius : InputFloat
        Distance of the instances from the origin
    transform_object : InputObject
        Reference object to define the accumulated transform
    curve_object : InputObject
        Reference curve object for array
    relative_space : InputBoolean
        Use relative space for the input geometry so the transforms of both inputs in relation are considered
    realize_instances : InputBoolean
        Turn the output into a single geometry rather than instances (required by many other modifiers)
    align_rotation : InputBoolean
        Rotate copies based on the array shape
    local_rotation : InputRotation
        Local rotation of the instances to tune the rotation alignment
    randomize : InputBoolean
        Randomize transforms between all copies
    randomize_offset : InputVector
        Offset the copies randomly
    randomize_rotation : InputVector
        Rotate the copies randomly
    randomize_scale_axes : InputMenu | Literal["Uniform", "Axes"]
        Whether to apply random scale uniformly or per axis
    socket_19 : InputVector
        Scale the copies randomly per axis
    socket_44 : InputFloat
        Scale the copies randomly
    randomize_flipping : InputVector
        Flip a fraction of copies along individual axes
    exclude_first : InputBoolean
        Exclude the first (original) copy from randomization
    exclude_last : InputBoolean
        Exclude the last copy from randomization
    seed : InputInteger
        Base value to control random variation in a reproducible way
    merge : InputBoolean
        Merge overlapping points by their distance. (Realize Instances must be enabled).
    merge_distance : InputFloat
        Distance below which points will be merged

    Inputs
    ------
    i.geometry : GeometrySocket
        Geometry that is duplicated
    i.shape : MenuSocket
        Method used for arranging the duplicates
    i.count_method : MenuSocket
        Method to choose the number of duplicates
    i.count : IntegerSocket
        The number of copies to generate
    i.distance : FloatSocket
        The distance along the curve between copies
    i.angular_distance : FloatSocket
        The angle along the circle arc between copies
    i.per_curve : BooleanSocket
        Specify the number of copies for each curve separately
    i.offset_method : MenuSocket
        Method to interpret the offset parameters
    i.transform_reference : MenuSocket
        Define the transform locally or with an object's transform
    i.translation : VectorSocket
        Translation accumulated for each copy
    i.offset : VectorSocket
        Amount to move each copy relative to its bounding box size
    i.rotation : RotationSocket
        Rotation accumulated for each copy
    i.scale : VectorSocket
        Scale accumulated for each copy
    i.central_axis : MenuSocket
        The up direction for the circle shape
    i.circle_segment : MenuSocket
        Whether the copies should fan out in a full circle or an arc
    i.sweep_angle : FloatSocket
        Total angle used to fan out the copies in a circular arc
    i.radius : FloatSocket
        Distance of the instances from the origin
    i.transform_object : ObjectSocket
        Reference object to define the accumulated transform
    i.curve_object : ObjectSocket
        Reference curve object for array
    i.relative_space : BooleanSocket
        Use relative space for the input geometry so the transforms of both inputs in relation are considered
    i.realize_instances : BooleanSocket
        Turn the output into a single geometry rather than instances (required by many other modifiers)
    i.align_rotation : BooleanSocket
        Rotate copies based on the array shape
    i.local_rotation : RotationSocket
        Local rotation of the instances to tune the rotation alignment
    i.randomize : BooleanSocket
        Randomize transforms between all copies
    i.randomize_offset : VectorSocket
        Offset the copies randomly
    i.randomize_rotation : VectorSocket
        Rotate the copies randomly
    i.randomize_scale_axes : MenuSocket
        Whether to apply random scale uniformly or per axis
    i.socket_19 : VectorSocket
        Scale the copies randomly per axis
    i.socket_44 : FloatSocket
        Scale the copies randomly
    i.randomize_flipping : VectorSocket
        Flip a fraction of copies along individual axes
    i.exclude_first : BooleanSocket
        Exclude the first (original) copy from randomization
    i.exclude_last : BooleanSocket
        Exclude the last copy from randomization
    i.seed : IntegerSocket
        Base value to control random variation in a reproducible way
    i.merge : BooleanSocket
        Merge overlapping points by their distance. (Realize Instances must be enabled).
    i.merge_distance : FloatSocket
        Distance below which points will be merged

    Outputs
    -------
    o.geometry : GeometrySocket
        Resulting Geometry
    """

    _name = "Array"
    _asset_name = "Array"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry that is duplicated"""
        shape: MenuSocket
        """Method used for arranging the duplicates"""
        count_method: MenuSocket
        """Method to choose the number of duplicates"""
        count: IntegerSocket
        """The number of copies to generate"""
        distance: FloatSocket
        """The distance along the curve between copies"""
        angular_distance: FloatSocket
        """The angle along the circle arc between copies"""
        per_curve: BooleanSocket
        """Specify the number of copies for each curve separately"""
        offset_method: MenuSocket
        """Method to interpret the offset parameters"""
        transform_reference: MenuSocket
        """Define the transform locally or with an object's transform"""
        translation: VectorSocket
        """Translation accumulated for each copy"""
        offset: VectorSocket
        """Amount to move each copy relative to its bounding box size"""
        rotation: RotationSocket
        """Rotation accumulated for each copy"""
        scale: VectorSocket
        """Scale accumulated for each copy"""
        central_axis: MenuSocket
        """The up direction for the circle shape"""
        circle_segment: MenuSocket
        """Whether the copies should fan out in a full circle or an arc"""
        sweep_angle: FloatSocket
        """Total angle used to fan out the copies in a circular arc"""
        radius: FloatSocket
        """Distance of the instances from the origin"""
        transform_object: ObjectSocket
        """Reference object to define the accumulated transform"""
        curve_object: ObjectSocket
        """Reference curve object for array"""
        relative_space: BooleanSocket
        """Use relative space for the input geometry so the transforms of both inputs in relation are considered"""
        realize_instances: BooleanSocket
        """Turn the output into a single geometry rather than instances (required by many other modifiers)"""
        align_rotation: BooleanSocket
        """Rotate copies based on the array shape"""
        local_rotation: RotationSocket
        """Local rotation of the instances to tune the rotation alignment"""
        randomize: BooleanSocket
        """Randomize transforms between all copies"""
        randomize_offset: VectorSocket
        """Offset the copies randomly"""
        randomize_rotation: VectorSocket
        """Rotate the copies randomly"""
        randomize_scale_axes: MenuSocket
        """Whether to apply random scale uniformly or per axis"""
        socket_19: VectorSocket
        """Scale the copies randomly per axis"""
        socket_44: FloatSocket
        """Scale the copies randomly"""
        randomize_flipping: VectorSocket
        """Flip a fraction of copies along individual axes"""
        exclude_first: BooleanSocket
        """Exclude the first (original) copy from randomization"""
        exclude_last: BooleanSocket
        """Exclude the last copy from randomization"""
        seed: IntegerSocket
        """Base value to control random variation in a reproducible way"""
        merge: BooleanSocket
        """Merge overlapping points by their distance. (Realize Instances must be enabled)."""
        merge_distance: FloatSocket
        """Distance below which points will be merged"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Resulting Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        shape: InputMenu | Literal["Line", "Circle", "Curve", "Transform"] = "Line",
        count_method: InputMenu | Literal["Count", "Distance"] = "Count",
        count: InputInteger = 3,
        distance: InputFloat = 1.0,
        angular_distance: InputFloat = 0.785398,
        per_curve: InputBoolean = True,
        offset_method: InputMenu
        | Literal["Relative", "Offset", "Endpoint"] = "Relative",
        transform_reference: InputMenu | Literal["Inputs", "Object"] = "Inputs",
        translation: InputVector = None,
        offset: InputVector = None,
        rotation: InputRotation = None,
        scale: InputVector = None,
        central_axis: InputMenu | Literal["X", "Y", "Z"] = "Z",
        circle_segment: InputMenu | Literal["Full", "Arc"] = "Full",
        sweep_angle: InputFloat = 3.141593,
        radius: InputFloat = 0.0,
        transform_object: InputObject = None,
        curve_object: InputObject = None,
        relative_space: InputBoolean = True,
        realize_instances: InputBoolean = True,
        align_rotation: InputBoolean = True,
        local_rotation: InputRotation = None,
        randomize: InputBoolean = False,
        randomize_offset: InputVector = None,
        randomize_rotation: InputVector = None,
        randomize_scale_axes: InputMenu | Literal["Uniform", "Axes"] = "Uniform",
        socket_19: InputVector = None,
        socket_44: InputFloat = 0.0,
        randomize_flipping: InputVector = None,
        exclude_first: InputBoolean = True,
        exclude_last: InputBoolean = False,
        seed: InputInteger = 0,
        merge: InputBoolean = False,
        merge_distance: InputFloat = 0.001,
    ):
        super().__init__(
            **{
                "Socket_7": geometry,
                "Socket_2": shape,
                "Socket_33": count_method,
                "Socket_5": count,
                "Socket_34": distance,
                "Socket_37": angular_distance,
                "Socket_35": per_curve,
                "Socket_14": offset_method,
                "Socket_25": transform_reference,
                "Socket_8": translation,
                "Socket_21": offset,
                "Socket_9": rotation,
                "Socket_10": scale,
                "Socket_11": central_axis,
                "Socket_29": circle_segment,
                "Socket_28": sweep_angle,
                "Socket_6": radius,
                "Socket_24": transform_object,
                "Socket_27": curve_object,
                "Socket_26": relative_space,
                "Socket_38": realize_instances,
                "Socket_12": align_rotation,
                "Socket_50": local_rotation,
                "Socket_17": randomize,
                "Socket_42": randomize_offset,
                "Socket_15": randomize_rotation,
                "Socket_43": randomize_scale_axes,
                "Socket_19": socket_19,
                "Socket_44": socket_44,
                "Socket_45": randomize_flipping,
                "Socket_22": exclude_first,
                "Socket_46": exclude_last,
                "Socket_18": seed,
                "Socket_31": merge,
                "Socket_32": merge_distance,
            }
        )


class AttachHairCurvesToSurface(AssetGeometryGroup):
    """
    Attach Hair Curves to Surface

    Parameters
    ----------
    geometry : InputGeometry
        Input geometry (may include geometry other than curves)
    surface_source : InputMenu | Literal["Attached", "Input", "Object"]
        Select the input source for the surface geometry.
    surface_geometry : InputGeometry
        Surface geometry to attach hair curves to
    surface_object : InputObject
        Surface Object to attach to
    surface_uv_map : InputVector
        Surface UV map used for attachment
    resting_surface : InputBoolean
        Use the surface's resting state to preserve stability under deformation
    use_existing_attachment : InputBoolean
        Sample the surface UV map at the attachment point
    snap_to_surface : InputBoolean
        Snap the root of each curve to the closest surface point
    blend_along_curve : InputFloat
        Blend deformation along each curve from the root
    align_to_surface_normal : InputBoolean
        Align the curve to the surface normal (needs a guide as reference)

    Inputs
    ------
    i.geometry : GeometrySocket
        Input geometry (may include geometry other than curves)
    i.surface_source : MenuSocket
        Select the input source for the surface geometry.
    i.surface_geometry : GeometrySocket
        Surface geometry to attach hair curves to
    i.surface_object : ObjectSocket
        Surface Object to attach to
    i.surface_uv_map : VectorSocket
        Surface UV map used for attachment
    i.resting_surface : BooleanSocket
        Use the surface's resting state to preserve stability under deformation
    i.use_existing_attachment : BooleanSocket
        Sample the surface UV map at the attachment point
    i.snap_to_surface : BooleanSocket
        Snap the root of each curve to the closest surface point
    i.blend_along_curve : FloatSocket
        Blend deformation along each curve from the root
    i.align_to_surface_normal : BooleanSocket
        Align the curve to the surface normal (needs a guide as reference)

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    o.surface_uv_coordinate : VectorSocket
        Surface UV coordinates at the attachment point
    o.surface_normal : VectorSocket
        Surface normal at the attachment point
    """

    _name = "Attach Hair Curves to Surface"
    _asset_name = "Attach Hair Curves to Surface"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Input geometry (may include geometry other than curves)"""
        surface_source: MenuSocket
        """Select the input source for the surface geometry."""
        surface_geometry: GeometrySocket
        """Surface geometry to attach hair curves to"""
        surface_object: ObjectSocket
        """Surface Object to attach to"""
        surface_uv_map: VectorSocket
        """Surface UV map used for attachment"""
        resting_surface: BooleanSocket
        """Use the surface's resting state to preserve stability under deformation"""
        use_existing_attachment: BooleanSocket
        """Sample the surface UV map at the attachment point"""
        snap_to_surface: BooleanSocket
        """Snap the root of each curve to the closest surface point"""
        blend_along_curve: FloatSocket
        """Blend deformation along each curve from the root"""
        align_to_surface_normal: BooleanSocket
        """Align the curve to the surface normal (needs a guide as reference)"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        surface_uv_coordinate: VectorSocket
        """Surface UV coordinates at the attachment point"""
        surface_normal: VectorSocket
        """Surface normal at the attachment point"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        surface_source: InputMenu | Literal["Attached", "Input", "Object"] = "Object",
        surface_geometry: InputGeometry = None,
        surface_object: InputObject = None,
        surface_uv_map: InputVector = None,
        resting_surface: InputBoolean = False,
        use_existing_attachment: InputBoolean = False,
        snap_to_surface: InputBoolean = True,
        blend_along_curve: InputFloat = 0.0,
        align_to_surface_normal: InputBoolean = False,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Socket_2": surface_source,
                "Input_3": surface_geometry,
                "Input_4": surface_object,
                "Input_2": surface_uv_map,
                "Input_6": resting_surface,
                "Input_10": use_existing_attachment,
                "Input_8": snap_to_surface,
                "Input_12": blend_along_curve,
                "Input_7": align_to_surface_normal,
            }
        )


class AttachmentInfo(AssetGeometryGroup):
    """
    Attachment Info

    Parameters
    ----------
    hair_curves : InputGeometry
        Surface geometry of the curve attachment

    Inputs
    ------
    i.hair_curves : GeometrySocket
        Surface geometry of the curve attachment

    Outputs
    -------
    o.surface_geometry : GeometrySocket
        Surface Geometry
    o.surface_exists : BooleanSocket
        Surface Exists
    o.attachment_uv : VectorSocket
        Surface attachment UV coordinates stored on each curve
    o.attachment_is_valid : BooleanSocket
        Whether the stored attachment UV coordinate is valid
    o.surface_normal : VectorSocket
        Normal direction of the surface mesh at the attachment point
    """

    _name = "Attachment Info"
    _asset_name = "Attachment Info"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        hair_curves: GeometrySocket
        """Surface geometry of the curve attachment"""

    class _Outputs(SocketAccessor):
        surface_geometry: GeometrySocket
        """Surface Geometry"""
        surface_exists: BooleanSocket
        """Surface Exists"""
        attachment_uv: VectorSocket
        """Surface attachment UV coordinates stored on each curve"""
        attachment_is_valid: BooleanSocket
        """Whether the stored attachment UV coordinate is valid"""
        surface_normal: VectorSocket
        """Normal direction of the surface mesh at the attachment point"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        hair_curves: InputGeometry = None,
    ):
        super().__init__(**{"Input_8": hair_curves})


class BlendHairCurves(AssetGeometryGroup):
    """
    Blend Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Input geometry (may include geometry other than curves)
    factor : InputFloat
        Factor to blend overall effect
    blend_radius : InputFloat
        Radius to select neighbors for blending
    blend_neighbors : InputInteger
        Amount of neighbors used for blending
    preserve_length : InputBoolean
        Preserve each curve's length during deformation

    Inputs
    ------
    i.geometry : GeometrySocket
        Input geometry (may include geometry other than curves)
    i.factor : FloatSocket
        Factor to blend overall effect
    i.blend_radius : FloatSocket
        Radius to select neighbors for blending
    i.blend_neighbors : IntegerSocket
        Amount of neighbors used for blending
    i.preserve_length : BooleanSocket
        Preserve each curve's length during deformation

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Blend Hair Curves"
    _asset_name = "Blend Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Input geometry (may include geometry other than curves)"""
        factor: FloatSocket
        """Factor to blend overall effect"""
        blend_radius: FloatSocket
        """Radius to select neighbors for blending"""
        blend_neighbors: IntegerSocket
        """Amount of neighbors used for blending"""
        preserve_length: BooleanSocket
        """Preserve each curve's length during deformation"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        factor: InputFloat = 1.0,
        blend_radius: InputFloat = 0.05,
        blend_neighbors: InputInteger = 10,
        preserve_length: InputBoolean = False,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_2": factor,
                "Input_5": blend_radius,
                "Input_4": blend_neighbors,
                "Input_6": preserve_length,
            }
        )


class BoxSelection(AssetGeometryGroup):
    """
    Box Selection

    Parameters
    ----------
    center : InputVector
        Center position of box selection
    size : InputVector
        Edge length of box selection

    Inputs
    ------
    i.center : VectorSocket
        Center position of box selection
    i.size : VectorSocket
        Edge length of box selection

    Outputs
    -------
    o.selection : BooleanSocket
        Elements inside the box
    """

    _name = "Box Selection"
    _asset_name = "Box Selection"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        center: VectorSocket
        """Center position of box selection"""
        size: VectorSocket
        """Edge length of box selection"""

    class _Outputs(SocketAccessor):
        selection: BooleanSocket
        """Elements inside the box"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        center: InputVector = None,
        size: InputVector = None,
    ):
        super().__init__(**{"Socket_1": center, "Socket_2": size})


class BraidHairCurves(AssetGeometryGroup):
    """
    Braid Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Geometry
    factor : InputFloat
        Factor to blend overall effect
    subdivision : InputInteger
        Subdivision level applied before deformation
    braid_start : InputFloat
        Percentage along each curve to blend deformation from the root
    radius : InputFloat
        Overall radius of the braids
    shape : InputFloat
        Shape of the braid radius along each curve
    frequency : InputFloat
        Frequency factor of the braids
    factor_min : InputFloat
        Factor of the minimum radius of the braids
    factor_max : InputFloat
        Factor of the maximum radius of the braids
    thickness : InputFloat
        Thickness of each strand of hair
    thickness_shape : InputFloat
        Shape adjustment of the strand thickness for the braids
    shape_asymmetry : InputFloat
        Asymmetry of the shape adjustment of the strand thickness
    flare_length : InputFloat
        Length of the flare at the end of the braid
    flare_opening : InputFloat
        Opening radius of the flare at the tip of the braid
    socket_2 : InputBoolean
        Hair Tie
    hair_tie_input_type : InputMenu | Literal["Object", "Geometry"]
        Select the input type for the hair tie geometry.
    input_17 : InputGeometry
        Geometry used for the hair tie instance (priority)
    input_16 : InputObject
        Object used for the hair tie instance
    hair_tie_scale : InputFloat
        Scale of the hair tie instance
    guide_index : InputInteger
        Guide index map to use. This input has priority.
    guide_distance : InputFloat
        Minimum distance between two guides for new guide map
    guide_mask : InputFloat
        Mask for which curves are eligible to be selected as guides
    existing_guide_map : InputBoolean
        Use the existing guide map attribute if available

    Inputs
    ------
    i.geometry : GeometrySocket
        Geometry
    i.factor : FloatSocket
        Factor to blend overall effect
    i.subdivision : IntegerSocket
        Subdivision level applied before deformation
    i.braid_start : FloatSocket
        Percentage along each curve to blend deformation from the root
    i.radius : FloatSocket
        Overall radius of the braids
    i.shape : FloatSocket
        Shape of the braid radius along each curve
    i.frequency : FloatSocket
        Frequency factor of the braids
    i.factor_min : FloatSocket
        Factor of the minimum radius of the braids
    i.factor_max : FloatSocket
        Factor of the maximum radius of the braids
    i.thickness : FloatSocket
        Thickness of each strand of hair
    i.thickness_shape : FloatSocket
        Shape adjustment of the strand thickness for the braids
    i.shape_asymmetry : FloatSocket
        Asymmetry of the shape adjustment of the strand thickness
    i.flare_length : FloatSocket
        Length of the flare at the end of the braid
    i.flare_opening : FloatSocket
        Opening radius of the flare at the tip of the braid
    i.socket_2 : BooleanSocket
        Hair Tie
    i.hair_tie_input_type : MenuSocket
        Select the input type for the hair tie geometry.
    i.input_17 : GeometrySocket
        Geometry used for the hair tie instance (priority)
    i.input_16 : ObjectSocket
        Object used for the hair tie instance
    i.hair_tie_scale : FloatSocket
        Scale of the hair tie instance
    i.guide_index : IntegerSocket
        Guide index map to use. This input has priority.
    i.guide_distance : FloatSocket
        Minimum distance between two guides for new guide map
    i.guide_mask : FloatSocket
        Mask for which curves are eligible to be selected as guides
    i.existing_guide_map : BooleanSocket
        Use the existing guide map attribute if available

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    o.flare_parameter : FloatSocket
        Parameter from 0 to 1 along the flare
    o.strand_index : IntegerSocket
        Index of the strand within a braid that each curve belongs to
    o.guide_index : IntegerSocket
        Guide index map that was used for the operation
    """

    _name = "Braid Hair Curves"
    _asset_name = "Braid Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        factor: FloatSocket
        """Factor to blend overall effect"""
        subdivision: IntegerSocket
        """Subdivision level applied before deformation"""
        braid_start: FloatSocket
        """Percentage along each curve to blend deformation from the root"""
        radius: FloatSocket
        """Overall radius of the braids"""
        shape: FloatSocket
        """Shape of the braid radius along each curve"""
        frequency: FloatSocket
        """Frequency factor of the braids"""
        factor_min: FloatSocket
        """Factor of the minimum radius of the braids"""
        factor_max: FloatSocket
        """Factor of the maximum radius of the braids"""
        thickness: FloatSocket
        """Thickness of each strand of hair"""
        thickness_shape: FloatSocket
        """Shape adjustment of the strand thickness for the braids"""
        shape_asymmetry: FloatSocket
        """Asymmetry of the shape adjustment of the strand thickness"""
        flare_length: FloatSocket
        """Length of the flare at the end of the braid"""
        flare_opening: FloatSocket
        """Opening radius of the flare at the tip of the braid"""
        socket_2: BooleanSocket
        """Hair Tie"""
        hair_tie_input_type: MenuSocket
        """Select the input type for the hair tie geometry."""
        input_17: GeometrySocket
        """Geometry used for the hair tie instance (priority)"""
        input_16: ObjectSocket
        """Object used for the hair tie instance"""
        hair_tie_scale: FloatSocket
        """Scale of the hair tie instance"""
        guide_index: IntegerSocket
        """Guide index map to use. This input has priority."""
        guide_distance: FloatSocket
        """Minimum distance between two guides for new guide map"""
        guide_mask: FloatSocket
        """Mask for which curves are eligible to be selected as guides"""
        existing_guide_map: BooleanSocket
        """Use the existing guide map attribute if available"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        flare_parameter: FloatSocket
        """Parameter from 0 to 1 along the flare"""
        strand_index: IntegerSocket
        """Index of the strand within a braid that each curve belongs to"""
        guide_index: IntegerSocket
        """Guide index map that was used for the operation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        factor: InputFloat = 1.0,
        subdivision: InputInteger = 1,
        braid_start: InputFloat = 0.1,
        radius: InputFloat = 0.1,
        shape: InputFloat = 0.5,
        frequency: InputFloat = 1.0,
        factor_min: InputFloat = 0.0,
        factor_max: InputFloat = 1.0,
        thickness: InputFloat = 1.0,
        thickness_shape: InputFloat = 0.5,
        shape_asymmetry: InputFloat = 0.0,
        flare_length: InputFloat = 0.0,
        flare_opening: InputFloat = 0.0,
        socket_2: InputBoolean = False,
        hair_tie_input_type: InputMenu | Literal["Object", "Geometry"] = "Object",
        input_17: InputGeometry = None,
        input_16: InputObject = None,
        hair_tie_scale: InputFloat = 1.0,
        guide_index: InputInteger = -987654,
        guide_distance: InputFloat = 0.1,
        guide_mask: InputFloat = 1.0,
        existing_guide_map: InputBoolean = True,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_2": factor,
                "Input_5": subdivision,
                "Input_6": braid_start,
                "Input_7": radius,
                "Input_8": shape,
                "Input_11": frequency,
                "Input_9": factor_min,
                "Input_10": factor_max,
                "Input_14": thickness,
                "Input_13": thickness_shape,
                "Input_12": shape_asymmetry,
                "Input_15": flare_length,
                "Input_21": flare_opening,
                "Socket_2": socket_2,
                "Socket_0": hair_tie_input_type,
                "Input_17": input_17,
                "Input_16": input_16,
                "Input_18": hair_tie_scale,
                "Input_25": guide_index,
                "Input_4": guide_distance,
                "Input_22": guide_mask,
                "Input_3": existing_guide_map,
            }
        )


class CaptureRestGeometry(AssetGeometryGroup):
    """
    Capture Rest Geometry

    Parameters
    ----------
    geometry : InputGeometry
        Points to modify the positions of
    rest_position : InputBoolean
        Rest Position

    Inputs
    ------
    i.geometry : GeometrySocket
        Points to modify the positions of
    i.rest_position : BooleanSocket
        Rest Position

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Capture Rest Geometry"
    _asset_name = "Capture Rest Geometry"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Points to modify the positions of"""
        rest_position: BooleanSocket
        """Rest Position"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        rest_position: InputBoolean = True,
    ):
        super().__init__(**{"Socket_1": geometry, "Socket_2": rest_position})


class ClothDynamicsExperimental(AssetGeometryGroup):
    """
    Simulate cloth while taking into account effectors like colliders and forces.

    Parameters
    ----------
    geometry : InputGeometry
        The static cloth mesh.
    pin_group : InputFloat
        How strong each vertex is pinned to its input position.
    invert_pin_group : InputBoolean
        Invert which vertices are pinned and which are not.
    stretchiness : InputFloat
        Higher values make the cloth more elastic.
    bendiness : InputFloat
        Higher values increase how much the cloth bends.
    substeps : InputInteger
        Number of simulation steps per frame.
    constraint_steps : InputInteger
        Number of steps done to solve constraints in each substep.
    simulation_to_world : InputMatrix
        Custom simulation space (by default, simulation space is world space).
    mass : InputFloat
        Mass assigned to each vertex in the solver.
    friction : InputFloat
        Friction coefficient for each vertex.
    collision_radius : InputFloat
        Collision radius for each vertex.
    linear_damping : InputFloat
        Damping increases the stability of the simulation while also slowing it down.
    socket_5 : InputBoolean
        Add gravity to the simulation.
    socket_3 : InputVector
        Direction and strength of the gravity.
    tearing : InputBoolean
        Enable dynamic tearing of the mesh.
    tearing_mode : InputMenu | Literal["All", "Custom", "Voronoi"]
        How to choose which edges are allowed to tear.
    tearing_edge_group : InputBoolean
        Selection of edges which are allowed to tear.
    tearing_threshold : InputFloat
        The higher the value, the stronger the stress required to tear an edge.
    tearing_voronoi_scale : InputFloat
        Scale of Voronoi patches whose boundaries can tear.
    effectors_collection : InputCollection
        A collection containing effectors for the simulation. This includes e.g. forces, colliders and custom effectors.
    cloth_tags : InputString
        Comma-separated list of tags which can be used to apply only a subset of effectors to this cloth.
    extra_sim_attributes : InputString
        Comma-separated list of custom attributes which should be persisted between simulation steps.
    effectors : InputBundle
        Additional effectors for the simulation.

    Inputs
    ------
    i.geometry : GeometrySocket
        The static cloth mesh.
    i.pin_group : FloatSocket
        How strong each vertex is pinned to its input position.
    i.invert_pin_group : BooleanSocket
        Invert which vertices are pinned and which are not.
    i.stretchiness : FloatSocket
        Higher values make the cloth more elastic.
    i.bendiness : FloatSocket
        Higher values increase how much the cloth bends.
    i.substeps : IntegerSocket
        Number of simulation steps per frame.
    i.constraint_steps : IntegerSocket
        Number of steps done to solve constraints in each substep.
    i.simulation_to_world : MatrixSocket
        Custom simulation space (by default, simulation space is world space).
    i.mass : FloatSocket
        Mass assigned to each vertex in the solver.
    i.friction : FloatSocket
        Friction coefficient for each vertex.
    i.collision_radius : FloatSocket
        Collision radius for each vertex.
    i.linear_damping : FloatSocket
        Damping increases the stability of the simulation while also slowing it down.
    i.socket_5 : BooleanSocket
        Add gravity to the simulation.
    i.socket_3 : VectorSocket
        Direction and strength of the gravity.
    i.tearing : BooleanSocket
        Enable dynamic tearing of the mesh.
    i.tearing_mode : MenuSocket
        How to choose which edges are allowed to tear.
    i.tearing_edge_group : BooleanSocket
        Selection of edges which are allowed to tear.
    i.tearing_threshold : FloatSocket
        The higher the value, the stronger the stress required to tear an edge.
    i.tearing_voronoi_scale : FloatSocket
        Scale of Voronoi patches whose boundaries can tear.
    i.effectors_collection : CollectionSocket
        A collection containing effectors for the simulation. This includes e.g. forces, colliders and custom effectors.
    i.cloth_tags : StringSocket
        Comma-separated list of tags which can be used to apply only a subset of effectors to this cloth.
    i.extra_sim_attributes : StringSocket
        Comma-separated list of custom attributes which should be persisted between simulation steps.
    i.effectors : BundleSocket
        Additional effectors for the simulation.

    Outputs
    -------
    o.geometry : GeometrySocket
        The simulated cloth mesh.
    o.residual_error : FloatSocket
        Average relative constraint error. 1 is good, higher is worse.
    """

    _name = "Cloth Dynamics (Experimental)"
    _asset_name = "Cloth Dynamics (Experimental)"
    _library = BundledLibrary("geometry_nodes_dynamics_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """The static cloth mesh."""
        pin_group: FloatSocket
        """How strong each vertex is pinned to its input position."""
        invert_pin_group: BooleanSocket
        """Invert which vertices are pinned and which are not."""
        stretchiness: FloatSocket
        """Higher values make the cloth more elastic."""
        bendiness: FloatSocket
        """Higher values increase how much the cloth bends."""
        substeps: IntegerSocket
        """Number of simulation steps per frame."""
        constraint_steps: IntegerSocket
        """Number of steps done to solve constraints in each substep."""
        simulation_to_world: MatrixSocket
        """Custom simulation space (by default, simulation space is world space)."""
        mass: FloatSocket
        """Mass assigned to each vertex in the solver."""
        friction: FloatSocket
        """Friction coefficient for each vertex."""
        collision_radius: FloatSocket
        """Collision radius for each vertex."""
        linear_damping: FloatSocket
        """Damping increases the stability of the simulation while also slowing it down."""
        socket_5: BooleanSocket
        """Add gravity to the simulation."""
        socket_3: VectorSocket
        """Direction and strength of the gravity."""
        tearing: BooleanSocket
        """Enable dynamic tearing of the mesh."""
        tearing_mode: MenuSocket
        """How to choose which edges are allowed to tear."""
        tearing_edge_group: BooleanSocket
        """Selection of edges which are allowed to tear."""
        tearing_threshold: FloatSocket
        """The higher the value, the stronger the stress required to tear an edge."""
        tearing_voronoi_scale: FloatSocket
        """Scale of Voronoi patches whose boundaries can tear."""
        effectors_collection: CollectionSocket
        """A collection containing effectors for the simulation. This includes e.g. forces, colliders and custom effectors."""
        cloth_tags: StringSocket
        """Comma-separated list of tags which can be used to apply only a subset of effectors to this cloth."""
        extra_sim_attributes: StringSocket
        """Comma-separated list of custom attributes which should be persisted between simulation steps."""
        effectors: BundleSocket
        """Additional effectors for the simulation."""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """The simulated cloth mesh."""
        residual_error: FloatSocket
        """Average relative constraint error. 1 is good, higher is worse."""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        pin_group: InputFloat = 0.0,
        invert_pin_group: InputBoolean = False,
        stretchiness: InputFloat = 0.0,
        bendiness: InputFloat = 0.0,
        substeps: InputInteger = 5,
        constraint_steps: InputInteger = 15,
        simulation_to_world: InputMatrix = None,
        mass: InputFloat = 1.0,
        friction: InputFloat = 0.5,
        collision_radius: InputFloat = 0.01,
        linear_damping: InputFloat = 1.0,
        socket_5: InputBoolean = True,
        socket_3: InputVector = None,
        tearing: InputBoolean = False,
        tearing_mode: InputMenu | Literal["All", "Custom", "Voronoi"] = "All",
        tearing_edge_group: InputBoolean = True,
        tearing_threshold: InputFloat = 1.2,
        tearing_voronoi_scale: InputFloat = 0.5,
        effectors_collection: InputCollection = None,
        cloth_tags: InputString = "",
        extra_sim_attributes: InputString = "",
        effectors: InputBundle = None,
    ):
        super().__init__(
            **{
                "Socket_0": geometry,
                "Socket_2": pin_group,
                "Socket_23": invert_pin_group,
                "Socket_6": stretchiness,
                "Socket_30": bendiness,
                "Socket_14": substeps,
                "Socket_15": constraint_steps,
                "Socket_29": simulation_to_world,
                "Socket_31": mass,
                "Socket_28": friction,
                "Socket_24": collision_radius,
                "Socket_8": linear_damping,
                "Socket_5": socket_5,
                "Socket_3": socket_3,
                "Socket_11": tearing,
                "Socket_17": tearing_mode,
                "Socket_13": tearing_edge_group,
                "Socket_12": tearing_threshold,
                "Socket_18": tearing_voronoi_scale,
                "Socket_7": effectors_collection,
                "Socket_20": cloth_tags,
                "Socket_22": extra_sim_attributes,
                "Socket_21": effectors,
            }
        )


class ClumpHairCurves(AssetGeometryGroup):
    """
    Clump Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Input geometry (may include geometry other than curves)
    factor : InputFloat
        Factor to blend overall effect
    shape : InputFloat
        Shape of the influence along curves (0 = constant, 0.5 = linear)
    tip_spread : InputFloat
        Distance of random spread at the curve tips
    clump_offset : InputFloat
        Offset of each clump in a random direction
    distance_falloff : InputFloat
        Falloff distance for the clumping effect (0 means no falloff)
    distance_threshold : InputFloat
        Distance threshold for the falloff around the guide
    seed : InputInteger
        Random seed for the operation
    preserve_length : InputBoolean
        Preserve each curve's length during deformation
    guide_index : InputInteger
        Guide index map to use. This input has priority.
    guide_distance : InputFloat
        Minimum distance between two guides for new guide map
    guide_mask : InputFloat
        Mask for which curves are eligible to be selected as guides
    existing_guide_map : InputBoolean
        Use the existing guide map attribute if available

    Inputs
    ------
    i.geometry : GeometrySocket
        Input geometry (may include geometry other than curves)
    i.factor : FloatSocket
        Factor to blend overall effect
    i.shape : FloatSocket
        Shape of the influence along curves (0 = constant, 0.5 = linear)
    i.tip_spread : FloatSocket
        Distance of random spread at the curve tips
    i.clump_offset : FloatSocket
        Offset of each clump in a random direction
    i.distance_falloff : FloatSocket
        Falloff distance for the clumping effect (0 means no falloff)
    i.distance_threshold : FloatSocket
        Distance threshold for the falloff around the guide
    i.seed : IntegerSocket
        Random seed for the operation
    i.preserve_length : BooleanSocket
        Preserve each curve's length during deformation
    i.guide_index : IntegerSocket
        Guide index map to use. This input has priority.
    i.guide_distance : FloatSocket
        Minimum distance between two guides for new guide map
    i.guide_mask : FloatSocket
        Mask for which curves are eligible to be selected as guides
    i.existing_guide_map : BooleanSocket
        Use the existing guide map attribute if available

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    o.guide_index : IntegerSocket
        Guide index map that was used for the operation
    """

    _name = "Clump Hair Curves"
    _asset_name = "Clump Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Input geometry (may include geometry other than curves)"""
        factor: FloatSocket
        """Factor to blend overall effect"""
        shape: FloatSocket
        """Shape of the influence along curves (0 = constant, 0.5 = linear)"""
        tip_spread: FloatSocket
        """Distance of random spread at the curve tips"""
        clump_offset: FloatSocket
        """Offset of each clump in a random direction"""
        distance_falloff: FloatSocket
        """Falloff distance for the clumping effect (0 means no falloff)"""
        distance_threshold: FloatSocket
        """Distance threshold for the falloff around the guide"""
        seed: IntegerSocket
        """Random seed for the operation"""
        preserve_length: BooleanSocket
        """Preserve each curve's length during deformation"""
        guide_index: IntegerSocket
        """Guide index map to use. This input has priority."""
        guide_distance: FloatSocket
        """Minimum distance between two guides for new guide map"""
        guide_mask: FloatSocket
        """Mask for which curves are eligible to be selected as guides"""
        existing_guide_map: BooleanSocket
        """Use the existing guide map attribute if available"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        guide_index: IntegerSocket
        """Guide index map that was used for the operation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        factor: InputFloat = 1.0,
        shape: InputFloat = 0.5,
        tip_spread: InputFloat = 0.0,
        clump_offset: InputFloat = 0.0,
        distance_falloff: InputFloat = 0.0,
        distance_threshold: InputFloat = 0.0,
        seed: InputInteger = 0,
        preserve_length: InputBoolean = False,
        guide_index: InputInteger = -987654,
        guide_distance: InputFloat = 0.1,
        guide_mask: InputFloat = 1.0,
        existing_guide_map: InputBoolean = True,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_7": factor,
                "Input_6": shape,
                "Input_10": tip_spread,
                "Input_13": clump_offset,
                "Input_12": distance_falloff,
                "Input_11": distance_threshold,
                "Input_14": seed,
                "Input_15": preserve_length,
                "Input_16": guide_index,
                "Input_9": guide_distance,
                "Input_19": guide_mask,
                "Input_8": existing_guide_map,
            }
        )


class Collider(AssetGeometryGroup):
    """
    Turn a geometry into a collider.

    Parameters
    ----------
    geometry : InputGeometry
        The collider geometry.
    deforming : InputBoolean
        Whether the collider geometry is changing.
    boundary : InputBoolean
        If true, the simulated geometry should stay within the mesh instead of it being pushed out of it.
    edge_contacts : InputBoolean
        Increased collision accuracy (only for collisions with curves/hair currently).
    margin : InputFloat
        Additional margin around the collider to prevent penetration.
    friction : InputFloat
        Friction coefficient for this collider.
    softness : InputFloat
        Increasing softness allows some penetration.
    filter : InputString
        Comma-separated list of tags this collider should apply to.
    error_threshold : InputFloat
        Used to compute a relative error of this constraint to determine solve quality.

    Inputs
    ------
    i.geometry : GeometrySocket
        The collider geometry.
    i.deforming : BooleanSocket
        Whether the collider geometry is changing.
    i.boundary : BooleanSocket
        If true, the simulated geometry should stay within the mesh instead of it being pushed out of it.
    i.edge_contacts : BooleanSocket
        Increased collision accuracy (only for collisions with curves/hair currently).
    i.margin : FloatSocket
        Additional margin around the collider to prevent penetration.
    i.friction : FloatSocket
        Friction coefficient for this collider.
    i.softness : FloatSocket
        Increasing softness allows some penetration.
    i.filter : StringSocket
        Comma-separated list of tags this collider should apply to.
    i.error_threshold : FloatSocket
        Used to compute a relative error of this constraint to determine solve quality.

    Outputs
    -------
    o.geometry : GeometrySocket
        The input geometry with additional collider information attached.
    o.collider : BundleSocket
        The collider effector bundle that can be passed into a simulation.
    """

    _name = "Collider"
    _asset_name = "Collider"
    _library = BundledLibrary("geometry_nodes_dynamics_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """The collider geometry."""
        deforming: BooleanSocket
        """Whether the collider geometry is changing."""
        boundary: BooleanSocket
        """If true, the simulated geometry should stay within the mesh instead of it being pushed out of it."""
        edge_contacts: BooleanSocket
        """Increased collision accuracy (only for collisions with curves/hair currently)."""
        margin: FloatSocket
        """Additional margin around the collider to prevent penetration."""
        friction: FloatSocket
        """Friction coefficient for this collider."""
        softness: FloatSocket
        """Increasing softness allows some penetration."""
        filter: StringSocket
        """Comma-separated list of tags this collider should apply to."""
        error_threshold: FloatSocket
        """Used to compute a relative error of this constraint to determine solve quality."""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """The input geometry with additional collider information attached."""
        collider: BundleSocket
        """The collider effector bundle that can be passed into a simulation."""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        deforming: InputBoolean = False,
        boundary: InputBoolean = False,
        edge_contacts: InputBoolean = False,
        margin: InputFloat = 0.0,
        friction: InputFloat = 0.2,
        softness: InputFloat = 0.0,
        filter: InputString = "",
        error_threshold: InputFloat = 0.001,
    ):
        super().__init__(
            **{
                "Socket_0": geometry,
                "Socket_3": deforming,
                "Socket_6": boundary,
                "Socket_5": edge_contacts,
                "Socket_12": margin,
                "Socket_2": friction,
                "Socket_8": softness,
                "Socket_4": filter,
                "Socket_10": error_threshold,
            }
        )


class CombineCylindrical(AssetGeometryGroup):
    """
    Combine Cylindrical

    Parameters
    ----------
    r : InputFloat
        Radius - Length of the vector
    phi : InputFloat
        Azimuth - Angle around the up axis
    z : InputFloat
        Offset from the ground plane

    Inputs
    ------
    i.r : FloatSocket
        Radius - Length of the vector
    i.phi : FloatSocket
        Azimuth - Angle around the up axis
    i.z : FloatSocket
        Offset from the ground plane

    Outputs
    -------
    o.vector : VectorSocket
        Vector
    """

    _name = "Combine Cylindrical"
    _asset_name = "Combine Cylindrical"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        r: FloatSocket
        """Radius - Length of the vector"""
        phi: FloatSocket
        """Azimuth - Angle around the up axis"""
        z: FloatSocket
        """Offset from the ground plane"""

    class _Outputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        r: InputFloat = 0.0,
        phi: InputFloat = 0.0,
        z: InputFloat = 0.0,
    ):
        super().__init__(**{"Input_3": r, "Input_0": phi, "Socket_2": z})


class CombineSpherical(AssetGeometryGroup):
    """
    Combine Spherical

    Parameters
    ----------
    r : InputFloat
        Radius - Length of the vector
    phi : InputFloat
        Azimuth - Angle around the up axis
    theta : InputFloat
        Zenith - Angle from the ground plane

    Inputs
    ------
    i.r : FloatSocket
        Radius - Length of the vector
    i.phi : FloatSocket
        Azimuth - Angle around the up axis
    i.theta : FloatSocket
        Zenith - Angle from the ground plane

    Outputs
    -------
    o.vector : VectorSocket
        Vector
    """

    _name = "Combine Spherical"
    _asset_name = "Combine Spherical"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        r: FloatSocket
        """Radius - Length of the vector"""
        phi: FloatSocket
        """Azimuth - Angle around the up axis"""
        theta: FloatSocket
        """Zenith - Angle from the ground plane"""

    class _Outputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        r: InputFloat = 0.0,
        phi: InputFloat = 0.0,
        theta: InputFloat = 0.0,
    ):
        super().__init__(**{"Input_3": r, "Input_0": phi, "Input_1": theta})


class CreateGuideIndexMap(AssetGeometryGroup):
    """
    Create Guide Index Map

    Parameters
    ----------
    geometry : InputGeometry
        Geometry
    guides : InputGeometry
        Guide curves or points used for the selection of guide curves
    guide_distance : InputFloat
        Minimum distance between two guides
    guide_mask : InputFloat
        Mask for which curves are eligible to be selected as guides
    group_id : InputInteger
        ID to group curves together for guide map creation

    Inputs
    ------
    i.geometry : GeometrySocket
        Geometry
    i.guides : GeometrySocket
        Guide curves or points used for the selection of guide curves
    i.guide_distance : FloatSocket
        Minimum distance between two guides
    i.guide_mask : FloatSocket
        Mask for which curves are eligible to be selected as guides
    i.group_id : IntegerSocket
        ID to group curves together for guide map creation

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    o.guide_curves : GeometrySocket
        Guide Curves
    o.guide_index : IntegerSocket
        Guide Index
    o.guide_selection : BooleanSocket
        Guide Selection
    """

    _name = "Create Guide Index Map"
    _asset_name = "Create Guide Index Map"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        guides: GeometrySocket
        """Guide curves or points used for the selection of guide curves"""
        guide_distance: FloatSocket
        """Minimum distance between two guides"""
        guide_mask: FloatSocket
        """Mask for which curves are eligible to be selected as guides"""
        group_id: IntegerSocket
        """ID to group curves together for guide map creation"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        guide_curves: GeometrySocket
        """Guide Curves"""
        guide_index: IntegerSocket
        """Guide Index"""
        guide_selection: BooleanSocket
        """Guide Selection"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        guides: InputGeometry = None,
        guide_distance: InputFloat = 0.0,
        guide_mask: InputFloat = 1.0,
        group_id: InputInteger = 0,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_10": guides,
                "Input_3": guide_distance,
                "Input_11": guide_mask,
                "Input_12": group_id,
            }
        )


class CurlHairCurves(AssetGeometryGroup):
    """
    Curl Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Geometry
    factor : InputFloat
        Factor to blend overall effect
    subdivision : InputInteger
        Subdivision level applied before deformation
    curl_start : InputFloat
        Percentage along each curve to blend deformation from the root
    radius : InputFloat
        Overall radius of the curls
    factor_start : InputFloat
        Factor for the radius at the curl start
    factor_end : InputFloat
        Factor for the radius at the curl end
    frequency : InputFloat
        Frequency factor of the curls
    random_offset : InputFloat
        Amount of random offset per curve
    seed : InputInteger
        Random seed for the operation
    guide_index : InputInteger
        Guide index map to use. This input has priority.
    guide_distance : InputFloat
        Minimum distance between two guides for new guide map
    guide_mask : InputFloat
        Mask for which curves are eligible to be selected as guides
    existing_guide_map : InputBoolean
        Use the existing guide map attribute if available

    Inputs
    ------
    i.geometry : GeometrySocket
        Geometry
    i.factor : FloatSocket
        Factor to blend overall effect
    i.subdivision : IntegerSocket
        Subdivision level applied before deformation
    i.curl_start : FloatSocket
        Percentage along each curve to blend deformation from the root
    i.radius : FloatSocket
        Overall radius of the curls
    i.factor_start : FloatSocket
        Factor for the radius at the curl start
    i.factor_end : FloatSocket
        Factor for the radius at the curl end
    i.frequency : FloatSocket
        Frequency factor of the curls
    i.random_offset : FloatSocket
        Amount of random offset per curve
    i.seed : IntegerSocket
        Random seed for the operation
    i.guide_index : IntegerSocket
        Guide index map to use. This input has priority.
    i.guide_distance : FloatSocket
        Minimum distance between two guides for new guide map
    i.guide_mask : FloatSocket
        Mask for which curves are eligible to be selected as guides
    i.existing_guide_map : BooleanSocket
        Use the existing guide map attribute if available

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    o.guide_index : IntegerSocket
        Guide index map that was used for the operation
    """

    _name = "Curl Hair Curves"
    _asset_name = "Curl Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        factor: FloatSocket
        """Factor to blend overall effect"""
        subdivision: IntegerSocket
        """Subdivision level applied before deformation"""
        curl_start: FloatSocket
        """Percentage along each curve to blend deformation from the root"""
        radius: FloatSocket
        """Overall radius of the curls"""
        factor_start: FloatSocket
        """Factor for the radius at the curl start"""
        factor_end: FloatSocket
        """Factor for the radius at the curl end"""
        frequency: FloatSocket
        """Frequency factor of the curls"""
        random_offset: FloatSocket
        """Amount of random offset per curve"""
        seed: IntegerSocket
        """Random seed for the operation"""
        guide_index: IntegerSocket
        """Guide index map to use. This input has priority."""
        guide_distance: FloatSocket
        """Minimum distance between two guides for new guide map"""
        guide_mask: FloatSocket
        """Mask for which curves are eligible to be selected as guides"""
        existing_guide_map: BooleanSocket
        """Use the existing guide map attribute if available"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        guide_index: IntegerSocket
        """Guide index map that was used for the operation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        factor: InputFloat = 1.0,
        subdivision: InputInteger = 1,
        curl_start: InputFloat = 0.1,
        radius: InputFloat = 0.1,
        factor_start: InputFloat = 1.0,
        factor_end: InputFloat = 1.0,
        frequency: InputFloat = 1.0,
        random_offset: InputFloat = 0.25,
        seed: InputInteger = 0,
        guide_index: InputInteger = -987654,
        guide_distance: InputFloat = 0.1,
        guide_mask: InputFloat = 1.0,
        existing_guide_map: InputBoolean = True,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_2": factor,
                "Input_5": subdivision,
                "Input_6": curl_start,
                "Input_7": radius,
                "Input_9": factor_start,
                "Input_10": factor_end,
                "Input_11": frequency,
                "Input_16": random_offset,
                "Input_15": seed,
                "Input_19": guide_index,
                "Input_4": guide_distance,
                "Input_18": guide_mask,
                "Input_3": existing_guide_map,
            }
        )


class CurveInfo(AssetGeometryGroup):
    """
    Curve Info

    Outputs
    -------
    o.curve_index : IntegerSocket
        Index of each curve
    o.curve_id : IntegerSocket
        ID of each curve
    o.length : FloatSocket
        Length of each curve
    o.direction : VectorSocket
        Direction from root to tip of each curve
    o.random : FloatSocket
        Random vector for each curve
    o.surface_uv : VectorSocket
        Attachment surface UV coordinates of each curve
    """

    _name = "Curve Info"
    _asset_name = "Curve Info"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        pass

    class _Outputs(SocketAccessor):
        curve_index: IntegerSocket
        """Index of each curve"""
        curve_id: IntegerSocket
        """ID of each curve"""
        length: FloatSocket
        """Length of each curve"""
        direction: VectorSocket
        """Direction from root to tip of each curve"""
        random: FloatSocket
        """Random vector for each curve"""
        surface_uv: VectorSocket
        """Attachment surface UV coordinates of each curve"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self):
        super().__init__(**{})


class CurveRoot(AssetGeometryGroup):
    """
    Curve Root

    Outputs
    -------
    o.root_selection : BooleanSocket
        Boolean selection of curve root points
    o.root_position : VectorSocket
        Position of the root point of a curve
    o.root_direction : VectorSocket
        Direction of the root segment of a curve
    o.root_index : IntegerSocket
        Index of the root point of a curve
    """

    _name = "Curve Root"
    _asset_name = "Curve Root"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        pass

    class _Outputs(SocketAccessor):
        root_selection: BooleanSocket
        """Boolean selection of curve root points"""
        root_position: VectorSocket
        """Position of the root point of a curve"""
        root_direction: VectorSocket
        """Direction of the root segment of a curve"""
        root_index: IntegerSocket
        """Index of the root point of a curve"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self):
        super().__init__(**{})


class CurveSegment(AssetGeometryGroup):
    """
    Curve Segment

    Outputs
    -------
    o.segment_length : FloatSocket
        Distance to the previous point on the curve
    o.segment_direction : VectorSocket
        Direction from the previous neighboring point on the segment
    o.neighbor_index : IntegerSocket
        Index of the previous neighboring point on the segment
    """

    _name = "Curve Segment"
    _asset_name = "Curve Segment"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        pass

    class _Outputs(SocketAccessor):
        segment_length: FloatSocket
        """Distance to the previous point on the curve"""
        segment_direction: VectorSocket
        """Direction from the previous neighboring point on the segment"""
        neighbor_index: IntegerSocket
        """Index of the previous neighboring point on the segment"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self):
        super().__init__(**{})


class CurveTip(AssetGeometryGroup):
    """
    Curve Tip

    Outputs
    -------
    o.tip_selection : BooleanSocket
        Boolean selection of curve tip points
    o.tip_position : VectorSocket
        Position of the tip point of a curve
    o.tip_direction : VectorSocket
        Direction of the tip segment of a curve
    o.tip_index : IntegerSocket
        Index of the tip point of a curve
    """

    _name = "Curve Tip"
    _asset_name = "Curve Tip"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        pass

    class _Outputs(SocketAccessor):
        tip_selection: BooleanSocket
        """Boolean selection of curve tip points"""
        tip_position: VectorSocket
        """Position of the tip point of a curve"""
        tip_direction: VectorSocket
        """Direction of the tip segment of a curve"""
        tip_index: IntegerSocket
        """Index of the tip point of a curve"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self):
        super().__init__(**{})


class CurveToTube(AssetGeometryGroup):
    """
    Curve to Tube

    Parameters
    ----------
    curve : InputGeometry
        Curve geometry defining the curve path
    scale : InputFloat
        Distance factor multiplied with the curve's radius attribute to define the resulting tube radius
    profile_mode : InputMenu | Literal["Round", "Custom"]
        Method used to define the profile shape
    profile_input : InputMenu | Literal["Object", "Geometry"]
        How the profile geometry input should be exposed
    profile_object : InputObject
        Shape defining a section of the tube, using the XY plane
    profile_geometry : InputGeometry
        Shape defining a section of the tube, using the XY plane
    profile_resolution : InputInteger
        Number of points on the profile circle. Also defines the round cap resolution.
    shade_smooth : InputBoolean
        Use smooth vertex normals instead of face normals for the result mesh
    resample : InputBoolean
        Resample the input curve before meshing
    resample_mode : InputMenu | Literal["Evaluated", "Auto", "Count", "Length"]
        How to specify the number of samples
    resample_count : InputInteger
        Number of sample points on the curve
    resample_length : InputFloat
        Distance between two sample points along the curve
    resample_scale : InputFloat
        Scale factor applied on the automatically derived resample length
    caps : InputBoolean
        Fill the holes at the tube ends with cap geometry
    caps_type : InputMenu | Literal["Flat", "Round", "Custom"]
        Method used to build the start and end geometry
    caps_input : InputMenu | Literal["Object", "Geometry"]
        How the cap geometry input should be exposed
    socket_21 : InputObject
        Geometry to add to the start of each curve
    socket_22 : InputObject
        Geometry to add to the end of each curve
    socket_23 : InputGeometry
        Geometry to add to the start of each curve
    socket_24 : InputGeometry
        Geometry to add to the end of each curve
    caps_resolution : InputInteger
        Amount of edge loops the round caps are generated with
    caps_smooth : InputBoolean
        Make border edges between the caps and the tube shape smooth instead of sharp
    caps_merge : InputBoolean
        Combine the cap geometry with the base mesh (realizing instances and merging vertices)
    caps_align_normals : InputBoolean
        Build custom normals on the caps for more continuous shading borders with the tube shape
    caps_extrapolate_radius : InputBoolean
        Adjust the shape of the cap to follow the change in radius towards the curve ends
    uv_map : InputBoolean
        Generate UV attribute data on the curve geometry
    uv_map_name : InputString
        Name of the UV map attribute to generate
    uv_map_parameter_u : InputMenu | Literal["Factor", "Length", "Index"]
        Method to generate the map's X coordinate along the main curve
    uv_map_parameter_v : InputMenu | Literal["Factor", "Length", "Index"]
        Method to generate the map's Y coordinate along the profile curve
    consider_curve_radius : InputBoolean
        Consider the main curve's radius attribute as a factor when mapping the V component by the profile curve's length parameter

    Inputs
    ------
    i.curve : GeometrySocket
        Curve geometry defining the curve path
    i.scale : FloatSocket
        Distance factor multiplied with the curve's radius attribute to define the resulting tube radius
    i.profile_mode : MenuSocket
        Method used to define the profile shape
    i.profile_input : MenuSocket
        How the profile geometry input should be exposed
    i.profile_object : ObjectSocket
        Shape defining a section of the tube, using the XY plane
    i.profile_geometry : GeometrySocket
        Shape defining a section of the tube, using the XY plane
    i.profile_resolution : IntegerSocket
        Number of points on the profile circle. Also defines the round cap resolution.
    i.shade_smooth : BooleanSocket
        Use smooth vertex normals instead of face normals for the result mesh
    i.resample : BooleanSocket
        Resample the input curve before meshing
    i.resample_mode : MenuSocket
        How to specify the number of samples
    i.resample_count : IntegerSocket
        Number of sample points on the curve
    i.resample_length : FloatSocket
        Distance between two sample points along the curve
    i.resample_scale : FloatSocket
        Scale factor applied on the automatically derived resample length
    i.caps : BooleanSocket
        Fill the holes at the tube ends with cap geometry
    i.caps_type : MenuSocket
        Method used to build the start and end geometry
    i.caps_input : MenuSocket
        How the cap geometry input should be exposed
    i.socket_21 : ObjectSocket
        Geometry to add to the start of each curve
    i.socket_22 : ObjectSocket
        Geometry to add to the end of each curve
    i.socket_23 : GeometrySocket
        Geometry to add to the start of each curve
    i.socket_24 : GeometrySocket
        Geometry to add to the end of each curve
    i.caps_resolution : IntegerSocket
        Amount of edge loops the round caps are generated with
    i.caps_smooth : BooleanSocket
        Make border edges between the caps and the tube shape smooth instead of sharp
    i.caps_merge : BooleanSocket
        Combine the cap geometry with the base mesh (realizing instances and merging vertices)
    i.caps_align_normals : BooleanSocket
        Build custom normals on the caps for more continuous shading borders with the tube shape
    i.caps_extrapolate_radius : BooleanSocket
        Adjust the shape of the cap to follow the change in radius towards the curve ends
    i.uv_map : BooleanSocket
        Generate UV attribute data on the curve geometry
    i.uv_map_name : StringSocket
        Name of the UV map attribute to generate
    i.uv_map_parameter_u : MenuSocket
        Method to generate the map's X coordinate along the main curve
    i.uv_map_parameter_v : MenuSocket
        Method to generate the map's Y coordinate along the profile curve
    i.consider_curve_radius : BooleanSocket
        Consider the main curve's radius attribute as a factor when mapping the V component by the profile curve's length parameter

    Outputs
    -------
    o.mesh : GeometrySocket
        Tube mesh
    """

    _name = "Curve to Tube"
    _asset_name = "Curve to Tube"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        curve: GeometrySocket
        """Curve geometry defining the curve path"""
        scale: FloatSocket
        """Distance factor multiplied with the curve's radius attribute to define the resulting tube radius"""
        profile_mode: MenuSocket
        """Method used to define the profile shape"""
        profile_input: MenuSocket
        """How the profile geometry input should be exposed"""
        profile_object: ObjectSocket
        """Shape defining a section of the tube, using the XY plane"""
        profile_geometry: GeometrySocket
        """Shape defining a section of the tube, using the XY plane"""
        profile_resolution: IntegerSocket
        """Number of points on the profile circle. Also defines the round cap resolution."""
        shade_smooth: BooleanSocket
        """Use smooth vertex normals instead of face normals for the result mesh"""
        resample: BooleanSocket
        """Resample the input curve before meshing"""
        resample_mode: MenuSocket
        """How to specify the number of samples"""
        resample_count: IntegerSocket
        """Number of sample points on the curve"""
        resample_length: FloatSocket
        """Distance between two sample points along the curve"""
        resample_scale: FloatSocket
        """Scale factor applied on the automatically derived resample length"""
        caps: BooleanSocket
        """Fill the holes at the tube ends with cap geometry"""
        caps_type: MenuSocket
        """Method used to build the start and end geometry"""
        caps_input: MenuSocket
        """How the cap geometry input should be exposed"""
        socket_21: ObjectSocket
        """Geometry to add to the start of each curve"""
        socket_22: ObjectSocket
        """Geometry to add to the end of each curve"""
        socket_23: GeometrySocket
        """Geometry to add to the start of each curve"""
        socket_24: GeometrySocket
        """Geometry to add to the end of each curve"""
        caps_resolution: IntegerSocket
        """Amount of edge loops the round caps are generated with"""
        caps_smooth: BooleanSocket
        """Make border edges between the caps and the tube shape smooth instead of sharp"""
        caps_merge: BooleanSocket
        """Combine the cap geometry with the base mesh (realizing instances and merging vertices)"""
        caps_align_normals: BooleanSocket
        """Build custom normals on the caps for more continuous shading borders with the tube shape"""
        caps_extrapolate_radius: BooleanSocket
        """Adjust the shape of the cap to follow the change in radius towards the curve ends"""
        uv_map: BooleanSocket
        """Generate UV attribute data on the curve geometry"""
        uv_map_name: StringSocket
        """Name of the UV map attribute to generate"""
        uv_map_parameter_u: MenuSocket
        """Method to generate the map's X coordinate along the main curve"""
        uv_map_parameter_v: MenuSocket
        """Method to generate the map's Y coordinate along the profile curve"""
        consider_curve_radius: BooleanSocket
        """Consider the main curve's radius attribute as a factor when mapping the V component by the profile curve's length parameter"""

    class _Outputs(SocketAccessor):
        mesh: GeometrySocket
        """Tube mesh"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        curve: InputGeometry = None,
        scale: InputFloat = 0.1,
        profile_mode: InputMenu | Literal["Round", "Custom"] = "Round",
        profile_input: InputMenu | Literal["Object", "Geometry"] = "Object",
        profile_object: InputObject = None,
        profile_geometry: InputGeometry = None,
        profile_resolution: InputInteger = 8,
        shade_smooth: InputBoolean = True,
        resample: InputBoolean = True,
        resample_mode: InputMenu
        | Literal["Evaluated", "Auto", "Count", "Length"] = "Evaluated",
        resample_count: InputInteger = 10,
        resample_length: InputFloat = 0.1,
        resample_scale: InputFloat = 1.0,
        caps: InputBoolean = True,
        caps_type: InputMenu | Literal["Flat", "Round", "Custom"] = "Flat",
        caps_input: InputMenu | Literal["Object", "Geometry"] = "Object",
        socket_21: InputObject = None,
        socket_22: InputObject = None,
        socket_23: InputGeometry = None,
        socket_24: InputGeometry = None,
        caps_resolution: InputInteger = 12,
        caps_smooth: InputBoolean = False,
        caps_merge: InputBoolean = True,
        caps_align_normals: InputBoolean = False,
        caps_extrapolate_radius: InputBoolean = True,
        uv_map: InputBoolean = True,
        uv_map_name: InputString = "UVMap",
        uv_map_parameter_u: InputMenu | Literal["Factor", "Length", "Index"] = "Length",
        uv_map_parameter_v: InputMenu | Literal["Factor", "Length", "Index"] = "Factor",
        consider_curve_radius: InputBoolean = True,
    ):
        super().__init__(
            **{
                "Socket_0": curve,
                "Socket_5": scale,
                "Socket_4": profile_mode,
                "Socket_26": profile_input,
                "Socket_3": profile_object,
                "Socket_27": profile_geometry,
                "Socket_2": profile_resolution,
                "Socket_11": shade_smooth,
                "Socket_36": resample,
                "Socket_32": resample_mode,
                "Socket_33": resample_count,
                "Socket_37": resample_length,
                "Socket_38": resample_scale,
                "Socket_39": caps,
                "Socket_10": caps_type,
                "Socket_25": caps_input,
                "Socket_21": socket_21,
                "Socket_22": socket_22,
                "Socket_23": socket_23,
                "Socket_24": socket_24,
                "Socket_28": caps_resolution,
                "Socket_15": caps_smooth,
                "Socket_13": caps_merge,
                "Socket_14": caps_align_normals,
                "Socket_30": caps_extrapolate_radius,
                "Socket_31": uv_map,
                "Socket_17": uv_map_name,
                "Socket_19": uv_map_parameter_u,
                "Socket_20": uv_map_parameter_v,
                "Socket_29": consider_curve_radius,
            }
        )


class CustomEffector(AssetGeometryGroup):
    """
    Create a custom effector that can be injected into e.g. simulations.

    Parameters
    ----------
    type : InputMenu | Literal["Geometry", "World"]
        The type of effector to create.
    socket_1 : InputMenu | Literal["Default", "Pre-Simulation", "Pre-Solve", "Post-Solve", "Custom"]
        At which stage the custom effector should be evaluated.
    socket_2 : InputString
        Custom stage name.
    geometry_effector : InputClosure
        Closure effecting one geometry at a time.
    world_effector : InputClosure
        Closure modifying an entire (simulation) world at once.
    filter : InputString
        Comma-separated list of tags this effector should apply to.

    Inputs
    ------
    i.type : MenuSocket
        The type of effector to create.
    i.socket_1 : MenuSocket
        At which stage the custom effector should be evaluated.
    i.socket_2 : StringSocket
        Custom stage name.
    i.geometry_effector : ClosureSocket
        Closure effecting one geometry at a time.
    i.world_effector : ClosureSocket
        Closure modifying an entire (simulation) world at once.
    i.filter : StringSocket
        Comma-separated list of tags this effector should apply to.

    Outputs
    -------
    o.effector : BundleSocket
        A bundle containing all information about this effector.
    """

    _name = "Custom Effector"
    _asset_name = "Custom Effector"
    _library = BundledLibrary("geometry_nodes_dynamics_assets.blend")

    class _Inputs(SocketAccessor):
        type: MenuSocket
        """The type of effector to create."""
        socket_1: MenuSocket
        """At which stage the custom effector should be evaluated."""
        socket_2: StringSocket
        """Custom stage name."""
        geometry_effector: ClosureSocket
        """Closure effecting one geometry at a time."""
        world_effector: ClosureSocket
        """Closure modifying an entire (simulation) world at once."""
        filter: StringSocket
        """Comma-separated list of tags this effector should apply to."""

    class _Outputs(SocketAccessor):
        effector: BundleSocket
        """A bundle containing all information about this effector."""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        type: InputMenu | Literal["Geometry", "World"] = "Geometry",
        socket_1: InputMenu
        | Literal[
            "Default", "Pre-Simulation", "Pre-Solve", "Post-Solve", "Custom"
        ] = "Default",
        socket_2: InputString = "",
        geometry_effector: InputClosure = None,
        world_effector: InputClosure = None,
        filter: InputString = "",
    ):
        super().__init__(
            **{
                "Socket_7": type,
                "Socket_1": socket_1,
                "Socket_2": socket_2,
                "Socket_5": geometry_effector,
                "Socket_6": world_effector,
                "Socket_3": filter,
            }
        )


class CustomForce(AssetGeometryGroup):
    """
    Create a custom force field to be used in simulations.

    Parameters
    ----------
    mode : InputMenu | Literal["Field", "Closure"]
        How the force field is defined.
    closure : InputClosure
        The closure computing the force at each point of the input geometry.
    selection : InputBoolean
        Selection of points this force is applied to.
    force : InputVector
        The actual force vector.
    socket_6 : InputMenu | Literal["Custom Space", "World Space", "Object Space"]
        The space the geometry is transformed to before the field is evaluated.
    socket_8 : InputMatrix
        Custom geometry space.
    socket_14 : InputObject
        Object to take the geometry space from.
    socket_7 : InputMenu | Literal["Custom Space", "World Space", "Object Space"]
        The space the provided force vector is in.
    socket_11 : InputMatrix
        Custom force space.
    socket_15 : InputObject
        Object to take the force space from.
    filter : InputString
        Comma-separated list of tags this effector should be applied to.

    Inputs
    ------
    i.mode : MenuSocket
        How the force field is defined.
    i.closure : ClosureSocket
        The closure computing the force at each point of the input geometry.
    i.selection : BooleanSocket
        Selection of points this force is applied to.
    i.force : VectorSocket
        The actual force vector.
    i.socket_6 : MenuSocket
        The space the geometry is transformed to before the field is evaluated.
    i.socket_8 : MatrixSocket
        Custom geometry space.
    i.socket_14 : ObjectSocket
        Object to take the geometry space from.
    i.socket_7 : MenuSocket
        The space the provided force vector is in.
    i.socket_11 : MatrixSocket
        Custom force space.
    i.socket_15 : ObjectSocket
        Object to take the force space from.
    i.filter : StringSocket
        Comma-separated list of tags this effector should be applied to.

    Outputs
    -------
    o.force : BundleSocket
        A bundle containing all information about this effector.
    """

    _name = "Custom Force"
    _asset_name = "Custom Force"
    _library = BundledLibrary("geometry_nodes_dynamics_assets.blend")

    class _Inputs(SocketAccessor):
        mode: MenuSocket
        """How the force field is defined."""
        closure: ClosureSocket
        """The closure computing the force at each point of the input geometry."""
        selection: BooleanSocket
        """Selection of points this force is applied to."""
        force: VectorSocket
        """The actual force vector."""
        socket_6: MenuSocket
        """The space the geometry is transformed to before the field is evaluated."""
        socket_8: MatrixSocket
        """Custom geometry space."""
        socket_14: ObjectSocket
        """Object to take the geometry space from."""
        socket_7: MenuSocket
        """The space the provided force vector is in."""
        socket_11: MatrixSocket
        """Custom force space."""
        socket_15: ObjectSocket
        """Object to take the force space from."""
        filter: StringSocket
        """Comma-separated list of tags this effector should be applied to."""

    class _Outputs(SocketAccessor):
        force: BundleSocket
        """A bundle containing all information about this effector."""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        mode: InputMenu | Literal["Field", "Closure"] = "Field",
        closure: InputClosure = None,
        selection: InputBoolean = True,
        force: InputVector = None,
        socket_6: InputMenu
        | Literal["Custom Space", "World Space", "Object Space"] = "World Space",
        socket_8: InputMatrix = None,
        socket_14: InputObject = None,
        socket_7: InputMenu
        | Literal["Custom Space", "World Space", "Object Space"] = "World Space",
        socket_11: InputMatrix = None,
        socket_15: InputObject = None,
        filter: InputString = "",
    ):
        super().__init__(
            **{
                "Socket_4": mode,
                "Socket_5": closure,
                "Socket_9": selection,
                "Socket_10": force,
                "Socket_6": socket_6,
                "Socket_8": socket_8,
                "Socket_14": socket_14,
                "Socket_7": socket_7,
                "Socket_11": socket_11,
                "Socket_15": socket_15,
                "Socket_1": filter,
            }
        )


class DisplaceGeometry(AssetGeometryGroup):
    """
    Displace Geometry

    Parameters
    ----------
    geometry : InputGeometry
        Geometry with points to displace
    selection : InputBoolean
        Selection of points that should be displaced
    strength : InputFloat
        Factor that the displacement is multiplied with
    offset_method : InputMenu | Literal["Normal", "Vector"]
        Input method for how to generate the displacement vector
    offset_vector : InputVector
        Displacement offset vector
    offset_distance : InputFloat
        Distance of the displacement offset in normal direction
    substeps : InputInteger
        Number of steps to divide the full displacement into. Fields, including normal and position, are re-evaluated before each step.
    post_substep_process : InputClosure
        Geometry process to apply after each displacement step

    Inputs
    ------
    i.geometry : GeometrySocket
        Geometry with points to displace
    i.selection : BooleanSocket
        Selection of points that should be displaced
    i.strength : FloatSocket
        Factor that the displacement is multiplied with
    i.offset_method : MenuSocket
        Input method for how to generate the displacement vector
    i.offset_vector : VectorSocket
        Displacement offset vector
    i.offset_distance : FloatSocket
        Distance of the displacement offset in normal direction
    i.substeps : IntegerSocket
        Number of steps to divide the full displacement into. Fields, including normal and position, are re-evaluated before each step.
    i.post_substep_process : ClosureSocket
        Geometry process to apply after each displacement step

    Outputs
    -------
    o.geometry : GeometrySocket
        Displaced geometry
    """

    _name = "Displace Geometry"
    _asset_name = "Displace Geometry"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry with points to displace"""
        selection: BooleanSocket
        """Selection of points that should be displaced"""
        strength: FloatSocket
        """Factor that the displacement is multiplied with"""
        offset_method: MenuSocket
        """Input method for how to generate the displacement vector"""
        offset_vector: VectorSocket
        """Displacement offset vector"""
        offset_distance: FloatSocket
        """Distance of the displacement offset in normal direction"""
        substeps: IntegerSocket
        """Number of steps to divide the full displacement into. Fields, including normal and position, are re-evaluated before each step."""
        post_substep_process: ClosureSocket
        """Geometry process to apply after each displacement step"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Displaced geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        selection: InputBoolean = True,
        strength: InputFloat = 1.0,
        offset_method: InputMenu | Literal["Normal", "Vector"] = "Normal",
        offset_vector: InputVector = None,
        offset_distance: InputFloat = 1.0,
        substeps: InputInteger = 1,
        post_substep_process: InputClosure = None,
    ):
        super().__init__(
            **{
                "Socket_0": geometry,
                "Socket_2": selection,
                "Socket_4": strength,
                "Socket_20": offset_method,
                "Socket_3": offset_vector,
                "Socket_6": offset_distance,
                "Socket_5": substeps,
                "Socket_19": post_substep_process,
            }
        )


class DisplaceHairCurves(AssetGeometryGroup):
    """
    Displace Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Input geometry (may include geometry other than curves)
    factor : InputFloat
        Factor to scale overall displacement
    shape : InputFloat
        Shape of the influence along curves (0 = constant, 0.5 = linear)
    object_space : InputObject
        Object used to define the displacement space
    displace_vector : InputVector
        Vector for displacement
    surface_normal : InputBoolean
        Surface Normal
    surface_input_type : InputMenu | Literal["Object", "Geometry"]
        Select the input type for the surface geometry.
    input_5 : InputGeometry
        Surface geometry used to sample the normal for displacement
    input_4 : InputObject
        Surface object used to sample the normal for displacement
    surface_uv_map : InputVector
        Surface UV map used to sample the normal for displacement
    surface_normal_distance : InputFloat
        Amount of displacemement along the surface normal

    Inputs
    ------
    i.geometry : GeometrySocket
        Input geometry (may include geometry other than curves)
    i.factor : FloatSocket
        Factor to scale overall displacement
    i.shape : FloatSocket
        Shape of the influence along curves (0 = constant, 0.5 = linear)
    i.object_space : ObjectSocket
        Object used to define the displacement space
    i.displace_vector : VectorSocket
        Vector for displacement
    i.surface_normal : BooleanSocket
        Surface Normal
    i.surface_input_type : MenuSocket
        Select the input type for the surface geometry.
    i.input_5 : GeometrySocket
        Surface geometry used to sample the normal for displacement
    i.input_4 : ObjectSocket
        Surface object used to sample the normal for displacement
    i.surface_uv_map : VectorSocket
        Surface UV map used to sample the normal for displacement
    i.surface_normal_distance : FloatSocket
        Amount of displacemement along the surface normal

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Displace Hair Curves"
    _asset_name = "Displace Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Input geometry (may include geometry other than curves)"""
        factor: FloatSocket
        """Factor to scale overall displacement"""
        shape: FloatSocket
        """Shape of the influence along curves (0 = constant, 0.5 = linear)"""
        object_space: ObjectSocket
        """Object used to define the displacement space"""
        displace_vector: VectorSocket
        """Vector for displacement"""
        surface_normal: BooleanSocket
        """Surface Normal"""
        surface_input_type: MenuSocket
        """Select the input type for the surface geometry."""
        input_5: GeometrySocket
        """Surface geometry used to sample the normal for displacement"""
        input_4: ObjectSocket
        """Surface object used to sample the normal for displacement"""
        surface_uv_map: VectorSocket
        """Surface UV map used to sample the normal for displacement"""
        surface_normal_distance: FloatSocket
        """Amount of displacemement along the surface normal"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        factor: InputFloat = 1.0,
        shape: InputFloat = 0.5,
        object_space: InputObject = None,
        displace_vector: InputVector = None,
        surface_normal: InputBoolean = False,
        surface_input_type: InputMenu | Literal["Object", "Geometry"] = "Object",
        input_5: InputGeometry = None,
        input_4: InputObject = None,
        surface_uv_map: InputVector = None,
        surface_normal_distance: InputFloat = 0.0,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_3": factor,
                "Input_8": shape,
                "Input_2": object_space,
                "Input_9": displace_vector,
                "Socket_2": surface_normal,
                "Socket_0": surface_input_type,
                "Input_5": input_5,
                "Input_4": input_4,
                "Input_6": surface_uv_map,
                "Input_7": surface_normal_distance,
            }
        )


class DuplicateHairCurves(AssetGeometryGroup):
    """
    Duplicate Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Input geometry (may include geometry other than curves)
    amount : InputInteger
        Amount of duplicates per curve
    viewport_amount : InputFloat
        Percentage of amount used for the viewport
    radius : InputFloat
        Radius in which the duplicate curves are offset from the guides
    distribution_shape : InputFloat
        Shape of distribution from center to the edge around the guide
    tip_roundness : InputFloat
        Offset of the curves to round the tip
    even_thickness : InputBoolean
        Keep an even thickness of the distribution of duplicates
    seed : InputInteger
        Random seed for the operation

    Inputs
    ------
    i.geometry : GeometrySocket
        Input geometry (may include geometry other than curves)
    i.amount : IntegerSocket
        Amount of duplicates per curve
    i.viewport_amount : FloatSocket
        Percentage of amount used for the viewport
    i.radius : FloatSocket
        Radius in which the duplicate curves are offset from the guides
    i.distribution_shape : FloatSocket
        Shape of distribution from center to the edge around the guide
    i.tip_roundness : FloatSocket
        Offset of the curves to round the tip
    i.even_thickness : BooleanSocket
        Keep an even thickness of the distribution of duplicates
    i.seed : IntegerSocket
        Random seed for the operation

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    o.guide_index : IntegerSocket
        Guide index map that was used for the operation
    """

    _name = "Duplicate Hair Curves"
    _asset_name = "Duplicate Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Input geometry (may include geometry other than curves)"""
        amount: IntegerSocket
        """Amount of duplicates per curve"""
        viewport_amount: FloatSocket
        """Percentage of amount used for the viewport"""
        radius: FloatSocket
        """Radius in which the duplicate curves are offset from the guides"""
        distribution_shape: FloatSocket
        """Shape of distribution from center to the edge around the guide"""
        tip_roundness: FloatSocket
        """Offset of the curves to round the tip"""
        even_thickness: BooleanSocket
        """Keep an even thickness of the distribution of duplicates"""
        seed: IntegerSocket
        """Random seed for the operation"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        guide_index: IntegerSocket
        """Guide index map that was used for the operation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        amount: InputInteger = 10,
        viewport_amount: InputFloat = 1.0,
        radius: InputFloat = 0.1,
        distribution_shape: InputFloat = 0.0,
        tip_roundness: InputFloat = 0.0,
        even_thickness: InputBoolean = False,
        seed: InputInteger = 0,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_2": amount,
                "Input_4": viewport_amount,
                "Input_5": radius,
                "Input_7": distribution_shape,
                "Input_8": tip_roundness,
                "Input_6": even_thickness,
                "Input_3": seed,
            }
        )


class EdgeLength(AssetGeometryGroup):
    """
    Edge Length

    Outputs
    -------
    o.length : FloatSocket
        Length
    """

    _name = "Edge Length"
    _asset_name = "Edge Length"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        pass

    class _Outputs(SocketAccessor):
        length: FloatSocket
        """Length"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self):
        super().__init__(**{})


class FaceCornerAngle(AssetGeometryGroup):
    """
    Face Corner Angle

    Outputs
    -------
    o.corner_angle : FloatSocket
        Angle between the next and previous edge of a face corner within the face
    o.bisector : VectorSocket
        Directional vector pointing central between next and previous edge of a face corner
    """

    _name = "Face Corner Angle"
    _asset_name = "Face Corner Angle"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        pass

    class _Outputs(SocketAccessor):
        corner_angle: FloatSocket
        """Angle between the next and previous edge of a face corner within the face"""
        bisector: VectorSocket
        """Directional vector pointing central between next and previous edge of a face corner"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self):
        super().__init__(**{})


class FrizzHairCurves(AssetGeometryGroup):
    """
    Frizz Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Input geometry (may include geometry other than curves)
    cumulative_offset : InputBoolean
        Apply offset cumulatively (previous points affect points after)
    factor : InputFloat
        Factor to blend overall effect
    distance : InputFloat
        Overall distance factor for the deformation
    shape : InputFloat
        Shape of the influence along curves (0 = constant, 0.5 = linear)
    seed : InputInteger
        Random seed for the operation
    preserve_length : InputBoolean
        Preserve each curve's length during deformation

    Inputs
    ------
    i.geometry : GeometrySocket
        Input geometry (may include geometry other than curves)
    i.cumulative_offset : BooleanSocket
        Apply offset cumulatively (previous points affect points after)
    i.factor : FloatSocket
        Factor to blend overall effect
    i.distance : FloatSocket
        Overall distance factor for the deformation
    i.shape : FloatSocket
        Shape of the influence along curves (0 = constant, 0.5 = linear)
    i.seed : IntegerSocket
        Random seed for the operation
    i.preserve_length : BooleanSocket
        Preserve each curve's length during deformation

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    o.offset_vector : VectorSocket
        Vector by which each point was offset during deformation
    """

    _name = "Frizz Hair Curves"
    _asset_name = "Frizz Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Input geometry (may include geometry other than curves)"""
        cumulative_offset: BooleanSocket
        """Apply offset cumulatively (previous points affect points after)"""
        factor: FloatSocket
        """Factor to blend overall effect"""
        distance: FloatSocket
        """Overall distance factor for the deformation"""
        shape: FloatSocket
        """Shape of the influence along curves (0 = constant, 0.5 = linear)"""
        seed: IntegerSocket
        """Random seed for the operation"""
        preserve_length: BooleanSocket
        """Preserve each curve's length during deformation"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        offset_vector: VectorSocket
        """Vector by which each point was offset during deformation"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        cumulative_offset: InputBoolean = True,
        factor: InputFloat = 1.0,
        distance: InputFloat = 0.01,
        shape: InputFloat = 0.5,
        seed: InputInteger = 0,
        preserve_length: InputBoolean = False,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_10": cumulative_offset,
                "Input_3": factor,
                "Input_11": distance,
                "Input_2": shape,
                "Input_8": seed,
                "Input_6": preserve_length,
            }
        )


class GenerateHairCurves(AssetGeometryGroup):
    """
    Generate Hair Curves

    Parameters
    ----------
    hair_surface : InputGeometry
        Surface geometry or hair geometry with existing surface attachment for reference
    surface_source : InputMenu | Literal["Attached", "Input", "Object"]
        Surface Source
    surface : InputObject
        Surface object for generation (needs matching transforms)
    surface_uv_map : InputVector
        Surface UV map used for attachment
    resting_surface : InputBoolean
        Use the surface's resting state to preserve stability under deformation
    attach_to_surface : InputBoolean
        Attach the generated hair curves to the surface geometry for dynamics
    hair_length : InputFloat
        Length of the generated hair curves
    hair_material : InputMaterial
        Material of the generated hair curves
    control_points : InputInteger
        Amount of control points of the generated hair curves
    distribution_method : InputMenu | Literal["Random", "Poisson Disk"]
        Use Poisson disk distribution method to keep a minimum distance
    density : InputFloat
        Surface density of generated hair curves
    density_mask : InputFloat
        Factor applied on the density for curve distribution
    mask_texture : InputImage
        Discard points based on a mask texture after distribution
    viewport_amount : InputFloat
        Factor applied on the density for the viewport
    seed : InputInteger
        Random seed for the operation

    Inputs
    ------
    i.hair_surface : GeometrySocket
        Surface geometry or hair geometry with existing surface attachment for reference
    i.surface_source : MenuSocket
        Surface Source
    i.surface : ObjectSocket
        Surface object for generation (needs matching transforms)
    i.surface_uv_map : VectorSocket
        Surface UV map used for attachment
    i.resting_surface : BooleanSocket
        Use the surface's resting state to preserve stability under deformation
    i.attach_to_surface : BooleanSocket
        Attach the generated hair curves to the surface geometry for dynamics
    i.hair_length : FloatSocket
        Length of the generated hair curves
    i.hair_material : MaterialSocket
        Material of the generated hair curves
    i.control_points : IntegerSocket
        Amount of control points of the generated hair curves
    i.distribution_method : MenuSocket
        Use Poisson disk distribution method to keep a minimum distance
    i.density : FloatSocket
        Surface density of generated hair curves
    i.density_mask : FloatSocket
        Factor applied on the density for curve distribution
    i.mask_texture : ImageSocket
        Discard points based on a mask texture after distribution
    i.viewport_amount : FloatSocket
        Factor applied on the density for the viewport
    i.seed : IntegerSocket
        Random seed for the operation

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    o.curves : GeometrySocket
        Curves
    o.surface_normal : VectorSocket
        Normal direction of the surface mesh at the attachment point
    """

    _name = "Generate Hair Curves"
    _asset_name = "Generate Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        hair_surface: GeometrySocket
        """Surface geometry or hair geometry with existing surface attachment for reference"""
        surface_source: MenuSocket
        """Surface Source"""
        surface: ObjectSocket
        """Surface object for generation (needs matching transforms)"""
        surface_uv_map: VectorSocket
        """Surface UV map used for attachment"""
        resting_surface: BooleanSocket
        """Use the surface's resting state to preserve stability under deformation"""
        attach_to_surface: BooleanSocket
        """Attach the generated hair curves to the surface geometry for dynamics"""
        hair_length: FloatSocket
        """Length of the generated hair curves"""
        hair_material: MaterialSocket
        """Material of the generated hair curves"""
        control_points: IntegerSocket
        """Amount of control points of the generated hair curves"""
        distribution_method: MenuSocket
        """Use Poisson disk distribution method to keep a minimum distance"""
        density: FloatSocket
        """Surface density of generated hair curves"""
        density_mask: FloatSocket
        """Factor applied on the density for curve distribution"""
        mask_texture: ImageSocket
        """Discard points based on a mask texture after distribution"""
        viewport_amount: FloatSocket
        """Factor applied on the density for the viewport"""
        seed: IntegerSocket
        """Random seed for the operation"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        curves: GeometrySocket
        """Curves"""
        surface_normal: VectorSocket
        """Normal direction of the surface mesh at the attachment point"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        hair_surface: InputGeometry = None,
        surface_source: InputMenu | Literal["Attached", "Input", "Object"] = "Attached",
        surface: InputObject = None,
        surface_uv_map: InputVector = None,
        resting_surface: InputBoolean = True,
        attach_to_surface: InputBoolean = True,
        hair_length: InputFloat = 1.0,
        hair_material: InputMaterial = None,
        control_points: InputInteger = 12,
        distribution_method: InputMenu | Literal["Random", "Poisson Disk"] = "Random",
        density: InputFloat = 10.0,
        density_mask: InputFloat = 1.0,
        mask_texture: InputImage = None,
        viewport_amount: InputFloat = 1.0,
        seed: InputInteger = 0,
    ):
        super().__init__(
            **{
                "Input_23": hair_surface,
                "Socket_3": surface_source,
                "Input_2": surface,
                "Input_18": surface_uv_map,
                "Input_12": resting_surface,
                "Socket_2": attach_to_surface,
                "Input_20": hair_length,
                "Input_22": hair_material,
                "Input_27": control_points,
                "Socket_1": distribution_method,
                "Input_15": density,
                "Input_14": density_mask,
                "Input_19": mask_texture,
                "Input_17": viewport_amount,
                "Input_16": seed,
            }
        )


class GeometryInput(AssetGeometryGroup):
    """
    Geometry Input

    Parameters
    ----------
    geometry : InputGeometry
        Geometry
    input_type : InputMenu | Literal["Object", "Collection"]
        How the geometry input should be exposed
    object : InputObject
        Object to use as the input geometry
    collection : InputCollection
        Collection to use as the input geometry
    relative_space : InputBoolean
        Transform the input relative to the main geometry
    as_instance : InputBoolean
        Input the geometry as an instance. (Further processing might require non-instance geometry).
    replace_original : InputBoolean
        Replace the original input geometry with the selected input geometry

    Inputs
    ------
    i.geometry : GeometrySocket
        Geometry
    i.input_type : MenuSocket
        How the geometry input should be exposed
    i.object : ObjectSocket
        Object to use as the input geometry
    i.collection : CollectionSocket
        Collection to use as the input geometry
    i.relative_space : BooleanSocket
        Transform the input relative to the main geometry
    i.as_instance : BooleanSocket
        Input the geometry as an instance. (Further processing might require non-instance geometry).
    i.replace_original : BooleanSocket
        Replace the original input geometry with the selected input geometry

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Geometry Input"
    _asset_name = "Geometry Input"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        input_type: MenuSocket
        """How the geometry input should be exposed"""
        object: ObjectSocket
        """Object to use as the input geometry"""
        collection: CollectionSocket
        """Collection to use as the input geometry"""
        relative_space: BooleanSocket
        """Transform the input relative to the main geometry"""
        as_instance: BooleanSocket
        """Input the geometry as an instance. (Further processing might require non-instance geometry)."""
        replace_original: BooleanSocket
        """Replace the original input geometry with the selected input geometry"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        input_type: InputMenu | Literal["Object", "Collection"] = "Object",
        object: InputObject = None,
        collection: InputCollection = None,
        relative_space: InputBoolean = False,
        as_instance: InputBoolean = True,
        replace_original: InputBoolean = False,
    ):
        super().__init__(
            **{
                "Socket_7": geometry,
                "Socket_6": input_type,
                "Socket_2": object,
                "Socket_3": collection,
                "Socket_4": relative_space,
                "Socket_5": as_instance,
                "Socket_1": replace_original,
            }
        )


class GeometryPrincipalComponents(AssetGeometryGroup):
    """
    Principal Component Analysis (PCA) of a the positions of points

    Parameters
    ----------
    geometry : InputGeometry
        Geometry to evaluate the given fields and store the resulting attributes on. All geometry types except volumes are supported
    position : InputVector
        Position

    Inputs
    ------
    i.geometry : GeometrySocket
        Geometry to evaluate the given fields and store the resulting attributes on. All geometry types except volumes are supported
    i.position : VectorSocket
        Position

    Outputs
    -------
    o.group_center : VectorSocket
        Group Center
    o.rotation : RotationSocket
        Rotation that defines the principal component basis
    o.principal_components : VectorSocket
        Variance of the data along each principal axis
    o.longest_axis : VectorSocket
        Axis along the most variance
    o.intermediate_axis : VectorSocket
        Axis completing a right-handed orthogonal basis with the longest and shortest axis
    o.shortest_axis : VectorSocket
        Axis along the least variance
    """

    _name = "Geometry Principal Components"
    _asset_name = "Geometry Principal Components"
    _library = BundledLibrary("principal_components.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry to evaluate the given fields and store the resulting attributes on. All geometry types except volumes are supported"""
        position: VectorSocket
        """Position"""

    class _Outputs(SocketAccessor):
        group_center: VectorSocket
        """Group Center"""
        rotation: RotationSocket
        """Rotation that defines the principal component basis"""
        principal_components: VectorSocket
        """Variance of the data along each principal axis"""
        longest_axis: VectorSocket
        """Axis along the most variance"""
        intermediate_axis: VectorSocket
        """Axis completing a right-handed orthogonal basis with the longest and shortest axis"""
        shortest_axis: VectorSocket
        """Axis along the least variance"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        position: InputVector = None,
    ):
        super().__init__(**{"Socket_11": geometry, "Socket_0": position})


class HairCurvesNoise(AssetGeometryGroup):
    """
    Hair Curves Noise

    Parameters
    ----------
    geometry : InputGeometry
        Geometry
    cumulative_offset : InputBoolean
        Apply offset cumulatively (previous points affect points after)
    factor : InputFloat
        Overall factor for the deformation
    distance : InputFloat
        Overall distance factor for the deformation
    shape : InputFloat
        Shape of amount along each curve (0 = constant, 0.5 = linear)
    scale : InputFloat
        Scale of the noise texture by root position
    scale_along_curve : InputFloat
        Scale of noise texture along each curve
    offset_per_curve : InputFloat
        Random offset of noise texture for each curve
    seed : InputInteger
        Seed value for randomization
    preserve_length : InputBoolean
        Preserve the length of the curves on a segment basis

    Inputs
    ------
    i.geometry : GeometrySocket
        Geometry
    i.cumulative_offset : BooleanSocket
        Apply offset cumulatively (previous points affect points after)
    i.factor : FloatSocket
        Overall factor for the deformation
    i.distance : FloatSocket
        Overall distance factor for the deformation
    i.shape : FloatSocket
        Shape of amount along each curve (0 = constant, 0.5 = linear)
    i.scale : FloatSocket
        Scale of the noise texture by root position
    i.scale_along_curve : FloatSocket
        Scale of noise texture along each curve
    i.offset_per_curve : FloatSocket
        Random offset of noise texture for each curve
    i.seed : IntegerSocket
        Seed value for randomization
    i.preserve_length : BooleanSocket
        Preserve the length of the curves on a segment basis

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    o.offset_vector : VectorSocket
        Offset Vector
    """

    _name = "Hair Curves Noise"
    _asset_name = "Hair Curves Noise"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        cumulative_offset: BooleanSocket
        """Apply offset cumulatively (previous points affect points after)"""
        factor: FloatSocket
        """Overall factor for the deformation"""
        distance: FloatSocket
        """Overall distance factor for the deformation"""
        shape: FloatSocket
        """Shape of amount along each curve (0 = constant, 0.5 = linear)"""
        scale: FloatSocket
        """Scale of the noise texture by root position"""
        scale_along_curve: FloatSocket
        """Scale of noise texture along each curve"""
        offset_per_curve: FloatSocket
        """Random offset of noise texture for each curve"""
        seed: IntegerSocket
        """Seed value for randomization"""
        preserve_length: BooleanSocket
        """Preserve the length of the curves on a segment basis"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        offset_vector: VectorSocket
        """Offset Vector"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        cumulative_offset: InputBoolean = True,
        factor: InputFloat = 1.0,
        distance: InputFloat = 0.01,
        shape: InputFloat = 0.5,
        scale: InputFloat = 1.0,
        scale_along_curve: InputFloat = 1.0,
        offset_per_curve: InputFloat = 0.0,
        seed: InputInteger = 0,
        preserve_length: InputBoolean = False,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_10": cumulative_offset,
                "Input_3": factor,
                "Input_14": distance,
                "Input_2": shape,
                "Input_11": scale,
                "Input_12": scale_along_curve,
                "Input_13": offset_per_curve,
                "Input_8": seed,
                "Input_6": preserve_length,
            }
        )


class HairDynamics(AssetGeometryGroup):
    """
    Simulate hair attached to a surface while taking effectors such as forces and colliders into account.

    Parameters
    ----------
    hair : InputGeometry
        Input hair curves.
    mode : InputMenu | Literal["Animation", "Physics (Experimental"]
        Either use proper simulation or just animation based on surface deformation.
    substeps : InputInteger
        Number of simulation steps per frame.
    constraint_steps : InputInteger
        Number of steps done to solve constraints in each substep.
    time_scale : InputFloat
        Multiplied to the delta time in each time step.
    simulation_to_world : InputMatrix
        Custom simulation space (by default, simulation space is world space).
    mass : InputFloat
        Mass assigned to each point in the simulation.
    friction : InputFloat
        Friction coefficient for each vertex.
    stretchiness : InputFloat
        Higher values make the hair more stretchy.
    bendiness : InputFloat
        Higher values allow the hair to bend more.
    root_bendiness : InputFloat
        Higher values allow the root points (which are attached to the surface) to rotate more.
    randomness : InputBoolean
        Add variation to the structural constraints.
    randomness_stretchiness : InputFloat
        How much to randomize the stretchiness.
    randomness_bendiness : InputFloat
        How much to randomize the bendiness.
    randomness_root_bendiness : InputFloat
        How much to randomize the root bendiness.
    linear : InputFloat
        Simulation stability increases with more linear damping.
    angular : InputFloat
        Simulation stability increases with more angular damping.
    surface_collision : InputBoolean
        Collide with the surface mesh the hair is attached to.
    deforming : InputBoolean
        The surface mesh is deforming.
    edge_contacts : InputBoolean
        Take edge contacts into account for more accurate collision avoidance.
    surface_friction : InputFloat
        Friction coefficient of the surface.
    socket_22 : InputBoolean
        Use gravity in the simulation.
    socket_24 : InputVector
        Direction and strength of the gravity.
    effectors_collection : InputCollection
        A collection containing effectors for the simulation. This includes e.g. forces, colliders and custom effectors.
    hair_tags : InputString
        Comma-separated list of tags which can be used to apply only a subset of effectors to this cloth.
    effectors : InputBundle
        Additional effectors for the simulation.

    Inputs
    ------
    i.hair : GeometrySocket
        Input hair curves.
    i.mode : MenuSocket
        Either use proper simulation or just animation based on surface deformation.
    i.substeps : IntegerSocket
        Number of simulation steps per frame.
    i.constraint_steps : IntegerSocket
        Number of steps done to solve constraints in each substep.
    i.time_scale : FloatSocket
        Multiplied to the delta time in each time step.
    i.simulation_to_world : MatrixSocket
        Custom simulation space (by default, simulation space is world space).
    i.mass : FloatSocket
        Mass assigned to each point in the simulation.
    i.friction : FloatSocket
        Friction coefficient for each vertex.
    i.stretchiness : FloatSocket
        Higher values make the hair more stretchy.
    i.bendiness : FloatSocket
        Higher values allow the hair to bend more.
    i.root_bendiness : FloatSocket
        Higher values allow the root points (which are attached to the surface) to rotate more.
    i.randomness : BooleanSocket
        Add variation to the structural constraints.
    i.randomness_stretchiness : FloatSocket
        How much to randomize the stretchiness.
    i.randomness_bendiness : FloatSocket
        How much to randomize the bendiness.
    i.randomness_root_bendiness : FloatSocket
        How much to randomize the root bendiness.
    i.linear : FloatSocket
        Simulation stability increases with more linear damping.
    i.angular : FloatSocket
        Simulation stability increases with more angular damping.
    i.surface_collision : BooleanSocket
        Collide with the surface mesh the hair is attached to.
    i.deforming : BooleanSocket
        The surface mesh is deforming.
    i.edge_contacts : BooleanSocket
        Take edge contacts into account for more accurate collision avoidance.
    i.surface_friction : FloatSocket
        Friction coefficient of the surface.
    i.socket_22 : BooleanSocket
        Use gravity in the simulation.
    i.socket_24 : VectorSocket
        Direction and strength of the gravity.
    i.effectors_collection : CollectionSocket
        A collection containing effectors for the simulation. This includes e.g. forces, colliders and custom effectors.
    i.hair_tags : StringSocket
        Comma-separated list of tags which can be used to apply only a subset of effectors to this cloth.
    i.effectors : BundleSocket
        Additional effectors for the simulation.

    Outputs
    -------
    o.hair : GeometrySocket
        The deformed hair curves.
    o.residual_error : FloatSocket
        Average relative constraint error. 1 is good, higher is worse.
    """

    _name = "Hair Dynamics"
    _asset_name = "Hair Dynamics"
    _library = BundledLibrary("geometry_nodes_dynamics_assets.blend")

    class _Inputs(SocketAccessor):
        hair: GeometrySocket
        """Input hair curves."""
        mode: MenuSocket
        """Either use proper simulation or just animation based on surface deformation."""
        substeps: IntegerSocket
        """Number of simulation steps per frame."""
        constraint_steps: IntegerSocket
        """Number of steps done to solve constraints in each substep."""
        time_scale: FloatSocket
        """Multiplied to the delta time in each time step."""
        simulation_to_world: MatrixSocket
        """Custom simulation space (by default, simulation space is world space)."""
        mass: FloatSocket
        """Mass assigned to each point in the simulation."""
        friction: FloatSocket
        """Friction coefficient for each vertex."""
        stretchiness: FloatSocket
        """Higher values make the hair more stretchy."""
        bendiness: FloatSocket
        """Higher values allow the hair to bend more."""
        root_bendiness: FloatSocket
        """Higher values allow the root points (which are attached to the surface) to rotate more."""
        randomness: BooleanSocket
        """Add variation to the structural constraints."""
        randomness_stretchiness: FloatSocket
        """How much to randomize the stretchiness."""
        randomness_bendiness: FloatSocket
        """How much to randomize the bendiness."""
        randomness_root_bendiness: FloatSocket
        """How much to randomize the root bendiness."""
        linear: FloatSocket
        """Simulation stability increases with more linear damping."""
        angular: FloatSocket
        """Simulation stability increases with more angular damping."""
        surface_collision: BooleanSocket
        """Collide with the surface mesh the hair is attached to."""
        deforming: BooleanSocket
        """The surface mesh is deforming."""
        edge_contacts: BooleanSocket
        """Take edge contacts into account for more accurate collision avoidance."""
        surface_friction: FloatSocket
        """Friction coefficient of the surface."""
        socket_22: BooleanSocket
        """Use gravity in the simulation."""
        socket_24: VectorSocket
        """Direction and strength of the gravity."""
        effectors_collection: CollectionSocket
        """A collection containing effectors for the simulation. This includes e.g. forces, colliders and custom effectors."""
        hair_tags: StringSocket
        """Comma-separated list of tags which can be used to apply only a subset of effectors to this cloth."""
        effectors: BundleSocket
        """Additional effectors for the simulation."""

    class _Outputs(SocketAccessor):
        hair: GeometrySocket
        """The deformed hair curves."""
        residual_error: FloatSocket
        """Average relative constraint error. 1 is good, higher is worse."""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        hair: InputGeometry = None,
        mode: InputMenu | Literal["Animation", "Physics (Experimental"] = "Animation",
        substeps: InputInteger = 10,
        constraint_steps: InputInteger = 15,
        time_scale: InputFloat = 1.0,
        simulation_to_world: InputMatrix = None,
        mass: InputFloat = 0.01,
        friction: InputFloat = 0.1,
        stretchiness: InputFloat = 0.0,
        bendiness: InputFloat = 0.5,
        root_bendiness: InputFloat = 0.2,
        randomness: InputBoolean = False,
        randomness_stretchiness: InputFloat = 0.5,
        randomness_bendiness: InputFloat = 0.5,
        randomness_root_bendiness: InputFloat = 0.5,
        linear: InputFloat = 3.0,
        angular: InputFloat = 3.0,
        surface_collision: InputBoolean = False,
        deforming: InputBoolean = True,
        edge_contacts: InputBoolean = False,
        surface_friction: InputFloat = 0.2,
        socket_22: InputBoolean = True,
        socket_24: InputVector = None,
        effectors_collection: InputCollection = None,
        hair_tags: InputString = "",
        effectors: InputBundle = None,
    ):
        super().__init__(
            **{
                "Socket_3": hair,
                "Socket_44": mode,
                "Socket_6": substeps,
                "Socket_10": constraint_steps,
                "Socket_45": time_scale,
                "Socket_37": simulation_to_world,
                "Socket_36": mass,
                "Socket_34": friction,
                "Socket_19": stretchiness,
                "Socket_20": bendiness,
                "Socket_35": root_bendiness,
                "Socket_43": randomness,
                "Socket_41": randomness_stretchiness,
                "Socket_42": randomness_bendiness,
                "Socket_39": randomness_root_bendiness,
                "Socket_13": linear,
                "Socket_14": angular,
                "Socket_15": surface_collision,
                "Socket_18": deforming,
                "Socket_38": edge_contacts,
                "Socket_17": surface_friction,
                "Socket_22": socket_22,
                "Socket_24": socket_24,
                "Socket_27": effectors_collection,
                "Socket_32": hair_tags,
                "Socket_11": effectors,
            }
        )


class InstanceOnElements(AssetGeometryGroup):
    """
    Instance on Elements

    Parameters
    ----------
    geometry : InputGeometry
        Geometry
    instance_on : InputMenu | Literal["Points", "Edges", "Faces", "Corners"]
        Geometry element type to instance on
    mask : InputFloat
        Specify which elements to use for instancing. (Floating point values result in a random selection.)
    input_type : InputMenu | Literal["Data-Block", "Geometry"]
        How the instance geometry input should be exposed
    instance_type : InputMenu | Literal["Object", "Collection"]
        How the instance geometry data-block should be exposed
    collection : InputCollection
        Instance geometry collection
    object : InputObject
        Instance geometry object
    instance : InputGeometry
        Instance geometry input
    realize_instances : InputBoolean
        Turn the output into a single geometry rather than instances (required by many other modifiers)
    keep_surface : InputBoolean
        Keep the original input geometry and join it with the instance geometry
    seed : InputInteger
        Base value to control random variation in a reproducible way
    pick_instance : InputBoolean
        Choose child instances for each element instead of instancing the entire geometry
    reset_transform : InputBoolean
        Reset the transforms of each individual child instance
    socket_13 : InputMenu | Literal["Random", "Sequence", "Input"]
        Method how the child instance is chosen per element
    socket_15 : InputInteger
        Which child instance to pick per element by index
    surface_offset : InputFloat
        Distance to offset each instance along the normal of the input geometry
    align_rotation : InputBoolean
        Rotate instances based on the shape of the input geometry
    scale : InputVector
        Scale the instances on each local axis
    scale_by_face_area : InputBoolean
        Scale the instances based on the face area of the input geometry
    scale_by_face_area_multiplier : InputFloat
        Multiply the instance scale with a factor to calibrate the considered face area
    corner_offset_method : InputMenu | Literal["Face Center", "Corner Center"]
        Method to define the direction of the offset along the corner
    corner_offset_factor : InputFloat
        Move the instances towards the face center
    corner_offset_distance : InputFloat
        Distance to offset the instances from the face corner
    even_edge_distance : InputBoolean
        Adjust the offset distance to keep an even perpendicular distance to edges

    Inputs
    ------
    i.geometry : GeometrySocket
        Geometry
    i.instance_on : MenuSocket
        Geometry element type to instance on
    i.mask : FloatSocket
        Specify which elements to use for instancing. (Floating point values result in a random selection.)
    i.input_type : MenuSocket
        How the instance geometry input should be exposed
    i.instance_type : MenuSocket
        How the instance geometry data-block should be exposed
    i.collection : CollectionSocket
        Instance geometry collection
    i.object : ObjectSocket
        Instance geometry object
    i.instance : GeometrySocket
        Instance geometry input
    i.realize_instances : BooleanSocket
        Turn the output into a single geometry rather than instances (required by many other modifiers)
    i.keep_surface : BooleanSocket
        Keep the original input geometry and join it with the instance geometry
    i.seed : IntegerSocket
        Base value to control random variation in a reproducible way
    i.pick_instance : BooleanSocket
        Choose child instances for each element instead of instancing the entire geometry
    i.reset_transform : BooleanSocket
        Reset the transforms of each individual child instance
    i.socket_13 : MenuSocket
        Method how the child instance is chosen per element
    i.socket_15 : IntegerSocket
        Which child instance to pick per element by index
    i.surface_offset : FloatSocket
        Distance to offset each instance along the normal of the input geometry
    i.align_rotation : BooleanSocket
        Rotate instances based on the shape of the input geometry
    i.scale : VectorSocket
        Scale the instances on each local axis
    i.scale_by_face_area : BooleanSocket
        Scale the instances based on the face area of the input geometry
    i.scale_by_face_area_multiplier : FloatSocket
        Multiply the instance scale with a factor to calibrate the considered face area
    i.corner_offset_method : MenuSocket
        Method to define the direction of the offset along the corner
    i.corner_offset_factor : FloatSocket
        Move the instances towards the face center
    i.corner_offset_distance : FloatSocket
        Distance to offset the instances from the face corner
    i.even_edge_distance : BooleanSocket
        Adjust the offset distance to keep an even perpendicular distance to edges

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Instance on Elements"
    _asset_name = "Instance on Elements"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        instance_on: MenuSocket
        """Geometry element type to instance on"""
        mask: FloatSocket
        """Specify which elements to use for instancing. (Floating point values result in a random selection.)"""
        input_type: MenuSocket
        """How the instance geometry input should be exposed"""
        instance_type: MenuSocket
        """How the instance geometry data-block should be exposed"""
        collection: CollectionSocket
        """Instance geometry collection"""
        object: ObjectSocket
        """Instance geometry object"""
        instance: GeometrySocket
        """Instance geometry input"""
        realize_instances: BooleanSocket
        """Turn the output into a single geometry rather than instances (required by many other modifiers)"""
        keep_surface: BooleanSocket
        """Keep the original input geometry and join it with the instance geometry"""
        seed: IntegerSocket
        """Base value to control random variation in a reproducible way"""
        pick_instance: BooleanSocket
        """Choose child instances for each element instead of instancing the entire geometry"""
        reset_transform: BooleanSocket
        """Reset the transforms of each individual child instance"""
        socket_13: MenuSocket
        """Method how the child instance is chosen per element"""
        socket_15: IntegerSocket
        """Which child instance to pick per element by index"""
        surface_offset: FloatSocket
        """Distance to offset each instance along the normal of the input geometry"""
        align_rotation: BooleanSocket
        """Rotate instances based on the shape of the input geometry"""
        scale: VectorSocket
        """Scale the instances on each local axis"""
        scale_by_face_area: BooleanSocket
        """Scale the instances based on the face area of the input geometry"""
        scale_by_face_area_multiplier: FloatSocket
        """Multiply the instance scale with a factor to calibrate the considered face area"""
        corner_offset_method: MenuSocket
        """Method to define the direction of the offset along the corner"""
        corner_offset_factor: FloatSocket
        """Move the instances towards the face center"""
        corner_offset_distance: FloatSocket
        """Distance to offset the instances from the face corner"""
        even_edge_distance: BooleanSocket
        """Adjust the offset distance to keep an even perpendicular distance to edges"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        instance_on: InputMenu
        | Literal["Points", "Edges", "Faces", "Corners"] = "Points",
        mask: InputFloat = 1.0,
        input_type: InputMenu | Literal["Data-Block", "Geometry"] = "Data-Block",
        instance_type: InputMenu | Literal["Object", "Collection"] = "Object",
        collection: InputCollection = None,
        object: InputObject = None,
        instance: InputGeometry = None,
        realize_instances: InputBoolean = False,
        keep_surface: InputBoolean = True,
        seed: InputInteger = 0,
        pick_instance: InputBoolean = False,
        reset_transform: InputBoolean = True,
        socket_13: InputMenu | Literal["Random", "Sequence", "Input"] = "Random",
        socket_15: InputInteger = 0,
        surface_offset: InputFloat = 0.0,
        align_rotation: InputBoolean = True,
        scale: InputVector = None,
        scale_by_face_area: InputBoolean = False,
        scale_by_face_area_multiplier: InputFloat = 1.0,
        corner_offset_method: InputMenu
        | Literal["Face Center", "Corner Center"] = "Face Center",
        corner_offset_factor: InputFloat = 0.1,
        corner_offset_distance: InputFloat = 0.1,
        even_edge_distance: InputBoolean = True,
    ):
        super().__init__(
            **{
                "Socket_0": geometry,
                "Socket_5": instance_on,
                "Socket_16": mask,
                "Socket_20": input_type,
                "Socket_9": instance_type,
                "Socket_10": collection,
                "Socket_2": object,
                "Socket_21": instance,
                "Socket_17": realize_instances,
                "Socket_18": keep_surface,
                "Socket_14": seed,
                "Socket_22": pick_instance,
                "Socket_29": reset_transform,
                "Socket_13": socket_13,
                "Socket_15": socket_15,
                "Socket_6": surface_offset,
                "Socket_7": align_rotation,
                "Socket_4": scale,
                "Socket_11": scale_by_face_area,
                "Socket_12": scale_by_face_area_multiplier,
                "Socket_24": corner_offset_method,
                "Socket_19": corner_offset_factor,
                "Socket_25": corner_offset_distance,
                "Socket_26": even_edge_distance,
            }
        )


class InterpolateHairCurves(AssetGeometryGroup):
    """
    Interpolate Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Input geometry (may include geometry other than curves)
    resting_surface : InputBoolean
        Use the surface's resting state to preserve stability under deformation
    follow_surface_normal : InputBoolean
        Align the interpolated curves to the surface normal
    part_by_mesh_islands : InputBoolean
        Use mesh islands of the surface geometry for parting
    interpolation_guides : InputInteger
        Amount of guides to be used for interpolation per curve
    distance_to_guides : InputFloat
        Distance around each guide to spawn interpolated curves
    distribution_method : InputMenu | Literal["Random", "Poisson Disk"]
        Distribution Method
    density : InputFloat
        Surface density of generated hair curves
    density_mask : InputFloat
        Factor applied on the density for curve distribution
    mask_texture : InputImage
        Discard points based on a mask texture after distribution
    viewport_amount : InputFloat
        Factor applied on the density for the viewport
    seed : InputInteger
        Random seed for the operation

    Inputs
    ------
    i.geometry : GeometrySocket
        Input geometry (may include geometry other than curves)
    i.resting_surface : BooleanSocket
        Use the surface's resting state to preserve stability under deformation
    i.follow_surface_normal : BooleanSocket
        Align the interpolated curves to the surface normal
    i.part_by_mesh_islands : BooleanSocket
        Use mesh islands of the surface geometry for parting
    i.interpolation_guides : IntegerSocket
        Amount of guides to be used for interpolation per curve
    i.distance_to_guides : FloatSocket
        Distance around each guide to spawn interpolated curves
    i.distribution_method : MenuSocket
        Distribution Method
    i.density : FloatSocket
        Surface density of generated hair curves
    i.density_mask : FloatSocket
        Factor applied on the density for curve distribution
    i.mask_texture : ImageSocket
        Discard points based on a mask texture after distribution
    i.viewport_amount : FloatSocket
        Factor applied on the density for the viewport
    i.seed : IntegerSocket
        Random seed for the operation

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    o.guide_index : IntegerSocket
        Index of the main guide curve per curve
    o.surface_normal : VectorSocket
        Normal direction of the surface mesh at the attachment point
    """

    _name = "Interpolate Hair Curves"
    _asset_name = "Interpolate Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Input geometry (may include geometry other than curves)"""
        resting_surface: BooleanSocket
        """Use the surface's resting state to preserve stability under deformation"""
        follow_surface_normal: BooleanSocket
        """Align the interpolated curves to the surface normal"""
        part_by_mesh_islands: BooleanSocket
        """Use mesh islands of the surface geometry for parting"""
        interpolation_guides: IntegerSocket
        """Amount of guides to be used for interpolation per curve"""
        distance_to_guides: FloatSocket
        """Distance around each guide to spawn interpolated curves"""
        distribution_method: MenuSocket
        """Distribution Method"""
        density: FloatSocket
        """Surface density of generated hair curves"""
        density_mask: FloatSocket
        """Factor applied on the density for curve distribution"""
        mask_texture: ImageSocket
        """Discard points based on a mask texture after distribution"""
        viewport_amount: FloatSocket
        """Factor applied on the density for the viewport"""
        seed: IntegerSocket
        """Random seed for the operation"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        guide_index: IntegerSocket
        """Index of the main guide curve per curve"""
        surface_normal: VectorSocket
        """Normal direction of the surface mesh at the attachment point"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        resting_surface: InputBoolean = True,
        follow_surface_normal: InputBoolean = False,
        part_by_mesh_islands: InputBoolean = True,
        interpolation_guides: InputInteger = 4,
        distance_to_guides: InputFloat = 0.0,
        distribution_method: InputMenu | Literal["Random", "Poisson Disk"] = "Random",
        density: InputFloat = 10.0,
        density_mask: InputFloat = 1.0,
        mask_texture: InputImage = None,
        viewport_amount: InputFloat = 1.0,
        seed: InputInteger = 0,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_12": resting_surface,
                "Input_24": follow_surface_normal,
                "Input_26": part_by_mesh_islands,
                "Input_10": interpolation_guides,
                "Input_28": distance_to_guides,
                "Socket_2": distribution_method,
                "Input_15": density,
                "Input_14": density_mask,
                "Input_19": mask_texture,
                "Input_17": viewport_amount,
                "Input_16": seed,
            }
        )


class IsEdgeBoundary(AssetGeometryGroup):
    """
    Is Edge Boundary

    Outputs
    -------
    o.is_edge_boundary : BooleanSocket
        Selection of edges that are part of the boundary of a mesh surface
    """

    _name = "Is Edge Boundary"
    _asset_name = "Is Edge Boundary"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        pass

    class _Outputs(SocketAccessor):
        is_edge_boundary: BooleanSocket
        """Selection of edges that are part of the boundary of a mesh surface"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self):
        super().__init__(**{})


class IsEdgeLoose(AssetGeometryGroup):
    """
    Is Edge Loose

    Outputs
    -------
    o.is_edge_loose : BooleanSocket
        Selection of edges that are not connected to a face
    """

    _name = "Is Edge Loose"
    _asset_name = "Is Edge Loose"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        pass

    class _Outputs(SocketAccessor):
        is_edge_loose: BooleanSocket
        """Selection of edges that are not connected to a face"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self):
        super().__init__(**{})


class IsEdgeManifold(AssetGeometryGroup):
    """
    Is Edge Manifold

    Outputs
    -------
    o.is_edge_manifold : BooleanSocket
        Selection of edges that connect two faces of a mesh surface
    """

    _name = "Is Edge Manifold"
    _asset_name = "Is Edge Manifold"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        pass

    class _Outputs(SocketAccessor):
        is_edge_manifold: BooleanSocket
        """Selection of edges that connect two faces of a mesh surface"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(self):
        super().__init__(**{})


class IsUVSplit(AssetGeometryGroup):
    """
    Is UV Split

    Parameters
    ----------
    uv_map : InputVector
        Vectors to compare between connected face corners of an edge for differences. (Supports 3D vectors.)

    Inputs
    ------
    i.uv_map : VectorSocket
        Vectors to compare between connected face corners of an edge for differences. (Supports 3D vectors.)

    Outputs
    -------
    o.is_uv_split : BooleanSocket
        Selection of edges that signify a discontinuity of the input vectors
    """

    _name = "Is UV Split"
    _asset_name = "Is UV Split"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        uv_map: VectorSocket
        """Vectors to compare between connected face corners of an edge for differences. (Supports 3D vectors.)"""

    class _Outputs(SocketAccessor):
        is_uv_split: BooleanSocket
        """Selection of edges that signify a discontinuity of the input vectors"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        uv_map: InputVector = None,
    ):
        super().__init__(**{"Socket_0": uv_map})


class NormalSelection(AssetGeometryGroup):
    """
    Normal Selection

    Parameters
    ----------
    direction : InputVector
        Target direction to compare the normal to
    threshold : InputFloat
        Maximum angle between normal and target to include in the selection

    Inputs
    ------
    i.direction : VectorSocket
        Target direction to compare the normal to
    i.threshold : FloatSocket
        Maximum angle between normal and target to include in the selection

    Outputs
    -------
    o.selection : BooleanSocket
        Selection of elements with normals matching a target direction. (The normal is evaluated on the same domain as this selection output.)
    """

    _name = "Normal Selection"
    _asset_name = "Normal Selection"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        direction: VectorSocket
        """Target direction to compare the normal to"""
        threshold: FloatSocket
        """Maximum angle between normal and target to include in the selection"""

    class _Outputs(SocketAccessor):
        selection: BooleanSocket
        """Selection of elements with normals matching a target direction. (The normal is evaluated on the same domain as this selection output.)"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        direction: InputVector = None,
        threshold: InputFloat = 0.087266,
    ):
        super().__init__(**{"Socket_1": direction, "Socket_3": threshold})


class PrincipalComponents(AssetGeometryGroup):
    """
    Principal Component Analysis (PCA) of a vector field

    Parameters
    ----------
    position : InputVector
        Position
    group_id : InputInteger
        An index used to group values together for multiple separate operations

    Inputs
    ------
    i.position : VectorSocket
        Position
    i.group_id : IntegerSocket
        An index used to group values together for multiple separate operations

    Outputs
    -------
    o.group_center : VectorSocket
        Group Center
    o.rotation : RotationSocket
        Rotation that defines the principal component basis
    o.principal_components : VectorSocket
        Variance of the data along each principal axis
    o.longest_axis : VectorSocket
        Axis along the most variance
    o.intermediate_axis : VectorSocket
        Axis completing a right-handed orthogonal basis with the longest and shortest axis
    o.shortest_axis : VectorSocket
        Axis along the least variance
    """

    _name = "Principal Components"
    _asset_name = "Principal Components"
    _library = BundledLibrary("principal_components.blend")

    class _Inputs(SocketAccessor):
        position: VectorSocket
        """Position"""
        group_id: IntegerSocket
        """An index used to group values together for multiple separate operations"""

    class _Outputs(SocketAccessor):
        group_center: VectorSocket
        """Group Center"""
        rotation: RotationSocket
        """Rotation that defines the principal component basis"""
        principal_components: VectorSocket
        """Variance of the data along each principal axis"""
        longest_axis: VectorSocket
        """Axis along the most variance"""
        intermediate_axis: VectorSocket
        """Axis completing a right-handed orthogonal basis with the longest and shortest axis"""
        shortest_axis: VectorSocket
        """Axis along the least variance"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        position: InputVector = None,
        group_id: InputInteger = 0,
    ):
        super().__init__(**{"Socket_0": position, "Socket_3": group_id})


class ProjectWithDepth(AssetGeometryGroup):
    """
    Project with Depth

    Parameters
    ----------
    normalized : InputVector
        Normalized
    depth : InputFloat
        Depth
    projection : InputMatrix
        Projection
    transform : InputMatrix
        Transform
    clip_start : InputFloat
        Clip Start
    clip_end : InputFloat
        Clip End

    Inputs
    ------
    i.normalized : VectorSocket
        Normalized
    i.depth : FloatSocket
        Depth
    i.projection : MatrixSocket
        Projection
    i.transform : MatrixSocket
        Transform
    i.clip_start : FloatSocket
        Clip Start
    i.clip_end : FloatSocket
        Clip End

    Outputs
    -------
    o.vector : VectorSocket
        Vector
    """

    _name = "Project with Depth"
    _asset_name = "Project with Depth"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        normalized: VectorSocket
        """Normalized"""
        depth: FloatSocket
        """Depth"""
        projection: MatrixSocket
        """Projection"""
        transform: MatrixSocket
        """Transform"""
        clip_start: FloatSocket
        """Clip Start"""
        clip_end: FloatSocket
        """Clip End"""

    class _Outputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        normalized: InputVector = None,
        depth: InputFloat = 1.0,
        projection: InputMatrix = None,
        transform: InputMatrix = None,
        clip_start: InputFloat = 0.1,
        clip_end: InputFloat = 100.0,
    ):
        super().__init__(
            **{
                "Socket_3": normalized,
                "Socket_2": depth,
                "Socket_5": projection,
                "Socket_6": transform,
                "Socket_0": clip_start,
                "Socket_1": clip_end,
            }
        )


class RandomRotation(AssetGeometryGroup):
    """
    Random Rotation

    Parameters
    ----------
    min_zenith : InputFloat
        Lower limit of the tilt away from the +Z direction
    max_zenith : InputFloat
        Upper limit of the tilt away from the +Z direction
    id : InputInteger
        Identifier per element used for randomization
    seed : InputInteger
        Base value to control random variation in a reproducible way

    Inputs
    ------
    i.min_zenith : FloatSocket
        Lower limit of the tilt away from the +Z direction
    i.max_zenith : FloatSocket
        Upper limit of the tilt away from the +Z direction
    i.id : IntegerSocket
        Identifier per element used for randomization
    i.seed : IntegerSocket
        Base value to control random variation in a reproducible way

    Outputs
    -------
    o.rotation : RotationSocket
        Random rotations resulting in uniformly distributed directions. Rotation around the Z axis is fully random.
    """

    _name = "Random Rotation"
    _asset_name = "Random Rotation"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        min_zenith: FloatSocket
        """Lower limit of the tilt away from the +Z direction"""
        max_zenith: FloatSocket
        """Upper limit of the tilt away from the +Z direction"""
        id: IntegerSocket
        """Identifier per element used for randomization"""
        seed: IntegerSocket
        """Base value to control random variation in a reproducible way"""

    class _Outputs(SocketAccessor):
        rotation: RotationSocket
        """Random rotations resulting in uniformly distributed directions. Rotation around the Z axis is fully random."""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        min_zenith: InputFloat = 0.0,
        max_zenith: InputFloat = 3.141593,
        id: InputInteger = 0,
        seed: InputInteger = 0,
    ):
        super().__init__(
            **{
                "Socket_3": min_zenith,
                "Socket_4": max_zenith,
                "Socket_0": id,
                "Socket_1": seed,
            }
        )


class RandomizeTransforms(AssetGeometryGroup):
    """
    Randomize Transforms

    Parameters
    ----------
    instances : InputGeometry
        Instances to rotate individually
    selection : InputBoolean
        Selection of instances to randomize
    local_space : InputBoolean
        Randomize instance transforms in their individual local space
    offset : InputVector
        Offset the instances randomly
    rotation : InputVector
        Rotate the instances randomly
    scale_axes : InputMenu | Literal["Uniform", "Axes"]
        Whether to apply random scale uniformly or per axis
    socket_4 : InputVector
        Scale the instances randomly per axis
    socket_8 : InputFloat
        Scale the instances randomly
    flipping : InputVector
        Flip a fraction of instances along individual axes
    seed : InputInteger
        Base value to control random variation in a reproducible way

    Inputs
    ------
    i.instances : GeometrySocket
        Instances to rotate individually
    i.selection : BooleanSocket
        Selection of instances to randomize
    i.local_space : BooleanSocket
        Randomize instance transforms in their individual local space
    i.offset : VectorSocket
        Offset the instances randomly
    i.rotation : VectorSocket
        Rotate the instances randomly
    i.scale_axes : MenuSocket
        Whether to apply random scale uniformly or per axis
    i.socket_4 : VectorSocket
        Scale the instances randomly per axis
    i.socket_8 : FloatSocket
        Scale the instances randomly
    i.flipping : VectorSocket
        Flip a fraction of instances along individual axes
    i.seed : IntegerSocket
        Base value to control random variation in a reproducible way

    Outputs
    -------
    o.instances : GeometrySocket
        Instances
    """

    _name = "Randomize Transforms"
    _asset_name = "Randomize Transforms"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        instances: GeometrySocket
        """Instances to rotate individually"""
        selection: BooleanSocket
        """Selection of instances to randomize"""
        local_space: BooleanSocket
        """Randomize instance transforms in their individual local space"""
        offset: VectorSocket
        """Offset the instances randomly"""
        rotation: VectorSocket
        """Rotate the instances randomly"""
        scale_axes: MenuSocket
        """Whether to apply random scale uniformly or per axis"""
        socket_4: VectorSocket
        """Scale the instances randomly per axis"""
        socket_8: FloatSocket
        """Scale the instances randomly"""
        flipping: VectorSocket
        """Flip a fraction of instances along individual axes"""
        seed: IntegerSocket
        """Base value to control random variation in a reproducible way"""

    class _Outputs(SocketAccessor):
        instances: GeometrySocket
        """Instances"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        instances: InputGeometry = None,
        selection: InputBoolean = True,
        local_space: InputBoolean = True,
        offset: InputVector = None,
        rotation: InputVector = None,
        scale_axes: InputMenu | Literal["Uniform", "Axes"] = "Uniform",
        socket_4: InputVector = None,
        socket_8: InputFloat = 0.0,
        flipping: InputVector = None,
        seed: InputInteger = 0,
    ):
        super().__init__(
            **{
                "Socket_0": instances,
                "Socket_2": selection,
                "Socket_10": local_space,
                "Socket_6": offset,
                "Socket_3": rotation,
                "Socket_7": scale_axes,
                "Socket_4": socket_4,
                "Socket_8": socket_8,
                "Socket_9": flipping,
                "Socket_5": seed,
            }
        )


class RedistributeCurvePoints(AssetGeometryGroup):
    """
    Redistribute Curve Points

    Parameters
    ----------
    curves : InputGeometry
        Curves
    factor : InputFloat
        Factor to blend overall effect
    feature_awareness : InputBoolean
        Use simple feature awareness to keep feature definition

    Inputs
    ------
    i.curves : GeometrySocket
        Curves
    i.factor : FloatSocket
        Factor to blend overall effect
    i.feature_awareness : BooleanSocket
        Use simple feature awareness to keep feature definition

    Outputs
    -------
    o.curves : GeometrySocket
        Curves
    """

    _name = "Redistribute Curve Points"
    _asset_name = "Redistribute Curve Points"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        curves: GeometrySocket
        """Curves"""
        factor: FloatSocket
        """Factor to blend overall effect"""
        feature_awareness: BooleanSocket
        """Use simple feature awareness to keep feature definition"""

    class _Outputs(SocketAccessor):
        curves: GeometrySocket
        """Curves"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        curves: InputGeometry = None,
        factor: InputFloat = 1.0,
        feature_awareness: InputBoolean = False,
    ):
        super().__init__(
            **{"Input_0": curves, "Input_2": factor, "Input_3": feature_awareness}
        )


class RestoreCurveSegmentLength(AssetGeometryGroup):
    """
    Restore Curve Segment Length

    Parameters
    ----------
    curves : InputGeometry
        Curves
    selection : InputBoolean
        Only affect selected elements
    factor : InputFloat
        Factor to blend overall effect
    reference_position : InputVector
        Reference position before deformation
    pin_at_parameter : InputFloat
        Pin each curve at a certain point for the operation

    Inputs
    ------
    i.curves : GeometrySocket
        Curves
    i.selection : BooleanSocket
        Only affect selected elements
    i.factor : FloatSocket
        Factor to blend overall effect
    i.reference_position : VectorSocket
        Reference position before deformation
    i.pin_at_parameter : FloatSocket
        Pin each curve at a certain point for the operation

    Outputs
    -------
    o.curves : GeometrySocket
        Curves
    """

    _name = "Restore Curve Segment Length"
    _asset_name = "Restore Curve Segment Length"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        curves: GeometrySocket
        """Curves"""
        selection: BooleanSocket
        """Only affect selected elements"""
        factor: FloatSocket
        """Factor to blend overall effect"""
        reference_position: VectorSocket
        """Reference position before deformation"""
        pin_at_parameter: FloatSocket
        """Pin each curve at a certain point for the operation"""

    class _Outputs(SocketAccessor):
        curves: GeometrySocket
        """Curves"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        curves: InputGeometry = None,
        selection: InputBoolean = True,
        factor: InputFloat = 1.0,
        reference_position: InputVector = None,
        pin_at_parameter: InputFloat = 0.0,
    ):
        super().__init__(
            **{
                "Input_0": curves,
                "Input_4": selection,
                "Input_3": factor,
                "Input_2": reference_position,
                "Input_6": pin_at_parameter,
            }
        )


class RollHairCurves(AssetGeometryGroup):
    """
    Roll Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Geometry
    factor : InputFloat
        Factor to blend the overall effect
    subdivision : InputInteger
        Subdivision level applied before deformation
    variation_level : InputInteger
        Level of smoothing on the roll path to include shape variation
    roll_length : InputFloat
        Length of each curve to be rolled
    roll_radius : InputFloat
        Radius of the rolls
    roll_depth : InputFloat
        Depth offset of the roll
    roll_taper : InputFloat
        Taper of the roll
    retain_overall_shape : InputFloat
        Offset the roll along the original curve to retain shape
    roll_direction : InputVector
        Axis around which each curve is rolled
    random_orientation : InputFloat
        Amount of randomization of the direction of the roll
    seed : InputInteger
        Random seed for the operation
    preserve_length : InputBoolean
        Preserve each curve's length during deformation

    Inputs
    ------
    i.geometry : GeometrySocket
        Geometry
    i.factor : FloatSocket
        Factor to blend the overall effect
    i.subdivision : IntegerSocket
        Subdivision level applied before deformation
    i.variation_level : IntegerSocket
        Level of smoothing on the roll path to include shape variation
    i.roll_length : FloatSocket
        Length of each curve to be rolled
    i.roll_radius : FloatSocket
        Radius of the rolls
    i.roll_depth : FloatSocket
        Depth offset of the roll
    i.roll_taper : FloatSocket
        Taper of the roll
    i.retain_overall_shape : FloatSocket
        Offset the roll along the original curve to retain shape
    i.roll_direction : VectorSocket
        Axis around which each curve is rolled
    i.random_orientation : FloatSocket
        Amount of randomization of the direction of the roll
    i.seed : IntegerSocket
        Random seed for the operation
    i.preserve_length : BooleanSocket
        Preserve each curve's length during deformation

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Roll Hair Curves"
    _asset_name = "Roll Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        factor: FloatSocket
        """Factor to blend the overall effect"""
        subdivision: IntegerSocket
        """Subdivision level applied before deformation"""
        variation_level: IntegerSocket
        """Level of smoothing on the roll path to include shape variation"""
        roll_length: FloatSocket
        """Length of each curve to be rolled"""
        roll_radius: FloatSocket
        """Radius of the rolls"""
        roll_depth: FloatSocket
        """Depth offset of the roll"""
        roll_taper: FloatSocket
        """Taper of the roll"""
        retain_overall_shape: FloatSocket
        """Offset the roll along the original curve to retain shape"""
        roll_direction: VectorSocket
        """Axis around which each curve is rolled"""
        random_orientation: FloatSocket
        """Amount of randomization of the direction of the roll"""
        seed: IntegerSocket
        """Random seed for the operation"""
        preserve_length: BooleanSocket
        """Preserve each curve's length during deformation"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        factor: InputFloat = 1.0,
        subdivision: InputInteger = 1,
        variation_level: InputInteger = 10,
        roll_length: InputFloat = 0.1,
        roll_radius: InputFloat = 0.05,
        roll_depth: InputFloat = 0.0,
        roll_taper: InputFloat = 0.0,
        retain_overall_shape: InputFloat = 0.0,
        roll_direction: InputVector = None,
        random_orientation: InputFloat = 0.5,
        seed: InputInteger = 0,
        preserve_length: InputBoolean = False,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_10": factor,
                "Input_13": subdivision,
                "Input_11": variation_level,
                "Input_2": roll_length,
                "Input_3": roll_radius,
                "Input_9": roll_depth,
                "Input_4": roll_taper,
                "Input_5": retain_overall_shape,
                "Input_7": roll_direction,
                "Input_6": random_orientation,
                "Input_8": seed,
                "Input_12": preserve_length,
            }
        )


class RotateHairCurves(AssetGeometryGroup):
    """
    Rotate Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Input geometry (may include geometry other than curves)
    factor : InputFloat
        Factor to influence the rotation angle
    axis : InputVector
        Rotation axis (default: tangent at root)
    angle : InputFloat
        Angle of rotation
    random_offset : InputFloat
        Random offset to the rotation angle per curve
    lock_ends : InputBoolean
        Lock rotation to the axis between the curve ends
    seed : InputInteger
        Random seed for the operation

    Inputs
    ------
    i.geometry : GeometrySocket
        Input geometry (may include geometry other than curves)
    i.factor : FloatSocket
        Factor to influence the rotation angle
    i.axis : VectorSocket
        Rotation axis (default: tangent at root)
    i.angle : FloatSocket
        Angle of rotation
    i.random_offset : FloatSocket
        Random offset to the rotation angle per curve
    i.lock_ends : BooleanSocket
        Lock rotation to the axis between the curve ends
    i.seed : IntegerSocket
        Random seed for the operation

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Rotate Hair Curves"
    _asset_name = "Rotate Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Input geometry (may include geometry other than curves)"""
        factor: FloatSocket
        """Factor to influence the rotation angle"""
        axis: VectorSocket
        """Rotation axis (default: tangent at root)"""
        angle: FloatSocket
        """Angle of rotation"""
        random_offset: FloatSocket
        """Random offset to the rotation angle per curve"""
        lock_ends: BooleanSocket
        """Lock rotation to the axis between the curve ends"""
        seed: IntegerSocket
        """Random seed for the operation"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        factor: InputFloat = 1.0,
        axis: InputVector = None,
        angle: InputFloat = 0.0,
        random_offset: InputFloat = 0.349066,
        lock_ends: InputBoolean = False,
        seed: InputInteger = 0,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_5": factor,
                "Input_3": axis,
                "Input_2": angle,
                "Input_6": random_offset,
                "Input_8": lock_ends,
                "Input_7": seed,
            }
        )


class ScatterOnSurface(AssetGeometryGroup):
    """
    Scatter on Surface

    Parameters
    ----------
    mesh : InputGeometry
        Mesh on whose faces to scatter on
    selection : InputBoolean
        Which faces to scatter on
    density_method : InputMenu | Literal["Density", "Amount"]
        Method to define the number of scattered instances
    distribution_method : InputMenu | Literal["Random", "Poisson Disk"]
        Method to use for scattering points
    amount : InputInteger
        Exact number of scattered instances before masking
    density : InputFloat
        Amount of scattered instances per unit squared
    distribution_mask : InputFloat
        Mask to multiply the density by
    minimum_distance : InputFloat
        Minimum allowed distance between the centers of two scattered instances. Increase value for a more locally even distribution.
    keep_surface : InputBoolean
        Keep the original input geometry and join it with the scattered geometry
    scatter_on_instances : InputBoolean
        Use instances contained in the input geometry as base for scattering
    seed : InputInteger
        Base value to control random variation in a reproducible way
    input_type : InputMenu | Literal["Data-Block", "Geometry"]
        How the instance geometry input should be exposed
    instance_type : InputMenu | Literal["Object", "Collection"]
        How the instance geometry data-block should be exposed
    object : InputObject
        Object providing the instance geometry used for scattering
    collection : InputCollection
        Collection providing the instance geometry used for scattering
    instance : InputGeometry
        Geometry that is instanced on the scattered points
    viewport_visibility : InputFloat
        Amount of scattered instances shown in the viewport
    realize_instances : InputBoolean
        Turn the output into a single geometry rather than instances (required by many other modifiers)
    pick_instance : InputBoolean
        Choose child instances for each element instead of instancing the entire geometry
    reset_transform : InputBoolean
        Reset the transforms of each individual child instance
    instance_seed : InputInteger
        Base value to control random instance variation in a reproducible way
    surface_offset : InputFloat
        Distance to offset each instance along the normal of the surface geometry
    align_rotation : InputBoolean
        Rotate instances based on the shape of the surface geometry
    alignment_axis : InputMenu | Literal["X", "Y", "Z"]
        Which axis to align with the normal of the surface geometry
    scale : InputVector
        Scale of the instances on each local axis
    randomize : InputBoolean
        Randomize transforms between all scattered instances
    randomize_offset : InputVector
        Offset the instances randomly
    randomize_rotation : InputVector
        Rotate the instances randomly
    randomize_scale_axes : InputMenu | Literal["Uniform", "Axes"]
        Whether to apply random scale uniformly or per axis
    socket_36 : InputVector
        Scale the instances down randomly per axis
    socket_41 : InputFloat
        Scale the instances down randomly
    randomize_flipping : InputVector
        Flip a fraction of instances along individual axes
    randomize_seed : InputInteger
        Base value to control random variation in a reproducible way
    masking : InputBoolean
        Additional masking applied after the initial scattering of instances
    image_mask : InputImage
        Grayscale image texture used to remove scattered instances
    uv_map : InputVector
        Texture coordinates used to map the image on the surface

    Inputs
    ------
    i.mesh : GeometrySocket
        Mesh on whose faces to scatter on
    i.selection : BooleanSocket
        Which faces to scatter on
    i.density_method : MenuSocket
        Method to define the number of scattered instances
    i.distribution_method : MenuSocket
        Method to use for scattering points
    i.amount : IntegerSocket
        Exact number of scattered instances before masking
    i.density : FloatSocket
        Amount of scattered instances per unit squared
    i.distribution_mask : FloatSocket
        Mask to multiply the density by
    i.minimum_distance : FloatSocket
        Minimum allowed distance between the centers of two scattered instances. Increase value for a more locally even distribution.
    i.keep_surface : BooleanSocket
        Keep the original input geometry and join it with the scattered geometry
    i.scatter_on_instances : BooleanSocket
        Use instances contained in the input geometry as base for scattering
    i.seed : IntegerSocket
        Base value to control random variation in a reproducible way
    i.input_type : MenuSocket
        How the instance geometry input should be exposed
    i.instance_type : MenuSocket
        How the instance geometry data-block should be exposed
    i.object : ObjectSocket
        Object providing the instance geometry used for scattering
    i.collection : CollectionSocket
        Collection providing the instance geometry used for scattering
    i.instance : GeometrySocket
        Geometry that is instanced on the scattered points
    i.viewport_visibility : FloatSocket
        Amount of scattered instances shown in the viewport
    i.realize_instances : BooleanSocket
        Turn the output into a single geometry rather than instances (required by many other modifiers)
    i.pick_instance : BooleanSocket
        Choose child instances for each element instead of instancing the entire geometry
    i.reset_transform : BooleanSocket
        Reset the transforms of each individual child instance
    i.instance_seed : IntegerSocket
        Base value to control random instance variation in a reproducible way
    i.surface_offset : FloatSocket
        Distance to offset each instance along the normal of the surface geometry
    i.align_rotation : BooleanSocket
        Rotate instances based on the shape of the surface geometry
    i.alignment_axis : MenuSocket
        Which axis to align with the normal of the surface geometry
    i.scale : VectorSocket
        Scale of the instances on each local axis
    i.randomize : BooleanSocket
        Randomize transforms between all scattered instances
    i.randomize_offset : VectorSocket
        Offset the instances randomly
    i.randomize_rotation : VectorSocket
        Rotate the instances randomly
    i.randomize_scale_axes : MenuSocket
        Whether to apply random scale uniformly or per axis
    i.socket_36 : VectorSocket
        Scale the instances down randomly per axis
    i.socket_41 : FloatSocket
        Scale the instances down randomly
    i.randomize_flipping : VectorSocket
        Flip a fraction of instances along individual axes
    i.randomize_seed : IntegerSocket
        Base value to control random variation in a reproducible way
    i.masking : BooleanSocket
        Additional masking applied after the initial scattering of instances
    i.image_mask : ImageSocket
        Grayscale image texture used to remove scattered instances
    i.uv_map : VectorSocket
        Texture coordinates used to map the image on the surface

    Outputs
    -------
    o.instances : GeometrySocket
        Instances
    """

    _name = "Scatter on Surface"
    _asset_name = "Scatter on Surface"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        mesh: GeometrySocket
        """Mesh on whose faces to scatter on"""
        selection: BooleanSocket
        """Which faces to scatter on"""
        density_method: MenuSocket
        """Method to define the number of scattered instances"""
        distribution_method: MenuSocket
        """Method to use for scattering points"""
        amount: IntegerSocket
        """Exact number of scattered instances before masking"""
        density: FloatSocket
        """Amount of scattered instances per unit squared"""
        distribution_mask: FloatSocket
        """Mask to multiply the density by"""
        minimum_distance: FloatSocket
        """Minimum allowed distance between the centers of two scattered instances. Increase value for a more locally even distribution."""
        keep_surface: BooleanSocket
        """Keep the original input geometry and join it with the scattered geometry"""
        scatter_on_instances: BooleanSocket
        """Use instances contained in the input geometry as base for scattering"""
        seed: IntegerSocket
        """Base value to control random variation in a reproducible way"""
        input_type: MenuSocket
        """How the instance geometry input should be exposed"""
        instance_type: MenuSocket
        """How the instance geometry data-block should be exposed"""
        object: ObjectSocket
        """Object providing the instance geometry used for scattering"""
        collection: CollectionSocket
        """Collection providing the instance geometry used for scattering"""
        instance: GeometrySocket
        """Geometry that is instanced on the scattered points"""
        viewport_visibility: FloatSocket
        """Amount of scattered instances shown in the viewport"""
        realize_instances: BooleanSocket
        """Turn the output into a single geometry rather than instances (required by many other modifiers)"""
        pick_instance: BooleanSocket
        """Choose child instances for each element instead of instancing the entire geometry"""
        reset_transform: BooleanSocket
        """Reset the transforms of each individual child instance"""
        instance_seed: IntegerSocket
        """Base value to control random instance variation in a reproducible way"""
        surface_offset: FloatSocket
        """Distance to offset each instance along the normal of the surface geometry"""
        align_rotation: BooleanSocket
        """Rotate instances based on the shape of the surface geometry"""
        alignment_axis: MenuSocket
        """Which axis to align with the normal of the surface geometry"""
        scale: VectorSocket
        """Scale of the instances on each local axis"""
        randomize: BooleanSocket
        """Randomize transforms between all scattered instances"""
        randomize_offset: VectorSocket
        """Offset the instances randomly"""
        randomize_rotation: VectorSocket
        """Rotate the instances randomly"""
        randomize_scale_axes: MenuSocket
        """Whether to apply random scale uniformly or per axis"""
        socket_36: VectorSocket
        """Scale the instances down randomly per axis"""
        socket_41: FloatSocket
        """Scale the instances down randomly"""
        randomize_flipping: VectorSocket
        """Flip a fraction of instances along individual axes"""
        randomize_seed: IntegerSocket
        """Base value to control random variation in a reproducible way"""
        masking: BooleanSocket
        """Additional masking applied after the initial scattering of instances"""
        image_mask: ImageSocket
        """Grayscale image texture used to remove scattered instances"""
        uv_map: VectorSocket
        """Texture coordinates used to map the image on the surface"""

    class _Outputs(SocketAccessor):
        instances: GeometrySocket
        """Instances"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        mesh: InputGeometry = None,
        selection: InputBoolean = True,
        density_method: InputMenu | Literal["Density", "Amount"] = "Density",
        distribution_method: InputMenu | Literal["Random", "Poisson Disk"] = "Random",
        amount: InputInteger = 1000,
        density: InputFloat = 1.0,
        distribution_mask: InputFloat = 1.0,
        minimum_distance: InputFloat = 0.0,
        keep_surface: InputBoolean = True,
        scatter_on_instances: InputBoolean = False,
        seed: InputInteger = 0,
        input_type: InputMenu | Literal["Data-Block", "Geometry"] = "Data-Block",
        instance_type: InputMenu | Literal["Object", "Collection"] = "Object",
        object: InputObject = None,
        collection: InputCollection = None,
        instance: InputGeometry = None,
        viewport_visibility: InputFloat = 1.0,
        realize_instances: InputBoolean = False,
        pick_instance: InputBoolean = False,
        reset_transform: InputBoolean = True,
        instance_seed: InputInteger = 0,
        surface_offset: InputFloat = 0.0,
        align_rotation: InputBoolean = True,
        alignment_axis: InputMenu | Literal["X", "Y", "Z"] = "Z",
        scale: InputVector = None,
        randomize: InputBoolean = False,
        randomize_offset: InputVector = None,
        randomize_rotation: InputVector = None,
        randomize_scale_axes: InputMenu | Literal["Uniform", "Axes"] = "Uniform",
        socket_36: InputVector = None,
        socket_41: InputFloat = 0.0,
        randomize_flipping: InputVector = None,
        randomize_seed: InputInteger = 0,
        masking: InputBoolean = False,
        image_mask: InputImage = None,
        uv_map: InputVector = None,
    ):
        super().__init__(
            **{
                "Socket_0": mesh,
                "Socket_1": selection,
                "Socket_30": density_method,
                "Socket_12": distribution_method,
                "Socket_31": amount,
                "Socket_27": density,
                "Socket_2": distribution_mask,
                "Socket_13": minimum_distance,
                "Socket_25": keep_surface,
                "Socket_46": scatter_on_instances,
                "Socket_4": seed,
                "Socket_19": input_type,
                "Socket_6": instance_type,
                "Socket_8": object,
                "Socket_7": collection,
                "Socket_3": instance,
                "Socket_33": viewport_visibility,
                "Socket_26": realize_instances,
                "Socket_17": pick_instance,
                "Socket_43": reset_transform,
                "Socket_16": instance_seed,
                "Socket_44": surface_offset,
                "Socket_18": align_rotation,
                "Socket_34": alignment_axis,
                "Socket_5": scale,
                "Socket_39": randomize,
                "Socket_40": randomize_offset,
                "Socket_35": randomize_rotation,
                "Socket_37": randomize_scale_axes,
                "Socket_36": socket_36,
                "Socket_41": socket_41,
                "Socket_42": randomize_flipping,
                "Socket_45": randomize_seed,
                "Socket_29": masking,
                "Socket_10": image_mask,
                "Socket_11": uv_map,
            }
        )


class ScreenTo3DSpace(AssetGeometryGroup):
    """
    Screen to 3D Space

    Parameters
    ----------
    normalized : InputVector
        2D screen space coordinates in the [0, 1] range
    depth : InputFloat
        Depth from camera in scene units. Same as depth pass
    camera : InputObject
        The camera used for rendering the scene

    Inputs
    ------
    i.normalized : VectorSocket
        2D screen space coordinates in the [0, 1] range
    i.depth : FloatSocket
        Depth from camera in scene units. Same as depth pass
    i.camera : ObjectSocket
        The camera used for rendering the scene

    Outputs
    -------
    o.vector : VectorSocket
        Projected 3D vector in 3D space
    """

    _name = "Screen to 3D Space"
    _asset_name = "Screen to 3D Space"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        normalized: VectorSocket
        """2D screen space coordinates in the [0, 1] range"""
        depth: FloatSocket
        """Depth from camera in scene units. Same as depth pass"""
        camera: ObjectSocket
        """The camera used for rendering the scene"""

    class _Outputs(SocketAccessor):
        vector: VectorSocket
        """Projected 3D vector in 3D space"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        normalized: InputVector = None,
        depth: InputFloat = 0.5,
        camera: InputObject = None,
    ):
        super().__init__(
            **{"Socket_1": normalized, "Socket_2": depth, "Socket_0": camera}
        )


class SeparateCylindrical(AssetGeometryGroup):
    """
    Separate Cylindrical

    Parameters
    ----------
    vector : InputVector
        Vector

    Inputs
    ------
    i.vector : VectorSocket
        Vector

    Outputs
    -------
    o.r : FloatSocket
        Radius - Length of the vector
    o.phi : FloatSocket
        Azimuth - Angle around the up axis
    o.z : FloatSocket
        Offset from the ground plane
    """

    _name = "Separate Cylindrical"
    _asset_name = "Separate Cylindrical"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    class _Outputs(SocketAccessor):
        r: FloatSocket
        """Radius - Length of the vector"""
        phi: FloatSocket
        """Azimuth - Angle around the up axis"""
        z: FloatSocket
        """Offset from the ground plane"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        vector: InputVector = None,
    ):
        super().__init__(**{"Input_7": vector})


class SeparateSpherical(AssetGeometryGroup):
    """
    Separate Spherical

    Parameters
    ----------
    vector : InputVector
        Vector

    Inputs
    ------
    i.vector : VectorSocket
        Vector

    Outputs
    -------
    o.r : FloatSocket
        Radius - Length of the vector
    o.phi : FloatSocket
        Azimuth - Angle around the up axis
    o.theta : FloatSocket
        Zenith - Angle from the ground plane
    """

    _name = "Separate Spherical"
    _asset_name = "Separate Spherical"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""

    class _Outputs(SocketAccessor):
        r: FloatSocket
        """Radius - Length of the vector"""
        phi: FloatSocket
        """Azimuth - Angle around the up axis"""
        theta: FloatSocket
        """Zenith - Angle from the ground plane"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        vector: InputVector = None,
    ):
        super().__init__(**{"Input_7": vector})


class SetEffector(AssetGeometryGroup):
    """
    Add effector information to the geometry bundle.

    Parameters
    ----------
    geometry : InputGeometry
        Geometry to add the effector to.
    effector : InputBundle
        The actual bundle containing one or multiple effectors.
    name : InputString
        Name of the effector in the geometry bundle.

    Inputs
    ------
    i.geometry : GeometrySocket
        Geometry to add the effector to.
    i.effector : BundleSocket
        The actual bundle containing one or multiple effectors.
    i.name : StringSocket
        Name of the effector in the geometry bundle.

    Outputs
    -------
    o.geometry : GeometrySocket
        The same geometry but with additional effector information.
    """

    _name = "Set Effector"
    _asset_name = "Set Effector"
    _library = BundledLibrary("geometry_nodes_dynamics_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry to add the effector to."""
        effector: BundleSocket
        """The actual bundle containing one or multiple effectors."""
        name: StringSocket
        """Name of the effector in the geometry bundle."""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """The same geometry but with additional effector information."""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        effector: InputBundle = None,
        name: InputString = "",
    ):
        super().__init__(
            **{"Socket_2": geometry, "Socket_0": effector, "Socket_3": name}
        )


class SetHairCurveProfile(AssetGeometryGroup):
    """
    Set Hair Curve Profile

    Parameters
    ----------
    geometry : InputGeometry
        Geometry
    replace_radius : InputBoolean
        Replace the original radius
    radius : InputFloat
        Base radius to be set if 'Replace Radius' is enabled
    shape : InputFloat
        Shape of the radius along the curve
    factor_min : InputFloat
        Factor of the radius at the minimum
    factor_max : InputFloat
        Factor of the radius at the maximum

    Inputs
    ------
    i.geometry : GeometrySocket
        Geometry
    i.replace_radius : BooleanSocket
        Replace the original radius
    i.radius : FloatSocket
        Base radius to be set if 'Replace Radius' is enabled
    i.shape : FloatSocket
        Shape of the radius along the curve
    i.factor_min : FloatSocket
        Factor of the radius at the minimum
    i.factor_max : FloatSocket
        Factor of the radius at the maximum

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Set Hair Curve Profile"
    _asset_name = "Set Hair Curve Profile"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""
        replace_radius: BooleanSocket
        """Replace the original radius"""
        radius: FloatSocket
        """Base radius to be set if 'Replace Radius' is enabled"""
        shape: FloatSocket
        """Shape of the radius along the curve"""
        factor_min: FloatSocket
        """Factor of the radius at the minimum"""
        factor_max: FloatSocket
        """Factor of the radius at the maximum"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        replace_radius: InputBoolean = True,
        radius: InputFloat = 0.01,
        shape: InputFloat = 0.5,
        factor_min: InputFloat = 0.0,
        factor_max: InputFloat = 1.0,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_6": replace_radius,
                "Input_3": radius,
                "Input_2": shape,
                "Input_4": factor_min,
                "Input_5": factor_max,
            }
        )


class ShrinkwrapHairCurves(AssetGeometryGroup):
    """
    Shrinkwrap Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Input geometry (may include geometry other than curves)
    surface_input_type : InputMenu | Literal["Object", "Geometry"]
        Select the input type for the surface geometry.
    input_2 : InputObject
        Surface object used for shrinkwrap
    input_3 : InputGeometry
        Surface geometry used for shrinkwrap
    factor : InputFloat
        Factor
    offset_distance : InputFloat
        Distance from the surface used for shrinkwrap
    above_surface : InputFloat
        Blend shrinkwrap for points above the surface
    smoothing_steps : InputInteger
        Amount of steps of smoothing applied after shrinkwrap
    lock_roots : InputBoolean
        Lock the position of root points

    Inputs
    ------
    i.geometry : GeometrySocket
        Input geometry (may include geometry other than curves)
    i.surface_input_type : MenuSocket
        Select the input type for the surface geometry.
    i.input_2 : ObjectSocket
        Surface object used for shrinkwrap
    i.input_3 : GeometrySocket
        Surface geometry used for shrinkwrap
    i.factor : FloatSocket
        Factor
    i.offset_distance : FloatSocket
        Distance from the surface used for shrinkwrap
    i.above_surface : FloatSocket
        Blend shrinkwrap for points above the surface
    i.smoothing_steps : IntegerSocket
        Amount of steps of smoothing applied after shrinkwrap
    i.lock_roots : BooleanSocket
        Lock the position of root points

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Shrinkwrap Hair Curves"
    _asset_name = "Shrinkwrap Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Input geometry (may include geometry other than curves)"""
        surface_input_type: MenuSocket
        """Select the input type for the surface geometry."""
        input_2: ObjectSocket
        """Surface object used for shrinkwrap"""
        input_3: GeometrySocket
        """Surface geometry used for shrinkwrap"""
        factor: FloatSocket
        """Factor"""
        offset_distance: FloatSocket
        """Distance from the surface used for shrinkwrap"""
        above_surface: FloatSocket
        """Blend shrinkwrap for points above the surface"""
        smoothing_steps: IntegerSocket
        """Amount of steps of smoothing applied after shrinkwrap"""
        lock_roots: BooleanSocket
        """Lock the position of root points"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        surface_input_type: InputMenu | Literal["Object", "Geometry"] = "Object",
        input_2: InputObject = None,
        input_3: InputGeometry = None,
        factor: InputFloat = 1.0,
        offset_distance: InputFloat = 0.0,
        above_surface: InputFloat = 0.5,
        smoothing_steps: InputInteger = 0,
        lock_roots: InputBoolean = True,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Socket_0": surface_input_type,
                "Input_2": input_2,
                "Input_3": input_3,
                "Input_5": factor,
                "Input_4": offset_distance,
                "Input_8": above_surface,
                "Input_6": smoothing_steps,
                "Input_7": lock_roots,
            }
        )


class SmoothByAngle(AssetGeometryGroup):
    """
    Smooth by Angle

    Parameters
    ----------
    mesh : InputGeometry
        Mesh
    angle : InputFloat
        Maximum face angle for smooth edges
    ignore_sharpness : InputBoolean
        Ignore Sharpness

    Inputs
    ------
    i.mesh : GeometrySocket
        Mesh
    i.angle : FloatSocket
        Maximum face angle for smooth edges
    i.ignore_sharpness : BooleanSocket
        Ignore Sharpness

    Outputs
    -------
    o.mesh : GeometrySocket
        Mesh
    """

    _name = "Smooth by Angle"
    _asset_name = "Smooth by Angle"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        mesh: GeometrySocket
        """Mesh"""
        angle: FloatSocket
        """Maximum face angle for smooth edges"""
        ignore_sharpness: BooleanSocket
        """Ignore Sharpness"""

    class _Outputs(SocketAccessor):
        mesh: GeometrySocket
        """Mesh"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        mesh: InputGeometry = None,
        angle: InputFloat = 0.523599,
        ignore_sharpness: InputBoolean = False,
    ):
        super().__init__(
            **{"Input_0": mesh, "Input_1": angle, "Socket_1": ignore_sharpness}
        )


class SmoothGeometry(AssetGeometryGroup):
    """
    Smooth Geometry

    Parameters
    ----------
    geometry : InputGeometry
        Points to smooth based on their neighbors
    selection : InputBoolean
        Selection
    iterations : InputInteger
        How many times to repeat the smoothing step
    weight : InputFloat
        Relative mix weight of neighboring elements

    Inputs
    ------
    i.geometry : GeometrySocket
        Points to smooth based on their neighbors
    i.selection : BooleanSocket
        Selection
    i.iterations : IntegerSocket
        How many times to repeat the smoothing step
    i.weight : FloatSocket
        Relative mix weight of neighboring elements

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Smooth Geometry"
    _asset_name = "Smooth Geometry"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Points to smooth based on their neighbors"""
        selection: BooleanSocket
        """Selection"""
        iterations: IntegerSocket
        """How many times to repeat the smoothing step"""
        weight: FloatSocket
        """Relative mix weight of neighboring elements"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        selection: InputBoolean = True,
        iterations: InputInteger = 5,
        weight: InputFloat = 0.5,
    ):
        super().__init__(
            **{
                "Socket_0": geometry,
                "Socket_2": selection,
                "Socket_3": iterations,
                "Socket_4": weight,
            }
        )


class SmoothHairCurves(AssetGeometryGroup):
    """
    Smooth Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Input geometry (may include geometry other than curves)
    amount : InputFloat
        Amount of smoothing
    shape : InputFloat
        Shape of the influence along curves (0 = constant, 0.5 = linear)
    iterations : InputInteger
        Amount of smoothing steps
    weight : InputFloat
        Weight used for smoothing
    lock_tips : InputBoolean
        Lock tip position when smoothing
    preserve_length : InputBoolean
        Preserve each curve's length during deformation

    Inputs
    ------
    i.geometry : GeometrySocket
        Input geometry (may include geometry other than curves)
    i.amount : FloatSocket
        Amount of smoothing
    i.shape : FloatSocket
        Shape of the influence along curves (0 = constant, 0.5 = linear)
    i.iterations : IntegerSocket
        Amount of smoothing steps
    i.weight : FloatSocket
        Weight used for smoothing
    i.lock_tips : BooleanSocket
        Lock tip position when smoothing
    i.preserve_length : BooleanSocket
        Preserve each curve's length during deformation

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Smooth Hair Curves"
    _asset_name = "Smooth Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Input geometry (may include geometry other than curves)"""
        amount: FloatSocket
        """Amount of smoothing"""
        shape: FloatSocket
        """Shape of the influence along curves (0 = constant, 0.5 = linear)"""
        iterations: IntegerSocket
        """Amount of smoothing steps"""
        weight: FloatSocket
        """Weight used for smoothing"""
        lock_tips: BooleanSocket
        """Lock tip position when smoothing"""
        preserve_length: BooleanSocket
        """Preserve each curve's length during deformation"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        amount: InputFloat = 1.0,
        shape: InputFloat = 0.0,
        iterations: InputInteger = 10,
        weight: InputFloat = 0.5,
        lock_tips: InputBoolean = False,
        preserve_length: InputBoolean = True,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_10": amount,
                "Input_13": shape,
                "Input_3": iterations,
                "Input_4": weight,
                "Input_2": lock_tips,
                "Input_8": preserve_length,
            }
        )


class SphereSelection(AssetGeometryGroup):
    """
    Sphere Selection

    Parameters
    ----------
    center : InputVector
        Center position of the sphere selection
    radius : InputFloat
        Maximum distance of the element from the selection center

    Inputs
    ------
    i.center : VectorSocket
        Center position of the sphere selection
    i.radius : FloatSocket
        Maximum distance of the element from the selection center

    Outputs
    -------
    o.selection : BooleanSocket
        Selection of elements within a sphere
    """

    _name = "Sphere Selection"
    _asset_name = "Sphere Selection"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        center: VectorSocket
        """Center position of the sphere selection"""
        radius: FloatSocket
        """Maximum distance of the element from the selection center"""

    class _Outputs(SocketAccessor):
        selection: BooleanSocket
        """Selection of elements within a sphere"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        center: InputVector = None,
        radius: InputFloat = 1.0,
    ):
        super().__init__(**{"Socket_1": center, "Socket_2": radius})


class StraightenHairCurves(AssetGeometryGroup):
    """
    Straighten Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Input geometry (may include geometry other than curves)
    amount : InputFloat
        Amount of straightening
    shape : InputFloat
        Shape of the influence along curves (0 = constant, 0.5 = linear)
    preserve_length : InputBoolean
        Preserve each curve's length during deformation

    Inputs
    ------
    i.geometry : GeometrySocket
        Input geometry (may include geometry other than curves)
    i.amount : FloatSocket
        Amount of straightening
    i.shape : FloatSocket
        Shape of the influence along curves (0 = constant, 0.5 = linear)
    i.preserve_length : BooleanSocket
        Preserve each curve's length during deformation

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Straighten Hair Curves"
    _asset_name = "Straighten Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Input geometry (may include geometry other than curves)"""
        amount: FloatSocket
        """Amount of straightening"""
        shape: FloatSocket
        """Shape of the influence along curves (0 = constant, 0.5 = linear)"""
        preserve_length: BooleanSocket
        """Preserve each curve's length during deformation"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        amount: InputFloat = 1.0,
        shape: InputFloat = 0.0,
        preserve_length: InputBoolean = True,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_2": amount,
                "Input_9": shape,
                "Input_7": preserve_length,
            }
        )


class TransformAndProject(AssetGeometryGroup):
    """
    Transform and Project

    Parameters
    ----------
    vector : InputVector
        Vector
    transform : InputMatrix
        Transform
    projection : InputMatrix
        Projection

    Inputs
    ------
    i.vector : VectorSocket
        Vector
    i.transform : MatrixSocket
        Transform
    i.projection : MatrixSocket
        Projection

    Outputs
    -------
    o.normalized : VectorSocket
        Normalized
    o.depth : FloatSocket
        Depth
    """

    _name = "Transform and Project"
    _asset_name = "Transform and Project"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Vector"""
        transform: MatrixSocket
        """Transform"""
        projection: MatrixSocket
        """Projection"""

    class _Outputs(SocketAccessor):
        normalized: VectorSocket
        """Normalized"""
        depth: FloatSocket
        """Depth"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        vector: InputVector = None,
        transform: InputMatrix = None,
        projection: InputMatrix = None,
    ):
        super().__init__(
            **{"Socket_0": vector, "Socket_1": transform, "Socket_2": projection}
        )


class TrimHairCurves(AssetGeometryGroup):
    """
    Trim Hair Curves

    Parameters
    ----------
    geometry : InputGeometry
        Input geometry (may include geometry other than curves)
    scale_uniform : InputBoolean
        Scale each curve uniformly to reach the target length
    length_factor : InputFloat
        Multiply the original length by a factor
    replace_length : InputBoolean
        Use the length input to fully replace the original length
    length : InputFloat
        Target length for the operation
    mask : InputFloat
        Mask to blend overall effect
    random_offset : InputFloat
        Trim hair curves randomly up to a certain amount
    pin_at_parameter : InputFloat
        Pin each curve at a certain point for the operation
    seed : InputInteger
        Random seed for the operation

    Inputs
    ------
    i.geometry : GeometrySocket
        Input geometry (may include geometry other than curves)
    i.scale_uniform : BooleanSocket
        Scale each curve uniformly to reach the target length
    i.length_factor : FloatSocket
        Multiply the original length by a factor
    i.replace_length : BooleanSocket
        Use the length input to fully replace the original length
    i.length : FloatSocket
        Target length for the operation
    i.mask : FloatSocket
        Mask to blend overall effect
    i.random_offset : FloatSocket
        Trim hair curves randomly up to a certain amount
    i.pin_at_parameter : FloatSocket
        Pin each curve at a certain point for the operation
    i.seed : IntegerSocket
        Random seed for the operation

    Outputs
    -------
    o.geometry : GeometrySocket
        Geometry
    """

    _name = "Trim Hair Curves"
    _asset_name = "Trim Hair Curves"
    _library = BundledLibrary("procedural_hair_node_assets.blend")

    class _Inputs(SocketAccessor):
        geometry: GeometrySocket
        """Input geometry (may include geometry other than curves)"""
        scale_uniform: BooleanSocket
        """Scale each curve uniformly to reach the target length"""
        length_factor: FloatSocket
        """Multiply the original length by a factor"""
        replace_length: BooleanSocket
        """Use the length input to fully replace the original length"""
        length: FloatSocket
        """Target length for the operation"""
        mask: FloatSocket
        """Mask to blend overall effect"""
        random_offset: FloatSocket
        """Trim hair curves randomly up to a certain amount"""
        pin_at_parameter: FloatSocket
        """Pin each curve at a certain point for the operation"""
        seed: IntegerSocket
        """Random seed for the operation"""

    class _Outputs(SocketAccessor):
        geometry: GeometrySocket
        """Geometry"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        geometry: InputGeometry = None,
        scale_uniform: InputBoolean = False,
        length_factor: InputFloat = 1.0,
        replace_length: InputBoolean = True,
        length: InputFloat = 1.0,
        mask: InputFloat = 1.0,
        random_offset: InputFloat = 0.0,
        pin_at_parameter: InputFloat = 0.0,
        seed: InputInteger = 0,
    ):
        super().__init__(
            **{
                "Input_0": geometry,
                "Input_9": scale_uniform,
                "Input_5": length_factor,
                "Input_6": replace_length,
                "Input_2": length,
                "Input_7": mask,
                "Input_4": random_offset,
                "Input_3": pin_at_parameter,
                "Input_8": seed,
            }
        )


class _3DToScreenSpace(AssetGeometryGroup):
    """
    3D to Screen Space

    Parameters
    ----------
    vector : InputVector
        Input 3D coordinates in world space
    camera : InputObject
        The camera used for rendering the scene
    clamp_depth : InputBoolean
        Clamps depth to camera clipping range

    Inputs
    ------
    i.vector : VectorSocket
        Input 3D coordinates in world space
    i.camera : ObjectSocket
        The camera used for rendering the scene
    i.clamp_depth : BooleanSocket
        Clamps depth to camera clipping range

    Outputs
    -------
    o.normalized : VectorSocket
        2D coordinates in the [0, 1] range in screen space
    o.depth : FloatSocket
        Depth in scene units. Same as depth pass
    """

    _name = "3D to Screen Space"
    _asset_name = "3D to Screen Space"
    _library = BundledLibrary("geometry_nodes_essentials.blend")

    class _Inputs(SocketAccessor):
        vector: VectorSocket
        """Input 3D coordinates in world space"""
        camera: ObjectSocket
        """The camera used for rendering the scene"""
        clamp_depth: BooleanSocket
        """Clamps depth to camera clipping range"""

    class _Outputs(SocketAccessor):
        normalized: VectorSocket
        """2D coordinates in the [0, 1] range in screen space"""
        depth: FloatSocket
        """Depth in scene units. Same as depth pass"""

    if TYPE_CHECKING:

        @property
        def i(self) -> _Inputs: ...
        @property
        def o(self) -> _Outputs: ...

    def __init__(
        self,
        vector: InputVector = None,
        camera: InputObject = None,
        clamp_depth: InputBoolean = True,
    ):
        super().__init__(
            **{"Socket_3": vector, "Socket_0": camera, "Socket_4": clamp_depth}
        )


__all__ = (
    "Array",
    "AttachHairCurvesToSurface",
    "AttachmentInfo",
    "BlendHairCurves",
    "BoxSelection",
    "BraidHairCurves",
    "CaptureRestGeometry",
    "ClothDynamicsExperimental",
    "ClumpHairCurves",
    "Collider",
    "CombineCylindrical",
    "CombineSpherical",
    "CreateGuideIndexMap",
    "CurlHairCurves",
    "CurveInfo",
    "CurveRoot",
    "CurveSegment",
    "CurveTip",
    "CurveToTube",
    "CustomEffector",
    "CustomForce",
    "DisplaceGeometry",
    "DisplaceHairCurves",
    "DuplicateHairCurves",
    "EdgeLength",
    "FaceCornerAngle",
    "FrizzHairCurves",
    "GenerateHairCurves",
    "GeometryInput",
    "GeometryPrincipalComponents",
    "HairCurvesNoise",
    "HairDynamics",
    "InstanceOnElements",
    "InterpolateHairCurves",
    "IsEdgeBoundary",
    "IsEdgeLoose",
    "IsEdgeManifold",
    "IsUVSplit",
    "NormalSelection",
    "PrincipalComponents",
    "ProjectWithDepth",
    "RandomRotation",
    "RandomizeTransforms",
    "RedistributeCurvePoints",
    "RestoreCurveSegmentLength",
    "RollHairCurves",
    "RotateHairCurves",
    "ScatterOnSurface",
    "ScreenTo3DSpace",
    "SeparateCylindrical",
    "SeparateSpherical",
    "SetEffector",
    "SetHairCurveProfile",
    "ShrinkwrapHairCurves",
    "SmoothByAngle",
    "SmoothGeometry",
    "SmoothHairCurves",
    "SphereSelection",
    "StraightenHairCurves",
    "TransformAndProject",
    "TrimHairCurves",
    "_3DToScreenSpace",
)
